odac 1.2.0 → 1.3.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.
@@ -28,6 +28,15 @@ trigger: always_on
28
28
  - **Loop Optimization:** Use labeled loops (`label: for`) for efficient control flow in nested structures. Eliminate intermediate "flag" variables (`isMatch`, `found`) by using direct `return` or `continue label`.
29
29
  - **Direct Returns:** Return a value as soon as it is determined. Avoid assigning to a temporary variable (e.g. `matchedUser`) and breaking the loop, unless post-loop processing is strictly necessary.
30
30
  - **Async State Safety:** When an async function depends on mutable class state (like `pendingMiddlewares`), capture that state into a local `const` *synchronously* before triggering any async operations. This prevents race conditions where the state changes before the async task consumes it.
31
+ - **Async I/O Preference:** Prefer asynchronous file system operations (`fs.promises` or `await fs.promises.*`) over synchronous methods (`fs.readFileSync`, `fs.writeFileSync`) to prevent blocking the event loop and ensure high concurrency, especially in request handling paths.
31
32
 
32
33
  ## Dependency Management
33
- - **Prefer Native Fetch:** Use the native `fetch` API for network requests in both Node.js (18+) and browser environments to reduce dependencies and bundle size.
34
+ - **Prefer Native Fetch:** Use the native `fetch` API for network requests in both Node.js (18+) and browser environments to reduce dependencies and bundle size.
35
+
36
+ ## Naming & Text Conventions
37
+ - **ODAC Casing:** Always write "ODAC" in uppercase letters when referring to the framework name in strings, comments, log messages, or user-facing text. **EXCEPTION:** The class name itself (`class Odac`) and variable references to it should remain `Odac` (PascalCase) as per code conventions.
38
+
39
+ ## Testing & Validation
40
+ - **Mandatory Test Coverage:** Every new feature, method, or significant logic change MUST be accompanied by a corresponding unit or integration test.
41
+ - **Verify Correctness:** do not assume code works; prove it with a test that covers both success and failure scenarios (e.g., edge cases, error conditions).
42
+ - **Update Existing Tests:** If a feature modifies existing behavior, update the relevant tests to reflect the new logic and ensure they pass.
@@ -7,7 +7,7 @@ on:
7
7
  paths-ignore:
8
8
  - 'CHANGELOG.md'
9
9
  - 'package.json'
10
- - '.github/workflows/test-publish.yml'
10
+ - '.github/workflows/**'
11
11
  workflow_dispatch:
12
12
 
13
13
  jobs:
@@ -56,6 +56,8 @@ jobs:
56
56
  repository: odac-run/actions
57
57
  token: ${{ secrets.GH_PAT }}
58
58
  path: .github/odac-actions
59
+ ref: main
60
+ persist-credentials: false
59
61
 
60
62
  - name: Generate Release Notes
61
63
  id: ai_notes
@@ -70,11 +72,35 @@ jobs:
70
72
  - name: Cleanup Actions
71
73
  if: always()
72
74
  run: rm -rf .github/odac-actions
75
+
76
+ - name: Update PR Title
77
+ uses: actions/github-script@v7
78
+ if: steps.ai_notes.outcome == 'success'
79
+ env:
80
+ AI_TITLE: ${{ steps.ai_notes.outputs.release-title }}
81
+ with:
82
+ github-token: ${{ secrets.GITHUB_TOKEN }}
83
+ script: |
84
+ const prs = await github.rest.repos.listPullRequestsAssociatedWithCommit({
85
+ owner: context.repo.owner,
86
+ repo: context.repo.repo,
87
+ commit_sha: context.sha,
88
+ });
89
+ if (prs.data.length > 0) {
90
+ await github.rest.pulls.update({
91
+ owner: context.repo.owner,
92
+ repo: context.repo.repo,
93
+ pull_number: prs.data[0].number,
94
+ title: process.env.AI_TITLE
95
+ });
96
+ }
97
+
73
98
  - name: Update Release
74
99
  uses: softprops/action-gh-release@v1
75
100
  if: steps.ai_notes.outcome == 'success' && steps.version.outputs.version != ''
76
101
  with:
77
102
  tag_name: v${{ steps.version.outputs.version }}
103
+ name: ${{ steps.ai_notes.outputs.release-title }}
78
104
  body_path: RELEASE_NOTE.md
79
105
  draft: false
80
106
  prerelease: false
package/.husky/pre-push CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env sh
2
2
  . "$(dirname -- "$0")/_/husky.sh"
3
3
 
4
- # Prevent pushing code with High/Critical vulnerabilities
5
- echo "🛡️ Running Security Gate (npm audit)..."
4
+ # Prevent pushing code with High/Critical vulnerabilities in production dependencies
5
+ echo "🛡️ Running Production Security Gate (npm audit)..."
6
6
 
7
- npm audit --audit-level=high
7
+ npm audit --audit-level=high --omit=dev
8
8
 
9
9
  if [ $? -ne 0 ]; then
10
10
  echo "❌ Security Check Failed! High vulnerabilities detected."
package/.releaserc.js CHANGED
@@ -122,7 +122,7 @@ Powered by [⚡ ODAC](https://odac.run)
122
122
  [
123
123
  '@semantic-release/npm',
124
124
  {
125
- npmPublish: false
125
+ provenance: true
126
126
  }
127
127
  ],
128
128
  [
@@ -134,4 +134,4 @@ Powered by [⚡ ODAC](https://odac.run)
134
134
  ],
135
135
  '@semantic-release/github'
136
136
  ]
137
- }
137
+ }
package/CHANGELOG.md CHANGED
@@ -1,3 +1,35 @@
1
+ ### ⚙️ Engine Tuning
2
+
3
+ - Improve disposable domain cache management by relocating the cache path, ensuring directory existence, and standardizing error logging.
4
+ - Migrate file system operations in Mail and View to use async `fs.promises` for non-blocking I/O, aligning with new memory.md guidelines.
5
+ - remove unused `WebSocketClient` variable assignments in `WebSocket.test.js`
6
+ - streamline cache file reading by removing redundant access check.
7
+ - **validator:** Migrate file operations to `fs.promises` for asynchronous I/O and enhance security with explicit content sanitization.
8
+
9
+ ### ⚡️ Performance Upgrades
10
+
11
+ - Optimize parametric route matching by implementing a two-phase, pre-indexed lookup strategy grouped by segment count.
12
+
13
+ ### ✨ What's New
14
+
15
+ - Add configurable max payload size and message rate limiting options to WebSocket routes.
16
+ - Refined pre-push security audit to omit dev dependencies, optimized variable initializations, enhanced test mocks with `writeHead` and `finished` properties, introduced conditional `setTimeout` for request handling, and improved code formatting in client-side WebSocket and AJAX logic.
17
+ - update `.gitignore` to no longer ignore package manager lock files and to ignore the `storage/` directory
18
+
19
+ ### 🛠️ Fixes & Improvements
20
+
21
+ - Enhance route directory not found error logging and add ODAC casing convention to memory rules.
22
+ - Set owner-only read/write permissions (0o600) for temporary cache files created during validation.
23
+ - suppress tailwind process stdout output
24
+ - Update default Unix socket path and enhance socket connection error handling with specific guidance for `ENOENT` errors.
25
+ - Update Tailwind CSS watch flag to '--watch=always' and refine child process stdio configuration.
26
+
27
+
28
+
29
+ ---
30
+
31
+ Powered by [⚡ ODAC](https://odac.run)
32
+
1
33
  ### agent
2
34
 
3
35
  - Clarify logging strategies for development and production environments
package/bin/odac.js CHANGED
@@ -117,6 +117,9 @@ async function run() {
117
117
  if (cluster.isPrimary) {
118
118
  const configs = getTailwindConfigs()
119
119
  const tails = []
120
+ const names = configs.map(c => c.name).join(', ')
121
+
122
+ console.log(`🎨 \x1b[36mODAC Styles:\x1b[0m Watching for changes (${names})`)
120
123
 
121
124
  configs.forEach(({input, cssOutput, name, isCustom}) => {
122
125
  let tailwindProcess = null
@@ -125,19 +128,32 @@ async function run() {
125
128
  const localCli = path.join(process.cwd(), 'node_modules', '.bin', 'tailwindcss')
126
129
  const useLocal = fs.existsSync(localCli)
127
130
  const cmd = useLocal ? localCli : 'npx'
128
- const args = useLocal ? ['-i', input, '-o', cssOutput, '--watch'] : ['@tailwindcss/cli', '-i', input, '-o', cssOutput, '--watch']
129
-
130
- console.log(`🎨 Starting Tailwind CSS for ${name} (${isCustom ? 'Custom' : 'Default'})...`)
131
- console.log(`📂 Watching directory: ${process.cwd()}`)
131
+ const args = useLocal
132
+ ? ['-i', input, '-o', cssOutput, '--watch=always']
133
+ : ['@tailwindcss/cli', '-i', input, '-o', cssOutput, '--watch=always']
132
134
 
133
135
  tailwindProcess = spawn(cmd, args, {
134
- stdio: 'inherit',
136
+ stdio: ['pipe', 'ignore', 'pipe'],
135
137
  shell: !useLocal, // Valid for npm/npx compatibility if local not found
136
138
  cwd: process.cwd()
137
139
  })
138
140
 
141
+ // Filter stderr: suppress status noise, forward only real errors
142
+ tailwindProcess.stderr.on('data', chunk => {
143
+ const raw = chunk.toString()
144
+ const lines = raw.split('\n')
145
+ for (const line of lines) {
146
+ // Strip ANSI escape codes to ensure reliable filtering
147
+ const clean = line.replace(/\x1B\[[0-9;]*[JKmsu]/g, '').trim()
148
+
149
+ if (!clean || clean.startsWith('Done in') || clean.startsWith('≈')) continue
150
+
151
+ process.stderr.write(`\x1b[31m[ODAC Style Error]\x1b[0m ${line}\n`)
152
+ }
153
+ })
154
+
139
155
  tailwindProcess.on('error', err => {
140
- console.error(`❌ Tailwind watcher failed to start for ${name}:`, err.message)
156
+ console.error(`❌ \x1b[31m[ODAC Style Error]\x1b[0m Failed to start watcher for ${name}:`, err.message)
141
157
  })
142
158
 
143
159
  tailwindProcess.on('exit', code => {