odac 1.0.0 → 1.1.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 (61) hide show
  1. package/.github/workflows/auto-pr-description.yml +3 -1
  2. package/CHANGELOG.md +127 -0
  3. package/README.md +39 -36
  4. package/bin/odac.js +1 -31
  5. package/client/odac.js +871 -994
  6. package/docs/backend/01-overview/03-development-server.md +7 -7
  7. package/docs/backend/02-structure/01-typical-project-layout.md +1 -0
  8. package/docs/backend/03-config/00-configuration-overview.md +9 -0
  9. package/docs/backend/03-config/01-database-connection.md +1 -1
  10. package/docs/backend/04-routing/02-controller-less-view-routes.md +9 -3
  11. package/docs/backend/04-routing/09-websocket.md +29 -0
  12. package/docs/backend/05-controllers/02-your-trusty-odac-assistant.md +2 -0
  13. package/docs/backend/05-controllers/03-controller-classes.md +27 -41
  14. package/docs/backend/05-forms/01-custom-forms.md +103 -95
  15. package/docs/backend/05-forms/02-automatic-database-insert.md +21 -21
  16. package/docs/backend/07-views/02-rendering-a-view.md +1 -1
  17. package/docs/backend/07-views/03-variables.md +5 -5
  18. package/docs/backend/07-views/04-request-data.md +1 -1
  19. package/docs/backend/07-views/08-backend-javascript.md +1 -1
  20. package/docs/backend/08-database/01-getting-started.md +100 -0
  21. package/docs/backend/08-database/02-basics.md +136 -0
  22. package/docs/backend/08-database/03-advanced.md +84 -0
  23. package/docs/backend/08-database/04-migrations.md +48 -0
  24. package/docs/backend/09-validation/01-the-validator-service.md +1 -0
  25. package/docs/backend/10-authentication/03-register.md +8 -1
  26. package/docs/backend/10-authentication/04-odac-register-forms.md +46 -46
  27. package/docs/backend/10-authentication/05-session-management.md +1 -1
  28. package/docs/backend/10-authentication/06-odac-login-forms.md +48 -48
  29. package/docs/backend/10-authentication/07-magic-links.md +134 -0
  30. package/docs/backend/11-mail/01-the-mail-service.md +118 -28
  31. package/docs/backend/12-streaming/01-streaming-overview.md +2 -2
  32. package/docs/backend/13-utilities/01-odac-var.md +7 -7
  33. package/docs/backend/13-utilities/02-ipc.md +73 -0
  34. package/docs/frontend/01-overview/01-introduction.md +5 -1
  35. package/docs/frontend/02-ajax-navigation/01-quick-start.md +1 -1
  36. package/docs/index.json +16 -124
  37. package/eslint.config.mjs +5 -47
  38. package/package.json +9 -4
  39. package/src/Auth.js +362 -104
  40. package/src/Config.js +7 -2
  41. package/src/Database.js +188 -0
  42. package/src/Ipc.js +330 -0
  43. package/src/Mail.js +408 -37
  44. package/src/Odac.js +65 -9
  45. package/src/Request.js +70 -48
  46. package/src/Route/Cron.js +4 -1
  47. package/src/Route/Internal.js +214 -11
  48. package/src/Route/Middleware.js +7 -2
  49. package/src/Route.js +106 -26
  50. package/src/Server.js +80 -11
  51. package/src/Storage.js +165 -0
  52. package/src/Validator.js +94 -2
  53. package/src/View/Form.js +193 -17
  54. package/src/View.js +46 -1
  55. package/src/WebSocket.js +18 -3
  56. package/template/config.json +1 -1
  57. package/template/route/www.js +12 -10
  58. package/test/core/{Candy.test.js → Odac.test.js} +2 -2
  59. package/docs/backend/08-database/01-database-connection.md +0 -99
  60. package/docs/backend/08-database/02-using-mysql.md +0 -322
  61. package/src/Mysql.js +0 -575
@@ -35,6 +35,8 @@ jobs:
35
35
 
36
36
  - name: Update PR Title and Body
37
37
  uses: actions/github-script@v7
38
+ env:
39
+ PR_BODY: ${{ steps.generate_body.outputs.body }}
38
40
  with:
39
41
  github-token: ${{ secrets.GITHUB_TOKEN }}
40
42
  script: |
@@ -43,5 +45,5 @@ jobs:
43
45
  repo: context.repo.repo,
44
46
  pull_number: context.issue.number,
45
47
  title: 'Sync `dev` to `main`',
46
- body: `${{ steps.generate_body.outputs.body }}`
48
+ body: process.env.PR_BODY
47
49
  });
package/CHANGELOG.md CHANGED
@@ -1,3 +1,130 @@
1
+ ### Fix
2
+
3
+ - Resolve WebSocket handshake error by echoing subprotocol header
4
+
5
+ ### Refactor
6
+
7
+ - Unified WebSocket architecture and fixed race conditions
8
+
9
+ ### deps
10
+
11
+ - update mysql2 dependency to ^3.16.0
12
+
13
+ ### ⚙️ Engine Tuning
14
+
15
+ - Add type checks for page assignments and a null check for the `authPage` method's `authFile` parameter.
16
+ - extract and trim validation rule names for clearer inverse rule processing.
17
+ - extract HTML stripping logic into a private helper method and apply it to text content generation.
18
+ - migrate custom `odac:field` tag to `odac:input` with updated parsing logic and regex patterns.
19
+ - migrate session locking from in-memory object to `Odac.Storage` for persistence.
20
+ - Move form message clearing logic to the beginning of form submission.
21
+ - move middleware execution to occur after URL parameter processing.
22
+ - pass PR body to github-script action via environment variable
23
+ - Remove duplicate data-error-email attribute assignment.
24
+ - rename `requestMagicLink` method to `magic` in Auth and update its usages and documentation
25
+ - Rename authentication token and session cookie keys from 'candy' to 'odac'.
26
+ - rename internal `Odac` class to `_odac`
27
+ - Rename Mysql to Database and implement connection pooling
28
+ - Update default magic link table name from 'magic_links' to 'odac_magic'.
29
+ - Use `crypto.randomBytes` for client and session ID generation instead of MD5 hashing.
30
+ - use `node:crypto.randomBytes` for generating unique IDs instead of `Date.now()` and `Math.random()`
31
+ - use file descriptor for mail template reading to ensure resource closure
32
+
33
+ ### ✨ What's New
34
+
35
+ - add `_odac/form` POST route with CSRF token validation
36
+ - Add `!disposable` validation rule to block temporary email providers by fetching and caching a daily updated blocklist.
37
+ - Add console error for missing controller files
38
+ - Add custom template rendering engine with caching to Mail service and enhance magic link email options.
39
+ - Add magic link rate limiting, expired link cleanup, and open redirect protection for magic link redirects.
40
+ - add passwordless auto-registration for magic links, improve URL query decoding, and disable token validation for the magic link verification route.
41
+ - Add request language property from Accept-Language header, defaulting to 'en'.
42
+ - Add session cooldown for magic link requests and return explicit errors for rate limits, updating documentation.
43
+ - Allow direct page route definition when a file is provided.
44
+ - Allow specifying and using a redirect URL for magic link authentication.
45
+ - emit 'ping' event when receiving a WebSocket PING frame
46
+ - Enable passing variables directly in view configuration objects for page routes and update documentation.
47
+ - Enable sending plain text and raw HTML emails without templates in the mail service.
48
+ - HTML Mail delivery via direct ODAC Mail Server
49
+ - Ignore database table not found errors when looking up users by email.
50
+ - Implement and document auto-clearing of form inputs on successful submission, controllable via a `clear` attribute.
51
+ - Implement backend-to-frontend data sharing via `Odac.share` and…
52
+ - implement built-in IPC system with Memory and Redis drivers
53
+ - Implement dynamic session garbage collection with simple and batch cleaning modes based on session count.
54
+ - Implement graceful shutdown for primary and worker processes in the cluster.
55
+ - Implement magic login functionality
56
+ - Implement magic login functionality with new routes, internal handlers, and form processing, while removing a generic form route.
57
+ - Implement passwordless signup by auto-registering new users during magic link verification and adding `node:crypto` for random password generation.
58
+ - Implement server actions for forms, allowing `Controller.method` as the action and dispatching internally via a generic endpoint.
59
+ - introduce `Odac.DB.nanoid()` helper, centralize its implementation, and update authentication ID generation strategy documentation.
60
+ - Introduce Nano IDs for primary keys and cookie identifiers, streamlining user insertion logic.
61
+ - introduce service classes in a dedicated directory with naming collision handling and refine route authentication logic.
62
+ - Introduce Storage module to encapsulate LMDB operations and session garbage collection.
63
+ - Migrate session management from in-memory to LMDB, enable server clustering, and add session garbage collection.
64
+ - Modernize db layer with magic api and migrations
65
+ - Modernize db layer with magic api and migrations
66
+ - Render form success and error messages as HTML using a new `textToHtml` utility.
67
+ - Return generic success message for user not found when auto-register is enabled to prevent enumeration.
68
+ - Server Clustering & Persistent Session Management
69
+ - support string-based WebSocket controller paths and update documentation
70
+ - Update route loading to execute function-exported route definitions with Odac.
71
+ - Update session private key hashing algorithm from MD5 to SHA256.
72
+
73
+ ### 📚 Documentation
74
+
75
+ - Add magic links documentation.
76
+ - Fix typo in controller classes documentation
77
+ - overhaul README to detail new Node.js framework features, advanced capabilities, updated quick start instructions, and license.
78
+ - remove redundant html code block tag
79
+ - remove server documentation index.
80
+ - Replace old database connection and MySQL guides with new getting started, query basics, advanced queries, and migrations documentation.
81
+ - Standardize framework name capitalization from Odac to ODAC across documentation.
82
+ - Update database interaction examples from `Odac.Mysql` to `Odac.DB`.
83
+ - update database query examples to include `.select()` and variable assignments.
84
+
85
+ ### 🛠️ Fixes & Improvements
86
+
87
+ - Add error handling for cache file access to ensure validation update proceeds.
88
+ - Add explicit response termination for middleware and redirects, and pass page file path to request.
89
+ - Adjust session key counting range
90
+ - Consume all magic link tokens for an email instead of just the used one to prevent reuse.
91
+ - Correct `odac` special variable path resolution by removing `/src` instead of `/framework/src`.
92
+ - Enable `MiddlewareChain` to automatically use auth handlers when created via `Route.auth.use`.
93
+ - Ensure all HTML tags are recursively stripped when converting HTML to plain text.
94
+ - Ignore `data:` and `vbscript:` pseudo-protocols when processing anchor hrefs.
95
+ - Implement form token rotation on successful form submission without redirect and update client-side form with the new token.
96
+ - Initialize cron interval only in the primary cluster process.
97
+ - Introduce `setSession` method for client ID initialization and optimize internal session and cookie storage.
98
+ - log errors when ensuring the magic link table exists instead of ignoring them
99
+ - Log Odac Auth errors when ensuring token table exists instead of ignoring them.
100
+ - Prevent navigation to `data:` and `vbscript:` URLs.
101
+ - re-register form submit handler when its `data-odac-form` attribute changes to ensure correct event capture.
102
+ - recursively strip nested script and style tags when sanitizing HTML
103
+ - Relax sameSite cookie policy to Lax and refactor redirect handling.
104
+ - remove all socket listeners when closing or disconnecting the WebSocket.
105
+ - Remove early exit from token hash check loop to mitigate timing attacks.
106
+ - return non-function default connection properties directly instead of attempting to bind them
107
+ - return registration error on unique check failure.
108
+ - Robustly extract multipart boundary from request body.
109
+ - serve static files via `createReadStream` and pipe streamable content to response.
110
+ - Validate error route cache handler is a function in Request abort method.
111
+
112
+
113
+
114
+ ---
115
+
116
+ Powered by [⚡ ODAC](https://odac.run)
117
+
118
+ ### 🛠️ Fixes & Improvements
119
+
120
+ - Simplify project initialization by removing directory emptiness validation and extraneous comments.
121
+
122
+
123
+
124
+ ---
125
+
126
+ Powered by [⚡ ODAC](https://odac.run)
127
+
1
128
  ### Framework
2
129
 
3
130
  - HTML Email
package/README.md CHANGED
@@ -1,57 +1,60 @@
1
- <p align="center">
2
- <img src="https://odac.run/assets/img/github/header.png?v=1" alt="Odac Header">
3
- </p>
4
1
 
5
- # ⚡ Odac
2
+ # ⚡ ODAC.JS
6
3
 
7
- **Odac** is a lightweight yet powerful server + framework toolkit for building and deploying modern web apps with ease with built-in automation and a developer-first philosophy.
4
+ **ODAC** is a lightweight, high-performance Node.js framework designed to build modern, scalable web applications with ease. It allows developers to focus on building features rather than configuring boilerplate, offering a complete toolkit for web development.
8
5
 
9
6
  ## ✨ Key Features
10
7
 
11
- ### Core Server Features
12
-
13
- * **Blazing Fast & Ultra Light:** Optimized for performance, Odac is significantly lighter and faster than traditional server solutions, ensuring maximum performance with minimal resource usage.
14
- * 🚀 **Zero-Config Hosting:** Leave the complex server configurations to Odac and focus solely on your code. Get your web applications up and running in minutes.
15
- * 🌐 **One Server, Many Domains:** Easily host and manage multiple websites on a single Odac instance, each with its own domain and resources.
16
- * 🔒 **SSL in Seconds:** Secure all your websites in seconds with free, auto-renewing SSL certificates.
17
- * 📬 **Native Mail Server:** A full-featured, built-in mail server (IMAP/SMTP) that allows you to create and manage email accounts for your domains without needing an external service.
18
- * ⚙️ **Process & CLI Monitor:** Keep your applications running smoothly with the integrated process manager and monitor your server from anywhere with the powerful command-line tool.
19
-
20
- ### Integrated Web Framework
21
-
22
- * 🔗 **Custom URLs & Infinite Pages:** Easily create clean, custom URLs and an unlimited number of pages thanks to the powerful routing and skeleton system.
23
- * ✨ **No-Code AJAX:** Automatically enable AJAX for form submissions and page transitions without writing any custom JavaScript, providing your users with a seamless single-page application (SPA) experience.
24
- * 🛡️ **Safe Requests:** Automatically secure all your endpoints against common vulnerabilities like CSRF with built-in token verification for POST and GET requests.
25
- * 🔐 **Auth Made Easy:** Implement user authentication in minutes with built-in session management, password hashing, and ready-to-use login/register forms.
26
- * 🌍 **Global Ready:** Reach a worldwide audience with built-in, automatic multi-language support. The framework simplifies internationalization (i18n).
27
- * ⏰ **Built-in Cron Jobs:** Schedule and automate recurring tasks with the integrated cron system, perfect for background jobs, data cleanup, and scheduled operations.
8
+ * 🚀 **Developer Friendly:** Simple setup and intuitive API design let you start building immediately.
9
+ * 🔗 **Powerful Routing:** Create clean, custom URLs and manage infinite pages with a flexible routing system.
10
+ * **Seamless SPA Experience:** Automatic AJAX handling for forms and page transitions eliminates the need for complex client-side code.
11
+ * 🛡️ **Built-in Security:** Automatic CSRF protection and secure default headers keep your application safe.
12
+ * 🔐 **Authentication:** Ready-to-use session management, password hashing, and authentication helpers.
13
+ * 🗄️ **Database Agnostic:** Integrated support for major databases (PostgreSQL, MySQL, SQLite) and Redis via Knex.js.
14
+ * 🌍 **i18n Support:** Native multi-language support to help you reach a global audience.
15
+ * **Task Scheduling:** Built-in Cron job system for handling background tasks and recurring operations.
16
+
17
+ ## 🛠️ Advanced Capabilities
18
+
19
+ ### Cluster-Ready IPC
20
+ Built for scale from day one, ODAC includes a powerful Inter-Process Communication (IPC) system.
21
+ * **Unified API:** Use the same `get`, `set`, `publish`, and `subscribe` methods regardless of the underlying driver.
22
+ * **Zero-Config Clustering:** The default `memory` driver automatically syncs data between Node.js cluster workers without external dependencies.
23
+ * **Redis Support:** Switch to the `redis` driver with a single config change to scale horizontally across multiple servers.
24
+
25
+ ### 🔌 Native WebSocket Support
26
+ Real-time features are a first-class citizen in ODAC.
27
+ * **Integrated Server:** No need for third-party libraries; ODAC features a lightweight, native WebSocket implementation.
28
+ * **Room System:** Easily manage user groups with built-in `join`, `leave`, and `broadcast` to room functionality.
29
+ * **Route Integration:** define WebSocket endpoints directly in your router alongside HTTP routes.
30
+
31
+ ### 🎨 Powerful Templating
32
+ ODAC's view engine combines the power of JavaScript with intuitive HTML tags.
33
+ * **Logic Tags:** Use `<odac:if>`, `<odac:for>`, and `<odac:else>` for clean control flow.
34
+ * **Async Support:** Fully asynchronous rendering allows fetching data directly within your views using `await`.
35
+ * **Safety:** Automatic escaping prevents XSS while allowing raw HTML output when explicitly requested.
28
36
 
29
37
  ## 🚀 Quick Start
30
38
 
31
- > 🔥 **Install with a single command. Works on Linux, macOS, and Windows.**
39
+ Get your new ODAC project up and running in seconds using our CLI.
32
40
 
33
- #### Linux & macOS
41
+ ### Create a new project
34
42
 
35
43
  ```bash
36
- curl -sL https://odac.run/install | sudo bash
44
+ npx odac init my-app
37
45
  ```
38
46
 
39
- #### Windows (PowerShell)
47
+ ### Start development
40
48
 
41
- ```powershell
42
- irm https://odac.run/install | iex
49
+ ```bash
50
+ cd my-app
51
+ npm run dev
43
52
  ```
44
53
 
45
- This command:
46
-
47
- - Installs Node.js (v18+) if missing
48
- - Installs Odac globally via npm
49
- - Prepares your system for development or deployment
50
-
51
54
  ## 📚 Documentation
52
55
 
53
- For more detailed information and API reference, please check out our [official documentation website](https://docs.odac.run).
56
+ For detailed guides, API references, and examples, visit our [official documentation](https://docs.odac.run).
54
57
 
55
58
  ## 📄 License
56
59
 
57
- This project is licensed under the AGPL-3.0 License. See the [LICENSE](LICENSE) file for details.
60
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
package/bin/odac.js CHANGED
@@ -20,31 +20,14 @@ async function run() {
20
20
  const projectName = args[0] || '.'
21
21
  const targetDir = path.resolve(process.cwd(), projectName)
22
22
 
23
- // 1. Validate Target Directory
24
- if (fs.existsSync(targetDir)) {
25
- const files = fs.readdirSync(targetDir)
26
- const isNotEmpty = files.some(file =>
27
- !['.git', '.DS_Store', '.gitignore', '.idea', '.vscode'].includes(file)
28
- )
29
-
30
- if (isNotEmpty) {
31
- console.error(`❌ Error: Directory "${projectName === '.' ? 'Current directory' : projectName}" is not empty.`)
32
- console.error(' Please run in an empty directory or specify a new project name.')
33
- process.exit(1)
34
- }
35
- } else {
36
- fs.mkdirSync(targetDir, { recursive: true })
37
- }
23
+ if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true })
38
24
 
39
- // 4. Copy Template
40
25
  console.log(`🚀 Initializing new Odac project in: ${targetDir}`)
41
26
  const templateDir = path.resolve(__dirname, '../template')
42
27
 
43
28
  try {
44
- // Recursive copy
45
29
  fs.cpSync(templateDir, targetDir, { recursive: true })
46
30
 
47
- // Update package.json
48
31
  const pkgPath = path.join(targetDir, 'package.json')
49
32
  const frameworkPkg = require('../package.json')
50
33
 
@@ -52,7 +35,6 @@ async function run() {
52
35
  pkg.name = projectName === '.' ? path.basename(targetDir) : projectName
53
36
  pkg.version = '0.0.1'
54
37
 
55
- // Inject framework dependency
56
38
  if (!pkg.dependencies) pkg.dependencies = {}
57
39
  pkg.dependencies[frameworkPkg.name] = `^${frameworkPkg.version}`
58
40
 
@@ -70,24 +52,12 @@ async function run() {
70
52
  }
71
53
 
72
54
  console.log('\n✨ Project initialized successfully!')
73
- console.log('\n🚀 Starting server...')
74
-
75
- try {
76
- execSync('npm run dev', {
77
- stdio: 'inherit',
78
- cwd: targetDir
79
- })
80
- } catch (err) {
81
- // User probably cancelled with Ctrl+C
82
- console.log('\n👋 Server stopped.')
83
- }
84
55
 
85
56
  } catch (error) {
86
57
  console.error('❌ Error initializing project:', error.message)
87
58
  }
88
59
 
89
60
  } else if (command === 'dev') {
90
- // Start the framework
91
61
  require('../index.js')
92
62
  } else {
93
63
  console.log('Usage:')