Compare commits
No commits in common. "PROD-v1.0.1" and "master" have entirely different histories.
PROD-v1.0.
...
master
@ -1,23 +0,0 @@
|
||||
---
|
||||
name: OpenSpec: Apply
|
||||
description: Implement an approved OpenSpec change and keep tasks in sync.
|
||||
category: OpenSpec
|
||||
tags: [openspec, apply]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
**Guardrails**
|
||||
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
|
||||
- Keep changes tightly scoped to the requested outcome.
|
||||
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
|
||||
|
||||
**Steps**
|
||||
Track these steps as TODOs and complete them one by one.
|
||||
1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
|
||||
2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
|
||||
3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
|
||||
4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
|
||||
5. Reference `openspec list` or `openspec show <item>` when additional context is required.
|
||||
|
||||
**Reference**
|
||||
- Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
|
||||
<!-- OPENSPEC:END -->
|
||||
@ -1,21 +0,0 @@
|
||||
---
|
||||
name: OpenSpec: Archive
|
||||
description: Archive a deployed OpenSpec change and update specs.
|
||||
category: OpenSpec
|
||||
tags: [openspec, archive]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
**Guardrails**
|
||||
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
|
||||
- Keep changes tightly scoped to the requested outcome.
|
||||
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
|
||||
|
||||
**Steps**
|
||||
1. Identify the requested change ID (via the prompt or `openspec list`).
|
||||
2. Run `openspec archive <id> --yes` to let the CLI move the change and apply spec updates without prompts (use `--skip-specs` only for tooling-only work).
|
||||
3. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
|
||||
4. Validate with `openspec validate --strict` and inspect with `openspec show <id>` if anything looks off.
|
||||
|
||||
**Reference**
|
||||
- Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
|
||||
<!-- OPENSPEC:END -->
|
||||
@ -1,27 +0,0 @@
|
||||
---
|
||||
name: OpenSpec: Proposal
|
||||
description: Scaffold a new OpenSpec change and validate strictly.
|
||||
category: OpenSpec
|
||||
tags: [openspec, change]
|
||||
---
|
||||
<!-- OPENSPEC:START -->
|
||||
**Guardrails**
|
||||
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
|
||||
- Keep changes tightly scoped to the requested outcome.
|
||||
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
|
||||
- Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
|
||||
|
||||
**Steps**
|
||||
1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
|
||||
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
|
||||
3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
|
||||
4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
|
||||
5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
|
||||
6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
|
||||
7. Validate with `openspec validate <id> --strict` and resolve every issue before sharing the proposal.
|
||||
|
||||
**Reference**
|
||||
- Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
|
||||
- Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
|
||||
- Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
|
||||
<!-- OPENSPEC:END -->
|
||||
@ -1,26 +0,0 @@
|
||||
node_modules
|
||||
.next
|
||||
.git
|
||||
.gitignore
|
||||
.env.local
|
||||
.env.*.local
|
||||
.angular
|
||||
dist
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.DS_Store
|
||||
*.pem
|
||||
.idea
|
||||
.vscode
|
||||
.svn
|
||||
.hg
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.cache
|
||||
.turbo
|
||||
coverage
|
||||
__pycache__
|
||||
*.egg-info
|
||||
.pytest_cache
|
||||
@ -1 +0,0 @@
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8000/api
|
||||
@ -1 +0,0 @@
|
||||
NEXT_PUBLIC_API_URL=https://portfolio-host.com/api
|
||||
@ -1,81 +0,0 @@
|
||||
name: Build and Deploy to k3s (Alpha)
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'PRE_ALPHA*'
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
env:
|
||||
KUBECONFIG: ~/.kube/config
|
||||
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'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Next.js app
|
||||
run: npm run build
|
||||
env:
|
||||
NEXT_PUBLIC_API_URL: ${{ secrets.ALPHA_API_URL }}
|
||||
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
docker build \
|
||||
-t ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-alpha:${{ github.sha }} \
|
||||
-t ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-alpha:latest \
|
||||
--build-arg NODE_ENV=production \
|
||||
.
|
||||
|
||||
- name: Login to Container Registry
|
||||
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ secrets.REGISTRY_URL }} -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||
|
||||
- name: Push Docker images
|
||||
run: |
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-alpha:${{ github.sha }}
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-alpha:latest
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v3
|
||||
with:
|
||||
version: 'latest'
|
||||
|
||||
- name: Configure kubectl
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBE_CONFIG }}" > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Validate kubeconfig and cluster connectivity
|
||||
run: |
|
||||
if ! kubectl version --client; then
|
||||
echo "❌ Failed to get kubectl version"
|
||||
exit 1
|
||||
fi
|
||||
if ! kubectl cluster-info --kubeconfig ~/.kube/config > /dev/null 2>&1; then
|
||||
echo "❌ Failed to connect to cluster"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Successfully connected to Kubernetes cluster"
|
||||
|
||||
- name: Deploy to Alpha (k3s)
|
||||
run: |
|
||||
echo "Applying Kubernetes manifests..."
|
||||
kubectl apply -k deploy/k3s/alpha --kubeconfig ~/.kube/config
|
||||
|
||||
echo "Updating deployment image..."
|
||||
kubectl set image deployment/hosting-frontend \
|
||||
hosting-frontend=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-alpha:${{ github.sha }} \
|
||||
-n hosting-alpha --kubeconfig ~/.kube/config
|
||||
|
||||
echo "Waiting for rollout to complete..."
|
||||
kubectl rollout status deployment/hosting-frontend -n hosting-alpha --kubeconfig ~/.kube/config --timeout=5m
|
||||
|
||||
echo "✅ Alpha deployment complete!"
|
||||
@ -1,81 +0,0 @@
|
||||
name: Build and Deploy to k3s (Production)
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'PROD*'
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
env:
|
||||
KUBECONFIG: ~/.kube/config
|
||||
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'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Next.js app
|
||||
run: npm run build
|
||||
env:
|
||||
NEXT_PUBLIC_API_URL: ${{ secrets.PROD_API_URL }}
|
||||
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
docker build \
|
||||
-t ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }} \
|
||||
-t ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:latest \
|
||||
--build-arg NODE_ENV=production \
|
||||
.
|
||||
|
||||
- name: Login to Container Registry
|
||||
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ secrets.REGISTRY_URL }} -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||
|
||||
- name: Push Docker images
|
||||
run: |
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }}
|
||||
docker push ${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:latest
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v3
|
||||
with:
|
||||
version: 'latest'
|
||||
|
||||
- name: Configure kubectl
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${{ secrets.KUBE_CONFIG }}" > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
|
||||
- name: Validate kubeconfig and cluster connectivity
|
||||
run: |
|
||||
if ! kubectl version --client; then
|
||||
echo "❌ Failed to get kubectl version"
|
||||
exit 1
|
||||
fi
|
||||
if ! kubectl cluster-info --kubeconfig ~/.kube/config > /dev/null 2>&1; then
|
||||
echo "❌ Failed to connect to cluster"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Successfully connected to Kubernetes cluster"
|
||||
|
||||
- name: Deploy to Production (k3s)
|
||||
run: |
|
||||
echo "Applying Kubernetes manifests..."
|
||||
kubectl apply -k deploy/k3s/prod --kubeconfig ~/.kube/config
|
||||
|
||||
echo "Updating deployment image..."
|
||||
kubectl set image deployment/hosting-frontend \
|
||||
hosting-frontend=${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/hosting-frontend-prod:${{ github.sha }} \
|
||||
-n hosting --kubeconfig ~/.kube/config
|
||||
|
||||
echo "Waiting for rollout to complete..."
|
||||
kubectl rollout status deployment/hosting-frontend -n hosting --kubeconfig ~/.kube/config --timeout=5m
|
||||
|
||||
echo "✅ Production deployment complete!"
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"pages": {
|
||||
"/layout": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js",
|
||||
"static/css/app/layout.css",
|
||||
"static/chunks/app/layout.js"
|
||||
],
|
||||
"/page": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js",
|
||||
"static/chunks/app/page.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"polyfillFiles": [
|
||||
"static/chunks/polyfills.js"
|
||||
],
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"lowPriorityFiles": [
|
||||
"static/development/_buildManifest.js",
|
||||
"static/development/_ssgManifest.js"
|
||||
],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js"
|
||||
],
|
||||
"rootMainFilesTree": {},
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"ampFirstPages": []
|
||||
}
|
||||
1
.next/cache/.previewinfo
vendored
1
.next/cache/.previewinfo
vendored
@ -1 +0,0 @@
|
||||
{"previewModeId":"dc559f34b2cfb8e471f5cf7c4303e624","previewModeSigningKey":"cbfcb5c64d2055dbda1bfdbc6833ad47f57d6fb250a5de05c1dc43c23f26d6b1","previewModeEncryptionKey":"0ac99f44e54b21dc78776676abda88910973e01c15da70460817db51a4491fdd","expireAt":1761863112139}
|
||||
1
.next/cache/.rscinfo
vendored
1
.next/cache/.rscinfo
vendored
@ -1 +0,0 @@
|
||||
{"encryption.key":"UJCuqkc43Q1Tu8qgslshb0xL4QAUycNhcPIjjC8lUyo=","encryption.expire_at":1761863112040}
|
||||
1
.next/cache/.tsbuildinfo
vendored
1
.next/cache/.tsbuildinfo
vendored
File diff suppressed because one or more lines are too long
1
.next/cache/next-devtools-config.json
vendored
1
.next/cache/next-devtools-config.json
vendored
@ -1 +0,0 @@
|
||||
{}
|
||||
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
Binary file not shown.
Binary file not shown.
BIN
.next/cache/webpack/client-production/0.pack
vendored
BIN
.next/cache/webpack/client-production/0.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/1.pack
vendored
BIN
.next/cache/webpack/client-production/1.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/2.pack
vendored
BIN
.next/cache/webpack/client-production/2.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/3.pack
vendored
BIN
.next/cache/webpack/client-production/3.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/4.pack
vendored
BIN
.next/cache/webpack/client-production/4.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/5.pack
vendored
BIN
.next/cache/webpack/client-production/5.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/6.pack
vendored
BIN
.next/cache/webpack/client-production/6.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/index.pack
vendored
BIN
.next/cache/webpack/client-production/index.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/client-production/index.pack.old
vendored
BIN
.next/cache/webpack/client-production/index.pack.old
vendored
Binary file not shown.
BIN
.next/cache/webpack/edge-server-production/0.pack
vendored
BIN
.next/cache/webpack/edge-server-production/0.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/edge-server-production/1.pack
vendored
BIN
.next/cache/webpack/edge-server-production/1.pack
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/0.pack
vendored
BIN
.next/cache/webpack/server-production/0.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/1.pack
vendored
BIN
.next/cache/webpack/server-production/1.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/2.pack
vendored
BIN
.next/cache/webpack/server-production/2.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/3.pack
vendored
BIN
.next/cache/webpack/server-production/3.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/4.pack
vendored
BIN
.next/cache/webpack/server-production/4.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/5.pack
vendored
BIN
.next/cache/webpack/server-production/5.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/index.pack
vendored
BIN
.next/cache/webpack/server-production/index.pack
vendored
Binary file not shown.
BIN
.next/cache/webpack/server-production/index.pack.old
vendored
BIN
.next/cache/webpack/server-production/index.pack.old
vendored
Binary file not shown.
@ -1 +0,0 @@
|
||||
{"type": "commonjs"}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"version": 4,
|
||||
"routes": {},
|
||||
"dynamicRoutes": {},
|
||||
"notFoundRoutes": [],
|
||||
"preview": {
|
||||
"previewModeId": "b519e1f670f54aba65a44541ac258fa1",
|
||||
"previewModeSigningKey": "357de2109d161118a84c195d2910555373bfa1683d172ae54a76574b720b4802",
|
||||
"previewModeEncryptionKey": "85cbb6533f9cf3ef2e23ca4286fc7869149638eadc425c8a643447926c624384"
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -1 +0,0 @@
|
||||
{"version":3,"caseSensitive":false,"basePath":"","rewrites":{"beforeFiles":[],"afterFiles":[],"fallback":[]},"redirects":[{"source":"/:path+/","destination":"/:path+","permanent":true,"internal":true,"regex":"^(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))\\/$"}],"headers":[]}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"/page": "app/page.js"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]"
|
||||
@ -1,22 +0,0 @@
|
||||
globalThis.__BUILD_MANIFEST = {
|
||||
"polyfillFiles": [
|
||||
"static/chunks/polyfills.js"
|
||||
],
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main-app.js"
|
||||
],
|
||||
"rootMainFilesTree": {},
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"ampFirstPages": []
|
||||
};
|
||||
globalThis.__BUILD_MANIFEST.lowPriorityFiles = [
|
||||
"/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
|
||||
,"/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
|
||||
|
||||
];
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"middleware": {},
|
||||
"functions": {},
|
||||
"sortedMiddleware": []
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
self.__REACT_LOADABLE_MANIFEST="{}"
|
||||
@ -1 +0,0 @@
|
||||
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{\"/home/sorti/projects/hosting-frontend/app/layout\":[\"static/media/e4af272ccee01ff0-s.p.woff2\"]},\"appUsingSizeAdjust\":true,\"pagesUsingSizeAdjust\":false}"
|
||||
@ -1 +0,0 @@
|
||||
{"pages":{},"app":{"/home/sorti/projects/hosting-frontend/app/layout":["static/media/e4af272ccee01ff0-s.p.woff2"]},"appUsingSizeAdjust":true,"pagesUsingSizeAdjust":false}
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -1 +0,0 @@
|
||||
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY\"\n}"
|
||||
@ -1,5 +0,0 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {},
|
||||
"encryptionKey": "UJCuqkc43Q1Tu8qgslshb0xL4QAUycNhcPIjjC8lUyo="
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
exports.id = "vendor-chunks/@swc";
|
||||
exports.ids = ["vendor-chunks/@swc"];
|
||||
exports.modules = {
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_base.js":
|
||||
/*!**************************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_class_private_field_loose_base.js ***!
|
||||
\**************************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _class_private_field_loose_base)\n/* harmony export */ });\nfunction _class_private_field_loose_base(receiver, privateKey) {\n if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {\n throw new TypeError(\"attempted to use private field on non-instance\");\n }\n\n return receiver;\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9fY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9iYXNlLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ2dEIiwic291cmNlcyI6WyIvaG9tZS9zb3J0aS9wcm9qZWN0cy9ob3N0aW5nLWZyb250ZW5kL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvZXNtL19jbGFzc19wcml2YXRlX2ZpZWxkX2xvb3NlX2Jhc2UuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2NsYXNzX3ByaXZhdGVfZmllbGRfbG9vc2VfYmFzZShyZWNlaXZlciwgcHJpdmF0ZUtleSkge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY2VpdmVyLCBwcml2YXRlS2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHVzZSBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVjZWl2ZXI7XG59XG5leHBvcnQgeyBfY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9iYXNlIGFzIF8gfTtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_base.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_key.js":
|
||||
/*!*************************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_class_private_field_loose_key.js ***!
|
||||
\*************************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _class_private_field_loose_key)\n/* harmony export */ });\nvar id = 0;\n\nfunction _class_private_field_loose_key(name) {\n return \"__private_\" + id++ + \"_\" + name;\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9fY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9rZXkuanMiLCJtYXBwaW5ncyI6Ijs7OztBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUMrQyIsInNvdXJjZXMiOlsiL2hvbWUvc29ydGkvcHJvamVjdHMvaG9zdGluZy1mcm9udGVuZC9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9fY2xhc3NfcHJpdmF0ZV9maWVsZF9sb29zZV9rZXkuanMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGlkID0gMDtcblxuZnVuY3Rpb24gX2NsYXNzX3ByaXZhdGVfZmllbGRfbG9vc2Vfa2V5KG5hbWUpIHtcbiAgICByZXR1cm4gXCJfX3ByaXZhdGVfXCIgKyBpZCsrICsgXCJfXCIgKyBuYW1lO1xufVxuZXhwb3J0IHsgX2NsYXNzX3ByaXZhdGVfZmllbGRfbG9vc2Vfa2V5IGFzIF8gfTtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_class_private_field_loose_key.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_interop_require_default.js":
|
||||
/*!*******************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_interop_require_default.js ***!
|
||||
\*******************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _interop_require_default)\n/* harmony export */ });\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : { default: obj };\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9faW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQuanMiLCJtYXBwaW5ncyI6Ijs7OztBQUFBO0FBQ0EsMkNBQTJDO0FBQzNDO0FBQ3lDIiwic291cmNlcyI6WyIvaG9tZS9zb3J0aS9wcm9qZWN0cy9ob3N0aW5nLWZyb250ZW5kL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvZXNtL19pbnRlcm9wX3JlcXVpcmVfZGVmYXVsdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfaW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07XG59XG5leHBvcnQgeyBfaW50ZXJvcF9yZXF1aXJlX2RlZmF1bHQgYXMgXyB9O1xuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_interop_require_default.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "(ssr)/./node_modules/@swc/helpers/esm/_interop_require_wildcard.js":
|
||||
/*!********************************************************************!*\
|
||||
!*** ./node_modules/@swc/helpers/esm/_interop_require_wildcard.js ***!
|
||||
\********************************************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ _: () => (/* binding */ _interop_require_wildcard)\n/* harmony export */ });\nfunction _getRequireWildcardCache(nodeInterop) {\n if (typeof WeakMap !== \"function\") return null;\n\n var cacheBabelInterop = new WeakMap();\n var cacheNodeInterop = new WeakMap();\n\n return (_getRequireWildcardCache = function(nodeInterop) {\n return nodeInterop ? cacheNodeInterop : cacheBabelInterop;\n })(nodeInterop);\n}\nfunction _interop_require_wildcard(obj, nodeInterop) {\n if (!nodeInterop && obj && obj.__esModule) return obj;\n if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") return { default: obj };\n\n var cache = _getRequireWildcardCache(nodeInterop);\n\n if (cache && cache.has(obj)) return cache.get(obj);\n\n var newObj = { __proto__: null };\n var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;\n\n for (var key in obj) {\n if (key !== \"default\" && Object.prototype.hasOwnProperty.call(obj, key)) {\n var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;\n if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);\n else newObj[key] = obj[key];\n }\n }\n\n newObj.default = obj;\n\n if (cache) cache.set(obj, newObj);\n\n return newObj;\n}\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHN3Yy9oZWxwZXJzL2VzbS9faW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSx1RkFBdUY7O0FBRXZGOztBQUVBOztBQUVBLG1CQUFtQjtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQzBDIiwic291cmNlcyI6WyIvaG9tZS9zb3J0aS9wcm9qZWN0cy9ob3N0aW5nLWZyb250ZW5kL25vZGVfbW9kdWxlcy9Ac3djL2hlbHBlcnMvZXNtL19pbnRlcm9wX3JlcXVpcmVfd2lsZGNhcmQuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlKG5vZGVJbnRlcm9wKSB7XG4gICAgaWYgKHR5cGVvZiBXZWFrTWFwICE9PSBcImZ1bmN0aW9uXCIpIHJldHVybiBudWxsO1xuXG4gICAgdmFyIGNhY2hlQmFiZWxJbnRlcm9wID0gbmV3IFdlYWtNYXAoKTtcbiAgICB2YXIgY2FjaGVOb2RlSW50ZXJvcCA9IG5ldyBXZWFrTWFwKCk7XG5cbiAgICByZXR1cm4gKF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSA9IGZ1bmN0aW9uKG5vZGVJbnRlcm9wKSB7XG4gICAgICAgIHJldHVybiBub2RlSW50ZXJvcCA/IGNhY2hlTm9kZUludGVyb3AgOiBjYWNoZUJhYmVsSW50ZXJvcDtcbiAgICB9KShub2RlSW50ZXJvcCk7XG59XG5mdW5jdGlvbiBfaW50ZXJvcF9yZXF1aXJlX3dpbGRjYXJkKG9iaiwgbm9kZUludGVyb3ApIHtcbiAgICBpZiAoIW5vZGVJbnRlcm9wICYmIG9iaiAmJiBvYmouX19lc01vZHVsZSkgcmV0dXJuIG9iajtcbiAgICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4geyBkZWZhdWx0OiBvYmogfTtcblxuICAgIHZhciBjYWNoZSA9IF9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZShub2RlSW50ZXJvcCk7XG5cbiAgICBpZiAoY2FjaGUgJiYgY2FjaGUuaGFzKG9iaikpIHJldHVybiBjYWNoZS5nZXQob2JqKTtcblxuICAgIHZhciBuZXdPYmogPSB7IF9fcHJvdG9fXzogbnVsbCB9O1xuICAgIHZhciBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKGtleSAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgdmFyIGRlc2MgPSBoYXNQcm9wZXJ0eURlc2NyaXB0b3IgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KSA6IG51bGw7XG4gICAgICAgICAgICBpZiAoZGVzYyAmJiAoZGVzYy5nZXQgfHwgZGVzYy5zZXQpKSBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpO1xuICAgICAgICAgICAgZWxzZSBuZXdPYmpba2V5XSA9IG9ialtrZXldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmV3T2JqLmRlZmF1bHQgPSBvYmo7XG5cbiAgICBpZiAoY2FjaGUpIGNhY2hlLnNldChvYmosIG5ld09iaik7XG5cbiAgICByZXR1cm4gbmV3T2JqO1xufVxuZXhwb3J0IHsgX2ludGVyb3BfcmVxdWlyZV93aWxkY2FyZCBhcyBfIH07XG4iXSwibmFtZXMiOltdLCJpZ25vcmVMaXN0IjpbMF0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@swc/helpers/esm/_interop_require_wildcard.js\n");
|
||||
|
||||
/***/ })
|
||||
|
||||
};
|
||||
;
|
||||
File diff suppressed because one or more lines are too long
@ -1,25 +0,0 @@
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
exports.id = "vendor-chunks/clsx";
|
||||
exports.ids = ["vendor-chunks/clsx"];
|
||||
exports.modules = {
|
||||
|
||||
/***/ "(rsc)/./node_modules/clsx/dist/clsx.mjs":
|
||||
/*!*****************************************!*\
|
||||
!*** ./node_modules/clsx/dist/clsx.mjs ***!
|
||||
\*****************************************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clsx: () => (/* binding */ clsx),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clsx);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9ub2RlX21vZHVsZXMvY2xzeC9kaXN0L2Nsc3gubWpzIiwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsY0FBYyxhQUFhLCtDQUErQyxnREFBZ0QsZUFBZSxRQUFRLElBQUksMENBQTBDLHlDQUF5QyxTQUFnQixnQkFBZ0Isd0NBQXdDLElBQUksbURBQW1ELFNBQVMsaUVBQWUsSUFBSSIsInNvdXJjZXMiOlsiL2hvbWUvc29ydGkvcHJvamVjdHMvaG9zdGluZy1mcm9udGVuZC9ub2RlX21vZHVsZXMvY2xzeC9kaXN0L2Nsc3gubWpzIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIHIoZSl7dmFyIHQsZixuPVwiXCI7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGV8fFwibnVtYmVyXCI9PXR5cGVvZiBlKW4rPWU7ZWxzZSBpZihcIm9iamVjdFwiPT10eXBlb2YgZSlpZihBcnJheS5pc0FycmF5KGUpKXt2YXIgbz1lLmxlbmd0aDtmb3IodD0wO3Q8bzt0KyspZVt0XSYmKGY9cihlW3RdKSkmJihuJiYobis9XCIgXCIpLG4rPWYpfWVsc2UgZm9yKGYgaW4gZSllW2ZdJiYobiYmKG4rPVwiIFwiKSxuKz1mKTtyZXR1cm4gbn1leHBvcnQgZnVuY3Rpb24gY2xzeCgpe2Zvcih2YXIgZSx0LGY9MCxuPVwiXCIsbz1hcmd1bWVudHMubGVuZ3RoO2Y8bztmKyspKGU9YXJndW1lbnRzW2ZdKSYmKHQ9cihlKSkmJihuJiYobis9XCIgXCIpLG4rPXQpO3JldHVybiBufWV4cG9ydCBkZWZhdWx0IGNsc3g7Il0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/clsx/dist/clsx.mjs\n");
|
||||
|
||||
/***/ })
|
||||
|
||||
};
|
||||
;
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
self.__BUILD_MANIFEST = (function(a){return {__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:a,__routerFilterDynamic:a,sortedPages:["\u002F_app"]}}(void 0));self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB()
|
||||
@ -1 +0,0 @@
|
||||
self.__SSG_MANIFEST=new Set;self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
||||
{"c":["app/layout","webpack"],"r":[],"m":[]}
|
||||
@ -1 +0,0 @@
|
||||
{"c":[],"r":[],"m":[]}
|
||||
@ -1,22 +0,0 @@
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
self["webpackHotUpdate_N_E"]("app/layout",{
|
||||
|
||||
/***/ "(app-pages-browser)/./app/globals.css":
|
||||
/*!*************************!*\
|
||||
!*** ./app/globals.css ***!
|
||||
\*************************/
|
||||
/***/ ((module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (\"f7e2466089dd\");\nif (true) { module.hot.accept() }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKGFwcC1wYWdlcy1icm93c2VyKS8uL2FwcC9nbG9iYWxzLmNzcyIsIm1hcHBpbmdzIjoiOzs7O0FBQUEsaUVBQWUsY0FBYztBQUM3QixJQUFJLElBQVUsSUFBSSxpQkFBaUIiLCJzb3VyY2VzIjpbIi9ob21lL3NvcnRpL3Byb2plY3RzL2hvc3RpbmctZnJvbnRlbmQvYXBwL2dsb2JhbHMuY3NzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IFwiZjdlMjQ2NjA4OWRkXCJcbmlmIChtb2R1bGUuaG90KSB7IG1vZHVsZS5ob3QuYWNjZXB0KCkgfVxuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(app-pages-browser)/./app/globals.css\n"));
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
@ -1,12 +0,0 @@
|
||||
"use strict";
|
||||
self["webpackHotUpdate_N_E"]("webpack",{},
|
||||
/******/ function(__webpack_require__) { // webpackRuntimeModules
|
||||
/******/ /* webpack/runtime/getFullHash */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.h = () => ("8e3f0ede0ae7b4ef")
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ }
|
||||
)
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJpZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZXMiOlsid2VicGFjay1pbnRlcm5hbDovL25leHRqcy93ZWJwYWNrLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoaXMgc291cmNlIHdhcyBnZW5lcmF0ZWQgYnkgTmV4dC5qcyBiYXNlZCBvZmYgb2YgdGhlIGdlbmVyYXRlZCBXZWJwYWNrIHJ1bnRpbWUuXG4vLyBUaGUgbWFwcGluZ3MgYXJlIGluY29ycmVjdC5cbi8vIFRvIGdldCB0aGUgY29ycmVjdCBsaW5lL2NvbHVtbiBtYXBwaW5ncywgdHVybiBvZmYgc291cmNlbWFwcyBpbiB5b3VyIGRlYnVnZ2VyLlxuXG5zZWxmW1wid2VicGFja0hvdFVwZGF0ZV9OX0VcIl0oXCJ3ZWJwYWNrXCIse30sXG4vKioqKioqLyBmdW5jdGlvbihfX3dlYnBhY2tfcmVxdWlyZV9fKSB7IC8vIHdlYnBhY2tSdW50aW1lTW9kdWxlc1xuLyoqKioqKi8gLyogd2VicGFjay9ydW50aW1lL2dldEZ1bGxIYXNoICovXG4vKioqKioqLyAoKCkgPT4ge1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmggPSAoKSA9PiAoXCI4ZTNmMGVkZTBhZTdiNGVmXCIpXG4vKioqKioqLyB9KSgpO1xuLyoqKioqKi8gXG4vKioqKioqLyB9XG4pIl19
|
||||
;
|
||||
10
.next/trace
10
.next/trace
File diff suppressed because one or more lines are too long
@ -1,84 +0,0 @@
|
||||
// File: /home/sorti/projects/hosting-frontend/app/layout.tsx
|
||||
import * as entry from '../../../app/layout.js'
|
||||
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
|
||||
|
||||
type TEntry = typeof import('../../../app/layout.js')
|
||||
|
||||
type SegmentParams<T extends Object = any> = T extends Record<string, any>
|
||||
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
|
||||
: T
|
||||
|
||||
// Check that the entry is a valid entry
|
||||
checkFields<Diff<{
|
||||
default: Function
|
||||
config?: {}
|
||||
generateStaticParams?: Function
|
||||
revalidate?: RevalidateRange<TEntry> | false
|
||||
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
|
||||
dynamicParams?: boolean
|
||||
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
|
||||
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
|
||||
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
|
||||
maxDuration?: number
|
||||
|
||||
metadata?: any
|
||||
generateMetadata?: Function
|
||||
viewport?: any
|
||||
generateViewport?: Function
|
||||
experimental_ppr?: boolean
|
||||
|
||||
}, TEntry, ''>>()
|
||||
|
||||
|
||||
// Check the prop type of the entry function
|
||||
checkFields<Diff<LayoutProps, FirstArg<TEntry['default']>, 'default'>>()
|
||||
|
||||
// Check the arguments and return type of the generateMetadata function
|
||||
if ('generateMetadata' in entry) {
|
||||
checkFields<Diff<LayoutProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateViewport function
|
||||
if ('generateViewport' in entry) {
|
||||
checkFields<Diff<LayoutProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateStaticParams function
|
||||
if ('generateStaticParams' in entry) {
|
||||
checkFields<Diff<{ params: SegmentParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
|
||||
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
|
||||
}
|
||||
|
||||
export interface PageProps {
|
||||
params?: Promise<SegmentParams>
|
||||
searchParams?: Promise<any>
|
||||
}
|
||||
export interface LayoutProps {
|
||||
children?: React.ReactNode
|
||||
|
||||
params?: Promise<SegmentParams>
|
||||
}
|
||||
|
||||
// =============
|
||||
// Utility types
|
||||
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
|
||||
|
||||
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
|
||||
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
|
||||
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
|
||||
|
||||
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
|
||||
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
|
||||
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
|
||||
|
||||
|
||||
|
||||
function checkFields<_ extends { [k in keyof any]: never }>() {}
|
||||
|
||||
// https://github.com/sindresorhus/type-fest
|
||||
type Numeric = number | bigint
|
||||
type Zero = 0 | 0n
|
||||
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
|
||||
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'
|
||||
@ -1,84 +0,0 @@
|
||||
// File: /home/sorti/projects/hosting-frontend/app/page.tsx
|
||||
import * as entry from '../../../app/page.js'
|
||||
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
|
||||
|
||||
type TEntry = typeof import('../../../app/page.js')
|
||||
|
||||
type SegmentParams<T extends Object = any> = T extends Record<string, any>
|
||||
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
|
||||
: T
|
||||
|
||||
// Check that the entry is a valid entry
|
||||
checkFields<Diff<{
|
||||
default: Function
|
||||
config?: {}
|
||||
generateStaticParams?: Function
|
||||
revalidate?: RevalidateRange<TEntry> | false
|
||||
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
|
||||
dynamicParams?: boolean
|
||||
fetchCache?: 'auto' | 'force-no-store' | 'only-no-store' | 'default-no-store' | 'default-cache' | 'only-cache' | 'force-cache'
|
||||
preferredRegion?: 'auto' | 'global' | 'home' | string | string[]
|
||||
runtime?: 'nodejs' | 'experimental-edge' | 'edge'
|
||||
maxDuration?: number
|
||||
|
||||
metadata?: any
|
||||
generateMetadata?: Function
|
||||
viewport?: any
|
||||
generateViewport?: Function
|
||||
experimental_ppr?: boolean
|
||||
|
||||
}, TEntry, ''>>()
|
||||
|
||||
|
||||
// Check the prop type of the entry function
|
||||
checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
|
||||
|
||||
// Check the arguments and return type of the generateMetadata function
|
||||
if ('generateMetadata' in entry) {
|
||||
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
checkFields<Diff<ResolvingMetadata, SecondArg<MaybeField<TEntry, 'generateMetadata'>>, 'generateMetadata'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateViewport function
|
||||
if ('generateViewport' in entry) {
|
||||
checkFields<Diff<PageProps, FirstArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
checkFields<Diff<ResolvingViewport, SecondArg<MaybeField<TEntry, 'generateViewport'>>, 'generateViewport'>>()
|
||||
}
|
||||
|
||||
// Check the arguments and return type of the generateStaticParams function
|
||||
if ('generateStaticParams' in entry) {
|
||||
checkFields<Diff<{ params: SegmentParams }, FirstArg<MaybeField<TEntry, 'generateStaticParams'>>, 'generateStaticParams'>>()
|
||||
checkFields<Diff<{ __tag__: 'generateStaticParams', __return_type__: any[] | Promise<any[]> }, { __tag__: 'generateStaticParams', __return_type__: ReturnType<MaybeField<TEntry, 'generateStaticParams'>> }>>()
|
||||
}
|
||||
|
||||
export interface PageProps {
|
||||
params?: Promise<SegmentParams>
|
||||
searchParams?: Promise<any>
|
||||
}
|
||||
export interface LayoutProps {
|
||||
children?: React.ReactNode
|
||||
|
||||
params?: Promise<SegmentParams>
|
||||
}
|
||||
|
||||
// =============
|
||||
// Utility types
|
||||
type RevalidateRange<T> = T extends { revalidate: any } ? NonNegative<T['revalidate']> : never
|
||||
|
||||
// If T is unknown or any, it will be an empty {} type. Otherwise, it will be the same as Omit<T, keyof Base>.
|
||||
type OmitWithTag<T, K extends keyof any, _M> = Omit<T, K>
|
||||
type Diff<Base, T extends Base, Message extends string = ''> = 0 extends (1 & T) ? {} : OmitWithTag<T, keyof Base, Message>
|
||||
|
||||
type FirstArg<T extends Function> = T extends (...args: [infer T, any]) => any ? unknown extends T ? any : T : never
|
||||
type SecondArg<T extends Function> = T extends (...args: [any, infer T]) => any ? unknown extends T ? any : T : never
|
||||
type MaybeField<T, K extends string> = T extends { [k in K]: infer G } ? G extends Function ? G : never : never
|
||||
|
||||
|
||||
|
||||
function checkFields<_ extends { [k in keyof any]: never }>() {}
|
||||
|
||||
// https://github.com/sindresorhus/type-fest
|
||||
type Numeric = number | bigint
|
||||
type Zero = 0 | 0n
|
||||
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never
|
||||
type NonNegative<T extends Numeric> = T extends Zero ? T : Negative<T> extends never ? T : '__invalid_negative_number__'
|
||||
141
.next/types/cache-life.d.ts
vendored
141
.next/types/cache-life.d.ts
vendored
@ -1,141 +0,0 @@
|
||||
// Type definitions for Next.js cacheLife configs
|
||||
|
||||
declare module 'next/cache' {
|
||||
export { unstable_cache } from 'next/dist/server/web/spec-extension/unstable-cache'
|
||||
export {
|
||||
revalidateTag,
|
||||
revalidatePath,
|
||||
unstable_expireTag,
|
||||
unstable_expirePath,
|
||||
} from 'next/dist/server/web/spec-extension/revalidate'
|
||||
export { unstable_noStore } from 'next/dist/server/web/spec-extension/unstable-no-store'
|
||||
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"default"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 900 seconds (15 minutes)
|
||||
* expire: never
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 15 minutes, start revalidating new values in the background.
|
||||
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "default"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"seconds"` profile.
|
||||
* ```
|
||||
* stale: 30 seconds
|
||||
* revalidate: 1 seconds
|
||||
* expire: 60 seconds (1 minute)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 30 seconds before checking with the server.
|
||||
* If the server receives a new request after 1 seconds, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 minute it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "seconds"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"minutes"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 60 seconds (1 minute)
|
||||
* expire: 3600 seconds (1 hour)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 minute, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 hour it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "minutes"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"hours"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 3600 seconds (1 hour)
|
||||
* expire: 86400 seconds (1 day)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 hour, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 day it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "hours"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"days"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 86400 seconds (1 day)
|
||||
* expire: 604800 seconds (1 week)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 day, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 week it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "days"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"weeks"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 604800 seconds (1 week)
|
||||
* expire: 2592000 seconds (30 days)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 week, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 30 days it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "weeks"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"max"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 2592000 seconds (30 days)
|
||||
* expire: never
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 30 days, start revalidating new values in the background.
|
||||
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "max"): void
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` using a custom timespan.
|
||||
* ```
|
||||
* stale: ... // seconds
|
||||
* revalidate: ... // seconds
|
||||
* expire: ... // seconds
|
||||
* ```
|
||||
*
|
||||
* This is similar to Cache-Control: max-age=`stale`,s-max-age=`revalidate`,stale-while-revalidate=`expire-revalidate`
|
||||
*
|
||||
* If a value is left out, the lowest of other cacheLife() calls or the default, is used instead.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: {
|
||||
/**
|
||||
* This cache may be stale on clients for ... seconds before checking with the server.
|
||||
*/
|
||||
stale?: number,
|
||||
/**
|
||||
* If the server receives a new request after ... seconds, start revalidating new values in the background.
|
||||
*/
|
||||
revalidate?: number,
|
||||
/**
|
||||
* If this entry has no traffic for ... seconds it will expire. The next request will recompute it.
|
||||
*/
|
||||
expire?: number
|
||||
}): void
|
||||
|
||||
|
||||
export { cacheTag as unstable_cacheTag } from 'next/dist/server/use-cache/cache-tag'
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
{"type": "module"}
|
||||
60
.next/types/routes.d.ts
vendored
60
.next/types/routes.d.ts
vendored
@ -1,60 +0,0 @@
|
||||
// This file is generated automatically by Next.js
|
||||
// Do not edit this file manually
|
||||
|
||||
type AppRoutes = "/" | "/dashboard" | "/login" | "/register"
|
||||
type PageRoutes = never
|
||||
type LayoutRoutes = "/"
|
||||
type RedirectRoutes = never
|
||||
type RewriteRoutes = never
|
||||
type Routes = AppRoutes | PageRoutes | LayoutRoutes | RedirectRoutes | RewriteRoutes
|
||||
|
||||
|
||||
interface ParamMap {
|
||||
"/": {}
|
||||
"/dashboard": {}
|
||||
"/login": {}
|
||||
"/register": {}
|
||||
}
|
||||
|
||||
|
||||
export type ParamsOf<Route extends Routes> = ParamMap[Route]
|
||||
|
||||
interface LayoutSlotMap {
|
||||
"/": never
|
||||
}
|
||||
|
||||
|
||||
export type { AppRoutes, PageRoutes, LayoutRoutes, RedirectRoutes, RewriteRoutes, ParamMap }
|
||||
|
||||
declare global {
|
||||
/**
|
||||
* Props for Next.js App Router page components
|
||||
* @example
|
||||
* ```tsx
|
||||
* export default function Page(props: PageProps<'/blog/[slug]'>) {
|
||||
* const { slug } = await props.params
|
||||
* return <div>Blog post: {slug}</div>
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
interface PageProps<AppRoute extends AppRoutes> {
|
||||
params: Promise<ParamMap[AppRoute]>
|
||||
searchParams: Promise<Record<string, string | string[] | undefined>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for Next.js App Router layout components
|
||||
* @example
|
||||
* ```tsx
|
||||
* export default function Layout(props: LayoutProps<'/dashboard'>) {
|
||||
* return <div>{props.children}</div>
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
type LayoutProps<LayoutRoute extends LayoutRoutes> = {
|
||||
params: Promise<ParamMap[LayoutRoute]>
|
||||
children: React.ReactNode
|
||||
} & {
|
||||
[K in LayoutSlotMap[LayoutRoute]]: React.ReactNode
|
||||
}
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
// This file is generated automatically by Next.js
|
||||
// Do not edit this file manually
|
||||
// This file validates that all pages and layouts export the correct types
|
||||
|
||||
import type { AppRoutes, LayoutRoutes, ParamMap } from "./routes.js"
|
||||
import type { ResolvingMetadata, ResolvingViewport } from "next/types.js"
|
||||
|
||||
type AppPageConfig<Route extends AppRoutes = AppRoutes> = {
|
||||
default: React.ComponentType<{ params: Promise<ParamMap[Route]> } & any> | ((props: { params: Promise<ParamMap[Route]> } & any) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
|
||||
generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
|
||||
generateMetadata?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingMetadata
|
||||
) => Promise<any> | any
|
||||
generateViewport?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingViewport
|
||||
) => Promise<any> | any
|
||||
metadata?: any
|
||||
viewport?: any
|
||||
}
|
||||
|
||||
type LayoutConfig<Route extends LayoutRoutes = LayoutRoutes> = {
|
||||
default: React.ComponentType<LayoutProps<Route>> | ((props: LayoutProps<Route>) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
|
||||
generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
|
||||
generateMetadata?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingMetadata
|
||||
) => Promise<any> | any
|
||||
generateViewport?: (
|
||||
props: { params: Promise<ParamMap[Route]> } & any,
|
||||
parent: ResolvingViewport
|
||||
) => Promise<any> | any
|
||||
metadata?: any
|
||||
viewport?: any
|
||||
}
|
||||
|
||||
|
||||
// Validate ../../app/dashboard/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/dashboard">> = Specific
|
||||
const handler = {} as typeof import("../../app/dashboard/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../app/login/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/login">> = Specific
|
||||
const handler = {} as typeof import("../../app/login/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../app/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/">> = Specific
|
||||
const handler = {} as typeof import("../../app/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
// Validate ../../app/register/page.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends AppPageConfig<"/register">> = Specific
|
||||
const handler = {} as typeof import("../../app/register/page.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Validate ../../app/layout.tsx
|
||||
{
|
||||
type __IsExpected<Specific extends LayoutConfig<"/">> = Specific
|
||||
const handler = {} as typeof import("../../app/layout.js")
|
||||
type __Check = __IsExpected<typeof handler>
|
||||
// @ts-ignore
|
||||
type __Unused = __Check
|
||||
}
|
||||
18
AGENTS.md
18
AGENTS.md
@ -1,18 +0,0 @@
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
These instructions are for AI assistants working in this project.
|
||||
|
||||
Always open `@/openspec/AGENTS.md` when the request:
|
||||
- Mentions planning or proposals (words like proposal, spec, change, plan)
|
||||
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
|
||||
- Sounds ambiguous and you need the authoritative spec before coding
|
||||
|
||||
Use `@/openspec/AGENTS.md` to learn:
|
||||
- How to create and apply change proposals
|
||||
- Spec format and conventions
|
||||
- Project structure and guidelines
|
||||
|
||||
Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
|
||||
<!-- OPENSPEC:END -->
|
||||
18
CLAUDE.md
18
CLAUDE.md
@ -1,18 +0,0 @@
|
||||
<!-- OPENSPEC:START -->
|
||||
# OpenSpec Instructions
|
||||
|
||||
These instructions are for AI assistants working in this project.
|
||||
|
||||
Always open `@/openspec/AGENTS.md` when the request:
|
||||
- Mentions planning or proposals (words like proposal, spec, change, plan)
|
||||
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
|
||||
- Sounds ambiguous and you need the authoritative spec before coding
|
||||
|
||||
Use `@/openspec/AGENTS.md` to learn:
|
||||
- How to create and apply change proposals
|
||||
- Spec format and conventions
|
||||
- Project structure and guidelines
|
||||
|
||||
Keep this managed block so 'openspec update' can refresh the instructions.
|
||||
|
||||
<!-- OPENSPEC:END -->
|
||||
47
Dockerfile
47
Dockerfile
@ -1,47 +0,0 @@
|
||||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
# Install dependencies (including dev dependencies for build)
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code and configuration
|
||||
COPY . .
|
||||
|
||||
# Build Next.js application with standalone output
|
||||
RUN npm run build
|
||||
|
||||
# Runtime stage
|
||||
FROM node:20-alpine
|
||||
|
||||
# Create non-root user for security
|
||||
RUN addgroup -g 101 nextjs && \
|
||||
adduser -D -u 101 -G nextjs nextjs
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy standalone output from builder stage
|
||||
COPY --from=builder --chown=nextjs:nextjs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nextjs /app/.next/static ./.next/static
|
||||
COPY --from=builder --chown=nextjs:nextjs /app/public ./public
|
||||
|
||||
# Set environment for production
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD node -e "require('http').get('http://localhost:3000/', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
|
||||
|
||||
# Run as non-root user
|
||||
USER nextjs
|
||||
|
||||
# Start the application
|
||||
CMD ["node", "server.js"]
|
||||
288
README.md
288
README.md
@ -1,299 +1,59 @@
|
||||
# Portfolio Hosting Platform - Frontend
|
||||
# HostingFrontend
|
||||
|
||||
A modern Next.js application for managing and deploying portfolio websites with custom domains.
|
||||
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.0.0.
|
||||
|
||||
## Tech Stack
|
||||
## Development server
|
||||
|
||||
- **Framework**: Next.js 15 with App Router
|
||||
- **Language**: TypeScript 5.8
|
||||
- **Styling**: Tailwind CSS 4.1 with shadcn/ui components
|
||||
- **State Management**: React Context API + hooks
|
||||
- **Forms**: React Hook Form
|
||||
- **Icons**: Lucide React
|
||||
- **Authentication**: JWT Bearer tokens
|
||||
|
||||
## Features
|
||||
|
||||
- **User Authentication**: Login and registration with JWT tokens
|
||||
- **Portfolio Management**: Create, upload, and deploy portfolio websites
|
||||
- **File Upload**: ZIP file upload with progress tracking
|
||||
- **Dashboard**: Comprehensive portfolio management interface
|
||||
- **Responsive Design**: Mobile-first, fully responsive UI
|
||||
- **Protected Routes**: Middleware-based authentication
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
/
|
||||
├── app/ # Next.js App Router pages
|
||||
│ ├── layout.tsx # Root layout with AuthProvider
|
||||
│ ├── page.tsx # Landing page
|
||||
│ ├── login/ # Login page
|
||||
│ ├── register/ # Registration page
|
||||
│ └── dashboard/ # Dashboard (protected)
|
||||
├── components/ # React components
|
||||
│ ├── ui/ # shadcn/ui primitives
|
||||
│ └── auth/ # Authentication components
|
||||
├── lib/ # Utilities and API client
|
||||
│ ├── api-client.ts # Fetch wrapper with auth
|
||||
│ ├── types.ts # TypeScript interfaces
|
||||
│ └── utils.ts # Utility functions
|
||||
├── hooks/ # Custom React hooks
|
||||
│ ├── use-auth.ts # Authentication hook
|
||||
│ └── use-portfolios.ts # Portfolio data hook
|
||||
└── middleware.ts # Route protection
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 18+ and npm
|
||||
- Backend API running (see API section)
|
||||
|
||||
### Installation
|
||||
To start a local development server, run:
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Set up environment variables
|
||||
cp .env.local.example .env.local
|
||||
# Edit .env.local with your API URL
|
||||
ng serve
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
||||
|
||||
Create a `.env.local` file:
|
||||
## Code scaffolding
|
||||
|
||||
```env
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8000/api
|
||||
```
|
||||
|
||||
For production, create `.env.production`:
|
||||
|
||||
```env
|
||||
NEXT_PUBLIC_API_URL=https://api.portfolio-host.com/api
|
||||
```
|
||||
|
||||
### Development
|
||||
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
||||
|
||||
```bash
|
||||
# Start development server
|
||||
npm run dev
|
||||
ng generate component component-name
|
||||
```
|
||||
|
||||
Visit [http://localhost:3000](http://localhost:3000)
|
||||
|
||||
### Build
|
||||
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
||||
|
||||
```bash
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Start production server
|
||||
npm start
|
||||
ng generate --help
|
||||
```
|
||||
|
||||
### Docker Deployment
|
||||
## Building
|
||||
|
||||
The project includes a multi-stage Dockerfile optimized for Next.js standalone output:
|
||||
To build the project run:
|
||||
|
||||
```bash
|
||||
# Build Docker image
|
||||
docker build -t hosting-frontend:latest .
|
||||
|
||||
# Run container with default settings
|
||||
docker run -p 3000:3000 hosting-frontend:latest
|
||||
|
||||
# Run with custom API URL
|
||||
docker run -p 3000:3000 \
|
||||
-e NEXT_PUBLIC_API_URL=https://api.example.com/api \
|
||||
hosting-frontend:latest
|
||||
|
||||
# Run with Docker Compose
|
||||
docker-compose up
|
||||
ng build
|
||||
```
|
||||
|
||||
#### Docker Image Features
|
||||
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
|
||||
|
||||
- **Multi-stage build**: Separates build and runtime stages for minimal image size
|
||||
- **Standalone output**: Uses Next.js `output: 'standalone'` mode (~150-200MB image)
|
||||
- **Non-root user**: Container runs as `nextjs` user (UID 1000) for security
|
||||
- **Health check**: Includes automatic health check endpoint monitoring
|
||||
- **Node.js 20 Alpine**: Lightweight runtime based on Alpine Linux
|
||||
## Running unit tests
|
||||
|
||||
#### Docker Environment Variables
|
||||
|
||||
Pass environment variables at runtime:
|
||||
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
-e NEXT_PUBLIC_API_URL=https://api.example.com/api \
|
||||
-e PORT=3000 \
|
||||
-p 3000:3000 \
|
||||
hosting-frontend:latest
|
||||
ng test
|
||||
```
|
||||
|
||||
#### Building Optimized Images
|
||||
## Running end-to-end tests
|
||||
|
||||
The `.dockerignore` file excludes unnecessary files from the build context:
|
||||
|
||||
- Development dependencies
|
||||
- Git history
|
||||
- Node modules (rebuilt in build stage)
|
||||
- Local environment files
|
||||
|
||||
## API Integration
|
||||
|
||||
The application integrates with a backend API for:
|
||||
|
||||
### Authentication Endpoints
|
||||
- `POST /auth/register` - User registration
|
||||
- `POST /auth/login` - User login
|
||||
- `POST /auth/logout` - Logout
|
||||
- `GET /auth/user` - Get current user
|
||||
- `POST /auth/refresh` - Refresh token
|
||||
|
||||
### Portfolio Endpoints
|
||||
- `GET /portfolios` - List user's portfolios
|
||||
- `POST /portfolios` - Create new portfolio
|
||||
- `POST /portfolios/{id}/upload` - Upload ZIP file
|
||||
- `POST /portfolios/{id}/deploy` - Deploy portfolio
|
||||
- `GET /portfolio/random` - Get random portfolio
|
||||
|
||||
### API Response Format
|
||||
|
||||
All API responses follow this structure:
|
||||
|
||||
```typescript
|
||||
{
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message?: string;
|
||||
errors?: any;
|
||||
}
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
1. User logs in via `/login`
|
||||
2. API returns JWT token
|
||||
3. Token stored in localStorage
|
||||
4. AuthContext provides auth state globally
|
||||
5. Middleware protects `/dashboard/*` routes
|
||||
6. API client automatically injects Bearer token
|
||||
|
||||
### Portfolio Management Flow
|
||||
|
||||
1. User creates portfolio (name + domain)
|
||||
2. Upload ZIP file containing portfolio files
|
||||
3. Deploy portfolio to make it live
|
||||
4. Status indicators show portfolio state:
|
||||
- **Pending Payment**: Not yet active
|
||||
- **Pending Upload**: Active but no files
|
||||
- **Uploaded**: Ready to deploy
|
||||
|
||||
## Code Style & Conventions
|
||||
|
||||
### File Naming
|
||||
- Components: `PascalCase.tsx`
|
||||
- Utilities: `kebab-case.ts`
|
||||
- Pages: Next.js conventions (`page.tsx`, `layout.tsx`)
|
||||
|
||||
### Component Patterns
|
||||
- Use `'use client'` directive for client components
|
||||
- Server components by default
|
||||
- Colocate styles with components
|
||||
|
||||
### State Management
|
||||
- Global auth state: `AuthContext`
|
||||
- Component state: `useState`
|
||||
- Form state: React Hook Form
|
||||
|
||||
### API Calls
|
||||
- Use `apiClient` from `lib/api-client.ts`
|
||||
- Wrap in try/catch
|
||||
- Handle loading and error states
|
||||
|
||||
## Migration from Angular
|
||||
|
||||
This project was migrated from Angular 20 to Next.js 15. Key changes:
|
||||
|
||||
- **Framework**: Angular → Next.js + React
|
||||
- **Routing**: Angular Router → Next.js App Router
|
||||
- **State**: RxJS → React Context API
|
||||
- **Forms**: Angular Reactive Forms → React Hook Form
|
||||
- **HTTP**: Angular HttpClient → Fetch API
|
||||
|
||||
The Angular code has been backed up to `/angular-backup` for reference.
|
||||
|
||||
## Deployment
|
||||
|
||||
### Production Build
|
||||
|
||||
The production build uses Next.js standalone output for optimal performance:
|
||||
For end-to-end (e2e) testing, run:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
ng e2e
|
||||
```
|
||||
|
||||
Output is in `.next/standalone/`
|
||||
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
||||
|
||||
### Environment Configuration
|
||||
## Additional Resources
|
||||
|
||||
- Development: `.env.local`
|
||||
- Production: `.env.production`
|
||||
- Staging: `.env.staging`
|
||||
|
||||
### Docker
|
||||
|
||||
The included `Dockerfile` creates an optimized production image:
|
||||
|
||||
```dockerfile
|
||||
# Build and run
|
||||
docker build -t portfolio-frontend .
|
||||
docker run -p 3000:3000 -e NEXT_PUBLIC_API_URL=https://api.example.com portfolio-frontend
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Errors
|
||||
|
||||
**Issue**: Tailwind CSS errors
|
||||
```bash
|
||||
# Ensure @tailwindcss/postcss is installed
|
||||
npm install @tailwindcss/postcss
|
||||
```
|
||||
|
||||
**Issue**: TypeScript errors
|
||||
```bash
|
||||
# Regenerate types
|
||||
rm -rf .next
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Runtime Errors
|
||||
|
||||
**Issue**: API connection failed
|
||||
- Check `NEXT_PUBLIC_API_URL` in `.env.local`
|
||||
- Verify backend API is running
|
||||
- Check CORS configuration on backend
|
||||
|
||||
**Issue**: Authentication not working
|
||||
- Check localStorage for `auth_token`
|
||||
- Verify JWT token format
|
||||
- Check middleware configuration
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Create feature branch from `main`
|
||||
2. Make changes following code style
|
||||
3. Test locally with `npm run build`
|
||||
4. Submit pull request
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2025 Portfolio Host. All rights reserved.
|
||||
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"hosting-frontend": {
|
||||
"projectType": "application",
|
||||
"schematics": {},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular/build:application",
|
||||
"options": {
|
||||
"browser": "src/main.ts",
|
||||
"polyfills": [
|
||||
"zone.js"
|
||||
],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kB",
|
||||
"maximumError": "1MB"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "16kB",
|
||||
"maximumError": "32kB"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular/build:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "hosting-frontend:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "hosting-frontend:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular/build:extract-i18n"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular/build:karma",
|
||||
"options": {
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideBrowserGlobalErrorListeners(),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(routes)
|
||||
]
|
||||
};
|
||||
@ -1 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
@ -1 +0,0 @@
|
||||
<router-outlet />
|
||||
@ -1,23 +0,0 @@
|
||||
import {Routes} from '@angular/router';
|
||||
import {LoginComponent} from './components/login/login.component';
|
||||
import {RegisterComponent} from './components/register/register.component';
|
||||
import {LandingComponent} from './components/landing/landing.component';
|
||||
import {DashboardComponent} from './components/dashboard/dashboard.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
|
||||
{
|
||||
path: 'login', component: LoginComponent, title: 'Login - Your App Name'
|
||||
},
|
||||
|
||||
{
|
||||
path: 'register', component: RegisterComponent, title: 'Register - Your App Name'
|
||||
},
|
||||
|
||||
{
|
||||
path: '', component: LandingComponent, title: 'Home'
|
||||
},
|
||||
|
||||
{path: 'dashboard', component: DashboardComponent}
|
||||
|
||||
];
|
||||
@ -1,23 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { App } from './app';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [App],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, hosting-frontend');
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user