odac 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/auto-pr-description.yml +0 -2
- package/.github/workflows/codeql.yml +46 -0
- package/.github/workflows/release.yml +13 -6
- package/.github/workflows/test-coverage.yml +10 -9
- package/.releaserc.js +9 -6
- package/CHANGELOG.md +62 -150
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTING.md +8 -8
- package/LICENSE +21 -661
- package/README.md +12 -12
- package/SECURITY.md +4 -4
- package/bin/odac.js +101 -0
- package/{framework/web/candy.js → client/odac.js} +310 -44
- package/docs/backend/01-overview/{01-whats-in-the-candy-box.md → 01-whats-in-the-odac-box.md} +4 -2
- package/docs/backend/01-overview/02-super-handy-helper-functions.md +29 -1
- package/docs/backend/01-overview/03-development-server.md +11 -11
- package/docs/backend/02-structure/01-typical-project-layout.md +4 -4
- package/docs/backend/03-config/00-configuration-overview.md +6 -6
- package/docs/backend/03-config/01-database-connection.md +1 -1
- package/docs/backend/03-config/02-static-route-mapping-optional.md +4 -4
- package/docs/backend/03-config/04-environment-variables.md +20 -20
- package/docs/backend/03-config/05-early-hints.md +4 -4
- package/docs/backend/04-routing/01-basic-page-routes.md +4 -4
- package/docs/backend/04-routing/02-controller-less-view-routes.md +5 -5
- package/docs/backend/04-routing/03-api-and-data-routes.md +3 -3
- package/docs/backend/04-routing/04-authentication-aware-routes.md +5 -5
- package/docs/backend/04-routing/05-advanced-routing.md +3 -3
- package/docs/backend/04-routing/06-error-pages.md +17 -17
- package/docs/backend/04-routing/07-cron-jobs.md +13 -13
- package/docs/backend/04-routing/08-middleware.md +214 -0
- package/docs/backend/04-routing/09-websocket-auth-middleware.md +292 -0
- package/docs/backend/04-routing/09-websocket-examples.md +381 -0
- package/docs/backend/04-routing/09-websocket-quick-reference.md +211 -0
- package/docs/backend/04-routing/09-websocket.md +298 -0
- package/docs/backend/05-controllers/01-how-to-build-a-controller.md +3 -3
- package/docs/backend/05-controllers/02-your-trusty-odac-assistant.md +41 -0
- package/docs/backend/05-controllers/03-controller-classes.md +19 -19
- package/docs/backend/05-forms/01-custom-forms.md +114 -114
- package/docs/backend/05-forms/02-automatic-database-insert.md +82 -82
- package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +26 -26
- package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +10 -10
- package/docs/backend/07-views/01-the-view-directory.md +1 -1
- package/docs/backend/07-views/02-rendering-a-view.md +22 -22
- package/docs/backend/07-views/03-template-syntax.md +52 -52
- package/docs/backend/07-views/03-variables.md +84 -84
- package/docs/backend/07-views/04-request-data.md +57 -57
- package/docs/backend/07-views/05-conditionals.md +78 -78
- package/docs/backend/07-views/06-loops.md +114 -114
- package/docs/backend/07-views/07-translations.md +66 -66
- package/docs/backend/07-views/08-backend-javascript.md +103 -103
- package/docs/backend/07-views/09-comments.md +71 -71
- package/docs/backend/08-database/01-database-connection.md +8 -8
- package/docs/backend/08-database/02-using-mysql.md +49 -49
- package/docs/backend/09-validation/01-the-validator-service.md +38 -38
- package/docs/backend/10-authentication/01-user-logins-with-authjs.md +15 -15
- package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +10 -10
- package/docs/backend/10-authentication/03-register.md +12 -12
- package/docs/backend/10-authentication/{04-candy-register-forms.md → 04-odac-register-forms.md} +141 -141
- package/docs/backend/10-authentication/05-session-management.md +10 -10
- package/docs/backend/10-authentication/{06-candy-login-forms.md → 06-odac-login-forms.md} +125 -125
- package/docs/backend/11-mail/01-the-mail-service.md +5 -5
- package/docs/backend/12-streaming/01-streaming-overview.md +96 -54
- package/docs/backend/13-utilities/{01-candy-var.md → 01-odac-var.md} +109 -109
- package/docs/frontend/01-overview/01-introduction.md +30 -30
- package/docs/frontend/02-ajax-navigation/01-quick-start.md +45 -45
- package/docs/frontend/02-ajax-navigation/02-configuration.md +14 -14
- package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +36 -36
- package/docs/frontend/03-forms/01-form-handling.md +32 -32
- package/docs/frontend/04-api-requests/01-get-post.md +33 -33
- package/docs/frontend/05-streaming/01-client-streaming.md +15 -15
- package/docs/frontend/06-websocket/00-overview.md +76 -0
- package/docs/frontend/06-websocket/01-websocket-client.md +139 -0
- package/docs/frontend/06-websocket/02-shared-websocket.md +149 -0
- package/docs/index.json +49 -11
- package/eslint.config.mjs +6 -6
- package/{framework/index.js → index.js} +1 -1
- package/package.json +14 -39
- package/{framework/src → src}/Auth.js +59 -59
- package/{framework/src → src}/Config.js +3 -3
- package/{framework/src → src}/Lang.js +7 -7
- package/{framework/src → src}/Mail.js +5 -5
- package/{framework/src → src}/Mysql.js +42 -42
- package/src/Odac.js +112 -0
- package/{framework/src → src}/Request.js +38 -36
- package/{framework/src → src}/Route/Internal.js +116 -116
- package/src/Route/Middleware.js +75 -0
- package/src/Route.js +621 -0
- package/src/Server.js +22 -0
- package/{framework/src → src}/Stream.js +11 -3
- package/{framework/src → src}/Validator.js +21 -21
- package/{framework/src → src}/Var.js +5 -5
- package/{framework/src → src}/View/EarlyHints.js +1 -1
- package/{framework/src → src}/View/Form.js +69 -69
- package/{framework/src → src}/View.js +78 -81
- package/src/WebSocket.js +403 -0
- package/template/config.json +5 -0
- package/{web → template}/controller/page/about.js +6 -6
- package/{web → template}/controller/page/index.js +9 -9
- package/{web → template}/package.json +4 -5
- package/{web → template}/public/assets/css/style.css +4 -4
- package/{web → template}/public/assets/js/app.js +6 -6
- package/{web → template}/route/www.js +6 -6
- package/{web → template}/skeleton/main.html +1 -1
- package/{web → template}/view/content/about.html +5 -5
- package/{web → template}/view/content/home.html +12 -12
- package/template/view/footer/main.html +11 -0
- package/{web → template}/view/head/main.html +1 -1
- package/{web → template}/view/header/main.html +2 -2
- package/test/core/Candy.test.js +58 -58
- package/test/core/Commands.test.js +7 -7
- package/test/core/Config.test.js +82 -85
- package/test/core/Lang.test.js +2 -2
- package/test/core/Process.test.js +6 -6
- package/test/framework/Route.test.js +56 -37
- package/test/framework/View/EarlyHints.test.js +2 -2
- package/test/framework/WebSocket.test.js +100 -0
- package/test/framework/middleware.test.js +85 -0
- package/test/server/Api.test.js +31 -31
- package/test/server/DNS.test.js +11 -11
- package/test/server/Hub.test.js +497 -0
- package/test/server/Mail.account.test_.js +3 -3
- package/test/server/Mail.init.test_.js +10 -10
- package/test/server/Mail.test_.js +20 -20
- package/test/server/SSL.test_.js +54 -54
- package/test/server/Server.test.js +39 -39
- package/test/server/Service.test_.js +7 -7
- package/test/server/Subdomain.test.js +7 -7
- package/test/server/Web/Firewall.test.js +87 -87
- package/test/server/Web/Proxy.test.js +397 -0
- package/test/server/{Web.test_.js → Web.test.js} +137 -205
- package/test/server/__mocks__/fs.js +2 -2
- package/test/server/__mocks__/{globalCandy.js → globalOdac.js} +5 -5
- package/test/server/__mocks__/index.js +6 -6
- package/test/server/__mocks__/testFactories.js +1 -1
- package/test/server/__mocks__/testHelpers.js +7 -7
- package/.husky/pre-commit +0 -2
- package/.kiro/steering/code-style.md +0 -56
- package/.kiro/steering/product.md +0 -20
- package/.kiro/steering/structure.md +0 -77
- package/.kiro/steering/tech.md +0 -87
- package/AGENTS.md +0 -84
- package/bin/candy +0 -10
- package/bin/candypack +0 -10
- package/cli/index.js +0 -3
- package/cli/src/Cli.js +0 -348
- package/cli/src/Connector.js +0 -93
- package/cli/src/Monitor.js +0 -416
- package/core/Candy.js +0 -87
- package/core/Commands.js +0 -239
- package/core/Config.js +0 -1094
- package/core/Lang.js +0 -52
- package/core/Log.js +0 -43
- package/core/Process.js +0 -26
- package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +0 -20
- package/docs/server/01-installation/01-quick-install.md +0 -19
- package/docs/server/01-installation/02-manual-installation-via-npm.md +0 -9
- package/docs/server/02-get-started/01-core-concepts.md +0 -7
- package/docs/server/02-get-started/02-basic-commands.md +0 -57
- package/docs/server/02-get-started/03-cli-reference.md +0 -276
- package/docs/server/02-get-started/04-cli-quick-reference.md +0 -102
- package/docs/server/03-service/01-start-a-new-service.md +0 -57
- package/docs/server/03-service/02-delete-a-service.md +0 -48
- package/docs/server/04-web/01-create-a-website.md +0 -36
- package/docs/server/04-web/02-list-websites.md +0 -9
- package/docs/server/04-web/03-delete-a-website.md +0 -29
- package/docs/server/05-subdomain/01-create-a-subdomain.md +0 -32
- package/docs/server/05-subdomain/02-list-subdomains.md +0 -33
- package/docs/server/05-subdomain/03-delete-a-subdomain.md +0 -41
- package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +0 -34
- package/docs/server/07-mail/01-create-a-mail-account.md +0 -23
- package/docs/server/07-mail/02-delete-a-mail-account.md +0 -20
- package/docs/server/07-mail/03-list-mail-accounts.md +0 -20
- package/docs/server/07-mail/04-change-account-password.md +0 -23
- package/framework/src/Candy.js +0 -81
- package/framework/src/Route.js +0 -455
- package/framework/src/Server.js +0 -15
- package/locale/de-DE.json +0 -80
- package/locale/en-US.json +0 -79
- package/locale/es-ES.json +0 -80
- package/locale/fr-FR.json +0 -80
- package/locale/pt-BR.json +0 -80
- package/locale/ru-RU.json +0 -80
- package/locale/tr-TR.json +0 -85
- package/locale/zh-CN.json +0 -80
- package/server/index.js +0 -5
- package/server/src/Api.js +0 -88
- package/server/src/DNS.js +0 -940
- package/server/src/Hub.js +0 -535
- package/server/src/Mail.js +0 -571
- package/server/src/SSL.js +0 -180
- package/server/src/Server.js +0 -27
- package/server/src/Service.js +0 -248
- package/server/src/Subdomain.js +0 -64
- package/server/src/Web/Firewall.js +0 -170
- package/server/src/Web/Proxy.js +0 -134
- package/server/src/Web.js +0 -451
- package/server/src/mail/imap.js +0 -1091
- package/server/src/mail/server.js +0 -32
- package/server/src/mail/smtp.js +0 -786
- package/test/server/Client.test.js +0 -338
- package/test/server/__mocks__/http-proxy.js +0 -105
- package/watchdog/index.js +0 -3
- package/watchdog/src/Watchdog.js +0 -156
- package/web/config.json +0 -5
- package/web/view/footer/main.html +0 -11
- /package/{framework/src → src}/Env.js +0 -0
- /package/{framework/src → src}/Route/Cron.js +0 -0
- /package/{framework/src → src}/Token.js +0 -0
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
<section class="hero">
|
|
3
3
|
<div class="container">
|
|
4
4
|
<div class="hero-content">
|
|
5
|
-
<h1 class="hero-title">🍭 Your
|
|
6
|
-
<p class="hero-subtitle">You've successfully created a new website with
|
|
5
|
+
<h1 class="hero-title">🍭 Your Odac Site is Ready!</h1>
|
|
6
|
+
<p class="hero-subtitle">You've successfully created a new website with Odac</p>
|
|
7
7
|
<p class="hero-description">
|
|
8
8
|
This is your starting template. Edit the files in your project directory to customize your site. Everything you need to build a
|
|
9
9
|
modern web application is already set up and ready to go.
|
|
10
10
|
</p>
|
|
11
11
|
<div class="hero-actions">
|
|
12
|
-
<a href="https://
|
|
13
|
-
<a href="https://docs.
|
|
12
|
+
<a href="https://odac.run" target="_blank" class="btn btn-primary" data-navigate="false">Visit odac.run</a>
|
|
13
|
+
<a href="https://docs.odac.run" target="_blank" class="btn btn-secondary" data-navigate="false">Read Documentation</a>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
@@ -86,16 +86,16 @@
|
|
|
86
86
|
<div class="step-number">2</div>
|
|
87
87
|
<h3 class="step-title">Add Routes</h3>
|
|
88
88
|
<p class="step-description">Define new pages in <code>route/www.js</code>. Map URLs to controllers:</p>
|
|
89
|
-
<pre class="code-snippet"><code>
|
|
89
|
+
<pre class="code-snippet"><code>Odac.Route.page('/my-page', 'page.mypage')</code></pre>
|
|
90
90
|
</div>
|
|
91
91
|
|
|
92
92
|
<div class="quickstart-step">
|
|
93
93
|
<div class="step-number">3</div>
|
|
94
94
|
<h3 class="step-title">Create Controllers</h3>
|
|
95
95
|
<p class="step-description">Add logic in <code>controller/page/mypage.js</code>:</p>
|
|
96
|
-
<pre class="code-snippet"><code>module.exports = function(
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
<pre class="code-snippet"><code>module.exports = function(Odac) {
|
|
97
|
+
Odac.View.skeleton('main')
|
|
98
|
+
Odac.View.set({
|
|
99
99
|
header: 'main',
|
|
100
100
|
content: 'mypage',
|
|
101
101
|
footer: 'main'
|
|
@@ -177,19 +177,19 @@
|
|
|
177
177
|
<h2 class="section-title">📚 Learn More</h2>
|
|
178
178
|
|
|
179
179
|
<div class="resources-grid">
|
|
180
|
-
<a href="https://
|
|
180
|
+
<a href="https://odac.run" target="_blank" class="resource-card" data-navigate="false">
|
|
181
181
|
<div class="resource-icon">🌐</div>
|
|
182
|
-
<h3>
|
|
182
|
+
<h3>odac.run</h3>
|
|
183
183
|
<p>Official website with guides, tutorials, and community resources</p>
|
|
184
184
|
</a>
|
|
185
185
|
|
|
186
|
-
<a href="https://docs.
|
|
186
|
+
<a href="https://docs.odac.run" target="_blank" class="resource-card" data-navigate="false">
|
|
187
187
|
<div class="resource-icon">📖</div>
|
|
188
188
|
<h3>Documentation</h3>
|
|
189
189
|
<p>Complete API reference, examples, and best practices</p>
|
|
190
190
|
</a>
|
|
191
191
|
|
|
192
|
-
<a href="https://github.com/
|
|
192
|
+
<a href="https://github.com/odac-run/odac" target="_blank" class="resource-card" data-navigate="false">
|
|
193
193
|
<div class="resource-icon">💻</div>
|
|
194
194
|
<h3>GitHub</h3>
|
|
195
195
|
<p>Source code, issues, and contribution guidelines</p>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- Footer -->
|
|
2
|
+
<div class="footer">
|
|
3
|
+
<div class="container">
|
|
4
|
+
<p>Powered by <strong>Odac</strong> - A next-generation server and framework toolkit</p>
|
|
5
|
+
<p class="footer-links">
|
|
6
|
+
<a href="https://github.com/odac-run/odac" target="_blank" data-navigate="false">GitHub</a> •
|
|
7
|
+
<a href="https://docs.odac.run" target="_blank" data-navigate="false">Documentation</a> •
|
|
8
|
+
<a href="https://odac.run" target="_blank" data-navigate="false">Official Site</a>
|
|
9
|
+
</p>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<meta charset="UTF-8" />
|
|
2
2
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
3
|
-
<title>
|
|
3
|
+
<title>Odac</title>
|
|
4
4
|
<meta name="description" content="A next-generation server and framework toolkit for modern web development" />
|
|
5
5
|
<link rel="stylesheet" href="/assets/css/style.css" />
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
<div class="container">
|
|
4
4
|
<div class="nav-brand">
|
|
5
5
|
<span class="brand-icon">🍭</span>
|
|
6
|
-
<span class="brand-name">
|
|
6
|
+
<span class="brand-name">Odac</span>
|
|
7
7
|
</div>
|
|
8
8
|
<div class="nav-links">
|
|
9
9
|
<a href="/" class="nav-link active">Getting Started</a>
|
|
10
10
|
<a href="/about" class="nav-link">About</a>
|
|
11
|
-
<a href="https://docs.
|
|
11
|
+
<a href="https://docs.odac.run" class="nav-link" target="_blank" data-navigate="false">Docs ↗</a>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
</nav>
|
package/test/core/Candy.test.js
CHANGED
|
@@ -10,17 +10,17 @@ jest.mock('fs', () => ({
|
|
|
10
10
|
}))
|
|
11
11
|
|
|
12
12
|
// Mock process.mainModule to avoid Config initialization issues
|
|
13
|
-
process.mainModule = {path: '/mock/node_modules/
|
|
13
|
+
process.mainModule = {path: '/mock/node_modules/odac/bin'}
|
|
14
14
|
|
|
15
15
|
// Import the module to ensure global setup
|
|
16
|
-
require('../../core/
|
|
16
|
+
require('../../core/Odac.js')
|
|
17
17
|
|
|
18
|
-
describe('
|
|
18
|
+
describe('Odac', () => {
|
|
19
19
|
describe('global setup', () => {
|
|
20
|
-
it('should have global
|
|
21
|
-
expect(global.
|
|
22
|
-
expect(global.
|
|
23
|
-
expect(global.
|
|
20
|
+
it('should have global Odac instance', () => {
|
|
21
|
+
expect(global.Odac).toBeDefined()
|
|
22
|
+
expect(global.Odac._registry).toBeInstanceOf(Map)
|
|
23
|
+
expect(global.Odac._singletons).toBeInstanceOf(Map)
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
it('should have global __ function', () => {
|
|
@@ -34,83 +34,83 @@ describe('CandyPack', () => {
|
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
it('should not recreate global if already exists', () => {
|
|
37
|
-
const existingCandy = global.
|
|
37
|
+
const existingCandy = global.Odac
|
|
38
38
|
|
|
39
39
|
// Clear module cache and re-require
|
|
40
|
-
delete require.cache[require.resolve('../../core/
|
|
41
|
-
require('../../core/
|
|
40
|
+
delete require.cache[require.resolve('../../core/Odac.js')]
|
|
41
|
+
require('../../core/Odac.js')
|
|
42
42
|
|
|
43
|
-
expect(global.
|
|
43
|
+
expect(global.Odac).toBe(existingCandy)
|
|
44
44
|
})
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
-
describe('
|
|
47
|
+
describe('Odac instance methods', () => {
|
|
48
48
|
it('should have core method', () => {
|
|
49
|
-
expect(typeof global.
|
|
49
|
+
expect(typeof global.Odac.core).toBe('function')
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
it('should have cli method', () => {
|
|
53
|
-
expect(typeof global.
|
|
53
|
+
expect(typeof global.Odac.cli).toBe('function')
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
it('should have server method', () => {
|
|
57
|
-
expect(typeof global.
|
|
57
|
+
expect(typeof global.Odac.server).toBe('function')
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
it('should have watchdog method', () => {
|
|
61
|
-
expect(typeof global.
|
|
61
|
+
expect(typeof global.Odac.watchdog).toBe('function')
|
|
62
62
|
})
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
describe('module loading functionality', () => {
|
|
66
66
|
it('should load core modules', () => {
|
|
67
|
-
const lang = global.
|
|
67
|
+
const lang = global.Odac.core('Lang')
|
|
68
68
|
expect(lang).toBeDefined()
|
|
69
|
-
expect(global.
|
|
69
|
+
expect(global.Odac._registry.has('core:Lang')).toBe(true)
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
it('should return singleton instances by default', () => {
|
|
73
|
-
const lang1 = global.
|
|
74
|
-
const lang2 = global.
|
|
73
|
+
const lang1 = global.Odac.core('Lang')
|
|
74
|
+
const lang2 = global.Odac.core('Lang')
|
|
75
75
|
expect(lang1).toBe(lang2)
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
it('should cache singleton instances', () => {
|
|
79
|
-
const lang1 = global.
|
|
80
|
-
const lang2 = global.
|
|
79
|
+
const lang1 = global.Odac.core('Lang')
|
|
80
|
+
const lang2 = global.Odac.core('Lang')
|
|
81
81
|
|
|
82
82
|
expect(lang1).toBe(lang2)
|
|
83
|
-
expect(global.
|
|
83
|
+
expect(global.Odac._singletons.has('core:Lang')).toBe(true)
|
|
84
84
|
})
|
|
85
85
|
|
|
86
86
|
it('should return new instances when singleton is false', () => {
|
|
87
87
|
// Clear any existing Lang registration first to test non-singleton behavior
|
|
88
|
-
global.
|
|
89
|
-
global.
|
|
88
|
+
global.Odac._registry.delete('core:Lang')
|
|
89
|
+
global.Odac._singletons.delete('core:Lang')
|
|
90
90
|
|
|
91
|
-
const lang1 = global.
|
|
92
|
-
const lang2 = global.
|
|
91
|
+
const lang1 = global.Odac.core('Lang', false)
|
|
92
|
+
const lang2 = global.Odac.core('Lang', false)
|
|
93
93
|
expect(lang1).not.toBe(lang2)
|
|
94
94
|
})
|
|
95
95
|
|
|
96
96
|
it('should call init method if module has one', () => {
|
|
97
97
|
// Test with Config module which has init method
|
|
98
|
-
const config = global.
|
|
98
|
+
const config = global.Odac.core('Config')
|
|
99
99
|
expect(config).toBeDefined()
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
it('should retrieve Config module as singleton', () => {
|
|
103
103
|
// Get Config instance twice
|
|
104
|
-
const config1 = global.
|
|
105
|
-
const config2 = global.
|
|
104
|
+
const config1 = global.Odac.core('Config')
|
|
105
|
+
const config2 = global.Odac.core('Config')
|
|
106
106
|
|
|
107
107
|
// Should be the same instance (singleton behavior)
|
|
108
108
|
expect(config1).toBe(config2)
|
|
109
109
|
expect(config1).toBeInstanceOf(Object)
|
|
110
110
|
|
|
111
111
|
// Should be registered in singleton cache
|
|
112
|
-
expect(global.
|
|
113
|
-
expect(global.
|
|
112
|
+
expect(global.Odac._singletons.has('core:Config')).toBe(true)
|
|
113
|
+
expect(global.Odac._singletons.get('core:Config')).toBe(config1)
|
|
114
114
|
|
|
115
115
|
// Should have Config class properties
|
|
116
116
|
expect(config1.config).toBeDefined()
|
|
@@ -120,7 +120,7 @@ describe('CandyPack', () => {
|
|
|
120
120
|
|
|
121
121
|
it('should handle modules without init method', () => {
|
|
122
122
|
// Test with Process module which doesn't have init method
|
|
123
|
-
const process = global.
|
|
123
|
+
const process = global.Odac.core('Process')
|
|
124
124
|
expect(process).toBeDefined()
|
|
125
125
|
})
|
|
126
126
|
})
|
|
@@ -129,21 +129,21 @@ describe('CandyPack', () => {
|
|
|
129
129
|
it('should load cli modules with correct path prefix', () => {
|
|
130
130
|
// This will fail but we can test the path construction
|
|
131
131
|
expect(() => {
|
|
132
|
-
global.
|
|
132
|
+
global.Odac.cli('NonExistentCli')
|
|
133
133
|
}).toThrow()
|
|
134
134
|
})
|
|
135
135
|
|
|
136
136
|
it('should load server modules with correct path prefix', () => {
|
|
137
137
|
// This will fail but we can test the path construction
|
|
138
138
|
expect(() => {
|
|
139
|
-
global.
|
|
139
|
+
global.Odac.server('NonExistentServer')
|
|
140
140
|
}).toThrow()
|
|
141
141
|
})
|
|
142
142
|
|
|
143
143
|
it('should load watchdog modules with correct path prefix', () => {
|
|
144
144
|
// This will fail but we can test the path construction
|
|
145
145
|
expect(() => {
|
|
146
|
-
global.
|
|
146
|
+
global.Odac.watchdog('NonExistentWatchdog')
|
|
147
147
|
}).toThrow()
|
|
148
148
|
})
|
|
149
149
|
})
|
|
@@ -151,16 +151,16 @@ describe('CandyPack', () => {
|
|
|
151
151
|
describe('registry functionality', () => {
|
|
152
152
|
it('should maintain separate registries for different module types', () => {
|
|
153
153
|
// Load a core module
|
|
154
|
-
global.
|
|
154
|
+
global.Odac.core('Lang')
|
|
155
155
|
|
|
156
|
-
expect(global.
|
|
157
|
-
expect(global.
|
|
156
|
+
expect(global.Odac._registry.has('core:Lang')).toBe(true)
|
|
157
|
+
expect(global.Odac._registry.size).toBeGreaterThan(0)
|
|
158
158
|
})
|
|
159
159
|
|
|
160
160
|
it('should store registry entries with correct structure', () => {
|
|
161
|
-
global.
|
|
161
|
+
global.Odac.core('Lang')
|
|
162
162
|
|
|
163
|
-
const entry = global.
|
|
163
|
+
const entry = global.Odac._registry.get('core:Lang')
|
|
164
164
|
expect(entry).toBeDefined()
|
|
165
165
|
expect(entry).toHaveProperty('value')
|
|
166
166
|
expect(entry).toHaveProperty('singleton')
|
|
@@ -168,24 +168,24 @@ describe('CandyPack', () => {
|
|
|
168
168
|
|
|
169
169
|
it('should handle non-singleton registry entries', () => {
|
|
170
170
|
// Clear existing registration
|
|
171
|
-
global.
|
|
172
|
-
global.
|
|
171
|
+
global.Odac._registry.delete('core:Lang')
|
|
172
|
+
global.Odac._singletons.delete('core:Lang')
|
|
173
173
|
|
|
174
|
-
global.
|
|
174
|
+
global.Odac.core('Lang', false)
|
|
175
175
|
|
|
176
|
-
const entry = global.
|
|
176
|
+
const entry = global.Odac._registry.get('core:Lang')
|
|
177
177
|
expect(entry.singleton).toBe(false)
|
|
178
178
|
})
|
|
179
179
|
})
|
|
180
180
|
|
|
181
181
|
describe('instantiation behavior', () => {
|
|
182
182
|
it('should instantiate function modules', () => {
|
|
183
|
-
const lang = global.
|
|
183
|
+
const lang = global.Odac.core('Lang')
|
|
184
184
|
expect(lang).toBeInstanceOf(Object)
|
|
185
185
|
})
|
|
186
186
|
|
|
187
187
|
it('should handle non-function modules', () => {
|
|
188
|
-
const config = global.
|
|
188
|
+
const config = global.Odac.core('Config')
|
|
189
189
|
expect(config).toBeDefined()
|
|
190
190
|
})
|
|
191
191
|
})
|
|
@@ -193,14 +193,14 @@ describe('CandyPack', () => {
|
|
|
193
193
|
describe('error handling', () => {
|
|
194
194
|
it('should handle module loading errors gracefully', () => {
|
|
195
195
|
expect(() => {
|
|
196
|
-
global.
|
|
196
|
+
global.Odac.core('NonExistentModule')
|
|
197
197
|
}).toThrow()
|
|
198
198
|
})
|
|
199
199
|
|
|
200
200
|
it('should throw specific error for non-existent registry entries', () => {
|
|
201
|
-
// Create a new
|
|
202
|
-
const
|
|
203
|
-
const testInstance = new
|
|
201
|
+
// Create a new Odac instance to test private methods
|
|
202
|
+
const OdacClass = global.Odac.constructor
|
|
203
|
+
const testInstance = new OdacClass()
|
|
204
204
|
|
|
205
205
|
expect(() => {
|
|
206
206
|
// This should trigger the resolve error
|
|
@@ -212,23 +212,23 @@ describe('CandyPack', () => {
|
|
|
212
212
|
describe('module caching', () => {
|
|
213
213
|
beforeEach(() => {
|
|
214
214
|
// Clear any existing registrations for clean tests
|
|
215
|
-
global.
|
|
216
|
-
global.
|
|
215
|
+
global.Odac._registry.clear()
|
|
216
|
+
global.Odac._singletons.clear()
|
|
217
217
|
})
|
|
218
218
|
|
|
219
219
|
it('should not re-register already registered modules', () => {
|
|
220
220
|
// Load Lang module twice
|
|
221
|
-
const lang1 = global.
|
|
222
|
-
const lang2 = global.
|
|
221
|
+
const lang1 = global.Odac.core('Lang')
|
|
222
|
+
const lang2 = global.Odac.core('Lang')
|
|
223
223
|
|
|
224
224
|
expect(lang1).toBe(lang2)
|
|
225
225
|
})
|
|
226
226
|
|
|
227
227
|
it('should maintain singleton cache correctly', () => {
|
|
228
|
-
const lang = global.
|
|
228
|
+
const lang = global.Odac.core('Lang')
|
|
229
229
|
|
|
230
|
-
expect(global.
|
|
231
|
-
expect(global.
|
|
230
|
+
expect(global.Odac._singletons.has('core:Lang')).toBe(true)
|
|
231
|
+
expect(global.Odac._singletons.get('core:Lang')).toBe(lang)
|
|
232
232
|
})
|
|
233
233
|
})
|
|
234
234
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Mock the
|
|
2
|
-
global.
|
|
1
|
+
// Mock the Odac global before requiring Commands
|
|
2
|
+
global.Odac = {
|
|
3
3
|
cli: jest.fn(),
|
|
4
4
|
core: jest.fn()
|
|
5
5
|
}
|
|
@@ -29,7 +29,7 @@ describe('Commands', () => {
|
|
|
29
29
|
monit: jest.fn()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
global.
|
|
32
|
+
global.Odac.cli.mockImplementation(name => {
|
|
33
33
|
switch (name) {
|
|
34
34
|
case 'Cli':
|
|
35
35
|
return mockCli
|
|
@@ -42,7 +42,7 @@ describe('Commands', () => {
|
|
|
42
42
|
}
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
-
global.
|
|
45
|
+
global.Odac.core.mockImplementation(name => {
|
|
46
46
|
if (name === 'Lang') {
|
|
47
47
|
return {get: key => key}
|
|
48
48
|
}
|
|
@@ -68,11 +68,11 @@ describe('Commands', () => {
|
|
|
68
68
|
})
|
|
69
69
|
|
|
70
70
|
it('should have correct command descriptions', () => {
|
|
71
|
-
expect(Commands.auth.description).toBe('Define your server to your
|
|
72
|
-
expect(Commands.debug.description).toBe('Debug
|
|
71
|
+
expect(Commands.auth.description).toBe('Define your server to your Odac account')
|
|
72
|
+
expect(Commands.debug.description).toBe('Debug Odac Server')
|
|
73
73
|
expect(Commands.help.description).toBe('List all available commands')
|
|
74
74
|
expect(Commands.monit.description).toBe('Monitor Website or Service')
|
|
75
|
-
expect(Commands.restart.description).toBe('Restart
|
|
75
|
+
expect(Commands.restart.description).toBe('Restart Odac Server')
|
|
76
76
|
expect(Commands.run.description).toBe('Add a new Service')
|
|
77
77
|
})
|
|
78
78
|
})
|