@tamyla/clodo-framework 4.4.0 → 4.5.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 (36) hide show
  1. package/CHANGELOG.md +2 -1844
  2. package/README.md +44 -18
  3. package/dist/cli/commands/add.js +325 -0
  4. package/dist/config/service-schema-config.js +98 -5
  5. package/dist/index.js +22 -3
  6. package/dist/middleware/Composer.js +2 -1
  7. package/dist/middleware/factories.js +445 -0
  8. package/dist/middleware/index.js +4 -1
  9. package/dist/modules/ModuleManager.js +6 -2
  10. package/dist/routing/EnhancedRouter.js +248 -44
  11. package/dist/routing/RequestContext.js +393 -0
  12. package/dist/schema/SchemaManager.js +6 -2
  13. package/dist/service-management/generators/code/ServiceMiddlewareGenerator.js +79 -223
  14. package/dist/service-management/generators/code/WorkerIndexGenerator.js +241 -98
  15. package/dist/service-management/generators/config/WranglerTomlGenerator.js +130 -89
  16. package/dist/simple-api.js +4 -4
  17. package/dist/utilities/index.js +134 -1
  18. package/dist/utils/config/environment-var-normalizer.js +233 -0
  19. package/dist/validation/environmentGuard.js +172 -0
  20. package/docs/CHANGELOG.md +1877 -0
  21. package/docs/api-reference.md +153 -0
  22. package/package.json +4 -1
  23. package/scripts/repro-clodo.js +123 -0
  24. package/templates/ai-worker/package.json +19 -0
  25. package/templates/ai-worker/src/index.js +160 -0
  26. package/templates/cron-worker/package.json +19 -0
  27. package/templates/cron-worker/src/index.js +211 -0
  28. package/templates/edge-proxy/package.json +18 -0
  29. package/templates/edge-proxy/src/index.js +150 -0
  30. package/templates/minimal/package.json +17 -0
  31. package/templates/minimal/src/index.js +40 -0
  32. package/templates/queue-processor/package.json +19 -0
  33. package/templates/queue-processor/src/index.js +213 -0
  34. package/templates/rest-api/.dev.vars +2 -0
  35. package/templates/rest-api/package.json +19 -0
  36. package/templates/rest-api/src/index.js +124 -0
package/README.md CHANGED
@@ -23,6 +23,7 @@ A comprehensive framework for building enterprise-grade software architecture on
23
23
  - **[Programmatic API](docs/api/PROGRAMMATIC_API.md)** - Complete programmatic usage
24
24
  - **[Parameter Reference](docs/api/parameter_reference.md)** - All parameters and validation
25
25
  - **[Error Reference](docs/errors.md)** - Error codes and troubleshooting
26
+ - **[Utilities Guide](docs/utilities/README.md)** - Cloudflare API extensions and integrations
26
27
 
27
28
  ### 📖 **Guides & Migration**
28
29
  - **[Getting Started](docs/HOWTO_CONSUME_CLODO_FRAMEWORK.md)** - Step-by-step tutorial
@@ -137,6 +138,16 @@ The Clodo Framework has undergone rigorous validation to ensure it delivers on i
137
138
  - **Configuration Override**: Environment-specific settings
138
139
  - **Template Enhancement**: Service-specific customizations
139
140
 
141
+ ### Cloudflare API Utilities (v4.4.0+)
142
+ - **AI Integration**: Workers AI for text generation, analysis, and embeddings
143
+ - **Storage Solutions**: R2 object storage and KV key-value store
144
+ - **Real-time Features**: Queues for messaging, Durable Objects for state
145
+ - **Advanced Analytics**: Custom metrics and performance monitoring
146
+ - **Email Processing**: Inbound/outbound email handling
147
+ - **Vector Databases**: AI-powered semantic search capabilities
148
+
149
+ > **💡 Utilities are optional extensions** - use them when you need advanced Cloudflare features. See [Utilities Guide](docs/utilities/README.md) for integration examples.
150
+
140
151
  ## 🚀 Three-Tier Service Creation
141
152
 
142
153
  The Clodo Framework implements a sophisticated three-tier service creation process that transforms your requirements into production-ready Cloudflare services:
@@ -264,30 +275,45 @@ The project is organized for maximum clarity and maintainability:
264
275
 
265
276
  ```
266
277
  clodo-framework/
267
- ├── docs/ # 📖 Public-facing documentation (API reference, guides)
268
- ├── i-docs/ # 📚 Internal documentation (organized by category)
269
- │ ├── architecture/ # Design docs, audits, specs
270
- │ ├── development/ # Dev guides, improvements
271
- │ ├── testing/ # Test plans, validation
272
- ├── deployment/ # Deployment analysis, fixes
273
- ├── roadmap/ # Strategic planning
274
- │ ├── guides/ # Integration guides
275
- │ ├── session-reports/ # Development sessions
276
- │ ├── phases/ # Phase completions
277
- │ ├── analysis/ # Technical analysis
278
- └── licensing/ # License information
279
- ├── src/ # 💻 Source code
280
- ├── test/ # Test suites (Latest CI: 115 suites; 2113 tests passed, 4 skipped)
281
- ├── bin/ # 🔧 CLI executables
282
- ├── dist/ # 📦 Built distribution
283
- └── templates/ # 📋 Service templates
278
+ ├── docs/ # 📖 Public documentation
279
+ ├── strategic/ # Business strategy & planning
280
+ │ ├── utilities/ # Utility integration guides
281
+ │ ├── api/ # API reference & guides
282
+ │ ├── integration/ # Integration & migration guides
283
+ └── phases/ # Framework development phases
284
+ ├── i-docs/ # 📚 Internal documentation (organized by category)
285
+ │ ├── architecture/ # Design docs, audits, specs
286
+ │ ├── development/ # Dev guides, improvements
287
+ │ ├── testing/ # Test plans, validation
288
+ │ ├── deployment/ # Deployment analysis, fixes
289
+ ├── roadmap/ # Strategic planning
290
+ ├── guides/ # Integration guides
291
+ ├── session-reports/ # Development sessions
292
+ ├── phases/ # Phase completions
293
+ ├── analysis/ # Technical analysis
294
+ └── licensing/ # License information
295
+ ├── src/ # 💻 Source code
296
+ ├── test/ # ✅ Test suites (Latest CI: 115 suites; 2113 tests passed, 4 skipped)
297
+ ├── cli/ # 🔧 CLI tools & commands
298
+ ├── examples/ # 📚 Usage examples & demos
299
+ ├── config/ # ⚙️ Configuration files & examples
300
+ ├── scripts/ # 🛠️ Build & utility scripts
301
+ ├── templates/ # 📋 Service templates
302
+ ├── dist/ # 📦 Built distribution
303
+ ├── lib/ # 📚 Compiled libraries
304
+ ├── .logs/ # 📝 Log files (hidden)
305
+ ├── .tmp/ # 🗂️ Temporary files (hidden)
306
+ ├── backups/ # 💾 Backup files
307
+ ├── deployments/ # 🚀 Deployment artifacts
308
+ ├── secrets/ # 🔐 Secret management
309
+ └── coverage/ # 📊 Test coverage reports
284
310
 
285
311
  ```
286
312
 
287
313
  **Quality Metrics:**
288
314
  - ✅ **Latest CI (2026-02-04): 115 test suites passed; 4 tests skipped; 2113/2117 tests passed**
289
315
  - ✅ **CLI tests:** passing (all CLI-specific tests passed in the latest run)
290
- - ✅ **Clean architecture** (no temporary or duplicate files)
316
+ - ✅ **Clean architecture** (organized file structure, no clutter in root)
291
317
  - ✅ **Configuration-based** (no hard-coded values in source)
292
318
 
293
319
  ## 📚 Incremental Adoption
@@ -0,0 +1,325 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * clodo add — Incremental enhancement command
4
+ *
5
+ * Adds Cloudflare bindings, middleware, and features to an existing
6
+ * Clodo-generated Worker project without regenerating from scratch.
7
+ *
8
+ * Usage:
9
+ * npx clodo add ai # Add Workers AI binding
10
+ * npx clodo add kv # Add KV namespace
11
+ * npx clodo add kv:users # Add KV with custom binding name
12
+ * npx clodo add d1 # Add D1 database
13
+ * npx clodo add r2 # Add R2 storage
14
+ * npx clodo add vectorize # Add Vectorize index
15
+ * npx clodo add queues # Add Queue producer/consumer
16
+ * npx clodo add cron # Add scheduled handler
17
+ * npx clodo add auth:bearer # Add bearer token middleware
18
+ * npx clodo add auth:apikey # Add API key middleware
19
+ * npx clodo add email # Add Email Workers
20
+ * npx clodo add hyperdrive # Add Hyperdrive (Postgres)
21
+ * npx clodo add analytics # Add Analytics Engine
22
+ * npx clodo add browser # Add Browser Rendering
23
+ *
24
+ * @module cli/commands/add
25
+ */
26
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
27
+ import { join, resolve } from 'path';
28
+
29
+ /**
30
+ * TOML snippets for each feature binding
31
+ */
32
+ const BINDING_TOML = {
33
+ ai: `
34
+ # ═══ Workers AI ════════════════════════════════════════════════════
35
+ [ai]
36
+ binding = "AI"`,
37
+ kv: (bindingName = 'KV') => `
38
+ # ═══ KV Namespace ══════════════════════════════════════════════════
39
+ [[kv_namespaces]]
40
+ binding = "${bindingName}"
41
+ id = ""`,
42
+ d1: (dbName = 'my-db') => `
43
+ # ═══ D1 Database ═══════════════════════════════════════════════════
44
+ [[d1_databases]]
45
+ binding = "DB"
46
+ database_name = "${dbName}"
47
+ database_id = ""`,
48
+ r2: (bucketName = 'my-storage') => `
49
+ # ═══ R2 Object Storage ═════════════════════════════════════════════
50
+ [[r2_buckets]]
51
+ binding = "R2_STORAGE"
52
+ bucket_name = "${bucketName}"`,
53
+ vectorize: (indexName = 'my-index') => `
54
+ # ═══ Vectorize ═════════════════════════════════════════════════════
55
+ [[vectorize]]
56
+ binding = "VECTORIZE_INDEX"
57
+ index_name = "${indexName}"`,
58
+ queues: (queueName = 'my-queue') => `
59
+ # ═══ Queues ════════════════════════════════════════════════════════
60
+ [[queues.producers]]
61
+ binding = "QUEUE"
62
+ queue = "${queueName}"
63
+
64
+ [[queues.consumers]]
65
+ queue = "${queueName}"
66
+ max_batch_size = 10
67
+ max_batch_timeout = 30
68
+ max_retries = 3`,
69
+ cron: `
70
+ # ═══ Cron Triggers ═════════════════════════════════════════════════
71
+ [triggers]
72
+ crons = ["*/5 * * * *"]`,
73
+ email: `
74
+ # ═══ Email Workers ═════════════════════════════════════════════════
75
+ [send_email]
76
+ binding = "EMAIL"`,
77
+ hyperdrive: `
78
+ # ═══ Hyperdrive ════════════════════════════════════════════════════
79
+ [[hyperdrive]]
80
+ binding = "HYPERDRIVE"
81
+ id = ""`,
82
+ analytics: (workerName = 'my-worker') => `
83
+ # ═══ Analytics Engine ══════════════════════════════════════════════
84
+ [[analytics_engine_datasets]]
85
+ binding = "ANALYTICS"
86
+ dataset = "${workerName}-analytics"`,
87
+ browser: `
88
+ # ═══ Browser Rendering ═════════════════════════════════════════════
89
+ [browser]
90
+ binding = "BROWSER"`
91
+ };
92
+
93
+ /**
94
+ * Import snippets to add to the worker entry point
95
+ */
96
+ const IMPORT_SNIPPETS = {
97
+ ai: {
98
+ framework: [],
99
+ utilities: ['runAIModel', 'streamAIResponse'],
100
+ envBinding: 'AI'
101
+ },
102
+ kv: {
103
+ framework: [],
104
+ utilities: ['getKV', 'putKV', 'listKV', 'deleteKV'],
105
+ envBinding: 'KV'
106
+ },
107
+ d1: {
108
+ framework: [],
109
+ utilities: [],
110
+ envBinding: 'DB'
111
+ },
112
+ r2: {
113
+ framework: [],
114
+ utilities: ['putR2Object', 'getR2Object'],
115
+ envBinding: 'R2_STORAGE'
116
+ },
117
+ vectorize: {
118
+ framework: [],
119
+ utilities: ['queryVectors', 'upsertVectors'],
120
+ envBinding: 'VECTORIZE_INDEX'
121
+ },
122
+ queues: {
123
+ framework: [],
124
+ utilities: [],
125
+ envBinding: 'QUEUE'
126
+ },
127
+ 'auth:bearer': {
128
+ framework: ['createBearerAuth'],
129
+ utilities: [],
130
+ envBinding: null
131
+ },
132
+ 'auth:apikey': {
133
+ framework: ['createApiKeyAuth'],
134
+ utilities: [],
135
+ envBinding: null
136
+ },
137
+ email: {
138
+ framework: [],
139
+ utilities: ['sendEmail'],
140
+ envBinding: 'EMAIL'
141
+ },
142
+ hyperdrive: {
143
+ framework: [],
144
+ utilities: [],
145
+ envBinding: 'HYPERDRIVE'
146
+ },
147
+ analytics: {
148
+ framework: [],
149
+ utilities: [],
150
+ envBinding: 'ANALYTICS'
151
+ },
152
+ browser: {
153
+ framework: [],
154
+ utilities: [],
155
+ envBinding: 'BROWSER'
156
+ }
157
+ };
158
+
159
+ /**
160
+ * Parse feature argument (e.g., "kv:users" → { feature: "kv", name: "users" })
161
+ */
162
+ function parseFeatureArg(arg) {
163
+ const [feature, name] = arg.split(':');
164
+ return {
165
+ feature: feature.toLowerCase(),
166
+ name
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Add a feature to an existing project
172
+ */
173
+ export async function addFeature(featureArg, options = {}) {
174
+ const cwd = options.cwd || process.cwd();
175
+ const {
176
+ feature,
177
+ name
178
+ } = parseFeatureArg(featureArg);
179
+ const results = {
180
+ feature,
181
+ wranglerUpdated: false,
182
+ envGuardUpdated: false,
183
+ importsAdded: [],
184
+ instructions: []
185
+ };
186
+
187
+ // 1. Update wrangler.toml
188
+ const wranglerPath = join(cwd, 'wrangler.toml');
189
+ if (existsSync(wranglerPath)) {
190
+ const wranglerContent = readFileSync(wranglerPath, 'utf8');
191
+
192
+ // Check if binding already exists
193
+ const bindingCheck = {
194
+ ai: '[ai]',
195
+ kv: '[[kv_namespaces]]',
196
+ d1: '[[d1_databases]]',
197
+ r2: '[[r2_buckets]]',
198
+ vectorize: '[[vectorize]]',
199
+ queues: '[[queues.',
200
+ cron: '[triggers]',
201
+ email: '[send_email]',
202
+ hyperdrive: '[[hyperdrive]]',
203
+ analytics: '[[analytics_engine_datasets]]',
204
+ browser: '[browser]'
205
+ };
206
+ const baseFeature = feature.includes(':') ? feature.split(':')[0] : feature;
207
+ if (bindingCheck[baseFeature] && wranglerContent.includes(bindingCheck[baseFeature])) {
208
+ results.instructions.push(`⚠️ ${baseFeature} binding already exists in wrangler.toml`);
209
+ } else {
210
+ const tomlSnippet = typeof BINDING_TOML[baseFeature] === 'function' ? BINDING_TOML[baseFeature](name || undefined) : BINDING_TOML[baseFeature];
211
+ if (tomlSnippet) {
212
+ writeFileSync(wranglerPath, wranglerContent.trimEnd() + '\n' + tomlSnippet + '\n', 'utf8');
213
+ results.wranglerUpdated = true;
214
+ results.instructions.push(`✅ Added ${baseFeature} binding to wrangler.toml`);
215
+ }
216
+ }
217
+ } else {
218
+ results.instructions.push('⚠️ No wrangler.toml found. Create one first with: npx clodo create');
219
+ }
220
+
221
+ // 2. Show import suggestions
222
+ const importInfo = IMPORT_SNIPPETS[feature] || IMPORT_SNIPPETS[feature.split(':')[0]];
223
+ if (importInfo) {
224
+ if (importInfo.framework.length > 0) {
225
+ results.importsAdded.push(`import { ${importInfo.framework.join(', ')} } from '@tamyla/clodo-framework';`);
226
+ results.instructions.push(`📦 Add to your worker: import { ${importInfo.framework.join(', ')} } from '@tamyla/clodo-framework';`);
227
+ }
228
+ if (importInfo.utilities.length > 0) {
229
+ results.importsAdded.push(`import { ${importInfo.utilities.join(', ')} } from '@tamyla/clodo-framework/utilities';`);
230
+ results.instructions.push(`📦 Add to your worker: import { ${importInfo.utilities.join(', ')} } from '@tamyla/clodo-framework/utilities';`);
231
+ }
232
+ if (importInfo.envBinding) {
233
+ results.instructions.push(`🔧 Add '${importInfo.envBinding}' to your createEnvironmentGuard({ required: [...] })`);
234
+ }
235
+ }
236
+
237
+ // 3. Feature-specific setup instructions
238
+ const setupInstructions = {
239
+ ai: '🚀 Workers AI is ready! Use env.AI.run(model, options) in your handler.',
240
+ kv: `🚀 Run: wrangler kv namespace create "${name || 'KV'}" to create the namespace, then paste the ID.`,
241
+ d1: `🚀 Run: wrangler d1 create "${name || 'my-db'}" to create the database.`,
242
+ r2: `🚀 Run: wrangler r2 bucket create "${name || 'my-storage'}" to create the bucket.`,
243
+ vectorize: `🚀 Run: wrangler vectorize create "${name || 'my-index'}" --dimensions 768 --metric cosine`,
244
+ queues: `🚀 Queue "${name || 'my-queue'}" will be auto-created on first deploy.`,
245
+ cron: '🚀 Cron trigger added. Implement the scheduled() handler in your worker.',
246
+ 'auth:bearer': '🔐 Add createBearerAuth({ token: env.SECRET_KEY }) to your middleware stack.',
247
+ 'auth:apikey': '🔐 Add createApiKeyAuth({ keys: [env.API_KEY] }) to your middleware stack.',
248
+ email: '🚀 Email binding ready. Use env.EMAIL.send() in your handler.',
249
+ hyperdrive: '🚀 Run: wrangler hyperdrive create <name> --connection-string "postgres://..."',
250
+ analytics: '🚀 Analytics Engine ready. Use env.ANALYTICS.writeDataPoint() in your handler.',
251
+ browser: '🚀 Browser Rendering ready. Use env.BROWSER in your handler.'
252
+ };
253
+ if (setupInstructions[feature]) {
254
+ results.instructions.push(setupInstructions[feature]);
255
+ }
256
+ return results;
257
+ }
258
+
259
+ /**
260
+ * CLI entry point for `clodo add`
261
+ */
262
+ export function registerAddCommand(program) {
263
+ program.command('add <feature>').description('Add a Cloudflare binding or feature to your existing Worker project').option('-d, --dir <path>', 'Project directory', '.').option('--dry-run', 'Show what would change without modifying files').action(async (feature, options) => {
264
+ console.log(`\n🔧 Adding "${feature}" to your Worker project...\n`);
265
+ const results = await addFeature(feature, {
266
+ cwd: resolve(options.dir),
267
+ dryRun: options.dryRun
268
+ });
269
+ for (const instruction of results.instructions) {
270
+ console.log(` ${instruction}`);
271
+ }
272
+ console.log('');
273
+ });
274
+ }
275
+
276
+ /**
277
+ * List all available features for `clodo add`
278
+ */
279
+ export function listAvailableFeatures() {
280
+ return [{
281
+ name: 'ai',
282
+ description: 'Workers AI (text generation, embeddings, etc.)'
283
+ }, {
284
+ name: 'kv',
285
+ description: 'KV Namespace (key-value storage)',
286
+ syntax: 'kv[:binding_name]'
287
+ }, {
288
+ name: 'd1',
289
+ description: 'D1 Database (SQLite)',
290
+ syntax: 'd1[:db_name]'
291
+ }, {
292
+ name: 'r2',
293
+ description: 'R2 Object Storage',
294
+ syntax: 'r2[:bucket_name]'
295
+ }, {
296
+ name: 'vectorize',
297
+ description: 'Vectorize (vector database)',
298
+ syntax: 'vectorize[:index_name]'
299
+ }, {
300
+ name: 'queues',
301
+ description: 'Queues (message queue)',
302
+ syntax: 'queues[:queue_name]'
303
+ }, {
304
+ name: 'cron',
305
+ description: 'Cron Triggers (scheduled jobs)'
306
+ }, {
307
+ name: 'auth:bearer',
308
+ description: 'Bearer token authentication middleware'
309
+ }, {
310
+ name: 'auth:apikey',
311
+ description: 'API key authentication middleware'
312
+ }, {
313
+ name: 'email',
314
+ description: 'Email Workers (send email)'
315
+ }, {
316
+ name: 'hyperdrive',
317
+ description: 'Hyperdrive (Postgres connection pool)'
318
+ }, {
319
+ name: 'analytics',
320
+ description: 'Analytics Engine (custom metrics)'
321
+ }, {
322
+ name: 'browser',
323
+ description: 'Browser Rendering API'
324
+ }];
325
+ }
@@ -2,8 +2,28 @@
2
2
  // Allows runtime overrides for enums and features to keep validation flexible and configurable
3
3
 
4
4
  let config = {
5
- serviceTypes: ['api-service', 'data-service', 'worker', 'pages', 'gateway', 'generic'],
6
- features: ['d1', 'upstash', 'kv', 'r2', 'pages', 'ws', 'durableObject', 'durableObjects', 'cron', 'metrics']
5
+ serviceTypes: ['api-service', 'data-service', 'worker', 'pages', 'gateway', 'generic',
6
+ // New real-world Cloudflare Worker patterns
7
+ 'ai-worker', 'queue-processor', 'cron-worker', 'edge-proxy'],
8
+ features: [
9
+ // Storage & Databases
10
+ 'd1', 'kv', 'r2',
11
+ // AI & ML
12
+ 'ai', 'vectorize',
13
+ // Messaging & Events
14
+ 'queues', 'cron',
15
+ // Compute
16
+ 'durableObject', 'durableObjects',
17
+ // Communication
18
+ 'email', 'ws',
19
+ // Networking
20
+ 'hyperdrive', 'browser',
21
+ // Observability
22
+ 'metrics', 'analytics',
23
+ // Infrastructure
24
+ 'pages',
25
+ // Legacy (kept for backward compatibility)
26
+ 'upstash']
7
27
  };
8
28
  export function getConfig() {
9
29
  return {
@@ -16,7 +36,80 @@ export function setConfig(updates = {}) {
16
36
  }
17
37
  export function resetConfig() {
18
38
  config = {
19
- serviceTypes: ['api-service', 'data-service', 'worker', 'pages', 'gateway', 'generic'],
20
- features: ['d1', 'upstash', 'kv', 'r2', 'pages', 'ws', 'durableObject', 'durableObjects', 'cron', 'metrics']
39
+ serviceTypes: ['api-service', 'data-service', 'worker', 'pages', 'gateway', 'generic', 'ai-worker', 'queue-processor', 'cron-worker', 'edge-proxy'],
40
+ features: ['d1', 'kv', 'r2', 'ai', 'vectorize', 'queues', 'cron', 'durableObject', 'durableObjects', 'email', 'ws', 'hyperdrive', 'browser', 'metrics', 'analytics', 'pages', 'upstash']
21
41
  };
22
- }
42
+ }
43
+
44
+ /**
45
+ * Maps feature names to their wrangler.toml binding configuration.
46
+ * Used by scaffold generators to produce correct wrangler.toml output.
47
+ */
48
+ export const FEATURE_BINDING_MAP = {
49
+ ai: {
50
+ toml: '[ai]\nbinding = "AI"',
51
+ envType: 'Ai',
52
+ binding: 'AI'
53
+ },
54
+ vectorize: {
55
+ toml: '[[vectorize]]\nbinding = "VECTORIZE_INDEX"\nindex_name = "my-index"',
56
+ envType: 'VectorizeIndex',
57
+ binding: 'VECTORIZE_INDEX'
58
+ },
59
+ kv: {
60
+ toml: '[[kv_namespaces]]\nbinding = "KV_DATA"\nid = ""',
61
+ envType: 'KVNamespace',
62
+ binding: 'KV_DATA'
63
+ },
64
+ d1: {
65
+ toml: '[[d1_databases]]\nbinding = "DB"\ndatabase_name = ""\ndatabase_id = ""',
66
+ envType: 'D1Database',
67
+ binding: 'DB'
68
+ },
69
+ r2: {
70
+ toml: '[[r2_buckets]]\nbinding = "R2_STORAGE"\nbucket_name = ""',
71
+ envType: 'R2Bucket',
72
+ binding: 'R2_STORAGE'
73
+ },
74
+ queues: {
75
+ toml: '[[queues.producers]]\nbinding = "QUEUE"\nqueue = "my-queue"\n\n[[queues.consumers]]\nqueue = "my-queue"\nmax_batch_size = 10\nmax_batch_timeout = 30',
76
+ envType: 'Queue',
77
+ binding: 'QUEUE'
78
+ },
79
+ durableObject: {
80
+ toml: '[[durable_objects.bindings]]\nname = "MY_DURABLE_OBJECT"\nclass_name = "MyDurableObject"',
81
+ envType: 'DurableObjectNamespace',
82
+ binding: 'MY_DURABLE_OBJECT'
83
+ },
84
+ durableObjects: {
85
+ toml: '[[durable_objects.bindings]]\nname = "MY_DURABLE_OBJECT"\nclass_name = "MyDurableObject"',
86
+ envType: 'DurableObjectNamespace',
87
+ binding: 'MY_DURABLE_OBJECT'
88
+ },
89
+ email: {
90
+ toml: '[send_email]\nname = "EMAIL"\ndestination_address = ""',
91
+ envType: 'SendEmail',
92
+ binding: 'EMAIL'
93
+ },
94
+ hyperdrive: {
95
+ toml: '[[hyperdrive]]\nbinding = "HYPERDRIVE"\nid = ""',
96
+ envType: 'Hyperdrive',
97
+ binding: 'HYPERDRIVE'
98
+ },
99
+ browser: {
100
+ toml: '[browser]\nbinding = "BROWSER"',
101
+ envType: 'Fetcher',
102
+ binding: 'BROWSER'
103
+ },
104
+ analytics: {
105
+ toml: '[[analytics_engine_datasets]]\nbinding = "ANALYTICS"\ndataset = "my-dataset"',
106
+ envType: 'AnalyticsEngineDataset',
107
+ binding: 'ANALYTICS'
108
+ },
109
+ cron: {
110
+ // Cron doesn't add bindings, it adds triggers
111
+ toml: '[triggers]\ncrons = ["*/5 * * * *"]',
112
+ envType: null,
113
+ binding: null
114
+ }
115
+ };
package/dist/index.js CHANGED
@@ -15,6 +15,18 @@ export { createDomainConfigSchema, validateDomainConfig, createDefaultDomainConf
15
15
  export { initializeService } from './worker/integration.js';
16
16
  export { autoConfigureFramework } from './version/VersionDetector.js';
17
17
 
18
+ // ─── NEW: Middleware Factories & Composition ─────────────────────────
19
+ export { createCorsMiddleware, createErrorHandler, createRateLimitGuard, createLogger, createBearerAuth, createApiKeyAuth, composeMiddleware } from './middleware/factories.js';
20
+
21
+ // ─── NEW: Environment Guard ──────────────────────────────────────────
22
+ export { EnvironmentGuard, createEnvironmentGuard } from './validation/environmentGuard.js';
23
+
24
+ // ─── NEW: RequestContext (Hono-style) ────────────────────────────────
25
+ export { RequestContext, createRequestContext } from './routing/RequestContext.js';
26
+
27
+ // ─── NEW: Feature-to-binding mapping ─────────────────────────────────
28
+ export { FEATURE_BINDING_MAP } from './config/service-schema-config.js';
29
+
18
30
  // Core data and schema components
19
31
  export * from './services/GenericDataService.js';
20
32
  export * from './schema/SchemaManager.js';
@@ -62,12 +74,19 @@ export { classifyError, getRecoverySuggestions } from './lib/shared/error-handli
62
74
  export { FrameworkInfo } from './version/FrameworkInfo.js';
63
75
  export { TemplateRuntime } from './utils/TemplateRuntime.js';
64
76
  export { HealthChecker } from './monitoring/HealthChecker.js';
65
- export const FRAMEWORK_VERSION = '1.0.0';
77
+ export const FRAMEWORK_VERSION = '4.4.1';
66
78
  export const FRAMEWORK_NAME = 'Clodo Framework';
67
79
 
68
- // Helper for framework initialization
80
+ // ─── Compatibility Constants (for consistent wrangler.toml generation) ──
81
+ export const RECOMMENDED_COMPATIBILITY_DATE = '2024-12-01';
82
+ export const MINIMUM_COMPATIBILITY_DATE = '2023-06-01';
83
+ export const RECOMMENDED_COMPATIBILITY_FLAGS = ['nodejs_compat'];
84
+
85
+ // Helper for framework initialization (silent by default, verbose with DEBUG)
69
86
  export const initializeFramework = (options = {}) => {
70
- console.log(`${FRAMEWORK_NAME} v${FRAMEWORK_VERSION} initialized`);
87
+ if (options.verbose || typeof process !== 'undefined' && process.env?.DEBUG) {
88
+ console.log(`${FRAMEWORK_NAME} v${FRAMEWORK_VERSION} initialized`);
89
+ }
71
90
  return {
72
91
  version: FRAMEWORK_VERSION,
73
92
  name: FRAMEWORK_NAME,
@@ -26,7 +26,8 @@ export class MiddlewareComposer {
26
26
  // Postprocess in reverse order
27
27
  for (const m of chain.slice().reverse()) {
28
28
  if (typeof m.postprocess === 'function') {
29
- const updated = await m.postprocess(response);
29
+ // Pass the original request as the second argument so postprocess can access per-request state
30
+ const updated = await m.postprocess(response, request);
30
31
  // Allow middleware to replace response
31
32
  if (updated instanceof Response) response = updated;
32
33
  }