@lolyjs/core 0.1.0-alpha.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 (53) hide show
  1. package/README.md +607 -0
  2. package/bin/loly.cjs +6 -0
  3. package/dist/bootstrap-BiCQmSkx.d.mts +50 -0
  4. package/dist/bootstrap-BiCQmSkx.d.ts +50 -0
  5. package/dist/cli.cjs +5186 -0
  6. package/dist/cli.cjs.map +1 -0
  7. package/dist/cli.d.mts +2 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +5181 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/index.cjs +5774 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.d.mts +445 -0
  14. package/dist/index.d.ts +445 -0
  15. package/dist/index.js +5731 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/react/cache.cjs +251 -0
  18. package/dist/react/cache.cjs.map +1 -0
  19. package/dist/react/cache.d.mts +59 -0
  20. package/dist/react/cache.d.ts +59 -0
  21. package/dist/react/cache.js +220 -0
  22. package/dist/react/cache.js.map +1 -0
  23. package/dist/react/components.cjs +218 -0
  24. package/dist/react/components.cjs.map +1 -0
  25. package/dist/react/components.d.mts +26 -0
  26. package/dist/react/components.d.ts +26 -0
  27. package/dist/react/components.js +190 -0
  28. package/dist/react/components.js.map +1 -0
  29. package/dist/react/hooks.cjs +86 -0
  30. package/dist/react/hooks.cjs.map +1 -0
  31. package/dist/react/hooks.d.mts +19 -0
  32. package/dist/react/hooks.d.ts +19 -0
  33. package/dist/react/hooks.js +58 -0
  34. package/dist/react/hooks.js.map +1 -0
  35. package/dist/react/sockets.cjs +43 -0
  36. package/dist/react/sockets.cjs.map +1 -0
  37. package/dist/react/sockets.d.mts +29 -0
  38. package/dist/react/sockets.d.ts +29 -0
  39. package/dist/react/sockets.js +18 -0
  40. package/dist/react/sockets.js.map +1 -0
  41. package/dist/react/themes.cjs +145 -0
  42. package/dist/react/themes.cjs.map +1 -0
  43. package/dist/react/themes.d.mts +13 -0
  44. package/dist/react/themes.d.ts +13 -0
  45. package/dist/react/themes.js +117 -0
  46. package/dist/react/themes.js.map +1 -0
  47. package/dist/runtime.cjs +626 -0
  48. package/dist/runtime.cjs.map +1 -0
  49. package/dist/runtime.d.mts +11 -0
  50. package/dist/runtime.d.ts +11 -0
  51. package/dist/runtime.js +599 -0
  52. package/dist/runtime.js.map +1 -0
  53. package/package.json +101 -0
@@ -0,0 +1,445 @@
1
+ import http from 'http';
2
+ import { Request, Response } from 'express';
3
+ import { Socket, Server } from 'socket.io';
4
+ export { c as bootstrapClient } from './bootstrap-BiCQmSkx.js';
5
+ import { ZodSchema, z } from 'zod';
6
+ import * as express_rate_limit from 'express-rate-limit';
7
+ import pino, { Logger as Logger$1 } from 'pino';
8
+
9
+ /**
10
+ * Framework configuration interface.
11
+ *
12
+ * Allows customization of framework behavior without code changes.
13
+ */
14
+ interface FrameworkConfig {
15
+ directories: {
16
+ app: string;
17
+ build: string;
18
+ static: string;
19
+ };
20
+ conventions: {
21
+ page: string;
22
+ layout: string;
23
+ notFound: string;
24
+ error: string;
25
+ api: string;
26
+ };
27
+ routing: {
28
+ trailingSlash: 'always' | 'never' | 'ignore';
29
+ caseSensitive: boolean;
30
+ basePath: string;
31
+ };
32
+ build: {
33
+ clientBundler: 'rspack' | 'webpack' | 'vite';
34
+ serverBundler: 'esbuild' | 'tsup' | 'swc';
35
+ outputFormat: 'cjs' | 'esm';
36
+ };
37
+ server: {
38
+ adapter: 'express' | 'fastify' | 'koa';
39
+ port: number;
40
+ host: string;
41
+ };
42
+ rendering: {
43
+ framework: 'react' | 'preact' | 'vue' | 'svelte';
44
+ streaming: boolean;
45
+ ssr: boolean;
46
+ ssg: boolean;
47
+ };
48
+ plugins?: any[];
49
+ }
50
+ /**
51
+ * Default framework configuration.
52
+ */
53
+ declare const DEFAULT_CONFIG: FrameworkConfig;
54
+ /**
55
+ * Loads framework configuration from project root.
56
+ *
57
+ * Looks for configuration in the following order:
58
+ * 1. loly.config.ts (TypeScript)
59
+ * 2. loly.config.js (JavaScript)
60
+ * 3. loly.config.json (JSON)
61
+ *
62
+ * Merges user config with defaults and validates.
63
+ *
64
+ * @param projectRoot - Root directory of the project
65
+ * @returns Framework configuration
66
+ */
67
+ declare function loadConfig(projectRoot: string): FrameworkConfig;
68
+ /**
69
+ * Gets the resolved app directory path.
70
+ *
71
+ * @param projectRoot - Root directory of the project
72
+ * @param config - Framework configuration
73
+ * @returns Resolved app directory path
74
+ */
75
+ declare function getAppDir(projectRoot: string, config: FrameworkConfig): string;
76
+ /**
77
+ * Gets the resolved build directory path.
78
+ *
79
+ * @param projectRoot - Root directory of the project
80
+ * @param config - Framework configuration
81
+ * @returns Resolved build directory path
82
+ */
83
+ declare function getBuildDir(projectRoot: string, config: FrameworkConfig): string;
84
+ /**
85
+ * Gets the resolved static directory path.
86
+ *
87
+ * @param projectRoot - Root directory of the project
88
+ * @param config - Framework configuration
89
+ * @returns Resolved static directory path
90
+ */
91
+ declare function getStaticDir(projectRoot: string, config: FrameworkConfig): string;
92
+
93
+ interface StartDevServerOptions {
94
+ port?: number;
95
+ rootDir?: string;
96
+ appDir?: string;
97
+ }
98
+ /**
99
+ * Development server startup.
100
+ * Wrapper around startServer for backward compatibility.
101
+ *
102
+ * @param options - Server options
103
+ */
104
+ declare function startDevServer(options?: StartDevServerOptions): Promise<void>;
105
+ interface StartProdServerOptions {
106
+ port?: number;
107
+ rootDir?: string;
108
+ appDir?: string;
109
+ }
110
+ /**
111
+ * Production server startup.
112
+ * Wrapper around startServer for backward compatibility.
113
+ *
114
+ * @param options - Server options
115
+ */
116
+ declare function startProdServer(options?: StartProdServerOptions): Promise<void>;
117
+
118
+ interface InitServerData {
119
+ server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
120
+ }
121
+
122
+ type GenerateStaticParams = () => Array<Record<string, string>> | Promise<Array<Record<string, string>>>;
123
+ interface ServerContext {
124
+ req: Request;
125
+ res: Response;
126
+ params: Record<string, string>;
127
+ pathname: string;
128
+ locals: Record<string, any>;
129
+ }
130
+ interface WssActions {
131
+ /**
132
+ * Emit an event to all clients in the namespace
133
+ */
134
+ emit: (event: string, ...args: any[]) => void;
135
+ /**
136
+ * Emit an event to a specific socket by Socket.IO socket ID
137
+ */
138
+ emitTo: (socketId: string, event: string, ...args: any[]) => void;
139
+ /**
140
+ * Emit an event to a specific client by custom clientId
141
+ * Requires clientId to be stored in socket.data.clientId during connection
142
+ */
143
+ emitToClient: (clientId: string, event: string, ...args: any[]) => void;
144
+ /**
145
+ * Broadcast an event to all clients in the namespace except the sender
146
+ */
147
+ broadcast: (event: string, ...args: any[]) => void;
148
+ }
149
+ interface WssContext {
150
+ socket: Socket;
151
+ io: Server;
152
+ params: Record<string, string>;
153
+ pathname: string;
154
+ data?: any;
155
+ actions: WssActions;
156
+ }
157
+ type RouteMiddleware = (ctx: ServerContext & {
158
+ theme?: string;
159
+ }, next: () => Promise<void>) => Promise<void> | void;
160
+ interface LoaderResult {
161
+ props?: Record<string, any>;
162
+ redirect?: {
163
+ destination: string;
164
+ permanent?: boolean;
165
+ };
166
+ notFound?: boolean;
167
+ metadata?: PageMetadata | null;
168
+ className?: string;
169
+ theme?: string;
170
+ }
171
+ type ServerLoader = (ctx: ServerContext) => Promise<LoaderResult>;
172
+ interface PageMetadata {
173
+ title?: string;
174
+ description?: string;
175
+ metaTags?: {
176
+ name?: string;
177
+ property?: string;
178
+ content: string;
179
+ }[];
180
+ }
181
+ type MetadataLoader = (ctx: ServerContext) => PageMetadata | Promise<PageMetadata>;
182
+ interface ApiContext {
183
+ req: Request;
184
+ res: Response;
185
+ Response: (body?: any, status?: number) => Response<any, Record<string, any>>;
186
+ NotFound: (body?: any) => Response<any, Record<string, any>>;
187
+ params: Record<string, string>;
188
+ pathname: string;
189
+ locals: Record<string, any>;
190
+ }
191
+ type ApiMiddleware = (ctx: ApiContext, next: () => Promise<void>) => void | Promise<void>;
192
+
193
+ interface ServerConfig {
194
+ bodyLimit?: string;
195
+ corsOrigin?: string | string[] | boolean | ((origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => void);
196
+ rateLimit?: {
197
+ windowMs?: number;
198
+ max?: number;
199
+ apiMax?: number;
200
+ strictMax?: number;
201
+ strictPatterns?: string[];
202
+ };
203
+ security?: {
204
+ contentSecurityPolicy?: boolean | Record<string, any>;
205
+ hsts?: boolean | {
206
+ maxAge?: number;
207
+ includeSubDomains?: boolean;
208
+ };
209
+ };
210
+ }
211
+
212
+ interface BuildAppOptions {
213
+ rootDir?: string;
214
+ appDir?: string;
215
+ config?: FrameworkConfig;
216
+ }
217
+ declare function buildApp(options?: BuildAppOptions): Promise<void>;
218
+
219
+ declare function withCache(fn: any, options: any): any;
220
+
221
+ /**
222
+ * Validation error with detailed information.
223
+ */
224
+ declare class ValidationError extends Error {
225
+ errors: z.ZodIssue[];
226
+ constructor(errors: z.ZodIssue[], message?: string);
227
+ /**
228
+ * Formats validation errors into a user-friendly format.
229
+ */
230
+ format(): Record<string, string[]>;
231
+ }
232
+ /**
233
+ * Validates data against a Zod schema.
234
+ *
235
+ * @param schema - Zod schema to validate against
236
+ * @param data - Data to validate
237
+ * @returns Validated data
238
+ * @throws ValidationError if validation fails
239
+ */
240
+ declare function validate<T>(schema: ZodSchema<T>, data: unknown): T;
241
+ /**
242
+ * Safely validates data and returns a result object.
243
+ *
244
+ * @param schema - Zod schema to validate against
245
+ * @param data - Data to validate
246
+ * @returns Result object with success flag and data/error
247
+ */
248
+ declare function safeValidate<T>(schema: ZodSchema<T>, data: unknown): {
249
+ success: true;
250
+ data: T;
251
+ } | {
252
+ success: false;
253
+ error: ValidationError;
254
+ };
255
+ /**
256
+ * Common validation schemas for reuse.
257
+ */
258
+ declare const commonSchemas: {
259
+ /**
260
+ * Validates a string parameter (e.g., route params).
261
+ */
262
+ stringParam: z.ZodString;
263
+ /**
264
+ * Validates an optional string parameter.
265
+ */
266
+ optionalStringParam: z.ZodOptional<z.ZodString>;
267
+ /**
268
+ * Validates a numeric ID parameter.
269
+ */
270
+ idParam: z.ZodEffects<z.ZodString, number, string>;
271
+ /**
272
+ * Validates a UUID parameter.
273
+ */
274
+ uuidParam: z.ZodString;
275
+ /**
276
+ * Validates pagination parameters.
277
+ */
278
+ pagination: z.ZodObject<{
279
+ page: z.ZodDefault<z.ZodEffects<z.ZodString, number, string>>;
280
+ limit: z.ZodDefault<z.ZodEffects<z.ZodString, number, string>>;
281
+ }, "strip", z.ZodTypeAny, {
282
+ page: number;
283
+ limit: number;
284
+ }, {
285
+ page?: string | undefined;
286
+ limit?: string | undefined;
287
+ }>;
288
+ /**
289
+ * Validates a search query parameter.
290
+ */
291
+ searchQuery: z.ZodOptional<z.ZodString>;
292
+ };
293
+
294
+ /**
295
+ * Security utilities for input sanitization.
296
+ */
297
+ /**
298
+ * Sanitizes a string by removing potentially dangerous characters.
299
+ * Basic sanitization - for production, consider using a library like DOMPurify.
300
+ *
301
+ * @param input - String to sanitize
302
+ * @returns Sanitized string
303
+ */
304
+ declare function sanitizeString(input: string): string;
305
+ /**
306
+ * Sanitizes an object by recursively sanitizing all string values.
307
+ *
308
+ * @param obj - Object to sanitize
309
+ * @returns Sanitized object
310
+ */
311
+ declare function sanitizeObject<T extends Record<string, any>>(obj: T): T;
312
+ /**
313
+ * Sanitizes route parameters.
314
+ *
315
+ * @param params - Route parameters object
316
+ * @returns Sanitized parameters
317
+ */
318
+ declare function sanitizeParams<T extends Record<string, string | string[]>>(params: T): T;
319
+ /**
320
+ * Sanitizes query parameters.
321
+ *
322
+ * @param query - Query parameters object
323
+ * @returns Sanitized query parameters
324
+ */
325
+ declare function sanitizeQuery<T extends Record<string, any>>(query: T): T;
326
+
327
+ interface RateLimitConfig {
328
+ windowMs?: number;
329
+ max?: number;
330
+ message?: string;
331
+ standardHeaders?: boolean;
332
+ legacyHeaders?: boolean;
333
+ skipSuccessfulRequests?: boolean;
334
+ skipFailedRequests?: boolean;
335
+ }
336
+ /**
337
+ * Creates a rate limiter middleware with configurable options.
338
+ *
339
+ * @param config - Rate limiting configuration
340
+ * @returns Express rate limit middleware
341
+ */
342
+ declare function createRateLimiter(config?: RateLimitConfig): express_rate_limit.RateLimitRequestHandler;
343
+ /**
344
+ * Default rate limiter for general API routes.
345
+ * Limits: 100 requests per 15 minutes per IP
346
+ */
347
+ declare const defaultRateLimiter: express_rate_limit.RateLimitRequestHandler;
348
+ /**
349
+ * Strict rate limiter for authentication and sensitive endpoints.
350
+ * Limits: 5 requests per 15 minutes per IP
351
+ */
352
+ declare const strictRateLimiter: express_rate_limit.RateLimitRequestHandler;
353
+ /**
354
+ * Lenient rate limiter for public pages.
355
+ * Limits: 200 requests per 15 minutes per IP
356
+ */
357
+ declare const lenientRateLimiter: express_rate_limit.RateLimitRequestHandler;
358
+
359
+ type LogLevel = "fatal" | "error" | "warn" | "info" | "debug" | "trace";
360
+ interface LoggerContext {
361
+ [key: string]: unknown;
362
+ }
363
+ interface LoggerOptions {
364
+ level?: LogLevel;
365
+ enabled?: boolean;
366
+ pretty?: boolean;
367
+ destination?: pino.DestinationStream;
368
+ }
369
+ /**
370
+ * Gets or creates the singleton logger instance.
371
+ */
372
+ declare function getLogger(options?: LoggerOptions): Logger$1;
373
+ /**
374
+ * Sets a custom logger instance (useful for testing or custom configuration).
375
+ */
376
+ declare function setLogger(customLogger: Logger$1): void;
377
+ /**
378
+ * Resets the logger instance (useful for testing).
379
+ */
380
+ declare function resetLogger(): void;
381
+ /**
382
+ * Logger class wrapper for easier usage with context.
383
+ */
384
+ declare class Logger {
385
+ private pino;
386
+ private context;
387
+ constructor(logger?: Logger$1, context?: LoggerContext);
388
+ /**
389
+ * Creates a child logger with additional context.
390
+ */
391
+ child(context: LoggerContext): Logger;
392
+ /**
393
+ * Logs a fatal error (application should terminate).
394
+ */
395
+ fatal(message: string, context?: LoggerContext): void;
396
+ /**
397
+ * Logs an error.
398
+ */
399
+ error(message: string, error?: Error | unknown, context?: LoggerContext): void;
400
+ /**
401
+ * Logs a warning.
402
+ */
403
+ warn(message: string, context?: LoggerContext): void;
404
+ /**
405
+ * Logs informational message.
406
+ */
407
+ info(message: string, context?: LoggerContext): void;
408
+ /**
409
+ * Logs a debug message (only in development or when level is debug).
410
+ */
411
+ debug(message: string, context?: LoggerContext): void;
412
+ /**
413
+ * Logs a trace message (most verbose).
414
+ */
415
+ trace(message: string, context?: LoggerContext): void;
416
+ }
417
+ /**
418
+ * Default logger instance.
419
+ */
420
+ declare const logger: Logger;
421
+ /**
422
+ * Creates a logger for a specific module/component.
423
+ */
424
+ declare function createModuleLogger(module: string, context?: LoggerContext): Logger;
425
+ /**
426
+ * Generates a unique request ID for request tracking.
427
+ */
428
+ declare function generateRequestId(): string;
429
+ /**
430
+ * Express middleware for request logging.
431
+ * Adds request ID to res.locals and logs incoming requests.
432
+ */
433
+ declare function requestLoggerMiddleware(options?: {
434
+ logger?: Logger;
435
+ logRequests?: boolean;
436
+ logResponses?: boolean;
437
+ ignorePaths?: (string | RegExp)[];
438
+ logStaticAssets?: boolean;
439
+ }): (req: Request, res: Response, next: () => void) => void;
440
+ /**
441
+ * Gets the logger from the request object (set by requestLoggerMiddleware).
442
+ */
443
+ declare function getRequestLogger(req: Request): Logger;
444
+
445
+ export { type ApiContext, type ApiMiddleware, DEFAULT_CONFIG, type FrameworkConfig, type GenerateStaticParams, type InitServerData, type LoaderResult, type LogLevel, Logger, type LoggerContext, type LoggerOptions, type MetadataLoader, type RouteMiddleware, type ServerConfig, type ServerContext, type ServerLoader, ValidationError, type WssContext, buildApp, commonSchemas, createModuleLogger, createRateLimiter, defaultRateLimiter, generateRequestId, getAppDir, getBuildDir, getLogger, getRequestLogger, getStaticDir, lenientRateLimiter, loadConfig, logger, requestLoggerMiddleware, resetLogger, safeValidate, sanitizeObject, sanitizeParams, sanitizeQuery, sanitizeString, setLogger, startDevServer, startProdServer, strictRateLimiter, validate, withCache };