@kumix/utils 0.1.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 +275 -0
- package/dist/index.d.ts +5162 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10763 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-BOB35dQN.js +231 -0
- package/dist/logger-BOB35dQN.js.map +1 -0
- package/dist/server.d.ts +446 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +555 -0
- package/dist/server.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { createConsola } from "consola";
|
|
2
|
+
//#region src/env.ts
|
|
3
|
+
/**
|
|
4
|
+
* Reads an environment variable in a runtime-agnostic way.
|
|
5
|
+
* Tries `process.env` first (Node/Bun), then falls back to `Deno.env`,
|
|
6
|
+
* and finally to the provided fallback value. Failures are swallowed so
|
|
7
|
+
* the function is safe to call in any JavaScript runtime, including
|
|
8
|
+
* Workers where neither global is available.
|
|
9
|
+
*
|
|
10
|
+
* @param key - The name of the environment variable to read
|
|
11
|
+
* @param fallback - Optional value to return when the variable is unset or empty
|
|
12
|
+
* @returns The environment value, or `fallback` if unavailable
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { getEnv } from '@kumix/utils';
|
|
17
|
+
*
|
|
18
|
+
* // Read with a fallback
|
|
19
|
+
* const port = getEnv('PORT', '3000');
|
|
20
|
+
* // Example output: '3000' if PORT is unset
|
|
21
|
+
*
|
|
22
|
+
* // Read optional config
|
|
23
|
+
* const databaseUrl = getEnv('DATABASE_URL');
|
|
24
|
+
* // Example output: 'postgres://...' or undefined
|
|
25
|
+
*
|
|
26
|
+
* // Use across runtimes (Node, Bun, Deno, Workers)
|
|
27
|
+
* const apiKey = getEnv('API_KEY');
|
|
28
|
+
* if (!apiKey) throw new Error('API_KEY is required');
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function getEnv(key, fallback) {
|
|
32
|
+
try {
|
|
33
|
+
if (typeof process !== "undefined" && process.env) return process.env[key] || fallback;
|
|
34
|
+
} catch {}
|
|
35
|
+
try {
|
|
36
|
+
if (typeof Deno !== "undefined") {
|
|
37
|
+
const env = Deno.env;
|
|
38
|
+
if (env && typeof env.get === "function") return env.get(key) || fallback;
|
|
39
|
+
}
|
|
40
|
+
} catch {}
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/constants/development.ts
|
|
45
|
+
/**
|
|
46
|
+
* Development and environment constants
|
|
47
|
+
* Provides environment detection and development-specific configuration values
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Node environment variable
|
|
51
|
+
* Indicates the current environment in which the application is running (e.g., 'development', 'production', 'staging').
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { NODE_ENV } from '@/utils/constants';
|
|
56
|
+
*
|
|
57
|
+
* if (NODE_ENV === 'development') {
|
|
58
|
+
* // Enable dev-only features
|
|
59
|
+
* console.log('Development mode enabled');
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* // Environment-specific configuration
|
|
63
|
+
* const apiUrl = NODE_ENV === 'production'
|
|
64
|
+
* ? 'https://api.kumix.com'
|
|
65
|
+
* : 'http://localhost:3001';
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
const NODE_ENV = getEnv("NODE_ENV");
|
|
69
|
+
/**
|
|
70
|
+
* Checks if the application is running in development mode
|
|
71
|
+
* Useful for enabling development-specific features and debugging.
|
|
72
|
+
*
|
|
73
|
+
* @returns True if NODE_ENV is 'development', false otherwise
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { isDevelopment } from '@/utils/constants';
|
|
78
|
+
*
|
|
79
|
+
* if (isDevelopment) {
|
|
80
|
+
* // Enable hot reloading and dev tools
|
|
81
|
+
* console.log('Development mode enabled');
|
|
82
|
+
* enableDevTools();
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* // Conditional imports
|
|
86
|
+
* if (isDevelopment) {
|
|
87
|
+
* import('./dev-utils').then(devUtils => {
|
|
88
|
+
* devUtils.setupDevEnvironment();
|
|
89
|
+
* });
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
const isDevelopment = NODE_ENV === "development";
|
|
94
|
+
/**
|
|
95
|
+
* Checks if the application is running in staging mode
|
|
96
|
+
* Used for testing production-like environments before deployment.
|
|
97
|
+
*
|
|
98
|
+
* @returns True if NODE_ENV is 'test', false otherwise
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* import { isStaging } from '@/utils/constants';
|
|
103
|
+
*
|
|
104
|
+
* if (isStaging) {
|
|
105
|
+
* // Use staging API endpoints
|
|
106
|
+
* apiUrl = 'https://staging-api.kumix.com';
|
|
107
|
+
* }
|
|
108
|
+
*
|
|
109
|
+
* // Staging-specific analytics
|
|
110
|
+
* const analyticsConfig = {
|
|
111
|
+
* enabled: isStaging || isProduction,
|
|
112
|
+
* debug: isStaging
|
|
113
|
+
* };
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
const isStaging = NODE_ENV === "test";
|
|
117
|
+
/**
|
|
118
|
+
* Checks if the application is running in production mode
|
|
119
|
+
* Used for enabling production optimizations and features.
|
|
120
|
+
*
|
|
121
|
+
* @returns True if NODE_ENV is 'production', false otherwise
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* import { isProduction } from '@/utils/constants';
|
|
126
|
+
*
|
|
127
|
+
* if (isProduction) {
|
|
128
|
+
* // Enable analytics and error tracking
|
|
129
|
+
* enableAnalytics();
|
|
130
|
+
* enableErrorTracking();
|
|
131
|
+
* }
|
|
132
|
+
*
|
|
133
|
+
* // Performance optimizations
|
|
134
|
+
* const shouldMinify = isProduction;
|
|
135
|
+
* const shouldCompress = isProduction;
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
const isProduction = NODE_ENV === "production";
|
|
139
|
+
/**
|
|
140
|
+
* The port number on which the application server runs.
|
|
141
|
+
* Defaults to '3000' if the PORT environment variable is not set.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* app.listen(PORT, () => {
|
|
145
|
+
* console.log(`Server running on port ${PORT}`);
|
|
146
|
+
* });
|
|
147
|
+
*/
|
|
148
|
+
const PORT = getEnv("PORT") || "3000";
|
|
149
|
+
/**
|
|
150
|
+
* The port number on which the api application server runs.
|
|
151
|
+
* Defaults to '3001' if the API_PORT environment variable is not set.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* app.listen(API_PORT, () => {
|
|
155
|
+
* console.log(`Server running on port ${API_PORT}`);
|
|
156
|
+
* });
|
|
157
|
+
*/
|
|
158
|
+
const API_PORT = getEnv("API_PORT") || "3001";
|
|
159
|
+
/**
|
|
160
|
+
* Indicates whether debug mode is enabled (true in development mode).
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* if (DEBUG) {
|
|
164
|
+
* console.log('Debugging enabled');
|
|
165
|
+
* }
|
|
166
|
+
*/
|
|
167
|
+
const DEBUG = !!isDevelopment;
|
|
168
|
+
/**
|
|
169
|
+
* Log level for Consola or other logging libraries.
|
|
170
|
+
* Controls the verbosity of logs output to the console.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* if (LOG_LEVEL === 'debug') {
|
|
174
|
+
* consola.debug('Debugging enabled');
|
|
175
|
+
* }
|
|
176
|
+
*/
|
|
177
|
+
const LOG_LEVEL = getEnv("LOG_LEVEL");
|
|
178
|
+
//#endregion
|
|
179
|
+
//#region src/functions/logging/logger.ts
|
|
180
|
+
/**
|
|
181
|
+
* Centralized logging utility for the application
|
|
182
|
+
* Provides consistent logging interface using Consola with custom formatting
|
|
183
|
+
* Used throughout the application to replace console.log statements
|
|
184
|
+
*/
|
|
185
|
+
/**
|
|
186
|
+
* Application logger instance with consistent formatting
|
|
187
|
+
*
|
|
188
|
+
* Provides structured logging with different levels (info, warn, error, debug)
|
|
189
|
+
* and consistent formatting across the application. Replaces direct console usage.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* import { logger } from '@kumix/utils';
|
|
194
|
+
*
|
|
195
|
+
* // Basic logging
|
|
196
|
+
* logger.info('User logged in successfully');
|
|
197
|
+
* logger.warn('API rate limit approaching');
|
|
198
|
+
* logger.error('Database connection failed');
|
|
199
|
+
* logger.debug('Processing user data', { userId: 123 });
|
|
200
|
+
*
|
|
201
|
+
* // With context data
|
|
202
|
+
* logger.info('User action completed', {
|
|
203
|
+
* userId: user.id,
|
|
204
|
+
* action: 'profile_update',
|
|
205
|
+
* timestamp: new Date().toISOString()
|
|
206
|
+
* });
|
|
207
|
+
*
|
|
208
|
+
* // Error logging with stack trace
|
|
209
|
+
* try {
|
|
210
|
+
* await riskyOperation();
|
|
211
|
+
* } catch (error) {
|
|
212
|
+
* logger.error('Operation failed', { error, context: 'user-service' });
|
|
213
|
+
* }
|
|
214
|
+
*
|
|
215
|
+
* // Performance logging
|
|
216
|
+
* const startTime = Date.now();
|
|
217
|
+
* await someOperation();
|
|
218
|
+
* logger.debug('Operation completed', {
|
|
219
|
+
* duration: Date.now() - startTime,
|
|
220
|
+
* operation: 'data-processing'
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
const logger = createConsola({
|
|
225
|
+
level: isDevelopment ? 5 : LOG_LEVEL ? Number(LOG_LEVEL) : 3,
|
|
226
|
+
formatOptions: { date: false }
|
|
227
|
+
});
|
|
228
|
+
//#endregion
|
|
229
|
+
export { NODE_ENV as a, isProduction as c, LOG_LEVEL as i, isStaging as l, API_PORT as n, PORT as o, DEBUG as r, isDevelopment as s, logger as t, getEnv as u };
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=logger-BOB35dQN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger-BOB35dQN.js","names":[],"sources":["../src/env.ts","../src/constants/development.ts","../src/functions/logging/logger.ts"],"sourcesContent":["/**\n * Runtime-agnostic environment variable reader\n * Provides safe environment variable access across Bun, Node, Deno, and Workers\n * without throwing when the host runtime does not expose `process` or `Deno`.\n */\n\n/** Minimal Deno global shape we rely on (full Deno namespace is not in std types). */\ndeclare const Deno: { env: { get(key: string): string | undefined } } | undefined;\n\n/**\n * Reads an environment variable in a runtime-agnostic way.\n * Tries `process.env` first (Node/Bun), then falls back to `Deno.env`,\n * and finally to the provided fallback value. Failures are swallowed so\n * the function is safe to call in any JavaScript runtime, including\n * Workers where neither global is available.\n *\n * @param key - The name of the environment variable to read\n * @param fallback - Optional value to return when the variable is unset or empty\n * @returns The environment value, or `fallback` if unavailable\n *\n * @example\n * ```ts\n * import { getEnv } from '@kumix/utils';\n *\n * // Read with a fallback\n * const port = getEnv('PORT', '3000');\n * // Example output: '3000' if PORT is unset\n *\n * // Read optional config\n * const databaseUrl = getEnv('DATABASE_URL');\n * // Example output: 'postgres://...' or undefined\n *\n * // Use across runtimes (Node, Bun, Deno, Workers)\n * const apiKey = getEnv('API_KEY');\n * if (!apiKey) throw new Error('API_KEY is required');\n * ```\n */\nexport function getEnv(key: string, fallback?: string): string | undefined {\n try {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[key] || fallback;\n }\n } catch {\n // process.env doesn't exist in Workers\n }\n try {\n if (typeof Deno !== \"undefined\") {\n const env = Deno.env;\n if (env && typeof env.get === \"function\") {\n return env.get(key) || fallback;\n }\n }\n } catch {\n // Deno not available\n }\n return fallback;\n}\n","/**\n * Development and environment constants\n * Provides environment detection and development-specific configuration values\n */\n\nimport { getEnv } from \"../env\";\n\n/**\n * Node environment variable\n * Indicates the current environment in which the application is running (e.g., 'development', 'production', 'staging').\n *\n * @example\n * ```ts\n * import { NODE_ENV } from '@/utils/constants';\n *\n * if (NODE_ENV === 'development') {\n * // Enable dev-only features\n * console.log('Development mode enabled');\n * }\n *\n * // Environment-specific configuration\n * const apiUrl = NODE_ENV === 'production'\n * ? 'https://api.kumix.com'\n * : 'http://localhost:3001';\n * ```\n */\nexport const NODE_ENV = getEnv(\"NODE_ENV\");\n\n/**\n * Checks if the application is running in development mode\n * Useful for enabling development-specific features and debugging.\n *\n * @returns True if NODE_ENV is 'development', false otherwise\n *\n * @example\n * ```ts\n * import { isDevelopment } from '@/utils/constants';\n *\n * if (isDevelopment) {\n * // Enable hot reloading and dev tools\n * console.log('Development mode enabled');\n * enableDevTools();\n * }\n *\n * // Conditional imports\n * if (isDevelopment) {\n * import('./dev-utils').then(devUtils => {\n * devUtils.setupDevEnvironment();\n * });\n * }\n * ```\n */\nexport const isDevelopment = NODE_ENV === \"development\";\n\n/**\n * Checks if the application is running in staging mode\n * Used for testing production-like environments before deployment.\n *\n * @returns True if NODE_ENV is 'test', false otherwise\n *\n * @example\n * ```ts\n * import { isStaging } from '@/utils/constants';\n *\n * if (isStaging) {\n * // Use staging API endpoints\n * apiUrl = 'https://staging-api.kumix.com';\n * }\n *\n * // Staging-specific analytics\n * const analyticsConfig = {\n * enabled: isStaging || isProduction,\n * debug: isStaging\n * };\n * ```\n */\nexport const isStaging = NODE_ENV === \"test\";\n\n/**\n * Checks if the application is running in production mode\n * Used for enabling production optimizations and features.\n *\n * @returns True if NODE_ENV is 'production', false otherwise\n *\n * @example\n * ```ts\n * import { isProduction } from '@/utils/constants';\n *\n * if (isProduction) {\n * // Enable analytics and error tracking\n * enableAnalytics();\n * enableErrorTracking();\n * }\n *\n * // Performance optimizations\n * const shouldMinify = isProduction;\n * const shouldCompress = isProduction;\n * ```\n */\nexport const isProduction = NODE_ENV === \"production\";\n\n/**\n * The port number on which the application server runs.\n * Defaults to '3000' if the PORT environment variable is not set.\n *\n * @example\n * app.listen(PORT, () => {\n * console.log(`Server running on port ${PORT}`);\n * });\n */\nexport const PORT = getEnv(\"PORT\") || \"3000\";\n\n/**\n * The port number on which the api application server runs.\n * Defaults to '3001' if the API_PORT environment variable is not set.\n *\n * @example\n * app.listen(API_PORT, () => {\n * console.log(`Server running on port ${API_PORT}`);\n * });\n */\nexport const API_PORT = getEnv(\"API_PORT\") || \"3001\";\n\n/**\n * Indicates whether debug mode is enabled (true in development mode).\n *\n * @example\n * if (DEBUG) {\n * console.log('Debugging enabled');\n * }\n */\nexport const DEBUG = !!isDevelopment;\n\n/**\n * Log level for Consola or other logging libraries.\n * Controls the verbosity of logs output to the console.\n *\n * @example\n * if (LOG_LEVEL === 'debug') {\n * consola.debug('Debugging enabled');\n * }\n */\nexport const LOG_LEVEL = getEnv(\"LOG_LEVEL\");\n","/**\n * Centralized logging utility for the application\n * Provides consistent logging interface using Consola with custom formatting\n * Used throughout the application to replace console.log statements\n */\n\nimport { createConsola } from \"consola\";\n\nimport { isDevelopment, LOG_LEVEL } from \"../../constants/development\";\n\n/**\n * Application logger instance with consistent formatting\n *\n * Provides structured logging with different levels (info, warn, error, debug)\n * and consistent formatting across the application. Replaces direct console usage.\n *\n * @example\n * ```typescript\n * import { logger } from '@kumix/utils';\n *\n * // Basic logging\n * logger.info('User logged in successfully');\n * logger.warn('API rate limit approaching');\n * logger.error('Database connection failed');\n * logger.debug('Processing user data', { userId: 123 });\n *\n * // With context data\n * logger.info('User action completed', {\n * userId: user.id,\n * action: 'profile_update',\n * timestamp: new Date().toISOString()\n * });\n *\n * // Error logging with stack trace\n * try {\n * await riskyOperation();\n * } catch (error) {\n * logger.error('Operation failed', { error, context: 'user-service' });\n * }\n *\n * // Performance logging\n * const startTime = Date.now();\n * await someOperation();\n * logger.debug('Operation completed', {\n * duration: Date.now() - startTime,\n * operation: 'data-processing'\n * });\n * ```\n */\nexport const logger = createConsola({\n level: isDevelopment ? 5 : LOG_LEVEL ? Number(LOG_LEVEL) : 3,\n formatOptions: {\n date: false,\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,OAAO,KAAa,UAAuC;CACzE,IAAI;EACF,IAAI,OAAO,YAAY,eAAe,QAAQ,KAC5C,OAAO,QAAQ,IAAI,QAAQ;CAE/B,QAAQ,CAER;CACA,IAAI;EACF,IAAI,OAAO,SAAS,aAAa;GAC/B,MAAM,MAAM,KAAK;GACjB,IAAI,OAAO,OAAO,IAAI,QAAQ,YAC5B,OAAO,IAAI,IAAI,GAAG,KAAK;EAE3B;CACF,QAAQ,CAER;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;AC9BA,MAAa,WAAW,OAAO,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;AA0BzC,MAAa,gBAAgB,aAAa;;;;;;;;;;;;;;;;;;;;;;;AAwB1C,MAAa,YAAY,aAAa;;;;;;;;;;;;;;;;;;;;;;AAuBtC,MAAa,eAAe,aAAa;;;;;;;;;;AAWzC,MAAa,OAAO,OAAO,MAAM,KAAK;;;;;;;;;;AAWtC,MAAa,WAAW,OAAO,UAAU,KAAK;;;;;;;;;AAU9C,MAAa,QAAQ,CAAC,CAAC;;;;;;;;;;AAWvB,MAAa,YAAY,OAAO,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7F3C,MAAa,SAAS,cAAc;CAClC,OAAO,gBAAgB,IAAI,YAAY,OAAO,SAAS,IAAI;CAC3D,eAAe,EACb,MAAM,MACR;AACF,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
|
|
3
|
+
//#region src/functions/crypto/generate-random-string.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Utility function for generating cryptographically secure random strings
|
|
6
|
+
* Provides secure random string generation for tokens, IDs, and other security-sensitive uses
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Generates a cryptographically secure random string of specified length
|
|
10
|
+
* Uses Node.js crypto module for secure random number generation
|
|
11
|
+
*
|
|
12
|
+
* @param length - The length of the random string to generate
|
|
13
|
+
* @returns A random string consisting of uppercase letters and numbers
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { generateRandomString } from '@/utils/functions';
|
|
18
|
+
*
|
|
19
|
+
* // Generate a 6-character random string
|
|
20
|
+
* const verificationCode = generateRandomString(6);
|
|
21
|
+
* // Example output: "A7B3C9"
|
|
22
|
+
*
|
|
23
|
+
* // Generate a longer random string for tokens
|
|
24
|
+
* const apiToken = generateRandomString(32);
|
|
25
|
+
* // Example output: "X7F9A2B5C8D1E4F7G0H3I6J9K2L5M8N1"
|
|
26
|
+
*
|
|
27
|
+
* // Use as unique identifiers
|
|
28
|
+
* const uniqueId = generateRandomString(12);
|
|
29
|
+
* // Example output: "B7C9D1E3F5G7"
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function generateRandomString(length: number): string;
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/functions/crypto/jwt.d.ts
|
|
35
|
+
/**
|
|
36
|
+
* Interface for JWT payload data
|
|
37
|
+
*/
|
|
38
|
+
interface JWTPayload {
|
|
39
|
+
/** User ID */
|
|
40
|
+
userId: string;
|
|
41
|
+
/** User email */
|
|
42
|
+
email: string;
|
|
43
|
+
/** User role */
|
|
44
|
+
role?: string;
|
|
45
|
+
/** Workspace ID */
|
|
46
|
+
workspaceId?: string;
|
|
47
|
+
/** Token expiration time (Unix timestamp) */
|
|
48
|
+
exp?: number;
|
|
49
|
+
/** Token issued at time (Unix timestamp) */
|
|
50
|
+
iat?: number;
|
|
51
|
+
/** Additional custom claims */
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
/** For Supabase */
|
|
54
|
+
aud?: string;
|
|
55
|
+
sub?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Interface for JWT options
|
|
59
|
+
*/
|
|
60
|
+
interface JWTOptions {
|
|
61
|
+
/** Token expiration time (default: '7d') */
|
|
62
|
+
expiresIn?: string;
|
|
63
|
+
/** Token issuer */
|
|
64
|
+
issuer?: string;
|
|
65
|
+
/** Token audience */
|
|
66
|
+
audience?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Interface for JWT verification result
|
|
70
|
+
*/
|
|
71
|
+
interface JWTVerificationResult {
|
|
72
|
+
/** Whether the token is valid */
|
|
73
|
+
isValid: boolean;
|
|
74
|
+
/** Decoded payload if valid */
|
|
75
|
+
payload?: JWTPayload;
|
|
76
|
+
/** Error message if verification failed */
|
|
77
|
+
error?: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Generates a JWT token with the provided payload
|
|
81
|
+
*
|
|
82
|
+
* @param payload - The data to encode in the token
|
|
83
|
+
* @param secret - The secret key for signing the token
|
|
84
|
+
* @param options - Token generation options
|
|
85
|
+
* @returns The generated JWT token or null if failed
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* import { generateJWT } from '@kumix/utils';
|
|
90
|
+
*
|
|
91
|
+
* // Basic usage
|
|
92
|
+
* const token = generateJWT(
|
|
93
|
+
* { userId: '123', email: 'user@example.com' },
|
|
94
|
+
* process.env.JWT_SECRET
|
|
95
|
+
* );
|
|
96
|
+
*
|
|
97
|
+
* // With custom expiration
|
|
98
|
+
* const token = generateJWT(
|
|
99
|
+
* { userId: '123', email: 'user@example.com', role: 'admin' },
|
|
100
|
+
* process.env.JWT_SECRET,
|
|
101
|
+
* { expiresIn: '1h' }
|
|
102
|
+
* );
|
|
103
|
+
*
|
|
104
|
+
* // For API authentication
|
|
105
|
+
* const authToken = generateJWT(
|
|
106
|
+
* { userId: user.id, email: user.email, workspaceId: workspace.id },
|
|
107
|
+
* process.env.JWT_SECRET,
|
|
108
|
+
* { expiresIn: '24h', issuer: 'myapp.com' }
|
|
109
|
+
* );
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
declare function generateJWT(payload: JWTPayload, secret: string, options?: JWTOptions): string | null;
|
|
113
|
+
/**
|
|
114
|
+
* Verifies and decodes a JWT token
|
|
115
|
+
*
|
|
116
|
+
* @param token - The JWT token to verify
|
|
117
|
+
* @param secret - The secret key used to sign the token
|
|
118
|
+
* @param options - Verification options
|
|
119
|
+
* @returns Verification result with payload if valid
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* import { verifyJWT } from '@kumix/utils';
|
|
124
|
+
*
|
|
125
|
+
* // Basic usage
|
|
126
|
+
* const result = verifyJWT(token, process.env.JWT_SECRET);
|
|
127
|
+
* if (result.isValid && result.payload) {
|
|
128
|
+
* const { userId, email } = result.payload;
|
|
129
|
+
* // Proceed with authenticated user
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* // With issuer verification
|
|
133
|
+
* const result = verifyJWT(token, process.env.JWT_SECRET, {
|
|
134
|
+
* issuer: 'myapp.com'
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* // In authentication middleware
|
|
138
|
+
* async function authenticateRequest(req, res, next) {
|
|
139
|
+
* const token = req.headers.authorization?.replace('Bearer ', '');
|
|
140
|
+
* const result = verifyJWT(token, process.env.JWT_SECRET);
|
|
141
|
+
*
|
|
142
|
+
* if (!result.isValid) {
|
|
143
|
+
* return res.status(401).json({ error: 'Invalid token' });
|
|
144
|
+
* }
|
|
145
|
+
*
|
|
146
|
+
* req.user = result.payload;
|
|
147
|
+
* next();
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
declare function verifyJWT(token: string, secret: string, options?: {
|
|
152
|
+
issuer?: string;
|
|
153
|
+
audience?: string;
|
|
154
|
+
}): JWTVerificationResult;
|
|
155
|
+
/**
|
|
156
|
+
* Decodes a JWT token without verification (for debugging/inspection)
|
|
157
|
+
*
|
|
158
|
+
* @param token - The JWT token to decode
|
|
159
|
+
* @returns Decoded payload or null if failed
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* import { decodeJWT } from '@kumix/utils';
|
|
164
|
+
*
|
|
165
|
+
* // Inspect token contents without verification
|
|
166
|
+
* const payload = decodeJWT(token);
|
|
167
|
+
* if (payload) {
|
|
168
|
+
* console.log('Token expires at:', new Date(payload.exp * 1000));
|
|
169
|
+
* console.log('User ID:', payload.userId);
|
|
170
|
+
* }
|
|
171
|
+
*
|
|
172
|
+
* // For debugging purposes
|
|
173
|
+
* function debugToken(token: string) {
|
|
174
|
+
* const payload = decodeJWT(token);
|
|
175
|
+
* if (payload) {
|
|
176
|
+
* console.log('Token payload:', payload);
|
|
177
|
+
* } else {
|
|
178
|
+
* console.log('Invalid token format');
|
|
179
|
+
* }
|
|
180
|
+
* }
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
declare function decodeJWT(token: string): JWTPayload | null;
|
|
184
|
+
/**
|
|
185
|
+
* Checks if a JWT token is expired
|
|
186
|
+
*
|
|
187
|
+
* @param token - The JWT token to check
|
|
188
|
+
* @returns True if token is expired, false otherwise
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* import { isJWTExpired } from '@kumix/utils';
|
|
193
|
+
*
|
|
194
|
+
* // Check if token needs refresh
|
|
195
|
+
* if (isJWTExpired(userToken)) {
|
|
196
|
+
* // Redirect to login or refresh token
|
|
197
|
+
* await refreshUserToken();
|
|
198
|
+
* }
|
|
199
|
+
*
|
|
200
|
+
* // In token refresh logic
|
|
201
|
+
* function shouldRefreshToken(token: string): boolean {
|
|
202
|
+
* return isJWTExpired(token);
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
declare function isJWTExpired(token: string): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Gets the remaining time until token expiration
|
|
209
|
+
*
|
|
210
|
+
* @param token - The JWT token to check
|
|
211
|
+
* @returns Remaining time in seconds, or 0 if expired/invalid
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* import { getJWTTimeRemaining } from '@kumix/utils';
|
|
216
|
+
*
|
|
217
|
+
* // Check how much time is left
|
|
218
|
+
* const timeLeft = getJWTTimeRemaining(userToken);
|
|
219
|
+
* if (timeLeft < 300) { // Less than 5 minutes
|
|
220
|
+
* // Show warning about token expiration
|
|
221
|
+
* showTokenExpirationWarning();
|
|
222
|
+
* }
|
|
223
|
+
*
|
|
224
|
+
* // Format time remaining for display
|
|
225
|
+
* function formatTimeRemaining(token: string): string {
|
|
226
|
+
* const seconds = getJWTTimeRemaining(token);
|
|
227
|
+
* const minutes = Math.floor(seconds / 60);
|
|
228
|
+
* const hours = Math.floor(minutes / 60);
|
|
229
|
+
*
|
|
230
|
+
* if (hours > 0) return `${hours}h ${minutes % 60}m`;
|
|
231
|
+
* if (minutes > 0) return `${minutes}m`;
|
|
232
|
+
* return `${seconds}s`;
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
declare function getJWTTimeRemaining(token: string): number;
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/functions/crypto/password.d.ts
|
|
239
|
+
/**
|
|
240
|
+
* Password hashing and verification utilities for SaaS applications
|
|
241
|
+
* Provides secure password handling using bcrypt with proper salt rounds
|
|
242
|
+
* Includes validation and error handling for production use
|
|
243
|
+
*/
|
|
244
|
+
/**
|
|
245
|
+
* Interface for password hashing options
|
|
246
|
+
*/
|
|
247
|
+
interface HashPasswordOptions {
|
|
248
|
+
/** Number of salt rounds for bcrypt (default: 12) */
|
|
249
|
+
saltRounds?: number;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Interface for password verification result
|
|
253
|
+
*/
|
|
254
|
+
interface VerifyPasswordResult {
|
|
255
|
+
/** Whether the password is valid */
|
|
256
|
+
isValid: boolean;
|
|
257
|
+
/** Error message if verification failed */
|
|
258
|
+
error?: string;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Hashes a password using bcrypt with salt
|
|
262
|
+
*
|
|
263
|
+
* @param password - The plain text password to hash
|
|
264
|
+
* @param options - Hashing options
|
|
265
|
+
* @returns Promise that resolves to the hashed password or null if failed
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```typescript
|
|
269
|
+
* import { hashPassword } from '@kumix/utils';
|
|
270
|
+
*
|
|
271
|
+
* // Basic usage
|
|
272
|
+
* const hashedPassword = await hashPassword('userPassword123');
|
|
273
|
+
* if (hashedPassword) {
|
|
274
|
+
* // Store hashedPassword in database
|
|
275
|
+
* await saveUser({ email, password: hashedPassword });
|
|
276
|
+
* }
|
|
277
|
+
*
|
|
278
|
+
* // With custom salt rounds
|
|
279
|
+
* const hashedPassword = await hashPassword('userPassword123', {
|
|
280
|
+
* saltRounds: 14
|
|
281
|
+
* });
|
|
282
|
+
*
|
|
283
|
+
* // Error handling
|
|
284
|
+
* const hashedPassword = await hashPassword('userPassword123');
|
|
285
|
+
* if (!hashedPassword) {
|
|
286
|
+
* throw new Error('Failed to hash password');
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
declare function hashPassword(password: string, options?: HashPasswordOptions): Promise<string | null>;
|
|
291
|
+
/**
|
|
292
|
+
* Verifies a password against its hash
|
|
293
|
+
*
|
|
294
|
+
* @param password - The plain text password to verify
|
|
295
|
+
* @param hashedPassword - The hashed password to compare against
|
|
296
|
+
* @returns Promise that resolves to verification result
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* import { verifyPassword } from '@kumix/utils';
|
|
301
|
+
*
|
|
302
|
+
* // Basic usage
|
|
303
|
+
* const result = await verifyPassword('userPassword123', storedHashedPassword);
|
|
304
|
+
* if (result.isValid) {
|
|
305
|
+
* // Password is correct, proceed with login
|
|
306
|
+
* await loginUser(user);
|
|
307
|
+
* } else {
|
|
308
|
+
* // Password is incorrect
|
|
309
|
+
* throw new Error('Invalid credentials');
|
|
310
|
+
* }
|
|
311
|
+
*
|
|
312
|
+
* // With error handling
|
|
313
|
+
* const result = await verifyPassword('userPassword123', storedHashedPassword);
|
|
314
|
+
* if (result.error) {
|
|
315
|
+
* logger.error('Password verification failed:', result.error);
|
|
316
|
+
* throw new Error('Authentication error');
|
|
317
|
+
* }
|
|
318
|
+
*
|
|
319
|
+
* // In authentication middleware
|
|
320
|
+
* async function authenticateUser(email: string, password: string) {
|
|
321
|
+
* const user = await getUserByEmail(email);
|
|
322
|
+
* if (!user) {
|
|
323
|
+
* return { success: false, error: 'User not found' };
|
|
324
|
+
* }
|
|
325
|
+
*
|
|
326
|
+
* const result = await verifyPassword(password, user.hashedPassword);
|
|
327
|
+
* if (!result.isValid) {
|
|
328
|
+
* return { success: false, error: 'Invalid password' };
|
|
329
|
+
* }
|
|
330
|
+
*
|
|
331
|
+
* return { success: true, user };
|
|
332
|
+
* }
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
declare function verifyPassword(password: string, hashedPassword: string): Promise<VerifyPasswordResult>;
|
|
336
|
+
/**
|
|
337
|
+
* Checks if a password needs to be rehashed (e.g., due to updated salt rounds)
|
|
338
|
+
*
|
|
339
|
+
* @param hashedPassword - The current hashed password
|
|
340
|
+
* @param targetSaltRounds - The target salt rounds (default: 12)
|
|
341
|
+
* @returns Whether the password needs to be rehashed
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```typescript
|
|
345
|
+
* import { needsRehash, hashPassword } from '@kumix/utils';
|
|
346
|
+
*
|
|
347
|
+
* // Check if password needs rehashing during login
|
|
348
|
+
* async function loginUser(email: string, password: string) {
|
|
349
|
+
* const user = await getUserByEmail(email);
|
|
350
|
+
* const result = await verifyPassword(password, user.hashedPassword);
|
|
351
|
+
*
|
|
352
|
+
* if (result.isValid) {
|
|
353
|
+
* // Check if we need to rehash with updated salt rounds
|
|
354
|
+
* if (needsRehash(user.hashedPassword, 14)) {
|
|
355
|
+
* const newHash = await hashPassword(password, { saltRounds: 14 });
|
|
356
|
+
* if (newHash) {
|
|
357
|
+
* await updateUserPassword(user.id, newHash);
|
|
358
|
+
* }
|
|
359
|
+
* }
|
|
360
|
+
*
|
|
361
|
+
* return { success: true, user };
|
|
362
|
+
* }
|
|
363
|
+
*
|
|
364
|
+
* return { success: false, error: 'Invalid credentials' };
|
|
365
|
+
* }
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
declare function needsRehash(hashedPassword: string, targetSaltRounds?: number): boolean;
|
|
369
|
+
/**
|
|
370
|
+
* Generates a secure random password
|
|
371
|
+
*
|
|
372
|
+
* @param length - Length of the password (default: 16, min: 8, max: 128)
|
|
373
|
+
* @param options - Password generation options
|
|
374
|
+
* @returns Generated password string
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* ```typescript
|
|
378
|
+
* import { generateSecurePassword } from '@kumix/utils';
|
|
379
|
+
*
|
|
380
|
+
* // Generate default password (16 characters)
|
|
381
|
+
* const password = generateSecurePassword();
|
|
382
|
+
*
|
|
383
|
+
* // Generate longer password
|
|
384
|
+
* const longPassword = generateSecurePassword(24);
|
|
385
|
+
*
|
|
386
|
+
* // Generate password without symbols
|
|
387
|
+
* const simplePassword = generateSecurePassword(12, {
|
|
388
|
+
* includeSymbols: false
|
|
389
|
+
* });
|
|
390
|
+
*
|
|
391
|
+
* // For temporary passwords
|
|
392
|
+
* const tempPassword = generateSecurePassword(12);
|
|
393
|
+
* await sendPasswordResetEmail(user.email, tempPassword);
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
declare function generateSecurePassword(length?: number, options?: {
|
|
397
|
+
includeUppercase?: boolean;
|
|
398
|
+
includeLowercase?: boolean;
|
|
399
|
+
includeNumbers?: boolean;
|
|
400
|
+
includeSymbols?: boolean;
|
|
401
|
+
}): string;
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/functions/datetime/parse-datetime.d.ts
|
|
404
|
+
/**
|
|
405
|
+
* Utility function for parsing date strings into Date objects
|
|
406
|
+
* Provides natural language date parsing capabilities
|
|
407
|
+
*/
|
|
408
|
+
/**
|
|
409
|
+
* Parses a date string into a Date object using natural language processing
|
|
410
|
+
* Passes through Date objects unchanged
|
|
411
|
+
*
|
|
412
|
+
* @param str - The date string to parse or a Date object to pass through
|
|
413
|
+
* @returns A Date object, or null if parsing fails
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```ts
|
|
417
|
+
* // Parse natural language date strings
|
|
418
|
+
* parseDateTime('tomorrow at 3pm')
|
|
419
|
+
* // Returns a Date object for tomorrow at 3:00 PM
|
|
420
|
+
*
|
|
421
|
+
* // Parse formal date strings
|
|
422
|
+
* parseDateTime('2023-06-15')
|
|
423
|
+
* // Returns a Date object for June 15, 2023
|
|
424
|
+
*
|
|
425
|
+
* // Parse relative dates
|
|
426
|
+
* parseDateTime('next Friday')
|
|
427
|
+
* // Returns a Date object for next Friday
|
|
428
|
+
*
|
|
429
|
+
* // Pass through existing Date objects
|
|
430
|
+
* const date = new Date('2023-06-15')
|
|
431
|
+
* parseDateTime(date)
|
|
432
|
+
* // Returns the same Date object
|
|
433
|
+
*
|
|
434
|
+
* // Parse time strings
|
|
435
|
+
* parseDateTime('3:30pm')
|
|
436
|
+
* // Returns a Date object for today at 3:30 PM
|
|
437
|
+
*
|
|
438
|
+
* // Parse complex date expressions
|
|
439
|
+
* parseDateTime('3 days after next Monday')
|
|
440
|
+
* // Returns the appropriate Date object
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
443
|
+
declare const parseDateTime: (str: Date | string) => Date | null;
|
|
444
|
+
//#endregion
|
|
445
|
+
export { decodeJWT, generateJWT, generateRandomString, generateSecurePassword, getJWTTimeRemaining, hashPassword, isJWTExpired, jwt, needsRehash, parseDateTime, verifyJWT, verifyPassword };
|
|
446
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","names":[],"sources":["../src/functions/crypto/generate-random-string.ts","../src/functions/crypto/jwt.ts","../src/functions/crypto/password.ts","../src/functions/datetime/parse-datetime.ts"],"mappings":";;;;;;AA+BA;;;;AAAmD;;;;ACrBpC;;;;;;;;;;;;;;AAsBV;AAAA;;iBDDW,oBAAA,CAAqB,MAAc;;;AAAA;;;AAAA,UChBzC,UAAA;EAAA;EAER,MAAA;;EAEA,KAAA;EAFA;EAIA,IAAA;EAAA;EAEA,WAAA;EAEA;EAAA,GAAA;EAIC;EAFD,GAAA;EAKA;EAAA,CAHC,GAAA;EAGE;EADH,GAAA;EACA,GAAA;AAAA;;;;UAMQ,UAAA;EAMA;EAJR,SAAA;EAUQ;EARR,MAAA;;EAEA,QAAA;AAAA;;;;UAMQ,qBAAA;EAMH;EAJL,OAAA;EAwCyB;EAtCzB,OAAA,GAAU,UAAU;EAyCI;EAvCxB,KAAA;AAAA;;;;;AAuCwB;AAiF1B;;;;;;;;;;;AAIwB;AAgFxB;;;;AAAoD;AAoCpD;;;;AAA0C;AAuC1C;;;;AAAiD;;iBAnPjC,WAAA,CACd,OAAA,EAAS,UAAA,EACT,MAAA,UACA,OAAA,GAAS,UAAe;;;;;;ACvEd;AAAA;;;;AAUL;AAiCP;;;;;;;;;AAGU;AA4EV;;;;;;;;;AAG+B;AAwE/B;;;;AAEgD;AAgDhD;;iBD/FgB,SAAA,CACd,KAAA,UACA,MAAA,UACA,OAAA;EAAW,MAAA;EAAiB,QAAA;AAAA,IAC3B,qBAAqB;;;;;;ACkGhB;;;;AC5OR;;;;;;;;AAAuD;;;;;;;;;;;iBF0NvC,SAAA,CAAU,KAAA,WAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;iBAoCpC,YAAA,CAAa,KAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuC1B,mBAAA,CAAoB,KAAa;;;;;;ADhTjD;;;;AAAmD;UETzC,mBAAA;;EAER,UAAU;AAAA;;;;UAMF,oBAAA;EDXR;ECaA,OAAA;EDTA;ECWA,KAAK;AAAA;;;;;ADFF;AAAA;;;;;;;;AAYK;AAAA;;;;;;;;;AAYH;AAoCP;;;;;;iBCzBsB,YAAA,CACpB,QAAA,UACA,OAAA,GAAS,mBAAA,GACR,OAAO;;;;ADyBgB;AAiF1B;;;;;;;;;;;AAIwB;AAgFxB;;;;AAAoD;AAoCpD;;;;AAA0C;AAuC1C;;;;AAAiD;;;;;;;;ACvTrC;AAAA;;;;AAUL;iBAgHe,cAAA,CACpB,QAAA,UACA,cAAA,WACC,OAAO,CAAC,oBAAA;;;;;;;;;AA/ED;AA4EV;;;;;;;;;AAG+B;AAwE/B;;;;AAEgD;AAgDhD;;;;;;;;iBAlDgB,WAAA,CACd,cAAA,UACA,gBAA8C;;;AAuDxC;;;;AC5OR;;;;;;;;AAAuD;;;;;;;;;;;;;iBDqOvC,sBAAA,CACd,MAAA,WACA,OAAA;EACE,gBAAA;EACA,gBAAA;EACA,cAAA;EACA,cAAA;AAAA;;;;;;AFtPJ;;;;AAAmD;;;;ACrBpC;;;;;;;;;;;;;;AAsBV;AAAA;;;;;;;;AAYK;AAAA;;;;cEFG,aAAA,GAAiB,GAAA,EAAK,IAAA,cAAgB,IAAI"}
|