First try at pipeline publish
This commit is contained in:
57
.gitea/workflows/publish.yml
Normal file
57
.gitea/workflows/publish.yml
Normal 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
1
.gitignore
vendored
@@ -22,3 +22,4 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
cdk.out
|
||||
|
||||
13
aws/index.ts
Normal file
13
aws/index.ts
Normal 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
202
aws/stack.ts
Normal 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
6
cdk.context.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"cli-telemetry": false,
|
||||
"acknowledged-issue-numbers": [
|
||||
34892
|
||||
]
|
||||
}
|
||||
12
cdk.json
Normal file
12
cdk.json
Normal 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
501
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "forge-profile",
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "forge-profile",
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@jkling38/forge": "^0.0.17",
|
||||
"react": "^19.1.0",
|
||||
@@ -14,9 +14,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.29.0",
|
||||
"@types/node": "^24.0.10",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.5.2",
|
||||
"aws-cdk": "^2.1020.2",
|
||||
"aws-cdk-lib": "^2.204.0",
|
||||
"eslint": "^9.29.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
@@ -40,6 +43,59 @@
|
||||
"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": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
@@ -1426,6 +1482,16 @@
|
||||
"dev": true,
|
||||
"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": {
|
||||
"version": "19.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
|
||||
@@ -1800,6 +1866,422 @@
|
||||
"dev": true,
|
||||
"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": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -1939,6 +2421,14 @@
|
||||
"dev": true,
|
||||
"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": {
|
||||
"version": "2.0.0",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"name": "forge-profile",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"cdk": "cdk"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jkling38/forge": "^0.0.17",
|
||||
@@ -16,9 +17,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.29.0",
|
||||
"@types/node": "^24.0.10",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@vitejs/plugin-react": "^4.5.2",
|
||||
"aws-cdk": "^2.1020.2",
|
||||
"aws-cdk-lib": "^2.204.0",
|
||||
"eslint": "^9.29.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
|
||||
@@ -5,14 +5,14 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
],
|
||||
base: '/',
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
assetsDir: 'static',
|
||||
sourcemap: false,
|
||||
rollupOptions: {
|
||||
external: ["react", "react-dom"],
|
||||
output: {
|
||||
globals: {
|
||||
react: "React",
|
||||
"react-dom": "ReactDOM",
|
||||
},
|
||||
manualChunks: undefined
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user