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,36 +1,36 @@
1
1
  # Advanced AJAX Navigation
2
2
 
3
- Advanced techniques and patterns for AJAX navigation in CandyPack.
3
+ Advanced techniques and patterns for AJAX navigation in Odac.
4
4
 
5
5
  **Note:** All examples assume you have properly configured your skeleton template and controller. See the [Quick Start guide](01-quick-start.md#skeleton-structure-required) for setup instructions.
6
6
 
7
7
  ## Programmatic Navigation
8
8
 
9
- ### Using Candy.load()
9
+ ### Using odac.load()
10
10
 
11
11
  Navigate programmatically from your code:
12
12
 
13
13
  ```javascript
14
14
  // Basic usage
15
- Candy.load('/about')
15
+ odac.load('/about')
16
16
 
17
17
  // With callback
18
- Candy.load('/about', function(page, variables) {
18
+ odac.load('/about', function(page, variables) {
19
19
  console.log('Loaded:', page)
20
20
  console.log('Data:', variables)
21
21
  })
22
22
 
23
23
  // Without updating history
24
- Candy.load('/about', callback, false)
24
+ odac.load('/about', callback, false)
25
25
  ```
26
26
 
27
27
  ### Use Cases
28
28
 
29
29
  **Redirect after form submission:**
30
30
  ```javascript
31
- Candy.form('#my-form', function(data) {
31
+ odac.form('#my-form', function(data) {
32
32
  if (data.result.success) {
33
- Candy.load('/success')
33
+ odac.load('/success')
34
34
  }
35
35
  })
36
36
  ```
@@ -38,16 +38,16 @@ Candy.form('#my-form', function(data) {
38
38
  **Conditional navigation:**
39
39
  ```javascript
40
40
  if (user.isLoggedIn) {
41
- Candy.load('/dashboard')
41
+ odac.load('/dashboard')
42
42
  } else {
43
- Candy.load('/login')
43
+ odac.load('/login')
44
44
  }
45
45
  ```
46
46
 
47
47
  **Timed navigation:**
48
48
  ```javascript
49
49
  setTimeout(() => {
50
- Candy.load('/next-page')
50
+ odac.load('/next-page')
51
51
  }, 3000)
52
52
  ```
53
53
 
@@ -58,7 +58,7 @@ setTimeout(() => {
58
58
  Update different parts of your page simultaneously:
59
59
 
60
60
  ```javascript
61
- Candy.action({
61
+ Odac.action({
62
62
  navigate: {
63
63
  update: {
64
64
  content: 'main',
@@ -75,9 +75,9 @@ Candy.action({
75
75
  Define all parts in your controller:
76
76
 
77
77
  ```javascript
78
- module.exports = function(Candy) {
79
- Candy.View.skeleton('main')
80
- Candy.View.set({
78
+ module.exports = function(Odac) {
79
+ odac.View.skeleton('main')
80
+ odac.View.set({
81
81
  header: 'main',
82
82
  content: 'dashboard',
83
83
  sidebar: 'dashboard',
@@ -100,7 +100,7 @@ let appState = {
100
100
  filters: {}
101
101
  }
102
102
 
103
- Candy.action({
103
+ Odac.action({
104
104
  navigate: {
105
105
  update: 'main',
106
106
  on: function(page, variables) {
@@ -121,7 +121,7 @@ Candy.action({
121
121
  Persist state across page reloads:
122
122
 
123
123
  ```javascript
124
- Candy.action({
124
+ Odac.action({
125
125
  navigate: {
126
126
  update: 'main',
127
127
  on: function(page, variables) {
@@ -148,7 +148,7 @@ Candy.action({
148
148
  Add custom animations:
149
149
 
150
150
  ```javascript
151
- Candy.action({
151
+ Odac.action({
152
152
  navigate: {
153
153
  update: 'main',
154
154
  on: function(page, variables) {
@@ -170,7 +170,7 @@ Candy.action({
170
170
  Smooth page transitions:
171
171
 
172
172
  ```javascript
173
- Candy.action({
173
+ Odac.action({
174
174
  navigate: {
175
175
  update: 'main',
176
176
  on: function(page, variables) {
@@ -209,7 +209,7 @@ main.page-enter-active {
209
209
  Automatically scroll to top on navigation:
210
210
 
211
211
  ```javascript
212
- Candy.action({
212
+ Odac.action({
213
213
  navigate: {
214
214
  update: 'main',
215
215
  on: function(page, variables) {
@@ -229,7 +229,7 @@ Remember scroll position:
229
229
  ```javascript
230
230
  let scrollPositions = {}
231
231
 
232
- Candy.action({
232
+ Odac.action({
233
233
  navigate: {
234
234
  update: 'main',
235
235
  on: function(page, variables) {
@@ -256,7 +256,7 @@ Candy.action({
256
256
  Scroll to specific element after navigation:
257
257
 
258
258
  ```javascript
259
- Candy.action({
259
+ Odac.action({
260
260
  navigate: {
261
261
  update: 'main',
262
262
  on: function(page, variables) {
@@ -282,10 +282,10 @@ Candy.action({
282
282
  Gracefully handle navigation errors:
283
283
 
284
284
  ```javascript
285
- // Override Candy.load to add error handling
286
- const originalLoad = Candy.load.bind(Candy)
285
+ // Override odac.load to add error handling
286
+ const originalLoad = odac.load.bind(Odac)
287
287
 
288
- Candy.load = function(url, callback, push) {
288
+ odac.load = function(url, callback, push) {
289
289
  try {
290
290
  originalLoad(url, function(page, variables) {
291
291
  if (callback) callback(page, variables)
@@ -308,7 +308,7 @@ function loadWithRetry(url, maxRetries = 3) {
308
308
 
309
309
  function attempt() {
310
310
  attempts++
311
- Candy.load(url,
311
+ odac.load(url,
312
312
  (page, vars) => {
313
313
  console.log('Success after', attempts, 'attempts')
314
314
  },
@@ -333,7 +333,7 @@ Prevent rapid navigation:
333
333
  ```javascript
334
334
  let navigationTimeout
335
335
 
336
- Candy.action({
336
+ Odac.action({
337
337
  click: {
338
338
  'a[href^="/"]': function(e) {
339
339
  clearTimeout(navigationTimeout)
@@ -353,7 +353,7 @@ Prefetch pages on hover:
353
353
  ```javascript
354
354
  let prefetchCache = {}
355
355
 
356
- Candy.action({
356
+ Odac.action({
357
357
  mouseover: {
358
358
  'a[href^="/"]': function() {
359
359
  const url = this.getAttribute('href')
@@ -362,7 +362,7 @@ Candy.action({
362
362
  // Prefetch the page
363
363
  fetch(url, {
364
364
  headers: {
365
- 'X-Candy': 'prefetch'
365
+ 'X-Odac': 'prefetch'
366
366
  }
367
367
  }).then(response => response.text())
368
368
  .then(html => {
@@ -381,7 +381,7 @@ Candy.action({
381
381
  Track page views:
382
382
 
383
383
  ```javascript
384
- Candy.action({
384
+ Odac.action({
385
385
  navigate: {
386
386
  update: 'main',
387
387
  on: function(page, variables) {
@@ -407,7 +407,7 @@ Candy.action({
407
407
  Redux/Vuex integration:
408
408
 
409
409
  ```javascript
410
- Candy.action({
410
+ Odac.action({
411
411
  navigate: {
412
412
  update: 'main',
413
413
  on: function(page, variables) {
@@ -430,7 +430,7 @@ Test navigation logic:
430
430
  ```javascript
431
431
  describe('Navigation', () => {
432
432
  it('should update active nav on page change', () => {
433
- Candy.action({
433
+ Odac.action({
434
434
  navigate: {
435
435
  update: 'main',
436
436
  on: (page) => {
@@ -440,7 +440,7 @@ describe('Navigation', () => {
440
440
  })
441
441
 
442
442
  // Simulate navigation
443
- Candy.load('/about')
443
+ odac.load('/about')
444
444
 
445
445
  // Assert
446
446
  expect(document.querySelector('.nav-link.active').href)
@@ -463,7 +463,7 @@ describe('Navigation', () => {
463
463
  ### Dashboard Navigation
464
464
 
465
465
  ```javascript
466
- Candy.action({
466
+ Odac.action({
467
467
  navigate: {
468
468
  links: '.sidebar a, .breadcrumb a',
469
469
  update: {
@@ -482,7 +482,7 @@ Candy.action({
482
482
  ### E-commerce
483
483
 
484
484
  ```javascript
485
- Candy.action({
485
+ Odac.action({
486
486
  navigate: {
487
487
  update: {
488
488
  content: 'main',
@@ -499,7 +499,7 @@ Candy.action({
499
499
  ### Blog
500
500
 
501
501
  ```javascript
502
- Candy.action({
502
+ Odac.action({
503
503
  navigate: {
504
504
  update: 'main',
505
505
  on: (page, vars) => {
@@ -516,4 +516,4 @@ Candy.action({
516
516
 
517
517
  - Learn about [Form Handling](../03-forms/01-form-handling.md)
518
518
  - Explore [API Requests](../04-api-requests/01-get-post.md)
519
- - Check [candy.js Overview](../01-overview/01-introduction.md)
519
+ - Check [odac.js Overview](../01-overview/01-introduction.md)
@@ -1,6 +1,6 @@
1
- # Form Handling with candy.js
1
+ # Form Handling with odac.js
2
2
 
3
- Learn how to handle forms with automatic AJAX submission, CSRF protection, and validation in CandyPack.
3
+ Learn how to handle forms with automatic AJAX submission, CSRF protection, and validation in Odac.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -14,14 +14,14 @@ Learn how to handle forms with automatic AJAX submission, CSRF protection, and v
14
14
  ```
15
15
 
16
16
  ```javascript
17
- Candy.form('#contact-form', function(data) {
17
+ odac.form('#contact-form', function(data) {
18
18
  if (data.result.success) {
19
19
  alert('Form submitted successfully!')
20
20
  }
21
21
  })
22
22
  ```
23
23
 
24
- That's it! candy.js handles:
24
+ That's it! odac.js handles:
25
25
  - ✅ AJAX submission
26
26
  - ✅ CSRF token (automatic)
27
27
  - ✅ Validation errors (auto-generated)
@@ -35,7 +35,7 @@ That's it! candy.js handles:
35
35
  ### Basic Usage
36
36
 
37
37
  ```javascript
38
- Candy.form('#my-form', function(data) {
38
+ odac.form('#my-form', function(data) {
39
39
  console.log('Response:', data)
40
40
  })
41
41
  ```
@@ -43,7 +43,7 @@ Candy.form('#my-form', function(data) {
43
43
  ### With Options
44
44
 
45
45
  ```javascript
46
- Candy.form({
46
+ odac.form({
47
47
  form: '#my-form',
48
48
  messages: true, // Show error/success messages
49
49
  loading: function(percent) {
@@ -59,7 +59,7 @@ Candy.form({
59
59
  ### Redirect After Submit
60
60
 
61
61
  ```javascript
62
- Candy.form('#my-form', '/success-page')
62
+ odac.form('#my-form', '/success-page')
63
63
  // Redirects to /success-page on success
64
64
  ```
65
65
 
@@ -75,17 +75,17 @@ If you want to control where errors appear, add error elements manually:
75
75
 
76
76
  ```html
77
77
  <input name="email" type="email">
78
- <span candy-form-error="email"></span>
78
+ <span odac-form-error="email"></span>
79
79
  ```
80
80
 
81
- **If not present:** The system automatically creates `<span candy-form-error="email">` after the input field.
81
+ **If not present:** The system automatically creates `<span odac-form-error="email">` after the input field.
82
82
 
83
83
  **If present:** The system uses your existing element and updates its content.
84
84
 
85
85
  ### Custom Error Display
86
86
 
87
87
  ```javascript
88
- Candy.form('#my-form', function(data) {
88
+ odac.form('#my-form', function(data) {
89
89
  if (!data.result.success) {
90
90
  // Custom error handling
91
91
  Object.entries(data.errors).forEach(([field, message]) => {
@@ -99,7 +99,7 @@ Candy.form('#my-form', function(data) {
99
99
 
100
100
  ```css
101
101
  /* Error message */
102
- [candy-form-error] {
102
+ [odac-form-error] {
103
103
  color: #ef4444;
104
104
  font-size: 0.875rem;
105
105
  margin-top: 0.25rem;
@@ -107,7 +107,7 @@ Candy.form('#my-form', function(data) {
107
107
  }
108
108
 
109
109
  /* Invalid input */
110
- input._candy_error {
110
+ input._odac_error {
111
111
  border-color: #ef4444;
112
112
  }
113
113
  ```
@@ -126,18 +126,18 @@ If you want to control where success messages appear, add a success element manu
126
126
  <form id="my-form" action="/api/submit" method="POST">
127
127
  <!-- form fields -->
128
128
  <button type="submit">Submit</button>
129
- <div candy-form-success></div>
129
+ <div odac-form-success></div>
130
130
  </form>
131
131
  ```
132
132
 
133
- **If not present:** The system automatically creates `<span candy-form-success>` at the end of the form.
133
+ **If not present:** The system automatically creates `<span odac-form-success>` at the end of the form.
134
134
 
135
135
  **If present:** The system uses your existing element and updates its content.
136
136
 
137
137
  ### Custom Success Message
138
138
 
139
139
  ```javascript
140
- Candy.form('#my-form', function(data) {
140
+ odac.form('#my-form', function(data) {
141
141
  if (data.result.success) {
142
142
  document.querySelector('#custom-message').innerHTML =
143
143
  'Thank you! Your form has been submitted.'
@@ -157,7 +157,7 @@ Candy.form('#my-form', function(data) {
157
157
  ```
158
158
 
159
159
  ```javascript
160
- Candy.form('#upload-form', function(data) {
160
+ odac.form('#upload-form', function(data) {
161
161
  if (data.result.success) {
162
162
  console.log('File uploaded:', data.result.filename)
163
163
  }
@@ -167,7 +167,7 @@ Candy.form('#upload-form', function(data) {
167
167
  ### Upload Progress
168
168
 
169
169
  ```javascript
170
- Candy.form({
170
+ odac.form({
171
171
  form: '#upload-form',
172
172
  loading: function(percent) {
173
173
  document.querySelector('#progress').style.width = percent + '%'
@@ -189,7 +189,7 @@ Candy.form({
189
189
  ### Disable Messages
190
190
 
191
191
  ```javascript
192
- Candy.form({
192
+ odac.form({
193
193
  form: '#my-form',
194
194
  messages: false // Don't show automatic messages
195
195
  }, function(data) {
@@ -200,7 +200,7 @@ Candy.form({
200
200
  ### Disable Specific Messages
201
201
 
202
202
  ```javascript
203
- Candy.form({
203
+ odac.form({
204
204
  form: '#my-form',
205
205
  messages: ['error'] // Only show errors, not success
206
206
  }, function(data) {
@@ -211,7 +211,7 @@ Candy.form({
211
211
  ### Form Reset
212
212
 
213
213
  ```javascript
214
- Candy.form('#my-form', function(data) {
214
+ odac.form('#my-form', function(data) {
215
215
  if (data.result.success) {
216
216
  // Reset the form
217
217
  document.querySelector('#my-form').reset()
@@ -229,7 +229,7 @@ document.querySelector('#my-form').addEventListener('submit', function(e) {
229
229
  }
230
230
  })
231
231
 
232
- Candy.form('#my-form', function(data) {
232
+ odac.form('#my-form', function(data) {
233
233
  console.log('Submitted!')
234
234
  })
235
235
  ```
@@ -240,9 +240,9 @@ Candy.form('#my-form', function(data) {
240
240
 
241
241
  ```javascript
242
242
  // controller/post/contact.js
243
- module.exports = async function(Candy) {
244
- const email = await Candy.Request.request('email')
245
- const message = await Candy.Request.request('message')
243
+ module.exports = async function(Odac) {
244
+ const email = await odac.Request.request('email')
245
+ const message = await odac.Request.request('message')
246
246
 
247
247
  // Validation
248
248
  const errors = {}
@@ -272,7 +272,7 @@ module.exports = async function(Candy) {
272
272
 
273
273
  ```javascript
274
274
  // route/www.js
275
- Candy.Route.post('/api/contact', 'contact')
275
+ odac.Route.post('/api/contact', 'contact')
276
276
  ```
277
277
 
278
278
  ## Validation
@@ -292,8 +292,8 @@ Use HTML5 validation:
292
292
  Always validate on the server:
293
293
 
294
294
  ```javascript
295
- module.exports = async function(Candy) {
296
- const email = await Candy.Request.request('email')
295
+ module.exports = async function(Odac) {
296
+ const email = await odac.Request.request('email')
297
297
 
298
298
  const errors = {}
299
299
 
@@ -336,7 +336,7 @@ module.exports = async function(Candy) {
336
336
  **Note:** Error and success elements are auto-generated. Add them manually only if you need custom positioning or styling.
337
337
 
338
338
  ```javascript
339
- Candy.form('#contact-form', function(data) {
339
+ odac.form('#contact-form', function(data) {
340
340
  if (data.result.success) {
341
341
  document.querySelector('#contact-form').reset()
342
342
  }
@@ -354,7 +354,7 @@ Candy.form('#contact-form', function(data) {
354
354
  ```
355
355
 
356
356
  ```javascript
357
- Candy.form('#login-form', function(data) {
357
+ odac.form('#login-form', function(data) {
358
358
  if (data.result.success) {
359
359
  // Redirect to dashboard
360
360
  window.location.href = '/dashboard'
@@ -379,7 +379,7 @@ Candy.form('#login-form', function(data) {
379
379
  ```html
380
380
  <div class="form-group">
381
381
  <input name="email" type="email" required>
382
- <span candy-form-error="email" class="error-message"></span>
382
+ <span odac-form-error="email" class="error-message"></span>
383
383
  </div>
384
384
  ```
385
385
 
@@ -396,7 +396,7 @@ Candy.form('#login-form', function(data) {
396
396
 
397
397
  ### Form Not Submitting
398
398
 
399
- - Check that `Candy.form()` is called after DOM is ready
399
+ - Check that `Odac.form()` is called after DOM is ready
400
400
  - Verify the form selector is correct
401
401
  - Check browser console for errors
402
402
 
@@ -405,7 +405,7 @@ Candy.form('#login-form', function(data) {
405
405
  - Errors are automatically created - no manual elements needed
406
406
  - Check that server returns errors in correct format: `{result: {success: false}, errors: {fieldName: 'message'}}`
407
407
  - Verify `messages` option is not set to `false`
408
- - If using custom error elements, ensure `candy-form-error` attributes match field names exactly
408
+ - If using custom error elements, ensure `odac-form-error` attributes match field names exactly
409
409
 
410
410
  ### CSRF Token Errors
411
411