@friggframework/devtools 2.0.0--canary.454.d57d533.0 → 2.0.0--canary.454.e2a280d.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.
@@ -3,7 +3,18 @@ const path = require('path');
3
3
 
4
4
  async function buildCommand(options) {
5
5
  console.log('Building the serverless application...');
6
-
6
+
7
+ // Suppress AWS SDK warning message about maintenance mode
8
+ process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE = '1';
9
+
10
+ // Skip AWS discovery for local builds (unless --production flag is set)
11
+ if (!options.production) {
12
+ process.env.FRIGG_SKIP_AWS_DISCOVERY = 'true';
13
+ console.log('🏠 Building in local mode (use --production flag for production builds with AWS discovery)');
14
+ } else {
15
+ console.log('🚀 Building in production mode with AWS discovery enabled');
16
+ }
17
+
7
18
  // AWS discovery is now handled directly in serverless-template.js
8
19
  console.log('📦 Packaging serverless application...');
9
20
  const backendPath = path.resolve(process.cwd());
@@ -37,6 +37,7 @@ program
37
37
  .description('Build the serverless application')
38
38
  .option('-s, --stage <stage>', 'deployment stage', 'dev')
39
39
  .option('-v, --verbose', 'enable verbose output')
40
+ .option('-p, --production', 'build for production (enables AWS discovery)')
40
41
  .action(buildCommand);
41
42
 
42
43
  program
@@ -8,12 +8,12 @@ Frigg Framework supports automatic provisioning of Amazon Aurora Serverless v2 P
8
8
 
9
9
  ### Key Features
10
10
 
11
- - **Aurora Serverless v2**: Cost-efficient auto-scaling database (0.5-1.0 ACU default)
12
- - **VPC Integration**: Deployed in same private subnets as Lambda functions
13
- - **Secrets Manager**: Automatic credential management and rotation
14
- - **Three Management Modes**: discover, create-new, use-existing
15
- - **Security**: Private subnet deployment with security group isolation
16
- - **High Availability**: Multi-AZ deployment with automatic failover
11
+ - **Aurora Serverless v2**: Cost-efficient auto-scaling database (0.5-1.0 ACU default)
12
+ - **VPC Integration**: Deployed in same private subnets as Lambda functions
13
+ - **Secrets Manager**: Automatic credential management and rotation
14
+ - **Three Management Modes**: discover, create-new, use-existing
15
+ - **Security**: Private subnet deployment with security group isolation
16
+ - **High Availability**: Multi-AZ deployment with automatic failover
17
17
 
18
18
  ---
19
19
 
@@ -49,8 +49,8 @@ const appDefinition = {
49
49
 
50
50
  // Scaling Configuration (Aurora Serverless v2)
51
51
  scaling: {
52
- minCapacity: 0.5, // ACUs (0.5 = ~1GB RAM, ~$43/month)
53
- maxCapacity: 1.0, // ACUs (1.0 = ~2GB RAM, ~$87/month)
52
+ minCapacity: 0.5, // ACUs (0.5 = ~1GB RAM, ~$43/month)
53
+ maxCapacity: 1.0, // ACUs (1.0 = ~2GB RAM, ~$87/month)
54
54
  },
55
55
 
56
56
  // Backup Configuration
@@ -64,8 +64,8 @@ const appDefinition = {
64
64
  // For use-existing mode
65
65
  clusterIdentifier: 'my-existing-cluster',
66
66
  secretArn: 'arn:aws:secretsmanager:...',
67
- }
68
- }
67
+ },
68
+ },
69
69
  };
70
70
 
71
71
  module.exports = {
@@ -91,6 +91,7 @@ database: {
91
91
  ```
92
92
 
93
93
  **Discovery Priority**:
94
+
94
95
  1. Frigg-managed cluster with matching service + stage tags
95
96
  2. Any Frigg-managed cluster
96
97
  3. First available Aurora PostgreSQL cluster
@@ -159,36 +160,42 @@ database: {
159
160
  When provisioning Aurora (`create-new` or `discover` mode without existing cluster), Frigg creates:
160
161
 
161
162
  ### 1. RDS DB Subnet Group
162
- - **Name**: `{service}-{stage}-db-subnet-group`
163
- - **Subnets**: Uses same private subnets as Lambda functions
164
- - **Purpose**: Defines which subnets Aurora can use
163
+
164
+ - **Name**: `{service}-{stage}-db-subnet-group`
165
+ - **Subnets**: Uses same private subnets as Lambda functions
166
+ - **Purpose**: Defines which subnets Aurora can use
165
167
 
166
168
  ### 2. Security Group
167
- - **Name**: `{service}-{stage}-aurora-sg`
168
- - **Ingress**: Port 5432 from Lambda security group
169
- - **Purpose**: Allows Lambda Aurora communication
169
+
170
+ - **Name**: `{service}-{stage}-aurora-sg`
171
+ - **Ingress**: Port 5432 from Lambda security group
172
+ - **Purpose**: Allows Lambda → Aurora communication
170
173
 
171
174
  ### 3. Secrets Manager Secret
172
- - **Name**: `{service}-{stage}-aurora-credentials`
173
- - **Contents**: `{ username, password }`
174
- - **Purpose**: Stores database credentials securely
175
- - **Rotation**: Automatic (optional, can be configured)
175
+
176
+ - **Name**: `{service}-{stage}-aurora-credentials`
177
+ - **Contents**: `{ username, password }`
178
+ - **Purpose**: Stores database credentials securely
179
+ - **Rotation**: Automatic (optional, can be configured)
176
180
 
177
181
  ### 4. Aurora Cluster
178
- - **Engine**: aurora-postgresql (version 15.3 default)
179
- - **Mode**: Provisioned (Serverless v2)
180
- - **Scaling**: 0.5-1.0 ACU (configurable)
181
- - **Backup**: 7-day retention (configurable)
182
- - **Multi-AZ**: Yes (high availability)
182
+
183
+ - **Engine**: aurora-postgresql (version 15.3 default)
184
+ - **Mode**: Provisioned (Serverless v2)
185
+ - **Scaling**: 0.5-1.0 ACU (configurable)
186
+ - **Backup**: 7-day retention (configurable)
187
+ - **Multi-AZ**: Yes (high availability)
183
188
 
184
189
  ### 5. Aurora Instance
185
- - **Class**: db.serverless
186
- - **Cluster**: Attached to cluster above
187
- - **Public Access**: No (private subnet only)
190
+
191
+ - **Class**: db.serverless
192
+ - **Cluster**: Attached to cluster above
193
+ - **Public Access**: No (private subnet only)
188
194
 
189
195
  ### 6. IAM Permissions
190
- - **Secrets Manager**: GetSecretValue, DescribeSecret
191
- - **Purpose**: Lambda functions can retrieve credentials
196
+
197
+ - **Secrets Manager**: GetSecretValue, DescribeSecret
198
+ - **Purpose**: Lambda functions can retrieve credentials
192
199
 
193
200
  ---
194
201
 
@@ -210,10 +217,11 @@ database: {
210
217
  ```
211
218
 
212
219
  **Estimated Monthly Costs**:
213
- - **Idle/Low Traffic**: $15-30/month (0.5 ACU minimum)
214
- - **Moderate Traffic**: $30-60/month (0.5-1.0 ACU average)
215
- - **Storage**: $0.10/GB-month
216
- - **Backup Storage**: Free (within retention period)
220
+
221
+ - **Idle/Low Traffic**: $15-30/month (0.5 ACU minimum)
222
+ - **Moderate Traffic**: $30-60/month (0.5-1.0 ACU average)
223
+ - **Storage**: $0.10/GB-month
224
+ - **Backup Storage**: Free (within retention period)
217
225
 
218
226
  ### Production Configuration
219
227
 
@@ -233,9 +241,10 @@ database: {
233
241
  ```
234
242
 
235
243
  **Estimated Monthly Costs**:
236
- - **Baseline**: $87/month (1.0 ACU minimum)
237
- - **Peak Traffic**: $348/month (4.0 ACU maximum)
238
- - **Performance Insights**: $7/month
244
+
245
+ - **Baseline**: $87/month (1.0 ACU minimum)
246
+ - **Peak Traffic**: $348/month (4.0 ACU maximum)
247
+ - **Performance Insights**: $7/month
239
248
 
240
249
  ### Cost-Saving Tips
241
250
 
@@ -251,16 +260,16 @@ database: {
251
260
 
252
261
  ### 1. Network Isolation
253
262
 
254
- - ✅ **Private Subnets Only**: Aurora deployed in private subnets (no internet access)
255
- - ✅ **Security Groups**: Restricts access to Lambda security group only
256
- - ✅ **VPC Endpoints**: Use VPC endpoints for AWS services (no NAT Gateway costs)
263
+ - ✅ **Private Subnets Only**: Aurora deployed in private subnets (no internet access)
264
+ - ✅ **Security Groups**: Restricts access to Lambda security group only
265
+ - ✅ **VPC Endpoints**: Use VPC endpoints for AWS services (no NAT Gateway costs)
257
266
 
258
267
  ### 2. Credential Management
259
268
 
260
- - ✅ **Secrets Manager**: Never hardcode database passwords
261
- - ✅ **Auto-Rotation**: Enable automatic secret rotation (recommended)
262
- - ✅ **IAM Integration**: Lambda uses IAM role to access secrets
263
- - ❌ **Never commit** `DATABASE_URL` to source control
269
+ - ✅ **Secrets Manager**: Never hardcode database passwords
270
+ - ✅ **Auto-Rotation**: Enable automatic secret rotation (recommended)
271
+ - ✅ **IAM Integration**: Lambda uses IAM role to access secrets
272
+ - ❌ **Never commit** `DATABASE_URL` to source control
264
273
 
265
274
  ### 3. Access Control
266
275
 
@@ -319,7 +328,7 @@ import { prismaClient } from '@friggframework/core/database/prisma';
319
328
  export async function handler(event, context) {
320
329
  // Prisma client uses DATABASE_URL automatically
321
330
  const result = await prismaClient.user.create({
322
- data: { email: 'user@example.com' }
331
+ data: { email: 'user@example.com' },
323
332
  });
324
333
 
325
334
  return { statusCode: 200, body: JSON.stringify(result) };
@@ -336,19 +345,19 @@ export async function handler(event, context) {
336
345
  # docker-compose.yml
337
346
  version: '3.8'
338
347
  services:
339
- postgres:
340
- image: postgres:15
341
- environment:
342
- POSTGRES_USER: frigg_admin
343
- POSTGRES_PASSWORD: local_password
344
- POSTGRES_DB: frigg_db
345
- ports:
346
- - "5432:5432"
347
- volumes:
348
- - postgres_data:/var/lib/postgresql/data
348
+ postgres:
349
+ image: postgres:15
350
+ environment:
351
+ POSTGRES_USER: frigg_admin
352
+ POSTGRES_PASSWORD: local_password
353
+ POSTGRES_DB: frigg_db
354
+ ports:
355
+ - '5432:5432'
356
+ volumes:
357
+ - postgres_data:/var/lib/postgresql/data
349
358
 
350
359
  volumes:
351
- postgres_data:
360
+ postgres_data:
352
361
  ```
353
362
 
354
363
  ```bash
@@ -374,79 +383,85 @@ DB_TYPE=postgresql
374
383
  ### From External PostgreSQL to Aurora
375
384
 
376
385
  1. **Backup Existing Database**
377
- ```bash
378
- pg_dump -h old-host -U user -d dbname > backup.sql
379
- ```
386
+
387
+ ```bash
388
+ pg_dump -h old-host -U user -d dbname > backup.sql
389
+ ```
380
390
 
381
391
  2. **Deploy Aurora Cluster**
382
- ```javascript
383
- // backend/index.js
384
- database: {
385
- postgres: {
386
- enable: true,
387
- management: 'create-new',
388
- }
389
- }
390
- ```
391
-
392
- ```bash
393
- npm run frigg:deploy
394
- ```
392
+
393
+ ```javascript
394
+ // backend/index.js
395
+ database: {
396
+ postgres: {
397
+ enable: true,
398
+ management: 'create-new',
399
+ }
400
+ }
401
+ ```
402
+
403
+ ```bash
404
+ npm run frigg:deploy
405
+ ```
395
406
 
396
407
  3. **Restore to Aurora**
397
- ```bash
398
- # Get Aurora endpoint from AWS console or deployment output
399
- psql -h aurora-endpoint.us-east-1.rds.amazonaws.com -U frigg_admin -d frigg_db < backup.sql
400
- ```
408
+
409
+ ```bash
410
+ # Get Aurora endpoint from AWS console or deployment output
411
+ psql -h aurora-endpoint.us-east-1.rds.amazonaws.com -U frigg_admin -d frigg_db < backup.sql
412
+ ```
401
413
 
402
414
  4. **Run Migrations**
403
- ```bash
404
- npm run frigg:db:setup
405
- ```
415
+ ```bash
416
+ npm run frigg:db:setup
417
+ ```
406
418
 
407
419
  ### From MongoDB to PostgreSQL
408
420
 
409
421
  1. **Add PostgreSQL Configuration**
410
- ```javascript
411
- database: {
412
- postgres: {
413
- enable: true,
414
- management: 'create-new',
415
- }
416
- }
417
- ```
422
+
423
+ ```javascript
424
+ database: {
425
+ postgres: {
426
+ enable: true,
427
+ management: 'create-new',
428
+ }
429
+ }
430
+ ```
418
431
 
419
432
  2. **Run Prisma Migrations**
420
- ```bash
421
- # Generate Prisma PostgreSQL client
422
- npm run frigg:db:setup
423
- ```
433
+
434
+ ```bash
435
+ # Generate Prisma PostgreSQL client
436
+ npm run frigg:db:setup
437
+ ```
424
438
 
425
439
  3. **Data Migration Script** (custom per application)
426
- ```javascript
427
- // migrate-data.js
428
- const { MongoClient } = require('mongodb');
429
- const { prismaClient } = require('@friggframework/core/database/prisma');
430
-
431
- async function migrate() {
432
- const mongo = await MongoClient.connect(process.env.MONGO_URI);
433
- const users = await mongo.db().collection('users').find().toArray();
434
-
435
- for (const user of users) {
436
- await prismaClient.user.create({
437
- data: {
438
- id: user._id.toString(),
439
- email: user.email,
440
- // ... map fields
441
- }
442
- });
443
- }
444
-
445
- await mongo.close();
446
- }
447
-
448
- migrate().catch(console.error);
449
- ```
440
+
441
+ ```javascript
442
+ // migrate-data.js
443
+ const { MongoClient } = require('mongodb');
444
+ const { prismaClient } = require('@friggframework/core/database/prisma');
445
+
446
+ async function migrate() {
447
+ const mongo = await MongoClient.connect(process.env.MONGO_URI);
448
+ const users = await mongo.db().collection('users').find().toArray();
449
+
450
+ for (const user of users) {
451
+ await prismaClient.user.create({
452
+ data: {
453
+ id: user._id.toString(),
454
+ email: user.email,
455
+ // ... map fields
456
+ },
457
+ });
458
+ }
459
+
460
+ await mongo.close();
461
+ }
462
+
463
+ migrate().catch(console.error);
464
+ ```
450
465
 
451
466
  ---
452
467
 
@@ -455,11 +470,13 @@ DB_TYPE=postgresql
455
470
  ### Issue: "No Aurora cluster found"
456
471
 
457
472
  **Error**:
473
+
458
474
  ```
459
475
  No Aurora cluster found in discovery mode. Set management to "create-new"...
460
476
  ```
461
477
 
462
478
  **Solution**:
479
+
463
480
  1. Check VPC is enabled: `vpc.enable: true`
464
481
  2. Set management mode: `management: 'create-new'`
465
482
  3. Or provide cluster identifier: `clusterIdentifier: 'my-cluster'`
@@ -471,20 +488,24 @@ No Aurora cluster found in discovery mode. Set management to "create-new"...
471
488
  **Symptoms**: Lambda functions timeout when connecting to Aurora
472
489
 
473
490
  **Possible Causes**:
491
+
474
492
  1. **Security Group Misconfiguration**
475
- - Check Lambda SG can access Aurora SG on port 5432
476
- - Verify Aurora SG allows inbound from Lambda SG
493
+
494
+ - Check Lambda SG can access Aurora SG on port 5432
495
+ - Verify Aurora SG allows inbound from Lambda SG
477
496
 
478
497
  2. **VPC/Subnet Issues**
479
- - Ensure Lambda and Aurora in same VPC
480
- - Verify Aurora in private subnets
481
- - Check route tables allow internal VPC traffic
498
+
499
+ - Ensure Lambda and Aurora in same VPC
500
+ - Verify Aurora in private subnets
501
+ - Check route tables allow internal VPC traffic
482
502
 
483
503
  3. **Secret Not Found**
484
- - Verify Secrets Manager secret exists
485
- - Check IAM role has secretsmanager:GetSecretValue permission
504
+ - Verify Secrets Manager secret exists
505
+ - Check IAM role has secretsmanager:GetSecretValue permission
486
506
 
487
507
  **Debug Steps**:
508
+
488
509
  ```bash
489
510
  # Check Aurora cluster status
490
511
  aws rds describe-db-clusters --db-cluster-identifier my-cluster
@@ -501,11 +522,13 @@ aws lambda invoke --function-name test-db-connection output.json
501
522
  ### Issue: "Insufficient capacity"
502
523
 
503
524
  **Error**:
525
+
504
526
  ```
505
527
  Cannot create Aurora cluster: InsufficientDBInstanceCapacity
506
528
  ```
507
529
 
508
530
  **Solution**:
531
+
509
532
  1. Try different availability zones
510
533
  2. Change instance class (though Serverless v2 shouldn't have this issue)
511
534
  3. Contact AWS support for capacity increase
@@ -517,26 +540,30 @@ Cannot create Aurora cluster: InsufficientDBInstanceCapacity
517
540
  **Symptoms**: Aurora costs higher than expected
518
541
 
519
542
  **Investigation**:
543
+
520
544
  1. **Check ACU Usage**:
521
- ```bash
522
- # CloudWatch metric: ServerlessDatabaseCapacity
523
- aws cloudwatch get-metric-statistics \
524
- --namespace AWS/RDS \
525
- --metric-name ServerlessDatabaseCapacity \
526
- --dimensions Name=DBClusterIdentifier,Value=my-cluster \
527
- --start-time 2024-01-01T00:00:00Z \
528
- --end-time 2024-01-02T00:00:00Z \
529
- --period 3600 \
530
- --statistics Average
531
- ```
545
+
546
+ ```bash
547
+ # CloudWatch metric: ServerlessDatabaseCapacity
548
+ aws cloudwatch get-metric-statistics \
549
+ --namespace AWS/RDS \
550
+ --metric-name ServerlessDatabaseCapacity \
551
+ --dimensions Name=DBClusterIdentifier,Value=my-cluster \
552
+ --start-time 2024-01-01T00:00:00Z \
553
+ --end-time 2024-01-02T00:00:00Z \
554
+ --period 3600 \
555
+ --statistics Average
556
+ ```
532
557
 
533
558
  2. **Review Scaling Configuration**:
534
- - Lower `maxCapacity` if traffic spikes are rare
535
- - Increase `minCapacity` only if cold starts are an issue
559
+
560
+ - Lower `maxCapacity` if traffic spikes are rare
561
+ - Increase `minCapacity` only if cold starts are an issue
536
562
 
537
563
  3. **Check for Long-Running Connections**:
538
- - Aurora doesn't scale down if connections are open
539
- - Review application connection pooling
564
+
565
+ - Aurora doesn't scale down if connections are open
566
+ - Review application connection pooling
540
567
 
541
568
  4. **Disable Performance Insights** in non-production
542
569
 
@@ -590,25 +617,13 @@ Frigg currently provisions a single Aurora instance. For read replicas:
590
617
 
591
618
  ## Reference
592
619
 
593
- ### Aurora Serverless v2 ACU Sizing
594
-
595
- | ACUs | RAM | Approx Monthly Cost | Use Case |
596
- |------|-------|---------------------|-----------------------------|
597
- | 0.5 | 1 GB | $43 | Development, low traffic |
598
- | 1.0 | 2 GB | $87 | Staging, moderate traffic |
599
- | 2.0 | 4 GB | $174 | Production, steady traffic |
600
- | 4.0 | 8 GB | $348 | Production, high traffic |
601
- | 8.0 | 16 GB | $696 | Production, very high traffic|
602
-
603
- **Note**: Costs as of 2024, us-east-1 region. Check current pricing at [AWS Pricing](https://aws.amazon.com/rds/aurora/pricing/).
604
-
605
620
  ### Supported PostgreSQL Versions
606
621
 
607
- - 15.3 (recommended, default)
608
- - 15.2
609
- - 14.6
610
- - 14.5
611
- - 13.9
622
+ - 15.3 (recommended, default)
623
+ - 15.2
624
+ - 14.6
625
+ - 14.5
626
+ - 13.9
612
627
 
613
628
  Check [Aurora PostgreSQL Releases](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Updates.html) for latest versions.
614
629
 
@@ -616,15 +631,15 @@ Check [Aurora PostgreSQL Releases](https://docs.aws.amazon.com/AmazonRDS/latest/
616
631
 
617
632
  ## Related Documentation
618
633
 
619
- - [VPC Configuration Guide](VPC-CONFIGURATION.md)
620
- - [Secrets Manager Integration](SECRETS-MANAGER.md)
621
- - [Database Migrations](../frigg-cli/DB-SETUP.md)
622
- - [AWS Discovery Troubleshooting](AWS-DISCOVERY-TROUBLESHOOTING.md)
634
+ - [VPC Configuration Guide](VPC-CONFIGURATION.md)
635
+ - [Secrets Manager Integration](SECRETS-MANAGER.md)
636
+ - [Database Migrations](../frigg-cli/DB-SETUP.md)
637
+ - [AWS Discovery Troubleshooting](AWS-DISCOVERY-TROUBLESHOOTING.md)
623
638
 
624
639
  ---
625
640
 
626
641
  ## Support
627
642
 
628
- - **Issues**: [GitHub Issues](https://github.com/friggframework/frigg/issues)
629
- - **Documentation**: [Frigg Framework Docs](https://docs.friggframework.org)
630
- - **Community**: [Slack Channel](https://friggframework.org/#contact)
643
+ - **Issues**: [GitHub Issues](https://github.com/friggframework/frigg/issues)
644
+ - **Documentation**: [Frigg Framework Docs](https://docs.friggframework.org)
645
+ - **Community**: [Slack Channel](https://friggframework.org/#contact)
@@ -24,11 +24,33 @@ const fs = require('fs-extra');
24
24
  const path = require('path');
25
25
  const { execSync } = require('child_process');
26
26
 
27
+ /**
28
+ * Find @friggframework/core package, handling workspace hoisting
29
+ * Searches up the directory tree to find node_modules/@friggframework/core
30
+ */
31
+ function findCorePackage(startDir) {
32
+ let currentDir = startDir;
33
+ const root = path.parse(currentDir).root;
34
+
35
+ while (currentDir !== root) {
36
+ const candidatePath = path.join(currentDir, 'node_modules/@friggframework/core');
37
+ if (fs.existsSync(candidatePath)) {
38
+ return candidatePath;
39
+ }
40
+ currentDir = path.dirname(currentDir);
41
+ }
42
+
43
+ throw new Error(
44
+ '@friggframework/core not found in node_modules.\n' +
45
+ 'Run "npm install" to install dependencies.'
46
+ );
47
+ }
48
+
27
49
  // Configuration
28
50
  // Script runs from integration project root (e.g., backend/)
29
51
  // and reads Prisma packages from @friggframework/core
30
52
  const PROJECT_ROOT = process.cwd();
31
- const CORE_PACKAGE_PATH = path.join(PROJECT_ROOT, 'node_modules/@friggframework/core');
53
+ const CORE_PACKAGE_PATH = findCorePackage(PROJECT_ROOT);
32
54
  const LAYER_OUTPUT_PATH = path.join(PROJECT_ROOT, 'layers/prisma');
33
55
  const LAYER_NODE_MODULES = path.join(LAYER_OUTPUT_PATH, 'nodejs/node_modules');
34
56
 
@@ -123,13 +145,18 @@ async function createLayerStructure() {
123
145
  async function copyPrismaPackages() {
124
146
  logStep(3, 'Copying Prisma packages from @friggframework/core');
125
147
 
126
- // Prisma packages can be in different locations:
127
- // 1. Standard npm packages (@prisma/client, prisma): in node_modules
128
- // 2. Generated clients (generated/*): in @friggframework/core package itself
148
+ // Build search paths, handling workspace hoisting
149
+ // Packages can be in:
150
+ // 1. Core's own node_modules (if not hoisted)
151
+ // 2. Project root node_modules (if hoisted from project)
152
+ // 3. Workspace root node_modules (where core is located - handles hoisting)
153
+ // 4. Core package itself (for generated/ directories)
154
+ const workspaceNodeModules = path.join(path.dirname(CORE_PACKAGE_PATH), '..');
129
155
  const searchPaths = [
130
156
  path.join(CORE_PACKAGE_PATH, 'node_modules'), // Core's own node_modules
131
- path.join(PROJECT_ROOT, 'node_modules'), // Project root node_modules
132
- CORE_PACKAGE_PATH, // Core package itself (for generated/ dirs)
157
+ path.join(PROJECT_ROOT, 'node_modules'), // Project node_modules
158
+ workspaceNodeModules, // Workspace root node_modules
159
+ CORE_PACKAGE_PATH, // Core package itself (for generated/)
133
160
  ];
134
161
 
135
162
  let copiedCount = 0;
@@ -160,7 +187,7 @@ async function copyPrismaPackages() {
160
187
  ? 'core package (generated)'
161
188
  : sourcePath.includes('@friggframework/core/node_modules')
162
189
  ? 'core node_modules'
163
- : 'project root';
190
+ : 'workspace';
164
191
  logSuccess(`Copied ${pkg} (from ${fromLocation})`);
165
192
  copiedCount++;
166
193
  } else {
@@ -526,20 +526,42 @@ const createBaseDefinition = (AppDefinition, appEnvironmentVars, discoveredResou
526
526
  package: {
527
527
  individually: true,
528
528
  patterns: [
529
- // Existing AWS SDK exclusions
529
+ // AWS SDK exclusions (already in Lambda runtime)
530
530
  '!**/node_modules/aws-sdk/**',
531
531
  '!**/node_modules/@aws-sdk/**',
532
- '!package.json',
533
-
534
- // GLOBAL Prisma exclusions - all Prisma packages moved to Lambda Layer
535
- // This reduces each function from ~120MB to ~45MB (60% reduction)
536
- '!node_modules/@prisma/**',
537
- '!node_modules/.prisma/**',
538
- '!node_modules/@prisma-mongodb/**',
539
- '!node_modules/@prisma-postgresql/**',
540
- '!node_modules/prisma/**',
541
- // Prisma packages will be provided at runtime via Lambda Layer
542
- // See: LAMBDA-LAYER-PRISMA.md for complete documentation
532
+
533
+ // Prisma exclusions (provided via Lambda Layer)
534
+ '!**/node_modules/@prisma/**',
535
+ '!**/node_modules/.prisma/**',
536
+ '!**/node_modules/@prisma-mongodb/**',
537
+ '!**/node_modules/@prisma-postgresql/**',
538
+ '!**/node_modules/prisma/**',
539
+
540
+ // Exclude Prisma generated clients from @friggframework/core
541
+ // These are 81MB and provided via Lambda Layer instead
542
+ '!**/node_modules/@friggframework/core/generated/**',
543
+
544
+ // Exclude development and test files
545
+ '!**/test/**',
546
+ '!**/tests/**',
547
+ '!**/*.test.js',
548
+ '!**/*.spec.js',
549
+ '!**/*.map',
550
+ '!**/jest.config.js',
551
+ '!**/jest.unit.config.js',
552
+ '!**/.eslintrc.json',
553
+ '!**/.prettierrc',
554
+ '!**/.prettierignore',
555
+ '!**/.markdownlintignore',
556
+ '!**/docker-compose.yml',
557
+ '!**/package.json',
558
+ '!**/README.md',
559
+ '!**/*.md',
560
+
561
+ // Exclude .DS_Store and other OS files
562
+ '!**/.DS_Store',
563
+ '!**/.git/**',
564
+ '!**/.claude-flow/**',
543
565
  ],
544
566
  },
545
567
  useDotenv: true,
@@ -584,7 +606,8 @@ const createBaseDefinition = (AppDefinition, appEnvironmentVars, discoveredResou
584
606
  },
585
607
  },
586
608
  plugins: [
587
- 'serverless-jetpack',
609
+ // Temporarily disabled Jetpack - it ignores package.patterns in dependency mode
610
+ // 'serverless-jetpack',
588
611
  'serverless-dotenv-plugin',
589
612
  'serverless-offline-sqs',
590
613
  'serverless-offline',
@@ -605,9 +628,10 @@ const createBaseDefinition = (AppDefinition, appEnvironmentVars, discoveredResou
605
628
  secretAccessKey: 'root',
606
629
  skipCacheInvalidation: false,
607
630
  },
608
- jetpack: {
609
- base: '..',
610
- },
631
+ // Jetpack config removed - testing with standard Serverless packaging
632
+ // jetpack: {
633
+ // base: '..',
634
+ // },
611
635
  },
612
636
  functions: {
613
637
  auth: {
@@ -774,7 +798,7 @@ const applyKmsConfiguration = (definition, AppDefinition, discoveredResources) =
774
798
  if (AppDefinition.encryption?.createResourceIfNoneFound !== true) {
775
799
  throw new Error(
776
800
  'KMS field-level encryption is enabled but no KMS key was found. ' +
777
- 'Either provide an existing KMS key or set encryption.createResourceIfNoneFound to true to create a new key.'
801
+ 'Either provide an existing KMS key or set encryption.createResourceIfNoneFound to true to create a new key.'
778
802
  );
779
803
  }
780
804
 
@@ -1173,8 +1197,8 @@ const configureVpc = (definition, AppDefinition, discoveredResources) => {
1173
1197
  AppDefinition.vpc.subnets?.ids?.length > 0
1174
1198
  ? AppDefinition.vpc.subnets.ids
1175
1199
  : discoveredResources.privateSubnetId1 && discoveredResources.privateSubnetId2
1176
- ? [discoveredResources.privateSubnetId1, discoveredResources.privateSubnetId2]
1177
- : [];
1200
+ ? [discoveredResources.privateSubnetId1, discoveredResources.privateSubnetId2]
1201
+ : [];
1178
1202
 
1179
1203
  if (vpcConfig.subnetIds.length < 2) {
1180
1204
  if (AppDefinition.vpc.selfHeal) {
@@ -2032,10 +2056,23 @@ const composeServerlessDefinition = async (AppDefinition) => {
2032
2056
  const appEnvironmentVars = getAppEnvironmentVars(AppDefinition);
2033
2057
  const definition = createBaseDefinition(AppDefinition, appEnvironmentVars, discoveredResources);
2034
2058
 
2035
- applyKmsConfiguration(definition, AppDefinition, discoveredResources);
2036
- configureVpc(definition, AppDefinition, discoveredResources);
2037
- configurePostgres(definition, AppDefinition, discoveredResources);
2038
- configureSsm(definition, AppDefinition);
2059
+ // Check if we're in local build mode (AWS discovery was skipped)
2060
+ const isLocalBuild = !shouldRunDiscovery(AppDefinition);
2061
+
2062
+ if (isLocalBuild) {
2063
+ console.log('🏠 Local build mode detected - skipping AWS-dependent configurations');
2064
+ }
2065
+
2066
+ // Apply configurations (skip AWS-dependent ones in local build mode)
2067
+ if (!isLocalBuild) {
2068
+ applyKmsConfiguration(definition, AppDefinition, discoveredResources);
2069
+ configureVpc(definition, AppDefinition, discoveredResources);
2070
+ configurePostgres(definition, AppDefinition, discoveredResources);
2071
+ configureSsm(definition, AppDefinition);
2072
+ } else {
2073
+ console.log(' ⏭️ Skipping: KMS, VPC, PostgreSQL, SSM configurations');
2074
+ }
2075
+
2039
2076
  attachIntegrations(definition, AppDefinition);
2040
2077
  configureWebsockets(definition, AppDefinition);
2041
2078
 
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.454.d57d533.0",
4
+ "version": "2.0.0--canary.454.e2a280d.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-ec2": "^3.835.0",
7
7
  "@aws-sdk/client-kms": "^3.835.0",
@@ -11,8 +11,8 @@
11
11
  "@babel/eslint-parser": "^7.18.9",
12
12
  "@babel/parser": "^7.25.3",
13
13
  "@babel/traverse": "^7.25.3",
14
- "@friggframework/schemas": "2.0.0--canary.454.d57d533.0",
15
- "@friggframework/test": "2.0.0--canary.454.d57d533.0",
14
+ "@friggframework/schemas": "2.0.0--canary.454.e2a280d.0",
15
+ "@friggframework/test": "2.0.0--canary.454.e2a280d.0",
16
16
  "@hapi/boom": "^10.0.1",
17
17
  "@inquirer/prompts": "^5.3.8",
18
18
  "axios": "^1.7.2",
@@ -34,8 +34,8 @@
34
34
  "serverless-http": "^2.7.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@friggframework/eslint-config": "2.0.0--canary.454.d57d533.0",
38
- "@friggframework/prettier-config": "2.0.0--canary.454.d57d533.0",
37
+ "@friggframework/eslint-config": "2.0.0--canary.454.e2a280d.0",
38
+ "@friggframework/prettier-config": "2.0.0--canary.454.e2a280d.0",
39
39
  "aws-sdk-client-mock": "^4.1.0",
40
40
  "aws-sdk-client-mock-jest": "^4.1.0",
41
41
  "jest": "^30.1.3",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "d57d533f4b0408aa33177c61a360d228159251bc"
73
+ "gitHead": "e2a280d643ad826ce11b8267c98eba09d89d4dfd"
74
74
  }