First try at pipeline publish
Some checks failed
Build and Publish Portfolio / build (push) Successful in 24s
Build and Publish Portfolio / publish (push) Failing after 3m9s

This commit is contained in:
2025-08-07 22:31:49 -05:00
parent a85c176d28
commit b3f30bc715
9 changed files with 801 additions and 9 deletions

View File

@@ -0,0 +1,57 @@
name: Build and Publish Portfolio
on:
push:
branches: [main]
tags:
- "v*" # Trigger on version tags like v1.0.0
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "20"
cache: ""
- name: Install dependencies
run: npm ci
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
publish:
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') # Only publish on version tags
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "20"
cache: ""
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: dist
path: dist/
- name: Install dependencies
run: npm ci
- name: Deploy
run: npm run-script cdk -- deploy

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ dist-ssr
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
cdk.out

13
aws/index.ts Normal file
View File

@@ -0,0 +1,13 @@
import { ForgePortfolioStack } from "./stack.ts";
import * as cdk from 'aws-cdk-lib';
const app = new cdk.App();
new ForgePortfolioStack(app, 'JaredForgePortfolio', {
env: {
account: process.env.AWS_ACCOUNT,
region: 'us-east-1',
},
domainName: 'portfolio.kling.dev',
hostedZoneId: process.env.AWS_ROUTE53_ZONE
});

202
aws/stack.ts Normal file
View File

@@ -0,0 +1,202 @@
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as route53 from 'aws-cdk-lib/aws-route53';
import * as targets from 'aws-cdk-lib/aws-route53-targets';
import * as certificatemanager from 'aws-cdk-lib/aws-certificatemanager';
import { Construct } from 'constructs';
export interface ForgePortfolioStackProps extends cdk.StackProps {
domainName?: string; // Optional custom domain
hostedZoneId?: string; // Required if using custom domain
}
export class ForgePortfolioStack extends cdk.Stack {
public readonly bucket: s3.Bucket;
public readonly distribution: cloudfront.Distribution;
public readonly deploymentUser: iam.User;
constructor(scope: Construct, id: string, props: ForgePortfolioStackProps) {
super(scope, id, props);
// S3 Bucket for hosting static files
this.bucket = new s3.Bucket(this, 'PortfolioBucket', {
bucketName: `${id.toLowerCase()}-portfolio-${this.account}`,
removalPolicy: cdk.RemovalPolicy.DESTROY, // Be careful with this in production
autoDeleteObjects: true,
publicReadAccess: false, // CloudFront will handle access
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
versioned: false, // Keep costs low
websiteIndexDocument: 'index.html',
websiteErrorDocument: 'error.html',
});
// Origin Access Control for CloudFront to access S3
const originAccessControl = new cloudfront.S3OriginAccessControl(this, 'OAC', {
description: 'OAC for portfolio website',
});
// SSL Certificate (only if custom domain is provided)
let certificate: certificatemanager.Certificate | undefined;
if (props.domainName) {
certificate = new certificatemanager.Certificate(this, 'Certificate', {
domainName: props.domainName,
validation: certificatemanager.CertificateValidation.fromDns(),
});
}
// CloudFront Distribution
this.distribution = new cloudfront.Distribution(this, 'Distribution', {
defaultBehavior: {
origin: origins.S3BucketOrigin.withOriginAccessControl(this.bucket, {
originAccessControl,
}),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
compress: true,
allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
},
defaultRootObject: 'index.html',
errorResponses: [
{
httpStatus: 404,
responseHttpStatus: 200,
responsePagePath: '/index.html', // For SPA routing
ttl: cdk.Duration.minutes(5),
},
{
httpStatus: 403,
responseHttpStatus: 200,
responsePagePath: '/index.html', // For SPA routing
ttl: cdk.Duration.minutes(5),
},
],
domainNames: props.domainName ? [props.domainName] : undefined,
certificate: certificate,
minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
priceClass: cloudfront.PriceClass.PRICE_CLASS_100, // Use only NA and Europe for cost optimization
});
// Grant CloudFront access to S3 bucket
this.bucket.addToResourcePolicy(
new iam.PolicyStatement({
actions: ['s3:GetObject'],
resources: [this.bucket.arnForObjects('*')],
principals: [new iam.ServicePrincipal('cloudfront.amazonaws.com')],
conditions: {
StringEquals: {
'AWS:SourceArn': `arn:aws:cloudfront::${this.account}:distribution/${this.distribution.distributionId}`,
},
},
})
);
// Ensure bucket allows CloudFront to list objects (needed for error handling)
this.bucket.addToResourcePolicy(
new iam.PolicyStatement({
actions: ['s3:ListBucket'],
resources: [this.bucket.bucketArn],
principals: [new iam.ServicePrincipal('cloudfront.amazonaws.com')],
conditions: {
StringEquals: {
'AWS:SourceArn': `arn:aws:cloudfront::${this.account}:distribution/${this.distribution.distributionId}`,
},
},
})
);
// Custom domain DNS record (if provided)
if (props.domainName && props.hostedZoneId) {
const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
hostedZoneId: props.hostedZoneId,
zoneName: props.domainName,
});
new route53.ARecord(this, 'ARecord', {
zone: hostedZone,
target: route53.RecordTarget.fromAlias(
new targets.CloudFrontTarget(this.distribution)
),
});
}
// IAM User for GitHub Actions deployment
this.deploymentUser = new iam.User(this, 'DeploymentUser', {
userName: `${id}-github-actions-user`,
});
// Policy for deployment user
const deploymentPolicy = new iam.Policy(this, 'DeploymentPolicy', {
statements: [
// S3 permissions for uploading files
new iam.PolicyStatement({
actions: [
's3:PutObject',
's3:PutObjectAcl',
's3:GetObject',
's3:DeleteObject',
's3:ListBucket',
],
resources: [
this.bucket.bucketArn,
this.bucket.arnForObjects('*'),
],
}),
// CloudFront invalidation permissions
new iam.PolicyStatement({
actions: ['cloudfront:CreateInvalidation'],
resources: [
`arn:aws:cloudfront::${this.account}:distribution/${this.distribution.distributionId}`,
],
}),
],
});
this.deploymentUser.attachInlinePolicy(deploymentPolicy);
// Create Access Key for the deployment user
const accessKey = new iam.AccessKey(this, 'DeploymentUserAccessKey', {
user: this.deploymentUser,
});
// Outputs for GitHub Actions
new cdk.CfnOutput(this, 'BucketName', {
value: this.bucket.bucketName,
description: 'S3 Bucket name for deployment',
});
new cdk.CfnOutput(this, 'DistributionId', {
value: this.distribution.distributionId,
description: 'CloudFront Distribution ID for cache invalidation',
});
new cdk.CfnOutput(this, 'DistributionDomainName', {
value: this.distribution.distributionDomainName,
description: 'CloudFront Distribution domain name',
});
new cdk.CfnOutput(this, 'AccessKeyId', {
value: accessKey.accessKeyId,
description: 'Access Key ID for GitHub Actions (store as secret)',
});
new cdk.CfnOutput(this, 'SecretAccessKey', {
value: accessKey.secretAccessKey.unsafeUnwrap(),
description: 'Secret Access Key for GitHub Actions (store as secret)',
});
if (props.domainName) {
new cdk.CfnOutput(this, 'WebsiteURL', {
value: `https://${props.domainName}`,
description: 'Website URL',
});
} else {
new cdk.CfnOutput(this, 'WebsiteURL', {
value: `https://${this.distribution.distributionDomainName}`,
description: 'Website URL',
});
}
}
}

6
cdk.context.json Normal file
View File

@@ -0,0 +1,6 @@
{
"cli-telemetry": false,
"acknowledged-issue-numbers": [
34892
]
}

12
cdk.json Normal file
View File

@@ -0,0 +1,12 @@
{
"app": "npx ts-node --prefer-ts-exts aws/index.ts",
"watch": {
"include": ["**"],
"exclude": ["README.md", "cdk*.json", "**/*.d.ts", "**/*.js", "tsconfig.json", "package*.json", "yarn.lock", "node_modules", "test"]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"]
}
}

501
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "forge-profile", "name": "forge-profile",
"version": "0.0.0", "version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "forge-profile", "name": "forge-profile",
"version": "0.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@jkling38/forge": "^0.0.17", "@jkling38/forge": "^0.0.17",
"react": "^19.1.0", "react": "^19.1.0",
@@ -14,9 +14,12 @@
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.29.0", "@eslint/js": "^9.29.0",
"@types/node": "^24.0.10",
"@types/react": "^19.1.8", "@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^4.5.2", "@vitejs/plugin-react": "^4.5.2",
"aws-cdk": "^2.1020.2",
"aws-cdk-lib": "^2.204.0",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-react-refresh": "^0.4.20",
@@ -40,6 +43,59 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@aws-cdk/asset-awscli-v1": {
"version": "2.2.242",
"resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.242.tgz",
"integrity": "sha512-4c1bAy2ISzcdKXYS1k4HYZsNrgiwbiDzj36ybwFVxEWZXVAP0dimQTCaB9fxu7sWzEjw3d+eaw6Fon+QTfTIpQ==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@aws-cdk/asset-node-proxy-agent-v6": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz",
"integrity": "sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@aws-cdk/cloud-assembly-schema": {
"version": "45.2.0",
"resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-45.2.0.tgz",
"integrity": "sha512-5TTUkGHQ+nfuUGwKA8/Yraxb+JdNUh4np24qk/VHXmrCMq+M6HfmGWfhcg/QlHA2S5P3YIamfYHdQAB4uSNLAg==",
"bundleDependencies": [
"jsonschema",
"semver"
],
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"jsonschema": "~1.4.1",
"semver": "^7.7.2"
},
"engines": {
"node": ">= 18.0.0"
}
},
"node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": {
"version": "1.4.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": {
"version": "7.7.2",
"dev": true,
"inBundle": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@babel/code-frame": { "node_modules/@babel/code-frame": {
"version": "7.27.1", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
@@ -1426,6 +1482,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": {
"version": "24.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz",
"integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.8.0"
}
},
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.1.8", "version": "19.1.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
@@ -1800,6 +1866,422 @@
"dev": true, "dev": true,
"license": "Python-2.0" "license": "Python-2.0"
}, },
"node_modules/aws-cdk": {
"version": "2.1020.2",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1020.2.tgz",
"integrity": "sha512-yWdt3dJh4aPm1VNyEgfG3lozGrvddw0i7avt+Cl9KOYixmisQtAg39/aZqzVVqjzVZVEanXmz+tlhzzh75Z69A==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"cdk": "bin/cdk"
},
"engines": {
"node": ">= 18.0.0"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/aws-cdk-lib": {
"version": "2.204.0",
"resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.204.0.tgz",
"integrity": "sha512-mY3nYu+QvPhO+fz+LCFKbc0PFhTHbHzDLnbcA2fPcQBKciYnTixpBd2ccRlKYWbG4y6NTc6ju6DudZ3HIS4OlA==",
"bundleDependencies": [
"@balena/dockerignore",
"case",
"fs-extra",
"ignore",
"jsonschema",
"minimatch",
"punycode",
"semver",
"table",
"yaml",
"mime-types"
],
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@aws-cdk/asset-awscli-v1": "2.2.242",
"@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0",
"@aws-cdk/cloud-assembly-schema": "^45.0.0",
"@balena/dockerignore": "^1.0.2",
"case": "1.6.3",
"fs-extra": "^11.3.0",
"ignore": "^5.3.2",
"jsonschema": "^1.5.0",
"mime-types": "^2.1.35",
"minimatch": "^3.1.2",
"punycode": "^2.3.1",
"semver": "^7.7.2",
"table": "^6.9.0",
"yaml": "1.10.2"
},
"engines": {
"node": ">= 14.15.0"
},
"peerDependencies": {
"constructs": "^10.0.0"
}
},
"node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": {
"version": "1.0.2",
"dev": true,
"inBundle": true,
"license": "Apache-2.0"
},
"node_modules/aws-cdk-lib/node_modules/ajv": {
"version": "8.17.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/aws-cdk-lib/node_modules/ansi-regex": {
"version": "5.0.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/aws-cdk-lib/node_modules/ansi-styles": {
"version": "4.3.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/aws-cdk-lib/node_modules/astral-regex": {
"version": "2.0.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/aws-cdk-lib/node_modules/balanced-match": {
"version": "1.0.2",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/brace-expansion": {
"version": "1.1.12",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/aws-cdk-lib/node_modules/case": {
"version": "1.6.3",
"dev": true,
"inBundle": true,
"license": "(MIT OR GPL-3.0-or-later)",
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/aws-cdk-lib/node_modules/color-convert": {
"version": "2.0.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/aws-cdk-lib/node_modules/color-name": {
"version": "1.1.4",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/concat-map": {
"version": "0.0.1",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/emoji-regex": {
"version": "8.0.0",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/fast-deep-equal": {
"version": "3.1.3",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/fast-uri": {
"version": "3.0.6",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"inBundle": true,
"license": "BSD-3-Clause"
},
"node_modules/aws-cdk-lib/node_modules/fs-extra": {
"version": "11.3.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=14.14"
}
},
"node_modules/aws-cdk-lib/node_modules/graceful-fs": {
"version": "4.2.11",
"dev": true,
"inBundle": true,
"license": "ISC"
},
"node_modules/aws-cdk-lib/node_modules/ignore": {
"version": "5.3.2",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/aws-cdk-lib/node_modules/json-schema-traverse": {
"version": "1.0.0",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/jsonfile": {
"version": "6.1.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/aws-cdk-lib/node_modules/jsonschema": {
"version": "1.5.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/aws-cdk-lib/node_modules/lodash.truncate": {
"version": "4.4.2",
"dev": true,
"inBundle": true,
"license": "MIT"
},
"node_modules/aws-cdk-lib/node_modules/mime-db": {
"version": "1.52.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/aws-cdk-lib/node_modules/mime-types": {
"version": "2.1.35",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/aws-cdk-lib/node_modules/minimatch": {
"version": "3.1.2",
"dev": true,
"inBundle": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/aws-cdk-lib/node_modules/punycode": {
"version": "2.3.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/aws-cdk-lib/node_modules/require-from-string": {
"version": "2.0.2",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/aws-cdk-lib/node_modules/semver": {
"version": "7.7.2",
"dev": true,
"inBundle": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/aws-cdk-lib/node_modules/slice-ansi": {
"version": "4.0.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"astral-regex": "^2.0.0",
"is-fullwidth-code-point": "^3.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
"node_modules/aws-cdk-lib/node_modules/string-width": {
"version": "4.2.3",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/aws-cdk-lib/node_modules/strip-ansi": {
"version": "6.0.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/aws-cdk-lib/node_modules/table": {
"version": "6.9.0",
"dev": true,
"inBundle": true,
"license": "BSD-3-Clause",
"dependencies": {
"ajv": "^8.0.1",
"lodash.truncate": "^4.4.2",
"slice-ansi": "^4.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/aws-cdk-lib/node_modules/universalify": {
"version": "2.0.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/aws-cdk-lib/node_modules/yaml": {
"version": "1.10.2",
"dev": true,
"inBundle": true,
"license": "ISC",
"engines": {
"node": ">= 6"
}
},
"node_modules/aws-cdk/node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1939,6 +2421,14 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/constructs": {
"version": "10.4.2",
"resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz",
"integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==",
"dev": true,
"license": "Apache-2.0",
"peer": true
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -3198,6 +3688,13 @@
"typescript": ">=4.8.4 <5.9.0" "typescript": ">=4.8.4 <5.9.0"
} }
}, },
"node_modules/undici-types": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"dev": true,
"license": "MIT"
},
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",

View File

@@ -1,13 +1,14 @@
{ {
"name": "forge-profile", "name": "forge-profile",
"private": true, "private": true,
"version": "0.0.0", "version": "1.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc -b && vite build", "build": "tsc -b && vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview",
"cdk": "cdk"
}, },
"dependencies": { "dependencies": {
"@jkling38/forge": "^0.0.17", "@jkling38/forge": "^0.0.17",
@@ -16,9 +17,12 @@
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.29.0", "@eslint/js": "^9.29.0",
"@types/node": "^24.0.10",
"@types/react": "^19.1.8", "@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^4.5.2", "@vitejs/plugin-react": "^4.5.2",
"aws-cdk": "^2.1020.2",
"aws-cdk-lib": "^2.204.0",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-react-refresh": "^0.4.20",

View File

@@ -5,14 +5,14 @@ export default defineConfig({
plugins: [ plugins: [
react(), react(),
], ],
base: '/',
build: { build: {
outDir: 'dist',
assetsDir: 'static',
sourcemap: false,
rollupOptions: { rollupOptions: {
external: ["react", "react-dom"],
output: { output: {
globals: { manualChunks: undefined
react: "React",
"react-dom": "ReactDOM",
},
}, },
}, },
}, },