h3ravel-monorepo 0.1.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.
Files changed (176) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.github/workflows/release.yml +42 -0
  4. package/.husky/pre-commit +1 -0
  5. package/LICENSE +21 -0
  6. package/README.md +65 -0
  7. package/docs/.gitkeep +0 -0
  8. package/eslint.config.js +17 -0
  9. package/examples/basic-app/.env.example +54 -0
  10. package/examples/basic-app/package.json +27 -0
  11. package/examples/basic-app/public/h3ravel-logo.svg +23 -0
  12. package/examples/basic-app/public/main.js +13 -0
  13. package/examples/basic-app/src/Exceptions/.gitkeep +0 -0
  14. package/examples/basic-app/src/config/app.ts +125 -0
  15. package/examples/basic-app/src/config/filesystem.ts +59 -0
  16. package/examples/basic-app/src/http/controllers/HomeController.ts +17 -0
  17. package/examples/basic-app/src/http/controllers/UserController.ts +29 -0
  18. package/examples/basic-app/src/http/middlewares/AuthMiddleware.ts +8 -0
  19. package/examples/basic-app/src/index.ts +30 -0
  20. package/examples/basic-app/src/resources/views/index.edge +383 -0
  21. package/examples/basic-app/src/routes/api.ts +17 -0
  22. package/examples/basic-app/src/routes/web.ts +6 -0
  23. package/examples/basic-app/src/storage/app/public/.gitkeep +0 -0
  24. package/examples/basic-app/tsconfig.json +8 -0
  25. package/package.json +36 -0
  26. package/packages/cache/node_modules/.bin/tsc +21 -0
  27. package/packages/cache/node_modules/.bin/tsserver +21 -0
  28. package/packages/cache/package.json +26 -0
  29. package/packages/cache/src/CacheManager.ts +1 -0
  30. package/packages/cache/src/Contracts/.gitkeep +0 -0
  31. package/packages/cache/src/Drivers/MemoryCache.ts +1 -0
  32. package/packages/cache/src/Drivers/RedisCache.ts +1 -0
  33. package/packages/cache/src/Helpers.ts +1 -0
  34. package/packages/cache/src/Providers/CacheServiceProvider.ts +16 -0
  35. package/packages/cache/src/index.ts +9 -0
  36. package/packages/cache/tests/.gitkeep +0 -0
  37. package/packages/cache/tsconfig.json +9 -0
  38. package/packages/cache/vite.config.ts +9 -0
  39. package/packages/config/node_modules/.bin/tsc +21 -0
  40. package/packages/config/node_modules/.bin/tsserver +21 -0
  41. package/packages/config/package.json +34 -0
  42. package/packages/config/src/ConfigRepository.ts +51 -0
  43. package/packages/config/src/Contracts/.gitkeep +0 -0
  44. package/packages/config/src/EnvLoader.ts +16 -0
  45. package/packages/config/src/Helpers.ts +1 -0
  46. package/packages/config/src/Providers/ConfigServiceProvider.ts +46 -0
  47. package/packages/config/src/index.ts +8 -0
  48. package/packages/config/tests/.gitkeep +0 -0
  49. package/packages/config/tsconfig.json +8 -0
  50. package/packages/config/vite.config.ts +9 -0
  51. package/packages/console/node_modules/.bin/tsc +21 -0
  52. package/packages/console/node_modules/.bin/tsserver +21 -0
  53. package/packages/console/package.json +26 -0
  54. package/packages/console/src/Commands/MakeController.ts +1 -0
  55. package/packages/console/src/Commands/MakeModel.ts +1 -0
  56. package/packages/console/src/Commands/MakeResource.ts +1 -0
  57. package/packages/console/src/Contracts/.gitkeep +0 -0
  58. package/packages/console/src/IO/.gitkeep +0 -0
  59. package/packages/console/src/Kernel.ts +1 -0
  60. package/packages/console/src/Musketeer.ts +4 -0
  61. package/packages/console/src/Providers/ConsoleServiceProvider.ts +16 -0
  62. package/packages/console/src/index.ts +10 -0
  63. package/packages/console/tests/.gitkeep +0 -0
  64. package/packages/console/tsconfig.json +8 -0
  65. package/packages/console/vite.config.ts +9 -0
  66. package/packages/core/node_modules/.bin/tsc +21 -0
  67. package/packages/core/node_modules/.bin/tsserver +21 -0
  68. package/packages/core/package.json +29 -0
  69. package/packages/core/src/Application.ts +164 -0
  70. package/packages/core/src/Container.ts +71 -0
  71. package/packages/core/src/Contracts/.gitkeep +0 -0
  72. package/packages/core/src/Contracts/BindingsContract.ts +37 -0
  73. package/packages/core/src/Controller.ts +20 -0
  74. package/packages/core/src/Exceptions/Handler.ts +1 -0
  75. package/packages/core/src/Http/Kernel.ts +47 -0
  76. package/packages/core/src/Providers/AppServiceProvider.ts +18 -0
  77. package/packages/core/src/Providers/ViewServiceProvider.ts +19 -0
  78. package/packages/core/src/ServiceProvider.ts +21 -0
  79. package/packages/core/src/Utils/PathLoader.ts +46 -0
  80. package/packages/core/src/index.ts +14 -0
  81. package/packages/core/tests/.gitkeep +0 -0
  82. package/packages/core/tsconfig.json +8 -0
  83. package/packages/core/vite.config.ts +9 -0
  84. package/packages/database/node_modules/.bin/tsc +21 -0
  85. package/packages/database/node_modules/.bin/tsserver +21 -0
  86. package/packages/database/package.json +26 -0
  87. package/packages/database/src/Contracts/.gitkeep +0 -0
  88. package/packages/database/src/Migrations/.gitkeep +0 -0
  89. package/packages/database/src/Model.ts +1 -0
  90. package/packages/database/src/Providers/DatabaseServiceProvider.ts +16 -0
  91. package/packages/database/src/Query/.gitkeep +0 -0
  92. package/packages/database/src/index.ts +6 -0
  93. package/packages/database/src/tests/.gitkeep +0 -0
  94. package/packages/database/tsconfig.json +8 -0
  95. package/packages/database/vite.config.ts +9 -0
  96. package/packages/http/node_modules/.bin/tsc +21 -0
  97. package/packages/http/node_modules/.bin/tsserver +21 -0
  98. package/packages/http/package.json +28 -0
  99. package/packages/http/src/Contracts/ControllerContracts.ts +13 -0
  100. package/packages/http/src/Contracts/HttpContract.ts +7 -0
  101. package/packages/http/src/Middleware/LogRequests.ts +9 -0
  102. package/packages/http/src/Middleware.ts +5 -0
  103. package/packages/http/src/Providers/HttpServiceProvider.ts +22 -0
  104. package/packages/http/src/Request.ts +59 -0
  105. package/packages/http/src/Resources/ApiResource.ts +39 -0
  106. package/packages/http/src/Resources/JsonResource.ts +201 -0
  107. package/packages/http/src/Response.ts +80 -0
  108. package/packages/http/src/index.ts +13 -0
  109. package/packages/http/tests/.gitkeep +0 -0
  110. package/packages/http/tsconfig.json +8 -0
  111. package/packages/http/vite.config.ts +9 -0
  112. package/packages/mail/node_modules/.bin/tsc +21 -0
  113. package/packages/mail/node_modules/.bin/tsserver +21 -0
  114. package/packages/mail/package.json +26 -0
  115. package/packages/mail/src/Contracts/.gitkeep +0 -0
  116. package/packages/mail/src/Drivers/SES.ts +1 -0
  117. package/packages/mail/src/Drivers/SMTP.ts +1 -0
  118. package/packages/mail/src/Helpers.ts +1 -0
  119. package/packages/mail/src/Mailable.ts +1 -0
  120. package/packages/mail/src/Mailer.ts +1 -0
  121. package/packages/mail/src/Providers/MailServiceProvider.ts +16 -0
  122. package/packages/mail/src/index.ts +10 -0
  123. package/packages/mail/tests/.gitkeep +0 -0
  124. package/packages/mail/tsconfig.json +8 -0
  125. package/packages/mail/vite.config.ts +9 -0
  126. package/packages/queue/node_modules/.bin/tsc +21 -0
  127. package/packages/queue/node_modules/.bin/tsserver +21 -0
  128. package/packages/queue/package.json +26 -0
  129. package/packages/queue/src/Contracts/.gitkeep +0 -0
  130. package/packages/queue/src/Drivers/MemoryDriver.ts +1 -0
  131. package/packages/queue/src/Drivers/RedisDriver.ts +1 -0
  132. package/packages/queue/src/Jobs/.gitkeep +0 -0
  133. package/packages/queue/src/Providers/QueueServiceProvider.ts +16 -0
  134. package/packages/queue/src/QueueManager.ts +1 -0
  135. package/packages/queue/src/Workers/.gitkeep +0 -0
  136. package/packages/queue/src/index.ts +8 -0
  137. package/packages/queue/tests/.gitkeep +0 -0
  138. package/packages/queue/tsconfig.json +8 -0
  139. package/packages/queue/vite.config.ts +9 -0
  140. package/packages/router/node_modules/.bin/tsc +21 -0
  141. package/packages/router/node_modules/.bin/tsserver +21 -0
  142. package/packages/router/package.json +27 -0
  143. package/packages/router/src/Contracts/.gitkeep +0 -0
  144. package/packages/router/src/Controller.ts +1 -0
  145. package/packages/router/src/Decorators/ApiResource.ts +1 -0
  146. package/packages/router/src/Decorators/Controller.ts +1 -0
  147. package/packages/router/src/Decorators/Get.ts +1 -0
  148. package/packages/router/src/Decorators/Middleware.ts +1 -0
  149. package/packages/router/src/Decorators/Post.ts +1 -0
  150. package/packages/router/src/Middleware/.gitkeep +0 -0
  151. package/packages/router/src/Providers/AssetsServiceProvider.ts +53 -0
  152. package/packages/router/src/Providers/RouteServiceProvider.ts +44 -0
  153. package/packages/router/src/Route.ts +1 -0
  154. package/packages/router/src/Router.ts +180 -0
  155. package/packages/router/src/index.ts +14 -0
  156. package/packages/router/tests/.gitkeep +0 -0
  157. package/packages/router/tsconfig.json +8 -0
  158. package/packages/router/vite.config.ts +9 -0
  159. package/packages/support/node_modules/.bin/tsc +21 -0
  160. package/packages/support/node_modules/.bin/tsserver +21 -0
  161. package/packages/support/package.json +26 -0
  162. package/packages/support/src/Contracts/ObjContract.ts +53 -0
  163. package/packages/support/src/Contracts/StrContract.ts +6 -0
  164. package/packages/support/src/Facades/.gitkeep +0 -0
  165. package/packages/support/src/Helpers/Arr.ts +33 -0
  166. package/packages/support/src/Helpers/Number.ts +194 -0
  167. package/packages/support/src/Helpers/Obj.ts +220 -0
  168. package/packages/support/src/Helpers/Str.ts +256 -0
  169. package/packages/support/src/index.ts +10 -0
  170. package/packages/support/tests/.gitkeep +0 -0
  171. package/packages/support/tsconfig.json +8 -0
  172. package/packages/support/vite.config.ts +9 -0
  173. package/pnpm-workspace.yaml +7 -0
  174. package/tsconfig.json +26 -0
  175. package/tsup.config.ts +15 -0
  176. package/vite.base.config.ts +12 -0
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@h3ravel/config",
3
+ "version": "0.1.1",
4
+ "description": "Environment/config loading and management system for H3ravel.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "barrel": "barrelsby --directory src --delete --singleQuotes",
19
+ "build": "tsup",
20
+ "dev": "tsx watch src/index.ts",
21
+ "start": "node dist/index.js",
22
+ "lint": "eslint . --ext .ts",
23
+ "test": "vitest"
24
+ },
25
+ "dependencies": {
26
+ "@h3ravel/core": "workspace:*",
27
+ "@h3ravel/support": "workspace:*",
28
+ "dotenv": "^17.2.1",
29
+ "h3": "^2.0.0-beta.1"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5.4.0"
33
+ }
34
+ }
@@ -0,0 +1,51 @@
1
+ import { DotNestedKeys, DotNestedValue, safeDot, setNested } from '@h3ravel/support'
2
+
3
+ import { Application } from "@h3ravel/core";
4
+ import path from 'node:path'
5
+ import { readdir } from 'node:fs/promises'
6
+
7
+ export class ConfigRepository {
8
+ private loaded: boolean = false
9
+ private configs: Record<string, Record<string, any>> = {}
10
+
11
+ constructor(private app: Application) { }
12
+
13
+ // get<X extends Record<string, any>> (): X
14
+ // get<X extends Record<string, any>, T extends Extract<keyof X, string>> (key: T): X[T]
15
+
16
+ /**
17
+ * Get the defined configurations
18
+ */
19
+ get<X extends Record<string, any>> (): X
20
+ get<X extends Record<string, any>, K extends DotNestedKeys<X>> (key: K, def?: any): DotNestedValue<X, K>
21
+ get<X extends Record<string, any>, K extends DotNestedKeys<X>> (key?: K, def?: any): any {
22
+ return safeDot(this.configs, key) ?? def
23
+ }
24
+
25
+ /**
26
+ * Modify the defined configurations
27
+ */
28
+ set<T extends string> (key: T, value: any): void {
29
+ setNested(this.configs, key, value)
30
+ }
31
+
32
+ async load () {
33
+ if (!this.loaded) {
34
+ const configPath = this.app.getPath('config')
35
+
36
+ const files = await readdir(configPath);
37
+
38
+ for (let i = 0; i < files.length; i++) {
39
+ const configModule = await import(path.join(configPath, files[i]))
40
+ const name = files[i].replaceAll(/.ts|js/g, '')
41
+ if (typeof configModule.default === 'function') {
42
+ this.configs[name] = configModule.default(this.app)
43
+ }
44
+ }
45
+
46
+ this.loaded = true
47
+ }
48
+
49
+ return this
50
+ }
51
+ }
File without changes
@@ -0,0 +1,16 @@
1
+ import { DotNestedKeys, DotNestedValue, safeDot } from '@h3ravel/support'
2
+
3
+ import { Application } from "@h3ravel/core";
4
+
5
+ export class EnvLoader {
6
+ constructor(private _app: Application) { }
7
+
8
+ /**
9
+ * Get the defined environment vars
10
+ */
11
+ get<X extends NodeJS.ProcessEnv> (): X
12
+ get<X extends NodeJS.ProcessEnv, K extends DotNestedKeys<X>> (key: K, def?: any): DotNestedValue<X, K>
13
+ get<X extends NodeJS.ProcessEnv, K extends DotNestedKeys<X>> (key?: K, def?: any): any {
14
+ return safeDot(process.env, key) ?? def
15
+ }
16
+ }
@@ -0,0 +1 @@
1
+ export default class { }
@@ -0,0 +1,46 @@
1
+ import { Bindings, ServiceProvider } from '@h3ravel/core'
2
+ import { ConfigRepository, EnvLoader } from '..'
3
+
4
+ import { config as loadEnv } from 'dotenv'
5
+
6
+ /**
7
+ * Loads configuration and environment files.
8
+ *
9
+ * Load .env and merge with config files.
10
+ * Bind ConfigRepository to the container.
11
+ *
12
+ * Auto-Registered
13
+ */
14
+ export class ConfigServiceProvider extends ServiceProvider {
15
+ async register () {
16
+
17
+ loadEnv()
18
+
19
+ /**
20
+ * Create singleton to load env
21
+ */
22
+ this.app.singleton('env', () => {
23
+ return new EnvLoader(this.app).get
24
+ })
25
+
26
+ /**
27
+ * Initialize the configuration through the repository
28
+ */
29
+ const repo = new ConfigRepository(this.app)
30
+ await repo.load()
31
+
32
+ /**
33
+ * Create singleton to load configurations
34
+ */
35
+ this.app.singleton('config', () => {
36
+ return {
37
+ get: (key, def) => repo.get(key as any, def),
38
+ set: repo.set
39
+ } as Bindings['config']
40
+ })
41
+
42
+ this.app.make('http.app').use(e => {
43
+ repo.set('app.url', e.url.origin)
44
+ })
45
+ }
46
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+
5
+ export * from './ConfigRepository';
6
+ export * from './EnvLoader';
7
+ export * from './Helpers';
8
+ export * from './Providers/ConfigServiceProvider';
File without changes
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["dist", "node_modules"]
8
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm', 'cjs'],
6
+ dts: true,
7
+ sourcemap: true,
8
+ clean: true
9
+ })
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsc" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsserver" "$@"
21
+ fi
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@h3ravel/console",
3
+ "version": "0.1.1",
4
+ "description": "CLI utilities for scaffolding, running migrations, tasks and for H3ravel.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "scripts": {
12
+ "barrel": "barrelsby --directory src --delete --singleQuotes",
13
+ "build": "tsup",
14
+ "dev": "tsx watch src/index.ts",
15
+ "start": "node dist/index.js",
16
+ "lint": "eslint . --ext .ts",
17
+ "test": "vitest"
18
+ },
19
+ "dependencies": {
20
+ "@h3ravel/core": "workspace:*",
21
+ "h3": "^2.0.0-beta.1"
22
+ },
23
+ "devDependencies": {
24
+ "typescript": "^5.4.0"
25
+ }
26
+ }
@@ -0,0 +1 @@
1
+ export default class { }
@@ -0,0 +1 @@
1
+ export default class { }
@@ -0,0 +1 @@
1
+ export default class { }
File without changes
File without changes
@@ -0,0 +1 @@
1
+ export default class { }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Musketeer is H3ravel's CLI tool
3
+ */
4
+ export default class { }
@@ -0,0 +1,16 @@
1
+ import { ServiceProvider } from '@h3ravel/core'
2
+
3
+ /**
4
+ * Handles CLI commands and tooling.
5
+ *
6
+ * Register DatabaseManager and QueryBuilder.
7
+ * Set up ORM models and relationships.
8
+ * Register migration and seeder commands.
9
+ *
10
+ * Auto-Registered when in CLI mode
11
+ */
12
+ export class ConsoleServiceProvider extends ServiceProvider {
13
+ register () {
14
+ // Core bindings
15
+ }
16
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+
5
+ export * from './Kernel';
6
+ export * from './Musketeer';
7
+ export * from './Commands/MakeController';
8
+ export * from './Commands/MakeModel';
9
+ export * from './Commands/MakeResource';
10
+ export * from './Providers/ConsoleServiceProvider';
File without changes
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["dist", "node_modules"]
8
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm', 'cjs'],
6
+ dts: true,
7
+ sourcemap: true,
8
+ clean: true
9
+ })
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsc" "$@"
21
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/bin/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/typescript@5.8.3/node_modules:/Users/ralph/Documents/Marx/Toneflix/OpenSource/H3ravel/framework/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
19
+ else
20
+ exec node "$basedir/../typescript/bin/tsserver" "$@"
21
+ fi
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@h3ravel/core",
3
+ "version": "0.1.1",
4
+ "description": "Core application container, lifecycle management and service providers for H3ravel.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "scripts": {
12
+ "barrel": "barrelsby --directory src --delete --singleQuotes",
13
+ "build": "tsup",
14
+ "dev": "tsx watch src/index.ts",
15
+ "start": "node dist/index.js",
16
+ "lint": "eslint . --ext .ts",
17
+ "test": "vitest"
18
+ },
19
+ "dependencies": {
20
+ "edge.js": "^6.3.0",
21
+ "h3": "^2.0.0-beta.1",
22
+ "reflect-metadata": "^0.2.2",
23
+ "srvx": "^0.8.2",
24
+ "tslib": "^2.6.0"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.4.0"
28
+ }
29
+ }
@@ -0,0 +1,164 @@
1
+ import { Container } from './Container'
2
+ import { PathLoader } from './Utils/PathLoader'
3
+ import { ServiceProvider } from './ServiceProvider'
4
+ import path from 'node:path'
5
+
6
+ export class Application extends Container {
7
+ paths = new PathLoader()
8
+ private booted = false
9
+ private versions = { app: '0', ts: '0' }
10
+ private basePath: string
11
+
12
+ private providers: ServiceProvider[] = []
13
+ protected externalProviders: Array<new (_app: Application) => ServiceProvider> = []
14
+
15
+ constructor(basePath: string) {
16
+ super()
17
+ this.basePath = basePath
18
+ this.setPath('base', basePath)
19
+ this.loadOptions()
20
+ this.registerBaseBindings()
21
+ }
22
+
23
+ /**
24
+ * Register core bindings into the container
25
+ */
26
+ protected registerBaseBindings () {
27
+ this.bind(Application, () => this)
28
+ this.bind('path.base', () => this.basePath)
29
+ this.bind('app.paths', () => this.paths)
30
+ }
31
+
32
+ /**
33
+ * Dynamically register all configured providers
34
+ */
35
+ public async registerConfiguredProviders () {
36
+ const providers = await this.getAllProviders()
37
+
38
+ for (const ProviderClass of providers) {
39
+ if (!ProviderClass) continue
40
+ const provider = new ProviderClass(this)
41
+ await this.register(provider)
42
+ }
43
+ }
44
+
45
+ protected async loadOptions () {
46
+ const app = await this.safeImport(this.getPath('base', 'package.json'))
47
+ const core = await this.safeImport('../package.json')
48
+
49
+ if (app && app.dependencies) {
50
+ this.versions.app = app.dependencies['@h3ravel/core']
51
+ }
52
+ if (core && core.devDependencies) {
53
+ this.versions.ts = app.devDependencies.typescript
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Load default and optional providers dynamically
59
+ *
60
+ * Auto-Registration Behavior
61
+ *
62
+ * Minimal App: Loads only core, config, http, router by default.
63
+ * Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
64
+ */
65
+ protected async getConfiguredProviders (): Promise<Array<new (_app: Application) => ServiceProvider>> {
66
+ return [
67
+ (await import('@h3ravel/core')).AppServiceProvider,
68
+ (await import('@h3ravel/http')).HttpServiceProvider,
69
+ (await import('@h3ravel/config')).ConfigServiceProvider,
70
+ (await import('@h3ravel/router')).RouteServiceProvider,
71
+ (await import('@h3ravel/router')).AssetsServiceProvider,
72
+ (await import('@h3ravel/core')).ViewServiceProvider,
73
+ (await this.safeImport('@h3ravel/database'))?.DatabaseServiceProvider,
74
+ (await this.safeImport('@h3ravel/cache'))?.CacheServiceProvider,
75
+ (await this.safeImport('@h3ravel/console'))?.ConsoleServiceProvider,
76
+ (await this.safeImport('@h3ravel/queue'))?.QueueServiceProvider,
77
+ (await this.safeImport('@h3ravel/mail'))?.MailServiceProvider,
78
+ ]
79
+ }
80
+
81
+ protected async getAllProviders (): Promise<Array<new (_app: Application) => ServiceProvider>> {
82
+ const coreProviders = await this.getConfiguredProviders()
83
+ return [...coreProviders, ...this.externalProviders]
84
+ }
85
+
86
+ registerProviders (providers: Array<new (_app: Application) => ServiceProvider>): void {
87
+ this.externalProviders.push(...providers)
88
+ }
89
+
90
+ /**
91
+ * Register a provider
92
+ */
93
+ public async register (provider: ServiceProvider) {
94
+ await provider.register()
95
+ this.providers.push(provider)
96
+ }
97
+
98
+ /**
99
+ * Boot all providers after registration
100
+ */
101
+ public async boot () {
102
+ if (this.booted) return
103
+
104
+ for (const provider of this.providers) {
105
+ if (provider.boot) {
106
+ await provider.boot()
107
+ }
108
+ }
109
+
110
+ this.booted = true
111
+ }
112
+
113
+ /**
114
+ * Attempt to dynamically import an optional module
115
+ */
116
+ private async safeImport (moduleName: string) {
117
+ try {
118
+ const mod = await import(moduleName)
119
+ return mod.default ?? mod
120
+ } catch {
121
+ return null
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Get the base path of the app
127
+ *
128
+ * @returns
129
+ */
130
+ getBasePath (): string {
131
+ return this.basePath
132
+ }
133
+
134
+ /**
135
+ * Dynamically retrieves a path property from the class.
136
+ * Any property ending with "Path" is accessible automatically.
137
+ *
138
+ * @param name - The base name of the path property
139
+ * @returns
140
+ */
141
+ getPath (name: Parameters<PathLoader['setPath']>[0], pth?: string) {
142
+ return path.join(this.paths.getPath(name, this.basePath), pth ?? '')
143
+ }
144
+
145
+ /**
146
+ * Programatically set the paths.
147
+ *
148
+ * @param name - The base name of the path property
149
+ * @param path - The new path
150
+ * @returns
151
+ */
152
+ setPath (name: Parameters<PathLoader['setPath']>[0], path: string) {
153
+ return this.paths.setPath(name, path, this.basePath)
154
+ }
155
+
156
+ /**
157
+ * Returns the installed version of the system core and typescript.
158
+ *
159
+ * @returns
160
+ */
161
+ getVersion (key: 'app' | 'ts') {
162
+ return this.versions[key]?.replaceAll(/\^|\~/g, '')
163
+ }
164
+ }
@@ -0,0 +1,71 @@
1
+ import type { Bindings, UseKey } from "./Contracts/BindingsContract"
2
+
3
+ type IBinding = UseKey | (new (..._args: any[]) => unknown)
4
+
5
+ export class Container {
6
+ private bindings = new Map<IBinding, () => unknown>()
7
+ private singletons = new Map<IBinding, unknown>()
8
+
9
+ /**
10
+ * Bind a transient service to the container
11
+ */
12
+ bind<T> (key: new (...args: any[]) => T, factory: () => T): void
13
+ bind<T extends UseKey> (key: T, factory: () => Bindings[T]): void
14
+ bind<T extends UseKey> (
15
+ key: T,
16
+ factory: () => Bindings[T] | T
17
+ ) {
18
+ this.bindings.set(key, factory)
19
+ }
20
+
21
+ /**
22
+ * Bind a singleton service to the container
23
+ */
24
+ singleton<T extends UseKey> (
25
+ key: T | (new (..._args: any[]) => Bindings[T]),
26
+ factory: () => Bindings[T]
27
+ ) {
28
+ this.bindings.set(key, () => {
29
+ if (!this.singletons.has(key)) {
30
+ this.singletons.set(key, factory())
31
+ }
32
+ return this.singletons.get(key)!
33
+ })
34
+ }
35
+
36
+ /**
37
+ * Resolve a service from the container
38
+ */
39
+ make<T extends UseKey> (key: T | (new (..._args: any[]) => Bindings[T])): Bindings[T] {
40
+ // 1️⃣ Direct factory binding
41
+ if (this.bindings.has(key)) {
42
+ return this.bindings.get(key)!() as Bindings[T]
43
+ }
44
+
45
+ // 2️⃣ If class constructor → auto-resolve via reflection
46
+ if (typeof key === 'function') {
47
+ return this.build(key)
48
+ }
49
+
50
+ throw new Error(
51
+ `No binding found for key: ${typeof key === 'string' ? key : (key as any)?.name}`
52
+ )
53
+ }
54
+
55
+ /**
56
+ * Automatically build a class with constructor dependency injection
57
+ */
58
+ private build<T extends UseKey> (ClassType: new (..._args: any[]) => Bindings[T]): Bindings[T] {
59
+ const paramTypes: any[] = Reflect.getMetadata('design:paramtypes', ClassType) || []
60
+ const dependencies = paramTypes.map((dep) => this.make(dep))
61
+ return new ClassType(...dependencies)
62
+ }
63
+
64
+
65
+ /**
66
+ * Check if a service is registered
67
+ */
68
+ has (key: UseKey): boolean {
69
+ return this.bindings.has(key)
70
+ }
71
+ }
File without changes