@friggframework/devtools 2.0.0--canary.414.db76eeb.0 → 2.0.0--canary.414.87ebab2.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/frigg-cli/deploy-command/index.js +121 -95
- package/infrastructure/env-validator.js +20 -16
- package/package.json +6 -6
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
const { spawn
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
|
+
// Configuration constants
|
|
6
|
+
const PATHS = {
|
|
7
|
+
APP_DEFINITION: 'index.js',
|
|
8
|
+
INFRASTRUCTURE: 'infrastructure.js'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const COMMANDS = {
|
|
12
|
+
SERVERLESS: 'serverless'
|
|
13
|
+
};
|
|
14
|
+
|
|
5
15
|
/**
|
|
6
16
|
* Constructs filtered environment variables for serverless deployment
|
|
7
|
-
* @param {string[]}
|
|
17
|
+
* @param {string[]} appDefinedVariables - Array of environment variable names from app definition
|
|
8
18
|
* @returns {Object} Filtered environment variables object
|
|
9
19
|
*/
|
|
10
|
-
function buildFilteredEnvironment(
|
|
20
|
+
function buildFilteredEnvironment(appDefinedVariables) {
|
|
11
21
|
return {
|
|
12
22
|
// Essential system variables needed to run serverless
|
|
13
23
|
PATH: process.env.PATH,
|
|
@@ -23,116 +33,123 @@ function buildFilteredEnvironment(envVars) {
|
|
|
23
33
|
|
|
24
34
|
// App-defined environment variables
|
|
25
35
|
...Object.fromEntries(
|
|
26
|
-
|
|
36
|
+
appDefinedVariables
|
|
27
37
|
.map((key) => [key, process.env[key]])
|
|
28
38
|
.filter(([_, value]) => value !== undefined)
|
|
29
39
|
),
|
|
30
40
|
};
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Loads and parses the app definition from index.js
|
|
45
|
+
* @returns {Object|null} App definition object or null if not found
|
|
46
|
+
*/
|
|
47
|
+
function loadAppDefinition() {
|
|
48
|
+
const appDefPath = path.join(process.cwd(), PATHS.APP_DEFINITION);
|
|
49
|
+
|
|
50
|
+
if (!fs.existsSync(appDefPath)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const { Definition } = require(appDefPath);
|
|
56
|
+
return Definition;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.warn('Could not load appDefinition environment config:', error.message);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Extracts environment variable names from app definition
|
|
65
|
+
* @param {Object} appDefinition - App definition object
|
|
66
|
+
* @returns {string[]} Array of environment variable names
|
|
67
|
+
*/
|
|
68
|
+
function extractEnvironmentVariables(appDefinition) {
|
|
69
|
+
if (!appDefinition?.environment) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log('🔧 Loading environment configuration from appDefinition...');
|
|
74
|
+
|
|
75
|
+
const appDefinedVariables = Object.keys(appDefinition.environment).filter(
|
|
76
|
+
(key) => appDefinition.environment[key] === true
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
console.log(` Found ${appDefinedVariables.length} environment variables: ${appDefinedVariables.join(', ')}`);
|
|
80
|
+
return appDefinedVariables;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Handles environment validation warnings
|
|
85
|
+
* @param {Object} validation - Validation result object
|
|
86
|
+
* @param {Object} options - Deploy command options
|
|
87
|
+
*/
|
|
88
|
+
function handleValidationWarnings(validation, options) {
|
|
89
|
+
if (validation.missing.length === 0 || options.skipEnvValidation) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.warn(`⚠️ Warning: Missing ${validation.missing.length} environment variables: ${validation.missing.join(', ')}`);
|
|
94
|
+
console.warn(' These variables are optional and deployment will continue');
|
|
95
|
+
console.warn(' Run with --skip-env-validation to bypass this check');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Validates environment variables and builds filtered environment
|
|
100
|
+
* @param {Object} appDefinition - App definition object
|
|
101
|
+
* @param {Object} options - Deploy command options
|
|
102
|
+
* @returns {Object} Filtered environment variables
|
|
103
|
+
*/
|
|
104
|
+
function validateAndBuildEnvironment(appDefinition, options) {
|
|
105
|
+
if (!appDefinition) {
|
|
106
|
+
return buildFilteredEnvironment([]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const appDefinedVariables = extractEnvironmentVariables(appDefinition);
|
|
110
|
+
|
|
111
|
+
// Try to use the env-validator if available
|
|
112
|
+
try {
|
|
113
|
+
const { validateEnvironmentVariables } = require('@friggframework/devtools/infrastructure/env-validator');
|
|
114
|
+
const validation = validateEnvironmentVariables(appDefinition);
|
|
115
|
+
|
|
116
|
+
handleValidationWarnings(validation, options);
|
|
117
|
+
return buildFilteredEnvironment(appDefinedVariables);
|
|
35
118
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (Definition.environment) {
|
|
46
|
-
console.log(
|
|
47
|
-
'🔧 Loading environment configuration from appDefinition...'
|
|
48
|
-
);
|
|
49
|
-
const envVars = Object.keys(Definition.environment).filter(
|
|
50
|
-
(key) => Definition.environment[key] === true
|
|
51
|
-
);
|
|
52
|
-
console.log(
|
|
53
|
-
` Found ${
|
|
54
|
-
envVars.length
|
|
55
|
-
} environment variables: ${envVars.join(', ')}`
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
// Try to use the env-validator if available
|
|
59
|
-
try {
|
|
60
|
-
const {
|
|
61
|
-
validateEnvironmentVariables,
|
|
62
|
-
} = require('@friggframework/devtools/infrastructure/env-validator');
|
|
63
|
-
const validation = validateEnvironmentVariables(Definition);
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
validation.missing.length > 0 &&
|
|
67
|
-
!options.skipEnvValidation
|
|
68
|
-
) {
|
|
69
|
-
console.warn(
|
|
70
|
-
`⚠️ Warning: Missing ${
|
|
71
|
-
validation.missing.length
|
|
72
|
-
} environment variables: ${validation.missing.join(
|
|
73
|
-
', '
|
|
74
|
-
)}`
|
|
75
|
-
);
|
|
76
|
-
console.warn(
|
|
77
|
-
' These variables are optional and deployment will continue'
|
|
78
|
-
);
|
|
79
|
-
console.warn(
|
|
80
|
-
' Run with --skip-env-validation to bypass this check'
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Pass essential system variables + AWS credentials + app-defined environment variables
|
|
85
|
-
integrationEnvironmentVariables =
|
|
86
|
-
buildFilteredEnvironment(envVars);
|
|
87
|
-
} catch (validatorError) {
|
|
88
|
-
// Validator not available in current version, just warn
|
|
89
|
-
const missing = envVars.filter((v) => !process.env[v]);
|
|
90
|
-
if (missing.length > 0) {
|
|
91
|
-
console.warn(
|
|
92
|
-
`⚠️ Warning: Missing ${
|
|
93
|
-
missing.length
|
|
94
|
-
} environment variables: ${missing.join(', ')}`
|
|
95
|
-
);
|
|
96
|
-
console.warn(
|
|
97
|
-
' These variables are optional and deployment will continue'
|
|
98
|
-
);
|
|
99
|
-
console.warn(
|
|
100
|
-
' Set them in your CI/CD environment or .env file if needed'
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Pass essential system variables + AWS credentials + app-defined environment variables
|
|
105
|
-
integrationEnvironmentVariables =
|
|
106
|
-
buildFilteredEnvironment(envVars);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.warn(
|
|
111
|
-
'Could not load appDefinition environment config:',
|
|
112
|
-
error.message
|
|
113
|
-
);
|
|
114
|
-
// Keep all env vars if we can't validate
|
|
119
|
+
} catch (validatorError) {
|
|
120
|
+
// Validator not available, do basic validation
|
|
121
|
+
const missingVariables = appDefinedVariables.filter((variable) => !process.env[variable]);
|
|
122
|
+
|
|
123
|
+
if (missingVariables.length > 0) {
|
|
124
|
+
console.warn(`⚠️ Warning: Missing ${missingVariables.length} environment variables: ${missingVariables.join(', ')}`);
|
|
125
|
+
console.warn(' These variables are optional and deployment will continue');
|
|
126
|
+
console.warn(' Set them in your CI/CD environment or .env file if needed');
|
|
115
127
|
}
|
|
128
|
+
|
|
129
|
+
return buildFilteredEnvironment(appDefinedVariables);
|
|
116
130
|
}
|
|
131
|
+
}
|
|
117
132
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Executes the serverless deployment command
|
|
135
|
+
* @param {Object} environment - Environment variables to pass to serverless
|
|
136
|
+
* @param {Object} options - Deploy command options
|
|
137
|
+
*/
|
|
138
|
+
function executeServerlessDeployment(environment, options) {
|
|
139
|
+
console.log('🚀 Deploying serverless application...');
|
|
140
|
+
|
|
123
141
|
const serverlessArgs = [
|
|
124
142
|
'deploy',
|
|
125
143
|
'--config',
|
|
126
|
-
|
|
144
|
+
PATHS.INFRASTRUCTURE,
|
|
127
145
|
'--stage',
|
|
128
146
|
options.stage,
|
|
129
|
-
options.stage,
|
|
130
147
|
];
|
|
131
148
|
|
|
132
|
-
const childProcess = spawn(
|
|
133
|
-
cwd:
|
|
149
|
+
const childProcess = spawn(COMMANDS.SERVERLESS, serverlessArgs, {
|
|
150
|
+
cwd: path.resolve(process.cwd()),
|
|
134
151
|
stdio: 'inherit',
|
|
135
|
-
env:
|
|
152
|
+
env: environment,
|
|
136
153
|
});
|
|
137
154
|
|
|
138
155
|
childProcess.on('error', (error) => {
|
|
@@ -146,4 +163,13 @@ async function deployCommand(options) {
|
|
|
146
163
|
});
|
|
147
164
|
}
|
|
148
165
|
|
|
166
|
+
async function deployCommand(options) {
|
|
167
|
+
console.log('Deploying the serverless application...');
|
|
168
|
+
|
|
169
|
+
const appDefinition = loadAppDefinition();
|
|
170
|
+
const environment = validateAndBuildEnvironment(appDefinition, options);
|
|
171
|
+
|
|
172
|
+
executeServerlessDeployment(environment, options);
|
|
173
|
+
}
|
|
174
|
+
|
|
149
175
|
module.exports = { deployCommand };
|
|
@@ -12,15 +12,15 @@ const validateEnvironmentVariables = (AppDefinition) => {
|
|
|
12
12
|
const results = {
|
|
13
13
|
valid: [],
|
|
14
14
|
missing: [],
|
|
15
|
-
warnings: []
|
|
15
|
+
warnings: [],
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
if (!AppDefinition.environment) {
|
|
19
19
|
return results;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
console.log('🔍 Validating environment variables...');
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
for (const [key, value] of Object.entries(AppDefinition.environment)) {
|
|
25
25
|
if (value === true) {
|
|
26
26
|
if (process.env[key]) {
|
|
@@ -30,30 +30,34 @@ const validateEnvironmentVariables = (AppDefinition) => {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
// Special handling for certain variables
|
|
35
35
|
if (results.missing.includes('NODE_ENV')) {
|
|
36
36
|
results.warnings.push('NODE_ENV not set, defaulting to "production"');
|
|
37
37
|
// Remove from missing since it has a default
|
|
38
|
-
results.missing = results.missing.filter(v => v !== 'NODE_ENV');
|
|
38
|
+
results.missing = results.missing.filter((v) => v !== 'NODE_ENV');
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
// Report results
|
|
42
42
|
if (results.valid.length > 0) {
|
|
43
|
-
console.log(
|
|
43
|
+
console.log(
|
|
44
|
+
` ✅ Valid: ${results.valid.length} environment variables found`
|
|
45
|
+
);
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
|
|
46
48
|
if (results.missing.length > 0) {
|
|
47
49
|
console.log(` ⚠️ Missing: ${results.missing.join(', ')}`);
|
|
48
|
-
results.warnings.push(
|
|
50
|
+
results.warnings.push(
|
|
51
|
+
`Missing ${results.missing.length} environment variables. These should be set in your CI/CD environment or .env file`
|
|
52
|
+
);
|
|
49
53
|
}
|
|
50
|
-
|
|
54
|
+
|
|
51
55
|
if (results.warnings.length > 0) {
|
|
52
|
-
results.warnings.forEach(warning => {
|
|
56
|
+
results.warnings.forEach((warning) => {
|
|
53
57
|
console.log(` ⚠️ ${warning}`);
|
|
54
58
|
});
|
|
55
59
|
}
|
|
56
|
-
|
|
60
|
+
|
|
57
61
|
return results;
|
|
58
62
|
};
|
|
59
63
|
|
|
@@ -67,7 +71,7 @@ const hasAllRequiredEnvVars = (AppDefinition) => {
|
|
|
67
71
|
return results.missing.length === 0;
|
|
68
72
|
};
|
|
69
73
|
|
|
70
|
-
module.exports = {
|
|
74
|
+
module.exports = {
|
|
71
75
|
validateEnvironmentVariables,
|
|
72
|
-
hasAllRequiredEnvVars
|
|
73
|
-
};
|
|
76
|
+
hasAllRequiredEnvVars,
|
|
77
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.414.
|
|
4
|
+
"version": "2.0.0--canary.414.87ebab2.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-ec2": "^3.835.0",
|
|
7
7
|
"@aws-sdk/client-kms": "^3.835.0",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"@babel/eslint-parser": "^7.18.9",
|
|
10
10
|
"@babel/parser": "^7.25.3",
|
|
11
11
|
"@babel/traverse": "^7.25.3",
|
|
12
|
-
"@friggframework/schemas": "2.0.0--canary.414.
|
|
13
|
-
"@friggframework/test": "2.0.0--canary.414.
|
|
12
|
+
"@friggframework/schemas": "2.0.0--canary.414.87ebab2.0",
|
|
13
|
+
"@friggframework/test": "2.0.0--canary.414.87ebab2.0",
|
|
14
14
|
"@hapi/boom": "^10.0.1",
|
|
15
15
|
"@inquirer/prompts": "^5.3.8",
|
|
16
16
|
"axios": "^1.7.2",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"serverless-http": "^2.7.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@friggframework/eslint-config": "2.0.0--canary.414.
|
|
36
|
-
"@friggframework/prettier-config": "2.0.0--canary.414.
|
|
35
|
+
"@friggframework/eslint-config": "2.0.0--canary.414.87ebab2.0",
|
|
36
|
+
"@friggframework/prettier-config": "2.0.0--canary.414.87ebab2.0",
|
|
37
37
|
"prettier": "^2.7.1",
|
|
38
38
|
"serverless": "3.39.0",
|
|
39
39
|
"serverless-dotenv-plugin": "^6.0.0",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "87ebab2b189ff79d45d9723ba62dee2be872120a"
|
|
69
69
|
}
|