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.
Files changed (208) hide show
  1. package/.github/workflows/auto-pr-description.yml +0 -2
  2. package/.github/workflows/codeql.yml +46 -0
  3. package/.github/workflows/release.yml +13 -6
  4. package/.github/workflows/test-coverage.yml +10 -9
  5. package/.releaserc.js +9 -6
  6. package/CHANGELOG.md +62 -150
  7. package/CODE_OF_CONDUCT.md +1 -1
  8. package/CONTRIBUTING.md +8 -8
  9. package/LICENSE +21 -661
  10. package/README.md +12 -12
  11. package/SECURITY.md +4 -4
  12. package/bin/odac.js +101 -0
  13. package/{framework/web/candy.js → client/odac.js} +310 -44
  14. package/docs/backend/01-overview/{01-whats-in-the-candy-box.md → 01-whats-in-the-odac-box.md} +4 -2
  15. package/docs/backend/01-overview/02-super-handy-helper-functions.md +29 -1
  16. package/docs/backend/01-overview/03-development-server.md +11 -11
  17. package/docs/backend/02-structure/01-typical-project-layout.md +4 -4
  18. package/docs/backend/03-config/00-configuration-overview.md +6 -6
  19. package/docs/backend/03-config/01-database-connection.md +1 -1
  20. package/docs/backend/03-config/02-static-route-mapping-optional.md +4 -4
  21. package/docs/backend/03-config/04-environment-variables.md +20 -20
  22. package/docs/backend/03-config/05-early-hints.md +4 -4
  23. package/docs/backend/04-routing/01-basic-page-routes.md +4 -4
  24. package/docs/backend/04-routing/02-controller-less-view-routes.md +5 -5
  25. package/docs/backend/04-routing/03-api-and-data-routes.md +3 -3
  26. package/docs/backend/04-routing/04-authentication-aware-routes.md +5 -5
  27. package/docs/backend/04-routing/05-advanced-routing.md +3 -3
  28. package/docs/backend/04-routing/06-error-pages.md +17 -17
  29. package/docs/backend/04-routing/07-cron-jobs.md +13 -13
  30. package/docs/backend/04-routing/08-middleware.md +214 -0
  31. package/docs/backend/04-routing/09-websocket-auth-middleware.md +292 -0
  32. package/docs/backend/04-routing/09-websocket-examples.md +381 -0
  33. package/docs/backend/04-routing/09-websocket-quick-reference.md +211 -0
  34. package/docs/backend/04-routing/09-websocket.md +298 -0
  35. package/docs/backend/05-controllers/01-how-to-build-a-controller.md +3 -3
  36. package/docs/backend/05-controllers/02-your-trusty-odac-assistant.md +41 -0
  37. package/docs/backend/05-controllers/03-controller-classes.md +19 -19
  38. package/docs/backend/05-forms/01-custom-forms.md +114 -114
  39. package/docs/backend/05-forms/02-automatic-database-insert.md +82 -82
  40. package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +26 -26
  41. package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +10 -10
  42. package/docs/backend/07-views/01-the-view-directory.md +1 -1
  43. package/docs/backend/07-views/02-rendering-a-view.md +22 -22
  44. package/docs/backend/07-views/03-template-syntax.md +52 -52
  45. package/docs/backend/07-views/03-variables.md +84 -84
  46. package/docs/backend/07-views/04-request-data.md +57 -57
  47. package/docs/backend/07-views/05-conditionals.md +78 -78
  48. package/docs/backend/07-views/06-loops.md +114 -114
  49. package/docs/backend/07-views/07-translations.md +66 -66
  50. package/docs/backend/07-views/08-backend-javascript.md +103 -103
  51. package/docs/backend/07-views/09-comments.md +71 -71
  52. package/docs/backend/08-database/01-database-connection.md +8 -8
  53. package/docs/backend/08-database/02-using-mysql.md +49 -49
  54. package/docs/backend/09-validation/01-the-validator-service.md +38 -38
  55. package/docs/backend/10-authentication/01-user-logins-with-authjs.md +15 -15
  56. package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +10 -10
  57. package/docs/backend/10-authentication/03-register.md +12 -12
  58. package/docs/backend/10-authentication/{04-candy-register-forms.md → 04-odac-register-forms.md} +141 -141
  59. package/docs/backend/10-authentication/05-session-management.md +10 -10
  60. package/docs/backend/10-authentication/{06-candy-login-forms.md → 06-odac-login-forms.md} +125 -125
  61. package/docs/backend/11-mail/01-the-mail-service.md +5 -5
  62. package/docs/backend/12-streaming/01-streaming-overview.md +96 -54
  63. package/docs/backend/13-utilities/{01-candy-var.md → 01-odac-var.md} +109 -109
  64. package/docs/frontend/01-overview/01-introduction.md +30 -30
  65. package/docs/frontend/02-ajax-navigation/01-quick-start.md +45 -45
  66. package/docs/frontend/02-ajax-navigation/02-configuration.md +14 -14
  67. package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +36 -36
  68. package/docs/frontend/03-forms/01-form-handling.md +32 -32
  69. package/docs/frontend/04-api-requests/01-get-post.md +33 -33
  70. package/docs/frontend/05-streaming/01-client-streaming.md +15 -15
  71. package/docs/frontend/06-websocket/00-overview.md +76 -0
  72. package/docs/frontend/06-websocket/01-websocket-client.md +139 -0
  73. package/docs/frontend/06-websocket/02-shared-websocket.md +149 -0
  74. package/docs/index.json +49 -11
  75. package/eslint.config.mjs +6 -6
  76. package/{framework/index.js → index.js} +1 -1
  77. package/package.json +14 -39
  78. package/{framework/src → src}/Auth.js +59 -59
  79. package/{framework/src → src}/Config.js +3 -3
  80. package/{framework/src → src}/Lang.js +7 -7
  81. package/{framework/src → src}/Mail.js +5 -5
  82. package/{framework/src → src}/Mysql.js +42 -42
  83. package/src/Odac.js +112 -0
  84. package/{framework/src → src}/Request.js +38 -36
  85. package/{framework/src → src}/Route/Internal.js +116 -116
  86. package/src/Route/Middleware.js +75 -0
  87. package/src/Route.js +621 -0
  88. package/src/Server.js +22 -0
  89. package/{framework/src → src}/Stream.js +11 -3
  90. package/{framework/src → src}/Validator.js +21 -21
  91. package/{framework/src → src}/Var.js +5 -5
  92. package/{framework/src → src}/View/EarlyHints.js +1 -1
  93. package/{framework/src → src}/View/Form.js +69 -69
  94. package/{framework/src → src}/View.js +78 -81
  95. package/src/WebSocket.js +403 -0
  96. package/template/config.json +5 -0
  97. package/{web → template}/controller/page/about.js +6 -6
  98. package/{web → template}/controller/page/index.js +9 -9
  99. package/{web → template}/package.json +4 -5
  100. package/{web → template}/public/assets/css/style.css +4 -4
  101. package/{web → template}/public/assets/js/app.js +6 -6
  102. package/{web → template}/route/www.js +6 -6
  103. package/{web → template}/skeleton/main.html +1 -1
  104. package/{web → template}/view/content/about.html +5 -5
  105. package/{web → template}/view/content/home.html +12 -12
  106. package/template/view/footer/main.html +11 -0
  107. package/{web → template}/view/head/main.html +1 -1
  108. package/{web → template}/view/header/main.html +2 -2
  109. package/test/core/Candy.test.js +58 -58
  110. package/test/core/Commands.test.js +7 -7
  111. package/test/core/Config.test.js +82 -85
  112. package/test/core/Lang.test.js +2 -2
  113. package/test/core/Process.test.js +6 -6
  114. package/test/framework/Route.test.js +56 -37
  115. package/test/framework/View/EarlyHints.test.js +2 -2
  116. package/test/framework/WebSocket.test.js +100 -0
  117. package/test/framework/middleware.test.js +85 -0
  118. package/test/server/Api.test.js +31 -31
  119. package/test/server/DNS.test.js +11 -11
  120. package/test/server/Hub.test.js +497 -0
  121. package/test/server/Mail.account.test_.js +3 -3
  122. package/test/server/Mail.init.test_.js +10 -10
  123. package/test/server/Mail.test_.js +20 -20
  124. package/test/server/SSL.test_.js +54 -54
  125. package/test/server/Server.test.js +39 -39
  126. package/test/server/Service.test_.js +7 -7
  127. package/test/server/Subdomain.test.js +7 -7
  128. package/test/server/Web/Firewall.test.js +87 -87
  129. package/test/server/Web/Proxy.test.js +397 -0
  130. package/test/server/{Web.test_.js → Web.test.js} +137 -205
  131. package/test/server/__mocks__/fs.js +2 -2
  132. package/test/server/__mocks__/{globalCandy.js → globalOdac.js} +5 -5
  133. package/test/server/__mocks__/index.js +6 -6
  134. package/test/server/__mocks__/testFactories.js +1 -1
  135. package/test/server/__mocks__/testHelpers.js +7 -7
  136. package/.husky/pre-commit +0 -2
  137. package/.kiro/steering/code-style.md +0 -56
  138. package/.kiro/steering/product.md +0 -20
  139. package/.kiro/steering/structure.md +0 -77
  140. package/.kiro/steering/tech.md +0 -87
  141. package/AGENTS.md +0 -84
  142. package/bin/candy +0 -10
  143. package/bin/candypack +0 -10
  144. package/cli/index.js +0 -3
  145. package/cli/src/Cli.js +0 -348
  146. package/cli/src/Connector.js +0 -93
  147. package/cli/src/Monitor.js +0 -416
  148. package/core/Candy.js +0 -87
  149. package/core/Commands.js +0 -239
  150. package/core/Config.js +0 -1094
  151. package/core/Lang.js +0 -52
  152. package/core/Log.js +0 -43
  153. package/core/Process.js +0 -26
  154. package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +0 -20
  155. package/docs/server/01-installation/01-quick-install.md +0 -19
  156. package/docs/server/01-installation/02-manual-installation-via-npm.md +0 -9
  157. package/docs/server/02-get-started/01-core-concepts.md +0 -7
  158. package/docs/server/02-get-started/02-basic-commands.md +0 -57
  159. package/docs/server/02-get-started/03-cli-reference.md +0 -276
  160. package/docs/server/02-get-started/04-cli-quick-reference.md +0 -102
  161. package/docs/server/03-service/01-start-a-new-service.md +0 -57
  162. package/docs/server/03-service/02-delete-a-service.md +0 -48
  163. package/docs/server/04-web/01-create-a-website.md +0 -36
  164. package/docs/server/04-web/02-list-websites.md +0 -9
  165. package/docs/server/04-web/03-delete-a-website.md +0 -29
  166. package/docs/server/05-subdomain/01-create-a-subdomain.md +0 -32
  167. package/docs/server/05-subdomain/02-list-subdomains.md +0 -33
  168. package/docs/server/05-subdomain/03-delete-a-subdomain.md +0 -41
  169. package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +0 -34
  170. package/docs/server/07-mail/01-create-a-mail-account.md +0 -23
  171. package/docs/server/07-mail/02-delete-a-mail-account.md +0 -20
  172. package/docs/server/07-mail/03-list-mail-accounts.md +0 -20
  173. package/docs/server/07-mail/04-change-account-password.md +0 -23
  174. package/framework/src/Candy.js +0 -81
  175. package/framework/src/Route.js +0 -455
  176. package/framework/src/Server.js +0 -15
  177. package/locale/de-DE.json +0 -80
  178. package/locale/en-US.json +0 -79
  179. package/locale/es-ES.json +0 -80
  180. package/locale/fr-FR.json +0 -80
  181. package/locale/pt-BR.json +0 -80
  182. package/locale/ru-RU.json +0 -80
  183. package/locale/tr-TR.json +0 -85
  184. package/locale/zh-CN.json +0 -80
  185. package/server/index.js +0 -5
  186. package/server/src/Api.js +0 -88
  187. package/server/src/DNS.js +0 -940
  188. package/server/src/Hub.js +0 -535
  189. package/server/src/Mail.js +0 -571
  190. package/server/src/SSL.js +0 -180
  191. package/server/src/Server.js +0 -27
  192. package/server/src/Service.js +0 -248
  193. package/server/src/Subdomain.js +0 -64
  194. package/server/src/Web/Firewall.js +0 -170
  195. package/server/src/Web/Proxy.js +0 -134
  196. package/server/src/Web.js +0 -451
  197. package/server/src/mail/imap.js +0 -1091
  198. package/server/src/mail/server.js +0 -32
  199. package/server/src/mail/smtp.js +0 -786
  200. package/test/server/Client.test.js +0 -338
  201. package/test/server/__mocks__/http-proxy.js +0 -105
  202. package/watchdog/index.js +0 -3
  203. package/watchdog/src/Watchdog.js +0 -156
  204. package/web/config.json +0 -5
  205. package/web/view/footer/main.html +0 -11
  206. /package/{framework/src → src}/Env.js +0 -0
  207. /package/{framework/src → src}/Route/Cron.js +0 -0
  208. /package/{framework/src → src}/Token.js +0 -0
@@ -1,41 +1,41 @@
1
- # Frontend Javascript Framework: candy.js
1
+ # Frontend Javascript Framework: odac.js
2
2
 
3
- `candy.js` is a lightweight frontend JavaScript framework designed to simplify interactions with the backend, handle forms, and manage page-specific logic within the CandyPack ecosystem. It provides a set of tools for event handling, AJAX requests, and more, all accessible through the global `Candy` object.
3
+ `odac.js` is a lightweight frontend JavaScript framework designed to simplify interactions with the backend, handle forms, and manage page-specific logic within the Odac ecosystem. It provides a set of tools for event handling, AJAX requests, and more, all accessible through the global `odac` object.
4
4
 
5
- ## The Global `Candy` Object
5
+ ## The Global `odac` Object
6
6
 
7
- After including `candy.js` in your page, you will have access to a global `Candy` object. This object is the main entry point for all the features of the framework.
7
+ After including `odac.js` in your page, you will have access to a global `odac` object. This object is the main entry point for all the features of the framework.
8
8
 
9
9
  ## Core Concepts
10
10
 
11
11
  ### Actions
12
12
 
13
- Actions are the fundamental building block of `candy.js`. An action is a collection of event handlers and lifecycle callbacks that define the behavior of a page or a component.
13
+ Actions are the fundamental building block of `odac.js`. An action is a collection of event handlers and lifecycle callbacks that define the behavior of a page or a component.
14
14
 
15
15
  ### Pages
16
16
 
17
- `candy.js` has a concept of "pages", which allows you to scope your JavaScript to a specific page. The current page identifier is determined by the backend based on:
17
+ `odac.js` has a concept of "pages", which allows you to scope your JavaScript to a specific page. The current page identifier is determined by the backend based on:
18
18
  - **Controller name** when using controller files (e.g., `'user'` for `controller/page/user.js`)
19
19
  - **View name** when using view objects (e.g., `'dashboard'` from `{content: 'dashboard'}`)
20
- - This identifier is accessible via `Candy.page()` and stored in `data-candy-page` attribute on the `<html>` element.
20
+ - This identifier is accessible via `Odac.page()` and stored in `data-odac-page` attribute on the `<html>` element.
21
21
 
22
22
  ### Lifecycle Events
23
23
 
24
- `candy.js` provides several lifecycle events that you can hook into:
24
+ `odac.js` provides several lifecycle events that you can hook into:
25
25
  - `start`: Fired once when the script is initialized.
26
26
  - `load`: Fired on every page load, after the DOM is ready.
27
27
  - `page`: Fired on a specific page, after the DOM is ready.
28
28
  - `interval`: Fired repeatedly at a specified interval.
29
29
 
30
- ## Event Handling with `Candy.action()`
30
+ ## Event Handling with `Odac.action()`
31
31
 
32
- The `Candy.action()` method is the most important method in the framework. It allows you to register event handlers and lifecycle callbacks.
32
+ The `Odac.action()` method is the most important method in the framework. It allows you to register event handlers and lifecycle callbacks.
33
33
 
34
34
  ```javascript
35
- Candy.action({
35
+ Odac.action({
36
36
  // Fired once on DOMContentLoaded
37
37
  start: function() {
38
- console.log('Candy.js started!');
38
+ console.log('odac.js started!');
39
39
  },
40
40
 
41
41
  // Fired on every page load
@@ -82,19 +82,19 @@ Candy.action({
82
82
  });
83
83
  ```
84
84
 
85
- ## Working with Forms using `Candy.form()`
85
+ ## Working with Forms using `Odac.form()`
86
86
 
87
- `Candy.form()` simplifies AJAX form submissions. It handles serialization, validation feedback, success messages, and file uploads automatically.
87
+ `Odac.form()` simplifies AJAX form submissions. It handles serialization, validation feedback, success messages, and file uploads automatically.
88
88
 
89
89
  ```javascript
90
90
  // Basic usage
91
- Candy.form('#my-form', function(data) {
91
+ odac.form('#my-form', function(data) {
92
92
  // This callback is executed on success
93
93
  console.log('Form submitted successfully!', data);
94
94
  });
95
95
 
96
96
  // With options
97
- Candy.form({
97
+ odac.form({
98
98
  form: '#my-form',
99
99
  messages: ['success', 'error'], // Show both success and error messages
100
100
  loading: function(percent) {
@@ -107,40 +107,40 @@ Candy.form({
107
107
  }
108
108
  });
109
109
  ```
110
- To display validation errors, you can add elements with the `candy-form-error` attribute to your form. The value of the attribute should be the `name` of the input field.
110
+ To display validation errors, you can add elements with the `odac-form-error` attribute to your form. The value of the attribute should be the `name` of the input field.
111
111
 
112
112
  ```html
113
113
  <input type="text" name="email">
114
- <span candy-form-error="email"></span>
114
+ <span odac-form-error="email"></span>
115
115
  ```
116
116
 
117
- ## Making AJAX requests with `Candy.get()`
117
+ ## Making AJAX requests with `Odac.get()`
118
118
 
119
- For simple GET requests, you can use the `Candy.get()` method.
119
+ For simple GET requests, you can use the `Odac.get()` method.
120
120
 
121
121
  ```javascript
122
- Candy.get('/api/users', function(data) {
122
+ odac.get('/api/users', function(data) {
123
123
  console.log('Users:', data);
124
124
  });
125
125
  ```
126
126
 
127
- ## Managing CSRF tokens with `Candy.token()`
127
+ ## Managing CSRF tokens with `Odac.token()`
128
128
 
129
- `candy.js` automatically manages CSRF tokens for you. The `Candy.token()` method will return a valid token for your requests. The `Candy.form()` and `Candy.get()` methods use this automatically, so you usually don't need to call it yourself.
129
+ `odac.js` automatically manages CSRF tokens for you. The `Odac.token()` method will return a valid token for your requests. The `Odac.form()` and `Odac.get()` methods use this automatically, so you usually don't need to call it yourself.
130
130
 
131
131
  ## Other Utility Functions
132
132
 
133
- - **`Candy.client()`**: Returns a unique client identifier from a cookie.
134
- - **`Candy.data()`**: Returns data from the `candy_data` cookie, which is set by the backend. This data includes the current page and the initial CSRF token.
135
- - **`Candy.page()`**: Returns the identifier of the current page. This is the controller name (e.g., `'user'`) or view name (e.g., `'dashboard'`) set by the backend. Use this to conditionally run code for specific pages.
136
- - **`Candy.storage()`**: A wrapper for `localStorage`.
133
+ - **`Odac.client()`**: Returns a unique client identifier from a cookie.
134
+ - **`Odac.data()`**: Returns data from the `candy_data` cookie, which is set by the backend. This data includes the current page and the initial CSRF token.
135
+ - **`Odac.page()`**: Returns the identifier of the current page. This is the controller name (e.g., `'user'`) or view name (e.g., `'dashboard'`) set by the backend. Use this to conditionally run code for specific pages.
136
+ - **`Odac.storage()`**: A wrapper for `localStorage`.
137
137
  ```javascript
138
138
  // Set a value
139
- Candy.storage('my-key', 'my-value');
139
+ odac.storage('my-key', 'my-value');
140
140
 
141
141
  // Get a value
142
- let value = Candy.storage('my-key');
142
+ let value = odac.storage('my-key');
143
143
 
144
144
  // Remove a value
145
- Candy.storage('my-key', null);
145
+ odac.storage('my-key', null);
146
146
  ```
@@ -1,6 +1,6 @@
1
1
  # AJAX Navigation
2
2
 
3
- CandyPack framework includes a built-in AJAX navigation system that enables smooth, single-page application (SPA) style navigation without full page reloads.
3
+ Odac framework includes a built-in AJAX navigation system that enables smooth, single-page application (SPA) style navigation without full page reloads.
4
4
 
5
5
  ## Features
6
6
 
@@ -19,7 +19,7 @@ CandyPack framework includes a built-in AJAX navigation system that enables smoo
19
19
  Just enable navigation - it automatically handles all internal links:
20
20
 
21
21
  ```javascript
22
- Candy.action({
22
+ Odac.action({
23
23
  navigate: 'main' // Update <main> element on navigation
24
24
  })
25
25
  ```
@@ -31,7 +31,7 @@ That's it! All links starting with `/` will now load via AJAX.
31
31
  Add a callback for post-navigation actions:
32
32
 
33
33
  ```javascript
34
- Candy.action({
34
+ Odac.action({
35
35
  navigate: {
36
36
  update: 'main',
37
37
  on: function(page, variables) {
@@ -47,7 +47,7 @@ Candy.action({
47
47
  Full control over navigation behavior:
48
48
 
49
49
  ```javascript
50
- Candy.action({
50
+ Odac.action({
51
51
  navigate: {
52
52
  links: 'a[href^="/"]', // Which links to intercept
53
53
  update: { // Which elements to update
@@ -94,7 +94,7 @@ Example `skeleton/main.html`:
94
94
  <html>
95
95
  <head>
96
96
  <title>My Site</title>
97
- <script src="/assets/js/candy.js"></script>
97
+ <script src="/assets/js/odac.js"></script>
98
98
  <script src="/assets/js/app.js"></script>
99
99
  </head>
100
100
  <body>
@@ -120,22 +120,22 @@ Example `skeleton/main.html`:
120
120
 
121
121
  ### Controller Setup
122
122
 
123
- Controllers automatically support AJAX loading. Use `Candy.View.skeleton()` to specify which skeleton to use:
123
+ Controllers automatically support AJAX loading. Use `Odac.View.skeleton()` to specify which skeleton to use:
124
124
 
125
125
  ```javascript
126
- module.exports = function (Candy) {
126
+ module.exports = function (Odac) {
127
127
  // Define the skeleton template
128
- Candy.View.skeleton('main')
128
+ odac.View.skeleton('main')
129
129
 
130
130
  // Set view parts - lowercase keys map to UPPERCASE placeholders
131
- Candy.View.set({
131
+ odac.View.set({
132
132
  header: 'main', // Loads view/header/main.html into {{ HEADER }}
133
133
  content: 'about', // Loads view/content/about.html into {{ CONTENT }}
134
134
  footer: 'main' // Loads view/footer/main.html into {{ FOOTER }}
135
135
  })
136
136
 
137
137
  // Optional: Send variables to frontend (AJAX only)
138
- Candy.set({
138
+ odac.set({
139
139
  pageTitle: 'About',
140
140
  data: {foo: 'bar'}
141
141
  }, true) // true = include in AJAX responses
@@ -159,8 +159,8 @@ module.exports = function (Candy) {
159
159
 
160
160
  1. User clicks `<a href="/about">`
161
161
  2. JavaScript intercepts click and sends AJAX request with:
162
- - Header: `X-Candy: ajaxload`
163
- - Header: `X-Candy-Load: content,header` (requested sections)
162
+ - Header: `X-Odac: ajaxload`
163
+ - Header: `X-Odac-Load: content,header` (requested sections)
164
164
  3. Server detects AJAX request and returns only requested sections as JSON:
165
165
  ```json
166
166
  {
@@ -179,20 +179,20 @@ module.exports = function (Candy) {
179
179
  6. Page-specific callbacks execute
180
180
 
181
181
  **Key Points:**
182
- - The `output` keys in the JSON response match the lowercase keys from `Candy.View.set()` in your controller
182
+ - The `output` keys in the JSON response match the lowercase keys from `Odac.View.set()` in your controller
183
183
  - These keys correspond to UPPERCASE placeholders in your skeleton (e.g., `content` → `{{ CONTENT }}`)
184
184
  - Only the sections specified in `navigate.update` are sent and updated
185
185
  - Frontend selectors target the HTML tags wrapping the placeholders
186
186
 
187
187
  ## API Reference
188
188
 
189
- ### Candy.action({ navigate: ... })
189
+ ### Odac.action({ navigate: ... })
190
190
 
191
191
  Initialize AJAX navigation using the action system.
192
192
 
193
193
  #### Minimal Usage
194
194
  ```javascript
195
- Candy.action({
195
+ Odac.action({
196
196
  navigate: 'main' // Just specify element to update
197
197
  })
198
198
  ```
@@ -201,7 +201,7 @@ Candy.action({
201
201
 
202
202
  #### Medium Usage
203
203
  ```javascript
204
- Candy.action({
204
+ Odac.action({
205
205
  navigate: {
206
206
  update: 'main', // Element to update
207
207
  on: function(page, vars) { // Callback after navigation
@@ -213,7 +213,7 @@ Candy.action({
213
213
 
214
214
  #### Advanced Usage
215
215
  ```javascript
216
- Candy.action({
216
+ Odac.action({
217
217
  navigate: {
218
218
  links: 'a[href^="/"]', // Which links to intercept
219
219
  update: { // Multiple elements to update
@@ -232,12 +232,12 @@ Candy.action({
232
232
 
233
233
  #### Boolean Usage
234
234
  ```javascript
235
- Candy.action({
235
+ Odac.action({
236
236
  navigate: true // Enable with all defaults
237
237
  })
238
238
 
239
239
  // Or disable completely
240
- Candy.action({
240
+ Odac.action({
241
241
  navigate: false // Disable AJAX navigation
242
242
  })
243
243
  ```
@@ -296,13 +296,13 @@ Both methods work automatically - no additional configuration needed!
296
296
  }
297
297
  ```
298
298
 
299
- ### Candy.loader(selector, elements, callback)
299
+ ### odac.loader(selector, elements, callback)
300
300
 
301
301
  Low-level method for direct initialization (not recommended for new code).
302
302
 
303
303
  **Parameters:** Same as navigate configuration, but as separate arguments.
304
304
 
305
- ### Candy.load(url, callback, push)
305
+ ### odac.load(url, callback, push)
306
306
 
307
307
  Programmatically load a page via AJAX.
308
308
 
@@ -313,7 +313,7 @@ Programmatically load a page via AJAX.
313
313
 
314
314
  **Example:**
315
315
  ```javascript
316
- Candy.load('/about', function(page, variables) {
316
+ odac.load('/about', function(page, variables) {
317
317
  console.log('Loaded:', page)
318
318
  })
319
319
  ```
@@ -323,7 +323,7 @@ Candy.load('/about', function(page, variables) {
323
323
  Run code when specific pages load. The page identifier is based on the controller name or view name:
324
324
 
325
325
  ```javascript
326
- Candy.action({
326
+ Odac.action({
327
327
  page: {
328
328
  // Runs when controller/page/index.js is used
329
329
  index: function(variables) {
@@ -347,7 +347,7 @@ Candy.action({
347
347
  **Page Identifier Rules:**
348
348
  - **With controller**: Uses controller filename (e.g., `user.js` → `'user'`)
349
349
  - **With view object**: Uses `content` or `all` value (e.g., `{content: 'dashboard'}` → `'dashboard'`)
350
- - Accessible via `Candy.page()` or `document.documentElement.dataset.candyPage`
350
+ - Accessible via `Odac.page()` or `document.documentElement.dataset.candyPage`
351
351
 
352
352
  ## Server Variables
353
353
 
@@ -355,7 +355,7 @@ Send data from server to client in AJAX responses:
355
355
 
356
356
  ```javascript
357
357
  // In controller
358
- Candy.set({
358
+ odac.set({
359
359
  user: {name: 'John', role: 'admin'},
360
360
  stats: {views: 1234}
361
361
  }, true) // true = include in AJAX
@@ -364,7 +364,7 @@ Candy.set({
364
364
  Access in client:
365
365
 
366
366
  ```javascript
367
- Candy.action({
367
+ Odac.action({
368
368
  navigate: {
369
369
  update: 'main',
370
370
  on: function(page, variables) {
@@ -388,25 +388,25 @@ Candy.action({
388
388
  ### Minimal Example
389
389
  ```javascript
390
390
  // Just enable AJAX navigation
391
- Candy.action({
391
+ Odac.action({
392
392
  navigate: 'main'
393
393
  })
394
394
  ```
395
395
 
396
396
  ### Real-World Example
397
397
  ```javascript
398
- // app.js - Everything in one Candy.action() call
399
- Candy.action({
398
+ // app.js - Everything in one Odac.action() call
399
+ Odac.action({
400
400
  // AJAX Navigation - automatically handles all internal links
401
401
  navigate: {
402
402
  update: 'main',
403
403
  on: function(page, variables) {
404
- Candy.fn.updateActiveNav(window.location.pathname)
404
+ odac.fn.updateActiveNav(window.location.pathname)
405
405
  console.log('Navigated to:', page)
406
406
  }
407
407
  },
408
408
 
409
- // Custom functions (accessible as Candy.fn.functionName)
409
+ // Custom functions (accessible as odac.fn.functionName)
410
410
  function: {
411
411
  updateActiveNav: function(url) {
412
412
  document.querySelectorAll('nav a').forEach(link => {
@@ -418,14 +418,14 @@ Candy.action({
418
418
  // App initialization
419
419
  load: function() {
420
420
  console.log('App initialized')
421
- Candy.fn.updateActiveNav(window.location.pathname)
421
+ odac.fn.updateActiveNav(window.location.pathname)
422
422
  },
423
423
 
424
424
  // Page-specific code
425
425
  page: {
426
426
  index: function(variables) {
427
427
  // Home page specific code
428
- Candy.form('#contact-form', function(data) {
428
+ odac.form('#contact-form', function(data) {
429
429
  if (data.result.success) {
430
430
  alert('Message sent!')
431
431
  }
@@ -441,7 +441,7 @@ Candy.action({
441
441
  // Event handlers
442
442
  click: {
443
443
  '#refresh-btn': function() {
444
- Candy.load(window.location.pathname)
444
+ odac.load(window.location.pathname)
445
445
  }
446
446
  }
447
447
  })
@@ -449,7 +449,7 @@ Candy.action({
449
449
 
450
450
  ### Advanced Multi-Section Example
451
451
  ```javascript
452
- Candy.action({
452
+ Odac.action({
453
453
  navigate: {
454
454
  update: {
455
455
  content: 'main',
@@ -473,7 +473,7 @@ Candy.action({
473
473
 
474
474
  ### Disable Completely
475
475
  ```javascript
476
- Candy.action({
476
+ Odac.action({
477
477
  navigate: false // Disable AJAX navigation entirely
478
478
  })
479
479
  ```
@@ -505,7 +505,7 @@ Candy.action({
505
505
  ### 1. Use Minimal Configuration
506
506
  ```javascript
507
507
  // Simple and effective
508
- Candy.action({
508
+ Odac.action({
509
509
  navigate: 'main'
510
510
  })
511
511
  ```
@@ -524,7 +524,7 @@ Candy.action({
524
524
 
525
525
  ### 3. Handle Loading States
526
526
  ```javascript
527
- Candy.action({
527
+ Odac.action({
528
528
  navigate: {
529
529
  update: 'main',
530
530
  on: (page, vars) => {
@@ -546,7 +546,7 @@ Candy.action({
546
546
  ### Links not loading via AJAX
547
547
 
548
548
  - Check browser console for errors
549
- - Verify navigate is enabled in `Candy.action()`
549
+ - Verify navigate is enabled in `Odac.action()`
550
550
  - Ensure links start with `/` for internal navigation
551
551
 
552
552
  ### Specific links should not use AJAX
@@ -573,8 +573,8 @@ This is usually caused by mismatched keys between your skeleton, controller, and
573
573
 
574
574
  2. **Controller** (`controller/page/about.js`):
575
575
  ```javascript
576
- Candy.View.skeleton('main')
577
- Candy.View.set({
576
+ odac.View.skeleton('main')
577
+ odac.View.set({
578
578
  header: 'main', // Lowercase → {{ HEADER }}
579
579
  content: 'about' // Lowercase → {{ CONTENT }}
580
580
  })
@@ -582,7 +582,7 @@ This is usually caused by mismatched keys between your skeleton, controller, and
582
582
 
583
583
  3. **Frontend** (`public/assets/js/app.js`):
584
584
  ```javascript
585
- Candy.action({
585
+ Odac.action({
586
586
  navigate: {
587
587
  update: {
588
588
  header: 'header', // Targets <header> tag
@@ -599,10 +599,10 @@ This is usually caused by mismatched keys between your skeleton, controller, and
599
599
 
600
600
  **Also verify:**
601
601
  - Element selectors match actual DOM elements (e.g., `'main'` matches `<main>`)
602
- - Skeleton template is defined with `Candy.View.skeleton('main')`
603
- - View parts are defined in controller with `Candy.View.set()`
602
+ - Skeleton template is defined with `Odac.View.skeleton('main')`
603
+ - View parts are defined in controller with `Odac.View.set()`
604
604
 
605
605
  ### Variables not available
606
606
 
607
- - Confirm `Candy.set(data, true)` has `true` as second parameter
607
+ - Confirm `Odac.set(data, true)` has `true` as second parameter
608
608
  - Check that variables are set before `View.print()` is called
@@ -1,6 +1,6 @@
1
1
  # AJAX Navigation Configuration
2
2
 
3
- Learn how to configure and customize AJAX navigation in your CandyPack application.
3
+ Learn how to configure and customize AJAX navigation in your Odac application.
4
4
 
5
5
  ## Prerequisites
6
6
 
@@ -23,7 +23,7 @@ Before configuring AJAX navigation, ensure your skeleton template is properly se
23
23
  The simplest way to enable AJAX navigation:
24
24
 
25
25
  ```javascript
26
- Candy.action({
26
+ Odac.action({
27
27
  navigate: 'main' // Update <main> element
28
28
  })
29
29
  ```
@@ -33,7 +33,7 @@ Candy.action({
33
33
  All available options:
34
34
 
35
35
  ```javascript
36
- Candy.action({
36
+ Odac.action({
37
37
  navigate: {
38
38
  // Which links to intercept
39
39
  links: 'a[href^="/"]', // Default: all internal links
@@ -129,7 +129,7 @@ The keys (content, header, etc.) must match the view parts defined in your contr
129
129
 
130
130
  ```javascript
131
131
  // In controller
132
- Candy.View.set({
132
+ odac.View.set({
133
133
  header: 'main',
134
134
  content: 'about',
135
135
  sidebar: 'main'
@@ -170,7 +170,7 @@ navigate: {
170
170
  Run code for specific pages:
171
171
 
172
172
  ```javascript
173
- Candy.action({
173
+ Odac.action({
174
174
  navigate: {
175
175
  update: 'main',
176
176
  on: (page, vars) => console.log('Navigated to:', page)
@@ -192,7 +192,7 @@ Candy.action({
192
192
  ### Disable Completely
193
193
 
194
194
  ```javascript
195
- Candy.action({
195
+ Odac.action({
196
196
  navigate: false // No AJAX navigation
197
197
  })
198
198
  ```
@@ -217,16 +217,16 @@ Candy.action({
217
217
  In your controller, send data to the client:
218
218
 
219
219
  ```javascript
220
- module.exports = function(Candy) {
220
+ module.exports = function(Odac) {
221
221
  // Set variables for AJAX responses
222
- Candy.set({
222
+ odac.set({
223
223
  title: 'About Page',
224
224
  user: {name: 'John', role: 'admin'},
225
225
  stats: {views: 1234}
226
226
  }, true) // true = include in AJAX
227
227
 
228
- Candy.View.skeleton('main')
229
- Candy.View.set({
228
+ odac.View.skeleton('main')
229
+ odac.View.set({
230
230
  header: 'main',
231
231
  content: 'about',
232
232
  footer: 'main'
@@ -256,7 +256,7 @@ navigate: {
256
256
  Show a loading spinner during navigation:
257
257
 
258
258
  ```javascript
259
- Candy.action({
259
+ Odac.action({
260
260
  navigate: {
261
261
  update: 'main',
262
262
  on: (page, vars) => {
@@ -290,7 +290,7 @@ Animated progress bar:
290
290
  ```javascript
291
291
  let progressBar = document.getElementById('progress')
292
292
 
293
- Candy.action({
293
+ Odac.action({
294
294
  navigate: {
295
295
  update: 'main',
296
296
  on: () => {
@@ -316,7 +316,7 @@ Candy.action({
316
316
  Confirm before navigating:
317
317
 
318
318
  ```javascript
319
- Candy.action({
319
+ Odac.action({
320
320
  navigate: {
321
321
  update: 'main'
322
322
  },
@@ -360,7 +360,7 @@ Candy.action({
360
360
 
361
361
  ### Variables Not Available
362
362
 
363
- - Confirm `Candy.set(data, true)` has `true` parameter
363
+ - Confirm `Odac.set(data, true)` has `true` parameter
364
364
  - Check variables are set before `View.print()`
365
365
 
366
366
  ## Next Steps