atxp 1.0.6 ā 1.0.8
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/dist/create-project.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export type Framework = 'express';
|
|
2
|
+
export declare function parseEnvFile(content: string): Array<{
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
comment?: string;
|
|
6
|
+
}>;
|
|
2
7
|
export declare function createProject(appName: string, framework: Framework, gitOption?: 'git' | 'no-git'): Promise<void>;
|
|
3
8
|
//# sourceMappingURL=create-project.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../src/create-project.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-project.d.ts","sourceRoot":"","sources":["../src/create-project.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC;AAclC,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsDrG;AAyGD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAqGtH"}
|
package/dist/create-project.js
CHANGED
|
@@ -2,6 +2,7 @@ import fs from 'fs-extra';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { spawn } from 'child_process';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
5
6
|
// Utility function to check if git is available
|
|
6
7
|
async function isGitAvailable() {
|
|
7
8
|
try {
|
|
@@ -13,6 +14,100 @@ async function isGitAvailable() {
|
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
15
16
|
}
|
|
17
|
+
// Parse environment variables from .env content
|
|
18
|
+
export function parseEnvFile(content) {
|
|
19
|
+
const lines = content.split('\n');
|
|
20
|
+
const envVars = [];
|
|
21
|
+
let pendingComment;
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
// Skip empty lines
|
|
25
|
+
if (!trimmed) {
|
|
26
|
+
pendingComment = undefined;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// Capture comments
|
|
30
|
+
if (trimmed.startsWith('#')) {
|
|
31
|
+
// Extract comment text, removing the # and any extra spaces/trailing ###
|
|
32
|
+
const commentText = trimmed.replace(/^#+\s*/, '').replace(/\s*#+\s*$/, '').trim();
|
|
33
|
+
if (commentText) {
|
|
34
|
+
pendingComment = commentText;
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// Look for key=value pairs
|
|
39
|
+
const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
|
|
40
|
+
if (match) {
|
|
41
|
+
const [, key, value] = match;
|
|
42
|
+
// Check if the value looks like a placeholder
|
|
43
|
+
const isPlaceholder = value === '' ||
|
|
44
|
+
value.includes('your_') ||
|
|
45
|
+
value.includes('YOUR_') ||
|
|
46
|
+
value.includes('<') ||
|
|
47
|
+
value.includes('TODO') ||
|
|
48
|
+
value.includes('REPLACE') ||
|
|
49
|
+
value === 'changeme' ||
|
|
50
|
+
(value.startsWith('"') && value.endsWith('"') &&
|
|
51
|
+
(value.includes('your_') || value.includes('YOUR_') || value === '""'));
|
|
52
|
+
if (isPlaceholder) {
|
|
53
|
+
envVars.push({
|
|
54
|
+
key,
|
|
55
|
+
value,
|
|
56
|
+
comment: pendingComment || `Configuration value for ${key}`
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// Reset pending comment after processing a variable
|
|
60
|
+
pendingComment = undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return envVars;
|
|
64
|
+
}
|
|
65
|
+
// Interactive environment variable configuration
|
|
66
|
+
async function configureEnvironmentVariables(envPath) {
|
|
67
|
+
const envContent = await fs.readFile(envPath, 'utf-8');
|
|
68
|
+
const envVars = parseEnvFile(envContent);
|
|
69
|
+
if (envVars.length === 0) {
|
|
70
|
+
console.log(chalk.green('Environment file looks good - no configuration needed'));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
console.log(chalk.blue('\nš§ Environment Configuration'));
|
|
74
|
+
console.log(chalk.gray('The template includes environment variables that need configuration.'));
|
|
75
|
+
const { shouldConfigure } = await inquirer.prompt([
|
|
76
|
+
{
|
|
77
|
+
type: 'confirm',
|
|
78
|
+
name: 'shouldConfigure',
|
|
79
|
+
message: 'Would you like to configure environment variables now?',
|
|
80
|
+
default: true
|
|
81
|
+
}
|
|
82
|
+
]);
|
|
83
|
+
if (!shouldConfigure) {
|
|
84
|
+
console.log(chalk.yellow('Skipped environment configuration. Remember to update your .env file before running the project!'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log(chalk.gray('You can skip any variable by pressing Enter to keep the placeholder.\n'));
|
|
88
|
+
console.log(chalk.gray('Clear the default text to set a variable to empty.\n'));
|
|
89
|
+
const updatedVars = {};
|
|
90
|
+
for (const envVar of envVars) {
|
|
91
|
+
const { value } = await inquirer.prompt([
|
|
92
|
+
{
|
|
93
|
+
type: 'input',
|
|
94
|
+
name: 'value',
|
|
95
|
+
message: `${envVar.key} (${envVar.comment}):`,
|
|
96
|
+
default: envVar.value
|
|
97
|
+
}
|
|
98
|
+
]);
|
|
99
|
+
// Use the value as-is. If user cleared the input, value will be empty string
|
|
100
|
+
updatedVars[envVar.key] = value;
|
|
101
|
+
}
|
|
102
|
+
// Update the .env file with new values
|
|
103
|
+
let updatedContent = envContent;
|
|
104
|
+
for (const [key, value] of Object.entries(updatedVars)) {
|
|
105
|
+
const regex = new RegExp(`^${key}=.*$`, 'm');
|
|
106
|
+
updatedContent = updatedContent.replace(regex, `${key}=${value}`);
|
|
107
|
+
}
|
|
108
|
+
await fs.writeFile(envPath, updatedContent);
|
|
109
|
+
console.log(chalk.green('ā
Environment variables configured successfully!'));
|
|
110
|
+
}
|
|
16
111
|
// Template repositories
|
|
17
112
|
const TEMPLATES = {
|
|
18
113
|
express: {
|
|
@@ -25,6 +120,31 @@ const TEMPLATES = {
|
|
|
25
120
|
// humanText: 'Vercel (Vercel.js starter template)'
|
|
26
121
|
// }
|
|
27
122
|
};
|
|
123
|
+
// Find env.example file in project directory or one level of subdirectories
|
|
124
|
+
async function findEnvExample(projectPath) {
|
|
125
|
+
// Check root directory first
|
|
126
|
+
const rootEnvExample = path.join(projectPath, 'env.example');
|
|
127
|
+
if (await fs.pathExists(rootEnvExample)) {
|
|
128
|
+
return rootEnvExample;
|
|
129
|
+
}
|
|
130
|
+
// Check subdirectories (max depth 1)
|
|
131
|
+
try {
|
|
132
|
+
const entries = await fs.readdir(projectPath, { withFileTypes: true });
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
if (entry.isDirectory()) {
|
|
135
|
+
const subDirEnvExample = path.join(projectPath, entry.name, 'env.example');
|
|
136
|
+
if (await fs.pathExists(subDirEnvExample)) {
|
|
137
|
+
return subDirEnvExample;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// If we can't read the directory, just return null
|
|
144
|
+
console.warn(chalk.yellow('Could not search for env.example files'));
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
28
148
|
export async function createProject(appName, framework, gitOption) {
|
|
29
149
|
try {
|
|
30
150
|
// Validate app name
|
|
@@ -65,15 +185,18 @@ export async function createProject(appName, framework, gitOption) {
|
|
|
65
185
|
await fs.ensureDir(projectPath);
|
|
66
186
|
// Clone template from GitHub
|
|
67
187
|
await cloneTemplate(framework, projectPath);
|
|
68
|
-
// Copy .env file from env.example if it exists
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
188
|
+
// Copy .env file from env.example if it exists and configure it interactively
|
|
189
|
+
// Search for env.example in project root and one level of subdirectories
|
|
190
|
+
const envExamplePath = await findEnvExample(projectPath);
|
|
191
|
+
let createdEnvPath = null;
|
|
192
|
+
if (envExamplePath) {
|
|
193
|
+
const envDir = path.dirname(envExamplePath);
|
|
194
|
+
const envPath = path.join(envDir, '.env');
|
|
72
195
|
await fs.copy(envExamplePath, envPath);
|
|
73
196
|
console.log(chalk.green('Environment file created from template'));
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
197
|
+
// Configure environment variables interactively
|
|
198
|
+
await configureEnvironmentVariables(envPath);
|
|
199
|
+
createdEnvPath = envPath;
|
|
77
200
|
}
|
|
78
201
|
// Update package.json with project name
|
|
79
202
|
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
@@ -101,9 +224,12 @@ export async function createProject(appName, framework, gitOption) {
|
|
|
101
224
|
console.log(chalk.green('\nProject created successfully!'));
|
|
102
225
|
console.log(chalk.blue('\nNext steps:'));
|
|
103
226
|
console.log(chalk.white(` cd ${appName}`));
|
|
104
|
-
console.log(chalk.white(' npm install'));
|
|
227
|
+
console.log(chalk.white(' npm run install-all'));
|
|
105
228
|
console.log(chalk.white(' npm start'));
|
|
106
|
-
|
|
229
|
+
// Only show env reminder if there is an .env file that exists
|
|
230
|
+
if (createdEnvPath && await fs.pathExists(createdEnvPath)) {
|
|
231
|
+
console.log(chalk.yellow('\nRemember to configure your environment variables in the .env file!'));
|
|
232
|
+
}
|
|
107
233
|
}
|
|
108
234
|
catch (error) {
|
|
109
235
|
console.error(chalk.red('Error creating project:'), error.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-project.js","sourceRoot":"","sources":["../src/create-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"create-project.js","sourceRoot":"","sources":["../src/create-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseEnvFile } from './create-project.js';
|
|
2
3
|
describe('createProject', () => {
|
|
3
4
|
describe('project name validation', () => {
|
|
4
5
|
const validateProjectName = (input) => {
|
|
@@ -43,4 +44,246 @@ describe('createProject', () => {
|
|
|
43
44
|
});
|
|
44
45
|
});
|
|
45
46
|
});
|
|
47
|
+
describe('parseEnvFile', () => {
|
|
48
|
+
describe('basic parsing', () => {
|
|
49
|
+
it('should parse environment variables with comments', () => {
|
|
50
|
+
const envContent = `# Database connection string
|
|
51
|
+
DATABASE_URL=your_database_url_here
|
|
52
|
+
|
|
53
|
+
# JWT secret for authentication
|
|
54
|
+
JWT_SECRET=
|
|
55
|
+
|
|
56
|
+
# Port for the server
|
|
57
|
+
PORT=3000`;
|
|
58
|
+
const result = parseEnvFile(envContent);
|
|
59
|
+
expect(result).toHaveLength(2);
|
|
60
|
+
expect(result[0]).toEqual({
|
|
61
|
+
key: 'DATABASE_URL',
|
|
62
|
+
value: 'your_database_url_here',
|
|
63
|
+
comment: 'Database connection string'
|
|
64
|
+
});
|
|
65
|
+
expect(result[1]).toEqual({
|
|
66
|
+
key: 'JWT_SECRET',
|
|
67
|
+
value: '',
|
|
68
|
+
comment: 'JWT secret for authentication'
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
it('should not include variables with non-placeholder values', () => {
|
|
72
|
+
const envContent = `# Database connection string
|
|
73
|
+
DATABASE_URL=your_database_url_here
|
|
74
|
+
|
|
75
|
+
# Port (already configured)
|
|
76
|
+
PORT=3000
|
|
77
|
+
|
|
78
|
+
# Environment
|
|
79
|
+
NODE_ENV=development`;
|
|
80
|
+
const result = parseEnvFile(envContent);
|
|
81
|
+
expect(result).toHaveLength(1);
|
|
82
|
+
expect(result[0].key).toBe('DATABASE_URL');
|
|
83
|
+
});
|
|
84
|
+
it('should handle multiple comment lines', () => {
|
|
85
|
+
const envContent = `# This is the main database URL
|
|
86
|
+
# It should point to your PostgreSQL instance
|
|
87
|
+
DATABASE_URL=your_database_url_here
|
|
88
|
+
|
|
89
|
+
# Simple comment
|
|
90
|
+
API_KEY=TODO`;
|
|
91
|
+
const result = parseEnvFile(envContent);
|
|
92
|
+
expect(result).toHaveLength(2);
|
|
93
|
+
expect(result[0].comment).toBe('It should point to your PostgreSQL instance');
|
|
94
|
+
expect(result[1].comment).toBe('Simple comment');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('placeholder detection', () => {
|
|
98
|
+
it('should detect empty values as placeholders', () => {
|
|
99
|
+
const envContent = `API_KEY=
|
|
100
|
+
DATABASE_URL=`;
|
|
101
|
+
const result = parseEnvFile(envContent);
|
|
102
|
+
expect(result).toHaveLength(2);
|
|
103
|
+
expect(result[0].key).toBe('API_KEY');
|
|
104
|
+
expect(result[1].key).toBe('DATABASE_URL');
|
|
105
|
+
});
|
|
106
|
+
it('should detect common placeholder patterns', () => {
|
|
107
|
+
const envContent = `API_KEY=your_api_key_here
|
|
108
|
+
SECRET=YOUR_SECRET_HERE
|
|
109
|
+
TOKEN=<your_token>
|
|
110
|
+
DB_URL=TODO
|
|
111
|
+
PASSWORD=REPLACE_ME
|
|
112
|
+
KEY=changeme`;
|
|
113
|
+
const result = parseEnvFile(envContent);
|
|
114
|
+
expect(result).toHaveLength(6);
|
|
115
|
+
expect(result.map(r => r.key)).toEqual(['API_KEY', 'SECRET', 'TOKEN', 'DB_URL', 'PASSWORD', 'KEY']);
|
|
116
|
+
});
|
|
117
|
+
it('should not detect real values as placeholders', () => {
|
|
118
|
+
const envContent = `PORT=3000
|
|
119
|
+
NODE_ENV=development
|
|
120
|
+
APP_NAME=MyApp
|
|
121
|
+
DEBUG=true
|
|
122
|
+
DATABASE_URL=postgresql://user:pass@localhost:5432/db`;
|
|
123
|
+
const result = parseEnvFile(envContent);
|
|
124
|
+
expect(result).toHaveLength(0);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe('comment handling', () => {
|
|
128
|
+
it('should handle comments with different formatting', () => {
|
|
129
|
+
const envContent = `# Simple comment
|
|
130
|
+
API_KEY=your_key
|
|
131
|
+
|
|
132
|
+
## Multiple hashes
|
|
133
|
+
SECRET=
|
|
134
|
+
|
|
135
|
+
### Extra spaces and hashes ###
|
|
136
|
+
TOKEN=TODO
|
|
137
|
+
|
|
138
|
+
# Comment with special chars !@#$%^&*()
|
|
139
|
+
PASSWORD=changeme`;
|
|
140
|
+
const result = parseEnvFile(envContent);
|
|
141
|
+
expect(result).toHaveLength(4);
|
|
142
|
+
expect(result[0].comment).toBe('Simple comment');
|
|
143
|
+
expect(result[1].comment).toBe('Multiple hashes');
|
|
144
|
+
expect(result[2].comment).toBe('Extra spaces and hashes');
|
|
145
|
+
expect(result[3].comment).toBe('Comment with special chars !@#$%^&*()');
|
|
146
|
+
});
|
|
147
|
+
it('should provide fallback description when no comment exists', () => {
|
|
148
|
+
const envContent = `API_KEY=your_key
|
|
149
|
+
|
|
150
|
+
SECRET=
|
|
151
|
+
TOKEN=TODO`;
|
|
152
|
+
const result = parseEnvFile(envContent);
|
|
153
|
+
expect(result).toHaveLength(3);
|
|
154
|
+
expect(result[0].comment).toBe('Configuration value for API_KEY');
|
|
155
|
+
expect(result[1].comment).toBe('Configuration value for SECRET');
|
|
156
|
+
expect(result[2].comment).toBe('Configuration value for TOKEN');
|
|
157
|
+
});
|
|
158
|
+
it('should reset comments properly between variables', () => {
|
|
159
|
+
const envContent = `# Comment for API_KEY
|
|
160
|
+
API_KEY=your_key
|
|
161
|
+
|
|
162
|
+
# This comment should not apply to PORT
|
|
163
|
+
PORT=3000
|
|
164
|
+
|
|
165
|
+
SECRET=TODO`;
|
|
166
|
+
const result = parseEnvFile(envContent);
|
|
167
|
+
expect(result).toHaveLength(2);
|
|
168
|
+
expect(result[0].comment).toBe('Comment for API_KEY');
|
|
169
|
+
expect(result[1].comment).toBe('Configuration value for SECRET');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('edge cases', () => {
|
|
173
|
+
it('should handle empty file', () => {
|
|
174
|
+
const result = parseEnvFile('');
|
|
175
|
+
expect(result).toHaveLength(0);
|
|
176
|
+
});
|
|
177
|
+
it('should handle file with only comments', () => {
|
|
178
|
+
const envContent = `# This is a comment
|
|
179
|
+
# Another comment
|
|
180
|
+
# No variables here`;
|
|
181
|
+
const result = parseEnvFile(envContent);
|
|
182
|
+
expect(result).toHaveLength(0);
|
|
183
|
+
});
|
|
184
|
+
it('should handle malformed lines gracefully', () => {
|
|
185
|
+
const envContent = `# Valid comment
|
|
186
|
+
API_KEY=your_key
|
|
187
|
+
invalid_line_without_equals
|
|
188
|
+
ANOTHER_KEY=
|
|
189
|
+
=value_without_key
|
|
190
|
+
KEY_WITH_EQUALS=value=with=equals`;
|
|
191
|
+
const result = parseEnvFile(envContent);
|
|
192
|
+
expect(result).toHaveLength(2);
|
|
193
|
+
expect(result[0].key).toBe('API_KEY');
|
|
194
|
+
expect(result[1].key).toBe('ANOTHER_KEY');
|
|
195
|
+
});
|
|
196
|
+
it('should handle variables with special characters in values', () => {
|
|
197
|
+
const envContent = `# Database URL with special chars
|
|
198
|
+
DATABASE_URL=your_url_here
|
|
199
|
+
# JWT with special formatting
|
|
200
|
+
JWT_SECRET=<replace_with_secret>
|
|
201
|
+
# Password with quotes (real value)
|
|
202
|
+
PASSWORD="my_actual_password"`;
|
|
203
|
+
const result = parseEnvFile(envContent);
|
|
204
|
+
expect(result).toHaveLength(2);
|
|
205
|
+
expect(result[0].key).toBe('DATABASE_URL');
|
|
206
|
+
expect(result[1].key).toBe('JWT_SECRET');
|
|
207
|
+
// PASSWORD should not be included as it has a real value
|
|
208
|
+
});
|
|
209
|
+
it('should handle mixed case variable names', () => {
|
|
210
|
+
const envContent = `# API key
|
|
211
|
+
api_key=your_key
|
|
212
|
+
Api_Key=your_key
|
|
213
|
+
API_KEY=your_key
|
|
214
|
+
database_url=your_url`;
|
|
215
|
+
const result = parseEnvFile(envContent);
|
|
216
|
+
// Only API_KEY should match the pattern (uppercase with underscores)
|
|
217
|
+
expect(result).toHaveLength(1);
|
|
218
|
+
expect(result[0].key).toBe('API_KEY');
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe('real-world examples', () => {
|
|
222
|
+
it('should parse a typical express app env.example', () => {
|
|
223
|
+
const envContent = `# Server configuration
|
|
224
|
+
PORT=3000
|
|
225
|
+
NODE_ENV=development
|
|
226
|
+
|
|
227
|
+
# Database
|
|
228
|
+
# PostgreSQL connection string
|
|
229
|
+
DATABASE_URL=your_database_url_here
|
|
230
|
+
|
|
231
|
+
# Authentication
|
|
232
|
+
# Secret key for JWT tokens (generate a strong random string)
|
|
233
|
+
JWT_SECRET=your_jwt_secret_here
|
|
234
|
+
|
|
235
|
+
# External APIs
|
|
236
|
+
# OpenAI API key for AI features
|
|
237
|
+
OPENAI_API_KEY=your_openai_key_here
|
|
238
|
+
|
|
239
|
+
# Optional: Redis for caching
|
|
240
|
+
REDIS_URL=your_redis_url_here`;
|
|
241
|
+
const result = parseEnvFile(envContent);
|
|
242
|
+
expect(result).toHaveLength(4);
|
|
243
|
+
const keys = result.map(r => r.key);
|
|
244
|
+
expect(keys).toEqual(['DATABASE_URL', 'JWT_SECRET', 'OPENAI_API_KEY', 'REDIS_URL']);
|
|
245
|
+
expect(result[0].comment).toBe('PostgreSQL connection string');
|
|
246
|
+
expect(result[1].comment).toBe('Secret key for JWT tokens (generate a strong random string)');
|
|
247
|
+
expect(result[2].comment).toBe('OpenAI API key for AI features');
|
|
248
|
+
expect(result[3].comment).toBe('Optional: Redis for caching');
|
|
249
|
+
});
|
|
250
|
+
it('should parse a typical web app env.example with various formats', () => {
|
|
251
|
+
const envContent = `# Application Settings
|
|
252
|
+
APP_NAME=MyApp
|
|
253
|
+
APP_URL=http://localhost:3000
|
|
254
|
+
|
|
255
|
+
# Database Configuration
|
|
256
|
+
# Primary database connection
|
|
257
|
+
DATABASE_URL=
|
|
258
|
+
|
|
259
|
+
# Authentication & Security
|
|
260
|
+
# Clerk Authentication Keys
|
|
261
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_publishable_key_here
|
|
262
|
+
CLERK_SECRET_KEY=your_secret_key_here
|
|
263
|
+
|
|
264
|
+
# Email Service
|
|
265
|
+
# SendGrid API key for transactional emails
|
|
266
|
+
SENDGRID_API_KEY=TODO
|
|
267
|
+
|
|
268
|
+
# Analytics (optional)
|
|
269
|
+
GOOGLE_ANALYTICS_ID=
|
|
270
|
+
|
|
271
|
+
# Feature Flags
|
|
272
|
+
ENABLE_PREMIUM_FEATURES=false`;
|
|
273
|
+
const result = parseEnvFile(envContent);
|
|
274
|
+
expect(result).toHaveLength(5);
|
|
275
|
+
const expectedVars = [
|
|
276
|
+
{ key: 'DATABASE_URL', comment: 'Primary database connection' },
|
|
277
|
+
{ key: 'NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY', comment: 'Clerk Authentication Keys' },
|
|
278
|
+
{ key: 'CLERK_SECRET_KEY', comment: 'Configuration value for CLERK_SECRET_KEY' }, // Comment is reset after first variable
|
|
279
|
+
{ key: 'SENDGRID_API_KEY', comment: 'SendGrid API key for transactional emails' },
|
|
280
|
+
{ key: 'GOOGLE_ANALYTICS_ID', comment: 'Analytics (optional)' }
|
|
281
|
+
];
|
|
282
|
+
expectedVars.forEach((expected, index) => {
|
|
283
|
+
expect(result[index].key).toBe(expected.key);
|
|
284
|
+
expect(result[index].comment).toBe(expected.comment);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
});
|
|
46
289
|
//# sourceMappingURL=create-project.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-project.test.js","sourceRoot":"","sources":["../src/create-project.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"create-project.test.js","sourceRoot":"","sources":["../src/create-project.test.ts"],"names":[],"mappings":"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"}
|