@friggframework/devtools 2.0.0--canary.461.ec909cf.0 → 2.0.0--canary.461.9483dbe.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/__tests__/unit/commands/build.test.js +6 -6
- package/frigg-cli/build-command/index.js +1 -1
- package/frigg-cli/deploy-command/index.js +6 -6
- package/frigg-cli/generate-command/index.js +2 -2
- package/frigg-cli/generate-iam-command.js +10 -10
- package/frigg-cli/start-command/index.js +1 -1
- package/frigg-cli/start-command/start-command.test.js +3 -3
- package/frigg-cli/utils/database-validator.js +14 -21
- package/infrastructure/REFACTOR.md +532 -0
- package/infrastructure/TRANSFORMATION-VISUAL.md +239 -0
- package/infrastructure/__tests__/postgres-config.test.js +1 -1
- package/infrastructure/create-frigg-infrastructure.js +1 -1
- package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
- package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
- package/infrastructure/domains/database/aurora-discovery.js +81 -0
- package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
- package/infrastructure/domains/integration/integration-builder.js +178 -0
- package/infrastructure/domains/integration/integration-builder.test.js +362 -0
- package/infrastructure/domains/integration/websocket-builder.js +69 -0
- package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
- package/infrastructure/domains/networking/vpc-discovery.test.js +257 -0
- package/infrastructure/domains/parameters/ssm-builder.js +79 -0
- package/infrastructure/domains/parameters/ssm-builder.test.js +188 -0
- package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
- package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
- package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
- package/infrastructure/domains/security/kms-builder.js +169 -0
- package/infrastructure/domains/security/kms-builder.test.js +354 -0
- package/infrastructure/domains/security/kms-discovery.js +80 -0
- package/infrastructure/domains/security/kms-discovery.test.js +176 -0
- package/infrastructure/domains/shared/base-builder.js +112 -0
- package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
- package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
- package/infrastructure/domains/shared/environment-builder.js +118 -0
- package/infrastructure/domains/shared/environment-builder.test.js +246 -0
- package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +366 -0
- package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
- package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
- package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
- package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
- package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
- package/infrastructure/domains/shared/resource-discovery.js +132 -0
- package/infrastructure/domains/shared/resource-discovery.test.js +410 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.js +2 -3
- package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
- package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
- package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +259 -0
- package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
- package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +134 -0
- package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
- package/infrastructure/esbuild.config.js +53 -0
- package/infrastructure/infrastructure-composer.js +85 -0
- package/infrastructure/scripts/build-prisma-layer.js +60 -47
- package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
- package/layers/prisma/nodejs/package.json +8 -0
- package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
- package/package.json +8 -8
- package/infrastructure/aws-discovery.js +0 -1704
- package/infrastructure/aws-discovery.test.js +0 -1666
- package/infrastructure/serverless-template.js +0 -2804
- package/infrastructure/serverless-template.test.js +0 -1897
- /package/infrastructure/{POSTGRES-CONFIGURATION.md → docs/POSTGRES-CONFIGURATION.md} +0 -0
- /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
- /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
- /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
- /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
- /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
- /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
- /package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +0 -0
- /package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +0 -0
- /package/infrastructure/{run-discovery.js → scripts/run-discovery.js} +0 -0
|
@@ -52,7 +52,7 @@ describe('CLI Command: build', () => {
|
|
|
52
52
|
await buildCommand({ stage: 'dev' });
|
|
53
53
|
|
|
54
54
|
expect(spawnSync).toHaveBeenCalledWith(
|
|
55
|
-
'
|
|
55
|
+
'osls',
|
|
56
56
|
['package', '--config', 'infrastructure.js', '--stage', 'dev'],
|
|
57
57
|
expect.objectContaining({
|
|
58
58
|
cwd: expect.any(String),
|
|
@@ -66,7 +66,7 @@ describe('CLI Command: build', () => {
|
|
|
66
66
|
await buildCommand({ stage: 'production' });
|
|
67
67
|
|
|
68
68
|
expect(spawnSync).toHaveBeenCalledWith(
|
|
69
|
-
'
|
|
69
|
+
'osls',
|
|
70
70
|
expect.arrayContaining(['--stage', 'production']),
|
|
71
71
|
expect.any(Object)
|
|
72
72
|
);
|
|
@@ -76,7 +76,7 @@ describe('CLI Command: build', () => {
|
|
|
76
76
|
await buildCommand({ stage: 'staging' });
|
|
77
77
|
|
|
78
78
|
expect(spawnSync).toHaveBeenCalledWith(
|
|
79
|
-
'
|
|
79
|
+
'osls',
|
|
80
80
|
expect.arrayContaining(['--stage', 'staging']),
|
|
81
81
|
expect.any(Object)
|
|
82
82
|
);
|
|
@@ -86,7 +86,7 @@ describe('CLI Command: build', () => {
|
|
|
86
86
|
await buildCommand({ stage: 'dev', verbose: true });
|
|
87
87
|
|
|
88
88
|
expect(spawnSync).toHaveBeenCalledWith(
|
|
89
|
-
'
|
|
89
|
+
'osls',
|
|
90
90
|
expect.arrayContaining(['--verbose']),
|
|
91
91
|
expect.any(Object)
|
|
92
92
|
);
|
|
@@ -161,7 +161,7 @@ describe('CLI Command: build', () => {
|
|
|
161
161
|
await buildCommand({ stage: 'dev' });
|
|
162
162
|
|
|
163
163
|
expect(spawnSync).toHaveBeenCalledWith(
|
|
164
|
-
'
|
|
164
|
+
'osls',
|
|
165
165
|
expect.arrayContaining(['--config', 'infrastructure.js']),
|
|
166
166
|
expect.any(Object)
|
|
167
167
|
);
|
|
@@ -188,7 +188,7 @@ describe('CLI Command: build', () => {
|
|
|
188
188
|
const [cmd, args, opts] = spawnSync.mock.calls[0];
|
|
189
189
|
|
|
190
190
|
// Verify complete command structure
|
|
191
|
-
expect(cmd).toBe('
|
|
191
|
+
expect(cmd).toBe('osls');
|
|
192
192
|
expect(args).toEqual([
|
|
193
193
|
'package',
|
|
194
194
|
'--config',
|
|
@@ -19,7 +19,7 @@ async function buildCommand(options) {
|
|
|
19
19
|
console.log('📦 Packaging serverless application...');
|
|
20
20
|
const backendPath = path.resolve(process.cwd());
|
|
21
21
|
const infrastructurePath = 'infrastructure.js';
|
|
22
|
-
const command = '
|
|
22
|
+
const command = 'osls'; // OSS-Serverless (drop-in replacement for serverless v3)
|
|
23
23
|
const serverlessArgs = [
|
|
24
24
|
'package',
|
|
25
25
|
'--config',
|
|
@@ -9,7 +9,7 @@ const PATHS = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
const COMMANDS = {
|
|
12
|
-
SERVERLESS: 'serverless
|
|
12
|
+
SERVERLESS: 'osls' // OSS-Serverless (drop-in replacement for serverless v3)
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -46,7 +46,7 @@ function buildFilteredEnvironment(appDefinedVariables) {
|
|
|
46
46
|
*/
|
|
47
47
|
function loadAppDefinition() {
|
|
48
48
|
const appDefPath = path.join(process.cwd(), PATHS.APP_DEFINITION);
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
if (!fs.existsSync(appDefPath)) {
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
@@ -71,7 +71,7 @@ function extractEnvironmentVariables(appDefinition) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
console.log('🔧 Loading environment configuration from appDefinition...');
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
const appDefinedVariables = Object.keys(appDefinition.environment).filter(
|
|
76
76
|
(key) => appDefinition.environment[key] === true
|
|
77
77
|
);
|
|
@@ -119,7 +119,7 @@ function validateAndBuildEnvironment(appDefinition, options) {
|
|
|
119
119
|
} catch (validatorError) {
|
|
120
120
|
// Validator not available, do basic validation
|
|
121
121
|
const missingVariables = appDefinedVariables.filter((variable) => !process.env[variable]);
|
|
122
|
-
|
|
122
|
+
|
|
123
123
|
if (missingVariables.length > 0) {
|
|
124
124
|
console.warn(`⚠️ Warning: Missing ${missingVariables.length} environment variables: ${missingVariables.join(', ')}`);
|
|
125
125
|
console.warn(' These variables are optional and deployment will continue');
|
|
@@ -137,7 +137,7 @@ function validateAndBuildEnvironment(appDefinition, options) {
|
|
|
137
137
|
*/
|
|
138
138
|
function executeServerlessDeployment(environment, options) {
|
|
139
139
|
console.log('🚀 Deploying serverless application...');
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
const serverlessArgs = [
|
|
142
142
|
'deploy',
|
|
143
143
|
'--config',
|
|
@@ -168,7 +168,7 @@ async function deployCommand(options) {
|
|
|
168
168
|
|
|
169
169
|
const appDefinition = loadAppDefinition();
|
|
170
170
|
const environment = validateAndBuildEnvironment(appDefinition, options);
|
|
171
|
-
|
|
171
|
+
|
|
172
172
|
executeServerlessDeployment(environment, options);
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -4,7 +4,7 @@ const { findNearestBackendPackageJson } = require('../utils/backend-path');
|
|
|
4
4
|
const { select } = require('@inquirer/prompts');
|
|
5
5
|
|
|
6
6
|
// Import generators for different formats
|
|
7
|
-
const { generateCloudFormationTemplate } = require('../../infrastructure/iam-generator');
|
|
7
|
+
const { generateCloudFormationTemplate } = require('../../infrastructure/domains/security/iam-generator');
|
|
8
8
|
const { generateTerraformTemplate } = require('./terraform-generator');
|
|
9
9
|
const { generateAzureARMTemplate, generateAzureTerraformTemplate } = require('./azure-generator');
|
|
10
10
|
const { generateGCPDeploymentManagerTemplate, generateGCPTerraformTemplate } = require('./gcp-generator');
|
|
@@ -87,7 +87,7 @@ async function generateCommand(options = {}) {
|
|
|
87
87
|
const backendDir = path.dirname(nearestBackendPackageJson);
|
|
88
88
|
const backendPackageJsonFile = JSON.parse(fs.readFileSync(nearestBackendPackageJson, 'utf8'));
|
|
89
89
|
const appName = backendPackageJsonFile.name || 'frigg-app';
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
if (options.verbose) {
|
|
92
92
|
console.log('Current directory:', process.cwd());
|
|
93
93
|
console.log('Backend package.json found at:', nearestBackendPackageJson);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { findNearestBackendPackageJson } = require('@friggframework/core');
|
|
4
|
-
const { generateIAMCloudFormation, getFeatureSummary } = require('../infrastructure/iam-generator');
|
|
4
|
+
const { generateIAMCloudFormation, getFeatureSummary } = require('../infrastructure/domains/security/iam-generator');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Generate IAM CloudFormation stack based on current app definition
|
|
@@ -10,7 +10,7 @@ const { generateIAMCloudFormation, getFeatureSummary } = require('../infrastruct
|
|
|
10
10
|
async function generateIamCommand(options = {}) {
|
|
11
11
|
try {
|
|
12
12
|
console.log('🔍 Finding Frigg application...');
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
// Find the backend package.json
|
|
15
15
|
const backendPath = findNearestBackendPackageJson();
|
|
16
16
|
if (!backendPath) {
|
|
@@ -21,7 +21,7 @@ async function generateIamCommand(options = {}) {
|
|
|
21
21
|
|
|
22
22
|
const backendDir = path.dirname(backendPath);
|
|
23
23
|
const backendFilePath = path.join(backendDir, 'index.js');
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
if (!fs.existsSync(backendFilePath)) {
|
|
26
26
|
console.error('❌ Could not find backend/index.js');
|
|
27
27
|
console.error(' Make sure your Frigg application has a backend/index.js file');
|
|
@@ -42,7 +42,7 @@ async function generateIamCommand(options = {}) {
|
|
|
42
42
|
|
|
43
43
|
// Get feature summary
|
|
44
44
|
const summary = getFeatureSummary(appDefinition);
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
console.log('\\n📋 Application Analysis:');
|
|
47
47
|
console.log(` App Name: ${summary.appName}`);
|
|
48
48
|
console.log(` Integrations: ${summary.integrationCount}`);
|
|
@@ -70,15 +70,15 @@ async function generateIamCommand(options = {}) {
|
|
|
70
70
|
// Determine output file path
|
|
71
71
|
const outputDir = options.output || path.join(backendDir, 'infrastructure');
|
|
72
72
|
await fs.ensureDir(outputDir);
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
const outputFile = path.join(outputDir, `${stackName}.yaml`);
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
// Write the file
|
|
77
77
|
await fs.writeFile(outputFile, cloudFormationYaml);
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
console.log(`\\n✅ IAM CloudFormation template generated successfully!`);
|
|
80
80
|
console.log(`📄 File: ${outputFile}`);
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
// Show deployment instructions
|
|
83
83
|
console.log('\\n📚 Next Steps:');
|
|
84
84
|
console.log('\\n1. Deploy the CloudFormation stack:');
|
|
@@ -87,13 +87,13 @@ async function generateIamCommand(options = {}) {
|
|
|
87
87
|
console.log(` --stack-name ${stackName} \\\\`);
|
|
88
88
|
console.log(` --capabilities CAPABILITY_NAMED_IAM \\\\`);
|
|
89
89
|
console.log(` --parameter-overrides DeploymentUserName=${deploymentUserName}`);
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
console.log('\\n2. Retrieve credentials:');
|
|
92
92
|
console.log(` aws cloudformation describe-stacks \\\\`);
|
|
93
93
|
console.log(` --stack-name ${stackName} \\\\`);
|
|
94
94
|
console.log(` --query 'Stacks[0].Outputs[?OutputKey==\`AccessKeyId\`].OutputValue' \\\\`);
|
|
95
95
|
console.log(` --output text`);
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
console.log('\\n3. Get secret access key:');
|
|
98
98
|
console.log(` aws secretsmanager get-secret-value \\\\`);
|
|
99
99
|
console.log(` --secret-id frigg-deployment-credentials \\\\`);
|
|
@@ -44,7 +44,7 @@ async function startCommand(options) {
|
|
|
44
44
|
const backendPath = path.resolve(process.cwd());
|
|
45
45
|
console.log(`Starting backend in ${backendPath}...`);
|
|
46
46
|
const infrastructurePath = 'infrastructure.js';
|
|
47
|
-
const command = '
|
|
47
|
+
const command = 'osls'; // OSS-Serverless (drop-in replacement for serverless v3)
|
|
48
48
|
const args = [
|
|
49
49
|
'offline',
|
|
50
50
|
'--config',
|
|
@@ -107,7 +107,7 @@ describe('startCommand', () => {
|
|
|
107
107
|
await startCommand(options);
|
|
108
108
|
|
|
109
109
|
expect(spawn).toHaveBeenCalledWith(
|
|
110
|
-
'
|
|
110
|
+
'osls',
|
|
111
111
|
['offline', '--config', 'infrastructure.js', '--stage', 'prod'],
|
|
112
112
|
expect.objectContaining({
|
|
113
113
|
cwd: expect.any(String),
|
|
@@ -125,7 +125,7 @@ describe('startCommand', () => {
|
|
|
125
125
|
await startCommand(options);
|
|
126
126
|
|
|
127
127
|
expect(spawn).toHaveBeenCalledWith(
|
|
128
|
-
'
|
|
128
|
+
'osls',
|
|
129
129
|
['offline', '--config', 'infrastructure.js', '--stage', 'dev', '--verbose'],
|
|
130
130
|
expect.any(Object)
|
|
131
131
|
);
|
|
@@ -280,7 +280,7 @@ describe('startCommand', () => {
|
|
|
280
280
|
await startCommand({ stage: 'dev' });
|
|
281
281
|
|
|
282
282
|
expect(spawn).toHaveBeenCalledWith(
|
|
283
|
-
'
|
|
283
|
+
'osls',
|
|
284
284
|
expect.arrayContaining(['offline']),
|
|
285
285
|
expect.any(Object)
|
|
286
286
|
);
|
|
@@ -107,45 +107,38 @@ async function testDatabaseConnection(databaseUrl, dbType, timeout = 5000) {
|
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
109
|
* Checks if Prisma client is generated for the database type
|
|
110
|
-
*
|
|
110
|
+
* Checks for the generated client directory in @friggframework/core/generated
|
|
111
111
|
*
|
|
112
112
|
* @param {'mongodb'|'postgresql'} dbType - Database type
|
|
113
113
|
* @param {string} projectRoot - Project root directory (used for require.resolve context)
|
|
114
114
|
* @returns {Object} { generated: boolean, path?: string, error?: string }
|
|
115
115
|
*/
|
|
116
116
|
function checkPrismaClientGenerated(dbType, projectRoot = process.cwd()) {
|
|
117
|
-
const clientPackageName = `@prisma-${dbType}/client`;
|
|
118
|
-
|
|
119
117
|
try {
|
|
120
|
-
//
|
|
118
|
+
// Resolve where @friggframework/core actually is
|
|
121
119
|
// This handles file: dependencies and symlinks correctly
|
|
122
120
|
const corePackagePath = require.resolve('@friggframework/core', {
|
|
123
121
|
paths: [projectRoot]
|
|
124
122
|
});
|
|
125
123
|
const corePackageDir = path.dirname(corePackagePath);
|
|
126
124
|
|
|
127
|
-
//
|
|
128
|
-
const clientPath =
|
|
129
|
-
|
|
130
|
-
corePackageDir, // Look in the actual core package location
|
|
131
|
-
projectRoot // Fallback to project root
|
|
132
|
-
]
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
generated: true,
|
|
137
|
-
path: path.dirname(clientPath)
|
|
138
|
-
};
|
|
125
|
+
// Check for the generated client directory (same path core uses)
|
|
126
|
+
const clientPath = path.join(corePackageDir, 'generated', `prisma-${dbType}`);
|
|
127
|
+
const clientIndexPath = path.join(clientPath, 'index.js');
|
|
139
128
|
|
|
140
|
-
|
|
141
|
-
// require.resolve throws MODULE_NOT_FOUND if the client doesn't exist
|
|
142
|
-
if (error.code === 'MODULE_NOT_FOUND') {
|
|
129
|
+
if (fs.existsSync(clientIndexPath)) {
|
|
143
130
|
return {
|
|
144
|
-
generated:
|
|
145
|
-
|
|
131
|
+
generated: true,
|
|
132
|
+
path: clientPath
|
|
146
133
|
};
|
|
147
134
|
}
|
|
148
135
|
|
|
136
|
+
return {
|
|
137
|
+
generated: false,
|
|
138
|
+
error: `Prisma client for ${dbType} not found at ${clientPath}. Run 'frigg db:setup' to generate it.`
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
} catch (error) {
|
|
149
142
|
return {
|
|
150
143
|
generated: false,
|
|
151
144
|
error: `Failed to check Prisma client: ${error.message}`
|