@macedon-technologies/batman 1.0.16

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 (41) hide show
  1. package/.jsii +637 -0
  2. package/API.md +5671 -0
  3. package/LICENSE +202 -0
  4. package/README.md +86 -0
  5. package/lib/ApiConstructFile.d.ts +5 -0
  6. package/lib/ApiConstructFile.js +175 -0
  7. package/lib/ApiFunctionFile.d.ts +5 -0
  8. package/lib/ApiFunctionFile.js +30 -0
  9. package/lib/Application.d.ts +21 -0
  10. package/lib/Application.js +72 -0
  11. package/lib/ApplicationStackFile.d.ts +5 -0
  12. package/lib/ApplicationStackFile.js +26 -0
  13. package/lib/BaseApplicationStackFile.d.ts +5 -0
  14. package/lib/BaseApplicationStackFile.js +172 -0
  15. package/lib/BatmanProject.d.ts +25 -0
  16. package/lib/BatmanProject.js +101 -0
  17. package/lib/GitHubRolesFile.d.ts +9 -0
  18. package/lib/GitHubRolesFile.js +26 -0
  19. package/lib/GitHubRolesStackFile.d.ts +8 -0
  20. package/lib/GitHubRolesStackFile.js +165 -0
  21. package/lib/LocalDevAppFile.d.ts +10 -0
  22. package/lib/LocalDevAppFile.js +34 -0
  23. package/lib/MainFile.d.ts +24 -0
  24. package/lib/MainFile.js +64 -0
  25. package/lib/MainTestFile.d.ts +5 -0
  26. package/lib/MainTestFile.js +33 -0
  27. package/lib/PrCleanupWorkflow.d.ts +9 -0
  28. package/lib/PrCleanupWorkflow.js +100 -0
  29. package/lib/PrDeployWorkflow.d.ts +10 -0
  30. package/lib/PrDeployWorkflow.js +106 -0
  31. package/lib/ProductionDeployWorkflow.d.ts +11 -0
  32. package/lib/ProductionDeployWorkflow.js +68 -0
  33. package/lib/StagingDeployWorkflow.d.ts +11 -0
  34. package/lib/StagingDeployWorkflow.js +68 -0
  35. package/lib/StaticWebsiteConstructFile.d.ts +5 -0
  36. package/lib/StaticWebsiteConstructFile.js +198 -0
  37. package/lib/ViteReactProject.d.ts +45 -0
  38. package/lib/ViteReactProject.js +654 -0
  39. package/lib/index.d.ts +5 -0
  40. package/lib/index.js +20 -0
  41. package/package.json +125 -0
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StaticWebsiteConstructFile = void 0;
4
+ const projen_1 = require("projen");
5
+ class StaticWebsiteConstructFile extends projen_1.SampleFile {
6
+ constructor(project) {
7
+ super(project, 'src/constructs/StaticWebsite.ts', {
8
+ contents: `import * as path from 'path';
9
+ import { DockerImage, Duration, RemovalPolicy } from 'aws-cdk-lib';
10
+ import { RestApi } from 'aws-cdk-lib/aws-apigateway';
11
+ import { Certificate, CertificateValidation } from 'aws-cdk-lib/aws-certificatemanager';
12
+ import {
13
+ AllowedMethods,
14
+ CacheHeaderBehavior,
15
+ CachePolicy,
16
+ Distribution,
17
+ ViewerProtocolPolicy,
18
+ } from 'aws-cdk-lib/aws-cloudfront';
19
+ import { RestApiOrigin, S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
20
+ import { PolicyStatement, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
21
+ import { ARecord, IHostedZone, RecordTarget } from 'aws-cdk-lib/aws-route53';
22
+ import { CloudFrontTarget } from 'aws-cdk-lib/aws-route53-targets';
23
+ import { BlockPublicAccess, Bucket, BucketAccessControl } from 'aws-cdk-lib/aws-s3';
24
+ import { BucketDeployment, Source } from 'aws-cdk-lib/aws-s3-deployment';
25
+ import { Construct } from 'constructs';
26
+
27
+ export interface StaticWebsiteProps {
28
+ readonly bucketName?: string;
29
+ readonly hostedZone: IHostedZone;
30
+ readonly api: RestApi;
31
+ readonly hostname?: string;
32
+ }
33
+
34
+ export class StaticWebsite extends Construct {
35
+ public bucket: Bucket;
36
+ public distribution: Distribution;
37
+ public certificate: Certificate;
38
+
39
+ private apiCachePolicy: CachePolicy;
40
+ private aRecord: ARecord;
41
+ private bucketDeployment: BucketDeployment;
42
+ private hostname: string;
43
+
44
+ constructor(scope: Construct, id: string, private props: StaticWebsiteProps) {
45
+ super(scope, id);
46
+
47
+ const domainName = props.hostedZone.zoneName;
48
+ const hostname = props.hostname || 'mvp';
49
+ this.hostname = \`\${hostname}.\${domainName}\`;
50
+
51
+ this.createCertificate();
52
+ if (!this.certificate) {
53
+ throw new Error('Failed to create certificate');
54
+ }
55
+
56
+ this.createBucket();
57
+ if (!this.bucket) {
58
+ throw new Error('Failed to create bucket');
59
+ }
60
+
61
+ this.createApiCachePolicy();
62
+ if (!this.apiCachePolicy) {
63
+ throw new Error('Failed to create API cache policy');
64
+ }
65
+
66
+ this.createDistribution();
67
+ if (!this.distribution) {
68
+ throw new Error('Failed to create distribution');
69
+ }
70
+
71
+ this.createDnsRecord();
72
+ if (!this.aRecord) {
73
+ throw new Error('Failed to create DNS A record');
74
+ }
75
+
76
+ this.addBucketPolicy();
77
+ this.createBucketDeployment();
78
+ if (!this.bucketDeployment) {
79
+ throw new Error('Failed to create bucket deployment');
80
+ }
81
+ }
82
+
83
+ protected createCertificate() {
84
+ this.certificate = new Certificate(this, 'Certificate', {
85
+ domainName: this.hostname,
86
+ validation: CertificateValidation.fromDns(this.props.hostedZone),
87
+ });
88
+ }
89
+
90
+ protected createBucket() {
91
+ this.bucket = new Bucket(this, 'Bucket', {
92
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
93
+ accessControl: BucketAccessControl.PRIVATE,
94
+ removalPolicy: RemovalPolicy.DESTROY,
95
+ autoDeleteObjects: true,
96
+ });
97
+ }
98
+
99
+ protected createApiCachePolicy() {
100
+ this.apiCachePolicy = new CachePolicy(this, 'ApiCachePolicy', {
101
+ comment: 'Cache policy for API Gateway with dynamic content',
102
+ defaultTtl: Duration.seconds(0),
103
+ maxTtl: Duration.seconds(1),
104
+ minTtl: Duration.seconds(0),
105
+ enableAcceptEncodingBrotli: true,
106
+ enableAcceptEncodingGzip: true,
107
+ headerBehavior: CacheHeaderBehavior.allowList('Authorization'),
108
+ });
109
+ }
110
+
111
+ protected createDistribution() {
112
+ this.distribution = new Distribution(this, 'Distribution', {
113
+ domainNames: [this.hostname],
114
+ certificate: this.certificate,
115
+ defaultBehavior: {
116
+ origin: S3BucketOrigin.withOriginAccessControl(this.bucket),
117
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
118
+ },
119
+ additionalBehaviors: {
120
+ '/api/*': {
121
+ origin: new RestApiOrigin(this.props.api),
122
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
123
+ allowedMethods: AllowedMethods.ALLOW_ALL,
124
+ cachePolicy: this.apiCachePolicy,
125
+
126
+ },
127
+ },
128
+ defaultRootObject: 'index.html',
129
+ errorResponses: [
130
+ {
131
+ httpStatus: 404,
132
+ responsePagePath: '/index.html',
133
+ },
134
+ {
135
+ httpStatus: 403,
136
+ responsePagePath: '/index.html',
137
+ },
138
+ ],
139
+ });
140
+ }
141
+
142
+ protected createDnsRecord() {
143
+ this.aRecord = new ARecord(this, 'ARecord', {
144
+ zone: this.props.hostedZone,
145
+ recordName: this.hostname,
146
+ target: RecordTarget.fromAlias(new CloudFrontTarget(this.distribution)),
147
+ });
148
+ }
149
+
150
+ protected addBucketPolicy() {
151
+ this.bucket.addToResourcePolicy(
152
+ new PolicyStatement({
153
+ sid: 'AllowCloudFrontServicePrincipal',
154
+ actions: ['s3:GetObject'],
155
+ resources: [\`\${this.bucket.bucketArn}/*\`],
156
+ principals: [new ServicePrincipal('cloudfront.amazonaws.com')],
157
+ conditions: {
158
+ StringEquals: {
159
+ 'AWS:SourceArn': \`arn:aws:cloudfront::\${this.bucket.stack.account}:distribution/\${this.distribution.distributionId}\`,
160
+ },
161
+ },
162
+ }),
163
+ );
164
+ }
165
+
166
+ protected createBucketDeployment() {
167
+ this.bucketDeployment = new BucketDeployment(this, 'BucketDeployment', {
168
+ sources: [Source.asset(path.join(__dirname, '../..'), {
169
+ bundling: {
170
+ image: DockerImage.fromRegistry('node:20-alpine'),
171
+ environment: {
172
+ npm_config_cache: '/tmp/.npm',
173
+ },
174
+ command: [
175
+ 'sh',
176
+ '-c',
177
+ [
178
+ 'cd /asset-input/web',
179
+ 'yarn install --frozen-lockfile --cache-folder /tmp/.yarn',
180
+ 'yarn build',
181
+ \`sed -i 's|"apiBaseUrl": "[^"]*"|"apiBaseUrl": "https://\${this.hostname}/api"|g' dist/config.json\`,
182
+ 'cp -r dist/* /asset-output/',
183
+ ].join(' && '),
184
+ ],
185
+ },
186
+ })],
187
+ destinationBucket: this.bucket,
188
+ distribution: this.distribution,
189
+ distributionPaths: ['/*'],
190
+ });
191
+ }
192
+ }
193
+ `,
194
+ });
195
+ }
196
+ }
197
+ exports.StaticWebsiteConstructFile = StaticWebsiteConstructFile;
198
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhdGljV2Vic2l0ZUNvbnN0cnVjdEZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU3RhdGljV2Vic2l0ZUNvbnN0cnVjdEZpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQW9DO0FBR3BDLE1BQWEsMEJBQTJCLFNBQVEsbUJBQVU7SUFDeEQsWUFBWSxPQUE0QjtRQUN0QyxLQUFLLENBQUMsT0FBTyxFQUFFLGlDQUFpQyxFQUFFO1lBQ2hELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F5TGY7U0FDSSxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUEvTEQsZ0VBK0xDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2FtcGxlRmlsZSB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBBd3NDZGtUeXBlU2NyaXB0QXBwIH0gZnJvbSAncHJvamVuL2xpYi9hd3NjZGsnO1xuXG5leHBvcnQgY2xhc3MgU3RhdGljV2Vic2l0ZUNvbnN0cnVjdEZpbGUgZXh0ZW5kcyBTYW1wbGVGaWxlIHtcbiAgY29uc3RydWN0b3IocHJvamVjdDogQXdzQ2RrVHlwZVNjcmlwdEFwcCkge1xuICAgIHN1cGVyKHByb2plY3QsICdzcmMvY29uc3RydWN0cy9TdGF0aWNXZWJzaXRlLnRzJywge1xuICAgICAgY29udGVudHM6IGBpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgRG9ja2VySW1hZ2UsIER1cmF0aW9uLCBSZW1vdmFsUG9saWN5IH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUmVzdEFwaSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5JztcbmltcG9ydCB7IENlcnRpZmljYXRlLCBDZXJ0aWZpY2F0ZVZhbGlkYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyJztcbmltcG9ydCB7XG4gIEFsbG93ZWRNZXRob2RzLFxuICBDYWNoZUhlYWRlckJlaGF2aW9yLFxuICBDYWNoZVBvbGljeSxcbiAgRGlzdHJpYnV0aW9uLFxuICBWaWV3ZXJQcm90b2NvbFBvbGljeSxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQnO1xuaW1wb3J0IHsgUmVzdEFwaU9yaWdpbiwgUzNCdWNrZXRPcmlnaW4gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udC1vcmlnaW5zJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgU2VydmljZVByaW5jaXBhbCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgQVJlY29yZCwgSUhvc3RlZFpvbmUsIFJlY29yZFRhcmdldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1yb3V0ZTUzJztcbmltcG9ydCB7IENsb3VkRnJvbnRUYXJnZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzJztcbmltcG9ydCB7IEJsb2NrUHVibGljQWNjZXNzLCBCdWNrZXQsIEJ1Y2tldEFjY2Vzc0NvbnRyb2wgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0IHsgQnVja2V0RGVwbG95bWVudCwgU291cmNlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnQnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGljV2Vic2l0ZVByb3BzIHtcbiAgcmVhZG9ubHkgYnVja2V0TmFtZT86IHN0cmluZztcbiAgcmVhZG9ubHkgaG9zdGVkWm9uZTogSUhvc3RlZFpvbmU7XG4gIHJlYWRvbmx5IGFwaTogUmVzdEFwaTtcbiAgcmVhZG9ubHkgaG9zdG5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBTdGF0aWNXZWJzaXRlIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHVibGljIGJ1Y2tldDogQnVja2V0O1xuICBwdWJsaWMgZGlzdHJpYnV0aW9uOiBEaXN0cmlidXRpb247XG4gIHB1YmxpYyBjZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGU7XG5cbiAgcHJpdmF0ZSBhcGlDYWNoZVBvbGljeTogQ2FjaGVQb2xpY3k7XG4gIHByaXZhdGUgYVJlY29yZDogQVJlY29yZDtcbiAgcHJpdmF0ZSBidWNrZXREZXBsb3ltZW50OiBCdWNrZXREZXBsb3ltZW50O1xuICBwcml2YXRlIGhvc3RuYW1lOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJpdmF0ZSBwcm9wczogU3RhdGljV2Vic2l0ZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IGRvbWFpbk5hbWUgPSBwcm9wcy5ob3N0ZWRab25lLnpvbmVOYW1lO1xuICAgIGNvbnN0IGhvc3RuYW1lID0gcHJvcHMuaG9zdG5hbWUgfHwgJ212cCc7XG4gICAgdGhpcy5ob3N0bmFtZSA9IFxcYFxcJHtob3N0bmFtZX0uXFwke2RvbWFpbk5hbWV9XFxgO1xuXG4gICAgdGhpcy5jcmVhdGVDZXJ0aWZpY2F0ZSgpO1xuICAgIGlmICghdGhpcy5jZXJ0aWZpY2F0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIGNlcnRpZmljYXRlJyk7XG4gICAgfVxuXG4gICAgdGhpcy5jcmVhdGVCdWNrZXQoKTtcbiAgICBpZiAoIXRoaXMuYnVja2V0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBjcmVhdGUgYnVja2V0Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5jcmVhdGVBcGlDYWNoZVBvbGljeSgpO1xuICAgIGlmICghdGhpcy5hcGlDYWNoZVBvbGljeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIEFQSSBjYWNoZSBwb2xpY3knKTtcbiAgICB9XG5cbiAgICB0aGlzLmNyZWF0ZURpc3RyaWJ1dGlvbigpO1xuICAgIGlmICghdGhpcy5kaXN0cmlidXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGNyZWF0ZSBkaXN0cmlidXRpb24nKTtcbiAgICB9XG5cbiAgICB0aGlzLmNyZWF0ZURuc1JlY29yZCgpO1xuICAgIGlmICghdGhpcy5hUmVjb3JkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBjcmVhdGUgRE5TIEEgcmVjb3JkJyk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGRCdWNrZXRQb2xpY3koKTtcbiAgICB0aGlzLmNyZWF0ZUJ1Y2tldERlcGxveW1lbnQoKTtcbiAgICBpZiAoIXRoaXMuYnVja2V0RGVwbG95bWVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIGJ1Y2tldCBkZXBsb3ltZW50Jyk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUNlcnRpZmljYXRlKCkge1xuICAgIHRoaXMuY2VydGlmaWNhdGUgPSBuZXcgQ2VydGlmaWNhdGUodGhpcywgJ0NlcnRpZmljYXRlJywge1xuICAgICAgZG9tYWluTmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICAgIHZhbGlkYXRpb246IENlcnRpZmljYXRlVmFsaWRhdGlvbi5mcm9tRG5zKHRoaXMucHJvcHMuaG9zdGVkWm9uZSksXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlQnVja2V0KCkge1xuICAgIHRoaXMuYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCAnQnVja2V0Jywge1xuICAgICAgYmxvY2tQdWJsaWNBY2Nlc3M6IEJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FMTCxcbiAgICAgIGFjY2Vzc0NvbnRyb2w6IEJ1Y2tldEFjY2Vzc0NvbnRyb2wuUFJJVkFURSxcbiAgICAgIHJlbW92YWxQb2xpY3k6IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgIGF1dG9EZWxldGVPYmplY3RzOiB0cnVlLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUFwaUNhY2hlUG9saWN5KCkge1xuICAgIHRoaXMuYXBpQ2FjaGVQb2xpY3kgPSBuZXcgQ2FjaGVQb2xpY3kodGhpcywgJ0FwaUNhY2hlUG9saWN5Jywge1xuICAgICAgY29tbWVudDogJ0NhY2hlIHBvbGljeSBmb3IgQVBJIEdhdGV3YXkgd2l0aCBkeW5hbWljIGNvbnRlbnQnLFxuICAgICAgZGVmYXVsdFR0bDogRHVyYXRpb24uc2Vjb25kcygwKSxcbiAgICAgIG1heFR0bDogRHVyYXRpb24uc2Vjb25kcygxKSxcbiAgICAgIG1pblR0bDogRHVyYXRpb24uc2Vjb25kcygwKSxcbiAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nQnJvdGxpOiB0cnVlLFxuICAgICAgZW5hYmxlQWNjZXB0RW5jb2RpbmdHemlwOiB0cnVlLFxuICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KCdBdXRob3JpemF0aW9uJyksXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlRGlzdHJpYnV0aW9uKCkge1xuICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gbmV3IERpc3RyaWJ1dGlvbih0aGlzLCAnRGlzdHJpYnV0aW9uJywge1xuICAgICAgZG9tYWluTmFtZXM6IFt0aGlzLmhvc3RuYW1lXSxcbiAgICAgIGNlcnRpZmljYXRlOiB0aGlzLmNlcnRpZmljYXRlLFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiB7XG4gICAgICAgIG9yaWdpbjogUzNCdWNrZXRPcmlnaW4ud2l0aE9yaWdpbkFjY2Vzc0NvbnRyb2wodGhpcy5idWNrZXQpLFxuICAgICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICB9LFxuICAgICAgYWRkaXRpb25hbEJlaGF2aW9yczoge1xuICAgICAgICAnL2FwaS8qJzoge1xuICAgICAgICAgIG9yaWdpbjogbmV3IFJlc3RBcGlPcmlnaW4odGhpcy5wcm9wcy5hcGkpLFxuICAgICAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfQUxMLFxuICAgICAgICAgIGNhY2hlUG9saWN5OiB0aGlzLmFwaUNhY2hlUG9saWN5LFxuXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgZGVmYXVsdFJvb3RPYmplY3Q6ICdpbmRleC5odG1sJyxcbiAgICAgIGVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBodHRwU3RhdHVzOiA0MDQsXG4gICAgICAgICAgcmVzcG9uc2VQYWdlUGF0aDogJy9pbmRleC5odG1sJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGh0dHBTdGF0dXM6IDQwMyxcbiAgICAgICAgICByZXNwb25zZVBhZ2VQYXRoOiAnL2luZGV4Lmh0bWwnLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVEbnNSZWNvcmQoKSB7XG4gICAgdGhpcy5hUmVjb3JkID0gbmV3IEFSZWNvcmQodGhpcywgJ0FSZWNvcmQnLCB7XG4gICAgICB6b25lOiB0aGlzLnByb3BzLmhvc3RlZFpvbmUsXG4gICAgICByZWNvcmROYW1lOiB0aGlzLmhvc3RuYW1lLFxuICAgICAgdGFyZ2V0OiBSZWNvcmRUYXJnZXQuZnJvbUFsaWFzKG5ldyBDbG91ZEZyb250VGFyZ2V0KHRoaXMuZGlzdHJpYnV0aW9uKSksXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWRkQnVja2V0UG9saWN5KCkge1xuICAgIHRoaXMuYnVja2V0LmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgc2lkOiAnQWxsb3dDbG91ZEZyb250U2VydmljZVByaW5jaXBhbCcsXG4gICAgICAgIGFjdGlvbnM6IFsnczM6R2V0T2JqZWN0J10sXG4gICAgICAgIHJlc291cmNlczogW1xcYFxcJHt0aGlzLmJ1Y2tldC5idWNrZXRBcm59LypcXGBdLFxuICAgICAgICBwcmluY2lwYWxzOiBbbmV3IFNlcnZpY2VQcmluY2lwYWwoJ2Nsb3VkZnJvbnQuYW1hem9uYXdzLmNvbScpXSxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgICAgJ0FXUzpTb3VyY2VBcm4nOiBcXGBhcm46YXdzOmNsb3VkZnJvbnQ6OlxcJHt0aGlzLmJ1Y2tldC5zdGFjay5hY2NvdW50fTpkaXN0cmlidXRpb24vXFwke3RoaXMuZGlzdHJpYnV0aW9uLmRpc3RyaWJ1dGlvbklkfVxcYCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVCdWNrZXREZXBsb3ltZW50KCkge1xuICAgIHRoaXMuYnVja2V0RGVwbG95bWVudCA9IG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsICdCdWNrZXREZXBsb3ltZW50Jywge1xuICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4nKSwge1xuICAgICAgICBidW5kbGluZzoge1xuICAgICAgICAgIGltYWdlOiBEb2NrZXJJbWFnZS5mcm9tUmVnaXN0cnkoJ25vZGU6MjAtYWxwaW5lJyksXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICAgIG5wbV9jb25maWdfY2FjaGU6ICcvdG1wLy5ucG0nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY29tbWFuZDogW1xuICAgICAgICAgICAgJ3NoJyxcbiAgICAgICAgICAgICctYycsXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICdjZCAvYXNzZXQtaW5wdXQvd2ViJyxcbiAgICAgICAgICAgICAgJ3lhcm4gaW5zdGFsbCAtLWZyb3plbi1sb2NrZmlsZSAtLWNhY2hlLWZvbGRlciAvdG1wLy55YXJuJyxcbiAgICAgICAgICAgICAgJ3lhcm4gYnVpbGQnLFxuICAgICAgICAgICAgICBcXGBzZWQgLWkgJ3N8XCJhcGlCYXNlVXJsXCI6IFwiW15cIl0qXCJ8XCJhcGlCYXNlVXJsXCI6IFwiaHR0cHM6Ly9cXCR7dGhpcy5ob3N0bmFtZX0vYXBpXCJ8ZycgZGlzdC9jb25maWcuanNvblxcYCxcbiAgICAgICAgICAgICAgJ2NwIC1yIGRpc3QvKiAvYXNzZXQtb3V0cHV0LycsXG4gICAgICAgICAgICBdLmpvaW4oJyAmJiAnKSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSldLFxuICAgICAgZGVzdGluYXRpb25CdWNrZXQ6IHRoaXMuYnVja2V0LFxuICAgICAgZGlzdHJpYnV0aW9uOiB0aGlzLmRpc3RyaWJ1dGlvbixcbiAgICAgIGRpc3RyaWJ1dGlvblBhdGhzOiBbJy8qJ10sXG4gICAgfSk7XG4gIH1cbn1cbmAsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,45 @@
1
+ import { TypeScriptAppProject, TypeScriptProjectOptions } from 'projen/lib/typescript';
2
+ export interface ViteReactProjectOptions extends TypeScriptProjectOptions {
3
+ /**
4
+ * Whether to generate sample code
5
+ * @default true
6
+ */
7
+ readonly sampleCode?: boolean;
8
+ /**
9
+ * Source directory
10
+ * @default "src"
11
+ */
12
+ readonly srcdir?: string;
13
+ /**
14
+ * Public directory for static assets
15
+ * @default "public"
16
+ */
17
+ readonly publicDir?: string;
18
+ /**
19
+ * Title for the HTML page
20
+ * @default project name
21
+ */
22
+ readonly title?: string;
23
+ }
24
+ /**
25
+ * Vite + React TypeScript project
26
+ */
27
+ export declare class ViteReactProject extends TypeScriptAppProject {
28
+ readonly srcdir: string;
29
+ readonly publicDir: string;
30
+ readonly devCommand: string;
31
+ private readonly configFields;
32
+ constructor(options: ViteReactProjectOptions);
33
+ /**
34
+ * Add a custom field to the Config type
35
+ * @param fieldName The name of the field
36
+ * @param fieldType The TypeScript type of the field (e.g., 'string', 'number', 'boolean', 'string[]')
37
+ * @returns this project instance for chaining
38
+ */
39
+ addConfigField(fieldName: string, fieldType: string): this;
40
+ /**
41
+ * Get the config fields map (for internal use by ConfigFile)
42
+ * @internal
43
+ */
44
+ getConfigFields(): Map<string, string>;
45
+ }