odac 0.9.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 (213) hide show
  1. package/.editorconfig +21 -0
  2. package/.github/workflows/auto-pr-description.yml +49 -0
  3. package/.github/workflows/release.yml +32 -0
  4. package/.github/workflows/test-coverage.yml +58 -0
  5. package/.husky/pre-commit +2 -0
  6. package/.kiro/steering/code-style.md +56 -0
  7. package/.kiro/steering/product.md +20 -0
  8. package/.kiro/steering/structure.md +77 -0
  9. package/.kiro/steering/tech.md +87 -0
  10. package/.prettierrc +10 -0
  11. package/.releaserc.js +134 -0
  12. package/AGENTS.md +84 -0
  13. package/CHANGELOG.md +181 -0
  14. package/CODE_OF_CONDUCT.md +83 -0
  15. package/CONTRIBUTING.md +63 -0
  16. package/LICENSE +661 -0
  17. package/README.md +57 -0
  18. package/SECURITY.md +26 -0
  19. package/bin/candy +10 -0
  20. package/bin/candypack +10 -0
  21. package/cli/index.js +3 -0
  22. package/cli/src/Cli.js +348 -0
  23. package/cli/src/Connector.js +93 -0
  24. package/cli/src/Monitor.js +416 -0
  25. package/core/Candy.js +87 -0
  26. package/core/Commands.js +239 -0
  27. package/core/Config.js +1094 -0
  28. package/core/Lang.js +52 -0
  29. package/core/Log.js +43 -0
  30. package/core/Process.js +26 -0
  31. package/docs/backend/01-overview/01-whats-in-the-candy-box.md +9 -0
  32. package/docs/backend/01-overview/02-super-handy-helper-functions.md +9 -0
  33. package/docs/backend/01-overview/03-development-server.md +79 -0
  34. package/docs/backend/02-structure/01-typical-project-layout.md +39 -0
  35. package/docs/backend/03-config/00-configuration-overview.md +214 -0
  36. package/docs/backend/03-config/01-database-connection.md +60 -0
  37. package/docs/backend/03-config/02-static-route-mapping-optional.md +20 -0
  38. package/docs/backend/03-config/03-request-timeout.md +11 -0
  39. package/docs/backend/03-config/04-environment-variables.md +227 -0
  40. package/docs/backend/03-config/05-early-hints.md +352 -0
  41. package/docs/backend/04-routing/01-basic-page-routes.md +28 -0
  42. package/docs/backend/04-routing/02-controller-less-view-routes.md +43 -0
  43. package/docs/backend/04-routing/03-api-and-data-routes.md +20 -0
  44. package/docs/backend/04-routing/04-authentication-aware-routes.md +48 -0
  45. package/docs/backend/04-routing/05-advanced-routing.md +14 -0
  46. package/docs/backend/04-routing/06-error-pages.md +101 -0
  47. package/docs/backend/04-routing/07-cron-jobs.md +149 -0
  48. package/docs/backend/05-controllers/01-how-to-build-a-controller.md +17 -0
  49. package/docs/backend/05-controllers/02-your-trusty-candy-assistant.md +20 -0
  50. package/docs/backend/05-controllers/03-controller-classes.md +93 -0
  51. package/docs/backend/05-forms/01-custom-forms.md +395 -0
  52. package/docs/backend/05-forms/02-automatic-database-insert.md +297 -0
  53. package/docs/backend/06-request-and-response/01-the-request-object-what-is-the-user-asking-for.md +96 -0
  54. package/docs/backend/06-request-and-response/02-sending-a-response-replying-to-the-user.md +40 -0
  55. package/docs/backend/07-views/01-the-view-directory.md +73 -0
  56. package/docs/backend/07-views/02-rendering-a-view.md +179 -0
  57. package/docs/backend/07-views/03-template-syntax.md +181 -0
  58. package/docs/backend/07-views/03-variables.md +328 -0
  59. package/docs/backend/07-views/04-request-data.md +231 -0
  60. package/docs/backend/07-views/05-conditionals.md +290 -0
  61. package/docs/backend/07-views/06-loops.md +353 -0
  62. package/docs/backend/07-views/07-translations.md +358 -0
  63. package/docs/backend/07-views/08-backend-javascript.md +398 -0
  64. package/docs/backend/07-views/09-comments.md +297 -0
  65. package/docs/backend/08-database/01-database-connection.md +99 -0
  66. package/docs/backend/08-database/02-using-mysql.md +322 -0
  67. package/docs/backend/09-validation/01-the-validator-service.md +424 -0
  68. package/docs/backend/10-authentication/01-user-logins-with-authjs.md +53 -0
  69. package/docs/backend/10-authentication/02-foiling-villains-with-csrf-protection.md +55 -0
  70. package/docs/backend/10-authentication/03-register.md +134 -0
  71. package/docs/backend/10-authentication/04-candy-register-forms.md +676 -0
  72. package/docs/backend/10-authentication/05-session-management.md +159 -0
  73. package/docs/backend/10-authentication/06-candy-login-forms.md +596 -0
  74. package/docs/backend/11-mail/01-the-mail-service.md +42 -0
  75. package/docs/backend/12-streaming/01-streaming-overview.md +300 -0
  76. package/docs/backend/13-utilities/01-candy-var.md +504 -0
  77. package/docs/frontend/01-overview/01-introduction.md +146 -0
  78. package/docs/frontend/02-ajax-navigation/01-quick-start.md +608 -0
  79. package/docs/frontend/02-ajax-navigation/02-configuration.md +370 -0
  80. package/docs/frontend/02-ajax-navigation/03-advanced-usage.md +519 -0
  81. package/docs/frontend/03-forms/01-form-handling.md +420 -0
  82. package/docs/frontend/04-api-requests/01-get-post.md +443 -0
  83. package/docs/frontend/05-streaming/01-client-streaming.md +163 -0
  84. package/docs/index.json +452 -0
  85. package/docs/server/01-installation/01-quick-install.md +19 -0
  86. package/docs/server/01-installation/02-manual-installation-via-npm.md +9 -0
  87. package/docs/server/02-get-started/01-core-concepts.md +7 -0
  88. package/docs/server/02-get-started/02-basic-commands.md +57 -0
  89. package/docs/server/02-get-started/03-cli-reference.md +276 -0
  90. package/docs/server/02-get-started/04-cli-quick-reference.md +102 -0
  91. package/docs/server/03-service/01-start-a-new-service.md +57 -0
  92. package/docs/server/03-service/02-delete-a-service.md +48 -0
  93. package/docs/server/04-web/01-create-a-website.md +36 -0
  94. package/docs/server/04-web/02-list-websites.md +9 -0
  95. package/docs/server/04-web/03-delete-a-website.md +29 -0
  96. package/docs/server/05-subdomain/01-create-a-subdomain.md +32 -0
  97. package/docs/server/05-subdomain/02-list-subdomains.md +33 -0
  98. package/docs/server/05-subdomain/03-delete-a-subdomain.md +41 -0
  99. package/docs/server/06-ssl/01-renew-an-ssl-certificate.md +34 -0
  100. package/docs/server/07-mail/01-create-a-mail-account.md +23 -0
  101. package/docs/server/07-mail/02-delete-a-mail-account.md +20 -0
  102. package/docs/server/07-mail/03-list-mail-accounts.md +20 -0
  103. package/docs/server/07-mail/04-change-account-password.md +23 -0
  104. package/eslint.config.mjs +120 -0
  105. package/framework/index.js +4 -0
  106. package/framework/src/Auth.js +309 -0
  107. package/framework/src/Candy.js +81 -0
  108. package/framework/src/Config.js +79 -0
  109. package/framework/src/Env.js +60 -0
  110. package/framework/src/Lang.js +57 -0
  111. package/framework/src/Mail.js +83 -0
  112. package/framework/src/Mysql.js +575 -0
  113. package/framework/src/Request.js +301 -0
  114. package/framework/src/Route/Cron.js +128 -0
  115. package/framework/src/Route/Internal.js +439 -0
  116. package/framework/src/Route.js +455 -0
  117. package/framework/src/Server.js +15 -0
  118. package/framework/src/Stream.js +163 -0
  119. package/framework/src/Token.js +37 -0
  120. package/framework/src/Validator.js +271 -0
  121. package/framework/src/Var.js +211 -0
  122. package/framework/src/View/EarlyHints.js +190 -0
  123. package/framework/src/View/Form.js +600 -0
  124. package/framework/src/View.js +513 -0
  125. package/framework/web/candy.js +838 -0
  126. package/jest.config.js +22 -0
  127. package/locale/de-DE.json +80 -0
  128. package/locale/en-US.json +79 -0
  129. package/locale/es-ES.json +80 -0
  130. package/locale/fr-FR.json +80 -0
  131. package/locale/pt-BR.json +80 -0
  132. package/locale/ru-RU.json +80 -0
  133. package/locale/tr-TR.json +85 -0
  134. package/locale/zh-CN.json +80 -0
  135. package/package.json +86 -0
  136. package/server/index.js +5 -0
  137. package/server/src/Api.js +88 -0
  138. package/server/src/DNS.js +940 -0
  139. package/server/src/Hub.js +535 -0
  140. package/server/src/Mail.js +571 -0
  141. package/server/src/SSL.js +180 -0
  142. package/server/src/Server.js +27 -0
  143. package/server/src/Service.js +248 -0
  144. package/server/src/Subdomain.js +64 -0
  145. package/server/src/Web/Firewall.js +170 -0
  146. package/server/src/Web/Proxy.js +134 -0
  147. package/server/src/Web.js +451 -0
  148. package/server/src/mail/imap.js +1091 -0
  149. package/server/src/mail/server.js +32 -0
  150. package/server/src/mail/smtp.js +786 -0
  151. package/test/cli/Cli.test.js +36 -0
  152. package/test/core/Candy.test.js +234 -0
  153. package/test/core/Commands.test.js +538 -0
  154. package/test/core/Config.test.js +1435 -0
  155. package/test/core/Lang.test.js +250 -0
  156. package/test/core/Process.test.js +156 -0
  157. package/test/framework/Route.test.js +239 -0
  158. package/test/framework/View/EarlyHints.test.js +282 -0
  159. package/test/scripts/check-coverage.js +132 -0
  160. package/test/server/Api.test.js +647 -0
  161. package/test/server/Client.test.js +338 -0
  162. package/test/server/DNS.test.js +2050 -0
  163. package/test/server/DNS.test.js.bak +2084 -0
  164. package/test/server/Log.test.js +73 -0
  165. package/test/server/Mail.account.test_.js +460 -0
  166. package/test/server/Mail.init.test_.js +411 -0
  167. package/test/server/Mail.test_.js +1340 -0
  168. package/test/server/SSL.test_.js +1491 -0
  169. package/test/server/Server.test.js +765 -0
  170. package/test/server/Service.test_.js +1127 -0
  171. package/test/server/Subdomain.test.js +440 -0
  172. package/test/server/Web/Firewall.test.js +175 -0
  173. package/test/server/Web.test_.js +1562 -0
  174. package/test/server/__mocks__/acme-client.js +17 -0
  175. package/test/server/__mocks__/bcrypt.js +50 -0
  176. package/test/server/__mocks__/child_process.js +389 -0
  177. package/test/server/__mocks__/crypto.js +432 -0
  178. package/test/server/__mocks__/fs.js +450 -0
  179. package/test/server/__mocks__/globalCandy.js +227 -0
  180. package/test/server/__mocks__/http-proxy.js +105 -0
  181. package/test/server/__mocks__/http.js +575 -0
  182. package/test/server/__mocks__/https.js +272 -0
  183. package/test/server/__mocks__/index.js +249 -0
  184. package/test/server/__mocks__/mail/server.js +100 -0
  185. package/test/server/__mocks__/mail/smtp.js +31 -0
  186. package/test/server/__mocks__/mailparser.js +81 -0
  187. package/test/server/__mocks__/net.js +369 -0
  188. package/test/server/__mocks__/node-forge.js +328 -0
  189. package/test/server/__mocks__/os.js +320 -0
  190. package/test/server/__mocks__/path.js +291 -0
  191. package/test/server/__mocks__/selfsigned.js +8 -0
  192. package/test/server/__mocks__/server/src/mail/server.js +100 -0
  193. package/test/server/__mocks__/server/src/mail/smtp.js +31 -0
  194. package/test/server/__mocks__/smtp-server.js +106 -0
  195. package/test/server/__mocks__/sqlite3.js +394 -0
  196. package/test/server/__mocks__/testFactories.js +299 -0
  197. package/test/server/__mocks__/testHelpers.js +363 -0
  198. package/test/server/__mocks__/tls.js +229 -0
  199. package/watchdog/index.js +3 -0
  200. package/watchdog/src/Watchdog.js +156 -0
  201. package/web/config.json +5 -0
  202. package/web/controller/page/about.js +27 -0
  203. package/web/controller/page/index.js +34 -0
  204. package/web/package.json +18 -0
  205. package/web/public/assets/css/style.css +1835 -0
  206. package/web/public/assets/js/app.js +96 -0
  207. package/web/route/www.js +19 -0
  208. package/web/skeleton/main.html +22 -0
  209. package/web/view/content/about.html +65 -0
  210. package/web/view/content/home.html +205 -0
  211. package/web/view/footer/main.html +11 -0
  212. package/web/view/head/main.html +5 -0
  213. package/web/view/header/main.html +14 -0
package/core/Lang.js ADDED
@@ -0,0 +1,52 @@
1
+ const fs = require('fs')
2
+
3
+ class Lang {
4
+ #locale = Intl.DateTimeFormat().resolvedOptions().locale
5
+ #file = __dirname + '/../locale/' + this.#locale + '.json'
6
+ #strings = {}
7
+ #loaded = false
8
+
9
+ constructor() {
10
+ this.#load()
11
+ }
12
+
13
+ #save() {
14
+ try {
15
+ fs.promises.writeFile(this.#file, JSON.stringify(this.#strings, null, 4), 'utf8')
16
+ } catch (err) {
17
+ console.error('Error saving language file:', err)
18
+ }
19
+ }
20
+
21
+ #load() {
22
+ try {
23
+ const data = fs.readFileSync(this.#file, 'utf8')
24
+ this.#loaded = true
25
+ this.#strings = JSON.parse(data)
26
+ } catch {
27
+ this.#strings = {}
28
+ this.#save()
29
+ }
30
+ return true
31
+ }
32
+
33
+ get(key, ...args) {
34
+ if (!this.#loaded) this.#load()
35
+ if (key === 'CandyPack') return 'CandyPack'
36
+ let text = this.#strings[key]
37
+ if (text === undefined) {
38
+ text = key
39
+ this.#strings[key] = text
40
+ this.#save()
41
+ }
42
+ if (args.length > 0) {
43
+ args.forEach((arg, i) => {
44
+ if (text.includes(`%s${i + 1}`)) text = text.replace(`%s${i + 1}`, arg)
45
+ else text = text.replace('%s', arg)
46
+ })
47
+ }
48
+ return text
49
+ }
50
+ }
51
+
52
+ module.exports = Lang
package/core/Log.js ADDED
@@ -0,0 +1,43 @@
1
+ class Log {
2
+ #cliMode = false
3
+
4
+ constructor() {
5
+ // Detect if we're running in CLI mode
6
+ // CLI mode is when the main module is in cli/ or bin/ directory
7
+ if (require.main && require.main.filename) {
8
+ const mainFile = require.main.filename
9
+ this.#cliMode = mainFile.includes('/cli/') || mainFile.includes('/bin/')
10
+ }
11
+ }
12
+
13
+ init(...arg) {
14
+ this.module = '[' + arg.join('][') + '] '
15
+ return {
16
+ error: this.error.bind(this),
17
+ log: this.log.bind(this)
18
+ }
19
+ }
20
+
21
+ error(...arg) {
22
+ // Always show errors, even in CLI mode
23
+ console.error(this.module, ...arg)
24
+ }
25
+
26
+ log(...arg) {
27
+ // Suppress logs in CLI mode to avoid breaking the interface
28
+ if (this.#cliMode) return
29
+
30
+ if (!arg.length) return this
31
+ if (typeof arg[0] === 'string' && arg[0].includes('%s')) {
32
+ let message = arg.shift()
33
+ while (message.includes('%s') && arg.length > 0) {
34
+ message = message.replace('%s', arg.shift())
35
+ }
36
+ message = message.replace(/%s/g, '')
37
+ arg.unshift(message)
38
+ }
39
+ console.log(this.module, ...arg)
40
+ }
41
+ }
42
+
43
+ module.exports = Log
@@ -0,0 +1,26 @@
1
+ const findProcess = require('find-process').default
2
+
3
+ class Process {
4
+ stop(pid) {
5
+ return new Promise(resolve => {
6
+ findProcess('pid', pid)
7
+ .then(list => {
8
+ for (const proc of list) if (proc.name == 'node') process.kill(proc.pid, 'SIGTERM')
9
+ })
10
+ .catch(() => {})
11
+ .finally(() => {
12
+ resolve()
13
+ })
14
+ })
15
+ }
16
+
17
+ async stopAll() {
18
+ if (Candy.core('Config').config.server?.watchdog) await this.stop(Candy.core('Config').config.server.watchdog)
19
+ if (Candy.core('Config').config.server?.pid) await this.stop(Candy.core('Config').config.server.pid)
20
+ for (const domain of Object.keys(Candy.core('Config').config?.websites ?? {}))
21
+ if (Candy.core('Config').config.websites[domain].pid) await this.stop(Candy.core('Config').config.websites[domain].pid)
22
+ for (const service of Candy.core('Config').config.services ?? []) if (service.pid) await this.stop(service.pid)
23
+ }
24
+ }
25
+
26
+ module.exports = Process
@@ -0,0 +1,9 @@
1
+ ## 🧰 What's in the `Candy` box?
2
+
3
+ Your `Candy` assistant comes with a bunch of handy services:
4
+
5
+ * `Request`: All the details about the user's incoming request.
6
+ * `View`: A tool to render your beautiful HTML pages.
7
+ * `Auth`: Your friendly security guard for managing the current user's login.
8
+ * `Token`: Helps protect the user's forms from nasty CSRF attacks.
9
+ * `Lang`: A helper for translating your app into the user's language.
@@ -0,0 +1,9 @@
1
+ ## ✨ Super-Handy Helper Functions
2
+
3
+ On top of that, `Candy` has some quick-and-easy helper functions:
4
+
5
+ * `return(data)`: Quickly send a response back to the user and you're done.
6
+ * `direct(url)`: Need to send the user to another page? This is your tool.
7
+ * `cookie(key, value)`: Leave a little cookie in the user's browser.
8
+ * `env(key, defaultValue)`: Access environment variables with an optional default value.
9
+ * `validator()`: A powerful tool to check the user's submitted data.
@@ -0,0 +1,79 @@
1
+ ## 🚀 Development Server
2
+
3
+ CandyPack provides a built-in development server that allows you to test your website locally without running the full CandyPack server infrastructure.
4
+
5
+ ### Quick Start
6
+
7
+ Navigate to your website directory and run one of these commands:
8
+
9
+ ```bash
10
+ # Using npm script
11
+ npm start
12
+
13
+ # Using CandyPack directly
14
+ candypack framework run
15
+ ```
16
+
17
+ Both commands will start a local development server on port `1071` by default, and your website will be accessible at `http://127.0.0.1:1071`.
18
+
19
+ ### Custom Port
20
+
21
+ You can specify a custom port by adding it as an argument:
22
+
23
+ ```bash
24
+ # Using npm script with custom port
25
+ npm start 8080
26
+
27
+ # Using CandyPack directly with custom port
28
+ candypack framework run 8080
29
+ ```
30
+
31
+ This will start the server on your specified port (e.g., `http://127.0.0.1:8080`).
32
+
33
+ ### Development vs Production
34
+
35
+ The development server (`npm start`) is designed for:
36
+
37
+ - **Local testing** and development only
38
+ - **Quick iteration** without server setup
39
+ - **Debugging** your application logic
40
+ - **Testing on localhost** (127.0.0.1)
41
+
42
+ **Important**: The development server does NOT provide DNS, SSL, or other production services.
43
+
44
+ For production deployment with full CandyPack server features, create your website using:
45
+
46
+ ```bash
47
+ candy web create
48
+ ```
49
+
50
+ This registers your website with the CandyPack server and provides:
51
+
52
+ - **Automatic SSL** certificate management
53
+ - **DNS handling** for your domain
54
+ - **Multi-domain hosting** capabilities
55
+ - **Process monitoring** and auto-restart
56
+ - **Production optimizations** and security
57
+
58
+ ### Package.json Scripts
59
+
60
+ When you create a new website, CandyPack automatically generates a `package.json` with these useful scripts:
61
+
62
+ ```json
63
+ {
64
+ "scripts": {
65
+ "start": "candy framework run",
66
+ "test": "echo \"Error: no test specified\" && exit 1"
67
+ }
68
+ }
69
+ ```
70
+
71
+ - `npm start` - Starts the development server for local testing
72
+ - `npm test` - Placeholder for your test suite
73
+
74
+ ### Tips
75
+
76
+ - The development server automatically detects changes in your code
77
+ - Use `Ctrl+C` to stop the development server
78
+ - The server will show helpful error messages in the console
79
+ - All CandyPack framework features are available in development mode
@@ -0,0 +1,39 @@
1
+ ## 📂 Typical Project Layout
2
+
3
+ Let's take a look at a typical project layout:
4
+
5
+ - `project_root/`
6
+ - `config.json`: This is where you'll keep your app's secrets and settings, like database passwords or API keys.
7
+ - `index.js`: The starting pistol for your web application! This file kicks off the CandyPack framework.
8
+ - `package.json`: Contains project metadata and npm scripts for development. Automatically generated when creating a new website.
9
+ - `public/`: All files placed in this folder are directly accessible from the outside. This is the perfect place for your images, stylesheets, and client-side JavaScript.
10
+ - `route/`: This folder holds all your route definitions. The filename of the route file corresponds to the subdomain it serves.
11
+ - `www.js`: Used for routes on your main domain (e.g., `www.example.com` or `example.com`).
12
+ - `api.js`: Used for routes on a subdomain (e.g., `api.example.com`). When a request comes in for `api.example.com`, this is the route file that gets used. You can create files for any subdomain!
13
+ - `controller/`: This is where the magic happens! Controllers contain the main logic for your application.
14
+ - `page/`: We suggest putting controllers that show HTML pages in here.
15
+ - `api/`: If you're building an API, it's a great idea to keep those controllers separate in their own folder.
16
+ - `view/`: For all your HTML template files. This is what your users will see.
17
+
18
+ ### Development Commands
19
+
20
+ Your `package.json` includes helpful npm scripts for development:
21
+
22
+ ```bash
23
+ # Start development server (default port 1071)
24
+ npm start
25
+
26
+ # Start development server on custom port
27
+ npm start 8080
28
+ ```
29
+
30
+ You can also use CandyPack commands directly:
31
+
32
+ ```bash
33
+ # Development server (local testing only)
34
+ candypack framework run [port]
35
+ ```
36
+
37
+ **Note**: For production websites with DNS and SSL, use `candy web create` to register with CandyPack server.
38
+
39
+ Following this structure helps keep your code's responsibilities separate. Your routing logic lives in one place, your app logic in another, and your presentation files in a third. It's a recipe for success!
@@ -0,0 +1,214 @@
1
+ ## ⚙️ Configuration Overview
2
+
3
+ CandyPack uses a simple and flexible configuration system based on `config.json` and optional `.env` files. You can choose the approach that best fits your needs.
4
+
5
+ ### Configuration Files
6
+
7
+ #### config.json (Required)
8
+ The main configuration file located in your website's root directory. This file contains all your application settings in JSON format.
9
+
10
+ ```json
11
+ {
12
+ "request": {
13
+ "timeout": 30000
14
+ },
15
+ "mysql": {
16
+ "host": "localhost",
17
+ "user": "root",
18
+ "password": "secret123",
19
+ "database": "myapp"
20
+ }
21
+ }
22
+ ```
23
+
24
+ #### .env (Optional)
25
+ An optional environment variables file for storing sensitive information like passwords and API keys. This file should be added to `.gitignore` to keep secrets out of version control.
26
+
27
+ ```bash
28
+ # .env
29
+ MYSQL_PASSWORD=super_secret_123
30
+ API_KEY=your_api_key_here
31
+ NODE_ENV=production
32
+ ```
33
+
34
+ ### Three Ways to Configure
35
+
36
+ #### 1. Direct Values (Simple)
37
+ Perfect for development or non-sensitive settings:
38
+
39
+ ```json
40
+ {
41
+ "mysql": {
42
+ "host": "localhost",
43
+ "password": "dev123"
44
+ }
45
+ }
46
+ ```
47
+
48
+ #### 2. Environment Variables (Secure)
49
+ Use `${VARIABLE}` syntax in `config.json` to reference `.env` values:
50
+
51
+ ```json
52
+ {
53
+ "mysql": {
54
+ "host": "${MYSQL_HOST}",
55
+ "password": "${MYSQL_PASSWORD}"
56
+ }
57
+ }
58
+ ```
59
+
60
+ ```bash
61
+ # .env
62
+ MYSQL_HOST=production.db.com
63
+ MYSQL_PASSWORD=super_secret_123
64
+ ```
65
+
66
+ #### 3. Mixed Approach (Flexible)
67
+ Combine both methods - use direct values for non-sensitive data and environment variables for secrets:
68
+
69
+ ```json
70
+ {
71
+ "mysql": {
72
+ "host": "localhost",
73
+ "user": "root",
74
+ "password": "${MYSQL_PASSWORD}",
75
+ "database": "myapp"
76
+ },
77
+ "api": {
78
+ "endpoint": "https://api.example.com",
79
+ "key": "${API_KEY}"
80
+ }
81
+ }
82
+ ```
83
+
84
+ ### Accessing Configuration
85
+
86
+ #### In Controllers
87
+ You can access configuration values in three ways:
88
+
89
+ ```javascript
90
+ // 1. From Candy.Config (recommended for structured config)
91
+ const dbHost = Candy.Config.mysql.host
92
+
93
+ // 2. Using Candy.env() helper
94
+ const apiKey = Candy.env('API_KEY')
95
+ const debug = Candy.env('DEBUG', 'false')
96
+
97
+ // 3. Direct process.env access
98
+ const nodeEnv = process.env.NODE_ENV
99
+ ```
100
+
101
+ ### Best Practices
102
+
103
+ **Development:**
104
+ - Use direct values in `config.json` for quick setup
105
+ - Keep development credentials simple
106
+
107
+ **Production:**
108
+ - Store sensitive data in `.env` file
109
+ - Add `.env` to `.gitignore`
110
+ - Use environment variables for passwords, API keys, and tokens
111
+ - Copy `.env.example` to `.env` and fill in production values
112
+
113
+ **Version Control:**
114
+ - Commit `config.json` with `${VARIABLE}` placeholders
115
+ - Commit `.env.example` with dummy values
116
+ - Never commit `.env` with real credentials
117
+
118
+ ### Common Configuration Options
119
+
120
+ **Request timeout:**
121
+ ```json
122
+ {
123
+ "request": {
124
+ "timeout": 30000
125
+ }
126
+ }
127
+ ```
128
+
129
+ **Database connection:**
130
+ ```json
131
+ {
132
+ "database": {
133
+ "host": "localhost",
134
+ "user": "root",
135
+ "password": "${MYSQL_PASSWORD}",
136
+ "database": "myapp"
137
+ }
138
+ }
139
+ ```
140
+
141
+ **Authentication sessions:**
142
+ ```json
143
+ {
144
+ "auth": {
145
+ "table": "users",
146
+ "token": "user_tokens",
147
+ "maxAge": 2592000000,
148
+ "updateAge": 86400000
149
+ }
150
+ }
151
+ ```
152
+
153
+ **Early Hints (HTTP 103):**
154
+ ```json
155
+ {
156
+ "earlyHints": {
157
+ "enabled": true,
158
+ "auto": true,
159
+ "maxResources": 5
160
+ }
161
+ }
162
+ ```
163
+
164
+ Early Hints is a performance optimization feature that works automatically without any configuration. The server sends preliminary HTTP headers to the browser before the final response, allowing browsers to start preloading critical resources (CSS, JavaScript, fonts) earlier. This is completely zero-config - it detects resources from your HTML automatically and sends hints on subsequent requests.
165
+
166
+ See individual documentation sections for detailed configuration options.
167
+
168
+ ### Example Setup
169
+
170
+ **config.json** (committed to git):
171
+ ```json
172
+ {
173
+ "request": {
174
+ "timeout": 30000
175
+ },
176
+ "mysql": {
177
+ "host": "${MYSQL_HOST}",
178
+ "user": "${MYSQL_USER}",
179
+ "password": "${MYSQL_PASSWORD}",
180
+ "database": "myapp"
181
+ },
182
+ "auth": {
183
+ "maxAge": 2592000000,
184
+ "updateAge": 86400000
185
+ },
186
+ "mail": {
187
+ "from": "${MAIL_FROM}"
188
+ }
189
+ }
190
+ ```
191
+
192
+ **.env.example** (committed to git):
193
+ ```bash
194
+ # Database
195
+ MYSQL_HOST=localhost
196
+ MYSQL_USER=root
197
+ MYSQL_PASSWORD=your_password_here
198
+
199
+ # Mail
200
+ MAIL_FROM=noreply@example.com
201
+ ```
202
+
203
+ **.env** (gitignored, not committed):
204
+ ```bash
205
+ # Database
206
+ MYSQL_HOST=production.db.com
207
+ MYSQL_USER=prod_user
208
+ MYSQL_PASSWORD=super_secret_production_password
209
+
210
+ # Mail
211
+ MAIL_FROM=noreply@myapp.com
212
+ ```
213
+
214
+ This approach keeps your code secure while maintaining flexibility across different environments.
@@ -0,0 +1,60 @@
1
+ ## 🔌 Database Connection
2
+
3
+ When you add a `mysql` object to your `config.json`, the system will automatically connect to your MySQL database. No separate connection setup is needed in your code.
4
+
5
+ ### Basic Configuration
6
+
7
+ ```json
8
+ {
9
+ "mysql": {
10
+ "host": "localhost",
11
+ "user": "your_user",
12
+ "password": "your_password",
13
+ "database": "your_database"
14
+ }
15
+ }
16
+ ```
17
+
18
+ Once this is configured, you can directly use `Candy.Mysql` commands to run queries.
19
+
20
+ ### Using Environment Variables
21
+
22
+ For better security, especially in production, you can use environment variables for sensitive information:
23
+
24
+ **config.json:**
25
+ ```json
26
+ {
27
+ "mysql": {
28
+ "host": "${MYSQL_HOST}",
29
+ "user": "${MYSQL_USER}",
30
+ "password": "${MYSQL_PASSWORD}",
31
+ "database": "myapp"
32
+ }
33
+ }
34
+ ```
35
+
36
+ **.env:**
37
+ ```bash
38
+ MYSQL_HOST=localhost
39
+ MYSQL_USER=root
40
+ MYSQL_PASSWORD=super_secret_123
41
+ ```
42
+
43
+ The `.env` file should be added to `.gitignore` to keep your credentials secure.
44
+
45
+ ### Mixed Approach
46
+
47
+ You can also mix direct values with environment variables:
48
+
49
+ ```json
50
+ {
51
+ "mysql": {
52
+ "host": "localhost",
53
+ "user": "root",
54
+ "password": "${MYSQL_PASSWORD}",
55
+ "database": "myapp"
56
+ }
57
+ }
58
+ ```
59
+
60
+ This way, non-sensitive values are directly in the config while passwords remain in the `.env` file.
@@ -0,0 +1,20 @@
1
+ ## 🗺️ Static Route Mapping (Optional)
2
+
3
+ Normally, all publicly served files should be in your `public` folder. However, if you need to expose a specific file from somewhere else on your server, you can use the optional `route` object in your `config.json`. This creates a direct mapping from a URL path to that file.
4
+
5
+ ```json
6
+ "route": {
7
+ "/assets/js/candy.js": "${candy}/framework/web/candy.js",
8
+ "/css/main.css": "/path/to/your/project/assets/css/main.css"
9
+ }
10
+ ```
11
+
12
+ When a user visits a URL that matches a key in the `route` object, CandyPack will serve the corresponding file from your filesystem.
13
+
14
+ #### Using the `${candy}` Variable
15
+
16
+ The special variable `${candy}` is a shortcut that points to the root directory where CandyPack is installed. This is helpful for linking to files that are part of the framework itself.
17
+
18
+ #### Absolute Paths
19
+
20
+ For your own project files, you should provide a full, absolute path to the file on your server.
@@ -0,0 +1,11 @@
1
+ ## ⏱️ Request Timeout
2
+
3
+ You can configure the global timeout for incoming requests by adding a `request` object to your `config.json`.
4
+
5
+ ```json
6
+ "request": {
7
+ "timeout": 10000
8
+ }
9
+ ```
10
+
11
+ The `timeout` value is in milliseconds. In this example, any request that takes longer than 10,000 milliseconds (10 seconds) to process will be timed out.