create-chaaskit 0.1.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 (122) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +25 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/add-infra.d.ts +6 -0
  6. package/dist/commands/add-infra.d.ts.map +1 -0
  7. package/dist/commands/add-infra.js +160 -0
  8. package/dist/commands/add-infra.js.map +1 -0
  9. package/dist/commands/build.d.ts +2 -0
  10. package/dist/commands/build.d.ts.map +1 -0
  11. package/dist/commands/build.js +63 -0
  12. package/dist/commands/build.js.map +1 -0
  13. package/dist/commands/db-sync.d.ts +13 -0
  14. package/dist/commands/db-sync.d.ts.map +1 -0
  15. package/dist/commands/db-sync.js +108 -0
  16. package/dist/commands/db-sync.js.map +1 -0
  17. package/dist/commands/dev.d.ts +7 -0
  18. package/dist/commands/dev.d.ts.map +1 -0
  19. package/dist/commands/dev.js +61 -0
  20. package/dist/commands/dev.js.map +1 -0
  21. package/dist/commands/init.d.ts +9 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +214 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +57 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/templates/.env.example +24 -0
  30. package/dist/templates/README.md +81 -0
  31. package/dist/templates/app/components/AcceptInviteClient.tsx +10 -0
  32. package/dist/templates/app/components/AdminDashboardClient.tsx +10 -0
  33. package/dist/templates/app/components/AdminTeamClient.tsx +10 -0
  34. package/dist/templates/app/components/AdminTeamsClient.tsx +10 -0
  35. package/dist/templates/app/components/AdminUsersClient.tsx +10 -0
  36. package/dist/templates/app/components/ApiKeysClient.tsx +10 -0
  37. package/dist/templates/app/components/AutomationsClient.tsx +10 -0
  38. package/dist/templates/app/components/ChatClient.tsx +13 -0
  39. package/dist/templates/app/components/ClientOnly.tsx +6 -0
  40. package/dist/templates/app/components/DocumentsClient.tsx +10 -0
  41. package/dist/templates/app/components/OAuthConsentClient.tsx +10 -0
  42. package/dist/templates/app/components/PricingClient.tsx +10 -0
  43. package/dist/templates/app/components/TeamSettingsClient.tsx +10 -0
  44. package/dist/templates/app/components/VerifyEmailClient.tsx +10 -0
  45. package/dist/templates/app/entry.client.tsx +12 -0
  46. package/dist/templates/app/entry.server.tsx +67 -0
  47. package/dist/templates/app/root.tsx +91 -0
  48. package/dist/templates/app/routes/_index.tsx +82 -0
  49. package/dist/templates/app/routes/admin._index.tsx +57 -0
  50. package/dist/templates/app/routes/admin.teams.$teamId.tsx +57 -0
  51. package/dist/templates/app/routes/admin.teams._index.tsx +57 -0
  52. package/dist/templates/app/routes/admin.users.tsx +57 -0
  53. package/dist/templates/app/routes/api-keys.tsx +57 -0
  54. package/dist/templates/app/routes/automations.tsx +57 -0
  55. package/dist/templates/app/routes/chat._index.tsx +11 -0
  56. package/dist/templates/app/routes/chat.admin._index.tsx +10 -0
  57. package/dist/templates/app/routes/chat.admin.teams.$teamId.tsx +10 -0
  58. package/dist/templates/app/routes/chat.admin.teams._index.tsx +10 -0
  59. package/dist/templates/app/routes/chat.admin.users.tsx +10 -0
  60. package/dist/templates/app/routes/chat.api-keys.tsx +10 -0
  61. package/dist/templates/app/routes/chat.automations.tsx +10 -0
  62. package/dist/templates/app/routes/chat.documents.tsx +10 -0
  63. package/dist/templates/app/routes/chat.team.$teamId.settings.tsx +10 -0
  64. package/dist/templates/app/routes/chat.thread.$threadId.tsx +11 -0
  65. package/dist/templates/app/routes/chat.tsx +39 -0
  66. package/dist/templates/app/routes/documents.tsx +57 -0
  67. package/dist/templates/app/routes/invite.$token.tsx +10 -0
  68. package/dist/templates/app/routes/login.tsx +334 -0
  69. package/dist/templates/app/routes/oauth.consent.tsx +10 -0
  70. package/dist/templates/app/routes/pricing.tsx +10 -0
  71. package/dist/templates/app/routes/privacy.tsx +197 -0
  72. package/dist/templates/app/routes/register.tsx +398 -0
  73. package/dist/templates/app/routes/shared.$shareId.tsx +226 -0
  74. package/dist/templates/app/routes/team.$teamId.settings.tsx +57 -0
  75. package/dist/templates/app/routes/terms.tsx +173 -0
  76. package/dist/templates/app/routes/thread.$threadId.tsx +102 -0
  77. package/dist/templates/app/routes/verify-email.tsx +10 -0
  78. package/dist/templates/app/routes.ts +47 -0
  79. package/dist/templates/config/app.config.ts +216 -0
  80. package/dist/templates/docs/admin.md +257 -0
  81. package/dist/templates/docs/api-keys.md +403 -0
  82. package/dist/templates/docs/authentication.md +247 -0
  83. package/dist/templates/docs/configuration.md +1212 -0
  84. package/dist/templates/docs/custom-pages.md +466 -0
  85. package/dist/templates/docs/deployment.md +362 -0
  86. package/dist/templates/docs/development.md +411 -0
  87. package/dist/templates/docs/documents.md +293 -0
  88. package/dist/templates/docs/extensions.md +639 -0
  89. package/dist/templates/docs/index.md +139 -0
  90. package/dist/templates/docs/installation.md +286 -0
  91. package/dist/templates/docs/mcp.md +952 -0
  92. package/dist/templates/docs/native-tools.md +688 -0
  93. package/dist/templates/docs/queue.md +514 -0
  94. package/dist/templates/docs/scheduled-prompts.md +279 -0
  95. package/dist/templates/docs/settings.md +415 -0
  96. package/dist/templates/docs/slack.md +318 -0
  97. package/dist/templates/docs/styling.md +288 -0
  98. package/dist/templates/extensions/agents/.gitkeep +0 -0
  99. package/dist/templates/extensions/pages/.gitkeep +0 -0
  100. package/dist/templates/extensions/payment-plans/.gitkeep +0 -0
  101. package/dist/templates/index.html +16 -0
  102. package/dist/templates/infra-aws/.github/workflows/deploy.yml +95 -0
  103. package/dist/templates/infra-aws/README.md +207 -0
  104. package/dist/templates/infra-aws/bin/cdk.ts +18 -0
  105. package/dist/templates/infra-aws/cdk.json +43 -0
  106. package/dist/templates/infra-aws/config/deployment.ts +156 -0
  107. package/dist/templates/infra-aws/lib/chaaskit-stack.ts +419 -0
  108. package/dist/templates/infra-aws/package.json +27 -0
  109. package/dist/templates/infra-aws/scripts/build-app.sh +63 -0
  110. package/dist/templates/infra-aws/tsconfig.json +25 -0
  111. package/dist/templates/package.json +46 -0
  112. package/dist/templates/prisma/schema/base.prisma +584 -0
  113. package/dist/templates/prisma/schema/custom.prisma +24 -0
  114. package/dist/templates/prisma/schema.prisma +271 -0
  115. package/dist/templates/public/favicon.svg +4 -0
  116. package/dist/templates/public/logo.svg +4 -0
  117. package/dist/templates/react-router.config.ts +11 -0
  118. package/dist/templates/server.js +52 -0
  119. package/dist/templates/src/main.tsx +8 -0
  120. package/dist/templates/tsconfig.json +26 -0
  121. package/dist/templates/vite.config.ts +26 -0
  122. package/package.json +46 -0
@@ -0,0 +1,419 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
3
+ import * as rds from 'aws-cdk-lib/aws-rds';
4
+ import * as s3 from 'aws-cdk-lib/aws-s3';
5
+ import * as iam from 'aws-cdk-lib/aws-iam';
6
+ import * as elasticbeanstalk from 'aws-cdk-lib/aws-elasticbeanstalk';
7
+ import * as s3assets from 'aws-cdk-lib/aws-s3-assets';
8
+ import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
9
+ import { Construct } from 'constructs';
10
+ import * as path from 'path';
11
+ import { DeploymentConfig } from '../config/deployment';
12
+
13
+ export interface ChaaskitStackProps extends cdk.StackProps {
14
+ stage: string;
15
+ config: DeploymentConfig;
16
+ }
17
+
18
+ export class ChaaskitStack extends cdk.Stack {
19
+ constructor(scope: Construct, id: string, props: ChaaskitStackProps) {
20
+ super(scope, id, props);
21
+
22
+ const { stage, config } = props;
23
+
24
+ // Get or create VPC
25
+ const vpc = this.getOrCreateVpc(config, stage);
26
+
27
+ // S3 Bucket for internal storage (file uploads, etc.)
28
+ const bucket = new s3.Bucket(this, 'InternalBucket', {
29
+ bucketName: `${config.serviceName}-${stage}-internal`,
30
+ removalPolicy: stage === 'prod'
31
+ ? cdk.RemovalPolicy.RETAIN
32
+ : cdk.RemovalPolicy.DESTROY,
33
+ autoDeleteObjects: stage !== 'prod',
34
+ encryption: s3.BucketEncryption.S3_MANAGED,
35
+ blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
36
+ });
37
+
38
+ // Get or create database
39
+ const { dbSecretArn, dbSecurityGroup } = this.getOrCreateDatabase(config, stage, vpc);
40
+
41
+ // IAM Role for Elastic Beanstalk EC2 instances
42
+ const ebRole = new iam.Role(this, 'EBInstanceRole', {
43
+ assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
44
+ managedPolicies: [
45
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AWSElasticBeanstalkWebTier'),
46
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AWSElasticBeanstalkWorkerTier'),
47
+ ],
48
+ });
49
+
50
+ // Grant permissions
51
+ bucket.grantReadWrite(ebRole);
52
+
53
+ // Grant access to the database secret
54
+ if (dbSecretArn) {
55
+ // Use fromSecretPartialArn to handle secrets without the 6-character suffix
56
+ const dbSecret = secretsmanager.Secret.fromSecretPartialArn(this, 'DbSecret', dbSecretArn);
57
+ dbSecret.grantRead(ebRole);
58
+ }
59
+
60
+ // Instance profile for EB
61
+ const instanceProfile = new iam.CfnInstanceProfile(this, 'EBInstanceProfile', {
62
+ roles: [ebRole.roleName],
63
+ });
64
+
65
+ // Elastic Beanstalk Application
66
+ const app = new elasticbeanstalk.CfnApplication(this, 'App', {
67
+ applicationName: `${config.serviceName}-${stage}`,
68
+ });
69
+
70
+ // Application Version from S3 asset
71
+ const appAsset = new s3assets.Asset(this, 'AppAsset', {
72
+ path: path.join(__dirname, `../../app-${config.buildVersion}.zip`),
73
+ });
74
+ appAsset.grantRead(ebRole);
75
+
76
+ const appVersion = new elasticbeanstalk.CfnApplicationVersion(this, 'AppVersion', {
77
+ applicationName: app.applicationName!,
78
+ sourceBundle: {
79
+ s3Bucket: appAsset.s3BucketName,
80
+ s3Key: appAsset.s3ObjectKey,
81
+ },
82
+ });
83
+ appVersion.addDependency(app);
84
+
85
+ // Build option settings based on configuration
86
+ const optionSettings = this.buildOptionSettings(config, stage, bucket, dbSecretArn, vpc, instanceProfile, dbSecurityGroup);
87
+
88
+ // Elastic Beanstalk Environment
89
+ const environment = new elasticbeanstalk.CfnEnvironment(this, 'Environment', {
90
+ applicationName: app.applicationName!,
91
+ environmentName: `${config.serviceName}-${stage}`,
92
+ solutionStackName: '64bit Amazon Linux 2023 v6.4.1 running Node.js 22',
93
+ versionLabel: appVersion.ref,
94
+ optionSettings,
95
+ });
96
+ environment.addDependency(appVersion);
97
+
98
+ // Outputs
99
+ new cdk.CfnOutput(this, 'EnvironmentUrl', {
100
+ value: config.balancerType === 'shared' && config.sharedAlb
101
+ ? `https://${config.sharedAlb.hostHeaders[0]}`
102
+ : `http://${environment.attrEndpointUrl}`,
103
+ description: 'Application URL',
104
+ });
105
+
106
+ new cdk.CfnOutput(this, 'BucketName', {
107
+ value: bucket.bucketName,
108
+ description: 'S3 bucket for internal storage',
109
+ });
110
+
111
+ if (dbSecretArn) {
112
+ new cdk.CfnOutput(this, 'DatabaseSecretArn', {
113
+ value: dbSecretArn,
114
+ description: 'ARN of the database credentials secret',
115
+ });
116
+ }
117
+ }
118
+
119
+ private getOrCreateVpc(config: DeploymentConfig, stage: string): ec2.IVpc {
120
+ if (config.existingVpc) {
121
+ // Use existing VPC
122
+ return ec2.Vpc.fromVpcAttributes(this, 'ExistingVpc', {
123
+ vpcId: config.existingVpc.vpcId,
124
+ availabilityZones: ['us-west-2a', 'us-west-2b'],
125
+ privateSubnetIds: config.existingVpc.privateSubnetIds,
126
+ publicSubnetIds: config.existingVpc.publicSubnetIds,
127
+ });
128
+ }
129
+
130
+ // Create new VPC
131
+ return new ec2.Vpc(this, 'Vpc', {
132
+ maxAzs: 2,
133
+ natGateways: config.balancerType === 'single_instance' ? 0 : 1,
134
+ subnetConfiguration: [
135
+ {
136
+ cidrMask: 24,
137
+ name: 'Public',
138
+ subnetType: ec2.SubnetType.PUBLIC,
139
+ },
140
+ {
141
+ cidrMask: 24,
142
+ name: 'Private',
143
+ subnetType: config.balancerType === 'single_instance'
144
+ ? ec2.SubnetType.PUBLIC
145
+ : ec2.SubnetType.PRIVATE_WITH_EGRESS,
146
+ },
147
+ ],
148
+ });
149
+ }
150
+
151
+ private getOrCreateDatabase(
152
+ config: DeploymentConfig,
153
+ stage: string,
154
+ vpc: ec2.IVpc
155
+ ): { dbSecretArn: string | undefined; dbSecurityGroup: ec2.ISecurityGroup | undefined } {
156
+ if (config.database === 'existing' && config.existingDbSecretArn) {
157
+ // Use existing database - just return the secret ARN
158
+ const dbSecurityGroup = config.existingVpc?.dbSecurityGroupId
159
+ ? ec2.SecurityGroup.fromSecurityGroupId(this, 'ExistingDbSg', config.existingVpc.dbSecurityGroupId)
160
+ : undefined;
161
+
162
+ return {
163
+ dbSecretArn: config.existingDbSecretArn,
164
+ dbSecurityGroup,
165
+ };
166
+ }
167
+
168
+ // Create new database
169
+ const dbSecurityGroup = new ec2.SecurityGroup(this, 'DbSecurityGroup', {
170
+ vpc,
171
+ description: 'Security group for RDS PostgreSQL',
172
+ allowAllOutbound: false,
173
+ });
174
+
175
+ // Allow connections from within VPC
176
+ dbSecurityGroup.addIngressRule(
177
+ ec2.Peer.ipv4(vpc.vpcCidrBlock),
178
+ ec2.Port.tcp(5432),
179
+ 'Allow PostgreSQL from VPC'
180
+ );
181
+
182
+ const database = new rds.DatabaseInstance(this, 'Database', {
183
+ engine: rds.DatabaseInstanceEngine.postgres({
184
+ version: rds.PostgresEngineVersion.VER_16,
185
+ }),
186
+ instanceType: ec2.InstanceType.of(
187
+ ec2.InstanceClass.T4G,
188
+ config.dbInstanceSize || ec2.InstanceSize.MICRO
189
+ ),
190
+ vpc,
191
+ vpcSubnets: {
192
+ subnetType: config.balancerType === 'single_instance'
193
+ ? ec2.SubnetType.PUBLIC
194
+ : ec2.SubnetType.PRIVATE_WITH_EGRESS,
195
+ },
196
+ securityGroups: [dbSecurityGroup],
197
+ credentials: rds.Credentials.fromGeneratedSecret('chaaskit', {
198
+ secretName: `${config.serviceName}-${stage}-db-credentials`,
199
+ }),
200
+ databaseName: 'chaaskit',
201
+ allocatedStorage: 20,
202
+ maxAllocatedStorage: 100,
203
+ storageEncrypted: true,
204
+ multiAz: stage === 'prod' && config.balancerType !== 'single_instance',
205
+ deletionProtection: stage === 'prod',
206
+ removalPolicy: stage === 'prod'
207
+ ? cdk.RemovalPolicy.SNAPSHOT
208
+ : cdk.RemovalPolicy.DESTROY,
209
+ backupRetention: stage === 'prod' ? cdk.Duration.days(7) : cdk.Duration.days(1),
210
+ });
211
+
212
+ return {
213
+ dbSecretArn: database.secret?.secretArn,
214
+ dbSecurityGroup,
215
+ };
216
+ }
217
+
218
+ private buildOptionSettings(
219
+ config: DeploymentConfig,
220
+ stage: string,
221
+ bucket: s3.Bucket,
222
+ dbSecretArn: string | undefined,
223
+ vpc: ec2.IVpc,
224
+ instanceProfile: iam.CfnInstanceProfile,
225
+ dbSecurityGroup: ec2.ISecurityGroup | undefined
226
+ ): elasticbeanstalk.CfnEnvironment.OptionSettingProperty[] {
227
+ const settings: elasticbeanstalk.CfnEnvironment.OptionSettingProperty[] = [];
228
+
229
+ // VPC settings
230
+ if (config.existingVpc) {
231
+ settings.push(
232
+ {
233
+ namespace: 'aws:ec2:vpc',
234
+ optionName: 'VPCId',
235
+ value: config.existingVpc.vpcId,
236
+ },
237
+ {
238
+ namespace: 'aws:ec2:vpc',
239
+ optionName: 'Subnets',
240
+ value: config.existingVpc.privateSubnetIds.join(','),
241
+ },
242
+ {
243
+ namespace: 'aws:ec2:vpc',
244
+ optionName: 'ELBSubnets',
245
+ value: config.existingVpc.publicSubnetIds.join(','),
246
+ }
247
+ );
248
+ } else {
249
+ settings.push(
250
+ {
251
+ namespace: 'aws:ec2:vpc',
252
+ optionName: 'VPCId',
253
+ value: vpc.vpcId,
254
+ },
255
+ {
256
+ namespace: 'aws:ec2:vpc',
257
+ optionName: 'Subnets',
258
+ value: vpc.privateSubnets.map(s => s.subnetId).join(','),
259
+ },
260
+ {
261
+ namespace: 'aws:ec2:vpc',
262
+ optionName: 'ELBSubnets',
263
+ value: vpc.publicSubnets.map(s => s.subnetId).join(','),
264
+ }
265
+ );
266
+ }
267
+
268
+ // Environment type settings based on balancer type
269
+ if (config.balancerType === 'single_instance') {
270
+ settings.push({
271
+ namespace: 'aws:elasticbeanstalk:environment',
272
+ optionName: 'EnvironmentType',
273
+ value: 'SingleInstance',
274
+ });
275
+ } else {
276
+ // Both 'load_balancer' and 'shared' are load balanced
277
+ settings.push(
278
+ {
279
+ namespace: 'aws:elasticbeanstalk:environment',
280
+ optionName: 'EnvironmentType',
281
+ value: 'LoadBalanced',
282
+ },
283
+ {
284
+ namespace: 'aws:elasticbeanstalk:environment',
285
+ optionName: 'LoadBalancerType',
286
+ value: 'application',
287
+ }
288
+ );
289
+
290
+ // Shared ALB settings
291
+ if (config.balancerType === 'shared' && config.sharedAlb) {
292
+ settings.push(
293
+ {
294
+ namespace: 'aws:elasticbeanstalk:environment',
295
+ optionName: 'LoadBalancerIsShared',
296
+ value: 'true',
297
+ },
298
+ {
299
+ namespace: 'aws:elbv2:loadbalancer',
300
+ optionName: 'SharedLoadBalancer',
301
+ value: config.sharedAlb.albArn,
302
+ },
303
+ // Listener rule for host-based routing
304
+ {
305
+ namespace: 'aws:elbv2:listener:443',
306
+ optionName: 'Rules',
307
+ value: 'HostRule',
308
+ },
309
+ {
310
+ namespace: 'aws:elbv2:listenerrule:HostRule',
311
+ optionName: 'HostHeaders',
312
+ value: config.sharedAlb.hostHeaders.join(','),
313
+ },
314
+ {
315
+ namespace: 'aws:elbv2:listenerrule:HostRule',
316
+ optionName: 'Priority',
317
+ value: String(config.sharedAlb.priority),
318
+ }
319
+ );
320
+ } else if (config.balancerType === 'load_balancer' && config.certificateArn) {
321
+ // New ALB with HTTPS
322
+ settings.push(
323
+ {
324
+ namespace: 'aws:elbv2:listener:443',
325
+ optionName: 'Protocol',
326
+ value: 'HTTPS',
327
+ },
328
+ {
329
+ namespace: 'aws:elbv2:listener:443',
330
+ optionName: 'SSLCertificateArns',
331
+ value: config.certificateArn,
332
+ }
333
+ );
334
+ }
335
+ }
336
+
337
+ // Instance settings
338
+ settings.push(
339
+ {
340
+ namespace: 'aws:autoscaling:launchconfiguration',
341
+ optionName: 'InstanceType',
342
+ value: config.instanceType || 't4g.small',
343
+ },
344
+ {
345
+ namespace: 'aws:autoscaling:launchconfiguration',
346
+ optionName: 'IamInstanceProfile',
347
+ value: instanceProfile.ref,
348
+ },
349
+ {
350
+ namespace: 'aws:autoscaling:asg',
351
+ optionName: 'MinSize',
352
+ value: '1',
353
+ },
354
+ {
355
+ namespace: 'aws:autoscaling:asg',
356
+ optionName: 'MaxSize',
357
+ value: String(config.maxInstances || 2),
358
+ }
359
+ );
360
+
361
+ // Security group for RDS access
362
+ if (dbSecurityGroup) {
363
+ settings.push({
364
+ namespace: 'aws:autoscaling:launchconfiguration',
365
+ optionName: 'SecurityGroups',
366
+ value: dbSecurityGroup.securityGroupId,
367
+ });
368
+ }
369
+
370
+ // Health check
371
+ settings.push(
372
+ {
373
+ namespace: 'aws:elasticbeanstalk:environment:process:default',
374
+ optionName: 'HealthCheckPath',
375
+ value: '/api/health',
376
+ },
377
+ {
378
+ namespace: 'aws:elasticbeanstalk:healthreporting:system',
379
+ optionName: 'SystemType',
380
+ value: 'enhanced',
381
+ }
382
+ );
383
+
384
+ // Environment variables
385
+ settings.push(
386
+ {
387
+ namespace: 'aws:elasticbeanstalk:application:environment',
388
+ optionName: 'NODE_ENV',
389
+ value: 'production',
390
+ },
391
+ {
392
+ namespace: 'aws:elasticbeanstalk:application:environment',
393
+ optionName: 'PORT',
394
+ value: '8080',
395
+ },
396
+ {
397
+ namespace: 'aws:elasticbeanstalk:application:environment',
398
+ optionName: 'INTERNAL_S3_BUCKET',
399
+ value: bucket.bucketName,
400
+ },
401
+ {
402
+ namespace: 'aws:elasticbeanstalk:application:environment',
403
+ optionName: 'AWS_REGION',
404
+ value: config.region,
405
+ }
406
+ );
407
+
408
+ // Database secret ARN
409
+ if (dbSecretArn) {
410
+ settings.push({
411
+ namespace: 'aws:elasticbeanstalk:application:environment',
412
+ optionName: 'DB_SECRET_ARN',
413
+ value: dbSecretArn,
414
+ });
415
+ }
416
+
417
+ return settings;
418
+ }
419
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "chaaskit-cdk",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "build": "tsc",
7
+ "watch": "tsc -w",
8
+ "cdk": "cdk",
9
+ "synth": "cdk synth",
10
+ "diff": "cdk diff",
11
+ "deploy": "./scripts/build-app.sh && cdk deploy --require-approval never",
12
+ "deploy:staging": "STAGE=staging npm run deploy",
13
+ "deploy:prod": "STAGE=prod npm run deploy",
14
+ "destroy": "cdk destroy"
15
+ },
16
+ "dependencies": {
17
+ "aws-cdk-lib": "^2.170.0",
18
+ "constructs": "^10.4.2",
19
+ "source-map-support": "^0.5.21"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^20.11.0",
23
+ "aws-cdk": "^2.170.0",
24
+ "ts-node": "^10.9.2",
25
+ "typescript": "~5.4.0"
26
+ }
27
+ }
@@ -0,0 +1,63 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Build script for packaging ChaasKit app for Elastic Beanstalk deployment
5
+ # Run this from the cdk/ directory
6
+
7
+ BUILD_VERSION=${BUILD_VERSION:-$(git rev-parse --short HEAD 2>/dev/null || echo "latest")}
8
+
9
+ echo "========================================"
10
+ echo "Building ChaasKit for Elastic Beanstalk"
11
+ echo "Version: ${BUILD_VERSION}"
12
+ echo "========================================"
13
+
14
+ # Navigate to project root
15
+ cd ..
16
+
17
+ # Install dependencies
18
+ echo ""
19
+ echo "Installing dependencies..."
20
+ pnpm install --frozen-lockfile
21
+
22
+ # Build the application
23
+ echo ""
24
+ echo "Building application..."
25
+ pnpm build
26
+
27
+ # Generate Prisma client
28
+ echo ""
29
+ echo "Generating Prisma client..."
30
+ pnpm db:generate
31
+
32
+ # Create deployment package
33
+ echo ""
34
+ echo "Creating deployment package..."
35
+ PACKAGE_NAME="cdk/app-${BUILD_VERSION}.zip"
36
+
37
+ # Remove old package if exists
38
+ rm -f "${PACKAGE_NAME}"
39
+
40
+ # Create zip with required files
41
+ # Note: We use --symlinks to preserve symlinks in node_modules
42
+ zip -r "${PACKAGE_NAME}" \
43
+ build/ \
44
+ node_modules/ \
45
+ package.json \
46
+ server.js \
47
+ prisma/ \
48
+ config/ \
49
+ extensions/ \
50
+ -x "*.git*" \
51
+ -x "*node_modules/.cache*" \
52
+ -x "*.env*" \
53
+ -x "*cdk/*" \
54
+ -x "*test*" \
55
+ -x "*.test.*" \
56
+ -x "*.spec.*"
57
+
58
+ echo ""
59
+ echo "========================================"
60
+ echo "Build complete!"
61
+ echo "Package: ${PACKAGE_NAME}"
62
+ echo "Size: $(du -h "${PACKAGE_NAME}" | cut -f1)"
63
+ echo "========================================"
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["es2020"],
6
+ "declaration": true,
7
+ "strict": true,
8
+ "noImplicitAny": true,
9
+ "strictNullChecks": true,
10
+ "noImplicitThis": true,
11
+ "alwaysStrict": true,
12
+ "noUnusedLocals": false,
13
+ "noUnusedParameters": false,
14
+ "noImplicitReturns": true,
15
+ "noFallthroughCasesInSwitch": false,
16
+ "inlineSourceMap": true,
17
+ "inlineSources": true,
18
+ "experimentalDecorators": true,
19
+ "strictPropertyInitialization": false,
20
+ "typeRoots": ["./node_modules/@types"],
21
+ "esModuleInterop": true,
22
+ "skipLibCheck": true
23
+ },
24
+ "exclude": ["node_modules", "cdk.out"]
25
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "prisma": {
7
+ "schema": "prisma/schema"
8
+ },
9
+ "scripts": {
10
+ "dev": "concurrently \"chaaskit-server\" \"react-router dev\"",
11
+ "build": "react-router build",
12
+ "start": "NODE_ENV=production node server.js",
13
+ "typecheck": "react-router typegen && tsc --noEmit",
14
+ "db:generate": "prisma generate",
15
+ "db:push": "prisma db push",
16
+ "db:migrate": "prisma migrate dev",
17
+ "db:studio": "prisma studio",
18
+ "db:sync": "chaaskit-server db:sync"
19
+ },
20
+ "dependencies": {
21
+ "@chaaskit/server": "^0.1.0",
22
+ "@chaaskit/client": "^0.1.0",
23
+ "@chaaskit/db": "^0.1.0",
24
+ "@chaaskit/shared": "^0.1.0",
25
+ "express": "^4.21.0",
26
+ "@prisma/client": "^6.0.0",
27
+ "@react-router/express": "^7.1.0",
28
+ "@react-router/node": "^7.1.0",
29
+ "concurrently": "^9.2.1",
30
+ "isbot": "^5.1.0",
31
+ "react": "^18.2.0",
32
+ "react-dom": "^18.2.0",
33
+ "react-router": "^7.1.0"
34
+ },
35
+ "devDependencies": {
36
+ "@react-router/dev": "^7.1.0",
37
+ "@react-router/fs-routes": "^7.1.0",
38
+ "@types/node": "^22.0.0",
39
+ "@types/react": "^18.2.0",
40
+ "@types/react-dom": "^18.2.0",
41
+ "prisma": "^6.0.0",
42
+ "typescript": "^5.6.0",
43
+ "vite": "^5.4.0",
44
+ "vite-tsconfig-paths": "^5.0.0"
45
+ }
46
+ }