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,6 +1,6 @@
1
- # Candy Register Forms
1
+ # Odac Register Forms
2
2
 
3
- The `<candy:register>` component provides a zero-configuration way to create secure registration forms. Simply write HTML, and CandyPack handles validation, security, database operations, and auto-login automatically.
3
+ The `<odac:register>` component provides a zero-configuration way to create secure registration forms. Simply write HTML, and Odac handles validation, security, database operations, and auto-login automatically.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -22,21 +22,21 @@ That's all you need! The `auth` configuration is optional.
22
22
  ### 2. Create Your Form (view/content/register.html)
23
23
 
24
24
  ```html
25
- <candy:register redirect="/dashboard">
26
- <candy:field name="email" type="email" placeholder="Email" unique>
27
- <candy:validate rule="required|email" message="Please enter a valid email"/>
28
- </candy:field>
25
+ <odac:register redirect="/dashboard">
26
+ <odac:field name="email" type="email" placeholder="Email" unique>
27
+ <odac:validate rule="required|email" message="Please enter a valid email"/>
28
+ </odac:field>
29
29
 
30
- <candy:field name="username" type="text" placeholder="Username" unique>
31
- <candy:validate rule="required|minlen:4" message="Username must be at least 4 characters"/>
32
- </candy:field>
30
+ <odac:field name="username" type="text" placeholder="Username" unique>
31
+ <odac:validate rule="required|minlen:4" message="Username must be at least 4 characters"/>
32
+ </odac:field>
33
33
 
34
- <candy:field name="password" type="password" placeholder="Password">
35
- <candy:validate rule="required|minlen:8" message="Password must be at least 8 characters"/>
36
- </candy:field>
34
+ <odac:field name="password" type="password" placeholder="Password">
35
+ <odac:validate rule="required|minlen:8" message="Password must be at least 8 characters"/>
36
+ </odac:field>
37
37
 
38
- <candy:submit>Create Account</candy:submit>
39
- </candy:register>
38
+ <odac:submit>Create Account</odac:submit>
39
+ </odac:register>
40
40
  ```
41
41
 
42
42
  That's it! No JavaScript, no controller code, no SQL needed. The form automatically:
@@ -76,16 +76,16 @@ If you want to customize table names or primary key:
76
76
 
77
77
  ## Form Attributes
78
78
 
79
- ### `<candy:register>`
79
+ ### `<odac:register>`
80
80
 
81
81
  Main form container with configuration options:
82
82
 
83
83
  ```html
84
- <candy:register
84
+ <odac:register
85
85
  redirect="/dashboard" <!-- Redirect URL after successful registration -->
86
86
  autologin="true"> <!-- Auto-login after registration (default: true) -->
87
87
  <!-- fields here -->
88
- </candy:register>
88
+ </odac:register>
89
89
  ```
90
90
 
91
91
  **Attributes:**
@@ -94,20 +94,20 @@ Main form container with configuration options:
94
94
 
95
95
  ## Field Types
96
96
 
97
- ### `<candy:field>`
97
+ ### `<odac:field>`
98
98
 
99
99
  Defines an input field with validation rules:
100
100
 
101
101
  ```html
102
- <candy:field
102
+ <odac:field
103
103
  name="email" <!-- Field name (required) -->
104
104
  type="email" <!-- Input type (default: text) -->
105
105
  placeholder="Email" <!-- Placeholder text -->
106
106
  label="Email Address" <!-- Label text (optional) -->
107
107
  unique> <!-- Check uniqueness in database -->
108
108
 
109
- <candy:validate rule="required|email" message="Valid email required"/>
110
- </candy:field>
109
+ <odac:validate rule="required|email" message="Valid email required"/>
110
+ </odac:field>
111
111
  ```
112
112
 
113
113
  **Attributes:**
@@ -132,19 +132,19 @@ Use the `skip` attribute for fields that should be validated but not saved to th
132
132
 
133
133
  ```html
134
134
  <!-- Password confirmation - validate but don't save -->
135
- <candy:field name="confirm_password" type="password" placeholder="Confirm Password" skip>
136
- <candy:validate rule="required|same:password" message="Passwords must match"/>
137
- </candy:field>
135
+ <odac:field name="confirm_password" type="password" placeholder="Confirm Password" skip>
136
+ <odac:validate rule="required|same:password" message="Passwords must match"/>
137
+ </odac:field>
138
138
 
139
139
  <!-- Terms acceptance - validate but don't save -->
140
- <candy:field name="terms" type="checkbox" label="I accept the terms" skip>
141
- <candy:validate rule="accepted" message="You must accept the terms"/>
142
- </candy:field>
140
+ <odac:field name="terms" type="checkbox" label="I accept the terms" skip>
141
+ <odac:validate rule="accepted" message="You must accept the terms"/>
142
+ </odac:field>
143
143
 
144
144
  <!-- Captcha verification - validate but don't save -->
145
- <candy:field name="captcha" type="text" placeholder="Enter captcha" skip>
146
- <candy:validate rule="required" message="Please complete the captcha"/>
147
- </candy:field>
145
+ <odac:field name="captcha" type="text" placeholder="Enter captcha" skip>
146
+ <odac:validate rule="required" message="Please complete the captcha"/>
147
+ </odac:field>
148
148
  ```
149
149
 
150
150
  **Common Use Cases:**
@@ -156,12 +156,12 @@ Use the `skip` attribute for fields that should be validated but not saved to th
156
156
 
157
157
  ## Validation Rules
158
158
 
159
- ### `<candy:validate>`
159
+ ### `<odac:validate>`
160
160
 
161
161
  Defines validation rules for a field:
162
162
 
163
163
  ```html
164
- <candy:validate
164
+ <odac:validate
165
165
  rule="required|minlen:4|alphanumeric"
166
166
  message="Username must be 4+ alphanumeric characters"/>
167
167
  ```
@@ -210,27 +210,27 @@ Defines validation rules for a field:
210
210
 
211
211
  ### Multiple Validation Rules
212
212
 
213
- You can add multiple `<candy:validate>` tags for different error messages:
213
+ You can add multiple `<odac:validate>` tags for different error messages:
214
214
 
215
215
  ```html
216
- <candy:field name="username" type="text" unique>
217
- <candy:validate rule="required" message="Username is required"/>
218
- <candy:validate rule="minlen:4" message="Username must be at least {min} characters"/>
219
- <candy:validate rule="maxlen:20" message="Username cannot exceed {max} characters"/>
220
- <candy:validate rule="alphanumeric" message="Username can only contain letters and numbers"/>
221
- <candy:validate rule="unique" message="Username '{value}' is already taken"/>
222
- </candy:field>
216
+ <odac:field name="username" type="text" unique>
217
+ <odac:validate rule="required" message="Username is required"/>
218
+ <odac:validate rule="minlen:4" message="Username must be at least {min} characters"/>
219
+ <odac:validate rule="maxlen:20" message="Username cannot exceed {max} characters"/>
220
+ <odac:validate rule="alphanumeric" message="Username can only contain letters and numbers"/>
221
+ <odac:validate rule="unique" message="Username '{value}' is already taken"/>
222
+ </odac:field>
223
223
  ```
224
224
 
225
225
  Or combine rules in a single tag:
226
226
 
227
227
  ```html
228
- <candy:field name="username" type="text" unique>
229
- <candy:validate
228
+ <odac:field name="username" type="text" unique>
229
+ <odac:validate
230
230
  rule="required|minlen:4|maxlen:20|alphanumeric"
231
231
  message="Username must be 4-20 alphanumeric characters"/>
232
- <candy:validate rule="unique" message="Username '{value}' is already taken"/>
233
- </candy:field>
232
+ <odac:validate rule="unique" message="Username '{value}' is already taken"/>
233
+ </odac:field>
234
234
  ```
235
235
 
236
236
  ## Message Placeholders
@@ -238,17 +238,17 @@ Or combine rules in a single tag:
238
238
  Use placeholders in error messages for dynamic values:
239
239
 
240
240
  ```html
241
- <candy:field name="username" type="text">
242
- <candy:validate
241
+ <odac:field name="username" type="text">
242
+ <odac:validate
243
243
  rule="minlen:4"
244
244
  message="Username '{value}' is too short. Minimum {min} characters required"/>
245
- </candy:field>
245
+ </odac:field>
246
246
 
247
- <candy:field name="age" type="number">
248
- <candy:validate
247
+ <odac:field name="age" type="number">
248
+ <odac:validate
249
249
  rule="min:18|max:120"
250
250
  message="Age must be between {min} and {max} years"/>
251
- </candy:field>
251
+ </odac:field>
252
252
  ```
253
253
 
254
254
  **Available Placeholders:**
@@ -262,25 +262,25 @@ Use placeholders in error messages for dynamic values:
262
262
 
263
263
  ## Backend-Only Values
264
264
 
265
- ### `<candy:set>`
265
+ ### `<odac:set>`
266
266
 
267
267
  Set values that are processed only on the backend (not visible in HTML):
268
268
 
269
269
  ```html
270
- <candy:register redirect="/dashboard">
270
+ <odac:register redirect="/dashboard">
271
271
  <!-- User input fields -->
272
- <candy:field name="email" type="email" unique>
273
- <candy:validate rule="required|email"/>
274
- </candy:field>
272
+ <odac:field name="email" type="email" unique>
273
+ <odac:validate rule="required|email"/>
274
+ </odac:field>
275
275
 
276
276
  <!-- Backend-only values -->
277
- <candy:set name="role" value="user"/>
278
- <candy:set name="status" value="pending"/>
279
- <candy:set name="registered_at" compute="now"/>
280
- <candy:set name="ip_address" compute="ip"/>
277
+ <odac:set name="role" value="user"/>
278
+ <odac:set name="status" value="pending"/>
279
+ <odac:set name="registered_at" compute="now"/>
280
+ <odac:set name="ip_address" compute="ip"/>
281
281
 
282
- <candy:submit>Register</candy:submit>
283
- </candy:register>
282
+ <odac:submit>Register</odac:submit>
283
+ </odac:register>
284
284
  ```
285
285
 
286
286
  **Attributes:**
@@ -295,13 +295,13 @@ Set values that are processed only on the backend (not visible in HTML):
295
295
  Use `compute` attribute for dynamic values:
296
296
 
297
297
  ```html
298
- <candy:set name="registered_at" compute="now"/> <!-- Unix timestamp -->
299
- <candy:set name="date" compute="date"/> <!-- 2025-01-20 -->
300
- <candy:set name="datetime" compute="datetime"/> <!-- ISO 8601 -->
301
- <candy:set name="timestamp" compute="timestamp"/> <!-- Milliseconds -->
302
- <candy:set name="ip_address" compute="ip"/> <!-- User's IP -->
303
- <candy:set name="user_agent" compute="user_agent"/> <!-- Browser info -->
304
- <candy:set name="uuid" compute="uuid"/> <!-- UUID v4 -->
298
+ <odac:set name="registered_at" compute="now"/> <!-- Unix timestamp -->
299
+ <odac:set name="date" compute="date"/> <!-- 2025-01-20 -->
300
+ <odac:set name="datetime" compute="datetime"/> <!-- ISO 8601 -->
301
+ <odac:set name="timestamp" compute="timestamp"/> <!-- Milliseconds -->
302
+ <odac:set name="ip_address" compute="ip"/> <!-- User's IP -->
303
+ <odac:set name="user_agent" compute="user_agent"/> <!-- Browser info -->
304
+ <odac:set name="uuid" compute="uuid"/> <!-- UUID v4 -->
305
305
  ```
306
306
 
307
307
  ### Conditional Values
@@ -309,103 +309,103 @@ Use `compute` attribute for dynamic values:
309
309
  Use `if-empty` to set a default only if the user didn't provide a value:
310
310
 
311
311
  ```html
312
- <candy:field name="country" type="text" placeholder="Country (optional)">
312
+ <odac:field name="country" type="text" placeholder="Country (optional)">
313
313
  <!-- User can optionally fill this -->
314
- </candy:field>
314
+ </odac:field>
315
315
 
316
- <candy:set name="country" value="TR" if-empty/>
316
+ <odac:set name="country" value="TR" if-empty/>
317
317
  <!-- If user leaves it empty, set to "TR" -->
318
318
  ```
319
319
 
320
320
  ## Submit Button
321
321
 
322
- ### `<candy:submit>`
322
+ ### `<odac:submit>`
323
323
 
324
324
  Defines the submit button:
325
325
 
326
326
  ```html
327
- <candy:submit
327
+ <odac:submit
328
328
  text="Create Account" <!-- Button text -->
329
329
  loading="Creating account..."> <!-- Loading state text -->
330
- </candy:submit>
330
+ </odac:submit>
331
331
  ```
332
332
 
333
333
  Or use content as button text:
334
334
 
335
335
  ```html
336
- <candy:submit>Create Account</candy:submit>
336
+ <odac:submit>Create Account</odac:submit>
337
337
  ```
338
338
 
339
339
  ## Complete Example
340
340
 
341
341
  ```html
342
- <candy:register redirect="/dashboard" autologin="true">
342
+ <odac:register redirect="/dashboard" autologin="true">
343
343
 
344
344
  <!-- Email Field -->
345
- <candy:field name="email" type="email" placeholder="Email Address" unique>
346
- <candy:validate rule="required" message="Email is required"/>
347
- <candy:validate rule="email" message="Please enter a valid email address"/>
348
- <candy:validate rule="unique" message="The email '{value}' is already registered"/>
349
- </candy:field>
345
+ <odac:field name="email" type="email" placeholder="Email Address" unique>
346
+ <odac:validate rule="required" message="Email is required"/>
347
+ <odac:validate rule="email" message="Please enter a valid email address"/>
348
+ <odac:validate rule="unique" message="The email '{value}' is already registered"/>
349
+ </odac:field>
350
350
 
351
351
  <!-- Username Field -->
352
- <candy:field name="username" type="text" placeholder="Username" unique>
353
- <candy:validate rule="required" message="Username is required"/>
354
- <candy:validate rule="minlen:4" message="Username must be at least {min} characters"/>
355
- <candy:validate rule="maxlen:20" message="Username cannot exceed {max} characters"/>
356
- <candy:validate rule="alphanumeric" message="Only letters and numbers allowed"/>
357
- <candy:validate rule="unique" message="Username '{value}' is already taken"/>
358
- </candy:field>
352
+ <odac:field name="username" type="text" placeholder="Username" unique>
353
+ <odac:validate rule="required" message="Username is required"/>
354
+ <odac:validate rule="minlen:4" message="Username must be at least {min} characters"/>
355
+ <odac:validate rule="maxlen:20" message="Username cannot exceed {max} characters"/>
356
+ <odac:validate rule="alphanumeric" message="Only letters and numbers allowed"/>
357
+ <odac:validate rule="unique" message="Username '{value}' is already taken"/>
358
+ </odac:field>
359
359
 
360
360
  <!-- Password Field -->
361
- <candy:field name="password" type="password" placeholder="Password">
362
- <candy:validate rule="required" message="Password is required"/>
363
- <candy:validate rule="minlen:8" message="Password must be at least {min} characters"/>
364
- </candy:field>
361
+ <odac:field name="password" type="password" placeholder="Password">
362
+ <odac:validate rule="required" message="Password is required"/>
363
+ <odac:validate rule="minlen:8" message="Password must be at least {min} characters"/>
364
+ </odac:field>
365
365
 
366
366
  <!-- Password Confirmation -->
367
- <candy:field name="password_confirm" type="password" placeholder="Confirm Password" skip>
368
- <candy:validate rule="required" message="Please confirm your password"/>
369
- <candy:validate rule="same:password" message="Passwords do not match"/>
370
- </candy:field>
367
+ <odac:field name="password_confirm" type="password" placeholder="Confirm Password" skip>
368
+ <odac:validate rule="required" message="Please confirm your password"/>
369
+ <odac:validate rule="same:password" message="Passwords do not match"/>
370
+ </odac:field>
371
371
 
372
372
  <!-- Full Name -->
373
- <candy:field name="name" type="text" placeholder="Full Name">
374
- <candy:validate rule="required" message="Name is required"/>
375
- <candy:validate rule="alphaspace" message="Name can only contain letters and spaces"/>
376
- <candy:validate rule="minlen:3" message="Name must be at least {min} characters"/>
377
- </candy:field>
373
+ <odac:field name="name" type="text" placeholder="Full Name">
374
+ <odac:validate rule="required" message="Name is required"/>
375
+ <odac:validate rule="alphaspace" message="Name can only contain letters and spaces"/>
376
+ <odac:validate rule="minlen:3" message="Name must be at least {min} characters"/>
377
+ </odac:field>
378
378
 
379
379
  <!-- Age -->
380
- <candy:field name="age" type="number" placeholder="Age">
381
- <candy:validate rule="required" message="Age is required"/>
382
- <candy:validate rule="min:18" message="You must be at least {min} years old"/>
383
- <candy:validate rule="max:120" message="Please enter a valid age"/>
384
- </candy:field>
380
+ <odac:field name="age" type="number" placeholder="Age">
381
+ <odac:validate rule="required" message="Age is required"/>
382
+ <odac:validate rule="min:18" message="You must be at least {min} years old"/>
383
+ <odac:validate rule="max:120" message="Please enter a valid age"/>
384
+ </odac:field>
385
385
 
386
386
  <!-- Terms Checkbox -->
387
- <candy:field name="terms" type="checkbox" label="I agree to the terms and conditions" skip>
388
- <candy:validate rule="accepted" message="You must accept the terms to continue"/>
389
- </candy:field>
387
+ <odac:field name="terms" type="checkbox" label="I agree to the terms and conditions" skip>
388
+ <odac:validate rule="accepted" message="You must accept the terms to continue"/>
389
+ </odac:field>
390
390
 
391
391
  <!-- Backend-only values -->
392
- <candy:set name="role" value="user"/>
393
- <candy:set name="status" value="active"/>
394
- <candy:set name="registered_at" compute="now"/>
395
- <candy:set name="ip_address" compute="ip"/>
396
- <candy:set name="user_agent" compute="user_agent"/>
392
+ <odac:set name="role" value="user"/>
393
+ <odac:set name="status" value="active"/>
394
+ <odac:set name="registered_at" compute="now"/>
395
+ <odac:set name="ip_address" compute="ip"/>
396
+ <odac:set name="user_agent" compute="user_agent"/>
397
397
 
398
398
  <!-- Submit Button -->
399
- <candy:submit text="Create Account" loading="Creating your account..."/>
399
+ <odac:submit text="Create Account" loading="Creating your account..."/>
400
400
 
401
- </candy:register>
401
+ </odac:register>
402
402
  ```
403
403
 
404
404
  ## Security Features
405
405
 
406
406
  ### Automatic Security
407
407
 
408
- CandyPack automatically handles:
408
+ Odac automatically handles:
409
409
 
410
410
  1. **CSRF Protection** - Form tokens prevent cross-site attacks
411
411
  2. **Password Hashing** - Passwords are hashed with bcrypt
@@ -420,29 +420,29 @@ Each form gets a unique token when rendered:
420
420
  - Token is stored server-side with field whitelist
421
421
  - Token expires after 30 minutes
422
422
  - Only fields defined in the view are accepted
423
- - Backend-only values (`<candy:set>`) are never exposed to HTML
423
+ - Backend-only values (`<odac:set>`) are never exposed to HTML
424
424
 
425
425
  ### Unique Field Checking
426
426
 
427
427
  Fields marked with `unique` attribute are checked against the database:
428
428
 
429
429
  ```html
430
- <candy:field name="email" type="email" unique>
431
- <candy:validate rule="unique" message="Email already exists"/>
432
- </candy:field>
430
+ <odac:field name="email" type="email" unique>
431
+ <odac:validate rule="unique" message="Email already exists"/>
432
+ </odac:field>
433
433
  ```
434
434
 
435
435
  The system automatically queries the auth table to check for duplicates.
436
436
 
437
437
  ## HTML5 Validation
438
438
 
439
- CandyPack automatically adds HTML5 validation attributes for better UX:
439
+ Odac automatically adds HTML5 validation attributes for better UX:
440
440
 
441
441
  ```html
442
442
  <!-- This field -->
443
- <candy:field name="username" type="text">
444
- <candy:validate rule="required|minlen:4|maxlen:20|alphanumeric"/>
445
- </candy:field>
443
+ <odac:field name="username" type="text">
444
+ <odac:validate rule="required|minlen:4|maxlen:20|alphanumeric"/>
445
+ </odac:field>
446
446
 
447
447
  <!-- Generates this HTML -->
448
448
  <input
@@ -506,7 +506,7 @@ Customize table names and primary key if needed:
506
506
 
507
507
  **Auto-Creation (Recommended):**
508
508
 
509
- The users table is created automatically on first registration! CandyPack analyzes your form fields and creates the appropriate table structure:
509
+ The users table is created automatically on first registration! Odac analyzes your form fields and creates the appropriate table structure:
510
510
 
511
511
  - Fields with `unique` attribute → `VARCHAR(255) NOT NULL UNIQUE`
512
512
  - Password field → `VARCHAR(255) NOT NULL` (for bcrypt hashes)
@@ -564,20 +564,20 @@ CREATE TABLE `candy_auth` (
564
564
 
565
565
  ### Display Errors
566
566
 
567
- Error messages are automatically displayed in `<span>` elements with `candy-form-error` attribute:
567
+ Error messages are automatically displayed in `<span>` elements with `odac-form-error` attribute:
568
568
 
569
569
  ```html
570
570
  <!-- Errors appear here automatically -->
571
- <span class="candy-form-error" candy-form-error="email" style="display:none;"></span>
571
+ <span class="odac-form-error" odac-form-error="email" style="display:none;"></span>
572
572
  ```
573
573
 
574
574
  ### Success Messages
575
575
 
576
- Success messages appear in elements with `candy-form-success` class:
576
+ Success messages appear in elements with `odac-form-success` class:
577
577
 
578
578
  ```html
579
579
  <!-- Success message appears here -->
580
- <span class="candy-form-success" style="display:none;"></span>
580
+ <span class="odac-form-success" style="display:none;"></span>
581
581
  ```
582
582
 
583
583
  ### Custom Styling
@@ -585,13 +585,13 @@ Success messages appear in elements with `candy-form-success` class:
585
585
  Style error and success messages with CSS:
586
586
 
587
587
  ```css
588
- .candy-form-error {
588
+ .odac-form-error {
589
589
  color: red;
590
590
  font-size: 0.875rem;
591
591
  margin-top: 0.25rem;
592
592
  }
593
593
 
594
- .candy-form-success {
594
+ .odac-form-success {
595
595
  color: green;
596
596
  font-size: 1rem;
597
597
  padding: 1rem;
@@ -600,11 +600,11 @@ Style error and success messages with CSS:
600
600
  border-radius: 0.25rem;
601
601
  }
602
602
 
603
- .candy-field {
603
+ .odac-field {
604
604
  margin-bottom: 1rem;
605
605
  }
606
606
 
607
- input._candy_error {
607
+ input._odac_error {
608
608
  border-color: red;
609
609
  }
610
610
  ```
@@ -617,13 +617,13 @@ You can define custom callbacks for computed values:
617
617
 
618
618
  ```javascript
619
619
  // In your page controller or global script
620
- Candy.fn.generateReferralCode = async (Candy) => {
620
+ Odac.fn.generateReferralCode = async (Odac) => {
621
621
  return Math.random().toString(36).substring(2, 10).toUpperCase()
622
622
  }
623
623
  ```
624
624
 
625
625
  ```html
626
- <candy:set name="referral_code" callback="generateReferralCode"/>
626
+ <odac:set name="referral_code" callback="generateReferralCode"/>
627
627
  ```
628
628
 
629
629
  ### Conditional Registration
@@ -631,21 +631,21 @@ Candy.fn.generateReferralCode = async (Candy) => {
631
631
  Disable auto-login and handle redirect manually:
632
632
 
633
633
  ```html
634
- <candy:register autologin="false">
634
+ <odac:register autologin="false">
635
635
  <!-- fields -->
636
- </candy:register>
636
+ </odac:register>
637
637
  ```
638
638
 
639
639
  Then handle the response in JavaScript if needed (though not required for basic usage).
640
640
 
641
641
  ## Best Practices
642
642
 
643
- 1. **Always validate on both client and server** - CandyPack does this automatically
643
+ 1. **Always validate on both client and server** - Odac does this automatically
644
644
  2. **Use unique attribute for email/username** - Prevents duplicate accounts
645
645
  3. **Set minimum password length** - Use `minlen:8` or higher
646
646
  4. **Use password confirmation** - Add a `password_confirm` field with `same:password` rule
647
647
  5. **Add terms checkbox** - Use `accepted` rule for legal compliance
648
- 6. **Use backend-only values** - Store metadata with `<candy:set>`
648
+ 6. **Use backend-only values** - Store metadata with `<odac:set>`
649
649
  7. **Provide clear error messages** - Use placeholders for dynamic values
650
650
  8. **Test form expiration** - Forms expire after 30 minutes
651
651
 
@@ -660,7 +660,7 @@ Then handle the response in JavaScript if needed (though not required for basic
660
660
  ### Validation Not Working
661
661
 
662
662
  - Ensure validation rules are spelled correctly
663
- - Check that field names match between `<candy:field>` and validation
663
+ - Check that field names match between `<odac:field>` and validation
664
664
  - Verify HTML5 validation isn't blocking submission
665
665
 
666
666
  ### Unique Check Failing
@@ -1,18 +1,18 @@
1
1
  ## ⏰ Session Management
2
2
 
3
- CandyPack uses a secure cookie-based session system with automatic expiration and cleanup.
3
+ Odac uses a secure cookie-based session system with automatic expiration and cleanup.
4
4
 
5
5
  ### How Sessions Work
6
6
 
7
- When a user logs in, CandyPack creates a session token stored in secure cookies:
7
+ When a user logs in, Odac creates a session token stored in secure cookies:
8
8
 
9
9
  ```javascript
10
10
  // Login creates a session
11
- await Candy.Auth.login({email, password})
11
+ await Odac.Auth.login({email, password})
12
12
 
13
13
  // Session is automatically checked on each request
14
- if (await Candy.Auth.check()) {
15
- const user = Candy.Auth.user(null)
14
+ if (await Odac.Auth.check()) {
15
+ const user = Odac.Auth.user(null)
16
16
  }
17
17
  ```
18
18
 
@@ -116,18 +116,18 @@ Sessions are protected with:
116
116
 
117
117
  **Logout current session:**
118
118
  ```javascript
119
- await Candy.Auth.logout()
119
+ await Odac.Auth.logout()
120
120
  ```
121
121
 
122
122
  **Check session status:**
123
123
  ```javascript
124
- const isLoggedIn = await Candy.Auth.check()
124
+ const isLoggedIn = await Odac.Auth.check()
125
125
  ```
126
126
 
127
127
  **Get user info:**
128
128
  ```javascript
129
- const user = Candy.Auth.user(null) // Full user object
130
- const email = Candy.Auth.user('email') // Specific field
129
+ const user = Odac.Auth.user(null) // Full user object
130
+ const email = Odac.Auth.user('email') // Specific field
131
131
  ```
132
132
 
133
133
  ### Best Practices
@@ -153,7 +153,7 @@ const email = Candy.Auth.user('email') // Specific field
153
153
  - Manually clean old sessions if needed:
154
154
  ```javascript
155
155
  const cutoffDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
156
- await Candy.Mysql.table('user_tokens')
156
+ await Odac.Mysql.table('user_tokens')
157
157
  .where('active', '<', cutoffDate)
158
158
  .delete()
159
159
  ```