@cruxjs/base 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Maysara Elshewehy (https://github.com/maysara-elshewehy)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,516 @@
1
+ <!-- ╔══════════════════════════════ BEG ══════════════════════════════╗ -->
2
+
3
+ <br>
4
+ <div align="center">
5
+ <p>
6
+ <img src="./assets/img/logo.png" alt="logo" style="" height="60" />
7
+ </p>
8
+ </div>
9
+
10
+ <div align="center">
11
+ <img src="https://img.shields.io/badge/v-0.0.1-black"/>
12
+ <img src="https://img.shields.io/badge/🔥-@cruxjs-black"/>
13
+ <br>
14
+ <img src="https://img.shields.io/github/issues/crux/base?style=flat" alt="Github Repo Issues" />
15
+ <img src="https://img.shields.io/github/stars/crux/base?style=social" alt="GitHub Repo stars" />
16
+ </div>
17
+ <br>
18
+
19
+ <!-- ╚═════════════════════════════════════════════════════════════════╝ -->
20
+
21
+ <br>
22
+
23
+ - ## Quick Start 🔥
24
+
25
+ > **_Core types and utilities for building CruxJS applications and plugins. A shared foundation for @cruxjs/app and plugin packages._**
26
+
27
+ - ### Overview
28
+
29
+ > `@cruxjs/base` is the **shared foundation** for the entire CruxJS ecosystem. It provides:
30
+
31
+ - **Type Definitions**: Core interfaces for plugins, app configuration, lifecycle management, and routing
32
+
33
+ - **Logger**: Debug-aware logging for CruxJS operations and plugins
34
+
35
+ - **PluginRegistry**: Plugin registration and lifecycle hook management
36
+
37
+ - **ResourceMerger**: Smart merging of routes, schemas, and static configs with user priority
38
+
39
+ > This package enables clean separation between **@cruxjs/app** (the framework) and **@cruxjs-plugins/** (domain-specific plugins), allowing plugins to be created independently without importing the entire app framework.
40
+
41
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
42
+
43
+ - ### Setup
44
+
45
+ > install [`hmm`](https://github.com/minejs-org/hmm) first.
46
+
47
+ ```bash
48
+ hmm i @cruxjs/base
49
+ ```
50
+
51
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
52
+
53
+ - ### Usage
54
+
55
+ - ### 1. Type Definitions (Core Types)
56
+
57
+ > Import shared types for building apps and plugins:
58
+
59
+ ```typescript
60
+ import {
61
+ // App Configuration & Instance
62
+ AppConfig,
63
+ AppInstance,
64
+ AppContext,
65
+ AppMiddleware,
66
+
67
+ // Plugin System
68
+ CruxPlugin,
69
+ MiddlewareExport,
70
+
71
+ // Lifecycle
72
+ LifecycleContext,
73
+ LifecycleHooks,
74
+
75
+ // Routing & Resources
76
+ RouteDefinition,
77
+ StaticConfig,
78
+ TableSchema
79
+ } from '@cruxjs/base'
80
+ ```
81
+
82
+ **Key Types:**
83
+
84
+ ```typescript
85
+ // Plugin Interface - what every plugin must implement
86
+ export interface CruxPlugin {
87
+ name : string
88
+ version : string
89
+
90
+ // Resources the plugin provides
91
+ routes? : RouteDefinition[]
92
+ schemas? : TableSchema[]
93
+ middlewares? : MiddlewareExport[]
94
+ static? : StaticConfig[]
95
+
96
+ // Lifecycle hooks
97
+ onRegister? : (app: AppInstance) => Promise<void>
98
+ onAwake? : (ctx: LifecycleContext) => Promise<void>
99
+ onStart? : (ctx: LifecycleContext) => Promise<void>
100
+ onReady? : (ctx: LifecycleContext) => Promise<void>
101
+ onShutdown? : (ctx: LifecycleContext) => Promise<void>
102
+ }
103
+
104
+ // App Configuration
105
+ export interface AppConfig {
106
+ server?: {
107
+ port? : number
108
+ host? : string
109
+ logging? : boolean | LoggingConfig
110
+ }
111
+ client?: {
112
+ entry : string
113
+ output : string
114
+ minify? : boolean
115
+ sourcemap? : boolean
116
+ }
117
+ database? : DatabaseConfig | DatabaseConfig[]
118
+ i18n? : I18nConfig
119
+ static? : StaticConfig | StaticConfig[]
120
+ api? : ApiConfig
121
+ security? : SecurityConfig
122
+ routes? : RouteDefinition[]
123
+ middlewares? : AppMiddleware[]
124
+ plugins? : CruxPlugin[]
125
+ debug? : boolean
126
+ }
127
+
128
+ // Route Definition
129
+ export interface RouteDefinition {
130
+ method : 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD'
131
+ path : string
132
+ handler : (c: AppContext) => any
133
+ middlewares? : AppMiddleware[]
134
+ }
135
+ ```
136
+
137
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
138
+
139
+ - ### 2. Logger Utility
140
+
141
+ Unified logging for CruxJS operations and plugins with debug mode support:
142
+
143
+ ```typescript
144
+ import { Logger } from '@cruxjs/base'
145
+
146
+ // Initialize logger (second param: debug mode)
147
+ const logger = new Logger(true)
148
+
149
+ // Log lifecycle phases
150
+ logger.phase('Database Setup')
151
+
152
+ // General info logs (only shown in debug mode)
153
+ logger.info('Loading configuration...')
154
+
155
+ // Success logs (only shown in debug mode)
156
+ logger.success('Server running on port 3000')
157
+
158
+ // Error logs (always shown)
159
+ logger.error('Failed to connect to database', err)
160
+
161
+ // Plugin-specific logs
162
+ logger.plugin('@cruxjs-plugins/auth', 'Initializing JWT strategy')
163
+ ```
164
+
165
+ **Output Example:**
166
+ ```
167
+ [CruxJS] ⚡ Phase: Database Setup
168
+ [CruxJS] Loading configuration...
169
+ [CruxJS] ✓ Server running on port 3000
170
+ [CruxJS:@cruxjs-plugins/auth] Initializing JWT strategy
171
+ [CruxJS] ✗ Failed to connect to database
172
+ Error: Connection timeout
173
+ ```
174
+
175
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
176
+
177
+ - ### 3. Plugin Registry
178
+
179
+ Manage plugin registration and lifecycle hooks:
180
+
181
+ ```typescript
182
+ import { PluginRegistry, Logger } from '@cruxjs/base'
183
+ import type { AppInstance, LifecycleContext } from '@cruxjs/base'
184
+
185
+ const logger = new Logger(true)
186
+ const registry = new PluginRegistry(logger)
187
+
188
+ // Register a plugin
189
+ const myPlugin = {
190
+ name: '@cruxjs-plugins/auth',
191
+ version: '1.0.0',
192
+ routes: [{ method: 'POST', path: '/login', handler: (c) => c.json({}) }],
193
+ async onRegister(app: AppInstance) {
194
+ console.log('Plugin registered!')
195
+ }
196
+ }
197
+
198
+ await registry.register(myPlugin, appInstance)
199
+
200
+ // Collect resources from all registered plugins
201
+ const allRoutes = registry.collectRoutes()
202
+ const allSchemas = registry.collectSchemas()
203
+ const allMiddlewares = registry.collectMiddlewares()
204
+ const allStatic = registry.collectStatic()
205
+
206
+ // Call lifecycle hooks across all plugins
207
+ await registry.callHook('onStart', lifecycleContext)
208
+ await registry.callHook('onReady', lifecycleContext)
209
+ ```
210
+
211
+ **Registry Methods:**
212
+
213
+ ```typescript
214
+ // Register a plugin and call its onRegister hook
215
+ register(plugin: CruxPlugin, app: AppInstance): Promise<void>
216
+
217
+ // Get all registered plugins
218
+ getAll(): CruxPlugin[]
219
+
220
+ // Call a lifecycle hook on all plugins that have it
221
+ callHook(hook: 'onAwake' | 'onStart' | 'onReady' | 'onShutdown', ctx: LifecycleContext): Promise<void>
222
+
223
+ // Collect resources from all plugins
224
+ collectRoutes(): RouteDefinition[]
225
+ collectSchemas(): TableSchema[]
226
+ collectMiddlewares(): Map<string, AppMiddleware>
227
+ collectStatic(): StaticConfig[]
228
+ ```
229
+
230
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
231
+
232
+ - ### 4. Resource Merger
233
+
234
+ Intelligently merge routes, schemas, and static configs with user-defined resources taking priority:
235
+
236
+ ```typescript
237
+ import { ResourceMerger, Logger } from '@cruxjs/base'
238
+ import type { RouteDefinition, TableSchema, StaticConfig } from '@cruxjs/base'
239
+
240
+ const logger = new Logger(false)
241
+ const merger = new ResourceMerger(logger)
242
+
243
+ // User routes have priority over plugin routes
244
+ const userRoutes: RouteDefinition[] = [
245
+ { method: 'GET', path: '/api/users', handler: (c) => c.json([]) }
246
+ ]
247
+ const pluginRoutes: RouteDefinition[] = [
248
+ { method: 'GET', path: '/api/users', handler: (c) => c.json({}) },
249
+ { method: 'POST', path: '/api/users', handler: (c) => c.json({}) }
250
+ ]
251
+
252
+ const merged = merger.mergeRoutes(userRoutes, pluginRoutes)
253
+ // Result: GET /api/users uses user handler, POST /api/users uses plugin handler
254
+
255
+ // Same priority system for schemas
256
+ const schemas = merger.mergeSchemas(userSchemas, pluginSchemas)
257
+
258
+ // Static files are simply concatenated
259
+ const statics = merger.mergeStatic(userStatic, pluginStatic)
260
+ ```
261
+
262
+ **Merge Behavior:**
263
+
264
+ | Resource | Priority | Behavior |
265
+ | -------- | ---------- | ------------------------------------------------------- |
266
+ | Routes | User first | Duplicate routes (method + path) override plugin routes |
267
+ | Schemas | User first | Duplicate schemas (by name) override plugin schemas |
268
+ | Static | Both | All configs are included (no deduplication) |
269
+
270
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
271
+
272
+ - ### 5. Creating a Plugin
273
+
274
+ Here's a complete example of creating a plugin using `@cruxjs/base`:
275
+
276
+ ```typescript
277
+ // plugins/auth/index.ts
278
+ import type { CruxPlugin, AppInstance, LifecycleContext } from '@cruxjs/base'
279
+
280
+ export function authPlugin(): CruxPlugin {
281
+ return {
282
+ name: '@cruxjs-plugins/auth',
283
+ version: '1.0.0',
284
+
285
+ // Routes provided by this plugin
286
+ routes: [
287
+ {
288
+ method: 'POST',
289
+ path: '/api/auth/login',
290
+ handler: async (c) => {
291
+ const { email, password } = await c.req.json()
292
+ // Authentication logic
293
+ return c.json({ token: 'jwt-token' })
294
+ }
295
+ },
296
+ {
297
+ method: 'POST',
298
+ path: '/api/auth/logout',
299
+ handler: (c) => c.json({ success: true })
300
+ }
301
+ ],
302
+
303
+ // Database schemas
304
+ schemas: [
305
+ {
306
+ name: 'users',
307
+ columns: [
308
+ { name: 'id', type: 'INTEGER', primaryKey: true },
309
+ { name: 'email', type: 'TEXT', unique: true },
310
+ { name: 'password_hash', type: 'TEXT' }
311
+ ]
312
+ }
313
+ ],
314
+
315
+ // Middleware exports
316
+ middlewares: [
317
+ {
318
+ name: 'authRequired',
319
+ handler: async (c, next) => {
320
+ const token = c.req.header('Authorization')
321
+ if (!token) return c.json({ error: 'Unauthorized' }, 401)
322
+ await next()
323
+ }
324
+ }
325
+ ],
326
+
327
+ // Static files (e.g., docs)
328
+ static: [
329
+ { path: '/auth-docs', directory: './docs/auth' }
330
+ ],
331
+
332
+ // Lifecycle hooks
333
+ async onRegister(app: AppInstance) {
334
+ console.log('Auth plugin registered')
335
+ },
336
+
337
+ async onStart(ctx: LifecycleContext) {
338
+ console.log('Auth plugin started - creating tables...')
339
+ // Initialize database tables
340
+ },
341
+
342
+ async onReady(ctx: LifecycleContext) {
343
+ console.log('Auth plugin ready!')
344
+ }
345
+ }
346
+ }
347
+ ```
348
+
349
+ **Export from your plugin:**
350
+
351
+ ```typescript
352
+ // plugins/auth/package.json
353
+ {
354
+ "name": "@cruxjs-plugins/auth",
355
+ "version": "1.0.0",
356
+ "main": "./dist/index.js",
357
+ "types": "./dist/index.d.ts",
358
+ "exports": {
359
+ ".": {
360
+ "import": "./dist/index.js",
361
+ "types": "./dist/index.d.ts"
362
+ }
363
+ }
364
+ }
365
+ ```
366
+
367
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
368
+
369
+ - ### 6. Using Plugins in @cruxjs/app
370
+
371
+ ```typescript
372
+ import { createApp } from '@cruxjs/app'
373
+ import { authPlugin } from '@cruxjs-plugins/auth'
374
+ import { blogPlugin } from '@cruxjs-plugins/blog'
375
+
376
+ const app = createApp({
377
+ server: { port: 3000 },
378
+ database: { connection: './app.db' },
379
+ plugins: [
380
+ authPlugin(),
381
+ blogPlugin({ defaultLanguage: 'en' })
382
+ ]
383
+ })
384
+
385
+ await app.start()
386
+ ```
387
+
388
+ All plugins are automatically:
389
+ - ✅ Registered with their `onRegister` hooks called
390
+ - ✅ Resources (routes, schemas, middlewares, static) merged intelligently
391
+ - ✅ Lifecycle hooks called in correct sequence
392
+ - ✅ Available in the app instance
393
+
394
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
395
+
396
+ - ### Architecture
397
+
398
+ **The Three-Layer CruxJS Architecture:**
399
+
400
+ ```
401
+ ┌───────────────────────────────────┐
402
+ │ @cruxjs/app (Framework) │
403
+ │ - Creates HTTP server │
404
+ │ - Manages lifecycle │
405
+ │ - Orchestrates plugins │
406
+ └───────────────────────────────────┘
407
+
408
+ ┌───────────────────────────────────┐
409
+ │ @cruxjs-plugins/* (Logic Layer) │
410
+ │ - Business logic │
411
+ │ - API routes & schemas │
412
+ │ - Independent plugins │
413
+ │ (Uses @cruxjs/base types only) │
414
+ └───────────────────────────────────┘
415
+
416
+ ┌───────────────────────────────────┐
417
+ │ @cruxjs-kit/* (UI Layer) │
418
+ │ - JSX components + @mineui style │
419
+ │ - Client-side logic │
420
+ │ - No business logic │
421
+ └───────────────────────────────────┘
422
+ ```
423
+
424
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
425
+
426
+ - ### API Reference
427
+
428
+ - #### Logger
429
+
430
+ ```typescript
431
+ class Logger {
432
+ constructor(debug: boolean = false)
433
+
434
+ phase(name: string): void
435
+ info(msg: string): void
436
+ success(msg: string): void
437
+ error(msg: string, err?: Error): void
438
+ plugin(name: string, msg: string): void
439
+ }
440
+ ```
441
+
442
+ - #### PluginRegistry
443
+
444
+ ```typescript
445
+ class PluginRegistry {
446
+ constructor(logger: Logger)
447
+
448
+ register(plugin: CruxPlugin, app: AppInstance): Promise<void>
449
+ getAll(): CruxPlugin[]
450
+ callHook(hook: HookName, ctx: LifecycleContext): Promise<void>
451
+ collectRoutes(): RouteDefinition[]
452
+ collectSchemas(): TableSchema[]
453
+ collectMiddlewares(): Map<string, AppMiddleware>
454
+ collectStatic(): StaticConfig[]
455
+ }
456
+ ```
457
+
458
+ - #### ResourceMerger
459
+
460
+ ```typescript
461
+ class ResourceMerger {
462
+ constructor(logger: Logger)
463
+
464
+ mergeRoutes(userRoutes?: RouteDefinition[], pluginRoutes?: RouteDefinition[]): RouteDefinition[]
465
+ mergeSchemas(userSchemas?: TableSchema[], pluginSchemas?: TableSchema[]): TableSchema[]
466
+ mergeStatic(userStatic?: StaticConfig[], pluginStatic?: StaticConfig[]): StaticConfig[]
467
+ }
468
+ ```
469
+
470
+ <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
471
+
472
+ - ### FAQ
473
+
474
+ - #### Q: When should I use @cruxjs/base vs @cruxjs/app?
475
+
476
+ - Use `@cruxjs/base` when:
477
+
478
+ > Creating a plugin for the CruxJS ecosystem
479
+
480
+ > You only need types and utilities, not the full framework
481
+
482
+ > You want minimal dependencies in your plugin package
483
+
484
+ - Use `@cruxjs/app` when:
485
+
486
+ > Building a complete CruxJS application
487
+
488
+ > You need to orchestrate plugins and start a server
489
+
490
+ - #### Q: Can I use @cruxjs/base without @cruxjs/app?
491
+
492
+ > Absolutely! `@cruxjs/base` is a standalone package with no dependency on `@cruxjs/app`. Plugins can use it independently.
493
+
494
+ - #### Q: How does resource merging prioritize user-defined resources?
495
+
496
+ > **Routes & Schemas**: User-defined resources override plugins. If both define the same route (method + path) or schema (by name), user wins.
497
+
498
+ > **Static**: All configs are combined without deduplication.
499
+
500
+ - #### Q: What if two plugins define the same route?
501
+
502
+ > The first plugin to register wins. However, if the user defines the same route, the user's definition takes priority. Use the `debug` flag to see what's being merged.
503
+
504
+ <!-- ╚═════════════════════════════════════════════════════════════════╝ -->
505
+
506
+ <!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
507
+
508
+ <br>
509
+
510
+ ---
511
+
512
+ <div align="center">
513
+ <a href="https://github.com/maysara-elshewehy"><img src="https://img.shields.io/badge/by-Maysara-black"/></a>
514
+ </div>
515
+
516
+ <!-- ╚═════════════════════════════════════════════════════════════════╝ -->
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';var g=class{constructor(e=false){this.debug=e;}phase(e){this.debug&&console.log(`
2
+ [CruxJS] \u26A1 Phase: ${e}`);}info(e){this.debug&&console.log(`[CruxJS] ${e}`);}success(e){this.debug&&console.log(`[CruxJS] \u2713 ${e}`);}error(e,t){console.error(`[CruxJS] \u2717 ${e}`),t&&console.error(t);}plugin(e,t){this.debug&&console.log(`[CruxJS:${e}] ${t}`);}};var a=class{constructor(e){this.logger=e;}mergeRoutes(e=[],t=[]){let o=[...e],i=new Set(e.map(s=>`${s.method}:${s.path}`));for(let s of t){let n=`${s.method}:${s.path}`;i.has(n)?this.logger.info(`Skipping plugin route ${n} (overridden by user)`):o.push(s);}return o}mergeSchemas(e=[],t=[]){let o=[...e],i=new Set(e.map(s=>s.name));for(let s of t)i.has(s.name)?this.logger.info(`Skipping plugin schema ${s.name} (overridden by user)`):o.push(s);return o}mergeStatic(e=[],t=[]){return [...e,...t]}};var l=class{constructor(e){this.plugins=[];this.logger=e;}async register(e,t){this.logger.info(`Registering plugin: ${e.name}`),this.plugins.push(e),e.onRegister&&await e.onRegister(t),this.logger.success(`Plugin registered: ${e.name} v${e.version}`);}getAll(){return this.plugins}async callHook(e,t){for(let o of this.plugins)o[e]&&(this.logger.plugin(o.name,`Calling ${e}`),await o[e](t));}collectRoutes(){let e=[];for(let t of this.plugins)t.routes&&(e.push(...t.routes),this.logger.plugin(t.name,`Provided ${t.routes.length} routes`));return e}collectSchemas(){let e=[];for(let t of this.plugins)t.schemas&&(e.push(...t.schemas),this.logger.plugin(t.name,`Provided ${t.schemas.length} schemas`));return e}collectMiddlewares(){let e=new Map;for(let t of this.plugins)if(t.middlewares)for(let o of t.middlewares)e.set(`${t.name}:${o.name}`,o.handler),this.logger.plugin(t.name,`Provided middleware: ${o.name}`);return e}collectStatic(){let e=[];for(let t of this.plugins)t.static&&(e.push(...t.static),this.logger.plugin(t.name,`Provided ${t.static.length} static configs`));return e}};exports.Logger=g;exports.PluginRegistry=l;exports.ResourceMerger=a;//# sourceMappingURL=index.cjs.map
3
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mod/logger.ts","../src/mod/resource_merger.ts","../src/mod/plugin_registry.ts"],"names":["Logger","debug","name","msg","err","ResourceMerger","logger","userRoutes","pluginRoutes","merged","userPaths","r","route","key","userSchemas","pluginSchemas","userTables","schema","userStatic","pluginStatic","PluginRegistry","plugin","app","hook","ctx","routes","schemas","middlewares","mw","statics"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/mod/logger.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class Logger {\r\n constructor(private debug: boolean = false) {}\r\n\r\n phase(name: string) {\r\n if (!this.debug) return;\r\n console.log(`\\n[CruxJS] ⚡ Phase: ${name}`);\r\n }\r\n\r\n info(msg: string) {\r\n if (!this.debug) return;\r\n console.log(`[CruxJS] ${msg}`);\r\n }\r\n\r\n success(msg: string) {\r\n if (!this.debug) return;\r\n console.log(`[CruxJS] ✓ ${msg}`);\r\n }\r\n\r\n error(msg: string, err?: Error) {\r\n console.error(`[CruxJS] ✗ ${msg}`);\r\n if (err) console.error(err);\r\n }\r\n\r\n plugin(name: string, msg: string) {\r\n if (!this.debug) return;\r\n console.log(`[CruxJS:${name}] ${msg}`);\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/resource_merger.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { RouteDefinition, TableSchema, StaticConfig } from '../types';\r\n import { Logger } from './logger';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class ResourceMerger {\r\n private logger: Logger;\r\n\r\n constructor(logger: Logger) {\r\n this.logger = logger;\r\n }\r\n\r\n mergeRoutes(\r\n userRoutes: RouteDefinition[] = [],\r\n pluginRoutes: RouteDefinition[] = []\r\n ): RouteDefinition[] {\r\n // User routes have priority\r\n const merged = [...userRoutes];\r\n const userPaths = new Set(userRoutes.map(r => `${r.method}:${r.path}`));\r\n\r\n for (const route of pluginRoutes) {\r\n const key = `${route.method}:${route.path}`;\r\n\r\n if (!userPaths.has(key)) {\r\n merged.push(route);\r\n } else {\r\n this.logger.info(`Skipping plugin route ${key} (overridden by user)`);\r\n }\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n mergeSchemas(\r\n userSchemas: TableSchema[] = [],\r\n pluginSchemas: TableSchema[] = []\r\n ): TableSchema[] {\r\n // User schemas have priority\r\n const merged = [...userSchemas];\r\n const userTables = new Set(userSchemas.map(s => s.name));\r\n\r\n for (const schema of pluginSchemas) {\r\n if (!userTables.has(schema.name)) {\r\n merged.push(schema);\r\n } else {\r\n this.logger.info(`Skipping plugin schema ${schema.name} (overridden by user)`);\r\n }\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n mergeStatic(\r\n userStatic: StaticConfig[] = [],\r\n pluginStatic: StaticConfig[] = []\r\n ): StaticConfig[] {\r\n return [...userStatic, ...pluginStatic];\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/plugin_registry.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import * as types from '../types';\r\n import { Logger } from './logger';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class PluginRegistry {\r\n private plugins: types.CruxPlugin[] = [];\r\n private logger: Logger;\r\n\r\n constructor(logger: Logger) {\r\n this.logger = logger;\r\n }\r\n\r\n async register(plugin: types.CruxPlugin, app: types.AppInstance) {\r\n this.logger.info(`Registering plugin: ${plugin.name}`);\r\n\r\n this.plugins.push(plugin);\r\n\r\n // Call plugin's onRegister hook\r\n if (plugin.onRegister) {\r\n await plugin.onRegister(app);\r\n }\r\n\r\n this.logger.success(`Plugin registered: ${plugin.name} v${plugin.version}`);\r\n }\r\n\r\n getAll(): types.CruxPlugin[] {\r\n return this.plugins;\r\n }\r\n\r\n async callHook(\r\n hook: keyof Pick<types.CruxPlugin, 'onAwake' | 'onStart' | 'onReady' | 'onShutdown'>,\r\n ctx: types.LifecycleContext\r\n ) {\r\n for (const plugin of this.plugins) {\r\n if (plugin[hook]) {\r\n this.logger.plugin(plugin.name, `Calling ${hook}`);\r\n await plugin[hook]!(ctx);\r\n }\r\n }\r\n }\r\n\r\n collectRoutes(): types.RouteDefinition[] {\r\n const routes: types.RouteDefinition[] = [];\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.routes) {\r\n routes.push(...plugin.routes);\r\n this.logger.plugin(plugin.name, `Provided ${plugin.routes.length} routes`);\r\n }\r\n }\r\n\r\n return routes;\r\n }\r\n\r\n collectSchemas(): types.TableSchema[] {\r\n const schemas: types.TableSchema[] = [];\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.schemas) {\r\n schemas.push(...plugin.schemas);\r\n this.logger.plugin(plugin.name, `Provided ${plugin.schemas.length} schemas`);\r\n }\r\n }\r\n\r\n return schemas;\r\n }\r\n\r\n collectMiddlewares(): Map<string, types.AppMiddleware> {\r\n const middlewares = new Map<string, types.AppMiddleware>();\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.middlewares) {\r\n for (const mw of plugin.middlewares) {\r\n middlewares.set(`${plugin.name}:${mw.name}`, mw.handler);\r\n this.logger.plugin(plugin.name, `Provided middleware: ${mw.name}`);\r\n }\r\n }\r\n }\r\n\r\n return middlewares;\r\n }\r\n\r\n collectStatic(): types.StaticConfig[] {\r\n const statics: types.StaticConfig[] = [];\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.static) {\r\n statics.push(...plugin.static);\r\n this.logger.plugin(plugin.name, `Provided ${plugin.static.length} static configs`);\r\n }\r\n }\r\n\r\n return statics;\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}
@@ -0,0 +1,164 @@
1
+ import { TableSchema as TableSchema$1, DB } from '@minejs/db';
2
+ import { AppContext as AppContext$1 } from '@minejs/server';
3
+
4
+ type AppContext = AppContext$1;
5
+ type TableSchema = TableSchema$1;
6
+ interface CruxPlugin {
7
+ name: string;
8
+ version: string;
9
+ routes?: RouteDefinition[];
10
+ schemas?: TableSchema$1[];
11
+ middlewares?: MiddlewareExport[];
12
+ static?: StaticConfig[];
13
+ onRegister?: (app: AppInstance) => void | Promise<void>;
14
+ onAwake?: (ctx: LifecycleContext) => void | Promise<void>;
15
+ onStart?: (ctx: LifecycleContext) => void | Promise<void>;
16
+ onReady?: (ctx: LifecycleContext) => void | Promise<void>;
17
+ onShutdown?: (ctx: LifecycleContext) => void | Promise<void>;
18
+ }
19
+ interface MiddlewareExport {
20
+ name: string;
21
+ handler: AppMiddleware;
22
+ }
23
+ type AppMiddleware = (c: AppContext$1, next: () => void | Promise<void>) => any;
24
+ interface AppConfig {
25
+ server?: {
26
+ port?: number;
27
+ host?: string;
28
+ logging?: boolean | {
29
+ level?: 'debug' | 'info' | 'warn' | 'error';
30
+ pretty?: boolean;
31
+ };
32
+ };
33
+ client?: {
34
+ entry: string;
35
+ output: string;
36
+ minify?: boolean;
37
+ sourcemap?: boolean;
38
+ target?: 'browser' | 'bun';
39
+ external?: string[];
40
+ };
41
+ database?: {
42
+ connection: string;
43
+ schema?: string;
44
+ name?: string;
45
+ timeout?: number;
46
+ } | {
47
+ connection: string;
48
+ schema?: string;
49
+ name?: string;
50
+ timeout?: number;
51
+ }[];
52
+ i18n?: {
53
+ defaultLanguage: string;
54
+ supportedLanguages: string[];
55
+ basePath: string;
56
+ fileExtension?: string;
57
+ };
58
+ static?: {
59
+ path: string;
60
+ directory: string;
61
+ maxAge?: number;
62
+ index?: string[];
63
+ } | {
64
+ path: string;
65
+ directory: string;
66
+ maxAge?: number;
67
+ index?: string[];
68
+ }[];
69
+ api?: {
70
+ path: string;
71
+ directory: string;
72
+ autoLoad?: boolean;
73
+ };
74
+ security?: {
75
+ cors?: boolean | {
76
+ origin?: string | string[];
77
+ credentials?: boolean;
78
+ maxAge?: number;
79
+ };
80
+ rateLimit?: boolean | {
81
+ windowMs?: number;
82
+ max?: number;
83
+ };
84
+ };
85
+ routes?: RouteDefinition[];
86
+ middlewares?: AppMiddleware[];
87
+ plugins?: CruxPlugin[];
88
+ debug?: boolean;
89
+ }
90
+ interface RouteDefinition {
91
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | ('GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD')[];
92
+ path: string;
93
+ handler: (c: AppContext$1) => any;
94
+ middlewares?: AppMiddleware[];
95
+ }
96
+ interface StaticConfig {
97
+ path: string;
98
+ directory: string;
99
+ maxAge?: number;
100
+ index?: string[];
101
+ }
102
+ interface LifecycleContext {
103
+ config: AppConfig;
104
+ databases: Map<string, DB>;
105
+ plugins: CruxPlugin[];
106
+ server?: any;
107
+ clientBuild?: {
108
+ success: boolean;
109
+ outputs: string[];
110
+ };
111
+ }
112
+ interface LifecycleHooks {
113
+ onConfig?: (config: AppConfig) => AppConfig | Promise<AppConfig>;
114
+ onAwake?: (ctx: LifecycleContext) => void | Promise<void>;
115
+ onStart?: (ctx: LifecycleContext) => void | Promise<void>;
116
+ onReady?: (ctx: LifecycleContext) => void | Promise<void>;
117
+ onFinish?: (ctx: LifecycleContext) => void | Promise<void>;
118
+ onError?: (ctx: LifecycleContext, phase: string, error: Error) => void | Promise<void>;
119
+ }
120
+ interface AppInstance {
121
+ config: AppConfig;
122
+ server: any;
123
+ databases: Map<string, DB>;
124
+ plugins: CruxPlugin[];
125
+ middlewares: Map<string, AppMiddleware>;
126
+ start(): Promise<void>;
127
+ stop(): Promise<void>;
128
+ restart(): Promise<void>;
129
+ getContext(): LifecycleContext;
130
+ getMiddleware(name: string): AppMiddleware | undefined;
131
+ }
132
+
133
+ declare class Logger {
134
+ private debug;
135
+ constructor(debug?: boolean);
136
+ phase(name: string): void;
137
+ info(msg: string): void;
138
+ success(msg: string): void;
139
+ error(msg: string, err?: Error): void;
140
+ plugin(name: string, msg: string): void;
141
+ }
142
+
143
+ declare class ResourceMerger {
144
+ private logger;
145
+ constructor(logger: Logger);
146
+ mergeRoutes(userRoutes?: RouteDefinition[], pluginRoutes?: RouteDefinition[]): RouteDefinition[];
147
+ mergeSchemas(userSchemas?: TableSchema[], pluginSchemas?: TableSchema[]): TableSchema[];
148
+ mergeStatic(userStatic?: StaticConfig[], pluginStatic?: StaticConfig[]): StaticConfig[];
149
+ }
150
+
151
+ declare class PluginRegistry {
152
+ private plugins;
153
+ private logger;
154
+ constructor(logger: Logger);
155
+ register(plugin: CruxPlugin, app: AppInstance): Promise<void>;
156
+ getAll(): CruxPlugin[];
157
+ callHook(hook: keyof Pick<CruxPlugin, 'onAwake' | 'onStart' | 'onReady' | 'onShutdown'>, ctx: LifecycleContext): Promise<void>;
158
+ collectRoutes(): RouteDefinition[];
159
+ collectSchemas(): TableSchema[];
160
+ collectMiddlewares(): Map<string, AppMiddleware>;
161
+ collectStatic(): StaticConfig[];
162
+ }
163
+
164
+ export { type AppConfig, type AppContext, type AppInstance, type AppMiddleware, type CruxPlugin, type LifecycleContext, type LifecycleHooks, Logger, type MiddlewareExport, PluginRegistry, ResourceMerger, type RouteDefinition, type StaticConfig, type TableSchema };
@@ -0,0 +1,164 @@
1
+ import { TableSchema as TableSchema$1, DB } from '@minejs/db';
2
+ import { AppContext as AppContext$1 } from '@minejs/server';
3
+
4
+ type AppContext = AppContext$1;
5
+ type TableSchema = TableSchema$1;
6
+ interface CruxPlugin {
7
+ name: string;
8
+ version: string;
9
+ routes?: RouteDefinition[];
10
+ schemas?: TableSchema$1[];
11
+ middlewares?: MiddlewareExport[];
12
+ static?: StaticConfig[];
13
+ onRegister?: (app: AppInstance) => void | Promise<void>;
14
+ onAwake?: (ctx: LifecycleContext) => void | Promise<void>;
15
+ onStart?: (ctx: LifecycleContext) => void | Promise<void>;
16
+ onReady?: (ctx: LifecycleContext) => void | Promise<void>;
17
+ onShutdown?: (ctx: LifecycleContext) => void | Promise<void>;
18
+ }
19
+ interface MiddlewareExport {
20
+ name: string;
21
+ handler: AppMiddleware;
22
+ }
23
+ type AppMiddleware = (c: AppContext$1, next: () => void | Promise<void>) => any;
24
+ interface AppConfig {
25
+ server?: {
26
+ port?: number;
27
+ host?: string;
28
+ logging?: boolean | {
29
+ level?: 'debug' | 'info' | 'warn' | 'error';
30
+ pretty?: boolean;
31
+ };
32
+ };
33
+ client?: {
34
+ entry: string;
35
+ output: string;
36
+ minify?: boolean;
37
+ sourcemap?: boolean;
38
+ target?: 'browser' | 'bun';
39
+ external?: string[];
40
+ };
41
+ database?: {
42
+ connection: string;
43
+ schema?: string;
44
+ name?: string;
45
+ timeout?: number;
46
+ } | {
47
+ connection: string;
48
+ schema?: string;
49
+ name?: string;
50
+ timeout?: number;
51
+ }[];
52
+ i18n?: {
53
+ defaultLanguage: string;
54
+ supportedLanguages: string[];
55
+ basePath: string;
56
+ fileExtension?: string;
57
+ };
58
+ static?: {
59
+ path: string;
60
+ directory: string;
61
+ maxAge?: number;
62
+ index?: string[];
63
+ } | {
64
+ path: string;
65
+ directory: string;
66
+ maxAge?: number;
67
+ index?: string[];
68
+ }[];
69
+ api?: {
70
+ path: string;
71
+ directory: string;
72
+ autoLoad?: boolean;
73
+ };
74
+ security?: {
75
+ cors?: boolean | {
76
+ origin?: string | string[];
77
+ credentials?: boolean;
78
+ maxAge?: number;
79
+ };
80
+ rateLimit?: boolean | {
81
+ windowMs?: number;
82
+ max?: number;
83
+ };
84
+ };
85
+ routes?: RouteDefinition[];
86
+ middlewares?: AppMiddleware[];
87
+ plugins?: CruxPlugin[];
88
+ debug?: boolean;
89
+ }
90
+ interface RouteDefinition {
91
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | ('GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD')[];
92
+ path: string;
93
+ handler: (c: AppContext$1) => any;
94
+ middlewares?: AppMiddleware[];
95
+ }
96
+ interface StaticConfig {
97
+ path: string;
98
+ directory: string;
99
+ maxAge?: number;
100
+ index?: string[];
101
+ }
102
+ interface LifecycleContext {
103
+ config: AppConfig;
104
+ databases: Map<string, DB>;
105
+ plugins: CruxPlugin[];
106
+ server?: any;
107
+ clientBuild?: {
108
+ success: boolean;
109
+ outputs: string[];
110
+ };
111
+ }
112
+ interface LifecycleHooks {
113
+ onConfig?: (config: AppConfig) => AppConfig | Promise<AppConfig>;
114
+ onAwake?: (ctx: LifecycleContext) => void | Promise<void>;
115
+ onStart?: (ctx: LifecycleContext) => void | Promise<void>;
116
+ onReady?: (ctx: LifecycleContext) => void | Promise<void>;
117
+ onFinish?: (ctx: LifecycleContext) => void | Promise<void>;
118
+ onError?: (ctx: LifecycleContext, phase: string, error: Error) => void | Promise<void>;
119
+ }
120
+ interface AppInstance {
121
+ config: AppConfig;
122
+ server: any;
123
+ databases: Map<string, DB>;
124
+ plugins: CruxPlugin[];
125
+ middlewares: Map<string, AppMiddleware>;
126
+ start(): Promise<void>;
127
+ stop(): Promise<void>;
128
+ restart(): Promise<void>;
129
+ getContext(): LifecycleContext;
130
+ getMiddleware(name: string): AppMiddleware | undefined;
131
+ }
132
+
133
+ declare class Logger {
134
+ private debug;
135
+ constructor(debug?: boolean);
136
+ phase(name: string): void;
137
+ info(msg: string): void;
138
+ success(msg: string): void;
139
+ error(msg: string, err?: Error): void;
140
+ plugin(name: string, msg: string): void;
141
+ }
142
+
143
+ declare class ResourceMerger {
144
+ private logger;
145
+ constructor(logger: Logger);
146
+ mergeRoutes(userRoutes?: RouteDefinition[], pluginRoutes?: RouteDefinition[]): RouteDefinition[];
147
+ mergeSchemas(userSchemas?: TableSchema[], pluginSchemas?: TableSchema[]): TableSchema[];
148
+ mergeStatic(userStatic?: StaticConfig[], pluginStatic?: StaticConfig[]): StaticConfig[];
149
+ }
150
+
151
+ declare class PluginRegistry {
152
+ private plugins;
153
+ private logger;
154
+ constructor(logger: Logger);
155
+ register(plugin: CruxPlugin, app: AppInstance): Promise<void>;
156
+ getAll(): CruxPlugin[];
157
+ callHook(hook: keyof Pick<CruxPlugin, 'onAwake' | 'onStart' | 'onReady' | 'onShutdown'>, ctx: LifecycleContext): Promise<void>;
158
+ collectRoutes(): RouteDefinition[];
159
+ collectSchemas(): TableSchema[];
160
+ collectMiddlewares(): Map<string, AppMiddleware>;
161
+ collectStatic(): StaticConfig[];
162
+ }
163
+
164
+ export { type AppConfig, type AppContext, type AppInstance, type AppMiddleware, type CruxPlugin, type LifecycleContext, type LifecycleHooks, Logger, type MiddlewareExport, PluginRegistry, ResourceMerger, type RouteDefinition, type StaticConfig, type TableSchema };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ var g=class{constructor(e=false){this.debug=e;}phase(e){this.debug&&console.log(`
2
+ [CruxJS] \u26A1 Phase: ${e}`);}info(e){this.debug&&console.log(`[CruxJS] ${e}`);}success(e){this.debug&&console.log(`[CruxJS] \u2713 ${e}`);}error(e,t){console.error(`[CruxJS] \u2717 ${e}`),t&&console.error(t);}plugin(e,t){this.debug&&console.log(`[CruxJS:${e}] ${t}`);}};var a=class{constructor(e){this.logger=e;}mergeRoutes(e=[],t=[]){let o=[...e],i=new Set(e.map(s=>`${s.method}:${s.path}`));for(let s of t){let n=`${s.method}:${s.path}`;i.has(n)?this.logger.info(`Skipping plugin route ${n} (overridden by user)`):o.push(s);}return o}mergeSchemas(e=[],t=[]){let o=[...e],i=new Set(e.map(s=>s.name));for(let s of t)i.has(s.name)?this.logger.info(`Skipping plugin schema ${s.name} (overridden by user)`):o.push(s);return o}mergeStatic(e=[],t=[]){return [...e,...t]}};var l=class{constructor(e){this.plugins=[];this.logger=e;}async register(e,t){this.logger.info(`Registering plugin: ${e.name}`),this.plugins.push(e),e.onRegister&&await e.onRegister(t),this.logger.success(`Plugin registered: ${e.name} v${e.version}`);}getAll(){return this.plugins}async callHook(e,t){for(let o of this.plugins)o[e]&&(this.logger.plugin(o.name,`Calling ${e}`),await o[e](t));}collectRoutes(){let e=[];for(let t of this.plugins)t.routes&&(e.push(...t.routes),this.logger.plugin(t.name,`Provided ${t.routes.length} routes`));return e}collectSchemas(){let e=[];for(let t of this.plugins)t.schemas&&(e.push(...t.schemas),this.logger.plugin(t.name,`Provided ${t.schemas.length} schemas`));return e}collectMiddlewares(){let e=new Map;for(let t of this.plugins)if(t.middlewares)for(let o of t.middlewares)e.set(`${t.name}:${o.name}`,o.handler),this.logger.plugin(t.name,`Provided middleware: ${o.name}`);return e}collectStatic(){let e=[];for(let t of this.plugins)t.static&&(e.push(...t.static),this.logger.plugin(t.name,`Provided ${t.static.length} static configs`));return e}};export{g as Logger,l as PluginRegistry,a as ResourceMerger};//# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mod/logger.ts","../src/mod/resource_merger.ts","../src/mod/plugin_registry.ts"],"names":["Logger","debug","name","msg","err","ResourceMerger","logger","userRoutes","pluginRoutes","merged","userPaths","r","route","key","userSchemas","pluginSchemas","userTables","schema","userStatic","pluginStatic","PluginRegistry","plugin","app","hook","ctx","routes","schemas","middlewares","mw","statics"],"mappings":"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","file":"index.js","sourcesContent":["// src/mod/logger.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class Logger {\r\n constructor(private debug: boolean = false) {}\r\n\r\n phase(name: string) {\r\n if (!this.debug) return;\r\n console.log(`\\n[CruxJS] ⚡ Phase: ${name}`);\r\n }\r\n\r\n info(msg: string) {\r\n if (!this.debug) return;\r\n console.log(`[CruxJS] ${msg}`);\r\n }\r\n\r\n success(msg: string) {\r\n if (!this.debug) return;\r\n console.log(`[CruxJS] ✓ ${msg}`);\r\n }\r\n\r\n error(msg: string, err?: Error) {\r\n console.error(`[CruxJS] ✗ ${msg}`);\r\n if (err) console.error(err);\r\n }\r\n\r\n plugin(name: string, msg: string) {\r\n if (!this.debug) return;\r\n console.log(`[CruxJS:${name}] ${msg}`);\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/resource_merger.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { RouteDefinition, TableSchema, StaticConfig } from '../types';\r\n import { Logger } from './logger';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class ResourceMerger {\r\n private logger: Logger;\r\n\r\n constructor(logger: Logger) {\r\n this.logger = logger;\r\n }\r\n\r\n mergeRoutes(\r\n userRoutes: RouteDefinition[] = [],\r\n pluginRoutes: RouteDefinition[] = []\r\n ): RouteDefinition[] {\r\n // User routes have priority\r\n const merged = [...userRoutes];\r\n const userPaths = new Set(userRoutes.map(r => `${r.method}:${r.path}`));\r\n\r\n for (const route of pluginRoutes) {\r\n const key = `${route.method}:${route.path}`;\r\n\r\n if (!userPaths.has(key)) {\r\n merged.push(route);\r\n } else {\r\n this.logger.info(`Skipping plugin route ${key} (overridden by user)`);\r\n }\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n mergeSchemas(\r\n userSchemas: TableSchema[] = [],\r\n pluginSchemas: TableSchema[] = []\r\n ): TableSchema[] {\r\n // User schemas have priority\r\n const merged = [...userSchemas];\r\n const userTables = new Set(userSchemas.map(s => s.name));\r\n\r\n for (const schema of pluginSchemas) {\r\n if (!userTables.has(schema.name)) {\r\n merged.push(schema);\r\n } else {\r\n this.logger.info(`Skipping plugin schema ${schema.name} (overridden by user)`);\r\n }\r\n }\r\n\r\n return merged;\r\n }\r\n\r\n mergeStatic(\r\n userStatic: StaticConfig[] = [],\r\n pluginStatic: StaticConfig[] = []\r\n ): StaticConfig[] {\r\n return [...userStatic, ...pluginStatic];\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝","// src/mod/plugin_registry.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import * as types from '../types';\r\n import { Logger } from './logger';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class PluginRegistry {\r\n private plugins: types.CruxPlugin[] = [];\r\n private logger: Logger;\r\n\r\n constructor(logger: Logger) {\r\n this.logger = logger;\r\n }\r\n\r\n async register(plugin: types.CruxPlugin, app: types.AppInstance) {\r\n this.logger.info(`Registering plugin: ${plugin.name}`);\r\n\r\n this.plugins.push(plugin);\r\n\r\n // Call plugin's onRegister hook\r\n if (plugin.onRegister) {\r\n await plugin.onRegister(app);\r\n }\r\n\r\n this.logger.success(`Plugin registered: ${plugin.name} v${plugin.version}`);\r\n }\r\n\r\n getAll(): types.CruxPlugin[] {\r\n return this.plugins;\r\n }\r\n\r\n async callHook(\r\n hook: keyof Pick<types.CruxPlugin, 'onAwake' | 'onStart' | 'onReady' | 'onShutdown'>,\r\n ctx: types.LifecycleContext\r\n ) {\r\n for (const plugin of this.plugins) {\r\n if (plugin[hook]) {\r\n this.logger.plugin(plugin.name, `Calling ${hook}`);\r\n await plugin[hook]!(ctx);\r\n }\r\n }\r\n }\r\n\r\n collectRoutes(): types.RouteDefinition[] {\r\n const routes: types.RouteDefinition[] = [];\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.routes) {\r\n routes.push(...plugin.routes);\r\n this.logger.plugin(plugin.name, `Provided ${plugin.routes.length} routes`);\r\n }\r\n }\r\n\r\n return routes;\r\n }\r\n\r\n collectSchemas(): types.TableSchema[] {\r\n const schemas: types.TableSchema[] = [];\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.schemas) {\r\n schemas.push(...plugin.schemas);\r\n this.logger.plugin(plugin.name, `Provided ${plugin.schemas.length} schemas`);\r\n }\r\n }\r\n\r\n return schemas;\r\n }\r\n\r\n collectMiddlewares(): Map<string, types.AppMiddleware> {\r\n const middlewares = new Map<string, types.AppMiddleware>();\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.middlewares) {\r\n for (const mw of plugin.middlewares) {\r\n middlewares.set(`${plugin.name}:${mw.name}`, mw.handler);\r\n this.logger.plugin(plugin.name, `Provided middleware: ${mw.name}`);\r\n }\r\n }\r\n }\r\n\r\n return middlewares;\r\n }\r\n\r\n collectStatic(): types.StaticConfig[] {\r\n const statics: types.StaticConfig[] = [];\r\n\r\n for (const plugin of this.plugins) {\r\n if (plugin.static) {\r\n statics.push(...plugin.static);\r\n this.logger.plugin(plugin.name, `Provided ${plugin.static.length} static configs`);\r\n }\r\n }\r\n\r\n return statics;\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@cruxjs/base",
3
+ "version": "0.0.1",
4
+ "description": "Core types and utilities for building CruxJS applications and plugins. A shared foundation for @cruxjs/app and plugin packages.",
5
+ "keywords": ["cruxjs", "base", "types"],
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/cruxjs-org/base#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/cruxjs-org/base/issues"
10
+ },
11
+ "author": {
12
+ "name": "Maysara",
13
+ "email": "maysara.elshewehy@gmail.com",
14
+ "url": "https://github.com/maysara-elshewehy"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/cruxjs-org/base.git"
19
+ },
20
+ "type": "module",
21
+ "main": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "files": ["dist"],
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js",
28
+ "require": "./dist/index.js"
29
+ }
30
+ },
31
+ "scripts": {
32
+ "build": "tsup",
33
+ "lint": "eslint src --ext .ts",
34
+ "test": "bun test"
35
+ },
36
+ "engines": {
37
+ "bun": ">=1.3.3"
38
+ },
39
+ "peerDependencies": {
40
+ "bun": "^1.3.3"
41
+ },
42
+ "dependencies": {
43
+ "@minejs/db": "^0.0.3",
44
+ "@minejs/server": "^0.0.5"
45
+ },
46
+ "devDependencies": {
47
+ "@eslint/js": "^9.39.2",
48
+ "@stylistic/eslint-plugin": "^5.6.1",
49
+ "@types/bun": "^1.3.5",
50
+ "@types/node": "^20.19.27",
51
+ "bun-plugin-dts": "^0.3.0",
52
+ "bun-types": "^1.3.5",
53
+ "ts-node": "^10.9.2",
54
+ "tsup": "^8.5.1",
55
+ "typescript": "^5.9.3",
56
+ "typescript-eslint": "^8.51.0"
57
+ }
58
+ }