@exyconn/common 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.
- package/README.md +259 -0
- package/dist/client/http/index.d.mts +85 -0
- package/dist/client/http/index.d.ts +85 -0
- package/dist/client/http/index.js +127 -0
- package/dist/client/http/index.js.map +1 -0
- package/dist/client/http/index.mjs +109 -0
- package/dist/client/http/index.mjs.map +1 -0
- package/dist/client/index.d.mts +7 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.js +964 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +889 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/client/logger/index.d.mts +53 -0
- package/dist/client/logger/index.d.ts +53 -0
- package/dist/client/logger/index.js +120 -0
- package/dist/client/logger/index.js.map +1 -0
- package/dist/client/logger/index.mjs +116 -0
- package/dist/client/logger/index.mjs.map +1 -0
- package/dist/client/utils/index.d.mts +285 -0
- package/dist/client/utils/index.d.ts +285 -0
- package/dist/client/utils/index.js +403 -0
- package/dist/client/utils/index.js.map +1 -0
- package/dist/client/utils/index.mjs +362 -0
- package/dist/client/utils/index.mjs.map +1 -0
- package/dist/index-BNdT-2X4.d.ts +229 -0
- package/dist/index-CcrANHAQ.d.mts +59 -0
- package/dist/index-ClWtDfwk.d.ts +833 -0
- package/dist/index-DSW6JfD-.d.mts +833 -0
- package/dist/index-Du0LLt9f.d.mts +229 -0
- package/dist/index-iTKxFa78.d.ts +59 -0
- package/dist/index.d.mts +171 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +3806 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3792 -0
- package/dist/index.mjs.map +1 -0
- package/dist/response.types-D--UhLJq.d.mts +67 -0
- package/dist/response.types-D--UhLJq.d.ts +67 -0
- package/dist/server/db/index.d.mts +38 -0
- package/dist/server/db/index.d.ts +38 -0
- package/dist/server/db/index.js +68 -0
- package/dist/server/db/index.js.map +1 -0
- package/dist/server/db/index.mjs +60 -0
- package/dist/server/db/index.mjs.map +1 -0
- package/dist/server/enums/index.d.mts +46 -0
- package/dist/server/enums/index.d.ts +46 -0
- package/dist/server/enums/index.js +48 -0
- package/dist/server/enums/index.js.map +1 -0
- package/dist/server/enums/index.mjs +43 -0
- package/dist/server/enums/index.mjs.map +1 -0
- package/dist/server/index.d.mts +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +569 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +523 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/server/logger/index.d.mts +34 -0
- package/dist/server/logger/index.d.ts +34 -0
- package/dist/server/logger/index.js +125 -0
- package/dist/server/logger/index.js.map +1 -0
- package/dist/server/logger/index.mjs +113 -0
- package/dist/server/logger/index.mjs.map +1 -0
- package/dist/server/middleware/index.d.mts +56 -0
- package/dist/server/middleware/index.d.ts +56 -0
- package/dist/server/middleware/index.js +128 -0
- package/dist/server/middleware/index.js.map +1 -0
- package/dist/server/middleware/index.mjs +118 -0
- package/dist/server/middleware/index.mjs.map +1 -0
- package/dist/server/response/index.d.mts +86 -0
- package/dist/server/response/index.d.ts +86 -0
- package/dist/server/response/index.js +140 -0
- package/dist/server/response/index.js.map +1 -0
- package/dist/server/response/index.mjs +126 -0
- package/dist/server/response/index.mjs.map +1 -0
- package/dist/server/utils/index.d.mts +69 -0
- package/dist/server/utils/index.d.ts +69 -0
- package/dist/server/utils/index.js +114 -0
- package/dist/server/utils/index.js.map +1 -0
- package/dist/server/utils/index.mjs +106 -0
- package/dist/server/utils/index.mjs.map +1 -0
- package/dist/shared/index.d.mts +4 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/index.js +933 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/index.mjs +612 -0
- package/dist/shared/index.mjs.map +1 -0
- package/package.json +202 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
// src/client/utils/date.ts
|
|
2
|
+
var formatDate = (date, locale = "en-US") => {
|
|
3
|
+
const dateObj = new Date(date);
|
|
4
|
+
return dateObj.toLocaleDateString(locale, {
|
|
5
|
+
year: "numeric",
|
|
6
|
+
month: "long",
|
|
7
|
+
day: "numeric"
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var formatDateTime = (date, locale = "en-US") => {
|
|
11
|
+
const dateObj = new Date(date);
|
|
12
|
+
return dateObj.toLocaleDateString(locale, {
|
|
13
|
+
year: "numeric",
|
|
14
|
+
month: "short",
|
|
15
|
+
day: "numeric",
|
|
16
|
+
hour: "2-digit",
|
|
17
|
+
minute: "2-digit"
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var formatRelativeTime = (date) => {
|
|
21
|
+
const dateObj = new Date(date);
|
|
22
|
+
const now = /* @__PURE__ */ new Date();
|
|
23
|
+
const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1e3);
|
|
24
|
+
const intervals = [
|
|
25
|
+
{ label: "year", seconds: 31536e3 },
|
|
26
|
+
{ label: "month", seconds: 2592e3 },
|
|
27
|
+
{ label: "week", seconds: 604800 },
|
|
28
|
+
{ label: "day", seconds: 86400 },
|
|
29
|
+
{ label: "hour", seconds: 3600 },
|
|
30
|
+
{ label: "minute", seconds: 60 },
|
|
31
|
+
{ label: "second", seconds: 1 }
|
|
32
|
+
];
|
|
33
|
+
for (const interval of intervals) {
|
|
34
|
+
const count = Math.floor(diffInSeconds / interval.seconds);
|
|
35
|
+
if (count >= 1) {
|
|
36
|
+
return `${count} ${interval.label}${count !== 1 ? "s" : ""} ago`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return "just now";
|
|
40
|
+
};
|
|
41
|
+
var formatDateForInput = (date) => {
|
|
42
|
+
const dateObj = new Date(date);
|
|
43
|
+
return dateObj.toISOString().split("T")[0];
|
|
44
|
+
};
|
|
45
|
+
var formatDateTimeForInput = (date) => {
|
|
46
|
+
const dateObj = new Date(date);
|
|
47
|
+
return dateObj.toISOString().slice(0, 16);
|
|
48
|
+
};
|
|
49
|
+
var isToday = (date) => {
|
|
50
|
+
const dateObj = new Date(date);
|
|
51
|
+
const today = /* @__PURE__ */ new Date();
|
|
52
|
+
return dateObj.getDate() === today.getDate() && dateObj.getMonth() === today.getMonth() && dateObj.getFullYear() === today.getFullYear();
|
|
53
|
+
};
|
|
54
|
+
var isPast = (date) => {
|
|
55
|
+
return new Date(date).getTime() < Date.now();
|
|
56
|
+
};
|
|
57
|
+
var isFuture = (date) => {
|
|
58
|
+
return new Date(date).getTime() > Date.now();
|
|
59
|
+
};
|
|
60
|
+
var addDays = (date, days) => {
|
|
61
|
+
const dateObj = new Date(date);
|
|
62
|
+
dateObj.setDate(dateObj.getDate() + days);
|
|
63
|
+
return dateObj;
|
|
64
|
+
};
|
|
65
|
+
var startOfDay = (date) => {
|
|
66
|
+
const dateObj = new Date(date);
|
|
67
|
+
dateObj.setHours(0, 0, 0, 0);
|
|
68
|
+
return dateObj;
|
|
69
|
+
};
|
|
70
|
+
var endOfDay = (date) => {
|
|
71
|
+
const dateObj = new Date(date);
|
|
72
|
+
dateObj.setHours(23, 59, 59, 999);
|
|
73
|
+
return dateObj;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/client/utils/clipboard.ts
|
|
77
|
+
var copyToClipboard = async (text) => {
|
|
78
|
+
try {
|
|
79
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
80
|
+
await navigator.clipboard.writeText(text);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
const textArea = document.createElement("textarea");
|
|
84
|
+
textArea.value = text;
|
|
85
|
+
textArea.style.position = "fixed";
|
|
86
|
+
textArea.style.left = "-999999px";
|
|
87
|
+
textArea.style.top = "-999999px";
|
|
88
|
+
document.body.appendChild(textArea);
|
|
89
|
+
textArea.focus();
|
|
90
|
+
textArea.select();
|
|
91
|
+
const success = document.execCommand("copy");
|
|
92
|
+
document.body.removeChild(textArea);
|
|
93
|
+
return success;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error("Failed to copy to clipboard:", error);
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var readFromClipboard = async () => {
|
|
100
|
+
try {
|
|
101
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
102
|
+
return await navigator.clipboard.readText();
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error("Failed to read from clipboard:", error);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var isClipboardAvailable = () => {
|
|
111
|
+
return !!(navigator.clipboard && window.isSecureContext);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// src/client/utils/slug.ts
|
|
115
|
+
var slugify = (text) => {
|
|
116
|
+
return text.toString().toLowerCase().trim().replace(/\s+/g, "-").replace(/[^\w\-]+/g, "").replace(/\-\-+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
|
|
117
|
+
};
|
|
118
|
+
var slugifyUnique = (text) => {
|
|
119
|
+
const baseSlug = slugify(text);
|
|
120
|
+
const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 5);
|
|
121
|
+
return `${baseSlug}-${uniqueSuffix}`;
|
|
122
|
+
};
|
|
123
|
+
var unslugify = (slug) => {
|
|
124
|
+
return slug.replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
125
|
+
};
|
|
126
|
+
var truncate = (text, maxLength, suffix = "...") => {
|
|
127
|
+
if (text.length <= maxLength) return text;
|
|
128
|
+
return text.substring(0, maxLength - suffix.length).trim() + suffix;
|
|
129
|
+
};
|
|
130
|
+
var truncateWords = (text, maxWords, suffix = "...") => {
|
|
131
|
+
const words = text.split(/\s+/);
|
|
132
|
+
if (words.length <= maxWords) return text;
|
|
133
|
+
return words.slice(0, maxWords).join(" ") + suffix;
|
|
134
|
+
};
|
|
135
|
+
var capitalizeWords = (text) => {
|
|
136
|
+
return text.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
137
|
+
};
|
|
138
|
+
var capitalize = (text) => {
|
|
139
|
+
if (!text) return "";
|
|
140
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
141
|
+
};
|
|
142
|
+
var camelToKebab = (text) => {
|
|
143
|
+
return text.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
144
|
+
};
|
|
145
|
+
var kebabToCamel = (text) => {
|
|
146
|
+
return text.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// src/client/utils/events.ts
|
|
150
|
+
var EventEmitter = class {
|
|
151
|
+
constructor() {
|
|
152
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Subscribe to an event
|
|
156
|
+
* @returns Unsubscribe function
|
|
157
|
+
*/
|
|
158
|
+
on(event, handler) {
|
|
159
|
+
if (!this.handlers.has(event)) {
|
|
160
|
+
this.handlers.set(event, /* @__PURE__ */ new Set());
|
|
161
|
+
}
|
|
162
|
+
this.handlers.get(event).add(handler);
|
|
163
|
+
return () => this.off(event, handler);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Subscribe to an event once
|
|
167
|
+
*/
|
|
168
|
+
once(event, handler) {
|
|
169
|
+
const wrappedHandler = (data) => {
|
|
170
|
+
this.off(event, wrappedHandler);
|
|
171
|
+
handler(data);
|
|
172
|
+
};
|
|
173
|
+
return this.on(event, wrappedHandler);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Unsubscribe from an event
|
|
177
|
+
*/
|
|
178
|
+
off(event, handler) {
|
|
179
|
+
const eventHandlers = this.handlers.get(event);
|
|
180
|
+
if (eventHandlers) {
|
|
181
|
+
eventHandlers.delete(handler);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Emit an event
|
|
186
|
+
*/
|
|
187
|
+
emit(event, data) {
|
|
188
|
+
const eventHandlers = this.handlers.get(event);
|
|
189
|
+
if (eventHandlers) {
|
|
190
|
+
eventHandlers.forEach((handler) => {
|
|
191
|
+
try {
|
|
192
|
+
handler(data);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
console.error(`Error in event handler for "${String(event)}":`, error);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Remove all handlers for an event (or all events)
|
|
201
|
+
*/
|
|
202
|
+
removeAllListeners(event) {
|
|
203
|
+
if (event) {
|
|
204
|
+
this.handlers.delete(event);
|
|
205
|
+
} else {
|
|
206
|
+
this.handlers.clear();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get count of listeners for an event
|
|
211
|
+
*/
|
|
212
|
+
listenerCount(event) {
|
|
213
|
+
return this.handlers.get(event)?.size ?? 0;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
var createEventEmitter = () => {
|
|
217
|
+
return new EventEmitter();
|
|
218
|
+
};
|
|
219
|
+
var appEvents = new EventEmitter();
|
|
220
|
+
|
|
221
|
+
// src/client/utils/api-urls.ts
|
|
222
|
+
var ApiUrlBuilder = class {
|
|
223
|
+
constructor(config) {
|
|
224
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
225
|
+
this.version = config.version || "";
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Build full URL from path
|
|
229
|
+
*/
|
|
230
|
+
build(path) {
|
|
231
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
232
|
+
const versionPath = this.version ? `/${this.version}` : "";
|
|
233
|
+
return `${this.baseUrl}${versionPath}${normalizedPath}`;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Build URL with query parameters
|
|
237
|
+
*/
|
|
238
|
+
buildWithParams(path, params) {
|
|
239
|
+
const url = this.build(path);
|
|
240
|
+
const filteredParams = Object.entries(params).filter(([, value]) => value !== void 0).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
|
|
241
|
+
return filteredParams ? `${url}?${filteredParams}` : url;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Build URL with path parameters
|
|
245
|
+
*/
|
|
246
|
+
buildWithPathParams(template, params) {
|
|
247
|
+
let path = template;
|
|
248
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
249
|
+
path = path.replace(`:${key}`, String(value));
|
|
250
|
+
path = path.replace(`{${key}}`, String(value));
|
|
251
|
+
});
|
|
252
|
+
return this.build(path);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get base URL
|
|
256
|
+
*/
|
|
257
|
+
getBaseUrl() {
|
|
258
|
+
return this.baseUrl;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Set new base URL
|
|
262
|
+
*/
|
|
263
|
+
setBaseUrl(baseUrl) {
|
|
264
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
var createApiUrlBuilder = (config) => {
|
|
268
|
+
return new ApiUrlBuilder(config);
|
|
269
|
+
};
|
|
270
|
+
var createApiEndpoints = (builder) => ({
|
|
271
|
+
// Auth endpoints
|
|
272
|
+
auth: {
|
|
273
|
+
login: () => builder.build("/auth/login"),
|
|
274
|
+
register: () => builder.build("/auth/register"),
|
|
275
|
+
logout: () => builder.build("/auth/logout"),
|
|
276
|
+
refresh: () => builder.build("/auth/refresh"),
|
|
277
|
+
me: () => builder.build("/auth/me"),
|
|
278
|
+
forgotPassword: () => builder.build("/auth/forgot-password"),
|
|
279
|
+
resetPassword: () => builder.build("/auth/reset-password")
|
|
280
|
+
},
|
|
281
|
+
// User endpoints
|
|
282
|
+
users: {
|
|
283
|
+
list: () => builder.build("/users"),
|
|
284
|
+
get: (id) => builder.buildWithPathParams("/users/:id", { id }),
|
|
285
|
+
create: () => builder.build("/users"),
|
|
286
|
+
update: (id) => builder.buildWithPathParams("/users/:id", { id }),
|
|
287
|
+
delete: (id) => builder.buildWithPathParams("/users/:id", { id })
|
|
288
|
+
},
|
|
289
|
+
// Generic CRUD factory
|
|
290
|
+
crud: (resource) => ({
|
|
291
|
+
list: () => builder.build(`/${resource}`),
|
|
292
|
+
get: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
|
|
293
|
+
create: () => builder.build(`/${resource}`),
|
|
294
|
+
update: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id }),
|
|
295
|
+
delete: (id) => builder.buildWithPathParams(`/${resource}/:id`, { id })
|
|
296
|
+
})
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// src/client/utils/response-parser.ts
|
|
300
|
+
var isSuccessResponse = (response) => {
|
|
301
|
+
return response.success === true;
|
|
302
|
+
};
|
|
303
|
+
var isErrorResponse = (response) => {
|
|
304
|
+
return response.success === false;
|
|
305
|
+
};
|
|
306
|
+
var getResponseData = (response, defaultValue) => {
|
|
307
|
+
if (isSuccessResponse(response) && response.data !== void 0) {
|
|
308
|
+
return response.data;
|
|
309
|
+
}
|
|
310
|
+
return defaultValue;
|
|
311
|
+
};
|
|
312
|
+
var getErrorMessage = (response, defaultMessage = "An error occurred") => {
|
|
313
|
+
if (response.error) {
|
|
314
|
+
return response.error;
|
|
315
|
+
}
|
|
316
|
+
if (response.message) {
|
|
317
|
+
return response.message;
|
|
318
|
+
}
|
|
319
|
+
return defaultMessage;
|
|
320
|
+
};
|
|
321
|
+
var hasData = (response) => {
|
|
322
|
+
return response.data !== null && response.data !== void 0;
|
|
323
|
+
};
|
|
324
|
+
var hasMorePages = (response) => {
|
|
325
|
+
return response.pagination.hasNextPage;
|
|
326
|
+
};
|
|
327
|
+
var getNextPage = (response) => {
|
|
328
|
+
if (response.pagination.hasNextPage) {
|
|
329
|
+
return response.pagination.page + 1;
|
|
330
|
+
}
|
|
331
|
+
return null;
|
|
332
|
+
};
|
|
333
|
+
var getPrevPage = (response) => {
|
|
334
|
+
if (response.pagination.hasPrevPage) {
|
|
335
|
+
return response.pagination.page - 1;
|
|
336
|
+
}
|
|
337
|
+
return null;
|
|
338
|
+
};
|
|
339
|
+
var createEmptyPaginationMeta = () => ({
|
|
340
|
+
total: 0,
|
|
341
|
+
page: 1,
|
|
342
|
+
limit: 10,
|
|
343
|
+
totalPages: 0,
|
|
344
|
+
hasNextPage: false,
|
|
345
|
+
hasPrevPage: false
|
|
346
|
+
});
|
|
347
|
+
var createSuccessResponse = (data, message = "Success") => ({
|
|
348
|
+
success: true,
|
|
349
|
+
message,
|
|
350
|
+
data,
|
|
351
|
+
statusCode: 200
|
|
352
|
+
});
|
|
353
|
+
var createErrorResponse = (message, statusCode = 400, error) => ({
|
|
354
|
+
success: false,
|
|
355
|
+
message,
|
|
356
|
+
error,
|
|
357
|
+
statusCode
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
export { ApiUrlBuilder, EventEmitter, addDays, appEvents, camelToKebab, capitalize, capitalizeWords, copyToClipboard, createApiEndpoints, createApiUrlBuilder, createEmptyPaginationMeta, createErrorResponse, createEventEmitter, createSuccessResponse, endOfDay, formatDate, formatDateForInput, formatDateTime, formatDateTimeForInput, formatRelativeTime, getErrorMessage, getNextPage, getPrevPage, getResponseData, hasData, hasMorePages, isClipboardAvailable, isErrorResponse, isFuture, isPast, isSuccessResponse, isToday, kebabToCamel, readFromClipboard, slugify, slugifyUnique, startOfDay, truncate, truncateWords, unslugify };
|
|
361
|
+
//# sourceMappingURL=index.mjs.map
|
|
362
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/client/utils/date.ts","../../../src/client/utils/clipboard.ts","../../../src/client/utils/slug.ts","../../../src/client/utils/events.ts","../../../src/client/utils/api-urls.ts","../../../src/client/utils/response-parser.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Format date to readable string\r\n * @param date - Date to format\r\n * @param locale - Locale for formatting (default: 'en-US')\r\n */\r\nexport const formatDate = (\r\n date: Date | string | number,\r\n locale: string = 'en-US'\r\n): string => {\r\n const dateObj = new Date(date);\r\n return dateObj.toLocaleDateString(locale, {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n });\r\n};\r\n\r\n/**\r\n * Format date with time\r\n */\r\nexport const formatDateTime = (\r\n date: Date | string | number,\r\n locale: string = 'en-US'\r\n): string => {\r\n const dateObj = new Date(date);\r\n return dateObj.toLocaleDateString(locale, {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n });\r\n};\r\n\r\n/**\r\n * Format date as relative time (e.g., \"2 hours ago\")\r\n */\r\nexport const formatRelativeTime = (date: Date | string | number): string => {\r\n const dateObj = new Date(date);\r\n const now = new Date();\r\n const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1000);\r\n\r\n const intervals: { label: string; seconds: number }[] = [\r\n { label: 'year', seconds: 31536000 },\r\n { label: 'month', seconds: 2592000 },\r\n { label: 'week', seconds: 604800 },\r\n { label: 'day', seconds: 86400 },\r\n { label: 'hour', seconds: 3600 },\r\n { label: 'minute', seconds: 60 },\r\n { label: 'second', seconds: 1 },\r\n ];\r\n\r\n for (const interval of intervals) {\r\n const count = Math.floor(diffInSeconds / interval.seconds);\r\n if (count >= 1) {\r\n return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`;\r\n }\r\n }\r\n\r\n return 'just now';\r\n};\r\n\r\n/**\r\n * Format date for input[type=\"date\"]\r\n */\r\nexport const formatDateForInput = (date: Date | string | number): string => {\r\n const dateObj = new Date(date);\r\n return dateObj.toISOString().split('T')[0];\r\n};\r\n\r\n/**\r\n * Format date for input[type=\"datetime-local\"]\r\n */\r\nexport const formatDateTimeForInput = (date: Date | string | number): string => {\r\n const dateObj = new Date(date);\r\n return dateObj.toISOString().slice(0, 16);\r\n};\r\n\r\n/**\r\n * Check if date is today\r\n */\r\nexport const isToday = (date: Date | string | number): boolean => {\r\n const dateObj = new Date(date);\r\n const today = new Date();\r\n return (\r\n dateObj.getDate() === today.getDate() &&\r\n dateObj.getMonth() === today.getMonth() &&\r\n dateObj.getFullYear() === today.getFullYear()\r\n );\r\n};\r\n\r\n/**\r\n * Check if date is in the past\r\n */\r\nexport const isPast = (date: Date | string | number): boolean => {\r\n return new Date(date).getTime() < Date.now();\r\n};\r\n\r\n/**\r\n * Check if date is in the future\r\n */\r\nexport const isFuture = (date: Date | string | number): boolean => {\r\n return new Date(date).getTime() > Date.now();\r\n};\r\n\r\n/**\r\n * Add days to a date\r\n */\r\nexport const addDays = (date: Date | string | number, days: number): Date => {\r\n const dateObj = new Date(date);\r\n dateObj.setDate(dateObj.getDate() + days);\r\n return dateObj;\r\n};\r\n\r\n/**\r\n * Get start of day\r\n */\r\nexport const startOfDay = (date: Date | string | number): Date => {\r\n const dateObj = new Date(date);\r\n dateObj.setHours(0, 0, 0, 0);\r\n return dateObj;\r\n};\r\n\r\n/**\r\n * Get end of day\r\n */\r\nexport const endOfDay = (date: Date | string | number): Date => {\r\n const dateObj = new Date(date);\r\n dateObj.setHours(23, 59, 59, 999);\r\n return dateObj;\r\n};\r\n\r\nexport default {\r\n formatDate,\r\n formatDateTime,\r\n formatRelativeTime,\r\n formatDateForInput,\r\n formatDateTimeForInput,\r\n isToday,\r\n isPast,\r\n isFuture,\r\n addDays,\r\n startOfDay,\r\n endOfDay,\r\n};\r\n","/**\r\n * Copy text to clipboard\r\n * @returns Promise<boolean> - true if successful\r\n */\r\nexport const copyToClipboard = async (text: string): Promise<boolean> => {\r\n try {\r\n // Modern API (preferred)\r\n if (navigator.clipboard && window.isSecureContext) {\r\n await navigator.clipboard.writeText(text);\r\n return true;\r\n }\r\n\r\n // Fallback for older browsers or non-secure contexts\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n textArea.style.position = 'fixed';\r\n textArea.style.left = '-999999px';\r\n textArea.style.top = '-999999px';\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n\r\n const success = document.execCommand('copy');\r\n document.body.removeChild(textArea);\r\n return success;\r\n } catch (error) {\r\n console.error('Failed to copy to clipboard:', error);\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Read text from clipboard\r\n * @returns Promise<string | null>\r\n */\r\nexport const readFromClipboard = async (): Promise<string | null> => {\r\n try {\r\n if (navigator.clipboard && window.isSecureContext) {\r\n return await navigator.clipboard.readText();\r\n }\r\n return null;\r\n } catch (error) {\r\n console.error('Failed to read from clipboard:', error);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Check if clipboard API is available\r\n */\r\nexport const isClipboardAvailable = (): boolean => {\r\n return !!(navigator.clipboard && window.isSecureContext);\r\n};\r\n\r\nexport default {\r\n copyToClipboard,\r\n readFromClipboard,\r\n isClipboardAvailable,\r\n};\r\n","/**\r\n * Generate URL-friendly slug from text\r\n */\r\nexport const slugify = (text: string): string => {\r\n return text\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n .replace(/\\s+/g, '-') // Replace spaces with -\r\n .replace(/[^\\w\\-]+/g, '') // Remove non-word chars\r\n .replace(/\\-\\-+/g, '-') // Replace multiple - with single -\r\n .replace(/^-+/, '') // Trim - from start\r\n .replace(/-+$/, ''); // Trim - from end\r\n};\r\n\r\n/**\r\n * Generate slug with unique suffix\r\n */\r\nexport const slugifyUnique = (text: string): string => {\r\n const baseSlug = slugify(text);\r\n const uniqueSuffix = Date.now().toString(36) + Math.random().toString(36).substring(2, 5);\r\n return `${baseSlug}-${uniqueSuffix}`;\r\n};\r\n\r\n/**\r\n * Convert slug back to readable text\r\n */\r\nexport const unslugify = (slug: string): string => {\r\n return slug\r\n .replace(/-/g, ' ')\r\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\r\n};\r\n\r\n/**\r\n * Truncate text to specified length with ellipsis\r\n */\r\nexport const truncate = (\r\n text: string,\r\n maxLength: number,\r\n suffix: string = '...'\r\n): string => {\r\n if (text.length <= maxLength) return text;\r\n return text.substring(0, maxLength - suffix.length).trim() + suffix;\r\n};\r\n\r\n/**\r\n * Truncate text by words\r\n */\r\nexport const truncateWords = (\r\n text: string,\r\n maxWords: number,\r\n suffix: string = '...'\r\n): string => {\r\n const words = text.split(/\\s+/);\r\n if (words.length <= maxWords) return text;\r\n return words.slice(0, maxWords).join(' ') + suffix;\r\n};\r\n\r\n/**\r\n * Capitalize first letter of each word\r\n */\r\nexport const capitalizeWords = (text: string): string => {\r\n return text.replace(/\\b\\w/g, (char) => char.toUpperCase());\r\n};\r\n\r\n/**\r\n * Capitalize first letter only\r\n */\r\nexport const capitalize = (text: string): string => {\r\n if (!text) return '';\r\n return text.charAt(0).toUpperCase() + text.slice(1);\r\n};\r\n\r\n/**\r\n * Convert camelCase to kebab-case\r\n */\r\nexport const camelToKebab = (text: string): string => {\r\n return text.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\r\n};\r\n\r\n/**\r\n * Convert kebab-case to camelCase\r\n */\r\nexport const kebabToCamel = (text: string): string => {\r\n return text.replace(/-([a-z])/g, (_, char) => char.toUpperCase());\r\n};\r\n\r\nexport default {\r\n slugify,\r\n slugifyUnique,\r\n unslugify,\r\n truncate,\r\n truncateWords,\r\n capitalizeWords,\r\n capitalize,\r\n camelToKebab,\r\n kebabToCamel,\r\n};\r\n","/**\r\n * Event Emitter for client-side event handling\r\n */\r\n\r\ntype EventHandler<T = unknown> = (data: T) => void;\r\n\r\ninterface EventMap {\r\n [event: string]: unknown;\r\n}\r\n\r\n/**\r\n * Simple typed event emitter for browser use\r\n */\r\nexport class EventEmitter<Events extends EventMap = EventMap> {\r\n private handlers: Map<keyof Events, Set<EventHandler<unknown>>> = new Map();\r\n\r\n /**\r\n * Subscribe to an event\r\n * @returns Unsubscribe function\r\n */\r\n on<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): () => void {\r\n if (!this.handlers.has(event)) {\r\n this.handlers.set(event, new Set());\r\n }\r\n this.handlers.get(event)!.add(handler as EventHandler<unknown>);\r\n\r\n // Return unsubscribe function\r\n return () => this.off(event, handler);\r\n }\r\n\r\n /**\r\n * Subscribe to an event once\r\n */\r\n once<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): () => void {\r\n const wrappedHandler: EventHandler<Events[K]> = (data) => {\r\n this.off(event, wrappedHandler);\r\n handler(data);\r\n };\r\n return this.on(event, wrappedHandler);\r\n }\r\n\r\n /**\r\n * Unsubscribe from an event\r\n */\r\n off<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): void {\r\n const eventHandlers = this.handlers.get(event);\r\n if (eventHandlers) {\r\n eventHandlers.delete(handler as EventHandler<unknown>);\r\n }\r\n }\r\n\r\n /**\r\n * Emit an event\r\n */\r\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\r\n const eventHandlers = this.handlers.get(event);\r\n if (eventHandlers) {\r\n eventHandlers.forEach((handler) => {\r\n try {\r\n handler(data);\r\n } catch (error) {\r\n console.error(`Error in event handler for \"${String(event)}\":`, error);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Remove all handlers for an event (or all events)\r\n */\r\n removeAllListeners(event?: keyof Events): void {\r\n if (event) {\r\n this.handlers.delete(event);\r\n } else {\r\n this.handlers.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Get count of listeners for an event\r\n */\r\n listenerCount(event: keyof Events): number {\r\n return this.handlers.get(event)?.size ?? 0;\r\n }\r\n}\r\n\r\n/**\r\n * Create a new event emitter instance\r\n */\r\nexport const createEventEmitter = <Events extends EventMap = EventMap>(): EventEmitter<Events> => {\r\n return new EventEmitter<Events>();\r\n};\r\n\r\n/**\r\n * Global app event emitter (singleton)\r\n */\r\nexport const appEvents = new EventEmitter<{\r\n 'auth:login': { userId: string };\r\n 'auth:logout': void;\r\n 'notification:show': { message: string; type: 'success' | 'error' | 'warning' | 'info' };\r\n 'theme:change': 'light' | 'dark';\r\n [key: string]: unknown;\r\n}>();\r\n\r\nexport default {\r\n EventEmitter,\r\n createEventEmitter,\r\n appEvents,\r\n};\r\n","/**\r\n * API URL Builder\r\n * Centralized API endpoint management\r\n */\r\n\r\nexport interface ApiUrlConfig {\r\n baseUrl: string;\r\n version?: string;\r\n}\r\n\r\n/**\r\n * API URL builder class\r\n */\r\nexport class ApiUrlBuilder {\r\n private baseUrl: string;\r\n private version: string;\r\n\r\n constructor(config: ApiUrlConfig) {\r\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\r\n this.version = config.version || '';\r\n }\r\n\r\n /**\r\n * Build full URL from path\r\n */\r\n build(path: string): string {\r\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\r\n const versionPath = this.version ? `/${this.version}` : '';\r\n return `${this.baseUrl}${versionPath}${normalizedPath}`;\r\n }\r\n\r\n /**\r\n * Build URL with query parameters\r\n */\r\n buildWithParams(path: string, params: Record<string, string | number | boolean | undefined>): string {\r\n const url = this.build(path);\r\n const filteredParams = Object.entries(params)\r\n .filter(([, value]) => value !== undefined)\r\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\r\n .join('&');\r\n\r\n return filteredParams ? `${url}?${filteredParams}` : url;\r\n }\r\n\r\n /**\r\n * Build URL with path parameters\r\n */\r\n buildWithPathParams(template: string, params: Record<string, string | number>): string {\r\n let path = template;\r\n Object.entries(params).forEach(([key, value]) => {\r\n path = path.replace(`:${key}`, String(value));\r\n path = path.replace(`{${key}}`, String(value));\r\n });\r\n return this.build(path);\r\n }\r\n\r\n /**\r\n * Get base URL\r\n */\r\n getBaseUrl(): string {\r\n return this.baseUrl;\r\n }\r\n\r\n /**\r\n * Set new base URL\r\n */\r\n setBaseUrl(baseUrl: string): void {\r\n this.baseUrl = baseUrl.replace(/\\/$/, '');\r\n }\r\n}\r\n\r\n/**\r\n * Create API URL builder\r\n */\r\nexport const createApiUrlBuilder = (config: ApiUrlConfig): ApiUrlBuilder => {\r\n return new ApiUrlBuilder(config);\r\n};\r\n\r\n/**\r\n * Common API endpoints factory\r\n */\r\nexport const createApiEndpoints = (builder: ApiUrlBuilder) => ({\r\n // Auth endpoints\r\n auth: {\r\n login: () => builder.build('/auth/login'),\r\n register: () => builder.build('/auth/register'),\r\n logout: () => builder.build('/auth/logout'),\r\n refresh: () => builder.build('/auth/refresh'),\r\n me: () => builder.build('/auth/me'),\r\n forgotPassword: () => builder.build('/auth/forgot-password'),\r\n resetPassword: () => builder.build('/auth/reset-password'),\r\n },\r\n\r\n // User endpoints\r\n users: {\r\n list: () => builder.build('/users'),\r\n get: (id: string) => builder.buildWithPathParams('/users/:id', { id }),\r\n create: () => builder.build('/users'),\r\n update: (id: string) => builder.buildWithPathParams('/users/:id', { id }),\r\n delete: (id: string) => builder.buildWithPathParams('/users/:id', { id }),\r\n },\r\n\r\n // Generic CRUD factory\r\n crud: (resource: string) => ({\r\n list: () => builder.build(`/${resource}`),\r\n get: (id: string) => builder.buildWithPathParams(`/${resource}/:id`, { id }),\r\n create: () => builder.build(`/${resource}`),\r\n update: (id: string) => builder.buildWithPathParams(`/${resource}/:id`, { id }),\r\n delete: (id: string) => builder.buildWithPathParams(`/${resource}/:id`, { id }),\r\n }),\r\n});\r\n\r\nexport default {\r\n ApiUrlBuilder,\r\n createApiUrlBuilder,\r\n createApiEndpoints,\r\n};\r\n","/**\n * Response Parser Utilities\n * Common patterns for parsing API responses\n */\nimport type { ApiResponse, PaginatedResponse, PaginationMeta } from '../../shared/types';\n\n/**\n * Check if response is successful\n */\nexport const isSuccessResponse = <T>(response: ApiResponse<T>): response is ApiResponse<T> & { success: true } => {\n return response.success === true;\n};\n\n/**\n * Check if response is an error\n */\nexport const isErrorResponse = <T>(response: ApiResponse<T>): response is ApiResponse<T> & { success: false } => {\n return response.success === false;\n};\n\n/**\n * Extract data from response or return default\n */\nexport const getResponseData = <T>(response: ApiResponse<T>, defaultValue: T): T => {\n if (isSuccessResponse(response) && response.data !== undefined) {\n return response.data;\n }\n return defaultValue;\n};\n\n/**\n * Extract error message from response\n */\nexport const getErrorMessage = <T>(response: ApiResponse<T>, defaultMessage: string = 'An error occurred'): string => {\n if (response.error) {\n return response.error;\n }\n if (response.message) {\n return response.message;\n }\n return defaultMessage;\n};\n\n/**\n * Check if response has data\n */\nexport const hasData = <T>(response: ApiResponse<T>): response is ApiResponse<T> & { data: NonNullable<T> } => {\n return response.data !== null && response.data !== undefined;\n};\n\n/**\n * Check if paginated response has more pages\n */\nexport const hasMorePages = <T>(response: PaginatedResponse<T>): boolean => {\n return response.pagination.hasNextPage;\n};\n\n/**\n * Get next page number from paginated response\n */\nexport const getNextPage = <T>(response: PaginatedResponse<T>): number | null => {\n if (response.pagination.hasNextPage) {\n return response.pagination.page + 1;\n }\n return null;\n};\n\n/**\n * Get previous page number from paginated response\n */\nexport const getPrevPage = <T>(response: PaginatedResponse<T>): number | null => {\n if (response.pagination.hasPrevPage) {\n return response.pagination.page - 1;\n }\n return null;\n};\n\n/**\n * Create empty pagination meta\n */\nexport const createEmptyPaginationMeta = (): PaginationMeta => ({\n total: 0,\n page: 1,\n limit: 10,\n totalPages: 0,\n hasNextPage: false,\n hasPrevPage: false,\n});\n\n/**\n * Create success response\n */\nexport const createSuccessResponse = <T>(data: T, message: string = 'Success'): ApiResponse<T> => ({\n success: true,\n message,\n data,\n statusCode: 200,\n});\n\n/**\n * Create error response\n */\nexport const createErrorResponse = (\n message: string,\n statusCode: number = 400,\n error?: string\n): ApiResponse<never> => ({\n success: false,\n message,\n error,\n statusCode,\n});\n\nexport default {\n isSuccessResponse,\n isErrorResponse,\n getResponseData,\n getErrorMessage,\n hasData,\n hasMorePages,\n getNextPage,\n getPrevPage,\n createEmptyPaginationMeta,\n createSuccessResponse,\n createErrorResponse,\n};\n"]}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { ApiResponse, HttpClientOptions, PaginatedResponse, createHttpClient, isForbidden, isNotFound, isServerError, isStatusError, isSuccess, isUnauthorized, parseError, parseFullResponse, parseResponse, withAbortSignal, withFormData, withTimeout } from './client/http/index.js';
|
|
2
|
+
import { ClientLogger, ClientLoggerConfig, LogLevel, clientLogger, createClientLogger } from './client/logger/index.js';
|
|
3
|
+
import { ApiUrlBuilder, ApiUrlConfig, EventEmitter, addDays, appEvents, camelToKebab, capitalize, capitalizeWords, copyToClipboard, createApiEndpoints, createApiUrlBuilder, createEmptyPaginationMeta, createErrorResponse, createEventEmitter, createSuccessResponse, endOfDay, formatDate, formatDateForInput, formatDateTime, formatDateTimeForInput, formatRelativeTime, getErrorMessage, getNextPage, getPrevPage, getResponseData, hasData, hasMorePages, isClipboardAvailable, isErrorResponse, isFuture, isPast, isSuccessResponse, isToday, kebabToCamel, readFromClipboard, slugify, slugifyUnique, startOfDay, truncate, truncateWords, unslugify } from './client/utils/index.js';
|
|
4
|
+
import { RefObject } from 'react';
|
|
5
|
+
|
|
6
|
+
type SetValue<T> = T | ((prevValue: T) => T);
|
|
7
|
+
interface UseLocalStorageOptions<T> {
|
|
8
|
+
/** Serialize function (default: JSON.stringify) */
|
|
9
|
+
serializer?: (value: T) => string;
|
|
10
|
+
/** Deserialize function (default: JSON.parse) */
|
|
11
|
+
deserializer?: (value: string) => T;
|
|
12
|
+
/** Enable cross-tab synchronization (default: true) */
|
|
13
|
+
syncTabs?: boolean;
|
|
14
|
+
/** Enable logging (default: false) */
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Hook to persist state in localStorage with cross-tab sync
|
|
19
|
+
* @param key - localStorage key
|
|
20
|
+
* @param initialValue - initial/fallback value
|
|
21
|
+
* @param options - configuration options
|
|
22
|
+
*/
|
|
23
|
+
declare function useLocalStorage<T>(key: string, initialValue: T, options?: UseLocalStorageOptions<T>): [T, (value: SetValue<T>) => void, () => void];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Debounce a value with configurable delay
|
|
27
|
+
* @param value - Value to debounce
|
|
28
|
+
* @param delay - Delay in milliseconds (default: 500)
|
|
29
|
+
*/
|
|
30
|
+
declare function useDebounce<T>(value: T, delay?: number): T;
|
|
31
|
+
|
|
32
|
+
interface UseCopyToClipboardReturn {
|
|
33
|
+
/** Copy text to clipboard */
|
|
34
|
+
copy: (text: string) => Promise<boolean>;
|
|
35
|
+
/** Whether copy was successful (resets after timeout) */
|
|
36
|
+
copied: boolean;
|
|
37
|
+
/** Error message if copy failed */
|
|
38
|
+
error: string | null;
|
|
39
|
+
/** Reset state */
|
|
40
|
+
reset: () => void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Copy text to clipboard with feedback
|
|
44
|
+
* @param resetDelay - Time in ms before copied state resets (default: 2000)
|
|
45
|
+
*/
|
|
46
|
+
declare function useCopyToClipboard(resetDelay?: number): UseCopyToClipboardReturn;
|
|
47
|
+
|
|
48
|
+
interface UsePageTitleOptions {
|
|
49
|
+
/** Suffix to append to the title (e.g., organization name) */
|
|
50
|
+
suffix?: string;
|
|
51
|
+
/** Separator between title and suffix (default: ' | ') */
|
|
52
|
+
separator?: string;
|
|
53
|
+
/** Whether to restore original title on unmount (default: true) */
|
|
54
|
+
restoreOnUnmount?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Set the document title with optional suffix
|
|
58
|
+
* @param title - Page title
|
|
59
|
+
* @param options - Configuration options
|
|
60
|
+
*/
|
|
61
|
+
declare function usePageTitle(title: string, options?: UsePageTitleOptions): void;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Run a callback on an interval
|
|
65
|
+
* @param callback - Function to call on each interval
|
|
66
|
+
* @param delay - Interval delay in ms (null to pause)
|
|
67
|
+
*/
|
|
68
|
+
declare function useInterval(callback: () => void, delay: number | null): void;
|
|
69
|
+
|
|
70
|
+
type ThemeMode = 'light' | 'dark';
|
|
71
|
+
/**
|
|
72
|
+
* Detect and track system color scheme preference
|
|
73
|
+
* @returns Current theme mode based on system preference
|
|
74
|
+
*/
|
|
75
|
+
declare function useThemeDetector(): ThemeMode;
|
|
76
|
+
|
|
77
|
+
type SnackbarSeverity = 'success' | 'error' | 'warning' | 'info';
|
|
78
|
+
interface SnackbarState {
|
|
79
|
+
open: boolean;
|
|
80
|
+
message: string;
|
|
81
|
+
severity: SnackbarSeverity;
|
|
82
|
+
autoHideDuration?: number;
|
|
83
|
+
}
|
|
84
|
+
interface UseSnackbarReturn {
|
|
85
|
+
/** Current snackbar state */
|
|
86
|
+
state: SnackbarState;
|
|
87
|
+
/** Show snackbar with message */
|
|
88
|
+
show: (message: string, severity?: SnackbarSeverity, duration?: number) => void;
|
|
89
|
+
/** Show success snackbar */
|
|
90
|
+
success: (message: string, duration?: number) => void;
|
|
91
|
+
/** Show error snackbar */
|
|
92
|
+
error: (message: string, duration?: number) => void;
|
|
93
|
+
/** Show warning snackbar */
|
|
94
|
+
warning: (message: string, duration?: number) => void;
|
|
95
|
+
/** Show info snackbar */
|
|
96
|
+
info: (message: string, duration?: number) => void;
|
|
97
|
+
/** Close snackbar */
|
|
98
|
+
close: () => void;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Manage snackbar/toast notification state
|
|
102
|
+
* @param defaultDuration - Default auto-hide duration in ms
|
|
103
|
+
*/
|
|
104
|
+
declare function useSnackbar(defaultDuration?: number): UseSnackbarReturn;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Track a media query match
|
|
108
|
+
* @param query - CSS media query string (e.g., '(min-width: 768px)')
|
|
109
|
+
*/
|
|
110
|
+
declare function useMediaQuery(query: string): boolean;
|
|
111
|
+
declare const useIsMobile: () => boolean;
|
|
112
|
+
declare const useIsTablet: () => boolean;
|
|
113
|
+
declare const useIsDesktop: () => boolean;
|
|
114
|
+
declare const useIsMobileOrTablet: () => boolean;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* useOnClickOutside Hook
|
|
118
|
+
* Detect clicks outside of a referenced element
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
type Handler = (event: MouseEvent | TouchEvent) => void;
|
|
122
|
+
/**
|
|
123
|
+
* Detect clicks outside of a referenced element
|
|
124
|
+
* @param ref - React ref to the element
|
|
125
|
+
* @param handler - Callback when click outside occurs
|
|
126
|
+
* @param enabled - Whether the hook is enabled (default: true)
|
|
127
|
+
*/
|
|
128
|
+
declare function useOnClickOutside<T extends HTMLElement = HTMLElement>(ref: RefObject<T>, handler: Handler, enabled?: boolean): void;
|
|
129
|
+
|
|
130
|
+
interface WindowSize {
|
|
131
|
+
width: number;
|
|
132
|
+
height: number;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Track window dimensions with resize updates
|
|
136
|
+
* @param debounceMs - Debounce resize events (default: 100ms)
|
|
137
|
+
*/
|
|
138
|
+
declare function useWindowSize(debounceMs?: number): WindowSize;
|
|
139
|
+
|
|
140
|
+
declare const index_ApiResponse: typeof ApiResponse;
|
|
141
|
+
declare const index_ApiUrlBuilder: typeof ApiUrlBuilder;
|
|
142
|
+
declare const index_ApiUrlConfig: typeof ApiUrlConfig;
|
|
143
|
+
declare const index_ClientLogger: typeof ClientLogger;
|
|
144
|
+
declare const index_ClientLoggerConfig: typeof ClientLoggerConfig;
|
|
145
|
+
declare const index_EventEmitter: typeof EventEmitter;
|
|
146
|
+
declare const index_HttpClientOptions: typeof HttpClientOptions;
|
|
147
|
+
declare const index_LogLevel: typeof LogLevel;
|
|
148
|
+
declare const index_PaginatedResponse: typeof PaginatedResponse;
|
|
149
|
+
type index_SetValue<T> = SetValue<T>;
|
|
150
|
+
type index_SnackbarSeverity = SnackbarSeverity;
|
|
151
|
+
type index_SnackbarState = SnackbarState;
|
|
152
|
+
type index_ThemeMode = ThemeMode;
|
|
153
|
+
type index_UseCopyToClipboardReturn = UseCopyToClipboardReturn;
|
|
154
|
+
type index_UseLocalStorageOptions<T> = UseLocalStorageOptions<T>;
|
|
155
|
+
type index_UsePageTitleOptions = UsePageTitleOptions;
|
|
156
|
+
type index_UseSnackbarReturn = UseSnackbarReturn;
|
|
157
|
+
type index_WindowSize = WindowSize;
|
|
158
|
+
declare const index_addDays: typeof addDays;
|
|
159
|
+
declare const index_appEvents: typeof appEvents;
|
|
160
|
+
declare const index_camelToKebab: typeof camelToKebab;
|
|
161
|
+
declare const index_capitalize: typeof capitalize;
|
|
162
|
+
declare const index_capitalizeWords: typeof capitalizeWords;
|
|
163
|
+
declare const index_clientLogger: typeof clientLogger;
|
|
164
|
+
declare const index_copyToClipboard: typeof copyToClipboard;
|
|
165
|
+
declare const index_createApiEndpoints: typeof createApiEndpoints;
|
|
166
|
+
declare const index_createApiUrlBuilder: typeof createApiUrlBuilder;
|
|
167
|
+
declare const index_createClientLogger: typeof createClientLogger;
|
|
168
|
+
declare const index_createEmptyPaginationMeta: typeof createEmptyPaginationMeta;
|
|
169
|
+
declare const index_createErrorResponse: typeof createErrorResponse;
|
|
170
|
+
declare const index_createEventEmitter: typeof createEventEmitter;
|
|
171
|
+
declare const index_createHttpClient: typeof createHttpClient;
|
|
172
|
+
declare const index_createSuccessResponse: typeof createSuccessResponse;
|
|
173
|
+
declare const index_endOfDay: typeof endOfDay;
|
|
174
|
+
declare const index_formatDate: typeof formatDate;
|
|
175
|
+
declare const index_formatDateForInput: typeof formatDateForInput;
|
|
176
|
+
declare const index_formatDateTime: typeof formatDateTime;
|
|
177
|
+
declare const index_formatDateTimeForInput: typeof formatDateTimeForInput;
|
|
178
|
+
declare const index_formatRelativeTime: typeof formatRelativeTime;
|
|
179
|
+
declare const index_getErrorMessage: typeof getErrorMessage;
|
|
180
|
+
declare const index_getNextPage: typeof getNextPage;
|
|
181
|
+
declare const index_getPrevPage: typeof getPrevPage;
|
|
182
|
+
declare const index_getResponseData: typeof getResponseData;
|
|
183
|
+
declare const index_hasData: typeof hasData;
|
|
184
|
+
declare const index_hasMorePages: typeof hasMorePages;
|
|
185
|
+
declare const index_isClipboardAvailable: typeof isClipboardAvailable;
|
|
186
|
+
declare const index_isErrorResponse: typeof isErrorResponse;
|
|
187
|
+
declare const index_isForbidden: typeof isForbidden;
|
|
188
|
+
declare const index_isFuture: typeof isFuture;
|
|
189
|
+
declare const index_isNotFound: typeof isNotFound;
|
|
190
|
+
declare const index_isPast: typeof isPast;
|
|
191
|
+
declare const index_isServerError: typeof isServerError;
|
|
192
|
+
declare const index_isStatusError: typeof isStatusError;
|
|
193
|
+
declare const index_isSuccess: typeof isSuccess;
|
|
194
|
+
declare const index_isSuccessResponse: typeof isSuccessResponse;
|
|
195
|
+
declare const index_isToday: typeof isToday;
|
|
196
|
+
declare const index_isUnauthorized: typeof isUnauthorized;
|
|
197
|
+
declare const index_kebabToCamel: typeof kebabToCamel;
|
|
198
|
+
declare const index_parseError: typeof parseError;
|
|
199
|
+
declare const index_parseFullResponse: typeof parseFullResponse;
|
|
200
|
+
declare const index_parseResponse: typeof parseResponse;
|
|
201
|
+
declare const index_readFromClipboard: typeof readFromClipboard;
|
|
202
|
+
declare const index_slugify: typeof slugify;
|
|
203
|
+
declare const index_slugifyUnique: typeof slugifyUnique;
|
|
204
|
+
declare const index_startOfDay: typeof startOfDay;
|
|
205
|
+
declare const index_truncate: typeof truncate;
|
|
206
|
+
declare const index_truncateWords: typeof truncateWords;
|
|
207
|
+
declare const index_unslugify: typeof unslugify;
|
|
208
|
+
declare const index_useCopyToClipboard: typeof useCopyToClipboard;
|
|
209
|
+
declare const index_useDebounce: typeof useDebounce;
|
|
210
|
+
declare const index_useInterval: typeof useInterval;
|
|
211
|
+
declare const index_useIsDesktop: typeof useIsDesktop;
|
|
212
|
+
declare const index_useIsMobile: typeof useIsMobile;
|
|
213
|
+
declare const index_useIsMobileOrTablet: typeof useIsMobileOrTablet;
|
|
214
|
+
declare const index_useIsTablet: typeof useIsTablet;
|
|
215
|
+
declare const index_useLocalStorage: typeof useLocalStorage;
|
|
216
|
+
declare const index_useMediaQuery: typeof useMediaQuery;
|
|
217
|
+
declare const index_useOnClickOutside: typeof useOnClickOutside;
|
|
218
|
+
declare const index_usePageTitle: typeof usePageTitle;
|
|
219
|
+
declare const index_useSnackbar: typeof useSnackbar;
|
|
220
|
+
declare const index_useThemeDetector: typeof useThemeDetector;
|
|
221
|
+
declare const index_useWindowSize: typeof useWindowSize;
|
|
222
|
+
declare const index_withAbortSignal: typeof withAbortSignal;
|
|
223
|
+
declare const index_withFormData: typeof withFormData;
|
|
224
|
+
declare const index_withTimeout: typeof withTimeout;
|
|
225
|
+
declare namespace index {
|
|
226
|
+
export { index_ApiResponse as ApiResponse, index_ApiUrlBuilder as ApiUrlBuilder, index_ApiUrlConfig as ApiUrlConfig, index_ClientLogger as ClientLogger, index_ClientLoggerConfig as ClientLoggerConfig, index_EventEmitter as EventEmitter, index_HttpClientOptions as HttpClientOptions, index_LogLevel as LogLevel, index_PaginatedResponse as PaginatedResponse, type index_SetValue as SetValue, type index_SnackbarSeverity as SnackbarSeverity, type index_SnackbarState as SnackbarState, type index_ThemeMode as ThemeMode, type index_UseCopyToClipboardReturn as UseCopyToClipboardReturn, type index_UseLocalStorageOptions as UseLocalStorageOptions, type index_UsePageTitleOptions as UsePageTitleOptions, type index_UseSnackbarReturn as UseSnackbarReturn, type index_WindowSize as WindowSize, index_addDays as addDays, index_appEvents as appEvents, index_camelToKebab as camelToKebab, index_capitalize as capitalize, index_capitalizeWords as capitalizeWords, index_clientLogger as clientLogger, index_copyToClipboard as copyToClipboard, index_createApiEndpoints as createApiEndpoints, index_createApiUrlBuilder as createApiUrlBuilder, index_createClientLogger as createClientLogger, index_createEmptyPaginationMeta as createEmptyPaginationMeta, index_createErrorResponse as createErrorResponse, index_createEventEmitter as createEventEmitter, index_createHttpClient as createHttpClient, index_createSuccessResponse as createSuccessResponse, index_endOfDay as endOfDay, index_formatDate as formatDate, index_formatDateForInput as formatDateForInput, index_formatDateTime as formatDateTime, index_formatDateTimeForInput as formatDateTimeForInput, index_formatRelativeTime as formatRelativeTime, index_getErrorMessage as getErrorMessage, index_getNextPage as getNextPage, index_getPrevPage as getPrevPage, index_getResponseData as getResponseData, index_hasData as hasData, index_hasMorePages as hasMorePages, index_isClipboardAvailable as isClipboardAvailable, index_isErrorResponse as isErrorResponse, index_isForbidden as isForbidden, index_isFuture as isFuture, index_isNotFound as isNotFound, index_isPast as isPast, index_isServerError as isServerError, index_isStatusError as isStatusError, index_isSuccess as isSuccess, index_isSuccessResponse as isSuccessResponse, index_isToday as isToday, index_isUnauthorized as isUnauthorized, index_kebabToCamel as kebabToCamel, index_parseError as parseError, index_parseFullResponse as parseFullResponse, index_parseResponse as parseResponse, index_readFromClipboard as readFromClipboard, index_slugify as slugify, index_slugifyUnique as slugifyUnique, index_startOfDay as startOfDay, index_truncate as truncate, index_truncateWords as truncateWords, index_unslugify as unslugify, index_useCopyToClipboard as useCopyToClipboard, index_useDebounce as useDebounce, index_useInterval as useInterval, index_useIsDesktop as useIsDesktop, index_useIsMobile as useIsMobile, index_useIsMobileOrTablet as useIsMobileOrTablet, index_useIsTablet as useIsTablet, index_useLocalStorage as useLocalStorage, index_useMediaQuery as useMediaQuery, index_useOnClickOutside as useOnClickOutside, index_usePageTitle as usePageTitle, index_useSnackbar as useSnackbar, index_useThemeDetector as useThemeDetector, index_useWindowSize as useWindowSize, index_withAbortSignal as withAbortSignal, index_withFormData as withFormData, index_withTimeout as withTimeout };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { type SetValue as S, type ThemeMode as T, type UseLocalStorageOptions as U, type WindowSize as W, useDebounce as a, useCopyToClipboard as b, usePageTitle as c, useInterval as d, useThemeDetector as e, useSnackbar as f, useMediaQuery as g, useOnClickOutside as h, index as i, useWindowSize as j, type UseCopyToClipboardReturn as k, type UsePageTitleOptions as l, type SnackbarSeverity as m, type SnackbarState as n, type UseSnackbarReturn as o, useIsMobile as p, useIsTablet as q, useIsDesktop as r, useIsMobileOrTablet as s, useLocalStorage as u };
|