@friggframework/devtools 2.0.0--canary.461.ec909cf.0 → 2.0.0--canary.461.7b36f0f.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.
Files changed (70) hide show
  1. package/frigg-cli/__tests__/unit/commands/build.test.js +6 -6
  2. package/frigg-cli/build-command/index.js +1 -1
  3. package/frigg-cli/deploy-command/index.js +6 -6
  4. package/frigg-cli/generate-command/index.js +2 -2
  5. package/frigg-cli/generate-iam-command.js +10 -10
  6. package/frigg-cli/start-command/index.js +1 -1
  7. package/frigg-cli/start-command/start-command.test.js +3 -3
  8. package/frigg-cli/utils/database-validator.js +14 -21
  9. package/infrastructure/REFACTOR.md +532 -0
  10. package/infrastructure/TRANSFORMATION-VISUAL.md +239 -0
  11. package/infrastructure/__tests__/postgres-config.test.js +1 -1
  12. package/infrastructure/create-frigg-infrastructure.js +1 -1
  13. package/infrastructure/{DEPLOYMENT-INSTRUCTIONS.md → docs/deployment-instructions.md} +3 -3
  14. package/infrastructure/{IAM-POLICY-TEMPLATES.md → docs/iam-policy-templates.md} +9 -10
  15. package/infrastructure/domains/database/aurora-discovery.js +81 -0
  16. package/infrastructure/domains/database/aurora-discovery.test.js +188 -0
  17. package/infrastructure/domains/integration/integration-builder.js +178 -0
  18. package/infrastructure/domains/integration/integration-builder.test.js +362 -0
  19. package/infrastructure/domains/integration/websocket-builder.js +69 -0
  20. package/infrastructure/domains/integration/websocket-builder.test.js +195 -0
  21. package/infrastructure/domains/networking/vpc-discovery.test.js +257 -0
  22. package/infrastructure/domains/parameters/ssm-builder.js +79 -0
  23. package/infrastructure/domains/parameters/ssm-builder.test.js +188 -0
  24. package/infrastructure/domains/parameters/ssm-discovery.js +84 -0
  25. package/infrastructure/domains/parameters/ssm-discovery.test.js +210 -0
  26. package/infrastructure/{iam-generator.js → domains/security/iam-generator.js} +2 -2
  27. package/infrastructure/domains/security/kms-builder.js +169 -0
  28. package/infrastructure/domains/security/kms-builder.test.js +354 -0
  29. package/infrastructure/domains/security/kms-discovery.js +80 -0
  30. package/infrastructure/domains/security/kms-discovery.test.js +176 -0
  31. package/infrastructure/domains/shared/base-builder.js +112 -0
  32. package/infrastructure/domains/shared/builder-orchestrator.js +212 -0
  33. package/infrastructure/domains/shared/builder-orchestrator.test.js +213 -0
  34. package/infrastructure/domains/shared/environment-builder.js +118 -0
  35. package/infrastructure/domains/shared/environment-builder.test.js +246 -0
  36. package/infrastructure/domains/shared/providers/aws-provider-adapter.test.js +366 -0
  37. package/infrastructure/domains/shared/providers/azure-provider-adapter.stub.js +93 -0
  38. package/infrastructure/domains/shared/providers/cloud-provider-adapter.js +136 -0
  39. package/infrastructure/domains/shared/providers/gcp-provider-adapter.stub.js +82 -0
  40. package/infrastructure/domains/shared/providers/provider-factory.js +108 -0
  41. package/infrastructure/domains/shared/providers/provider-factory.test.js +170 -0
  42. package/infrastructure/domains/shared/resource-discovery.js +132 -0
  43. package/infrastructure/domains/shared/resource-discovery.test.js +410 -0
  44. package/infrastructure/domains/shared/utilities/base-definition-factory.js.bak +338 -0
  45. package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +248 -0
  46. package/infrastructure/domains/shared/utilities/handler-path-resolver.test.js +259 -0
  47. package/infrastructure/domains/shared/utilities/prisma-layer-manager.js +55 -0
  48. package/infrastructure/domains/shared/utilities/prisma-layer-manager.test.js +134 -0
  49. package/infrastructure/domains/shared/validation/env-validator.test.js +173 -0
  50. package/infrastructure/esbuild.config.js +53 -0
  51. package/infrastructure/infrastructure-composer.js +85 -0
  52. package/infrastructure/scripts/build-prisma-layer.js +60 -47
  53. package/infrastructure/{build-time-discovery.test.js → scripts/build-time-discovery.test.js} +5 -4
  54. package/layers/prisma/nodejs/package.json +8 -0
  55. package/management-ui/server/utils/environment/awsParameterStore.js +29 -18
  56. package/package.json +8 -8
  57. package/infrastructure/aws-discovery.js +0 -1704
  58. package/infrastructure/aws-discovery.test.js +0 -1666
  59. package/infrastructure/serverless-template.js +0 -2804
  60. package/infrastructure/serverless-template.test.js +0 -1897
  61. /package/infrastructure/{POSTGRES-CONFIGURATION.md → docs/POSTGRES-CONFIGURATION.md} +0 -0
  62. /package/infrastructure/{WEBSOCKET-CONFIGURATION.md → docs/WEBSOCKET-CONFIGURATION.md} +0 -0
  63. /package/infrastructure/{GENERATE-IAM-DOCS.md → docs/generate-iam-command.md} +0 -0
  64. /package/infrastructure/{iam-generator.test.js → domains/security/iam-generator.test.js} +0 -0
  65. /package/infrastructure/{frigg-deployment-iam-stack.yaml → domains/security/templates/frigg-deployment-iam-stack.yaml} +0 -0
  66. /package/infrastructure/{iam-policy-basic.json → domains/security/templates/iam-policy-basic.json} +0 -0
  67. /package/infrastructure/{iam-policy-full.json → domains/security/templates/iam-policy-full.json} +0 -0
  68. /package/infrastructure/{env-validator.js → domains/shared/validation/env-validator.js} +0 -0
  69. /package/infrastructure/{build-time-discovery.js → scripts/build-time-discovery.js} +0 -0
  70. /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
- 'serverless',
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
- 'serverless',
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
- 'serverless',
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
- 'serverless',
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
- 'serverless',
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('serverless');
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 = 'serverless';
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 = 'serverless';
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
- 'serverless',
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
- 'serverless',
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
- 'serverless',
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
- * Uses require.resolve to find the client in node_modules
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
- // First, resolve where @friggframework/core actually is
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
- // Now look for the Prisma client within the resolved core package
128
- const clientPath = require.resolve(clientPackageName, {
129
- paths: [
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
- } catch (error) {
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: false,
145
- error: `Prisma client for ${dbType} (${clientPackageName}) not found. Run 'frigg db:setup' to generate it.`
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}`