@tamyla/clodo-framework 4.0.13 → 4.0.14

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 (62) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +7 -0
  3. package/dist/cli/commands/create.js +2 -1
  4. package/dist/middleware/Composer.js +38 -0
  5. package/dist/middleware/Registry.js +14 -0
  6. package/dist/middleware/index.js +3 -0
  7. package/dist/middleware/shared/basicAuth.js +21 -0
  8. package/dist/middleware/shared/cors.js +28 -0
  9. package/dist/middleware/shared/index.js +3 -0
  10. package/dist/middleware/shared/logging.js +14 -0
  11. package/dist/service-management/GenerationEngine.js +13 -2
  12. package/dist/service-management/ServiceOrchestrator.js +6 -2
  13. package/dist/service-management/generators/code/ServiceMiddlewareGenerator.js +156 -10
  14. package/dist/service-management/generators/code/WorkerIndexGenerator.js +75 -9
  15. package/dist/simple-api.js +32 -1
  16. package/docs/MIDDLEWARE_MIGRATION_SUMMARY.md +121 -0
  17. package/package.json +4 -1
  18. package/scripts/DEPLOY_COMMAND_NEW.js +128 -0
  19. package/scripts/README-automated-testing-suite.md +356 -0
  20. package/scripts/README-test-clodo-deployment.md +157 -0
  21. package/scripts/README.md +50 -0
  22. package/scripts/analyze-imports.ps1 +104 -0
  23. package/scripts/analyze-mixed-code.js +163 -0
  24. package/scripts/analyze-mixed-rationale.js +149 -0
  25. package/scripts/automated-testing-suite.js +776 -0
  26. package/scripts/deployment/README.md +31 -0
  27. package/scripts/deployment/deploy-domain.ps1 +449 -0
  28. package/scripts/deployment/deploy-staging.js +120 -0
  29. package/scripts/deployment/validate-staging.js +166 -0
  30. package/scripts/diagnose-imports.js +362 -0
  31. package/scripts/framework-diagnostic.js +368 -0
  32. package/scripts/migration/migrate-middleware-legacy-to-contract.js +47 -0
  33. package/scripts/post-publish-test.js +663 -0
  34. package/scripts/scan-worker-issues.js +52 -0
  35. package/scripts/service-management/README.md +27 -0
  36. package/scripts/service-management/setup-interactive.ps1 +693 -0
  37. package/scripts/test-clodo-deployment.js +588 -0
  38. package/scripts/test-downstream-install.js +237 -0
  39. package/scripts/test-local-package.ps1 +126 -0
  40. package/scripts/test-local-package.sh +166 -0
  41. package/scripts/test-package.js +339 -0
  42. package/scripts/testing/README.md +49 -0
  43. package/scripts/testing/test-first.ps1 +0 -0
  44. package/scripts/testing/test-first50.ps1 +0 -0
  45. package/scripts/testing/test.ps1 +0 -0
  46. package/scripts/utilities/README.md +61 -0
  47. package/scripts/utilities/check-bin.js +8 -0
  48. package/scripts/utilities/check-bundle.js +23 -0
  49. package/scripts/utilities/check-dist-imports.js +65 -0
  50. package/scripts/utilities/check-import-paths.js +191 -0
  51. package/scripts/utilities/cleanup-cli.js +159 -0
  52. package/scripts/utilities/deployment-helpers.ps1 +199 -0
  53. package/scripts/utilities/fix-dist-imports.js +135 -0
  54. package/scripts/utilities/generate-secrets.js +159 -0
  55. package/scripts/utilities/safe-push.ps1 +51 -0
  56. package/scripts/utilities/setup-helpers.ps1 +206 -0
  57. package/scripts/utilities/test-packaged-artifact.js +92 -0
  58. package/scripts/utilities/validate-dist-imports.js +189 -0
  59. package/scripts/utilities/validate-schema.js +102 -0
  60. package/scripts/verify-exports.js +193 -0
  61. package/scripts/verify-worker-safety.js +73 -0
  62. package/types/middleware.d.ts +1 -0
@@ -0,0 +1,27 @@
1
+ # Service Management Scripts
2
+
3
+ Scripts for creating, initializing, and setting up Clodo Framework services.
4
+
5
+ ## Scripts
6
+
7
+ ### setup-interactive.ps1
8
+ Interactive service setup wizard that guides users through creating new services.
9
+
10
+ **Features:**
11
+ - Interactive prompts for service configuration
12
+ - Template selection and customization
13
+ - Domain configuration setup
14
+ - Automatic dependency installation
15
+
16
+ **Usage:**
17
+ ```powershell
18
+ .\scripts\service-management\setup-interactive.ps1 -ServiceName my-service -ServiceType api-gateway
19
+ ```
20
+
21
+ **Parameters:**
22
+ - `ServiceName` - Name of the service to create
23
+ - `ServiceType` - Type of service (data-service, auth-service, content-service, api-gateway, generic)
24
+ - `DomainName` - Domain name for the service
25
+ - `NonInteractive` - Skip interactive prompts
26
+ - `TemplatePath` - Path to service templates
27
+ - `OutputPath` - Output directory for the service
@@ -0,0 +1,693 @@
1
+ param(
2
+ [Parameter(Mandatory=$false)]
3
+ [string]$ServiceName,
4
+
5
+ [Parameter(Mandatory=$false)]
6
+ [ValidateSet("data-service", "auth-service", "content-service", "api-gateway", "generic")]
7
+ [string]$ServiceType = "generic",
8
+
9
+ [Parameter(Mandatory=$false)]
10
+ [string]$DomainName,
11
+
12
+ [Parameter(Mandatory=$false)]
13
+ [switch]$NonInteractive,
14
+
15
+ [Parameter(Mandatory=$false)]
16
+ [string]$TemplatePath = ".\templates",
17
+
18
+ [Parameter(Mandatory=$false)]
19
+ [string]$OutputPath = "."
20
+ )
21
+
22
+ # Import Clodo Framework utilities
23
+ . "$PSScriptRoot\..\utilities\deployment-helpers.ps1"
24
+ . "$PSScriptRoot\..\utilities\setup-helpers.ps1"
25
+
26
+ # Configuration
27
+ $ErrorActionPreference = "Stop"
28
+ $ProgressPreference = "SilentlyContinue"
29
+
30
+ # Colors for output
31
+ $Green = "Green"
32
+ $Yellow = "Yellow"
33
+ $Red = "Red"
34
+ $Cyan = "Cyan"
35
+ $White = "White"
36
+ $Magenta = "Magenta"
37
+
38
+ function Write-Step {
39
+ param([string]$Message)
40
+ Write-Host "==> $Message" -ForegroundColor $Cyan
41
+ }
42
+
43
+ function Write-Success {
44
+ param([string]$Message)
45
+ Write-Host "[OK] $Message" -ForegroundColor $Green
46
+ }
47
+
48
+ function Write-Warning {
49
+ param([string]$Message)
50
+ Write-Host "WARNING: $Message" -ForegroundColor $Yellow
51
+ }
52
+
53
+ function Write-Error-Message {
54
+ param([string]$Message)
55
+ Write-Host "[ERROR] $Message" -ForegroundColor $Red
56
+ }
57
+
58
+ function Write-Prompt {
59
+ param([string]$Message)
60
+ Write-Host "$Message" -ForegroundColor $Magenta -NoNewline
61
+ }
62
+
63
+ function Exit-WithError {
64
+ param([string]$Message, [int]$ExitCode = 1)
65
+ Write-Error-Message $Message
66
+ exit $ExitCode
67
+ }
68
+
69
+ # Main setup function
70
+ function Invoke-InteractiveSetup {
71
+ Write-Step "Clodo Framework - Interactive Service Setup"
72
+ Write-Host "Welcome to the Clodo Framework service setup wizard!" -ForegroundColor $Cyan
73
+ Write-Host "This wizard will help you create a new service with proper configuration.`n" -ForegroundColor $White
74
+
75
+ # Gather service information
76
+ $serviceInfo = Get-ServiceInformation
77
+ $domainInfo = Get-DomainInformation
78
+ $cloudflareInfo = Get-CloudflareInformation
79
+ $featureInfo = Get-FeatureConfiguration -ServiceType $serviceInfo.Type
80
+
81
+ # Display configuration summary
82
+ Show-ConfigurationSummary -ServiceInfo $serviceInfo -DomainInfo $domainInfo -CloudflareInfo $cloudflareInfo -FeatureInfo $featureInfo
83
+
84
+ # Confirm setup
85
+ if (-not $NonInteractive) {
86
+ $confirmation = Get-UserConfirmation "Do you want to proceed with this configuration?"
87
+ if (-not $confirmation) {
88
+ Write-Host "Setup cancelled by user." -ForegroundColor $Yellow
89
+ exit 0
90
+ }
91
+ }
92
+
93
+ # Create service structure
94
+ Write-Step "Creating service structure"
95
+ $servicePath = New-ServiceStructure -ServiceInfo $serviceInfo -OutputPath $OutputPath
96
+ Write-Success "Service structure created at: $servicePath"
97
+
98
+ # Generate configuration files
99
+ Write-Step "Generating configuration files"
100
+ New-ServiceConfiguration -ServiceInfo $serviceInfo -DomainInfo $domainInfo -CloudflareInfo $cloudflareInfo -FeatureInfo $featureInfo -ServicePath $servicePath
101
+ Write-Success "Configuration files generated"
102
+
103
+ # Initialize project
104
+ Write-Step "Initializing project"
105
+ Initialize-ServiceProject -ServicePath $servicePath -ServiceInfo $serviceInfo
106
+ Write-Success "Project initialized"
107
+
108
+ # Setup Cloudflare resources
109
+ if (-not $NonInteractive) {
110
+ $setupCloudflare = Get-UserConfirmation "Do you want to set up Cloudflare resources now?"
111
+ if ($setupCloudflare) {
112
+ Write-Step "Setting up Cloudflare resources"
113
+ $cfResult = Initialize-CloudflareResources -ServiceInfo $serviceInfo -DomainInfo $domainInfo -CloudflareInfo $cloudflareInfo
114
+ if ($cfResult.Success) {
115
+ Write-Success "Cloudflare resources configured"
116
+ } else {
117
+ Write-Warning "Cloudflare setup failed: $($cfResult.Error)"
118
+ }
119
+ }
120
+ }
121
+
122
+ # Display next steps
123
+ Show-NextSteps -ServiceInfo $serviceInfo -ServicePath $servicePath
124
+
125
+ Write-Step "Service setup completed successfully!"
126
+ Write-Host "`n[SUCCESS] Your new Clodo service is ready to go!" -ForegroundColor $Green
127
+ }
128
+
129
+ # Gather service information
130
+ function Get-ServiceInformation {
131
+ Write-Step "Service Information"
132
+
133
+ if ($ServiceName) {
134
+ $name = $ServiceName
135
+ } else {
136
+ Write-Prompt "Enter service name: "
137
+ $name = Read-Host
138
+ if (-not $name) {
139
+ Exit-WithError "Service name is required"
140
+ }
141
+ }
142
+
143
+ # Validate service name
144
+ if ($name -notmatch '^[a-z0-9-]+$') {
145
+ Exit-WithError "Service name must contain only lowercase letters, numbers, and hyphens"
146
+ }
147
+
148
+ $displayName = Get-UserInput "Display name" "$($name -replace '-', ' ' | ForEach-Object { (Get-Culture).TextInfo.ToTitleCase($_) })"
149
+ $description = Get-UserInput "Description" "A Clodo Framework service"
150
+ $version = Get-UserInput "Initial version" "1.0.0"
151
+ $author = Get-UserInput "Author" $env:USERNAME
152
+
153
+ return @{
154
+ Name = $name
155
+ DisplayName = $displayName
156
+ Description = $description
157
+ Version = $version
158
+ Author = $author
159
+ Type = $ServiceType
160
+ }
161
+ }
162
+
163
+ # Gather domain information
164
+ function Get-DomainInformation {
165
+ Write-Step "Domain Configuration"
166
+
167
+ if ($DomainName) {
168
+ $name = $DomainName
169
+ } else {
170
+ Write-Prompt "Enter domain name: "
171
+ $name = Read-Host
172
+ if (-not $name) {
173
+ Exit-WithError "Domain name is required"
174
+ }
175
+ }
176
+
177
+ $displayName = Get-UserInput "Domain display name" "$($name -replace '-', ' ' | ForEach-Object { (Get-Culture).TextInfo.ToTitleCase($_) })"
178
+
179
+ Write-Host "Domain URLs:" -ForegroundColor $White
180
+ $productionUrl = Get-UserInput "Production URL" "api.$name.com"
181
+ $stagingUrl = Get-UserInput "Staging URL" "staging-api.$name.com"
182
+ $developmentUrl = Get-UserInput "Development URL" "dev-api.$name.com"
183
+
184
+ return @{
185
+ Name = $name
186
+ DisplayName = $displayName
187
+ ProductionUrl = $productionUrl
188
+ StagingUrl = $stagingUrl
189
+ DevelopmentUrl = $developmentUrl
190
+ }
191
+ }
192
+
193
+ # Gather Cloudflare information
194
+ function Get-CloudflareInformation {
195
+ Write-Step "Cloudflare Configuration"
196
+
197
+ Write-Host "You'll need your Cloudflare account information." -ForegroundColor $White
198
+ Write-Host "You can find this in your Cloudflare dashboard under Account Settings.`n" -ForegroundColor $White
199
+
200
+ $accountId = Get-UserInput "Account ID" ""
201
+ $zoneId = Get-UserInput "Zone ID" ""
202
+
203
+ if (-not $accountId -or -not $zoneId) {
204
+ Write-Warning "Cloudflare IDs are required for deployment. You can configure them later in the generated config files."
205
+ }
206
+
207
+ return @{
208
+ AccountId = $accountId
209
+ ZoneId = $zoneId
210
+ }
211
+ }
212
+
213
+ # Get feature configuration based on service type
214
+ function Get-FeatureConfiguration {
215
+ param([string]$ServiceType)
216
+
217
+ Write-Step "Feature Configuration"
218
+
219
+ $baseFeatures = @{
220
+ logging = $true
221
+ monitoring = $true
222
+ errorReporting = $true
223
+ }
224
+
225
+ $serviceSpecificFeatures = switch ($ServiceType) {
226
+ "data-service" {
227
+ @{
228
+ authentication = $true
229
+ authorization = $true
230
+ fileStorage = $true
231
+ search = $true
232
+ filtering = $true
233
+ pagination = $true
234
+ }
235
+ }
236
+ "auth-service" {
237
+ @{
238
+ authentication = $true
239
+ authorization = $true
240
+ userProfiles = $true
241
+ emailNotifications = $true
242
+ magicLinkAuth = $true
243
+ }
244
+ }
245
+ "content-service" {
246
+ @{
247
+ fileStorage = $true
248
+ search = $true
249
+ filtering = $true
250
+ pagination = $true
251
+ caching = $true
252
+ }
253
+ }
254
+ "api-gateway" {
255
+ @{
256
+ authentication = $true
257
+ authorization = $true
258
+ rateLimiting = $true
259
+ caching = $true
260
+ monitoring = $true
261
+ }
262
+ }
263
+ default {
264
+ @{
265
+ authentication = $false
266
+ authorization = $false
267
+ }
268
+ }
269
+ }
270
+
271
+ $allFeatures = $baseFeatures + $serviceSpecificFeatures
272
+
273
+ Write-Host "Default features for $ServiceType service:" -ForegroundColor $White
274
+ foreach ($feature in $allFeatures.GetEnumerator() | Sort-Object Name) {
275
+ $status = if ($feature.Value) { "[ENABLED]" } else { "[DISABLED]" }
276
+ Write-Host " $status $($feature.Name)" -ForegroundColor $(if ($feature.Value) { $Green } else { $White })
277
+ }
278
+
279
+ Write-Host ""
280
+
281
+ if (-not $NonInteractive) {
282
+ Write-Host "You can modify these features later in the generated configuration files." -ForegroundColor $Yellow
283
+ }
284
+
285
+ return $allFeatures
286
+ }
287
+
288
+ # Display configuration summary
289
+ function Show-ConfigurationSummary {
290
+ param($ServiceInfo, $DomainInfo, $CloudflareInfo, $FeatureInfo)
291
+
292
+ Write-Step "Configuration Summary"
293
+
294
+ Write-Host "Service:" -ForegroundColor $Cyan
295
+ Write-Host " Name: $($ServiceInfo.Name)" -ForegroundColor $White
296
+ Write-Host " Display Name: $($ServiceInfo.DisplayName)" -ForegroundColor $White
297
+ Write-Host " Type: $($ServiceInfo.Type)" -ForegroundColor $White
298
+ Write-Host " Version: $($ServiceInfo.Version)" -ForegroundColor $White
299
+
300
+ Write-Host "`nDomain:" -ForegroundColor $Cyan
301
+ Write-Host " Name: $($DomainInfo.Name)" -ForegroundColor $White
302
+ Write-Host " Production: $($DomainInfo.ProductionUrl)" -ForegroundColor $White
303
+ Write-Host " Staging: $($DomainInfo.StagingUrl)" -ForegroundColor $White
304
+ Write-Host " Development: $($DomainInfo.DevelopmentUrl)" -ForegroundColor $White
305
+
306
+ Write-Host "`nCloudflare:" -ForegroundColor $Cyan
307
+ Write-Host " Account ID: $(if ($CloudflareInfo.AccountId) { $CloudflareInfo.AccountId } else { 'Not configured' })" -ForegroundColor $White
308
+ Write-Host " Zone ID: $(if ($CloudflareInfo.ZoneId) { $CloudflareInfo.ZoneId } else { 'Not configured' })" -ForegroundColor $White
309
+
310
+ Write-Host "`nEnabled Features:" -ForegroundColor $Cyan
311
+ $enabledFeatures = $FeatureInfo.GetEnumerator() | Where-Object { $_.Value } | Sort-Object Name
312
+ foreach ($feature in $enabledFeatures) {
313
+ Write-Host " [ENABLED] $($feature.Name)" -ForegroundColor $Green
314
+ }
315
+
316
+ Write-Host ""
317
+ }
318
+
319
+ # Create service directory structure
320
+ function New-ServiceStructure {
321
+ param($ServiceInfo, [string]$OutputPath)
322
+
323
+ $servicePath = Join-Path $OutputPath $ServiceInfo.Name
324
+
325
+ if (Test-Path $servicePath) {
326
+ if (-not $NonInteractive) {
327
+ $overwrite = Get-UserConfirmation "Service directory already exists. Overwrite?"
328
+ if (-not $overwrite) {
329
+ Exit-WithError "Service directory already exists"
330
+ }
331
+ Remove-Item $servicePath -Recurse -Force
332
+ } else {
333
+ Exit-WithError "Service directory already exists: $servicePath"
334
+ }
335
+ }
336
+
337
+ # Create directory structure
338
+ $directories = @(
339
+ $servicePath,
340
+ (Join-Path $servicePath "src"),
341
+ (Join-Path $servicePath "src\config"),
342
+ (Join-Path $servicePath "src\worker"),
343
+ (Join-Path $servicePath "src\routes"),
344
+ (Join-Path $servicePath "src\services"),
345
+ (Join-Path $servicePath "scripts"),
346
+ (Join-Path $servicePath "tests"),
347
+ (Join-Path $servicePath "migrations"),
348
+ (Join-Path $servicePath "docs")
349
+ )
350
+
351
+ foreach ($dir in $directories) {
352
+ New-Item -ItemType Directory -Path $dir -Force | Out-Null
353
+ }
354
+
355
+ return $servicePath
356
+ }
357
+
358
+ # Generate configuration files
359
+ function New-ServiceConfiguration {
360
+ param($ServiceInfo, $DomainInfo, $CloudflareInfo, $FeatureInfo, [string]$ServicePath)
361
+
362
+ # Generate package.json
363
+ $packageJson = @{
364
+ name = $ServiceInfo.Name
365
+ version = $ServiceInfo.Version
366
+ description = $ServiceInfo.Description
367
+ main = "src/worker/index.js"
368
+ type = "module"
369
+ scripts = @{
370
+ test = "jest"
371
+ deploy = "powershell .\scripts\deploy.ps1"
372
+ setup = "powershell .\scripts\setup.ps1"
373
+ }
374
+ dependencies = @{
375
+ "@tamyla/clodo-framework" = "^1.0.0"
376
+ "wrangler" = "^3.0.0"
377
+ }
378
+ devDependencies = @{
379
+ "jest" = "^29.7.0"
380
+ "@babel/core" = "^7.23.0"
381
+ "@babel/preset-env" = "^7.23.0"
382
+ }
383
+ author = $ServiceInfo.Author
384
+ license = "MIT"
385
+ }
386
+
387
+ $packageJson | ConvertTo-Json -Depth 10 | Out-File (Join-Path $ServicePath "package.json") -Encoding UTF8
388
+
389
+ # Generate domain configuration
390
+ $featureString = ($FeatureInfo.GetEnumerator() | Where-Object { $_.Value } | ForEach-Object { " $($_.Name): true," }) -join "`n"
391
+ $domainConfig = @"
392
+ import { createDomainConfigSchema } from '@tamyla/clodo-framework';
393
+
394
+ export const domains = {
395
+ '$($DomainInfo.Name)': {
396
+ ...createDomainConfigSchema(),
397
+ name: '$($DomainInfo.Name)',
398
+ displayName: '$($DomainInfo.DisplayName)',
399
+ accountId: '$($CloudflareInfo.AccountId)',
400
+ zoneId: '$($CloudflareInfo.ZoneId)',
401
+ domains: {
402
+ production: '$($DomainInfo.ProductionUrl)',
403
+ staging: '$($DomainInfo.StagingUrl)',
404
+ development: '$($DomainInfo.DevelopmentUrl)'
405
+ },
406
+ features: {
407
+ $($featureString)
408
+ }
409
+ }
410
+ };
411
+ "@
412
+
413
+ $domainConfig | Out-File (Join-Path $ServicePath "src\config\domains.js") -Encoding UTF8
414
+
415
+ # Generate wrangler.toml
416
+ $wranglerConfig = @"
417
+ name = "$($ServiceInfo.Name)-staging"
418
+ main = "src/worker/index.js"
419
+ compatibility_date = $(Get-Date -Format "yyyy-MM-dd")
420
+
421
+ [env.staging]
422
+ name = "$($ServiceInfo.Name)-staging"
423
+
424
+ [env.production]
425
+ name = "$($ServiceInfo.Name)-production"
426
+
427
+ # Database bindings will be added during deployment
428
+ # [[d1_databases]]
429
+ # binding = "$($ServiceInfo.Name)-db"
430
+ # database_name = "$($ServiceInfo.Name)-db"
431
+ "@
432
+
433
+ $wranglerConfig | Out-File (Join-Path $ServicePath "wrangler.toml") -Encoding UTF8
434
+
435
+ # Generate main worker file
436
+ $workerCode = @"
437
+ import { initializeService, createFeatureGuard, COMMON_FEATURES } from '@tamyla/clodo-framework';
438
+ import { domains } from './config/domains.js';
439
+
440
+ export default {
441
+ async fetch(request, env, ctx) {
442
+ try {
443
+ // Initialize service with Clodo Framework
444
+ const service = initializeService(env, domains);
445
+
446
+ // Route handling based on service type: $($ServiceInfo.Type)
447
+ const url = new URL(request.url);
448
+
449
+ // Health check endpoint
450
+ if (url.pathname === '/health') {
451
+ return new Response(JSON.stringify({
452
+ status: 'healthy',
453
+ service: '$($ServiceInfo.Name)',
454
+ version: '$($ServiceInfo.Version)',
455
+ features: service.features
456
+ }), {
457
+ headers: { 'Content-Type': 'application/json' }
458
+ });
459
+ }
460
+
461
+ // Add your service-specific routes here
462
+ // Example:
463
+ // if (url.pathname.startsWith('/api/')) {
464
+ // return handleApiRequest(request, env, ctx);
465
+ // }
466
+
467
+ return new Response('Clodo Service: $($ServiceInfo.DisplayName)', {
468
+ headers: { 'Content-Type': 'text/plain' }
469
+ });
470
+
471
+ } catch (error) {
472
+ console.error('Service error:', error);
473
+ return new Response(JSON.stringify({
474
+ error: 'Internal Server Error',
475
+ message: error.message
476
+ }), {
477
+ status: 500,
478
+ headers: { 'Content-Type': 'application/json' }
479
+ });
480
+ }
481
+ }
482
+ };
483
+ "@
484
+
485
+ $workerCode | Out-File (Join-Path $ServicePath "src\worker\index.js") -Encoding UTF8
486
+
487
+ # Generate README.md
488
+ $featureList = ($FeatureInfo.GetEnumerator() | Where-Object { $_.Value } | ForEach-Object { "- $($_.Name)" }) -join "`n"
489
+ $readme = @"
490
+ # $($ServiceInfo.DisplayName)
491
+
492
+ $($ServiceInfo.Description)
493
+
494
+ ## Features
495
+
496
+ $featureList
497
+
498
+ ## Setup
499
+
500
+ 1. Install dependencies:
501
+ ```bash
502
+
503
+ ## Setup
504
+
505
+ 1. Install dependencies:
506
+ ```bash
507
+ npm install
508
+ ```
509
+
510
+ 2. Configure your domain settings in `src/config/domains.js`
511
+
512
+ 3. Deploy to Cloudflare:
513
+ ```bash
514
+ npm run deploy
515
+ ```
516
+
517
+ ## Development
518
+
519
+ - Start development server: `npm run dev`
520
+ - Run tests: `npm test`
521
+ - Deploy to staging: `npm run deploy -- --Environment staging`
522
+ - Deploy to production: `npm run deploy -- --Environment production`
523
+
524
+ ## Clodo Framework
525
+
526
+ This service is built using the Clodo Framework, which provides:
527
+ - Domain configuration management
528
+ - Feature flag system
529
+ - Deployment automation
530
+ - Consistent service patterns
531
+
532
+ Learn more: [Clodo Framework Documentation](../packages/clodo-framework/README.md)
533
+ "@
534
+
535
+ $readme | Out-File (Join-Path $ServicePath "README.md") -Encoding UTF8
536
+ }
537
+
538
+ # Initialize project
539
+ function Initialize-ServiceProject {
540
+ param([string]$ServicePath, $ServiceInfo)
541
+
542
+ Push-Location $ServicePath
543
+
544
+ try {
545
+ # Initialize git repository
546
+ if (-not (Test-Path ".git")) {
547
+ & git init 2>$null | Out-Null
548
+ Write-Success "Git repository initialized"
549
+ }
550
+
551
+ # Create .gitignore
552
+ $gitignore = @"
553
+ node_modules/
554
+ .env
555
+ .env.local
556
+ .wrangler/
557
+ logs/
558
+ *.log
559
+ coverage/
560
+ .nyc_output/
561
+ "@
562
+
563
+ $gitignore | Out-File ".gitignore" -Encoding UTF8
564
+
565
+ # Create initial .env.example
566
+ $envExample = @"
567
+ # Clodo Framework Environment Variables
568
+ DOMAIN_NAME=$($ServiceInfo.Name)
569
+ ENVIRONMENT=development
570
+
571
+ # Cloudflare Account (configure in src/config/domains.js)
572
+ # CLOUDFLARE_ACCOUNT_ID=your-account-id
573
+ # CLOUDFLARE_ZONE_ID=your-zone-id
574
+
575
+ # Service-specific environment variables
576
+ "@
577
+
578
+ $envExample | Out-File ".env.example" -Encoding UTF8
579
+
580
+ } finally {
581
+ Pop-Location
582
+ }
583
+ }
584
+
585
+ # Setup Cloudflare resources
586
+ function Initialize-CloudflareResources {
587
+ param($ServiceInfo, $DomainInfo, $CloudflareInfo)
588
+
589
+ if (-not $CloudflareInfo.AccountId -or -not $CloudflareInfo.ZoneId) {
590
+ return @{ Success = $false; Error = "Cloudflare credentials not configured" }
591
+ }
592
+
593
+ try {
594
+ # Test Cloudflare authentication
595
+ if (-not (Test-CloudflareAuth)) {
596
+ throw "Cloudflare authentication failed"
597
+ }
598
+
599
+ # Create D1 database
600
+ $dbResult = New-D1Database -DatabaseName "$($ServiceInfo.Name)-db"
601
+ if (-not $dbResult.Success) {
602
+ throw "Failed to create database: $($dbResult.Error)"
603
+ }
604
+
605
+ return @{
606
+ Success = $true
607
+ DatabaseId = $dbResult.DatabaseId
608
+ }
609
+ } catch {
610
+ return @{
611
+ Success = $false
612
+ Error = $_.Exception.Message
613
+ }
614
+ }
615
+ }
616
+
617
+ # Display next steps
618
+ function Show-NextSteps {
619
+ param($ServiceInfo, [string]$ServicePath)
620
+
621
+ Write-Step "Next Steps"
622
+
623
+ Write-Host "Your service has been created! Here's what to do next:" -ForegroundColor $Cyan
624
+ Write-Host ""
625
+
626
+ Write-Host "1. Navigate to your service:" -ForegroundColor $White
627
+ Write-Host " cd $ServicePath" -ForegroundColor $Yellow
628
+ Write-Host ""
629
+
630
+ Write-Host "2. Install dependencies:" -ForegroundColor $White
631
+ Write-Host " npm install" -ForegroundColor $Yellow
632
+ Write-Host ""
633
+
634
+ Write-Host "3. Configure your domain settings:" -ForegroundColor $White
635
+ Write-Host " Edit src/config/domains.js" -ForegroundColor $Yellow
636
+ Write-Host ""
637
+
638
+ Write-Host "4. Implement your service logic:" -ForegroundColor $White
639
+ Write-Host " Edit src/worker/index.js" -ForegroundColor $Yellow
640
+ Write-Host ""
641
+
642
+ Write-Host "5. Test your service:" -ForegroundColor $White
643
+ Write-Host " npm test" -ForegroundColor $Yellow
644
+ Write-Host ""
645
+
646
+ Write-Host "6. Deploy to staging:" -ForegroundColor $White
647
+ Write-Host " npm run deploy -- --Environment staging" -ForegroundColor $Yellow
648
+ Write-Host ""
649
+
650
+ Write-Host "7. Deploy to production:" -ForegroundColor $White
651
+ Write-Host " npm run deploy -- --Environment production" -ForegroundColor $Yellow
652
+ Write-Host ""
653
+ }
654
+
655
+ # Helper functions
656
+ function Get-UserInput {
657
+ param([string]$Prompt, [string]$DefaultValue = "")
658
+
659
+ if ($NonInteractive) {
660
+ return $DefaultValue
661
+ }
662
+
663
+ $promptText = $Prompt
664
+ if ($DefaultValue) {
665
+ $promptText += " (default: $DefaultValue)"
666
+ }
667
+ $promptText += ": "
668
+
669
+ Write-Prompt $promptText
670
+ $userInput = Read-Host
671
+
672
+ return if ($userInput) { $userInput } else { $DefaultValue }
673
+ }
674
+
675
+ function Get-UserConfirmation {
676
+ param([string]$Prompt)
677
+
678
+ if ($NonInteractive) {
679
+ return $true
680
+ }
681
+
682
+ Write-Prompt "$Prompt (y/N): "
683
+ $response = Read-Host
684
+
685
+ return $response -eq 'y' -or $response -eq 'Y'
686
+ }
687
+
688
+ # Run main setup
689
+ try {
690
+ Invoke-InteractiveSetup
691
+ } catch {
692
+ Exit-WithError "Setup failed: $_"
693
+ }