@tamyla/clodo-framework 1.0.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.
- package/CHANGELOG.md +564 -0
- package/LICENSE +21 -0
- package/README.md +1393 -0
- package/bin/README.md +71 -0
- package/bin/clodo-service.js +416 -0
- package/bin/security/security-cli.js +96 -0
- package/bin/service-management/README.md +74 -0
- package/bin/service-management/create-service.js +129 -0
- package/bin/service-management/init-service.js +102 -0
- package/bin/service-management/init-service.js.backup +889 -0
- package/bin/shared/config/customer-cli.js +293 -0
- package/dist/config/ConfigurationManager.js +159 -0
- package/dist/config/CustomerConfigCLI.js +220 -0
- package/dist/config/FeatureManager.js +426 -0
- package/dist/config/customers.js +441 -0
- package/dist/config/domains.js +180 -0
- package/dist/config/features.js +225 -0
- package/dist/config/index.js +6 -0
- package/dist/database/database-orchestrator.js +730 -0
- package/dist/database/index.js +4 -0
- package/dist/deployment/auditor.js +971 -0
- package/dist/deployment/index.js +10 -0
- package/dist/deployment/rollback-manager.js +523 -0
- package/dist/deployment/testers/api-tester.js +80 -0
- package/dist/deployment/testers/auth-tester.js +129 -0
- package/dist/deployment/testers/core.js +217 -0
- package/dist/deployment/testers/database-tester.js +105 -0
- package/dist/deployment/testers/index.js +74 -0
- package/dist/deployment/testers/load-tester.js +120 -0
- package/dist/deployment/testers/performance-tester.js +105 -0
- package/dist/deployment/validator.js +558 -0
- package/dist/deployment/wrangler-deployer.js +574 -0
- package/dist/handlers/GenericRouteHandler.js +532 -0
- package/dist/index.js +39 -0
- package/dist/migration/MigrationAdapters.js +562 -0
- package/dist/modules/ModuleManager.js +668 -0
- package/dist/modules/security.js +98 -0
- package/dist/orchestration/cross-domain-coordinator.js +1083 -0
- package/dist/orchestration/index.js +5 -0
- package/dist/orchestration/modules/DeploymentCoordinator.js +258 -0
- package/dist/orchestration/modules/DomainResolver.js +196 -0
- package/dist/orchestration/modules/StateManager.js +332 -0
- package/dist/orchestration/multi-domain-orchestrator.js +255 -0
- package/dist/routing/EnhancedRouter.js +158 -0
- package/dist/schema/SchemaManager.js +778 -0
- package/dist/security/ConfigurationValidator.js +490 -0
- package/dist/security/DeploymentManager.js +208 -0
- package/dist/security/SecretGenerator.js +142 -0
- package/dist/security/SecurityCLI.js +228 -0
- package/dist/security/index.js +51 -0
- package/dist/security/patterns/environment-rules.js +66 -0
- package/dist/security/patterns/insecure-patterns.js +21 -0
- package/dist/service-management/ConfirmationEngine.js +411 -0
- package/dist/service-management/ErrorTracker.js +294 -0
- package/dist/service-management/GenerationEngine.js +3109 -0
- package/dist/service-management/InputCollector.js +237 -0
- package/dist/service-management/ServiceCreator.js +229 -0
- package/dist/service-management/ServiceInitializer.js +448 -0
- package/dist/service-management/ServiceOrchestrator.js +638 -0
- package/dist/service-management/handlers/ConfigMutator.js +130 -0
- package/dist/service-management/handlers/ConfirmationHandler.js +71 -0
- package/dist/service-management/handlers/GenerationHandler.js +80 -0
- package/dist/service-management/handlers/InputHandler.js +59 -0
- package/dist/service-management/handlers/ValidationHandler.js +203 -0
- package/dist/service-management/index.js +7 -0
- package/dist/services/GenericDataService.js +488 -0
- package/dist/shared/cloudflare/domain-discovery.js +562 -0
- package/dist/shared/cloudflare/domain-manager.js +912 -0
- package/dist/shared/cloudflare/index.js +8 -0
- package/dist/shared/cloudflare/ops.js +387 -0
- package/dist/shared/config/cache.js +1167 -0
- package/dist/shared/config/command-config-manager.js +174 -0
- package/dist/shared/config/customer-cli.js +258 -0
- package/dist/shared/config/index.js +9 -0
- package/dist/shared/config/manager.js +289 -0
- package/dist/shared/database/connection-manager.js +338 -0
- package/dist/shared/database/index.js +7 -0
- package/dist/shared/database/orchestrator.js +632 -0
- package/dist/shared/deployment/auditor.js +971 -0
- package/dist/shared/deployment/index.js +10 -0
- package/dist/shared/deployment/rollback-manager.js +523 -0
- package/dist/shared/deployment/validator.js +558 -0
- package/dist/shared/index.js +32 -0
- package/dist/shared/monitoring/health-checker.js +250 -0
- package/dist/shared/monitoring/index.js +8 -0
- package/dist/shared/monitoring/memory-manager.js +382 -0
- package/dist/shared/monitoring/production-monitor.js +390 -0
- package/dist/shared/production-tester/api-tester.js +80 -0
- package/dist/shared/production-tester/auth-tester.js +129 -0
- package/dist/shared/production-tester/core.js +217 -0
- package/dist/shared/production-tester/database-tester.js +105 -0
- package/dist/shared/production-tester/index.js +74 -0
- package/dist/shared/production-tester/load-tester.js +120 -0
- package/dist/shared/production-tester/performance-tester.js +105 -0
- package/dist/shared/security/api-token-manager.js +296 -0
- package/dist/shared/security/index.js +8 -0
- package/dist/shared/security/secret-generator.js +918 -0
- package/dist/shared/security/secure-token-manager.js +379 -0
- package/dist/shared/utils/error-recovery.js +240 -0
- package/dist/shared/utils/graceful-shutdown-manager.js +380 -0
- package/dist/shared/utils/index.js +9 -0
- package/dist/shared/utils/interactive-prompts.js +134 -0
- package/dist/shared/utils/rate-limiter.js +249 -0
- package/dist/utils/ErrorHandler.js +173 -0
- package/dist/utils/deployment/config-cache.js +1160 -0
- package/dist/utils/deployment/index.js +6 -0
- package/dist/utils/deployment/interactive-prompts.js +97 -0
- package/dist/utils/deployment/secret-generator.js +896 -0
- package/dist/utils/dirname-helper.js +35 -0
- package/dist/utils/domain-config.js +159 -0
- package/dist/utils/error-recovery.js +240 -0
- package/dist/utils/esm-helper.js +52 -0
- package/dist/utils/framework-config.js +481 -0
- package/dist/utils/graceful-shutdown-manager.js +379 -0
- package/dist/utils/health-checker.js +114 -0
- package/dist/utils/index.js +36 -0
- package/dist/utils/prompt-handler.js +98 -0
- package/dist/utils/usage-tracker.js +252 -0
- package/dist/utils/validation.js +112 -0
- package/dist/version/VersionDetector.js +723 -0
- package/dist/worker/index.js +4 -0
- package/dist/worker/integration.js +332 -0
- package/docs/FRAMEWORK-ARCHITECTURE-OVERVIEW.md +206 -0
- package/docs/INTEGRATION_GUIDE.md +2045 -0
- package/docs/README.md +82 -0
- package/docs/SECURITY.md +242 -0
- package/docs/deployment/deployment-guide.md +540 -0
- package/docs/overview.md +280 -0
- package/package.json +176 -0
- package/types/index.d.ts +575 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clodo Framework - Service Initializer
|
|
3
|
+
* Programmatic API for initializing services with configurations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, readdirSync } from 'fs';
|
|
7
|
+
import { join, dirname, resolve } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
const FRAMEWORK_ROOT = resolve(__dirname, '..', '..');
|
|
12
|
+
const TEMPLATES_DIR = join(FRAMEWORK_ROOT, 'templates');
|
|
13
|
+
const SERVICE_TYPES = ['generic', 'data-service', 'auth-service', 'content-service', 'api-gateway'];
|
|
14
|
+
export class ServiceInitializer {
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.frameworkRoot = options.frameworkRoot || FRAMEWORK_ROOT;
|
|
17
|
+
this.templatesDir = options.templatesDir || TEMPLATES_DIR;
|
|
18
|
+
this.serviceTypes = options.serviceTypes || SERVICE_TYPES;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Validate service name according to framework conventions
|
|
23
|
+
* @param {string} name - Service name to validate
|
|
24
|
+
* @throws {Error} If validation fails
|
|
25
|
+
*/
|
|
26
|
+
validateServiceName(name) {
|
|
27
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
28
|
+
throw new Error('Service name must contain only lowercase letters, numbers, and hyphens');
|
|
29
|
+
}
|
|
30
|
+
if (name.length < 3 || name.length > 50) {
|
|
31
|
+
throw new Error('Service name must be between 3 and 50 characters');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Validate service type
|
|
37
|
+
* @param {string} type - Service type to validate
|
|
38
|
+
* @throws {Error} If type is invalid
|
|
39
|
+
*/
|
|
40
|
+
validateServiceType(type) {
|
|
41
|
+
if (!this.serviceTypes.includes(type)) {
|
|
42
|
+
throw new Error(`Invalid service type. Must be one of: ${this.serviceTypes.join(', ')}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Initialize a service with auto-generated configurations
|
|
48
|
+
* @param {string} serviceName - Name of the service to initialize
|
|
49
|
+
* @param {Object} options - Initialization options
|
|
50
|
+
* @param {string} options.type - Service type (default: 'generic')
|
|
51
|
+
* @param {string} options.domains - Comma-separated list of domains
|
|
52
|
+
* @param {string} options.env - Target environment (default: 'development')
|
|
53
|
+
* @param {string} options.apiToken - Cloudflare API token
|
|
54
|
+
* @param {string} options.accountId - Cloudflare account ID
|
|
55
|
+
* @param {string} options.zoneId - Cloudflare zone ID
|
|
56
|
+
* @param {string} options.output - Output directory (default: current directory)
|
|
57
|
+
* @param {boolean} options.force - Overwrite existing directory (default: false)
|
|
58
|
+
* @param {boolean} options.dryRun - Show what would be created without creating files (default: false)
|
|
59
|
+
* @returns {Object} Initialization result
|
|
60
|
+
*/
|
|
61
|
+
async initializeService(serviceName, options = {}) {
|
|
62
|
+
const config = {
|
|
63
|
+
type: 'generic',
|
|
64
|
+
domains: '',
|
|
65
|
+
env: 'development',
|
|
66
|
+
output: process.cwd(),
|
|
67
|
+
force: false,
|
|
68
|
+
dryRun: false,
|
|
69
|
+
...options
|
|
70
|
+
};
|
|
71
|
+
try {
|
|
72
|
+
// Validate inputs
|
|
73
|
+
this.validateServiceName(serviceName);
|
|
74
|
+
this.validateServiceType(config.type);
|
|
75
|
+
|
|
76
|
+
// Parse domain information
|
|
77
|
+
const domainInfo = this.parseDomainInfo(config, serviceName);
|
|
78
|
+
|
|
79
|
+
// Generate configurations
|
|
80
|
+
const configs = this.generateConfigurations(serviceName, config, domainInfo);
|
|
81
|
+
if (config.dryRun) {
|
|
82
|
+
return {
|
|
83
|
+
success: true,
|
|
84
|
+
dryRun: true,
|
|
85
|
+
serviceName,
|
|
86
|
+
configs
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Create service structure
|
|
91
|
+
this.createServiceStructure(serviceName, config, configs);
|
|
92
|
+
return {
|
|
93
|
+
success: true,
|
|
94
|
+
serviceName,
|
|
95
|
+
serviceType: config.type,
|
|
96
|
+
serviceDir: join(config.output, 'services', serviceName),
|
|
97
|
+
configs: Object.keys(configs),
|
|
98
|
+
domainInfo
|
|
99
|
+
};
|
|
100
|
+
} catch (error) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
serviceName,
|
|
104
|
+
error: error.message
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Parse domain information from options
|
|
111
|
+
* @param {Object} config - Configuration options
|
|
112
|
+
* @param {string} serviceName - Service name
|
|
113
|
+
* @returns {Object} Domain information
|
|
114
|
+
*/
|
|
115
|
+
parseDomainInfo(config, serviceName) {
|
|
116
|
+
const domainInfo = {
|
|
117
|
+
domains: [],
|
|
118
|
+
defaultAccountId: config.accountId || process.env.CLOUDFLARE_ACCOUNT_ID,
|
|
119
|
+
defaultZoneId: config.zoneId || process.env.CLOUDFLARE_ZONE_ID,
|
|
120
|
+
apiToken: config.apiToken || process.env.CLOUDFLARE_API_TOKEN
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Parse domains from command line - support format: domain[:accountId[:zoneId]]
|
|
124
|
+
if (config.domains) {
|
|
125
|
+
const domainSpecs = config.domains.split(',').map(d => d.trim());
|
|
126
|
+
domainInfo.domains = domainSpecs.map(spec => {
|
|
127
|
+
const parts = spec.split(':');
|
|
128
|
+
return {
|
|
129
|
+
domain: parts[0],
|
|
130
|
+
accountId: parts[1] || domainInfo.defaultAccountId,
|
|
131
|
+
zoneId: parts[2] || domainInfo.defaultZoneId,
|
|
132
|
+
name: `${serviceName}-${parts[0].replace(/[^a-zA-Z0-9]/g, '-')}`
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// If no domains specified, create a default one
|
|
138
|
+
if (domainInfo.domains.length === 0) {
|
|
139
|
+
domainInfo.domains.push({
|
|
140
|
+
domain: `${serviceName}.example.com`,
|
|
141
|
+
accountId: domainInfo.defaultAccountId,
|
|
142
|
+
zoneId: domainInfo.defaultZoneId,
|
|
143
|
+
name: `${serviceName}-default`
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return domainInfo;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Generate all configurations for the service
|
|
151
|
+
* @param {string} serviceName - Service name
|
|
152
|
+
* @param {Object} config - Configuration options
|
|
153
|
+
* @param {Object} domainInfo - Domain information
|
|
154
|
+
* @returns {Object} Generated configurations
|
|
155
|
+
*/
|
|
156
|
+
generateConfigurations(serviceName, config, domainInfo) {
|
|
157
|
+
const configs = {};
|
|
158
|
+
|
|
159
|
+
// Generate wrangler.toml
|
|
160
|
+
Object.assign(configs, this.generateWranglerConfig(serviceName, config, domainInfo));
|
|
161
|
+
|
|
162
|
+
// Generate domains.js
|
|
163
|
+
configs['src/config/domains.js'] = this.generateDomainsConfig(serviceName, config, domainInfo);
|
|
164
|
+
|
|
165
|
+
// Generate package.json
|
|
166
|
+
configs['package.json'] = this.generatePackageJson(serviceName, config);
|
|
167
|
+
|
|
168
|
+
// Generate README.md
|
|
169
|
+
configs['README.md'] = this.generateReadme(serviceName, config, domainInfo);
|
|
170
|
+
return configs;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Generate Wrangler configuration
|
|
175
|
+
* @param {string} serviceName - Service name
|
|
176
|
+
* @param {Object} config - Configuration options
|
|
177
|
+
* @param {Object} domainInfo - Domain information
|
|
178
|
+
* @returns {Object} Wrangler configurations
|
|
179
|
+
*/
|
|
180
|
+
generateWranglerConfig(serviceName, config, domainInfo) {
|
|
181
|
+
const env = config.env;
|
|
182
|
+
|
|
183
|
+
// For multiple domains, generate separate wrangler files
|
|
184
|
+
if (domainInfo.domains.length > 1) {
|
|
185
|
+
const wranglerConfigs = {};
|
|
186
|
+
domainInfo.domains.forEach(domainConfig => {
|
|
187
|
+
const configName = `wrangler.${domainConfig.name}.toml`;
|
|
188
|
+
wranglerConfigs[configName] = this.generateSingleWranglerConfig(domainConfig.name, env, config, domainConfig, serviceName);
|
|
189
|
+
});
|
|
190
|
+
return wranglerConfigs;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// For single domain, generate single wrangler.toml
|
|
194
|
+
return {
|
|
195
|
+
'wrangler.toml': this.generateSingleWranglerConfig(`${serviceName}-${env}`, env, config, domainInfo.domains[0], serviceName)
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Generate single Wrangler configuration
|
|
201
|
+
* @param {string} name - Configuration name
|
|
202
|
+
* @param {string} env - Environment
|
|
203
|
+
* @param {Object} config - Configuration options
|
|
204
|
+
* @param {Object} domainConfig - Domain configuration
|
|
205
|
+
* @param {string} serviceName - Service name
|
|
206
|
+
* @returns {string} Wrangler TOML content
|
|
207
|
+
*/
|
|
208
|
+
generateSingleWranglerConfig(name, env, config, domainConfig, serviceName) {
|
|
209
|
+
const isProduction = env === 'production';
|
|
210
|
+
let wranglerConfig = `name = "${name}"
|
|
211
|
+
main = "src/worker/index.js"
|
|
212
|
+
compatibility_date = "${new Date().toISOString().split('T')[0]}"
|
|
213
|
+
|
|
214
|
+
`;
|
|
215
|
+
if (!isProduction) {
|
|
216
|
+
wranglerConfig += `[env.${env}]
|
|
217
|
+
name = "${name}"
|
|
218
|
+
|
|
219
|
+
`;
|
|
220
|
+
}
|
|
221
|
+
wranglerConfig += `[env.production]
|
|
222
|
+
name = "${name.replace(`-${env}`, '')}-production"
|
|
223
|
+
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
// Add D1 databases for data services
|
|
227
|
+
if (config.type === 'data-service') {
|
|
228
|
+
wranglerConfig += `# Database bindings
|
|
229
|
+
[[d1_databases]]
|
|
230
|
+
binding = "${name.toUpperCase().replace(/[^A-Z0-9]/g, '_')}_DB"
|
|
231
|
+
database_name = "${name}-db"
|
|
232
|
+
|
|
233
|
+
`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Environment variables
|
|
237
|
+
wranglerConfig += `# Environment variables
|
|
238
|
+
[vars]
|
|
239
|
+
DOMAIN_NAME = "${domainConfig.domain}"
|
|
240
|
+
ENVIRONMENT = "${env}"
|
|
241
|
+
SERVICE_NAME = "${serviceName}"
|
|
242
|
+
SERVICE_TYPE = "${config.type}"
|
|
243
|
+
DOMAIN_CONFIG = "${domainConfig.name}"
|
|
244
|
+
|
|
245
|
+
`;
|
|
246
|
+
|
|
247
|
+
// Add service-specific environment variables
|
|
248
|
+
if (config.type === 'auth-service') {
|
|
249
|
+
wranglerConfig += `JWT_SECRET = "change-in-production"
|
|
250
|
+
AUTH_PROVIDERS = "google,github"
|
|
251
|
+
`;
|
|
252
|
+
} else if (config.type === 'api-gateway') {
|
|
253
|
+
wranglerConfig += `RATE_LIMIT_REQUESTS = "100"
|
|
254
|
+
RATE_LIMIT_WINDOW_MS = "60000"
|
|
255
|
+
ENABLE_CORS = "true"
|
|
256
|
+
`;
|
|
257
|
+
}
|
|
258
|
+
return wranglerConfig;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Generate domains configuration
|
|
263
|
+
* @param {string} serviceName - Service name
|
|
264
|
+
* @param {Object} config - Configuration options
|
|
265
|
+
* @param {Object} domainInfo - Domain information
|
|
266
|
+
* @returns {string} Domains configuration content
|
|
267
|
+
*/
|
|
268
|
+
generateDomainsConfig(serviceName, config, domainInfo) {
|
|
269
|
+
let domainsConfig = `import { createDomainConfigSchema } from '@tamyla/clodo-framework';
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Domain configurations for ${serviceName}
|
|
273
|
+
*
|
|
274
|
+
* Auto-generated by Clodo Framework Service Initializer
|
|
275
|
+
* Generated on: ${new Date().toISOString()}
|
|
276
|
+
*
|
|
277
|
+
* This service supports multiple domains with domain-specific configurations
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
export const domains = [
|
|
281
|
+
`;
|
|
282
|
+
domainInfo.domains.forEach((domain, index) => {
|
|
283
|
+
domainsConfig += ` {
|
|
284
|
+
name: '${domain.name}',
|
|
285
|
+
domain: '${domain.domain}',
|
|
286
|
+
accountId: '${domain.accountId || 'your-account-id'}',
|
|
287
|
+
zoneId: '${domain.zoneId || 'your-zone-id'}',
|
|
288
|
+
environment: '${config.env}',
|
|
289
|
+
ssl: true,
|
|
290
|
+
cors: ${config.type === 'api-gateway' ? 'true' : 'false'}
|
|
291
|
+
}`;
|
|
292
|
+
if (index < domainInfo.domains.length - 1) {
|
|
293
|
+
domainsConfig += ',';
|
|
294
|
+
}
|
|
295
|
+
domainsConfig += '\n';
|
|
296
|
+
});
|
|
297
|
+
domainsConfig += `];
|
|
298
|
+
|
|
299
|
+
export const domainConfigSchema = createDomainConfigSchema();
|
|
300
|
+
`;
|
|
301
|
+
return domainsConfig;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Generate package.json for the service
|
|
306
|
+
* @param {string} serviceName - Service name
|
|
307
|
+
* @param {Object} config - Configuration options
|
|
308
|
+
* @returns {string} Package.json content
|
|
309
|
+
*/
|
|
310
|
+
generatePackageJson(serviceName, config) {
|
|
311
|
+
const packageJson = {
|
|
312
|
+
name: serviceName,
|
|
313
|
+
version: '1.0.0',
|
|
314
|
+
description: `${config.type} service created with Clodo Framework`,
|
|
315
|
+
type: 'module',
|
|
316
|
+
main: 'dist/index.js',
|
|
317
|
+
scripts: {
|
|
318
|
+
build: 'babel src --out-dir dist --copy-files',
|
|
319
|
+
dev: 'wrangler dev',
|
|
320
|
+
deploy: 'wrangler deploy',
|
|
321
|
+
test: 'jest',
|
|
322
|
+
setup: 'node setup.js'
|
|
323
|
+
},
|
|
324
|
+
dependencies: {
|
|
325
|
+
'@tamyla/clodo-framework': '^3.0.5'
|
|
326
|
+
},
|
|
327
|
+
devDependencies: {
|
|
328
|
+
'@babel/cli': '^7.0.0',
|
|
329
|
+
'@babel/core': '^7.0.0',
|
|
330
|
+
'@babel/preset-env': '^7.0.0',
|
|
331
|
+
'jest': '^29.0.0',
|
|
332
|
+
'wrangler': '^3.0.0'
|
|
333
|
+
},
|
|
334
|
+
keywords: ['cloudflare', 'workers', 'clodo-framework', config.type],
|
|
335
|
+
author: 'Generated by Clodo Framework',
|
|
336
|
+
license: 'MIT'
|
|
337
|
+
};
|
|
338
|
+
return JSON.stringify(packageJson, null, 2);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Generate README for the service
|
|
343
|
+
* @param {string} serviceName - Service name
|
|
344
|
+
* @param {Object} config - Configuration options
|
|
345
|
+
* @param {Object} domainInfo - Domain information
|
|
346
|
+
* @returns {string} README content
|
|
347
|
+
*/
|
|
348
|
+
generateReadme(serviceName, config, domainInfo) {
|
|
349
|
+
return `# ${serviceName}
|
|
350
|
+
|
|
351
|
+
${config.type} service created with Clodo Framework.
|
|
352
|
+
|
|
353
|
+
## Setup
|
|
354
|
+
|
|
355
|
+
\`\`\`bash
|
|
356
|
+
npm install
|
|
357
|
+
npm run setup
|
|
358
|
+
\`\`\`
|
|
359
|
+
|
|
360
|
+
## Development
|
|
361
|
+
|
|
362
|
+
\`\`\`bash
|
|
363
|
+
npm run dev
|
|
364
|
+
\`\`\`
|
|
365
|
+
|
|
366
|
+
## Deployment
|
|
367
|
+
|
|
368
|
+
\`\`\`bash
|
|
369
|
+
npm run deploy
|
|
370
|
+
\`\`\`
|
|
371
|
+
|
|
372
|
+
## Domains
|
|
373
|
+
|
|
374
|
+
${domainInfo.domains.map(d => `- ${d.domain}`).join('\n')}
|
|
375
|
+
|
|
376
|
+
## Environment
|
|
377
|
+
|
|
378
|
+
- **Environment**: ${config.env}
|
|
379
|
+
- **Type**: ${config.type}
|
|
380
|
+
- **Generated**: ${new Date().toISOString()}
|
|
381
|
+
`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Create the service directory structure and write configurations
|
|
386
|
+
* @param {string} serviceName - Service name
|
|
387
|
+
* @param {Object} config - Configuration options
|
|
388
|
+
* @param {Object} configs - Generated configurations
|
|
389
|
+
*/
|
|
390
|
+
createServiceStructure(serviceName, config, configs) {
|
|
391
|
+
const servicesDir = join(config.output, 'services');
|
|
392
|
+
const serviceDir = join(servicesDir, serviceName);
|
|
393
|
+
|
|
394
|
+
// Create directories
|
|
395
|
+
mkdirSync(servicesDir, {
|
|
396
|
+
recursive: true
|
|
397
|
+
});
|
|
398
|
+
mkdirSync(serviceDir, {
|
|
399
|
+
recursive: true
|
|
400
|
+
});
|
|
401
|
+
mkdirSync(join(serviceDir, 'src', 'config'), {
|
|
402
|
+
recursive: true
|
|
403
|
+
});
|
|
404
|
+
mkdirSync(join(serviceDir, 'src', 'worker'), {
|
|
405
|
+
recursive: true
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Write configuration files
|
|
409
|
+
for (const [filePath, content] of Object.entries(configs)) {
|
|
410
|
+
const fullPath = join(serviceDir, filePath);
|
|
411
|
+
mkdirSync(dirname(fullPath), {
|
|
412
|
+
recursive: true
|
|
413
|
+
});
|
|
414
|
+
writeFileSync(fullPath, content, 'utf8');
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Create basic worker file
|
|
418
|
+
const workerContent = `import { ClodoWorker } from '@tamyla/clodo-framework/worker';
|
|
419
|
+
import { domains } from './config/domains.js';
|
|
420
|
+
|
|
421
|
+
export default {
|
|
422
|
+
async fetch(request, env, ctx) {
|
|
423
|
+
const worker = new ClodoWorker({
|
|
424
|
+
domains,
|
|
425
|
+
environment: env
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
return worker.handleRequest(request, env, ctx);
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
`;
|
|
432
|
+
writeFileSync(join(serviceDir, 'src', 'worker', 'index.js'), workerContent, 'utf8');
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Get available service types
|
|
437
|
+
* @returns {string[]} Array of available service types
|
|
438
|
+
*/
|
|
439
|
+
getServiceTypes() {
|
|
440
|
+
return [...this.serviceTypes];
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Convenience function for quick service initialization
|
|
445
|
+
export async function initializeService(serviceName, options = {}) {
|
|
446
|
+
const initializer = new ServiceInitializer();
|
|
447
|
+
return await initializer.initializeService(serviceName, options);
|
|
448
|
+
}
|