@diagramers/cli 1.0.12 → 1.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.
@@ -11,7 +11,9 @@ export interface InitOptions {
11
11
 
12
12
  export class ProjectInitializer {
13
13
  private templateFiles: string[] = [
14
+ 'scripts',
14
15
  'src/**/*',
16
+ 'scripts/**/*',
15
17
  'package.json',
16
18
  'tsconfig.json',
17
19
  'webpack.config.js',
@@ -50,6 +52,12 @@ export class ProjectInitializer {
50
52
  // Create README
51
53
  await this.createReadme(projectPath, projectName, templateType);
52
54
 
55
+ // Make scripts executable
56
+ await this.makeScriptsExecutable(projectPath);
57
+
58
+ // Process template for project name (update database names, etc.)
59
+ await this.processTemplate(projectPath, projectName);
60
+
53
61
  // Clean up the temporary installation
54
62
  await this.cleanup(projectPath);
55
63
 
@@ -137,6 +145,19 @@ export class ProjectInitializer {
137
145
  if (packageJson.bin) {
138
146
  delete packageJson.bin;
139
147
  }
148
+
149
+ // Ensure CLI scripts are included
150
+ if (!packageJson.scripts) {
151
+ packageJson.scripts = {};
152
+ }
153
+
154
+ // Add CLI scripts if they don't exist
155
+ if (!packageJson.scripts['generate:module']) {
156
+ packageJson.scripts['generate:module'] = './scripts/generate-module.sh';
157
+ }
158
+ if (!packageJson.scripts['cli']) {
159
+ packageJson.scripts['cli'] = './scripts/cli-commands.sh';
160
+ }
140
161
 
141
162
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
142
163
  }
@@ -268,4 +289,47 @@ MIT
268
289
 
269
290
  await fs.writeFile(path.join(projectPath, 'README.md'), readmeContent);
270
291
  }
292
+
293
+ private async makeScriptsExecutable(projectPath: string): Promise<void> {
294
+ const scriptsDir = path.join(projectPath, 'scripts');
295
+
296
+ if (await fs.pathExists(scriptsDir)) {
297
+ try {
298
+ const scripts = await fs.readdir(scriptsDir);
299
+ for (const script of scripts) {
300
+ if (script.endsWith('.sh')) {
301
+ const scriptPath = path.join(scriptsDir, script);
302
+ // Make script executable (chmod 755)
303
+ await fs.chmod(scriptPath, 0o755);
304
+ console.log(chalk.blue(`🔧 Made executable: ${script}`));
305
+ }
306
+ }
307
+ } catch (error: any) {
308
+ console.log(chalk.yellow(`⚠️ Warning: Could not make scripts executable: ${error.message}`));
309
+ }
310
+ }
311
+ }
312
+
313
+ private async processTemplate(projectPath: string, projectName: string): Promise<void> {
314
+ try {
315
+ console.log(chalk.blue(`🔧 Processing template for project: ${projectName}`));
316
+
317
+ // Change to project directory
318
+ const originalCwd = process.cwd();
319
+ process.chdir(projectPath);
320
+
321
+ // Run the template processor
322
+ execSync(`npm run cli process:template ${projectName}`, {
323
+ stdio: 'inherit'
324
+ });
325
+
326
+ // Change back to original directory
327
+ process.chdir(originalCwd);
328
+
329
+ console.log(chalk.green(`✅ Template processed successfully`));
330
+ } catch (error: any) {
331
+ console.log(chalk.yellow(`⚠️ Warning: Could not process template: ${error.message}`));
332
+ console.log(chalk.yellow(` You can manually run: npm run cli process:template ${projectName}`));
333
+ }
334
+ }
271
335
  }
@@ -0,0 +1,161 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ export async function processTemplate(projectName: string): Promise<void> {
5
+ if (!projectName) {
6
+ throw new Error('Project name is required');
7
+ }
8
+
9
+ const currentDir = process.cwd();
10
+
11
+ // Check if we're in a diagramers API project
12
+ const packageJsonPath = path.join(currentDir, 'package.json');
13
+ if (!fs.existsSync(packageJsonPath)) {
14
+ throw new Error('package.json not found. Please run this command from a diagramers API project root.');
15
+ }
16
+
17
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
18
+ if (!packageJson.name?.includes('diagramers') && !packageJson.name?.includes('api')) {
19
+ throw new Error('This command should be run from a diagramers API project.');
20
+ }
21
+
22
+ // Convert project name to database-friendly format
23
+ const dbName = projectName
24
+ .toLowerCase()
25
+ .replace(/[^a-zA-Z0-9]/g, '_')
26
+ .replace(/_+/g, '_')
27
+ .replace(/^_|_$/g, '');
28
+
29
+ console.log(`🗄️ Database name will be: ${dbName}`);
30
+
31
+ // Process configuration files
32
+ console.log('📝 Updating configuration files...');
33
+
34
+ // Update development config
35
+ const devConfigPath = path.join(currentDir, 'src/config/development.ts');
36
+ if (fs.existsSync(devConfigPath)) {
37
+ let devConfig = fs.readFileSync(devConfigPath, 'utf8');
38
+ devConfig = devConfig.replace(
39
+ /mongodb:\/\/127\.0\.0\.1:27017\/[^,\s]+/g,
40
+ `mongodb://127.0.0.1:27017/${dbName}-development`
41
+ );
42
+ fs.writeFileSync(devConfigPath, devConfig);
43
+ console.log(' ✅ Updated development.ts');
44
+ }
45
+
46
+ // Update staging config
47
+ const stagingConfigPath = path.join(currentDir, 'src/config/staging.ts');
48
+ if (fs.existsSync(stagingConfigPath)) {
49
+ let stagingConfig = fs.readFileSync(stagingConfigPath, 'utf8');
50
+ stagingConfig = stagingConfig.replace(
51
+ /sendifier-staging/g,
52
+ `${dbName}-staging`
53
+ );
54
+ fs.writeFileSync(stagingConfigPath, stagingConfig);
55
+ console.log(' ✅ Updated staging.ts');
56
+ }
57
+
58
+ // Update production config
59
+ const prodConfigPath = path.join(currentDir, 'src/config/production.ts');
60
+ if (fs.existsSync(prodConfigPath)) {
61
+ let prodConfig = fs.readFileSync(prodConfigPath, 'utf8');
62
+ prodConfig = prodConfig.replace(
63
+ /sendifier-production/g,
64
+ `${dbName}-production`
65
+ );
66
+ fs.writeFileSync(prodConfigPath, prodConfig);
67
+ console.log(' ✅ Updated production.ts');
68
+ }
69
+
70
+ // Update package.json
71
+ let packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
72
+ packageJsonContent = packageJsonContent.replace(
73
+ /"name":\s*"@diagramers\/api"/g,
74
+ `"name": "${projectName}"`
75
+ );
76
+ packageJsonContent = packageJsonContent.replace(
77
+ /"description":\s*"Diagramers API - A comprehensive Node\.js API template with TypeScript, Firebase Functions, and Socket\.io"/g,
78
+ `"description": "${projectName} - API project"`
79
+ );
80
+ fs.writeFileSync(packageJsonPath, packageJsonContent);
81
+ console.log(' ✅ Updated package.json');
82
+
83
+ // Update README.md
84
+ const readmePath = path.join(currentDir, 'README.md');
85
+ if (fs.existsSync(readmePath)) {
86
+ let readmeContent = fs.readFileSync(readmePath, 'utf8');
87
+ readmeContent = readmeContent.replace(
88
+ /# @diagramers\/api/g,
89
+ `# ${projectName}`
90
+ );
91
+ readmeContent = readmeContent.replace(
92
+ /A comprehensive Node\.js API template with TypeScript, Firebase Functions, and Socket\.io\./g,
93
+ `${projectName} - API project.`
94
+ );
95
+ fs.writeFileSync(readmePath, readmeContent);
96
+ console.log(' ✅ Updated README.md');
97
+ }
98
+
99
+ // Create .env file template
100
+ console.log('📄 Creating .env template...');
101
+ const envTemplate = generateEnvTemplate(dbName);
102
+ fs.writeFileSync(path.join(currentDir, '.env.example'), envTemplate);
103
+
104
+ console.log('✅ Template processing completed!');
105
+ console.log('');
106
+ console.log('📋 Summary:');
107
+ console.log(` Project Name: ${projectName}`);
108
+ console.log(` Database Name: ${dbName}`);
109
+ console.log(` Development DB: ${dbName}-development`);
110
+ console.log(` Staging DB: ${dbName}-staging`);
111
+ console.log(` Production DB: ${dbName}-production`);
112
+ console.log('');
113
+ console.log('🚀 Next steps:');
114
+ console.log(' 1. Copy .env.example to .env and configure your environment variables');
115
+ console.log(' 2. Install dependencies: npm install');
116
+ console.log(' 3. Build the project: npm run build:dev');
117
+ console.log(' 4. Start the server: npm run serve');
118
+ }
119
+
120
+ function generateEnvTemplate(dbName: string): string {
121
+ return `# Environment Configuration
122
+ NODE_ENV=development
123
+
124
+ # Server Configuration
125
+ PORT=4000
126
+ HOST=localhost
127
+
128
+ # Database Configuration
129
+ MONGODB_URI=mongodb://127.0.0.1:27017/${dbName}-development
130
+
131
+ # Firebase Configuration
132
+ FIREBASE_API_KEY=your-api-key
133
+ FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
134
+ FIREBASE_PROJECT_ID=your-project-id
135
+ FIREBASE_STORAGE_BUCKET=your-project.appspot.com
136
+ FIREBASE_MESSAGING_SENDER_ID=your-sender-id
137
+ FIREBASE_APP_ID=your-app-id
138
+
139
+ # JWT Configuration
140
+ JWT_SECRET=your-jwt-secret-key
141
+
142
+ # Twilio Configuration (for SMS)
143
+ TWILIO_ACCOUNT_SID=your-account-sid
144
+ TWILIO_AUTH_TOKEN=your-auth-token
145
+
146
+ # Email Configuration
147
+ SMTP_HOST=smtp.gmail.com
148
+ SMTP_PORT=587
149
+ SMTP_USER=your-email@gmail.com
150
+ SMTP_PASS=your-app-password
151
+
152
+ # Internal API Configuration
153
+ INTERNAL_REQUEST_HEADER_VALUE=your-secret-header-value
154
+
155
+ # Optional Configuration
156
+ BASE_SITE_URL=http://localhost:3000
157
+ LOCAL_API_TUNNEL_URL=https://your-ngrok-url.ngrok-free.app
158
+ LOCAL_UI_TUNNEL_URL=https://your-ui-ngrok-url.ngrok-free.app
159
+ BACKUP_DATABASES_FOLDER_PATH=/path/to/backup/folder
160
+ EXTERNAL_HTTP_REQUEST_TIMEOUT=5000`;
161
+ }