@h3ravel/core 0.2.0 → 0.3.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.
@@ -1,743 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
-
4
- // ../http/src/Middleware.ts
5
- var Middleware = class {
6
- static {
7
- __name(this, "Middleware");
8
- }
9
- };
10
-
11
- // ../http/src/Request.ts
12
- import { getQuery, getRouterParams, readBody } from "h3";
13
-
14
- // ../support/src/Helpers/Obj.ts
15
- function safeDot(data, key) {
16
- if (!key) return data;
17
- return key.split(".").reduce((acc, k) => acc?.[k], data);
18
- }
19
- __name(safeDot, "safeDot");
20
- var setNested = /* @__PURE__ */ __name((obj, key, value) => {
21
- if (!key.includes(".")) {
22
- obj[key] = value;
23
- return;
24
- }
25
- const parts = key.split(".");
26
- let current = obj;
27
- for (let i = 0; i < parts.length; i++) {
28
- const part = parts[i];
29
- if (i === parts.length - 1) {
30
- current[part] = value;
31
- } else {
32
- if (typeof current[part] !== "object" || current[part] === null) {
33
- current[part] = {};
34
- }
35
- current = current[part];
36
- }
37
- }
38
- }, "setNested");
39
-
40
- // ../support/src/Helpers/Str.ts
41
- var afterLast = /* @__PURE__ */ __name((value, search) => {
42
- if (!search) return value;
43
- const lastIndex = value.lastIndexOf(search);
44
- return lastIndex !== -1 ? value.slice(lastIndex + search.length) : value;
45
- }, "afterLast");
46
- var before = /* @__PURE__ */ __name((value, search) => {
47
- if (!search) return value;
48
- const index = value.indexOf(search);
49
- return index !== -1 ? value.slice(0, index) : value;
50
- }, "before");
51
-
52
- // ../http/src/Request.ts
53
- var Request = class {
54
- static {
55
- __name(this, "Request");
56
- }
57
- event;
58
- constructor(event) {
59
- this.event = event;
60
- }
61
- /**
62
- * Get all input data (query + body).
63
- */
64
- async all() {
65
- let data = {
66
- ...getRouterParams(this.event),
67
- ...getQuery(this.event)
68
- };
69
- if (this.event.req.method === "POST") {
70
- data = Object.assign({}, data, Object.fromEntries((await this.event.req.formData()).entries()));
71
- } else if (this.event.req.method === "PUT") {
72
- data = Object.fromEntries(Object.entries(await readBody(this.event)));
73
- }
74
- return data;
75
- }
76
- /**
77
- * Get a single input field from query or body.
78
- */
79
- async input(key, defaultValue) {
80
- const data = await this.all();
81
- return data[key] ?? defaultValue;
82
- }
83
- /**
84
- * Get route parameters.
85
- */
86
- params() {
87
- return getRouterParams(this.event);
88
- }
89
- /**
90
- * Get query parameters.
91
- */
92
- query() {
93
- return getQuery(this.event);
94
- }
95
- getEvent(key) {
96
- return safeDot(this.event, key);
97
- }
98
- };
99
-
100
- // ../http/src/Response.ts
101
- import { html, redirect } from "h3";
102
- var Response = class {
103
- static {
104
- __name(this, "Response");
105
- }
106
- event;
107
- statusCode = 200;
108
- headers = {};
109
- constructor(event) {
110
- this.event = event;
111
- }
112
- /**
113
- * Set HTTP status code.
114
- */
115
- setStatusCode(code) {
116
- this.statusCode = code;
117
- this.event.res.status = code;
118
- return this;
119
- }
120
- /**
121
- * Set a header.
122
- */
123
- setHeader(name, value) {
124
- this.headers[name] = value;
125
- return this;
126
- }
127
- html(content) {
128
- this.applyHeaders();
129
- return html(this.event, content);
130
- }
131
- /**
132
- * Send a JSON response.
133
- */
134
- json(data) {
135
- this.setHeader("content-type", "application/json; charset=utf-8");
136
- this.applyHeaders();
137
- return data;
138
- }
139
- /**
140
- * Send plain text.
141
- */
142
- text(data) {
143
- this.setHeader("content-type", "text/plain; charset=utf-8");
144
- this.applyHeaders();
145
- return data;
146
- }
147
- /**
148
- * Redirect to another URL.
149
- */
150
- redirect(url, status = 302) {
151
- this.setStatusCode(status);
152
- return redirect(this.event, url, this.statusCode);
153
- }
154
- /**
155
- * Apply headers before sending response.
156
- */
157
- applyHeaders() {
158
- Object.entries(this.headers).forEach(([key, value]) => {
159
- this.event.res.headers.set(key, value);
160
- });
161
- }
162
- getEvent(key) {
163
- return safeDot(this.event, key);
164
- }
165
- };
166
-
167
- // ../http/src/Middleware/LogRequests.ts
168
- var LogRequests = class extends Middleware {
169
- static {
170
- __name(this, "LogRequests");
171
- }
172
- async handle({ request }, next) {
173
- const url = request.getEvent("url");
174
- console.log(`[${request.getEvent("method")}] ${url.pathname + url.search}`);
175
- return next();
176
- }
177
- };
178
-
179
- // ../http/src/Providers/HttpServiceProvider.ts
180
- import { H3, serve } from "h3";
181
-
182
- // src/Container.ts
183
- var Container = class {
184
- static {
185
- __name(this, "Container");
186
- }
187
- bindings = /* @__PURE__ */ new Map();
188
- singletons = /* @__PURE__ */ new Map();
189
- bind(key, factory) {
190
- this.bindings.set(key, factory);
191
- }
192
- /**
193
- * Bind a singleton service to the container
194
- */
195
- singleton(key, factory) {
196
- this.bindings.set(key, () => {
197
- if (!this.singletons.has(key)) {
198
- this.singletons.set(key, factory());
199
- }
200
- return this.singletons.get(key);
201
- });
202
- }
203
- /**
204
- * Resolve a service from the container
205
- */
206
- make(key) {
207
- if (this.bindings.has(key)) {
208
- return this.bindings.get(key)();
209
- }
210
- if (typeof key === "function") {
211
- return this.build(key);
212
- }
213
- throw new Error(`No binding found for key: ${typeof key === "string" ? key : key?.name}`);
214
- }
215
- /**
216
- * Automatically build a class with constructor dependency injection
217
- */
218
- build(ClassType) {
219
- const paramTypes = Reflect.getMetadata("design:paramtypes", ClassType) || [];
220
- const dependencies = paramTypes.map((dep) => this.make(dep));
221
- return new ClassType(...dependencies);
222
- }
223
- /**
224
- * Check if a service is registered
225
- */
226
- has(key) {
227
- return this.bindings.has(key);
228
- }
229
- };
230
-
231
- // src/Utils/PathLoader.ts
232
- import nodepath from "path";
233
- var PathLoader = class {
234
- static {
235
- __name(this, "PathLoader");
236
- }
237
- paths = {
238
- base: "",
239
- views: "/src/resources/views",
240
- assets: "/public/assets",
241
- routes: "/src/routes",
242
- config: "/src/config",
243
- public: "/public",
244
- storage: "/src/storage"
245
- };
246
- /**
247
- * Dynamically retrieves a path property from the class.
248
- * Any property ending with "Path" is accessible automatically.
249
- *
250
- * @param name - The base name of the path property
251
- * @param base - The base path to include to the path
252
- * @returns
253
- */
254
- getPath(name, base) {
255
- if (base && name !== "base") {
256
- return nodepath.join(base, this.paths[name]);
257
- }
258
- return this.paths[name];
259
- }
260
- /**
261
- * Programatically set the paths.
262
- *
263
- * @param name - The base name of the path property
264
- * @param path - The new path
265
- * @param base - The base path to include to the path
266
- */
267
- setPath(name, path2, base) {
268
- if (base && name !== "base") {
269
- this.paths[name] = nodepath.join(base, path2);
270
- }
271
- this.paths[name] = path2;
272
- }
273
- };
274
-
275
- // src/Application.ts
276
- import path from "path";
277
- var Application = class _Application extends Container {
278
- static {
279
- __name(this, "Application");
280
- }
281
- paths = new PathLoader();
282
- booted = false;
283
- versions = {
284
- app: "0",
285
- ts: "0"
286
- };
287
- basePath;
288
- providers = [];
289
- externalProviders = [];
290
- constructor(basePath) {
291
- super();
292
- this.basePath = basePath;
293
- this.setPath("base", basePath);
294
- this.loadOptions();
295
- this.registerBaseBindings();
296
- }
297
- /**
298
- * Register core bindings into the container
299
- */
300
- registerBaseBindings() {
301
- this.bind(_Application, () => this);
302
- this.bind("path.base", () => this.basePath);
303
- this.bind("app.paths", () => this.paths);
304
- }
305
- /**
306
- * Dynamically register all configured providers
307
- */
308
- async registerConfiguredProviders() {
309
- const providers = await this.getAllProviders();
310
- for (const ProviderClass of providers) {
311
- if (!ProviderClass) continue;
312
- const provider = new ProviderClass(this);
313
- await this.register(provider);
314
- }
315
- }
316
- async loadOptions() {
317
- const app = await this.safeImport(this.getPath("base", "package.json"));
318
- const core = await this.safeImport("../package.json");
319
- if (app && app.dependencies) {
320
- this.versions.app = app.dependencies["@h3ravel/core"];
321
- }
322
- if (core && core.devDependencies) {
323
- this.versions.ts = app.devDependencies.typescript;
324
- }
325
- }
326
- /**
327
- * Load default and optional providers dynamically
328
- *
329
- * Auto-Registration Behavior
330
- *
331
- * Minimal App: Loads only core, config, http, router by default.
332
- * Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
333
- */
334
- async getConfiguredProviders() {
335
- return [
336
- (await import("./index.js")).AppServiceProvider,
337
- (await import("./src-MGSAHSEB.js")).HttpServiceProvider,
338
- (await import("./src-UIEMS3XE.js")).ConfigServiceProvider,
339
- (await import("./src-ZLODNLLQ.js")).RouteServiceProvider,
340
- (await import("./src-ZLODNLLQ.js")).AssetsServiceProvider,
341
- (await import("./index.js")).ViewServiceProvider,
342
- (await this.safeImport("@h3ravel/database"))?.DatabaseServiceProvider,
343
- (await this.safeImport("@h3ravel/cache"))?.CacheServiceProvider,
344
- (await this.safeImport("@h3ravel/console"))?.ConsoleServiceProvider,
345
- (await this.safeImport("@h3ravel/queue"))?.QueueServiceProvider,
346
- (await this.safeImport("@h3ravel/mail"))?.MailServiceProvider
347
- ];
348
- }
349
- async getAllProviders() {
350
- const coreProviders = await this.getConfiguredProviders();
351
- return [
352
- ...coreProviders,
353
- ...this.externalProviders
354
- ];
355
- }
356
- registerProviders(providers) {
357
- this.externalProviders.push(...providers);
358
- }
359
- /**
360
- * Register a provider
361
- */
362
- async register(provider) {
363
- await provider.register();
364
- this.providers.push(provider);
365
- }
366
- /**
367
- * Boot all providers after registration
368
- */
369
- async boot() {
370
- if (this.booted) return;
371
- for (const provider of this.providers) {
372
- if (provider.boot) {
373
- await provider.boot();
374
- }
375
- }
376
- this.booted = true;
377
- }
378
- /**
379
- * Attempt to dynamically import an optional module
380
- */
381
- async safeImport(moduleName) {
382
- try {
383
- const mod = await import(moduleName);
384
- return mod.default ?? mod;
385
- } catch {
386
- return null;
387
- }
388
- }
389
- /**
390
- * Get the base path of the app
391
- *
392
- * @returns
393
- */
394
- getBasePath() {
395
- return this.basePath;
396
- }
397
- /**
398
- * Dynamically retrieves a path property from the class.
399
- * Any property ending with "Path" is accessible automatically.
400
- *
401
- * @param name - The base name of the path property
402
- * @returns
403
- */
404
- getPath(name, pth) {
405
- return path.join(this.paths.getPath(name, this.basePath), pth ?? "");
406
- }
407
- /**
408
- * Programatically set the paths.
409
- *
410
- * @param name - The base name of the path property
411
- * @param path - The new path
412
- * @returns
413
- */
414
- setPath(name, path2) {
415
- return this.paths.setPath(name, path2, this.basePath);
416
- }
417
- /**
418
- * Returns the installed version of the system core and typescript.
419
- *
420
- * @returns
421
- */
422
- getVersion(key) {
423
- return this.versions[key]?.replaceAll(/\^|\~/g, "");
424
- }
425
- };
426
-
427
- // src/Controller.ts
428
- var Controller = class {
429
- static {
430
- __name(this, "Controller");
431
- }
432
- app;
433
- constructor(app) {
434
- this.app = app;
435
- }
436
- show(_ctx) {
437
- return;
438
- }
439
- index(_ctx) {
440
- return;
441
- }
442
- store(_ctx) {
443
- return;
444
- }
445
- update(_ctx) {
446
- return;
447
- }
448
- destroy(_ctx) {
449
- return;
450
- }
451
- };
452
-
453
- // src/ServiceProvider.ts
454
- var ServiceProvider = class {
455
- static {
456
- __name(this, "ServiceProvider");
457
- }
458
- app;
459
- constructor(app) {
460
- this.app = app;
461
- }
462
- };
463
-
464
- // src/Http/Kernel.ts
465
- var Kernel = class {
466
- static {
467
- __name(this, "Kernel");
468
- }
469
- middleware;
470
- constructor(middleware = []) {
471
- this.middleware = middleware;
472
- }
473
- async handle(event, next) {
474
- const context = {
475
- request: new Request(event),
476
- response: new Response(event)
477
- };
478
- const result = await this.runMiddleware(context, () => next(context));
479
- if (result !== void 0 && this.isPlainObject(result)) {
480
- event.res.headers.set("Content-Type", "application/json; charset=UTF-8");
481
- }
482
- return result;
483
- }
484
- async runMiddleware(context, next) {
485
- let index = -1;
486
- const runner = /* @__PURE__ */ __name(async (i) => {
487
- if (i <= index) throw new Error("next() called multiple times");
488
- index = i;
489
- const middleware = this.middleware[i];
490
- if (middleware) {
491
- return middleware.handle(context, () => runner(i + 1));
492
- } else {
493
- return next(context);
494
- }
495
- }, "runner");
496
- return runner(0);
497
- }
498
- isPlainObject(value) {
499
- return typeof value === "object" && value !== null && (value.constructor === Object || value.constructor === Array);
500
- }
501
- };
502
-
503
- // src/Providers/AppServiceProvider.ts
504
- import "reflect-metadata";
505
- var AppServiceProvider = class extends ServiceProvider {
506
- static {
507
- __name(this, "AppServiceProvider");
508
- }
509
- register() {
510
- }
511
- };
512
-
513
- // src/Providers/ViewServiceProvider.ts
514
- import { Edge } from "edge.js";
515
- var ViewServiceProvider = class extends ServiceProvider {
516
- static {
517
- __name(this, "ViewServiceProvider");
518
- }
519
- register() {
520
- const config = this.app.make("config");
521
- const edge = Edge.create({
522
- cache: process.env.NODE_ENV === "production"
523
- });
524
- edge.mount(this.app.getPath("views"));
525
- edge.global("asset", this.app.make("asset"));
526
- edge.global("config", config.get);
527
- edge.global("app", this.app);
528
- this.app.bind("view", () => edge);
529
- }
530
- };
531
-
532
- // ../http/src/Providers/HttpServiceProvider.ts
533
- var HttpServiceProvider = class extends ServiceProvider {
534
- static {
535
- __name(this, "HttpServiceProvider");
536
- }
537
- register() {
538
- this.app.singleton("http.app", () => {
539
- return new H3();
540
- });
541
- this.app.singleton("http.serve", () => serve);
542
- }
543
- };
544
-
545
- // ../http/src/Resources/JsonResource.ts
546
- var JsonResource = class {
547
- static {
548
- __name(this, "JsonResource");
549
- }
550
- event;
551
- /**
552
- * The request instance
553
- */
554
- request;
555
- /**
556
- * The response instance
557
- */
558
- response;
559
- /**
560
- * The data to send to the client
561
- */
562
- resource;
563
- /**
564
- * The final response data object
565
- */
566
- body = {
567
- data: {}
568
- };
569
- /**
570
- * Flag to track if response should be sent automatically
571
- */
572
- shouldSend = false;
573
- /**
574
- * Flag to track if response has been sent
575
- */
576
- responseSent = false;
577
- /**
578
- * @param req The request instance
579
- * @param res The response instance
580
- * @param rsc The data to send to the client
581
- */
582
- constructor(event, rsc) {
583
- this.event = event;
584
- this.request = event.req;
585
- this.response = event.res;
586
- this.resource = rsc;
587
- for (const key of Object.keys(rsc)) {
588
- if (!(key in this)) {
589
- Object.defineProperty(this, key, {
590
- enumerable: true,
591
- configurable: true,
592
- get: /* @__PURE__ */ __name(() => this.resource[key], "get"),
593
- set: /* @__PURE__ */ __name((value) => {
594
- this.resource[key] = value;
595
- }, "set")
596
- });
597
- }
598
- }
599
- }
600
- /**
601
- * Return the data in the expected format
602
- *
603
- * @returns
604
- */
605
- data() {
606
- return this.resource;
607
- }
608
- /**
609
- * Build the response object
610
- * @returns this
611
- */
612
- json() {
613
- this.shouldSend = true;
614
- this.response.status = 200;
615
- const resource = this.data();
616
- let data = Array.isArray(resource) ? [
617
- ...resource
618
- ] : {
619
- ...resource
620
- };
621
- if (typeof data.data !== "undefined") {
622
- data = data.data;
623
- }
624
- if (!Array.isArray(resource)) {
625
- delete data.pagination;
626
- }
627
- this.body = {
628
- data
629
- };
630
- if (!Array.isArray(resource) && resource.pagination) {
631
- const meta = this.body.meta ?? {};
632
- meta.pagination = resource.pagination;
633
- this.body.meta = meta;
634
- }
635
- if (this.resource.pagination && !this.body.meta?.pagination) {
636
- const meta = this.body.meta ?? {};
637
- meta.pagination = this.resource.pagination;
638
- this.body.meta = meta;
639
- }
640
- return this;
641
- }
642
- /**
643
- * Add context data to the response object
644
- * @param data Context data
645
- * @returns this
646
- */
647
- additional(data) {
648
- this.shouldSend = true;
649
- delete data.data;
650
- delete data.pagination;
651
- this.body = {
652
- ...this.body,
653
- ...data
654
- };
655
- return this;
656
- }
657
- /**
658
- * Send the output to the client
659
- * @returns this
660
- */
661
- send() {
662
- this.shouldSend = false;
663
- if (!this.responseSent) {
664
- this.#send();
665
- }
666
- return this;
667
- }
668
- /**
669
- * Set the status code for this response
670
- * @param code Status code
671
- * @returns this
672
- */
673
- status(code) {
674
- this.response.status = code;
675
- return this;
676
- }
677
- /**
678
- * Private method to send the response
679
- */
680
- #send() {
681
- if (!this.responseSent) {
682
- this.event.context.this.response.json(this.body);
683
- this.responseSent = true;
684
- }
685
- }
686
- /**
687
- * Check if send should be triggered automatically
688
- */
689
- checkSend() {
690
- if (this.shouldSend && !this.responseSent) {
691
- this.#send();
692
- }
693
- }
694
- };
695
-
696
- // ../http/src/Resources/ApiResource.ts
697
- function ApiResource(instance) {
698
- return new Proxy(instance, {
699
- get(target, prop, receiver) {
700
- const value = Reflect.get(target, prop, receiver);
701
- if (typeof value === "function") {
702
- if (prop === "json" || prop === "additional") {
703
- return (...args) => {
704
- const result = value.apply(target, args);
705
- setImmediate(() => target["checkSend"]());
706
- return result;
707
- };
708
- } else if (prop === "send") {
709
- return (...args) => {
710
- target["shouldSend"] = false;
711
- return value.apply(target, args);
712
- };
713
- }
714
- }
715
- return value;
716
- }
717
- });
718
- }
719
- __name(ApiResource, "ApiResource");
720
-
721
- export {
722
- __name,
723
- Container,
724
- PathLoader,
725
- Middleware,
726
- safeDot,
727
- setNested,
728
- afterLast,
729
- before,
730
- Request,
731
- Response,
732
- LogRequests,
733
- HttpServiceProvider,
734
- JsonResource,
735
- ApiResource,
736
- Application,
737
- Controller,
738
- ServiceProvider,
739
- Kernel,
740
- AppServiceProvider,
741
- ViewServiceProvider
742
- };
743
- //# sourceMappingURL=chunk-22XJG4AW.js.map