Compare commits
10 Commits
b5fd4a4ca1
...
c27e1f2689
| Author | SHA1 | Date | |
|---|---|---|---|
| c27e1f2689 | |||
| d5903fb8d2 | |||
| 47e366ea2e | |||
| 5ead80fdc7 | |||
| c91fa2ce4d | |||
| 9483750161 | |||
| 6def9993da | |||
| 20a0b6c4e5 | |||
| 6be4875c5e | |||
| 95efb9652e |
+85
-26
@@ -1,6 +1,4 @@
|
||||
# GitLab CI for Laravel 12
|
||||
# Save this file as: .gitlab-ci.yml
|
||||
|
||||
# GitLab CI for Laravel 12 API
|
||||
workflow:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "push"'
|
||||
@@ -12,6 +10,7 @@ stages:
|
||||
- test
|
||||
- build
|
||||
- security
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
APP_ENV: testing
|
||||
@@ -41,16 +40,19 @@ cache:
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get install -y --no-install-recommends git unzip curl libzip-dev libpng-dev libonig-dev libxml2-dev libsqlite3-dev
|
||||
- docker-php-ext-install mbstring zip gd
|
||||
- docker-php-ext-install mbstring zip gd pdo_sqlite
|
||||
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||||
- rm composer-setup.php
|
||||
- composer install --prefer-dist --no-interaction --no-progress
|
||||
# Install Pint if not present
|
||||
- composer require --dev laravel/pint --ignore-platform-reqs || true
|
||||
# Generate .env with real keys
|
||||
- |
|
||||
cat > .env <<EOF
|
||||
APP_NAME=school_api
|
||||
APP_ENV=testing
|
||||
APP_KEY=
|
||||
APP_KEY=base64:$(openssl rand -base64 32)
|
||||
APP_DEBUG=false
|
||||
APP_URL=http://localhost
|
||||
|
||||
@@ -67,21 +69,23 @@ cache:
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
|
||||
JWT_SECRET=ci_dummy_secret_not_for_production
|
||||
JWT_SECRET=$(openssl rand -base64 32)
|
||||
EOF
|
||||
- mkdir -p database storage/framework/cache storage/framework/sessions storage/framework/views storage/logs bootstrap/cache reports
|
||||
- touch database/database.sqlite
|
||||
- php artisan key:generate --force
|
||||
- php artisan jwt:secret --force || true # If JWT package installed
|
||||
- php artisan config:clear
|
||||
- php artisan view:clear
|
||||
|
||||
composer_validate:
|
||||
extends: .php_laravel_job
|
||||
stage: validate
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- bash -o pipefail -c 'composer validate --strict 2>&1 | tee reports/composer-validate.log'
|
||||
- bash -o pipefail -c 'php -v 2>&1 | tee reports/php-version.log'
|
||||
- bash -o pipefail -c 'php artisan --version 2>&1 | tee reports/artisan-version.log'
|
||||
- composer validate --strict | tee reports/composer-validate.log
|
||||
- php -v | tee reports/php-version.log
|
||||
- php artisan --version | tee reports/artisan-version.log
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
@@ -94,60 +98,78 @@ laravel_pint:
|
||||
stage: validate
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- bash -o pipefail -c 'vendor/bin/pint --test 2>&1 | tee reports/pint.log'
|
||||
- vendor/bin/pint --test --format=json | tee reports/pint.json
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- reports/
|
||||
- storage/logs/
|
||||
allow_failure: true
|
||||
|
||||
phpunit:
|
||||
extends: .php_laravel_job
|
||||
stage: test
|
||||
parallel:
|
||||
matrix:
|
||||
- TEST_SUITE: [Unit, Feature]
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- bash -o pipefail -c 'php artisan migrate --force 2>&1 | tee reports/migrate.log'
|
||||
- bash -o pipefail -c 'php artisan test --testsuite=Feature --no-interaction --log-junit reports/phpunit-feature.xml 2>&1 | tee reports/phpunit-feature.log'
|
||||
- bash -o pipefail -c 'php artisan test --testsuite=Unit --no-interaction --log-junit reports/phpunit-unit.xml 2>&1 | tee reports/phpunit-unit.log'
|
||||
- php artisan migrate --force | tee reports/migrate.log
|
||||
- php artisan test --testsuite=$TEST_SUITE --coverage-text --log-junit reports/phpunit.xml | tee reports/phpunit.log
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
reports:
|
||||
junit:
|
||||
- reports/phpunit-feature.xml
|
||||
- reports/phpunit-unit.xml
|
||||
junit: reports/phpunit.xml
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: reports/coverage.xml
|
||||
paths:
|
||||
- reports/
|
||||
- storage/logs/
|
||||
coverage: '/^\s*Lines:\s*\d+\.\d+%/'
|
||||
cache:
|
||||
paths:
|
||||
- .composer-cache/
|
||||
- .npm-cache/
|
||||
- vendor/
|
||||
- node_modules/
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
|
||||
build_frontend:
|
||||
image: node:22-alpine
|
||||
stage: build
|
||||
before_script:
|
||||
- npm ci
|
||||
- npm ci --cache .npm --prefer-offline
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- sh -c 'npm run build 2>&1 | tee reports/npm-build.log'
|
||||
- npm run build 2>&1 | tee reports/npm-build.log
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- public/build/
|
||||
- public/css/
|
||||
- public/js/
|
||||
- reports/
|
||||
cache:
|
||||
paths:
|
||||
- .npm/
|
||||
|
||||
composer_audit:
|
||||
extends: .php_laravel_job
|
||||
stage: security
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- bash -o pipefail -c 'composer audit --locked --no-interaction 2>&1 | tee reports/composer-audit.log'
|
||||
- composer audit --locked --no-interaction --format=json | tee reports/composer-audit.json
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- reports/
|
||||
- storage/logs/
|
||||
allow_failure: true
|
||||
|
||||
npm_audit:
|
||||
image: node:22-alpine
|
||||
@@ -156,7 +178,7 @@ npm_audit:
|
||||
- npm ci
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- sh -c 'npm audit --audit-level=high 2>&1 | tee reports/npm-audit.log'
|
||||
- npm audit --json --audit-level=high | tee reports/npm-audit.json || true
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
@@ -172,14 +194,20 @@ secret_detection_basic:
|
||||
script:
|
||||
- mkdir -p reports
|
||||
- |
|
||||
echo "Scanning for obvious committed secrets..." | tee reports/secret-detection-basic.log
|
||||
! grep -RInE "(APP_KEY=base64:|DB_PASSWORD=.+|JWT_SECRET=.+|MAIL_PASSWORD=.+|PAYPAL_(CLIENT|SECRET|MODE)|AKIA[0-9A-Z]{16}|-----BEGIN (RSA|OPENSSH|PRIVATE) KEY-----)" \
|
||||
echo "Scanning for committed secrets..." | tee reports/secret-detection.log
|
||||
if grep -RInE "(APP_KEY=base64:[A-Za-z0-9+/=]{44}|DB_PASSWORD=.+|JWT_SECRET=.+|MAIL_PASSWORD=.+|PAYPAL_(CLIENT|SECRET|MODE)|AKIA[0-9A-Z]{16}|-----BEGIN (RSA|OPENSSH|PRIVATE) KEY-----)" \
|
||||
--exclude-dir=.git \
|
||||
--exclude-dir=vendor \
|
||||
--exclude-dir=node_modules \
|
||||
--exclude=.env.example \
|
||||
--exclude=.env.prod.example \
|
||||
. 2>&1 | tee -a reports/secret-detection-basic.log
|
||||
--exclude=reports \
|
||||
. 2>&1 | tee -a reports/secret-detection.log; then
|
||||
echo "❌ Secrets detected! Check reports/secret-detection.log"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ No secrets found"
|
||||
fi
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
@@ -187,9 +215,40 @@ secret_detection_basic:
|
||||
- reports/
|
||||
allow_failure: false
|
||||
|
||||
# Optional GitLab-native security scanners.
|
||||
# These run only if your GitLab tier/project supports the templates.
|
||||
# Deploy to shared hosting (optional - add if needed)
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: alpine:latest
|
||||
before_script:
|
||||
- apk add --no-cache openssh-client sshpass rsync
|
||||
script:
|
||||
- echo "Deploying to production..."
|
||||
- sshpass -p "$SSH_PASSWORD" rsync -avz --delete \
|
||||
-e "ssh -p $SSH_PORT -o StrictHostKeyChecking=no" \
|
||||
--exclude='.env' \
|
||||
--exclude='storage/logs/*' \
|
||||
--exclude='.git' \
|
||||
--exclude='tests' \
|
||||
--exclude='database/sqlite' \
|
||||
./ $SSH_USER@$SSH_HOST:$SSH_TARGET_DIR/
|
||||
environment:
|
||||
name: production
|
||||
url: $PRODUCTION_URL
|
||||
only:
|
||||
- main
|
||||
- master
|
||||
when: manual
|
||||
needs:
|
||||
- phpunit
|
||||
- composer_audit
|
||||
|
||||
# Include GitLab native templates (ensure you have license)
|
||||
include:
|
||||
- template: Jobs/SAST.gitlab-ci.yml
|
||||
- template: Jobs/Secret-Detection.gitlab-ci.yml
|
||||
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
|
||||
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
|
||||
|
||||
# Optional: Run SAST only on main branch
|
||||
sast:
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master"'
|
||||
@@ -0,0 +1 @@
|
||||
cookie
|
||||
@@ -0,0 +1 @@
|
||||
2026-06-11T07:11:03.205132Z WARN turborepo_filewatch: failed to wait for initial filesystem cookie: filewatching failed to start: waiting for cookie timed out: deadline has elapsed
|
||||
@@ -0,0 +1,16 @@
|
||||
FROM node:20-bookworm
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm install -g npm@10.5.0 --no-fund --no-audit
|
||||
RUN corepack enable
|
||||
|
||||
COPY package.json package-lock.json turbo.json tsconfig.base.json ./
|
||||
COPY apps ./apps
|
||||
COPY packages ./packages
|
||||
|
||||
RUN npm ci --no-fund --no-audit
|
||||
|
||||
EXPOSE 3000 3001 3002 3003 4000
|
||||
|
||||
CMD ["sh", "-c", "npm run db:generate && npm run dev"]
|
||||
@@ -0,0 +1,58 @@
|
||||
FROM node:20-bookworm AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable && corepack prepare npm@10.5.0 --activate
|
||||
|
||||
COPY package.json package-lock.json turbo.json tsconfig.base.json ./
|
||||
COPY apps ./apps
|
||||
COPY packages ./packages
|
||||
|
||||
# These URLs are read by Next.js config during `next build`, so the production
|
||||
# image must bake Docker-network service URLs instead of localhost defaults.
|
||||
ARG API_INTERNAL_URL=http://api:4000/api/v1
|
||||
ARG DASHBOARD_INTERNAL_URL=http://dashboard:3001
|
||||
ARG ADMIN_INTERNAL_URL=http://admin:3002
|
||||
|
||||
# NEXT_PUBLIC_* vars must be present at build time — they are inlined into JS bundles
|
||||
ARG NEXT_PUBLIC_API_URL
|
||||
ARG NEXT_PUBLIC_MARKETPLACE_URL
|
||||
ARG NEXT_PUBLIC_DASHBOARD_URL
|
||||
ARG NEXT_PUBLIC_ADMIN_URL
|
||||
ENV API_INTERNAL_URL=$API_INTERNAL_URL \
|
||||
DASHBOARD_INTERNAL_URL=$DASHBOARD_INTERNAL_URL \
|
||||
ADMIN_INTERNAL_URL=$ADMIN_INTERNAL_URL \
|
||||
NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL \
|
||||
NEXT_PUBLIC_MARKETPLACE_URL=$NEXT_PUBLIC_MARKETPLACE_URL \
|
||||
NEXT_PUBLIC_DASHBOARD_URL=$NEXT_PUBLIC_DASHBOARD_URL \
|
||||
NEXT_PUBLIC_ADMIN_URL=$NEXT_PUBLIC_ADMIN_URL
|
||||
|
||||
RUN npm install
|
||||
RUN npm run db:generate
|
||||
RUN npm run build
|
||||
|
||||
FROM node:20-bookworm AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN corepack enable && corepack prepare npm@10.5.0 --activate \
|
||||
&& groupadd --system --gid 10001 app \
|
||||
&& useradd --system --uid 10001 --gid app --home-dir /app --shell /usr/sbin/nologin app \
|
||||
&& mkdir -p /var/lib/rentaldrivego/storage/public /var/lib/rentaldrivego/storage/private /tmp/rentaldrivego \
|
||||
&& chown -R app:app /app /var/lib/rentaldrivego /tmp/rentaldrivego
|
||||
|
||||
COPY --from=builder --chown=app:app /app/package.json /app/package-lock.json /app/turbo.json /app/tsconfig.base.json ./
|
||||
COPY --from=builder --chown=app:app /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=app:app /app/apps ./apps
|
||||
COPY --from=builder --chown=app:app /app/packages ./packages
|
||||
COPY --chown=root:root docker/entrypoint.production.sh /usr/local/bin/rdg-entrypoint.sh
|
||||
|
||||
RUN chmod 755 /usr/local/bin/rdg-entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/rdg-entrypoint.sh"]
|
||||
|
||||
EXPOSE 3000 3001 3002 4000
|
||||
|
||||
CMD ["npm", "run", "start", "--workspace", "@rentaldrivego/api"]
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM node:20-bookworm
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable && corepack prepare npm@10.5.0 --activate
|
||||
|
||||
COPY package.json package-lock.json turbo.json tsconfig.base.json ./
|
||||
COPY apps ./apps
|
||||
COPY packages ./packages
|
||||
|
||||
RUN npm install
|
||||
|
||||
ENV NODE_ENV=test
|
||||
|
||||
CMD ["sh", "-c", "npm run db:deploy && npm run db:generate && npm run type-check && npm run build && npm run test:api:integration"]
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Link, useSearchParams } from 'react-router-dom'
|
||||
import { ApiHttpError } from '../../api/http'
|
||||
import { fetchInventoryDashboard } from '../../api/inventory'
|
||||
import { INVENTORY_BOOK_BASE } from './inventoryPaths'
|
||||
|
||||
/**
|
||||
* Inventory Dashboard — summary counts by type, low stock, out of stock, etc.
|
||||
* Backend: GET /api/v1/inventory/dashboard
|
||||
*/
|
||||
export function InventoryDashboardPage() {
|
||||
const [searchParams] = useSearchParams()
|
||||
const [data, setData] = useState<Record<string, unknown>>({})
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const load = useCallback(() => {
|
||||
setLoading(true)
|
||||
fetchInventoryDashboard(searchParams)
|
||||
.then((res) => {
|
||||
if (res && typeof res === 'object') {
|
||||
setData(res as Record<string, unknown>)
|
||||
}
|
||||
setError(null)
|
||||
})
|
||||
.catch((e: unknown) => {
|
||||
setError(e instanceof ApiHttpError ? e.message : 'Unable to load dashboard.')
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}, [searchParams])
|
||||
|
||||
useEffect(() => {
|
||||
load()
|
||||
}, [load])
|
||||
|
||||
const byType = (data.by_type as Record<string, number>) ?? {}
|
||||
const totalItems = Number(data.total_items ?? 0)
|
||||
const lowStockCount = Number(data.low_stock_count ?? 0)
|
||||
const outOfStockCount = Number(data.out_of_stock_count ?? 0)
|
||||
const needsRepairCount = Number(data.needs_repair_count ?? 0)
|
||||
const missingCount = Number(data.missing_count ?? 0)
|
||||
|
||||
return (
|
||||
<div className="container-fluid px-0 mt-3">
|
||||
<div className="d-flex justify-content-between align-items-center mb-3 px-3 flex-wrap gap-2">
|
||||
<h3 className="mb-0">Inventory Dashboard</h3>
|
||||
<div className="d-flex gap-2">
|
||||
<Link className="btn btn-outline-info btn-sm" to="/app/administrator/inventory/stock-status">
|
||||
Stock Status
|
||||
</Link>
|
||||
<Link className="btn btn-outline-secondary" to={INVENTORY_BOOK_BASE}>
|
||||
Back to Items
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error ? <div className="alert alert-danger mx-3">{error}</div> : null}
|
||||
|
||||
{loading ? (
|
||||
<p className="text-muted px-3">Loading…</p>
|
||||
) : (
|
||||
<div className="row g-3 px-3">
|
||||
{/* Summary Cards */}
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<div className="card border-primary h-100">
|
||||
<div className="card-body text-center">
|
||||
<h5 className="card-title text-primary">{totalItems}</h5>
|
||||
<p className="card-text">Total Items</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<div className="card border-warning h-100">
|
||||
<div className="card-body text-center">
|
||||
<h5 className="card-title text-warning">{lowStockCount}</h5>
|
||||
<p className="card-text">Low Stock Items</p>
|
||||
{lowStockCount > 0 ? (
|
||||
<Link className="btn btn-sm btn-warning" to="/app/administrator/inventory/low-stock">
|
||||
View Low Stock
|
||||
</Link>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<div className="card border-danger h-100">
|
||||
<div className="card-body text-center">
|
||||
<h5 className="card-title text-danger">{outOfStockCount}</h5>
|
||||
<p className="card-text">Out of Stock</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<div className="card border-info h-100">
|
||||
<div className="card-body text-center">
|
||||
<h5 className="card-title text-info">{needsRepairCount}</h5>
|
||||
<p className="card-text">Needs Repair</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<div className="card border-secondary h-100">
|
||||
<div className="card-body text-center">
|
||||
<h5 className="card-title text-secondary">{missingCount}</h5>
|
||||
<p className="card-text">Missing / Cannot Find</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Items by Type */}
|
||||
<div className="col-12">
|
||||
<div className="card">
|
||||
<div className="card-header">Items by Type</div>
|
||||
<div className="card-body">
|
||||
{Object.keys(byType).length === 0 ? (
|
||||
<p className="text-muted mb-0">No items found.</p>
|
||||
) : (
|
||||
<div className="table-responsive">
|
||||
<table className="table table-striped align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th className="text-end">Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.entries(byType).map(([type, count]) => (
|
||||
<tr key={type}>
|
||||
<td style={{ textTransform: 'capitalize' }}>{type}</td>
|
||||
<td className="text-end">{Number(count).toLocaleString()}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div className="col-12">
|
||||
<div className="card">
|
||||
<div className="card-header">Quick Actions</div>
|
||||
<div className="card-body">
|
||||
<div className="d-flex gap-2 flex-wrap">
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/classroom">
|
||||
Classroom Equipment
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to={INVENTORY_BOOK_BASE}>
|
||||
Books
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/office">
|
||||
Office Supplies
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/kitchen">
|
||||
Kitchen Supplies
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/movements">
|
||||
Movements
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/summary">
|
||||
Summary
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/reorder-suggestions">
|
||||
Reorder Suggestions
|
||||
</Link>
|
||||
<Link className="btn btn-outline-primary" to="/app/administrator/inventory/low-stock">
|
||||
Low Stock
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { ApiHttpError } from '../../api/http'
|
||||
import { fetchLowStock } from '../../api/inventory'
|
||||
import { INVENTORY_BOOK_BASE } from './inventoryPaths'
|
||||
|
||||
/**
|
||||
* Low Stock Items — items where quantity <= reorder_point.
|
||||
* Backend: GET /api/v1/inventory/low-stock
|
||||
*/
|
||||
export function InventoryLowStockPage() {
|
||||
const [items, setItems] = useState<Record<string, unknown>[]>([])
|
||||
const [count, setCount] = useState(0)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const load = useCallback(() => {
|
||||
setLoading(true)
|
||||
fetchLowStock()
|
||||
.then((res) => {
|
||||
if (res && typeof res === 'object') {
|
||||
const o = res as Record<string, unknown>
|
||||
const arr = Array.isArray(o.items) ? (o.items as Record<string, unknown>[]) : []
|
||||
setItems(arr)
|
||||
setCount(Number(o.count ?? arr.length))
|
||||
}
|
||||
setError(null)
|
||||
})
|
||||
.catch((e: unknown) => {
|
||||
setError(e instanceof ApiHttpError ? e.message : 'Unable to load low stock items.')
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
load()
|
||||
}, [load])
|
||||
|
||||
return (
|
||||
<div className="container-fluid px-0 mt-3">
|
||||
<div className="d-flex justify-content-between align-items-center mb-3 px-3 flex-wrap gap-2">
|
||||
<h3 className="mb-0">Low Stock Items ({count})</h3>
|
||||
<div className="d-flex gap-2">
|
||||
<Link className="btn btn-outline-info btn-sm" to="/app/administrator/inventory/reorder-suggestions">
|
||||
Reorder Suggestions
|
||||
</Link>
|
||||
<Link className="btn btn-outline-secondary" to={INVENTORY_BOOK_BASE}>
|
||||
Back to Items
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error ? <div className="alert alert-danger mx-3">{error}</div> : null}
|
||||
|
||||
{loading ? (
|
||||
<p className="text-muted px-3">Loading…</p>
|
||||
) : items.length === 0 ? (
|
||||
<div className="alert alert-success mx-3">
|
||||
<strong>All stocked up!</strong> No items are below their reorder point.
|
||||
</div>
|
||||
) : (
|
||||
<div className="card mx-3">
|
||||
<div className="card-body table-responsive">
|
||||
<table className="table table-striped align-middle" id="lowStockTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Category</th>
|
||||
<th className="text-end">Current Qty</th>
|
||||
<th className="text-end">Reorder Point</th>
|
||||
<th className="text-end">Reorder Qty</th>
|
||||
<th className="text-end">Lead Time (Days)</th>
|
||||
<th>Preferred Supplier</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((item) => {
|
||||
const i = item as Record<string, unknown>
|
||||
const supplier = i.preferred_supplier as Record<string, unknown> | null
|
||||
return (
|
||||
<tr key={String(i.id)}>
|
||||
<td>{String(i.name ?? '')}</td>
|
||||
<td style={{ textTransform: 'capitalize' }}>{String(i.type ?? '')}</td>
|
||||
<td>{String((i.category as Record<string, unknown>)?.name ?? i.category ?? '')}</td>
|
||||
<td className="text-end text-danger fw-semibold">
|
||||
{Number(i.quantity ?? 0).toLocaleString()}
|
||||
</td>
|
||||
<td className="text-end">{Number(i.reorder_point ?? 0).toLocaleString()}</td>
|
||||
<td className="text-end">{Number(i.reorder_quantity ?? 0).toLocaleString() || '—'}</td>
|
||||
<td className="text-end">{Number(i.lead_time_days ?? 0) || '—'}</td>
|
||||
<td>{supplier ? String(supplier.name ?? '') : '—'}</td>
|
||||
<td>
|
||||
<Link
|
||||
className="btn btn-sm btn-warning"
|
||||
to={`/app/administrator/inventory/items/${String(i.id)}/adjust`}
|
||||
>
|
||||
Adjust Stock
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { ApiHttpError } from '../../api/http'
|
||||
import { fetchReorderSuggestions } from '../../api/inventory'
|
||||
import { INVENTORY_BOOK_BASE } from './inventoryPaths'
|
||||
|
||||
/**
|
||||
* Reorder Suggestions — calculated suggested order quantities for low-stock items.
|
||||
* Backend: GET /api/v1/inventory/reorder-suggestions
|
||||
*/
|
||||
export function InventoryReorderSuggestionsPage() {
|
||||
const [suggestions, setSuggestions] = useState<Record<string, unknown>[]>([])
|
||||
const [count, setCount] = useState(0)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const load = useCallback(() => {
|
||||
setLoading(true)
|
||||
fetchReorderSuggestions()
|
||||
.then((res) => {
|
||||
if (res && typeof res === 'object') {
|
||||
const o = res as Record<string, unknown>
|
||||
const arr = Array.isArray(o.suggestions) ? (o.suggestions as Record<string, unknown>[]) : []
|
||||
setSuggestions(arr)
|
||||
setCount(Number(o.count ?? arr.length))
|
||||
}
|
||||
setError(null)
|
||||
})
|
||||
.catch((e: unknown) => {
|
||||
setError(e instanceof ApiHttpError ? e.message : 'Unable to load reorder suggestions.')
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
load()
|
||||
}, [load])
|
||||
|
||||
return (
|
||||
<div className="container-fluid px-0 mt-3">
|
||||
<div className="d-flex justify-content-between align-items-center mb-3 px-3 flex-wrap gap-2">
|
||||
<h3 className="mb-0">Reorder Suggestions ({count})</h3>
|
||||
<div className="d-flex gap-2">
|
||||
<Link className="btn btn-outline-warning btn-sm" to="/app/administrator/inventory/low-stock">
|
||||
Low Stock
|
||||
</Link>
|
||||
<Link className="btn btn-outline-secondary" to={INVENTORY_BOOK_BASE}>
|
||||
Back to Items
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error ? <div className="alert alert-danger mx-3">{error}</div> : null}
|
||||
|
||||
{loading ? (
|
||||
<p className="text-muted px-3">Loading…</p>
|
||||
) : suggestions.length === 0 ? (
|
||||
<div className="alert alert-success mx-3">
|
||||
<strong>All stocked up!</strong> No reorder suggestions at this time.
|
||||
</div>
|
||||
) : (
|
||||
<div className="card mx-3">
|
||||
<div className="card-body table-responsive">
|
||||
<table className="table table-striped align-middle" id="reorderSuggestionsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Category</th>
|
||||
<th className="text-end">Current Qty</th>
|
||||
<th className="text-end">Reorder Point</th>
|
||||
<th className="text-end">Suggested Order</th>
|
||||
<th>Preferred Supplier</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{suggestions.map((s) => {
|
||||
const supplier = s.preferred_supplier as Record<string, unknown> | null
|
||||
return (
|
||||
<tr key={String(s.id)}>
|
||||
<td>{String(s.name ?? '')}</td>
|
||||
<td>{String(s.category ?? '—')}</td>
|
||||
<td className="text-end text-danger fw-semibold">
|
||||
{Number(s.current_quantity ?? 0).toLocaleString()}
|
||||
</td>
|
||||
<td className="text-end">{Number(s.reorder_point ?? 0).toLocaleString()}</td>
|
||||
<td className="text-end fw-semibold">
|
||||
{Number(s.suggested_order_qty ?? 0).toLocaleString()}
|
||||
</td>
|
||||
<td>{supplier ? String(supplier.name ?? '') : '—'}</td>
|
||||
<td>
|
||||
<Link
|
||||
className="btn btn-sm btn-warning"
|
||||
to={`/app/administrator/inventory/items/${String(s.id)}/adjust`}
|
||||
>
|
||||
Adjust Stock
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Link, useSearchParams } from 'react-router-dom'
|
||||
import { ApiHttpError } from '../../api/http'
|
||||
import { fetchStockStatus } from '../../api/inventory'
|
||||
import { INVENTORY_BOOK_BASE } from './inventoryPaths'
|
||||
|
||||
/**
|
||||
* Stock Status — all items with status: ok/low_stock/out_of_stock.
|
||||
* Backend: GET /api/v1/inventory/stock-status
|
||||
*/
|
||||
export function InventoryStockStatusPage() {
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const [items, setItems] = useState<Record<string, unknown>[]>([])
|
||||
const [counts, setCounts] = useState<Record<string, number>>({})
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const load = useCallback(() => {
|
||||
setLoading(true)
|
||||
fetchStockStatus(searchParams)
|
||||
.then((res) => {
|
||||
if (res && typeof res === 'object') {
|
||||
const o = res as Record<string, unknown>
|
||||
setItems(Array.isArray(o.items) ? (o.items as Record<string, unknown>[]) : [])
|
||||
setCounts((o.counts as Record<string, number>) ?? {})
|
||||
}
|
||||
setError(null)
|
||||
})
|
||||
.catch((e: unknown) => {
|
||||
setError(e instanceof ApiHttpError ? e.message : 'Unable to load stock status.')
|
||||
})
|
||||
.finally(() => setLoading(false))
|
||||
}, [searchParams])
|
||||
|
||||
useEffect(() => {
|
||||
load()
|
||||
}, [load])
|
||||
|
||||
function onTypeFilter(v: string) {
|
||||
const next = new URLSearchParams(searchParams)
|
||||
if (v) next.set('type', v)
|
||||
else next.delete('type')
|
||||
setSearchParams(next)
|
||||
}
|
||||
|
||||
const currentType = searchParams.get('type') ?? ''
|
||||
|
||||
return (
|
||||
<div className="container-fluid px-0 mt-3">
|
||||
<div className="d-flex justify-content-between align-items-center mb-3 px-3 flex-wrap gap-2">
|
||||
<h3 className="mb-0">Stock Status</h3>
|
||||
<div className="d-flex gap-2">
|
||||
<Link className="btn btn-outline-warning btn-sm" to="/app/administrator/inventory/low-stock">
|
||||
Low Stock
|
||||
</Link>
|
||||
<Link className="btn btn-outline-info btn-sm" to="/app/administrator/inventory/reorder-suggestions">
|
||||
Reorder Suggestions
|
||||
</Link>
|
||||
<Link className="btn btn-outline-secondary" to={INVENTORY_BOOK_BASE}>
|
||||
Back to Items
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error ? <div className="alert alert-danger mx-3">{error}</div> : null}
|
||||
|
||||
{loading ? (
|
||||
<p className="text-muted px-3">Loading…</p>
|
||||
) : (
|
||||
<>
|
||||
{/* Summary Badges */}
|
||||
<div className="d-flex gap-3 mb-3 px-3 flex-wrap">
|
||||
<span className="badge bg-success fs-6">
|
||||
OK: {counts.ok ?? 0}
|
||||
</span>
|
||||
<span className="badge bg-warning fs-6">
|
||||
Low Stock: {counts.low_stock ?? 0}
|
||||
</span>
|
||||
<span className="badge bg-danger fs-6">
|
||||
Out of Stock: {counts.out_of_stock ?? 0}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="card mx-3">
|
||||
<div className="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||
<span>All Items</span>
|
||||
<select
|
||||
className="form-select form-select-sm"
|
||||
style={{ minWidth: 180 }}
|
||||
value={currentType}
|
||||
onChange={(e) => onTypeFilter(e.target.value)}
|
||||
>
|
||||
<option value="">All Types</option>
|
||||
<option value="book">Books</option>
|
||||
<option value="classroom">Classroom</option>
|
||||
<option value="office">Office</option>
|
||||
<option value="kitchen">Kitchen</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="card-body table-responsive">
|
||||
<table className="table table-striped align-middle" id="stockStatusTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Category</th>
|
||||
<th className="text-end">Quantity</th>
|
||||
<th className="text-end">Reorder Point</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan={7} className="text-center text-muted py-4">
|
||||
No items found.
|
||||
</td>
|
||||
</tr>
|
||||
) : (
|
||||
items.map((item) => {
|
||||
const status = String(item.status ?? 'ok')
|
||||
const badgeClass =
|
||||
status === 'out_of_stock'
|
||||
? 'bg-danger'
|
||||
: status === 'low_stock'
|
||||
? 'bg-warning'
|
||||
: 'bg-success'
|
||||
const badgeLabel =
|
||||
status === 'out_of_stock'
|
||||
? 'Out of Stock'
|
||||
: status === 'low_stock'
|
||||
? 'Low Stock'
|
||||
: 'OK'
|
||||
return (
|
||||
<tr key={String(item.id)}>
|
||||
<td>{String(item.name ?? '')}</td>
|
||||
<td style={{ textTransform: 'capitalize' }}>{String(item.type ?? '')}</td>
|
||||
<td>{String(item.category ?? '—')}</td>
|
||||
<td className="text-end">{Number(item.quantity ?? 0).toLocaleString()}</td>
|
||||
<td className="text-end">
|
||||
{item.reorder_point != null ? Number(item.reorder_point).toLocaleString() : '—'}
|
||||
</td>
|
||||
<td>
|
||||
<span className={`badge ${badgeClass}`}>{badgeLabel}</span>
|
||||
</td>
|
||||
<td>
|
||||
<Link
|
||||
className="btn btn-sm btn-outline-primary me-1"
|
||||
to={`/app/administrator/inventory/items/${String(item.id)}/adjust`}
|
||||
>
|
||||
Adjust
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\Inventory\InventoryMovementService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class InventoryReconcile extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'inventory:reconcile
|
||||
{--school-year= : The school year to reconcile (e.g., 2025-2026). Defaults to current.}
|
||||
{--fix : Automatically fix discrepancies by creating adjustment movements.}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Reconcile inventory item quantities against movement ledger totals';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(InventoryMovementService $movementService)
|
||||
{
|
||||
$schoolYear = $this->option('school-year');
|
||||
$autoFix = $this->option('fix');
|
||||
|
||||
$result = $movementService->reconcile($schoolYear);
|
||||
|
||||
$this->info("School Year: {$result['school_year']}");
|
||||
$this->info("Total Items: {$result['total_items']}");
|
||||
$this->info("Discrepancies: {$result['discrepancies_count']}");
|
||||
|
||||
if (empty($result['discrepancies'])) {
|
||||
$this->info('✅ All item quantities match movement ledger.');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
$this->table(
|
||||
['ID', 'Name', 'Stored Qty', 'Movement Sum', 'Variance'],
|
||||
collect($result['discrepancies'])->map(fn ($d) => [
|
||||
$d['id'],
|
||||
$d['name'],
|
||||
$d['stored_quantity'],
|
||||
$d['movement_sum'],
|
||||
$d['variance'],
|
||||
])->toArray()
|
||||
);
|
||||
|
||||
if ($autoFix) {
|
||||
$this->info('Fixing discrepancies...');
|
||||
foreach ($result['discrepancies'] as $d) {
|
||||
if ($d['variance'] !== 0) {
|
||||
$movementService->recordMovement(
|
||||
itemId: $d['id'],
|
||||
qtyChange: -$d['variance'],
|
||||
type: 'adjust',
|
||||
reason: 'Auto-reconciliation: stored qty differed from movement sum',
|
||||
note: 'Reconciled from '.$d['stored_quantity'].' to '.$d['movement_sum'],
|
||||
performedBy: null
|
||||
);
|
||||
$this->line(" Fixed item #{$d['id']} ({$d['name']}): variance was {$d['variance']}");
|
||||
}
|
||||
}
|
||||
$this->info('✅ Fix applied.');
|
||||
} else {
|
||||
$this->warn('Run with --fix to automatically correct discrepancies.');
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use App\Services\Auth\ApiLoginSecurityService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
|
||||
|
||||
class AuthController extends BaseApiController
|
||||
@@ -24,6 +25,11 @@ class AuthController extends BaseApiController
|
||||
$password = (string) ($payload['password'] ?? '');
|
||||
|
||||
if ($email === '' || $password === '') {
|
||||
Log::notice('api_login: missing credentials', [
|
||||
'ip' => (string) $request->ip(),
|
||||
'email' => $this->maskEmail($email),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Email and password are required.',
|
||||
@@ -32,6 +38,11 @@ class AuthController extends BaseApiController
|
||||
|
||||
$ip = $request->ip();
|
||||
if ($security->isIpBlocked((string) $ip)) {
|
||||
Log::notice('api_login: ip blocked', [
|
||||
'ip' => (string) $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Too many failed attempts from your IP. Please try again later.',
|
||||
@@ -41,6 +52,24 @@ class AuthController extends BaseApiController
|
||||
$user = User::query()->whereRaw('LOWER(email) = ?', [$email])->first();
|
||||
if (! $user) {
|
||||
$security->logIpAttempt((string) $ip);
|
||||
Log::notice('api_login: unknown email', [
|
||||
'ip' => (string) $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Invalid email or password.',
|
||||
], 401);
|
||||
}
|
||||
|
||||
if (blank($user->password)) {
|
||||
$security->logIpAttempt((string) $ip);
|
||||
Log::notice('api_login: password missing', [
|
||||
'ip' => (string) $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@@ -50,6 +79,12 @@ class AuthController extends BaseApiController
|
||||
|
||||
if (! verify_stored_password($password, (string) $user->password)) {
|
||||
$security->handleFailedLogin($user, $email, (string) $ip);
|
||||
Log::notice('api_login: password mismatch', [
|
||||
'ip' => (string) $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
'failed_attempts' => (int) ($user->fresh()?->failed_attempts ?? 0),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@@ -60,6 +95,12 @@ class AuthController extends BaseApiController
|
||||
// Suspension is checked AFTER credentials are verified so that the
|
||||
// response shape cannot be used to enumerate which emails exist.
|
||||
if ($user->is_suspended) {
|
||||
Log::notice('api_login: suspended account', [
|
||||
'ip' => (string) $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Account suspended. Please reset your password.',
|
||||
@@ -71,6 +112,12 @@ class AuthController extends BaseApiController
|
||||
|
||||
$fresh = $user->fresh();
|
||||
if (! $fresh) {
|
||||
Log::warning('api_login: fresh user reload failed after successful verification', [
|
||||
'ip' => (string) $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Invalid email or password.',
|
||||
@@ -82,6 +129,19 @@ class AuthController extends BaseApiController
|
||||
return response()->json($security->buildLoginResponse($fresh, $jwtToken));
|
||||
}
|
||||
|
||||
private function maskEmail(string $email): string
|
||||
{
|
||||
$email = trim(strtolower($email));
|
||||
if ($email === '' || ! str_contains($email, '@')) {
|
||||
return $email;
|
||||
}
|
||||
|
||||
[$local, $domain] = explode('@', $email, 2);
|
||||
$localPrefix = substr($local, 0, min(2, strlen($local)));
|
||||
|
||||
return $localPrefix.str_repeat('*', max(strlen($local) - strlen($localPrefix), 0)).'@'.$domain;
|
||||
}
|
||||
|
||||
public function refresh(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -12,6 +12,7 @@ use App\Services\Auth\AuthSessionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
|
||||
|
||||
/**
|
||||
@@ -89,6 +90,11 @@ class AuthSessionController extends Controller
|
||||
$ip = (string) $request->ip();
|
||||
|
||||
if ($this->security->isIpBlocked($ip)) {
|
||||
Log::notice('session_login: ip blocked', [
|
||||
'ip' => $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Too many failed attempts from your IP. Please try again later.',
|
||||
@@ -99,6 +105,24 @@ class AuthSessionController extends Controller
|
||||
|
||||
if (! $user) {
|
||||
$this->security->logIpAttempt($ip);
|
||||
Log::notice('session_login: unknown email', [
|
||||
'ip' => $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'The email and password combination you entered is invalid. Please try again.',
|
||||
], 401);
|
||||
}
|
||||
|
||||
if (blank($user->password)) {
|
||||
$this->security->logIpAttempt($ip);
|
||||
Log::notice('session_login: password missing', [
|
||||
'ip' => $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@@ -107,6 +131,12 @@ class AuthSessionController extends Controller
|
||||
}
|
||||
|
||||
if ($user->is_suspended) {
|
||||
Log::notice('session_login: suspended account', [
|
||||
'ip' => $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Account suspended. Please check your email to reset your password.',
|
||||
@@ -115,6 +145,12 @@ class AuthSessionController extends Controller
|
||||
|
||||
if (! verify_stored_password($password, (string) $user->password)) {
|
||||
$this->security->handleFailedLogin($user, $email, $ip);
|
||||
Log::notice('session_login: password mismatch', [
|
||||
'ip' => $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
'failed_attempts' => (int) ($user->fresh()?->failed_attempts ?? 0),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@@ -124,6 +160,12 @@ class AuthSessionController extends Controller
|
||||
|
||||
$fresh = $user->fresh();
|
||||
if (! $fresh) {
|
||||
Log::warning('session_login: fresh user reload failed after successful verification', [
|
||||
'ip' => $ip,
|
||||
'email' => $this->maskEmail($email),
|
||||
'user_id' => (int) $user->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'The email and password combination you entered is invalid. Please try again.',
|
||||
@@ -151,6 +193,19 @@ class AuthSessionController extends Controller
|
||||
]));
|
||||
}
|
||||
|
||||
private function maskEmail(string $email): string
|
||||
{
|
||||
$email = trim(strtolower($email));
|
||||
if ($email === '' || ! str_contains($email, '@')) {
|
||||
return $email;
|
||||
}
|
||||
|
||||
[$local, $domain] = explode('@', $email, 2);
|
||||
$localPrefix = substr($local, 0, min(2, strlen($local)));
|
||||
|
||||
return $localPrefix.str_repeat('*', max(strlen($local) - strlen($localPrefix), 0)).'@'.$domain;
|
||||
}
|
||||
|
||||
/** Closes the current web session. */
|
||||
public function logout(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\CompetitionWinners;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Admin\SaveCompetitionScoresRequest;
|
||||
use App\Http\Requests\Admin\StoreCompetitionWinnerRequest;
|
||||
use App\Http\Requests\Admin\UpdateCompetitionWinnerRequest;
|
||||
use App\Services\Admin\CompetitionWinners\CompetitionWinnersAdminService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CompetitionWinnersController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private CompetitionWinnersAdminService $service,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$payload = $this->service->indexData();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'competitions' => array_values(array_map(
|
||||
fn ($row) => $this->normalizeCompetitionRow($this->rowToArray($row)),
|
||||
$this->iterableToArray($payload['competitions'] ?? [])
|
||||
)),
|
||||
'sectionMap' => $payload['sectionMap'] ?? [],
|
||||
]);
|
||||
}
|
||||
|
||||
public function createForm(): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
...$this->service->createFormData(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function settingsForm(int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$payload = $this->service->settingsFormData($id);
|
||||
if ($payload === null) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
...$payload,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreCompetitionWinnerRequest $request): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$validated = $request->validated();
|
||||
$id = $this->service->storeCompetition(
|
||||
$validated,
|
||||
(array) ($validated['winner_overrides'] ?? []),
|
||||
(array) ($validated['question_counts'] ?? []),
|
||||
(array) ($validated['prizes'] ?? []),
|
||||
$guard
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Competition created.',
|
||||
'id' => $id,
|
||||
], Response::HTTP_CREATED);
|
||||
}
|
||||
|
||||
public function update(UpdateCompetitionWinnerRequest $request, int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$validated = $request->validated();
|
||||
$updated = $this->service->updateCompetition(
|
||||
$id,
|
||||
$validated,
|
||||
(array) ($validated['winner_overrides'] ?? []),
|
||||
(array) ($validated['question_counts'] ?? []),
|
||||
(array) ($validated['prizes'] ?? [])
|
||||
);
|
||||
|
||||
if (! $updated) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Competition updated.',
|
||||
'id' => $id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function scores(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$payload = $this->service->editScoresData($id, $this->intOrNull($request->query('class_section_id')));
|
||||
if ($payload === null) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
...$payload,
|
||||
]);
|
||||
}
|
||||
|
||||
public function saveScores(SaveCompetitionScoresRequest $request, int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$competition = $this->service->editScoresData($id, $this->intOrNull($request->input('class_section_id')));
|
||||
if ($competition === null) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$saved = $this->service->saveScores(
|
||||
$id,
|
||||
(array) ($payload['scores'] ?? []),
|
||||
$this->intOrNull($payload['class_section_id'] ?? null),
|
||||
(array) ($competition['competition'] ?? [])
|
||||
);
|
||||
|
||||
if (! $saved) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Select a class section before saving scores.',
|
||||
], Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Scores saved.',
|
||||
'savedCount' => count((array) ($payload['scores'] ?? [])),
|
||||
]);
|
||||
}
|
||||
|
||||
public function preview(int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$payload = $this->service->previewData($id);
|
||||
if ($payload === null) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
...$payload,
|
||||
]);
|
||||
}
|
||||
|
||||
public function winners(int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$payload = $this->service->settingsFormData($id);
|
||||
if ($payload === null || ! isset($payload['competition'])) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'competition' => $payload['competition'],
|
||||
'rows' => $this->service->winnersListingRows($id),
|
||||
'sectionMap' => $this->service->getClassSectionMap(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function publish(int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
if (! $this->service->publishWinners($id)) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Competition winners published.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function lock(int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
if (! $this->service->lockCompetition($id, $guard)) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Competition locked.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function unlock(int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
if (! $this->service->unlockCompetition($id)) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Competition not found.',
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Competition unlocked.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function exportQuiz(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$guard = $this->authenticatedAdminOrForbidden();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'class_section_id' => ['nullable', 'integer'],
|
||||
'semester' => ['nullable', 'string'],
|
||||
'school_year' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
$schoolId = $this->intOrNull(optional(auth()->user())->school_id);
|
||||
$result = $this->service->exportCompetitionToQuiz(
|
||||
$id,
|
||||
$this->intOrNull($validated['class_section_id'] ?? null) ?? 0,
|
||||
$schoolId,
|
||||
$guard,
|
||||
$validated['semester'] ?? null,
|
||||
$validated['school_year'] ?? null
|
||||
);
|
||||
|
||||
return response()->json($result, $result['ok'] ? Response::HTTP_OK : Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
private function authenticatedAdminOrForbidden(): int|JsonResponse
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
if (! $user || (int) ($user->id ?? 0) <= 0) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$roles = array_map('strtolower', (array) ($user->roles ?? []));
|
||||
$allowed = ['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'];
|
||||
if (empty(array_intersect($roles, $allowed))) {
|
||||
return response()->json(['ok' => false, 'message' => 'Forbidden.'], Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
return (int) $user->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iterable<mixed> $rows
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private function iterableToArray(iterable $rows): array
|
||||
{
|
||||
return is_array($rows) ? $rows : iterator_to_array($rows, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function normalizeCompetitionRow(array $row): array
|
||||
{
|
||||
$id = $this->intOrNull($row['id'] ?? $row['competition_id'] ?? null);
|
||||
if ($id !== null) {
|
||||
$row['id'] = $id;
|
||||
}
|
||||
|
||||
$classSectionId = $this->intOrNull($row['class_section_id'] ?? null);
|
||||
$row['class_section_id'] = $classSectionId;
|
||||
$row['is_locked'] = (bool) ($row['is_locked'] ?? false);
|
||||
$row['is_published'] = (bool) ($row['is_published'] ?? false);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function rowToArray(mixed $row): array
|
||||
{
|
||||
if (is_array($row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
if ($row instanceof \JsonSerializable) {
|
||||
$serialized = $row->jsonSerialize();
|
||||
if (is_array($serialized)) {
|
||||
return $serialized;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_object($row) && method_exists($row, 'toArray')) {
|
||||
$array = $row->toArray();
|
||||
if (is_array($array)) {
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
return (array) $row;
|
||||
}
|
||||
|
||||
private function intOrNull(mixed $value): ?int
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_numeric($value)) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use App\Http\Requests\Payments\PaymentManualUpdateRequest;
|
||||
use App\Services\Payments\PaymentManualService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class PaymentManualController extends BaseApiController
|
||||
@@ -70,18 +71,26 @@ class PaymentManualController extends BaseApiController
|
||||
|
||||
$payload = $request->validated();
|
||||
|
||||
$result = $this->service->recordPayment(
|
||||
$invoiceId,
|
||||
(float) $payload['amount'],
|
||||
(string) $payload['payment_method'],
|
||||
$payload['payment_date'] ?? null,
|
||||
$payload['check_number'] ?? null,
|
||||
$payload['payment_type'] ?? null,
|
||||
$request->file('payment_file'),
|
||||
$payload['school_year'] ?? null,
|
||||
$payload['semester'] ?? null,
|
||||
$guard
|
||||
);
|
||||
try {
|
||||
$result = $this->service->recordPayment(
|
||||
$invoiceId,
|
||||
(float) $payload['amount'],
|
||||
(string) $payload['payment_method'],
|
||||
$payload['payment_date'] ?? null,
|
||||
$payload['check_number'] ?? null,
|
||||
$payload['payment_type'] ?? null,
|
||||
$request->file('payment_file'),
|
||||
$payload['school_year'] ?? null,
|
||||
$payload['semester'] ?? null,
|
||||
$guard
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Manual payment record failed: '.$e->getMessage());
|
||||
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to record payment.'], 400);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true] + $result);
|
||||
}
|
||||
@@ -95,14 +104,22 @@ class PaymentManualController extends BaseApiController
|
||||
|
||||
$payload = $request->validated();
|
||||
|
||||
$this->service->editPayment(
|
||||
$paymentId,
|
||||
(float) $payload['paid_amount'],
|
||||
(string) $payload['payment_method'],
|
||||
$payload['check_number'] ?? null,
|
||||
$request->file('payment_file'),
|
||||
$guard
|
||||
);
|
||||
try {
|
||||
$this->service->editPayment(
|
||||
$paymentId,
|
||||
(float) $payload['paid_amount'],
|
||||
(string) $payload['payment_method'],
|
||||
$payload['check_number'] ?? null,
|
||||
$request->file('payment_file'),
|
||||
$guard
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Manual payment edit failed: '.$e->getMessage());
|
||||
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to update payment.'], 400);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ use App\Http\Requests\Inventory\InventoryItemUpdateRequest;
|
||||
use App\Http\Requests\Inventory\InventoryTeacherDistributionRequest;
|
||||
use App\Http\Requests\Inventory\InventoryTeacherDistributionStoreRequest;
|
||||
use App\Http\Resources\Inventory\InventoryItemResource;
|
||||
use App\Models\InventoryItem;
|
||||
use App\Services\Inventory\InventoryItemService;
|
||||
use App\Services\Inventory\InventoryMovementService;
|
||||
use App\Services\Inventory\InventorySummaryService;
|
||||
use App\Services\Inventory\InventoryTeacherDistributionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -23,7 +25,8 @@ class InventoryController extends BaseApiController
|
||||
public function __construct(
|
||||
private InventoryItemService $items,
|
||||
private InventorySummaryService $summary,
|
||||
private InventoryTeacherDistributionService $distribution
|
||||
private InventoryTeacherDistributionService $distribution,
|
||||
private InventoryMovementService $movementService
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -185,6 +188,161 @@ class InventoryController extends BaseApiController
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get low-stock items (where quantity <= reorder_point).
|
||||
*/
|
||||
public function lowStock(): JsonResponse
|
||||
{
|
||||
$items = InventoryItem::lowStock()
|
||||
->with('category', 'preferredSupplier')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
return $this->success([
|
||||
'items' => InventoryItemResource::collection($items),
|
||||
'count' => $items->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reorder suggestions based on low-stock items.
|
||||
*/
|
||||
public function reorderSuggestions(): JsonResponse
|
||||
{
|
||||
$lowStockItems = InventoryItem::lowStock()
|
||||
->with('category', 'preferredSupplier')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
$suggestions = $lowStockItems->map(function ($item) {
|
||||
$reorderQty = (int) ($item->reorder_quantity ?: 0);
|
||||
$currentQty = (int) $item->quantity;
|
||||
$reorderPoint = (int) ($item->reorder_point ?: 0);
|
||||
|
||||
// If no reorder quantity is set, suggest enough to bring back above reorder point
|
||||
if ($reorderQty <= 0) {
|
||||
$reorderQty = max(1, $reorderPoint - $currentQty + 5);
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'name' => $item->name,
|
||||
'current_quantity' => $currentQty,
|
||||
'reorder_point' => $reorderPoint,
|
||||
'suggested_order_qty' => $reorderQty,
|
||||
'preferred_supplier' => $item->preferredSupplier ? [
|
||||
'id' => $item->preferredSupplier->id,
|
||||
'name' => $item->preferredSupplier->name,
|
||||
] : null,
|
||||
'category' => $item->category ? $item->category->name : null,
|
||||
];
|
||||
});
|
||||
|
||||
return $this->success([
|
||||
'suggestions' => $suggestions,
|
||||
'count' => $suggestions->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a reorder request for a low-stock item.
|
||||
*/
|
||||
public function reorderRequest(int $id): JsonResponse
|
||||
{
|
||||
$item = InventoryItem::with('preferredSupplier')->find($id);
|
||||
if (! $item) {
|
||||
return $this->error('Item not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$reorderQty = (int) ($item->reorder_quantity ?: 0);
|
||||
if ($reorderQty <= 0) {
|
||||
$reorderQty = max(1, ((int) ($item->reorder_point ?: 0)) - ((int) $item->quantity) + 5);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'item_id' => $item->id,
|
||||
'item_name' => $item->name,
|
||||
'current_quantity' => (int) $item->quantity,
|
||||
'suggested_quantity' => $reorderQty,
|
||||
'preferred_supplier' => $item->preferredSupplier ? [
|
||||
'id' => $item->preferredSupplier->id,
|
||||
'name' => $item->preferredSupplier->name,
|
||||
] : null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View all items with their stock status.
|
||||
*/
|
||||
public function stockStatus(): JsonResponse
|
||||
{
|
||||
$type = request()->query('type');
|
||||
$items = InventoryItem::query()
|
||||
->with('category', 'preferredSupplier')
|
||||
->when($type, fn ($q) => $q->where('type', $type))
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
$qty = (int) $item->quantity;
|
||||
$reorderPoint = (int) ($item->reorder_point ?: 0);
|
||||
$status = 'ok';
|
||||
if ($qty <= 0) {
|
||||
$status = 'out_of_stock';
|
||||
} elseif ($reorderPoint > 0 && $qty <= $reorderPoint) {
|
||||
$status = 'low_stock';
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'name' => $item->name,
|
||||
'type' => $item->type,
|
||||
'category' => $item->category ? $item->category->name : null,
|
||||
'quantity' => $qty,
|
||||
'reorder_point' => $reorderPoint,
|
||||
'status' => $status,
|
||||
];
|
||||
});
|
||||
|
||||
$counts = [
|
||||
'ok' => $items->where('status', 'ok')->count(),
|
||||
'low_stock' => $items->where('status', 'low_stock')->count(),
|
||||
'out_of_stock' => $items->where('status', 'out_of_stock')->count(),
|
||||
];
|
||||
|
||||
return $this->success([
|
||||
'items' => $items,
|
||||
'counts' => $counts,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inventory dashboard summary.
|
||||
*/
|
||||
public function dashboard(): JsonResponse
|
||||
{
|
||||
$schoolYear = request()->query('school_year');
|
||||
|
||||
$items = InventoryItem::query()
|
||||
->when($schoolYear, fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->get();
|
||||
|
||||
$totalItems = $items->count();
|
||||
$byType = $items->groupBy('type')->map(fn ($g) => $g->count());
|
||||
$lowStockCount = $items->filter(fn ($i) => $i->reorder_point && $i->quantity <= $i->reorder_point)->count();
|
||||
$outOfStockCount = $items->filter(fn ($i) => $i->quantity <= 0)->count();
|
||||
$needsRepairCount = $items->sum('needs_repair_qty');
|
||||
$missingCount = $items->sum('cannot_find_qty');
|
||||
|
||||
return $this->success([
|
||||
'total_items' => $totalItems,
|
||||
'by_type' => $byType,
|
||||
'low_stock_count' => $lowStockCount,
|
||||
'out_of_stock_count' => $outOfStockCount,
|
||||
'needs_repair_count' => (int) $needsRepairCount,
|
||||
'missing_count' => (int) $missingCount,
|
||||
]);
|
||||
}
|
||||
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -73,6 +73,57 @@ class InventoryMovementController extends BaseApiController
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Void a movement (append-only correction).
|
||||
*/
|
||||
public function void(int $id): JsonResponse
|
||||
{
|
||||
$actor = $this->authenticatedUserIdOrUnauthorized();
|
||||
if ($actor instanceof JsonResponse) {
|
||||
return $actor;
|
||||
}
|
||||
|
||||
$reason = (string) request()->input('reason', '');
|
||||
if (empty(trim($reason))) {
|
||||
return $this->error('Reason is required to void a movement.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
$result = $this->movements->voidMovement($id, $reason, $actor);
|
||||
if (! ($result['ok'] ?? false)) {
|
||||
return $this->error($result['message'] ?? 'Failed to void movement.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
return $this->success(['message' => 'Movement voided successfully.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a correction movement.
|
||||
*/
|
||||
public function correct(int $id): JsonResponse
|
||||
{
|
||||
$actor = $this->authenticatedUserIdOrUnauthorized();
|
||||
if ($actor instanceof JsonResponse) {
|
||||
return $actor;
|
||||
}
|
||||
|
||||
$qtyChange = (int) request()->input('qty_change', 0);
|
||||
$reason = (string) request()->input('reason', '');
|
||||
|
||||
if ($qtyChange === 0) {
|
||||
return $this->error('Quantity change must be non-zero.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
if (empty(trim($reason))) {
|
||||
return $this->error('Reason is required.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
$result = $this->movements->correctMovement($id, $qtyChange, $reason, $actor);
|
||||
if (! ($result['ok'] ?? false)) {
|
||||
return $this->error($result['message'] ?? 'Failed to correct movement.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
return $this->success(['message' => 'Correction movement created.']);
|
||||
}
|
||||
|
||||
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
||||
{
|
||||
$userId = (int) (auth()->id() ?? 0);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Stats;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class StatsController extends BaseApiController
|
||||
@@ -11,6 +12,10 @@ class StatsController extends BaseApiController
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
if (! Schema::hasTable('stats')) {
|
||||
return $this->success([], 'Statistics retrieved successfully');
|
||||
}
|
||||
|
||||
$stats = Stats::query()->get()->toArray();
|
||||
|
||||
return $this->success($stats, 'Statistics retrieved successfully');
|
||||
|
||||
@@ -192,17 +192,17 @@ class StudentController extends BaseApiController
|
||||
'firstname' => ['required', 'string', 'max:150'],
|
||||
'lastname' => ['required', 'string', 'max:150'],
|
||||
'dob' => ['nullable', 'date'],
|
||||
'age' => ['nullable', 'integer', 'min:0'],
|
||||
'gender' => ['nullable', 'string', 'max:20'],
|
||||
'age' => ['required', 'integer', 'min:0'],
|
||||
'gender' => ['required', 'string', 'max:20'],
|
||||
'is_active' => ['nullable', 'boolean'],
|
||||
'registration_grade' => ['nullable', 'string', 'max:50'],
|
||||
'is_new' => ['nullable', 'boolean'],
|
||||
'photo_consent' => ['nullable', 'boolean'],
|
||||
'parent_id' => ['nullable', 'integer', 'min:1'],
|
||||
'photo_consent' => ['required', 'boolean'],
|
||||
'parent_id' => ['required', 'integer', 'min:1'],
|
||||
'registration_date' => ['nullable', 'date'],
|
||||
'tuition_paid' => ['nullable', 'boolean'],
|
||||
'semester' => ['nullable', 'string', 'max:50'],
|
||||
'year_of_registration' => ['nullable', 'integer', 'min:1900'],
|
||||
'year_of_registration' => ['required', 'integer', 'min:1900'],
|
||||
'school_year' => ['required', 'string', 'max:50'],
|
||||
'medical_conditions' => ['nullable', 'string'],
|
||||
'allergies' => ['nullable', 'string'],
|
||||
@@ -229,7 +229,26 @@ class StudentController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $validator->validated();
|
||||
$student = Student::query()->create($payload);
|
||||
$studentPayload = collect($payload)->only([
|
||||
'school_id',
|
||||
'firstname',
|
||||
'lastname',
|
||||
'dob',
|
||||
'age',
|
||||
'gender',
|
||||
'is_active',
|
||||
'registration_grade',
|
||||
'is_new',
|
||||
'photo_consent',
|
||||
'parent_id',
|
||||
'registration_date',
|
||||
'tuition_paid',
|
||||
'semester',
|
||||
'year_of_registration',
|
||||
'school_year',
|
||||
])->all();
|
||||
|
||||
$student = Student::query()->create($studentPayload);
|
||||
|
||||
if (empty($student->school_id)) {
|
||||
$student->school_id = $this->generateSchoolId($student->id);
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\System;
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Models\Stats;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class StatsController extends BaseApiController
|
||||
@@ -12,6 +13,10 @@ class StatsController extends BaseApiController
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
if (! Schema::hasTable('stats')) {
|
||||
return $this->success([], 'Statistics retrieved successfully');
|
||||
}
|
||||
|
||||
$stats = Stats::query()->get()->toArray();
|
||||
|
||||
return $this->success($stats, 'Statistics retrieved successfully');
|
||||
|
||||
@@ -14,13 +14,13 @@ class InventoryItemStoreRequest extends ApiFormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'type' => ['required', 'string', 'max:20'],
|
||||
'category_id' => ['nullable', 'integer', 'min:1'],
|
||||
'type' => ['required', 'string', 'in:classroom,book,office,kitchen'],
|
||||
'category_id' => ['nullable', 'integer', 'min:1', 'exists:inventory_categories,id'],
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'description' => ['nullable', 'string'],
|
||||
'quantity' => ['nullable', 'integer'],
|
||||
'quantity' => ['nullable', 'integer', 'min:0'],
|
||||
'unit' => ['nullable', 'string', 'max:50'],
|
||||
'condition' => ['nullable', 'string', 'max:50'],
|
||||
'condition' => ['nullable', 'string', 'in:good,needs_repair,need_replace,cannot_find'],
|
||||
'isbn' => ['nullable', 'string', 'max:50'],
|
||||
'edition' => ['nullable', 'string', 'max:50'],
|
||||
'sku' => ['nullable', 'string', 'max:50'],
|
||||
|
||||
@@ -14,12 +14,12 @@ class InventoryItemUpdateRequest extends ApiFormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'category_id' => ['nullable', 'integer', 'min:1'],
|
||||
'category_id' => ['nullable', 'integer', 'min:1', 'exists:inventory_categories,id'],
|
||||
'name' => ['sometimes', 'string', 'max:255'],
|
||||
'description' => ['nullable', 'string'],
|
||||
'quantity' => ['nullable', 'integer'],
|
||||
// quantity is intentionally excluded: stock changes must go through movements
|
||||
'unit' => ['nullable', 'string', 'max:50'],
|
||||
'condition' => ['nullable', 'string', 'max:50'],
|
||||
'condition' => ['nullable', 'string', 'in:good,needs_repair,need_replace,cannot_find'],
|
||||
'isbn' => ['nullable', 'string', 'max:50'],
|
||||
'edition' => ['nullable', 'string', 'max:50'],
|
||||
'sku' => ['nullable', 'string', 'max:50'],
|
||||
|
||||
@@ -28,6 +28,16 @@ class InventoryItemResource extends JsonResource
|
||||
'semester' => $this['semester'] ?? null,
|
||||
'school_year' => $this['school_year'] ?? null,
|
||||
'updated_by' => $this['updated_by'] ?? null,
|
||||
// New fields
|
||||
'preferred_supplier_id' => $this['preferred_supplier_id'] ?? null,
|
||||
'last_purchase_price' => $this['last_purchase_price'] ?? null,
|
||||
'average_unit_cost' => $this['average_unit_cost'] ?? null,
|
||||
'reorder_point' => $this['reorder_point'] ?? null,
|
||||
'reorder_quantity' => $this['reorder_quantity'] ?? null,
|
||||
'lead_time_days' => $this['lead_time_days'] ?? null,
|
||||
'barcode' => $this['barcode'] ?? null,
|
||||
'qr_code' => $this['qr_code'] ?? null,
|
||||
'asset_tag' => $this['asset_tag'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,17 @@ class InventoryItem extends BaseModel
|
||||
'needs_repair_qty',
|
||||
'need_replace_qty',
|
||||
'cannot_find_qty',
|
||||
// Supplier/reorder fields
|
||||
'preferred_supplier_id',
|
||||
'last_purchase_price',
|
||||
'average_unit_cost',
|
||||
'reorder_point',
|
||||
'reorder_quantity',
|
||||
'lead_time_days',
|
||||
// Barcode/QR fields
|
||||
'barcode',
|
||||
'qr_code',
|
||||
'asset_tag',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
@@ -39,6 +50,13 @@ class InventoryItem extends BaseModel
|
||||
'needs_repair_qty' => 'integer',
|
||||
'need_replace_qty' => 'integer',
|
||||
'cannot_find_qty' => 'integer',
|
||||
|
||||
'preferred_supplier_id' => 'integer',
|
||||
'last_purchase_price' => 'decimal:2',
|
||||
'average_unit_cost' => 'decimal:2',
|
||||
'reorder_point' => 'integer',
|
||||
'reorder_quantity' => 'integer',
|
||||
'lead_time_days' => 'integer',
|
||||
];
|
||||
|
||||
/* Optional relationships */
|
||||
@@ -46,4 +64,25 @@ class InventoryItem extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(InventoryCategory::class, 'category_id');
|
||||
}
|
||||
|
||||
public function preferredSupplier()
|
||||
{
|
||||
return $this->belongsTo(Supplier::class, 'preferred_supplier_id');
|
||||
}
|
||||
|
||||
public function movements()
|
||||
{
|
||||
return $this->hasMany(InventoryMovement::class, 'item_id');
|
||||
}
|
||||
|
||||
public function scopeLowStock($query)
|
||||
{
|
||||
return $query->whereNotNull('reorder_point')
|
||||
->whereColumn('quantity', '<=', 'reorder_point');
|
||||
}
|
||||
|
||||
public function scopeOutOfStock($query)
|
||||
{
|
||||
return $query->where('quantity', '<=', 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,13 @@ class InventoryMovement extends BaseModel
|
||||
'teacher_id',
|
||||
'student_id',
|
||||
'class_section_id',
|
||||
// Audit/correction fields
|
||||
'voided_at',
|
||||
'voided_by',
|
||||
'void_reason',
|
||||
'corrects_movement_id',
|
||||
'source_type',
|
||||
'source_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
@@ -30,8 +37,23 @@ class InventoryMovement extends BaseModel
|
||||
'teacher_id' => 'integer',
|
||||
'student_id' => 'integer',
|
||||
'class_section_id' => 'integer',
|
||||
'voided_by' => 'integer',
|
||||
'corrects_movement_id' => 'integer',
|
||||
'source_id' => 'integer',
|
||||
'voided_at' => 'datetime',
|
||||
];
|
||||
|
||||
/* Scopes */
|
||||
public function scopeNotVoided($query)
|
||||
{
|
||||
return $query->whereNull('voided_at');
|
||||
}
|
||||
|
||||
public function scopeVoided($query)
|
||||
{
|
||||
return $query->whereNotNull('voided_at');
|
||||
}
|
||||
|
||||
/* Optional relationships */
|
||||
public function item()
|
||||
{
|
||||
@@ -57,4 +79,19 @@ class InventoryMovement extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(ClassSection::class, 'class_section_id');
|
||||
}
|
||||
|
||||
public function voidedBy()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'voided_by');
|
||||
}
|
||||
|
||||
public function correctsMovement()
|
||||
{
|
||||
return $this->belongsTo(self::class, 'corrects_movement_id');
|
||||
}
|
||||
|
||||
public function corrections()
|
||||
{
|
||||
return $this->hasMany(self::class, 'corrects_movement_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ class PurchaseOrderItem extends BaseModel
|
||||
protected $fillable = [
|
||||
'purchase_order_id',
|
||||
'supply_id',
|
||||
'inventory_item_id',
|
||||
'description',
|
||||
'quantity',
|
||||
'received_qty',
|
||||
|
||||
@@ -31,6 +31,7 @@ class Student extends BaseModel
|
||||
'is_new',
|
||||
'parent_id',
|
||||
'school_year',
|
||||
'semester',
|
||||
'registration_date',
|
||||
'tuition_paid',
|
||||
'year_of_registration',
|
||||
|
||||
+8
-2
@@ -724,8 +724,14 @@ class User extends Authenticatable implements JWTSubject
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid double-hashing
|
||||
$this->attributes['password'] = str_starts_with((string) $value, '$2y$')
|
||||
$value = (string) $value;
|
||||
$hashInfo = password_get_info($value);
|
||||
$hashParts = preg_split('/[:$]/', $value);
|
||||
$isPbkdf2Hash = is_array($hashParts) && count($hashParts) === 4;
|
||||
|
||||
// Avoid double-hashing when callers already pass a password_hash()
|
||||
// value or one of the legacy PBKDF2 hashes used by this codebase.
|
||||
$this->attributes['password'] = (($hashInfo['algo'] ?? null) !== null || $isPbkdf2Hash)
|
||||
? $value
|
||||
: Hash::make($value);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@ namespace App\Services\Administrator;
|
||||
|
||||
use App\Models\Configuration;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AdministratorSharedService
|
||||
{
|
||||
protected ?bool $teacherClassHasSemesterColumn = null;
|
||||
|
||||
public function __construct(
|
||||
protected Configuration $configuration
|
||||
) {}
|
||||
@@ -150,4 +153,13 @@ class AdministratorSharedService
|
||||
|
||||
return count(array_unique($ids));
|
||||
}
|
||||
|
||||
public function teacherClassSupportsSemester(): bool
|
||||
{
|
||||
if ($this->teacherClassHasSemesterColumn !== null) {
|
||||
return $this->teacherClassHasSemesterColumn;
|
||||
}
|
||||
|
||||
return $this->teacherClassHasSemesterColumn = Schema::hasColumn('teacher_class', 'semester');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,13 +142,18 @@ class TeacherSubmissionNotificationService
|
||||
return [];
|
||||
}
|
||||
|
||||
return ClassSection::query()
|
||||
$query = ClassSection::query()
|
||||
->select('teacher_class.class_section_id', 'teacher_class.teacher_id')
|
||||
->join('teacher_class', 'teacher_class.class_section_id', '=', 'classSection.class_section_id')
|
||||
->whereIn('teacher_class.teacher_id', $teacherIds)
|
||||
->where('teacher_class.school_year', $schoolYear)
|
||||
->where('teacher_class.semester', $semester)
|
||||
->orderBy('teacher_class.class_section_id')
|
||||
->orderBy('teacher_class.class_section_id');
|
||||
|
||||
if ($this->shared->teacherClassSupportsSemester() && $semester !== '') {
|
||||
$query->where('teacher_class.semester', $semester);
|
||||
}
|
||||
|
||||
return $query
|
||||
->get()
|
||||
->map(static fn ($row): array => [
|
||||
'class_section_id' => (int) $row->class_section_id,
|
||||
|
||||
@@ -20,8 +20,9 @@ class TeacherSubmissionReportService
|
||||
{
|
||||
$semester = $this->shared->getSemester($filters['semester'] ?? null);
|
||||
$schoolYear = $this->shared->getSchoolYear($filters['school_year'] ?? null);
|
||||
$teacherClassSupportsSemester = $this->shared->teacherClassSupportsSemester();
|
||||
|
||||
$assignmentRows = DB::table('teacher_class as tc')
|
||||
$assignmentQuery = DB::table('teacher_class as tc')
|
||||
->select([
|
||||
'tc.class_section_id',
|
||||
'cs.class_section_name',
|
||||
@@ -33,8 +34,13 @@ class TeacherSubmissionReportService
|
||||
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
|
||||
->leftJoin('users as u', 'u.id', '=', 'tc.teacher_id')
|
||||
->where('tc.school_year', $schoolYear)
|
||||
->where('tc.semester', $semester)
|
||||
->orderBy('cs.class_section_name')
|
||||
->orderBy('cs.class_section_name');
|
||||
|
||||
if ($teacherClassSupportsSemester && $semester !== '') {
|
||||
$assignmentQuery->where('tc.semester', $semester);
|
||||
}
|
||||
|
||||
$assignmentRows = $assignmentQuery
|
||||
->get()
|
||||
->map(fn ($r) => (array) $r)
|
||||
->all();
|
||||
|
||||
@@ -15,6 +15,7 @@ class InventoryMovementService
|
||||
{
|
||||
$selectedYear = trim((string) ($filters['school_year'] ?? $this->context->schoolYear()));
|
||||
$selectedSem = trim((string) ($filters['semester'] ?? $this->context->semester()));
|
||||
$includeVoided = ! empty($filters['include_voided']);
|
||||
|
||||
$builder = DB::table('inventory_movements as m')
|
||||
->select([
|
||||
@@ -32,6 +33,11 @@ class InventoryMovementService
|
||||
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'm.class_section_id')
|
||||
->orderBy('m.id', 'DESC');
|
||||
|
||||
// Exclude voided movements by default
|
||||
if (! $includeVoided) {
|
||||
$builder->whereNull('m.voided_at');
|
||||
}
|
||||
|
||||
if ($selectedYear !== '') {
|
||||
$builder->where('m.school_year', $selectedYear);
|
||||
}
|
||||
@@ -42,6 +48,10 @@ class InventoryMovementService
|
||||
return $builder->get()->map(fn ($r) => (array) $r)->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use recordMovement() instead. This method allows editing
|
||||
* movement history which weakens auditability.
|
||||
*/
|
||||
public function create(array $data, int $performedBy = 0): array
|
||||
{
|
||||
$itemId = (int) ($data['item_id'] ?? 0);
|
||||
@@ -58,19 +68,7 @@ class InventoryMovementService
|
||||
return ['ok' => false, 'message' => 'Not enough stock to apply this movement.'];
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'item_id' => $itemId,
|
||||
'qty_change' => $qtyChange,
|
||||
'movement_type' => $movementType,
|
||||
'reason' => trim((string) ($data['reason'] ?? '')),
|
||||
'note' => trim((string) ($data['note'] ?? '')),
|
||||
'semester' => $data['semester'] ?? $this->context->semester(),
|
||||
'school_year' => $data['school_year'] ?? $this->context->schoolYear(),
|
||||
'performed_by' => $performedBy ?: null,
|
||||
'teacher_id' => $this->nullableInt($data['teacher_id'] ?? null),
|
||||
'student_id' => $this->nullableInt($data['student_id'] ?? null),
|
||||
'class_section_id' => $this->nullableInt($data['class_section_id'] ?? null),
|
||||
];
|
||||
$payload = $this->buildMovementPayload($data, $itemId, $qtyChange, $movementType, $performedBy);
|
||||
|
||||
try {
|
||||
InventoryMovement::query()->create($payload);
|
||||
@@ -84,6 +82,10 @@ class InventoryMovementService
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do NOT edit movements directly. Use voidMovement() + recordMovement() instead.
|
||||
* Editing historical movements destroys audit integrity.
|
||||
*/
|
||||
public function update(int $id, array $data): array
|
||||
{
|
||||
$movement = InventoryMovement::query()->find($id);
|
||||
@@ -91,6 +93,11 @@ class InventoryMovementService
|
||||
return ['ok' => false, 'message' => 'Movement not found.'];
|
||||
}
|
||||
|
||||
// Prevent editing voided movements
|
||||
if ($movement->voided_at) {
|
||||
return ['ok' => false, 'message' => 'Cannot edit a voided movement.'];
|
||||
}
|
||||
|
||||
$movementType = (string) ($data['movement_type'] ?? $movement->movement_type);
|
||||
$qtyChange = (int) ($data['qty_change'] ?? $movement->qty_change);
|
||||
$qtyChange = $this->normalizeMovementQty($movementType, $qtyChange);
|
||||
@@ -125,6 +132,10 @@ class InventoryMovementService
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do NOT hard-delete movements. Use voidMovement() instead.
|
||||
* Deleting historical movements destroys audit integrity.
|
||||
*/
|
||||
public function delete(int $id): array
|
||||
{
|
||||
$movement = InventoryMovement::query()->find($id);
|
||||
@@ -132,6 +143,14 @@ class InventoryMovementService
|
||||
return ['ok' => false, 'message' => 'Movement not found.'];
|
||||
}
|
||||
|
||||
// Prevent hard-deleting movements that have corrections
|
||||
$hasCorrections = InventoryMovement::query()
|
||||
->where('corrects_movement_id', $id)
|
||||
->exists();
|
||||
if ($hasCorrections) {
|
||||
return ['ok' => false, 'message' => 'Cannot delete a movement that has corrections. Void it instead.'];
|
||||
}
|
||||
|
||||
$itemId = (int) $movement->item_id;
|
||||
try {
|
||||
$movement->delete();
|
||||
@@ -147,6 +166,10 @@ class InventoryMovementService
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do NOT bulk-delete movements. Use voidMovement() instead.
|
||||
* Deleting historical movements destroys audit integrity.
|
||||
*/
|
||||
public function bulkDelete(array $ids): array
|
||||
{
|
||||
$ids = array_values(array_filter(array_map('intval', $ids), static fn ($v) => $v > 0));
|
||||
@@ -154,6 +177,14 @@ class InventoryMovementService
|
||||
return ['ok' => false, 'message' => 'No movements selected.'];
|
||||
}
|
||||
|
||||
// Check for corrections
|
||||
$hasCorrections = InventoryMovement::query()
|
||||
->whereIn('corrects_movement_id', $ids)
|
||||
->exists();
|
||||
if ($hasCorrections) {
|
||||
return ['ok' => false, 'message' => 'Cannot delete movements that have corrections. Void them instead.'];
|
||||
}
|
||||
|
||||
$itemIds = DB::table('inventory_movements')
|
||||
->select('item_id')
|
||||
->whereIn('id', $ids)
|
||||
@@ -178,6 +209,10 @@ class InventoryMovementService
|
||||
return ['ok' => true, 'deleted' => count($ids)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a new inventory movement (append-only).
|
||||
* This is the primary method for all stock changes.
|
||||
*/
|
||||
public function recordMovement(
|
||||
int $itemId,
|
||||
int $qtyChange,
|
||||
@@ -223,11 +258,109 @@ class InventoryMovementService
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Void an existing movement (append-only correction).
|
||||
* The original movement is preserved but marked as voided.
|
||||
*/
|
||||
public function voidMovement(int $movementId, string $reason, int $voidedBy): array
|
||||
{
|
||||
$movement = InventoryMovement::query()->find($movementId);
|
||||
if (! $movement) {
|
||||
return ['ok' => false, 'message' => 'Movement not found.'];
|
||||
}
|
||||
|
||||
if ($movement->voided_at) {
|
||||
return ['ok' => false, 'message' => 'Movement is already voided.'];
|
||||
}
|
||||
|
||||
$itemId = (int) $movement->item_id;
|
||||
|
||||
try {
|
||||
DB::transaction(function () use ($movement, $reason, $voidedBy, $itemId) {
|
||||
// Mark original as voided
|
||||
$movement->update([
|
||||
'voided_at' => now(),
|
||||
'voided_by' => $voidedBy,
|
||||
'void_reason' => $reason,
|
||||
]);
|
||||
|
||||
// Create reverse movement to correct the quantity
|
||||
$reverseQty = -(int) $movement->qty_change;
|
||||
if ($reverseQty !== 0) {
|
||||
InventoryMovement::query()->create([
|
||||
'item_id' => $itemId,
|
||||
'qty_change' => $reverseQty,
|
||||
'movement_type' => 'adjust',
|
||||
'reason' => 'Correction: voided movement #'.$movement->id,
|
||||
'note' => $reason,
|
||||
'semester' => $this->context->semester(),
|
||||
'school_year' => $this->context->schoolYear(),
|
||||
'performed_by' => $voidedBy,
|
||||
'corrects_movement_id' => $movement->id,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->recalcQuantity($itemId);
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Inventory movement void failed: '.$e->getMessage());
|
||||
|
||||
return ['ok' => false, 'message' => 'Could not void movement.'];
|
||||
}
|
||||
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a correction movement for an existing movement.
|
||||
* This does NOT void the original; it adds an adjusting entry.
|
||||
*/
|
||||
public function correctMovement(int $movementId, int $correctedQtyChange, string $reason, int $performedBy): array
|
||||
{
|
||||
$movement = InventoryMovement::query()->find($movementId);
|
||||
if (! $movement) {
|
||||
return ['ok' => false, 'message' => 'Movement not found.'];
|
||||
}
|
||||
|
||||
if ($movement->voided_at) {
|
||||
return ['ok' => false, 'message' => 'Cannot correct a voided movement.'];
|
||||
}
|
||||
|
||||
$itemId = (int) $movement->item_id;
|
||||
|
||||
if ($this->wouldGoNegative($itemId, $correctedQtyChange)) {
|
||||
return ['ok' => false, 'message' => 'Not enough stock to apply correction.'];
|
||||
}
|
||||
|
||||
try {
|
||||
InventoryMovement::query()->create([
|
||||
'item_id' => $itemId,
|
||||
'qty_change' => $correctedQtyChange,
|
||||
'movement_type' => 'adjust',
|
||||
'reason' => 'Correction for movement #'.$movement->id,
|
||||
'note' => $reason,
|
||||
'semester' => $this->context->semester(),
|
||||
'school_year' => $this->context->schoolYear(),
|
||||
'performed_by' => $performedBy,
|
||||
'corrects_movement_id' => $movement->id,
|
||||
]);
|
||||
|
||||
$this->recalcQuantity($itemId);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Inventory movement correction failed: '.$e->getMessage());
|
||||
|
||||
return ['ok' => false, 'message' => 'Could not correct movement.'];
|
||||
}
|
||||
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
public function recalcQuantity(int $itemId): void
|
||||
{
|
||||
$sumRow = InventoryMovement::query()
|
||||
->selectRaw('SUM(qty_change) as qty_change')
|
||||
->where('item_id', $itemId)
|
||||
->whereNull('voided_at') // Exclude voided movements from calculations
|
||||
->first();
|
||||
|
||||
$sum = (int) ($sumRow?->qty_change ?? 0);
|
||||
@@ -258,6 +391,47 @@ class InventoryMovementService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile inventory items - compare stored quantity against movement totals.
|
||||
* Returns an array of items that have discrepancies.
|
||||
*/
|
||||
public function reconcile(?string $schoolYear = null): array
|
||||
{
|
||||
$schoolYear = $schoolYear ?: $this->context->schoolYear();
|
||||
$discrepancies = [];
|
||||
|
||||
$items = InventoryItem::query()
|
||||
->when($schoolYear, fn ($q) => $q->where('school_year', $schoolYear))
|
||||
->get();
|
||||
|
||||
foreach ($items as $item) {
|
||||
$movementSum = (int) InventoryMovement::query()
|
||||
->where('item_id', $item->id)
|
||||
->whereNull('voided_at')
|
||||
->sum('qty_change');
|
||||
|
||||
$storedQty = (int) $item->quantity;
|
||||
$variance = $storedQty - $movementSum;
|
||||
|
||||
if ($variance !== 0) {
|
||||
$discrepancies[] = [
|
||||
'id' => $item->id,
|
||||
'name' => $item->name,
|
||||
'stored_quantity' => $storedQty,
|
||||
'movement_sum' => $movementSum,
|
||||
'variance' => $variance,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'school_year' => $schoolYear,
|
||||
'total_items' => $items->count(),
|
||||
'discrepancies_count' => count($discrepancies),
|
||||
'discrepancies' => $discrepancies,
|
||||
];
|
||||
}
|
||||
|
||||
private function ensureInitialMovement(int $itemId): void
|
||||
{
|
||||
$hasMov = InventoryMovement::query()->where('item_id', $itemId)->exists();
|
||||
@@ -345,4 +519,21 @@ class InventoryMovementService
|
||||
|
||||
return (int) $val;
|
||||
}
|
||||
|
||||
private function buildMovementPayload(array $data, int $itemId, int $qtyChange, string $movementType, int $performedBy): array
|
||||
{
|
||||
return [
|
||||
'item_id' => $itemId,
|
||||
'qty_change' => $qtyChange,
|
||||
'movement_type' => $movementType,
|
||||
'reason' => trim((string) ($data['reason'] ?? '')),
|
||||
'note' => trim((string) ($data['note'] ?? '')),
|
||||
'semester' => $data['semester'] ?? $this->context->semester(),
|
||||
'school_year' => $data['school_year'] ?? $this->context->schoolYear(),
|
||||
'performed_by' => $performedBy ?: null,
|
||||
'teacher_id' => $this->nullableInt($data['teacher_id'] ?? null),
|
||||
'student_id' => $this->nullableInt($data['student_id'] ?? null),
|
||||
'class_section_id' => $this->nullableInt($data['class_section_id'] ?? null),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,16 @@ use App\Models\PurchaseOrder;
|
||||
use App\Models\PurchaseOrderItem;
|
||||
use App\Models\Supply;
|
||||
use App\Models\SupplyTransaction;
|
||||
use App\Services\Inventory\InventoryMovementService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use RuntimeException;
|
||||
|
||||
class PurchaseOrderReceiveService
|
||||
{
|
||||
public function __construct(
|
||||
private InventoryMovementService $inventoryMovementService
|
||||
) {}
|
||||
|
||||
public function receive(int $poId, array $received, string $issuedBy): array
|
||||
{
|
||||
$po = PurchaseOrder::query()->find($poId);
|
||||
@@ -52,25 +57,36 @@ class PurchaseOrderReceiveService
|
||||
$poItem->received_qty = (int) $poItem->received_qty + $toReceive;
|
||||
$poItem->save();
|
||||
|
||||
// Update supply qty_on_hand (legacy support)
|
||||
$supply = Supply::query()->find($poItem->supply_id);
|
||||
if (! $supply) {
|
||||
$completed = false;
|
||||
if ($supply) {
|
||||
$supply->qty_on_hand = (int) $supply->qty_on_hand + $toReceive;
|
||||
$supply->save();
|
||||
|
||||
continue;
|
||||
SupplyTransaction::query()->create([
|
||||
'supply_id' => $supply->id,
|
||||
'type' => 'in',
|
||||
'quantity' => $toReceive,
|
||||
'ref' => 'PO '.($po->po_number ?? $po->id),
|
||||
'issued_to' => 'Inventory',
|
||||
'issued_by' => $issuedBy,
|
||||
'notes' => 'Received against PO',
|
||||
]);
|
||||
}
|
||||
|
||||
$supply->qty_on_hand = (int) $supply->qty_on_hand + $toReceive;
|
||||
$supply->save();
|
||||
|
||||
SupplyTransaction::query()->create([
|
||||
'supply_id' => $supply->id,
|
||||
'type' => 'in',
|
||||
'quantity' => $toReceive,
|
||||
'ref' => 'PO '.($po->po_number ?? $po->id),
|
||||
'issued_to' => 'Inventory',
|
||||
'issued_by' => $issuedBy,
|
||||
'notes' => 'Received against PO',
|
||||
]);
|
||||
// Create inventory movement if the PO item is linked to an inventory item
|
||||
$inventoryItemId = $poItem->inventory_item_id;
|
||||
if ($inventoryItemId) {
|
||||
$performedBy = is_numeric($issuedBy) ? (int) $issuedBy : null;
|
||||
$this->inventoryMovementService->recordMovement(
|
||||
itemId: (int) $inventoryItemId,
|
||||
qtyChange: $toReceive,
|
||||
type: 'in',
|
||||
reason: 'Purchase order received',
|
||||
note: 'PO '.($po->po_number ?? $po->id),
|
||||
performedBy: $performedBy
|
||||
);
|
||||
}
|
||||
|
||||
if ($poItem->received_qty < $poItem->quantity) {
|
||||
$completed = false;
|
||||
|
||||
@@ -164,22 +164,27 @@ class RefundOverpaymentService
|
||||
->select('id', 'parent_id', 'total_amount', 'school_year')
|
||||
->where('school_year', $schoolYear)
|
||||
->get()
|
||||
->map(fn ($row) => (array) $row)
|
||||
->map(fn ($row) => method_exists($row, 'toArray') ? $row->toArray() : (array) $row)
|
||||
->filter(fn (array $row) => isset($row['id'], $row['parent_id']))
|
||||
->values()
|
||||
->all();
|
||||
|
||||
if (empty($invRows)) {
|
||||
return ['created_ids' => [], 'updated_ids' => []];
|
||||
}
|
||||
|
||||
$invoiceIds = array_map(static fn ($row) => (int) $row['id'], $invRows);
|
||||
$invoiceIds = array_values(array_filter(array_map(static fn ($row) => (int) ($row['id'] ?? 0), $invRows)));
|
||||
|
||||
$paidByInv = $this->sumPaymentsByInvoice($invoiceIds);
|
||||
$discByInv = $this->sumDiscountsByInvoice($invoiceIds);
|
||||
$refByInv = $this->sumRefundsByInvoice($invoiceIds);
|
||||
|
||||
foreach ($invRows as $inv) {
|
||||
$iid = (int) $inv['id'];
|
||||
$pid = (int) $inv['parent_id'];
|
||||
$iid = (int) ($inv['id'] ?? 0);
|
||||
$pid = (int) ($inv['parent_id'] ?? 0);
|
||||
if ($iid <= 0 || $pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$total = (float) ($inv['total_amount'] ?? 0);
|
||||
$paid = (float) ($paidByInv[$iid] ?? 0);
|
||||
$disc = (float) ($discByInv[$iid] ?? 0);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
jRlQg50qYlv2hlr5AFzlp
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"/_global-error/page": "/_global-error",
|
||||
"/_not-found/page": "/_not-found",
|
||||
"/auth-redirect/page": "/auth-redirect",
|
||||
"/dashboard/admin-users/page": "/dashboard/admin-users",
|
||||
"/dashboard/audit-logs/page": "/dashboard/audit-logs",
|
||||
"/dashboard/billing/page": "/dashboard/billing",
|
||||
"/dashboard/companies/[id]/page": "/dashboard/companies/[id]",
|
||||
"/dashboard/companies/page": "/dashboard/companies",
|
||||
"/dashboard/containers/page": "/dashboard/containers",
|
||||
"/dashboard/menu-management/page": "/dashboard/menu-management",
|
||||
"/dashboard/notifications/page": "/dashboard/notifications",
|
||||
"/dashboard/page": "/dashboard",
|
||||
"/dashboard/pricing/page": "/dashboard/pricing",
|
||||
"/dashboard/renters/page": "/dashboard/renters",
|
||||
"/dashboard/site-config/page": "/dashboard/site-config",
|
||||
"/favicon.ico/route": "/favicon.ico",
|
||||
"/forgot-password/page": "/forgot-password",
|
||||
"/icon/route": "/icon",
|
||||
"/login/page": "/login",
|
||||
"/page": "/",
|
||||
"/reset-password/page": "/reset-password"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"devFiles": [],
|
||||
"polyfillFiles": [
|
||||
"static/chunks/0cz1d0mv5g_q7.js"
|
||||
],
|
||||
"lowPriorityFiles": [
|
||||
"static/jRlQg50qYlv2hlr5AFzlp/_buildManifest.js",
|
||||
"static/jRlQg50qYlv2hlr5AFzlp/_ssgManifest.js",
|
||||
"static/jRlQg50qYlv2hlr5AFzlp/_clientMiddlewareManifest.js"
|
||||
],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/3fi7ta8l6_q46.js",
|
||||
"static/chunks/2de_cmw_l_puw.js",
|
||||
"static/chunks/3svce10uq2e6q.js",
|
||||
"static/chunks/40z7xw1jd_fv0.js",
|
||||
"static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
var R=require("./chunks/[turbopack]_runtime.js")("1af38f23a0b57e90.js")
|
||||
R.c("chunks/[turbopack-node]_transforms_postcss_ts_1qskksv._.js")
|
||||
R.c("chunks/[root-of-the-server]__1hypy_2._.js")
|
||||
R.m("[turbopack-node]/child_process/globals.ts [postcss] (ecmascript)")
|
||||
R.m("[turbopack-node]/child_process/evaluate.ts/evaluate.js { INNER => \"[turbopack-node]/transforms/postcss.ts { CONFIG => \\\"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)\\\" } [postcss] (ecmascript)\", RUNTIME => \"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)\" } [postcss] (ecmascript)")
|
||||
module.exports=R.m("[turbopack-node]/child_process/evaluate.ts/evaluate.js { INNER => \"[turbopack-node]/transforms/postcss.ts { CONFIG => \\\"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)\\\" } [postcss] (ecmascript)\", RUNTIME => \"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)\" } [postcss] (ecmascript)").exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
module.exports = [
|
||||
"[externals]/path [external] (path, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("path", () => require("path"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/url [external] (url, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("url", () => require("url"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/fs [external] (fs, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("fs", () => require("fs"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:url [external] (node:url, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("node:url", () => require("node:url"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:path [external] (node:path, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("node:path", () => require("node:path"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
return __turbopack_context__.a(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try {
|
||||
|
||||
__turbopack_context__.s([
|
||||
"default",
|
||||
()=>__TURBOPACK__default__export__
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$url__$5b$external$5d$__$28$node$3a$url$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:url [external] (node:url, cjs)");
|
||||
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$path__$5b$external$5d$__$28$node$3a$path$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:path [external] (node:path, cjs)");
|
||||
;
|
||||
;
|
||||
const configPath = __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$path__$5b$external$5d$__$28$node$3a$path$2c$__cjs$29$__["default"].join(process.cwd(), "./postcss.config.js");
|
||||
// Absolute paths don't work with ESM imports on Windows:
|
||||
// https://github.com/nodejs/node/issues/31710
|
||||
// convert it to a file:// URL, which works on all platforms
|
||||
const configUrl = (0, __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$url__$5b$external$5d$__$28$node$3a$url$2c$__cjs$29$__["pathToFileURL"])(configPath).toString();
|
||||
const mod = await __turbopack_context__.y(configUrl);
|
||||
const __TURBOPACK__default__export__ = mod.default ?? mod;
|
||||
__turbopack_async_result__();
|
||||
} catch(e) { __turbopack_async_result__(e); } }, true);}),
|
||||
"[turbopack-node]/transforms/transforms.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Shared utilities for our 2 transform implementations.
|
||||
*/ __turbopack_context__.s([
|
||||
"fromPath",
|
||||
()=>fromPath,
|
||||
"getReadEnvVariables",
|
||||
()=>getReadEnvVariables,
|
||||
"toPath",
|
||||
()=>toPath
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/path [external] (path, cjs)");
|
||||
;
|
||||
const contextDir = process.cwd();
|
||||
const toPath = (file)=>{
|
||||
const relPath = (0, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["relative"])(contextDir, file);
|
||||
if ((0, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["isAbsolute"])(relPath)) {
|
||||
throw new Error(`Cannot depend on path (${file}) outside of root directory (${contextDir})`);
|
||||
}
|
||||
return __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"] !== '/' ? relPath.replaceAll(__TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"], '/') : relPath;
|
||||
};
|
||||
const fromPath = (path)=>{
|
||||
return (0, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["join"])(/* turbopackIgnore: true */ contextDir, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"] !== '/' ? path.replaceAll('/', __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"]) : path);
|
||||
};
|
||||
// Patch process.env to track which env vars are read
|
||||
const originalEnv = process.env;
|
||||
const readEnvVars = new Set();
|
||||
process.env = new Proxy(originalEnv, {
|
||||
get (target, prop) {
|
||||
if (typeof prop === 'string') {
|
||||
// We register the env var as dependency on the
|
||||
// current transform and all future transforms
|
||||
// since the env var might be cached in module scope
|
||||
// and influence them all
|
||||
readEnvVars.add(prop);
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
},
|
||||
set (target, prop, value) {
|
||||
return Reflect.set(target, prop, value);
|
||||
}
|
||||
});
|
||||
function getReadEnvVariables() {
|
||||
return Array.from(readEnvVars);
|
||||
}
|
||||
}),
|
||||
"[turbopack-node]/transforms/postcss.ts { CONFIG => \"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)\" } [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
return __turbopack_context__.a(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try {
|
||||
|
||||
__turbopack_context__.s([
|
||||
"default",
|
||||
()=>transform,
|
||||
"init",
|
||||
()=>init
|
||||
]);
|
||||
// @ts-ignore
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$postcss$2f$lib$2f$postcss$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/postcss/lib/postcss.mjs [postcss] (ecmascript)");
|
||||
// @ts-ignore
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$apps$2f$admin$2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/transforms/transforms.ts [postcss] (ecmascript)");
|
||||
var __turbopack_async_dependencies__ = __turbopack_handle_async_dependencies__([
|
||||
__TURBOPACK__imported__module__$5b$project$5d2f$apps$2f$admin$2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__
|
||||
]);
|
||||
[__TURBOPACK__imported__module__$5b$project$5d2f$apps$2f$admin$2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__] = __turbopack_async_dependencies__.then ? (await __turbopack_async_dependencies__)() : __turbopack_async_dependencies__;
|
||||
;
|
||||
;
|
||||
;
|
||||
let processor;
|
||||
const init = async (ipc)=>{
|
||||
let config = __TURBOPACK__imported__module__$5b$project$5d2f$apps$2f$admin$2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__["default"];
|
||||
if (typeof config === 'function') {
|
||||
config = await config({
|
||||
env: 'development'
|
||||
});
|
||||
}
|
||||
if (typeof config === 'undefined') {
|
||||
throw new Error('PostCSS config is undefined (make sure to export an function or object from config file)');
|
||||
}
|
||||
let plugins;
|
||||
if (Array.isArray(config.plugins)) {
|
||||
plugins = config.plugins.map((plugin)=>{
|
||||
if (Array.isArray(plugin)) {
|
||||
return plugin;
|
||||
} else if (typeof plugin === 'string') {
|
||||
return [
|
||||
plugin,
|
||||
{}
|
||||
];
|
||||
} else {
|
||||
return plugin;
|
||||
}
|
||||
});
|
||||
} else if (typeof config.plugins === 'object') {
|
||||
plugins = Object.entries(config.plugins).filter(([, options])=>options);
|
||||
} else {
|
||||
plugins = [];
|
||||
}
|
||||
const loadedPlugins = plugins.map((plugin)=>{
|
||||
if (Array.isArray(plugin)) {
|
||||
const [arg, options] = plugin;
|
||||
let pluginFactory = arg;
|
||||
if (typeof pluginFactory === 'string') {
|
||||
pluginFactory = require(/* turbopackIgnore: true */ pluginFactory);
|
||||
}
|
||||
if (pluginFactory.default) {
|
||||
pluginFactory = pluginFactory.default;
|
||||
}
|
||||
return pluginFactory(options);
|
||||
}
|
||||
return plugin;
|
||||
});
|
||||
processor = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$postcss$2f$lib$2f$postcss$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__["default"])(loadedPlugins);
|
||||
};
|
||||
async function transform(ipc, cssContent, name, sourceMap) {
|
||||
const { css, map, messages } = await processor.process(cssContent, {
|
||||
from: name,
|
||||
to: name,
|
||||
map: sourceMap ? {
|
||||
inline: false,
|
||||
annotation: false
|
||||
} : undefined
|
||||
});
|
||||
const assets = [];
|
||||
const filePaths = [];
|
||||
const buildFilePaths = [];
|
||||
const directories = [];
|
||||
for (const msg of messages){
|
||||
switch(msg.type){
|
||||
case 'asset':
|
||||
assets.push({
|
||||
file: msg.file,
|
||||
content: msg.content,
|
||||
sourceMap: !sourceMap ? undefined : typeof msg.sourceMap === 'string' ? msg.sourceMap : JSON.stringify(msg.sourceMap)
|
||||
});
|
||||
break;
|
||||
case 'dependency':
|
||||
case 'missing-dependency':
|
||||
filePaths.push((0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.file));
|
||||
break;
|
||||
case 'build-dependency':
|
||||
buildFilePaths.push((0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.file));
|
||||
break;
|
||||
case 'dir-dependency':
|
||||
directories.push([
|
||||
(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.dir),
|
||||
msg.glob
|
||||
]);
|
||||
break;
|
||||
case 'context-dependency':
|
||||
directories.push([
|
||||
(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.dir),
|
||||
'**'
|
||||
]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ipc.sendInfo({
|
||||
type: 'dependencies',
|
||||
filePaths,
|
||||
directories,
|
||||
buildFilePaths,
|
||||
envVariables: (0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["getReadEnvVariables"])()
|
||||
});
|
||||
return {
|
||||
css,
|
||||
map: sourceMap ? JSON.stringify(map) : undefined,
|
||||
assets
|
||||
};
|
||||
}
|
||||
__turbopack_async_result__();
|
||||
} catch(e) { __turbopack_async_result__(e); } }, false);}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=%5Broot-of-the-server%5D__0g29496._.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,500 @@
|
||||
module.exports = [
|
||||
"[turbopack-node]/child_process/globals.ts [postcss] (ecmascript)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
// @ts-ignore
|
||||
process.turbopack = {};
|
||||
}),
|
||||
"[externals]/node:net [external] (node:net, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("node:net", () => require("node:net"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:stream [external] (node:stream, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
const mod = __turbopack_context__.x("node:stream", () => require("node:stream"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[turbopack-node]/compiled/stacktrace-parser/index.js [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"parse",
|
||||
()=>parse
|
||||
]);
|
||||
if (typeof __nccwpck_require__ !== "undefined") __nccwpck_require__.ab = ("TURBOPACK compile-time value", "/ROOT/compiled/stacktrace-parser") + "/";
|
||||
var n = "<unknown>";
|
||||
function parse(e) {
|
||||
var r = e.split("\n");
|
||||
return r.reduce(function(e, r) {
|
||||
var n = parseChrome(r) || parseWinjs(r) || parseGecko(r) || parseNode(r) || parseJSC(r);
|
||||
if (n) {
|
||||
e.push(n);
|
||||
}
|
||||
return e;
|
||||
}, []);
|
||||
}
|
||||
var a = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
||||
var l = /\((\S*)(?::(\d+))(?::(\d+))\)/;
|
||||
function parseChrome(e) {
|
||||
var r = a.exec(e);
|
||||
if (!r) {
|
||||
return null;
|
||||
}
|
||||
var u = r[2] && r[2].indexOf("native") === 0;
|
||||
var t = r[2] && r[2].indexOf("eval") === 0;
|
||||
var i = l.exec(r[2]);
|
||||
if (t && i != null) {
|
||||
r[2] = i[1];
|
||||
r[3] = i[2];
|
||||
r[4] = i[3];
|
||||
}
|
||||
return {
|
||||
file: !u ? r[2] : null,
|
||||
methodName: r[1] || n,
|
||||
arguments: u ? [
|
||||
r[2]
|
||||
] : [],
|
||||
lineNumber: r[3] ? +r[3] : null,
|
||||
column: r[4] ? +r[4] : null
|
||||
};
|
||||
}
|
||||
var u = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
||||
function parseWinjs(e) {
|
||||
var r = u.exec(e);
|
||||
if (!r) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
file: r[2],
|
||||
methodName: r[1] || n,
|
||||
arguments: [],
|
||||
lineNumber: +r[3],
|
||||
column: r[4] ? +r[4] : null
|
||||
};
|
||||
}
|
||||
var t = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
|
||||
var i = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
|
||||
function parseGecko(e) {
|
||||
var r = t.exec(e);
|
||||
if (!r) {
|
||||
return null;
|
||||
}
|
||||
var a = r[3] && r[3].indexOf(" > eval") > -1;
|
||||
var l = i.exec(r[3]);
|
||||
if (a && l != null) {
|
||||
r[3] = l[1];
|
||||
r[4] = l[2];
|
||||
r[5] = null;
|
||||
}
|
||||
return {
|
||||
file: r[3],
|
||||
methodName: r[1] || n,
|
||||
arguments: r[2] ? r[2].split(",") : [],
|
||||
lineNumber: r[4] ? +r[4] : null,
|
||||
column: r[5] ? +r[5] : null
|
||||
};
|
||||
}
|
||||
var s = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
|
||||
function parseJSC(e) {
|
||||
var r = s.exec(e);
|
||||
if (!r) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
file: r[3],
|
||||
methodName: r[1] || n,
|
||||
arguments: [],
|
||||
lineNumber: +r[4],
|
||||
column: r[5] ? +r[5] : null
|
||||
};
|
||||
}
|
||||
var o = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
||||
function parseNode(e) {
|
||||
var r = o.exec(e);
|
||||
if (!r) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
file: r[2],
|
||||
methodName: r[1] || n,
|
||||
arguments: [],
|
||||
lineNumber: +r[3],
|
||||
column: r[4] ? +r[4] : null
|
||||
};
|
||||
}
|
||||
}),
|
||||
"[turbopack-node]/error.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"default",
|
||||
()=>isError,
|
||||
"getProperError",
|
||||
()=>getProperError,
|
||||
"structuredError",
|
||||
()=>structuredError
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$compiled$2f$stacktrace$2d$parser$2f$index$2e$js__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/compiled/stacktrace-parser/index.js [postcss] (ecmascript)");
|
||||
;
|
||||
function isError(err) {
|
||||
return typeof err === 'object' && err !== null && 'name' in err && 'message' in err;
|
||||
}
|
||||
function getProperError(err) {
|
||||
if (isError(err)) {
|
||||
return err;
|
||||
}
|
||||
if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable
|
||||
;
|
||||
return new Error(isPlainObject(err) ? JSON.stringify(err) : err + '');
|
||||
}
|
||||
function getObjectClassLabel(value) {
|
||||
return Object.prototype.toString.call(value);
|
||||
}
|
||||
function isPlainObject(value) {
|
||||
if (getObjectClassLabel(value) !== '[object Object]') {
|
||||
return false;
|
||||
}
|
||||
const prototype = Object.getPrototypeOf(value);
|
||||
/**
|
||||
* this used to be previously:
|
||||
*
|
||||
* `return prototype === null || prototype === Object.prototype`
|
||||
*
|
||||
* but Edge Runtime expose Object from vm, being that kind of type-checking wrongly fail.
|
||||
*
|
||||
* It was changed to the current implementation since it's resilient to serialization.
|
||||
*/ return prototype === null || prototype.hasOwnProperty('isPrototypeOf');
|
||||
}
|
||||
function structuredError(e) {
|
||||
e = getProperError(e);
|
||||
return {
|
||||
name: e.name,
|
||||
message: e.message,
|
||||
stack: typeof e.stack === 'string' ? (0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$compiled$2f$stacktrace$2d$parser$2f$index$2e$js__$5b$postcss$5d$__$28$ecmascript$29$__["parse"])(e.stack) : [],
|
||||
cause: e.cause ? structuredError(getProperError(e.cause)) : undefined
|
||||
};
|
||||
}
|
||||
}),
|
||||
"[turbopack-node]/child_process/index.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"IPC",
|
||||
()=>IPC
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$net__$5b$external$5d$__$28$node$3a$net$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:net [external] (node:net, cjs)");
|
||||
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$stream__$5b$external$5d$__$28$node$3a$stream$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:stream [external] (node:stream, cjs)");
|
||||
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$error$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/error.ts [postcss] (ecmascript)");
|
||||
;
|
||||
;
|
||||
;
|
||||
function createIpc(port) {
|
||||
const socket = (0, __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$net__$5b$external$5d$__$28$node$3a$net$2c$__cjs$29$__["createConnection"])({
|
||||
port,
|
||||
host: '127.0.0.1'
|
||||
});
|
||||
/**
|
||||
* A writable stream that writes to the socket.
|
||||
* We don't write directly to the socket because we need to
|
||||
* handle backpressure and wait for the socket to be drained
|
||||
* before writing more data.
|
||||
*/ const socketWritable = new __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$stream__$5b$external$5d$__$28$node$3a$stream$2c$__cjs$29$__["Writable"]({
|
||||
write (chunk, _enc, cb) {
|
||||
if (socket.write(chunk)) {
|
||||
cb();
|
||||
} else {
|
||||
socket.once('drain', cb);
|
||||
}
|
||||
},
|
||||
final (cb) {
|
||||
socket.end(cb);
|
||||
}
|
||||
});
|
||||
const packetQueue = [];
|
||||
const recvPromiseResolveQueue = [];
|
||||
function pushPacket(packet) {
|
||||
const recvPromiseResolve = recvPromiseResolveQueue.shift();
|
||||
if (recvPromiseResolve != null) {
|
||||
recvPromiseResolve(JSON.parse(packet.toString('utf8')));
|
||||
} else {
|
||||
packetQueue.push(packet);
|
||||
}
|
||||
}
|
||||
let state = {
|
||||
type: 'waiting'
|
||||
};
|
||||
let buffer = Buffer.alloc(0);
|
||||
socket.once('connect', ()=>{
|
||||
socket.setNoDelay(true);
|
||||
socket.on('data', (chunk)=>{
|
||||
buffer = Buffer.concat([
|
||||
buffer,
|
||||
chunk
|
||||
]);
|
||||
loop: while(true){
|
||||
switch(state.type){
|
||||
case 'waiting':
|
||||
{
|
||||
if (buffer.length >= 4) {
|
||||
const length = buffer.readUInt32BE(0);
|
||||
buffer = buffer.subarray(4);
|
||||
state = {
|
||||
type: 'packet',
|
||||
length
|
||||
};
|
||||
} else {
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'packet':
|
||||
{
|
||||
if (buffer.length >= state.length) {
|
||||
const packet = buffer.subarray(0, state.length);
|
||||
buffer = buffer.subarray(state.length);
|
||||
state = {
|
||||
type: 'waiting'
|
||||
};
|
||||
pushPacket(packet);
|
||||
} else {
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
invariant(state, (state)=>`Unknown state type: ${state?.type}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// When the socket is closed, this process is no longer needed.
|
||||
// This might happen e. g. when parent process is killed or
|
||||
// node.js pool is garbage collected.
|
||||
socket.once('close', ()=>{
|
||||
process.exit(0);
|
||||
});
|
||||
// TODO(lukesandberg): some of the messages being sent are very large and contain lots
|
||||
// of redundant information. Consider adding gzip compression to our stream.
|
||||
function doSend(message) {
|
||||
return new Promise((resolve, reject)=>{
|
||||
// Reserve 4 bytes for our length prefix, we will over-write after encoding.
|
||||
const packet = Buffer.from('0000' + message, 'utf8');
|
||||
packet.writeUInt32BE(packet.length - 4, 0);
|
||||
socketWritable.write(packet, (err)=>{
|
||||
process.stderr.write(`TURBOPACK_OUTPUT_D\n`);
|
||||
process.stdout.write(`TURBOPACK_OUTPUT_D\n`);
|
||||
if (err != null) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function send(message) {
|
||||
return doSend(JSON.stringify(message));
|
||||
}
|
||||
function sendReady() {
|
||||
return doSend('');
|
||||
}
|
||||
return {
|
||||
async recv () {
|
||||
const packet = packetQueue.shift();
|
||||
if (packet != null) {
|
||||
return JSON.parse(packet.toString('utf8'));
|
||||
}
|
||||
const result = await new Promise((resolve)=>{
|
||||
recvPromiseResolveQueue.push((result)=>{
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
},
|
||||
send (message) {
|
||||
return send(message);
|
||||
},
|
||||
sendReady,
|
||||
async sendError (error) {
|
||||
let failed = false;
|
||||
try {
|
||||
await send({
|
||||
type: 'error',
|
||||
...(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$error$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["structuredError"])(error)
|
||||
});
|
||||
} catch (err) {
|
||||
// There's nothing we can do about errors that happen after this point, we can't tell anyone
|
||||
// about them.
|
||||
console.error('failed to send error back to rust:', err);
|
||||
failed = true;
|
||||
}
|
||||
await new Promise((res)=>socket.end(()=>res()));
|
||||
process.exit(failed ? 1 : 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
const PORT = process.argv[2];
|
||||
const IPC = createIpc(parseInt(PORT, 10));
|
||||
process.on('uncaughtException', (err)=>{
|
||||
IPC.sendError(err);
|
||||
});
|
||||
process.on('unhandledRejection', (reason)=>{
|
||||
IPC.sendError(reason instanceof Error ? reason : new Error(String(reason)));
|
||||
});
|
||||
const improveConsole = (name, stream, addStack)=>{
|
||||
// @ts-ignore
|
||||
const original = console[name];
|
||||
// @ts-ignore
|
||||
const stdio = process[stream];
|
||||
// @ts-ignore
|
||||
console[name] = (...args)=>{
|
||||
stdio.write(`TURBOPACK_OUTPUT_B\n`);
|
||||
original(...args);
|
||||
if (addStack) {
|
||||
const stack = new Error().stack?.replace(/^.+\n.+\n/, '') + '\n';
|
||||
stdio.write('TURBOPACK_OUTPUT_S\n');
|
||||
stdio.write(stack);
|
||||
}
|
||||
stdio.write('TURBOPACK_OUTPUT_E\n');
|
||||
};
|
||||
};
|
||||
improveConsole('error', 'stderr', true);
|
||||
improveConsole('warn', 'stderr', true);
|
||||
improveConsole('count', 'stdout', true);
|
||||
improveConsole('trace', 'stderr', false);
|
||||
improveConsole('log', 'stdout', true);
|
||||
improveConsole('group', 'stdout', true);
|
||||
improveConsole('groupCollapsed', 'stdout', true);
|
||||
improveConsole('table', 'stdout', true);
|
||||
improveConsole('debug', 'stdout', true);
|
||||
improveConsole('info', 'stdout', true);
|
||||
improveConsole('dir', 'stdout', true);
|
||||
improveConsole('dirxml', 'stdout', true);
|
||||
improveConsole('timeEnd', 'stdout', true);
|
||||
improveConsole('timeLog', 'stdout', true);
|
||||
improveConsole('timeStamp', 'stdout', true);
|
||||
improveConsole('assert', 'stderr', true);
|
||||
/**
|
||||
* Utility function to ensure all variants of an enum are handled.
|
||||
*/ function invariant(never, computeMessage) {
|
||||
throw new Error(`Invariant: ${computeMessage(never)}`);
|
||||
}
|
||||
}),
|
||||
"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"run",
|
||||
()=>run
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$index$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/child_process/index.ts [postcss] (ecmascript)");
|
||||
;
|
||||
const ipc = __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$index$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["IPC"];
|
||||
const queue = [];
|
||||
const run = async (moduleFactory)=>{
|
||||
let nextId = 1;
|
||||
const requests = new Map();
|
||||
const internalIpc = {
|
||||
sendInfo: (message)=>ipc.send({
|
||||
type: 'info',
|
||||
data: message
|
||||
}),
|
||||
sendRequest: (message)=>{
|
||||
const id = nextId++;
|
||||
let resolve, reject;
|
||||
const promise = new Promise((res, rej)=>{
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
requests.set(id, {
|
||||
resolve,
|
||||
reject
|
||||
});
|
||||
return ipc.send({
|
||||
type: 'request',
|
||||
id,
|
||||
data: message
|
||||
}).then(()=>promise);
|
||||
},
|
||||
sendError: (error)=>{
|
||||
return ipc.sendError(error);
|
||||
}
|
||||
};
|
||||
// Initialize module and send ready message
|
||||
let getValue;
|
||||
try {
|
||||
const module = await moduleFactory();
|
||||
if (typeof module.init === 'function') {
|
||||
await module.init();
|
||||
}
|
||||
getValue = module.default;
|
||||
await ipc.sendReady();
|
||||
} catch (err) {
|
||||
await ipc.sendReady();
|
||||
await ipc.sendError(err);
|
||||
}
|
||||
// Queue handling
|
||||
let isRunning = false;
|
||||
const run = async ()=>{
|
||||
while(queue.length > 0){
|
||||
const args = queue.shift();
|
||||
try {
|
||||
const value = await getValue(internalIpc, ...args);
|
||||
await ipc.send({
|
||||
type: 'end',
|
||||
data: value === undefined ? undefined : JSON.stringify(value, null, 2),
|
||||
duration: 0
|
||||
});
|
||||
} catch (e) {
|
||||
await ipc.sendError(e);
|
||||
}
|
||||
}
|
||||
isRunning = false;
|
||||
};
|
||||
// Communication handling
|
||||
while(true){
|
||||
const msg = await ipc.recv();
|
||||
switch(msg.type){
|
||||
case 'evaluate':
|
||||
{
|
||||
queue.push(msg.args);
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
run();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'result':
|
||||
{
|
||||
const request = requests.get(msg.id);
|
||||
if (request) {
|
||||
requests.delete(msg.id);
|
||||
if (msg.error) {
|
||||
request.reject(new Error(msg.error));
|
||||
} else {
|
||||
request.resolve(msg.data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
console.error('unexpected message type', msg.type);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}),
|
||||
"[turbopack-node]/child_process/evaluate.ts/evaluate.js { INNER => \"[turbopack-node]/transforms/postcss.ts { CONFIG => \\\"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)\\\" } [postcss] (ecmascript)\", RUNTIME => \"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)\" } [postcss] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([]);
|
||||
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$evaluate$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)");
|
||||
;
|
||||
(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$evaluate$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["run"])(()=>__turbopack_context__.A('[turbopack-node]/transforms/postcss.ts { CONFIG => "[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)" } [postcss] (ecmascript, async loader)'));
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=%5Broot-of-the-server%5D__1hypy_2._.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,13 @@
|
||||
module.exports = [
|
||||
"[turbopack-node]/transforms/postcss.ts { CONFIG => \"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)\" } [postcss] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"chunks/node_modules_20v-8wl._.js",
|
||||
"chunks/[root-of-the-server]__0g29496._.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[turbopack-node]/transforms/postcss.ts { CONFIG => \"[project]/apps/admin/postcss.config.js_.loader.mjs [postcss] (ecmascript)\" } [postcss] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
];
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,890 @@
|
||||
const RUNTIME_PUBLIC_PATH = "chunks/[turbopack]_runtime.js";
|
||||
const RELATIVE_ROOT_PATH = "../../..";
|
||||
const ASSET_PREFIX = "/";
|
||||
const WORKER_FORWARDED_GLOBALS = [];
|
||||
/**
|
||||
* This file contains runtime types and functions that are shared between all
|
||||
* TurboPack ECMAScript runtimes.
|
||||
*
|
||||
* It will be prepended to the runtime code of each runtime.
|
||||
*/ /* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="./runtime-types.d.ts" />
|
||||
/**
|
||||
* Describes why a module was instantiated.
|
||||
* Shared between browser and Node.js runtimes.
|
||||
*/ var SourceType = /*#__PURE__*/ function(SourceType) {
|
||||
/**
|
||||
* The module was instantiated because it was included in an evaluated chunk's
|
||||
* runtime.
|
||||
* SourceData is a ChunkPath.
|
||||
*/ SourceType[SourceType["Runtime"] = 0] = "Runtime";
|
||||
/**
|
||||
* The module was instantiated because a parent module imported it.
|
||||
* SourceData is a ModuleId.
|
||||
*/ SourceType[SourceType["Parent"] = 1] = "Parent";
|
||||
/**
|
||||
* The module was instantiated because it was included in a chunk's hot module
|
||||
* update.
|
||||
* SourceData is an array of ModuleIds or undefined.
|
||||
*/ SourceType[SourceType["Update"] = 2] = "Update";
|
||||
return SourceType;
|
||||
}(SourceType || {});
|
||||
/**
|
||||
* Flag indicating which module object type to create when a module is merged. Set to `true`
|
||||
* by each runtime that uses ModuleWithDirection (browser dev-base.ts, nodejs dev-base.ts,
|
||||
* nodejs build-base.ts). Browser production (build-base.ts) leaves it as `false` since it
|
||||
* uses plain Module objects.
|
||||
*/ let createModuleWithDirectionFlag = false;
|
||||
const REEXPORTED_OBJECTS = new WeakMap();
|
||||
/**
|
||||
* Constructs the `__turbopack_context__` object for a module.
|
||||
*/ function Context(module, exports) {
|
||||
this.m = module;
|
||||
// We need to store this here instead of accessing it from the module object to:
|
||||
// 1. Make it available to factories directly, since we rewrite `this` to
|
||||
// `__turbopack_context__.e` in CJS modules.
|
||||
// 2. Support async modules which rewrite `module.exports` to a promise, so we
|
||||
// can still access the original exports object from functions like
|
||||
// `esmExport`
|
||||
// Ideally we could find a new approach for async modules and drop this property altogether.
|
||||
this.e = exports;
|
||||
}
|
||||
const contextPrototype = Context.prototype;
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
const toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag;
|
||||
function defineProp(obj, name, options) {
|
||||
if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options);
|
||||
}
|
||||
function getOverwrittenModule(moduleCache, id) {
|
||||
let module = moduleCache[id];
|
||||
if (!module) {
|
||||
if (createModuleWithDirectionFlag) {
|
||||
// set in development modes for hmr support
|
||||
module = createModuleWithDirection(id);
|
||||
} else {
|
||||
module = createModuleObject(id);
|
||||
}
|
||||
moduleCache[id] = module;
|
||||
}
|
||||
return module;
|
||||
}
|
||||
/**
|
||||
* Creates the module object. Only done here to ensure all module objects have the same shape.
|
||||
*/ function createModuleObject(id) {
|
||||
return {
|
||||
exports: {},
|
||||
error: undefined,
|
||||
id,
|
||||
namespaceObject: undefined
|
||||
};
|
||||
}
|
||||
function createModuleWithDirection(id) {
|
||||
return {
|
||||
exports: {},
|
||||
error: undefined,
|
||||
id,
|
||||
namespaceObject: undefined,
|
||||
parents: [],
|
||||
children: []
|
||||
};
|
||||
}
|
||||
const BindingTag_Value = 0;
|
||||
/**
|
||||
* Adds the getters to the exports object.
|
||||
*/ function esm(exports, bindings) {
|
||||
defineProp(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
if (toStringTag) defineProp(exports, toStringTag, {
|
||||
value: 'Module'
|
||||
});
|
||||
let i = 0;
|
||||
while(i < bindings.length){
|
||||
const propName = bindings[i++];
|
||||
const tagOrFunction = bindings[i++];
|
||||
if (typeof tagOrFunction === 'number') {
|
||||
if (tagOrFunction === BindingTag_Value) {
|
||||
defineProp(exports, propName, {
|
||||
value: bindings[i++],
|
||||
enumerable: true,
|
||||
writable: false
|
||||
});
|
||||
} else {
|
||||
throw new Error(`unexpected tag: ${tagOrFunction}`);
|
||||
}
|
||||
} else {
|
||||
const getterFn = tagOrFunction;
|
||||
if (typeof bindings[i] === 'function') {
|
||||
const setterFn = bindings[i++];
|
||||
defineProp(exports, propName, {
|
||||
get: getterFn,
|
||||
set: setterFn,
|
||||
enumerable: true
|
||||
});
|
||||
} else {
|
||||
defineProp(exports, propName, {
|
||||
get: getterFn,
|
||||
enumerable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.seal(exports);
|
||||
}
|
||||
/**
|
||||
* Makes the module an ESM with exports
|
||||
*/ function esmExport(bindings, id) {
|
||||
let module;
|
||||
let exports;
|
||||
if (id != null) {
|
||||
module = getOverwrittenModule(this.c, id);
|
||||
exports = module.exports;
|
||||
} else {
|
||||
module = this.m;
|
||||
exports = this.e;
|
||||
}
|
||||
module.namespaceObject = exports;
|
||||
esm(exports, bindings);
|
||||
}
|
||||
contextPrototype.s = esmExport;
|
||||
function ensureDynamicExports(module, exports) {
|
||||
let reexportedObjects = REEXPORTED_OBJECTS.get(module);
|
||||
if (!reexportedObjects) {
|
||||
REEXPORTED_OBJECTS.set(module, reexportedObjects = []);
|
||||
module.exports = module.namespaceObject = new Proxy(exports, {
|
||||
get (target, prop) {
|
||||
if (hasOwnProperty.call(target, prop) || prop === 'default' || prop === '__esModule') {
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
for (const obj of reexportedObjects){
|
||||
const value = Reflect.get(obj, prop);
|
||||
if (value !== undefined) return value;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
ownKeys (target) {
|
||||
const keys = Reflect.ownKeys(target);
|
||||
for (const obj of reexportedObjects){
|
||||
for (const key of Reflect.ownKeys(obj)){
|
||||
if (key !== 'default' && !keys.includes(key)) keys.push(key);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
});
|
||||
}
|
||||
return reexportedObjects;
|
||||
}
|
||||
/**
|
||||
* Dynamically exports properties from an object
|
||||
*/ function dynamicExport(object, id) {
|
||||
let module;
|
||||
let exports;
|
||||
if (id != null) {
|
||||
module = getOverwrittenModule(this.c, id);
|
||||
exports = module.exports;
|
||||
} else {
|
||||
module = this.m;
|
||||
exports = this.e;
|
||||
}
|
||||
const reexportedObjects = ensureDynamicExports(module, exports);
|
||||
if (typeof object === 'object' && object !== null) {
|
||||
reexportedObjects.push(object);
|
||||
}
|
||||
}
|
||||
contextPrototype.j = dynamicExport;
|
||||
function exportValue(value, id) {
|
||||
let module;
|
||||
if (id != null) {
|
||||
module = getOverwrittenModule(this.c, id);
|
||||
} else {
|
||||
module = this.m;
|
||||
}
|
||||
module.exports = value;
|
||||
}
|
||||
contextPrototype.v = exportValue;
|
||||
function exportNamespace(namespace, id) {
|
||||
let module;
|
||||
if (id != null) {
|
||||
module = getOverwrittenModule(this.c, id);
|
||||
} else {
|
||||
module = this.m;
|
||||
}
|
||||
module.exports = module.namespaceObject = namespace;
|
||||
}
|
||||
contextPrototype.n = exportNamespace;
|
||||
function createGetter(obj, key) {
|
||||
return ()=>obj[key];
|
||||
}
|
||||
/**
|
||||
* @returns prototype of the object
|
||||
*/ const getProto = Object.getPrototypeOf ? (obj)=>Object.getPrototypeOf(obj) : (obj)=>obj.__proto__;
|
||||
/** Prototypes that are not expanded for exports */ const LEAF_PROTOTYPES = [
|
||||
null,
|
||||
getProto({}),
|
||||
getProto([]),
|
||||
getProto(getProto)
|
||||
];
|
||||
/**
|
||||
* @param raw
|
||||
* @param ns
|
||||
* @param allowExportDefault
|
||||
* * `false`: will have the raw module as default export
|
||||
* * `true`: will have the default property as default export
|
||||
*/ function interopEsm(raw, ns, allowExportDefault) {
|
||||
const bindings = [];
|
||||
let defaultLocation = -1;
|
||||
for(let current = raw; (typeof current === 'object' || typeof current === 'function') && !LEAF_PROTOTYPES.includes(current); current = getProto(current)){
|
||||
for (const key of Object.getOwnPropertyNames(current)){
|
||||
bindings.push(key, createGetter(raw, key));
|
||||
if (defaultLocation === -1 && key === 'default') {
|
||||
defaultLocation = bindings.length - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// this is not really correct
|
||||
// we should set the `default` getter if the imported module is a `.cjs file`
|
||||
if (!(allowExportDefault && defaultLocation >= 0)) {
|
||||
// Replace the binding with one for the namespace itself in order to preserve iteration order.
|
||||
if (defaultLocation >= 0) {
|
||||
// Replace the getter with the value
|
||||
bindings.splice(defaultLocation, 1, BindingTag_Value, raw);
|
||||
} else {
|
||||
bindings.push('default', BindingTag_Value, raw);
|
||||
}
|
||||
}
|
||||
esm(ns, bindings);
|
||||
return ns;
|
||||
}
|
||||
function createNS(raw) {
|
||||
if (typeof raw === 'function') {
|
||||
return function(...args) {
|
||||
return raw.apply(this, args);
|
||||
};
|
||||
} else {
|
||||
return Object.create(null);
|
||||
}
|
||||
}
|
||||
function esmImport(id) {
|
||||
const module = getOrInstantiateModuleFromParent(id, this.m);
|
||||
// any ES module has to have `module.namespaceObject` defined.
|
||||
if (module.namespaceObject) return module.namespaceObject;
|
||||
// only ESM can be an async module, so we don't need to worry about exports being a promise here.
|
||||
const raw = module.exports;
|
||||
return module.namespaceObject = interopEsm(raw, createNS(raw), raw && raw.__esModule);
|
||||
}
|
||||
contextPrototype.i = esmImport;
|
||||
function asyncLoader(moduleId) {
|
||||
const loader = this.r(moduleId);
|
||||
return loader(esmImport.bind(this));
|
||||
}
|
||||
contextPrototype.A = asyncLoader;
|
||||
// Add a simple runtime require so that environments without one can still pass
|
||||
// `typeof require` CommonJS checks so that exports are correctly registered.
|
||||
const runtimeRequire = // @ts-ignore
|
||||
typeof require === 'function' ? require : function require1() {
|
||||
throw new Error('Unexpected use of runtime require');
|
||||
};
|
||||
contextPrototype.t = runtimeRequire;
|
||||
function commonJsRequire(id) {
|
||||
return getOrInstantiateModuleFromParent(id, this.m).exports;
|
||||
}
|
||||
contextPrototype.r = commonJsRequire;
|
||||
/**
|
||||
* Remove fragments and query parameters since they are never part of the context map keys
|
||||
*
|
||||
* This matches how we parse patterns at resolving time. Arguably we should only do this for
|
||||
* strings passed to `import` but the resolve does it for `import` and `require` and so we do
|
||||
* here as well.
|
||||
*/ function parseRequest(request) {
|
||||
// Per the URI spec fragments can contain `?` characters, so we should trim it off first
|
||||
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
|
||||
const hashIndex = request.indexOf('#');
|
||||
if (hashIndex !== -1) {
|
||||
request = request.substring(0, hashIndex);
|
||||
}
|
||||
const queryIndex = request.indexOf('?');
|
||||
if (queryIndex !== -1) {
|
||||
request = request.substring(0, queryIndex);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
/**
|
||||
* `require.context` and require/import expression runtime.
|
||||
*/ function moduleContext(map) {
|
||||
function moduleContext(id) {
|
||||
id = parseRequest(id);
|
||||
if (hasOwnProperty.call(map, id)) {
|
||||
return map[id].module();
|
||||
}
|
||||
const e = new Error(`Cannot find module '${id}'`);
|
||||
e.code = 'MODULE_NOT_FOUND';
|
||||
throw e;
|
||||
}
|
||||
moduleContext.keys = ()=>{
|
||||
return Object.keys(map);
|
||||
};
|
||||
moduleContext.resolve = (id)=>{
|
||||
id = parseRequest(id);
|
||||
if (hasOwnProperty.call(map, id)) {
|
||||
return map[id].id();
|
||||
}
|
||||
const e = new Error(`Cannot find module '${id}'`);
|
||||
e.code = 'MODULE_NOT_FOUND';
|
||||
throw e;
|
||||
};
|
||||
moduleContext.import = async (id)=>{
|
||||
return await moduleContext(id);
|
||||
};
|
||||
return moduleContext;
|
||||
}
|
||||
contextPrototype.f = moduleContext;
|
||||
/**
|
||||
* Returns the path of a chunk defined by its data.
|
||||
*/ function getChunkPath(chunkData) {
|
||||
return typeof chunkData === 'string' ? chunkData : chunkData.path;
|
||||
}
|
||||
function isPromise(maybePromise) {
|
||||
return maybePromise != null && typeof maybePromise === 'object' && 'then' in maybePromise && typeof maybePromise.then === 'function';
|
||||
}
|
||||
function isAsyncModuleExt(obj) {
|
||||
return turbopackQueues in obj;
|
||||
}
|
||||
function createPromise() {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((res, rej)=>{
|
||||
reject = rej;
|
||||
resolve = res;
|
||||
});
|
||||
return {
|
||||
promise,
|
||||
resolve: resolve,
|
||||
reject: reject
|
||||
};
|
||||
}
|
||||
// Load the CompressedmoduleFactories of a chunk into the `moduleFactories` Map.
|
||||
// The CompressedModuleFactories format is
|
||||
// - 1 or more module ids
|
||||
// - a module factory function
|
||||
// So walking this is a little complex but the flat structure is also fast to
|
||||
// traverse, we can use `typeof` operators to distinguish the two cases.
|
||||
function installCompressedModuleFactories(chunkModules, offset, moduleFactories, newModuleId) {
|
||||
let i = offset;
|
||||
while(i < chunkModules.length){
|
||||
let end = i + 1;
|
||||
// Find our factory function
|
||||
while(end < chunkModules.length && typeof chunkModules[end] !== 'function'){
|
||||
end++;
|
||||
}
|
||||
if (end === chunkModules.length) {
|
||||
throw new Error('malformed chunk format, expected a factory function');
|
||||
}
|
||||
// Install the factory for each module ID that doesn't already have one.
|
||||
// When some IDs in this group already have a factory, reuse that existing
|
||||
// group factory for the missing IDs to keep all IDs in the group consistent.
|
||||
// Otherwise, install the factory from this chunk.
|
||||
const moduleFactoryFn = chunkModules[end];
|
||||
let existingGroupFactory = undefined;
|
||||
for(let j = i; j < end; j++){
|
||||
const id = chunkModules[j];
|
||||
const existingFactory = moduleFactories.get(id);
|
||||
if (existingFactory) {
|
||||
existingGroupFactory = existingFactory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const factoryToInstall = existingGroupFactory ?? moduleFactoryFn;
|
||||
let didInstallFactory = false;
|
||||
for(let j = i; j < end; j++){
|
||||
const id = chunkModules[j];
|
||||
if (!moduleFactories.has(id)) {
|
||||
if (!didInstallFactory) {
|
||||
if (factoryToInstall === moduleFactoryFn) {
|
||||
applyModuleFactoryName(moduleFactoryFn);
|
||||
}
|
||||
didInstallFactory = true;
|
||||
}
|
||||
moduleFactories.set(id, factoryToInstall);
|
||||
newModuleId?.(id);
|
||||
}
|
||||
}
|
||||
i = end + 1; // end is pointing at the last factory advance to the next id or the end of the array.
|
||||
}
|
||||
}
|
||||
// everything below is adapted from webpack
|
||||
// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13
|
||||
const turbopackQueues = Symbol('turbopack queues');
|
||||
const turbopackExports = Symbol('turbopack exports');
|
||||
const turbopackError = Symbol('turbopack error');
|
||||
function resolveQueue(queue) {
|
||||
if (queue && queue.status !== 1) {
|
||||
queue.status = 1;
|
||||
queue.forEach((fn)=>fn.queueCount--);
|
||||
queue.forEach((fn)=>fn.queueCount-- ? fn.queueCount++ : fn());
|
||||
}
|
||||
}
|
||||
function wrapDeps(deps) {
|
||||
return deps.map((dep)=>{
|
||||
if (dep !== null && typeof dep === 'object') {
|
||||
if (isAsyncModuleExt(dep)) return dep;
|
||||
if (isPromise(dep)) {
|
||||
const queue = Object.assign([], {
|
||||
status: 0
|
||||
});
|
||||
const obj = {
|
||||
[turbopackExports]: {},
|
||||
[turbopackQueues]: (fn)=>fn(queue)
|
||||
};
|
||||
dep.then((res)=>{
|
||||
obj[turbopackExports] = res;
|
||||
resolveQueue(queue);
|
||||
}, (err)=>{
|
||||
obj[turbopackError] = err;
|
||||
resolveQueue(queue);
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return {
|
||||
[turbopackExports]: dep,
|
||||
[turbopackQueues]: ()=>{}
|
||||
};
|
||||
});
|
||||
}
|
||||
function asyncModule(body, hasAwait) {
|
||||
const module = this.m;
|
||||
const queue = hasAwait ? Object.assign([], {
|
||||
status: -1
|
||||
}) : undefined;
|
||||
const depQueues = new Set();
|
||||
const { resolve, reject, promise: rawPromise } = createPromise();
|
||||
const promise = Object.assign(rawPromise, {
|
||||
[turbopackExports]: module.exports,
|
||||
[turbopackQueues]: (fn)=>{
|
||||
queue && fn(queue);
|
||||
depQueues.forEach(fn);
|
||||
promise['catch'](()=>{});
|
||||
}
|
||||
});
|
||||
const attributes = {
|
||||
get () {
|
||||
return promise;
|
||||
},
|
||||
set (v) {
|
||||
// Calling `esmExport` leads to this.
|
||||
if (v !== promise) {
|
||||
promise[turbopackExports] = v;
|
||||
}
|
||||
}
|
||||
};
|
||||
Object.defineProperty(module, 'exports', attributes);
|
||||
Object.defineProperty(module, 'namespaceObject', attributes);
|
||||
function handleAsyncDependencies(deps) {
|
||||
const currentDeps = wrapDeps(deps);
|
||||
const getResult = ()=>currentDeps.map((d)=>{
|
||||
if (d[turbopackError]) throw d[turbopackError];
|
||||
return d[turbopackExports];
|
||||
});
|
||||
const { promise, resolve } = createPromise();
|
||||
const fn = Object.assign(()=>resolve(getResult), {
|
||||
queueCount: 0
|
||||
});
|
||||
function fnQueue(q) {
|
||||
if (q !== queue && !depQueues.has(q)) {
|
||||
depQueues.add(q);
|
||||
if (q && q.status === 0) {
|
||||
fn.queueCount++;
|
||||
q.push(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
currentDeps.map((dep)=>dep[turbopackQueues](fnQueue));
|
||||
return fn.queueCount ? promise : getResult();
|
||||
}
|
||||
function asyncResult(err) {
|
||||
if (err) {
|
||||
reject(promise[turbopackError] = err);
|
||||
} else {
|
||||
resolve(promise[turbopackExports]);
|
||||
}
|
||||
resolveQueue(queue);
|
||||
}
|
||||
body(handleAsyncDependencies, asyncResult);
|
||||
if (queue && queue.status === -1) {
|
||||
queue.status = 0;
|
||||
}
|
||||
}
|
||||
contextPrototype.a = asyncModule;
|
||||
/**
|
||||
* A pseudo "fake" URL object to resolve to its relative path.
|
||||
*
|
||||
* When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this
|
||||
* runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid
|
||||
* hydration mismatch.
|
||||
*
|
||||
* This is based on webpack's existing implementation:
|
||||
* https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js
|
||||
*/ const relativeURL = function relativeURL(inputUrl) {
|
||||
const realUrl = new URL(inputUrl, 'x:/');
|
||||
const values = {};
|
||||
for(const key in realUrl)values[key] = realUrl[key];
|
||||
values.href = inputUrl;
|
||||
values.pathname = inputUrl.replace(/[?#].*/, '');
|
||||
values.origin = values.protocol = '';
|
||||
values.toString = values.toJSON = (..._args)=>inputUrl;
|
||||
for(const key in values)Object.defineProperty(this, key, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: values[key]
|
||||
});
|
||||
};
|
||||
relativeURL.prototype = URL.prototype;
|
||||
contextPrototype.U = relativeURL;
|
||||
/**
|
||||
* Utility function to ensure all variants of an enum are handled.
|
||||
*/ function invariant(never, computeMessage) {
|
||||
throw new Error(`Invariant: ${computeMessage(never)}`);
|
||||
}
|
||||
/**
|
||||
* Constructs an error message for when a module factory is not available.
|
||||
*/ function factoryNotAvailableMessage(moduleId, sourceType, sourceData) {
|
||||
let instantiationReason;
|
||||
switch(sourceType){
|
||||
case 0:
|
||||
instantiationReason = `as a runtime entry of chunk ${sourceData}`;
|
||||
break;
|
||||
case 1:
|
||||
instantiationReason = `because it was required from module ${sourceData}`;
|
||||
break;
|
||||
case 2:
|
||||
instantiationReason = 'because of an HMR update';
|
||||
break;
|
||||
default:
|
||||
invariant(sourceType, (sourceType)=>`Unknown source type: ${sourceType}`);
|
||||
}
|
||||
return `Module ${moduleId} was instantiated ${instantiationReason}, but the module factory is not available.`;
|
||||
}
|
||||
/**
|
||||
* A stub function to make `require` available but non-functional in ESM.
|
||||
*/ function requireStub(_moduleId) {
|
||||
throw new Error('dynamic usage of require is not supported');
|
||||
}
|
||||
contextPrototype.z = requireStub;
|
||||
// Make `globalThis` available to the module in a way that cannot be shadowed by a local variable.
|
||||
contextPrototype.g = globalThis;
|
||||
function applyModuleFactoryName(factory) {
|
||||
// Give the module factory a nice name to improve stack traces.
|
||||
Object.defineProperty(factory, 'name', {
|
||||
value: 'module evaluation'
|
||||
});
|
||||
}
|
||||
/// <reference path="../shared/runtime/runtime-utils.ts" />
|
||||
/// A 'base' utilities to support runtime can have externals.
|
||||
/// Currently this is for node.js / edge runtime both.
|
||||
/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.
|
||||
async function externalImport(id) {
|
||||
let raw;
|
||||
try {
|
||||
raw = await import(id);
|
||||
} catch (err) {
|
||||
// TODO(alexkirsz) This can happen when a client-side module tries to load
|
||||
// an external module we don't provide a shim for (e.g. querystring, url).
|
||||
// For now, we fail semi-silently, but in the future this should be a
|
||||
// compilation error.
|
||||
throw new Error(`Failed to load external module ${id}: ${err}`);
|
||||
}
|
||||
if (raw && raw.__esModule && raw.default && 'default' in raw.default) {
|
||||
return interopEsm(raw.default, createNS(raw), true);
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
contextPrototype.y = externalImport;
|
||||
function externalRequire(id, thunk, esm = false) {
|
||||
let raw;
|
||||
try {
|
||||
raw = thunk();
|
||||
} catch (err) {
|
||||
// TODO(alexkirsz) This can happen when a client-side module tries to load
|
||||
// an external module we don't provide a shim for (e.g. querystring, url).
|
||||
// For now, we fail semi-silently, but in the future this should be a
|
||||
// compilation error.
|
||||
throw new Error(`Failed to load external module ${id}: ${err}`);
|
||||
}
|
||||
if (!esm || raw.__esModule) {
|
||||
return raw;
|
||||
}
|
||||
return interopEsm(raw, createNS(raw), true);
|
||||
}
|
||||
externalRequire.resolve = (id, options)=>{
|
||||
return require.resolve(id, options);
|
||||
};
|
||||
contextPrototype.x = externalRequire;
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */ const path = require('path');
|
||||
const relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, '.');
|
||||
// Compute the relative path to the `distDir`.
|
||||
const relativePathToDistRoot = path.join(relativePathToRuntimeRoot, RELATIVE_ROOT_PATH);
|
||||
const RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot);
|
||||
// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.
|
||||
const ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot);
|
||||
/**
|
||||
* Returns an absolute path to the given module path.
|
||||
* Module path should be relative, either path to a file or a directory.
|
||||
*
|
||||
* This fn allows to calculate an absolute path for some global static values, such as
|
||||
* `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.
|
||||
* See ImportMetaBinding::code_generation for the usage.
|
||||
*/ function resolveAbsolutePath(modulePath) {
|
||||
if (modulePath) {
|
||||
return path.join(ABSOLUTE_ROOT, modulePath);
|
||||
}
|
||||
return ABSOLUTE_ROOT;
|
||||
}
|
||||
Context.prototype.P = resolveAbsolutePath;
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="../shared/runtime/runtime-utils.ts" />
|
||||
function readWebAssemblyAsResponse(path) {
|
||||
const { createReadStream } = require('fs');
|
||||
const { Readable } = require('stream');
|
||||
const stream = createReadStream(path);
|
||||
// @ts-ignore unfortunately there's a slight type mismatch with the stream.
|
||||
return new Response(Readable.toWeb(stream), {
|
||||
headers: {
|
||||
'content-type': 'application/wasm'
|
||||
}
|
||||
});
|
||||
}
|
||||
async function compileWebAssemblyFromPath(path) {
|
||||
const response = readWebAssemblyAsResponse(path);
|
||||
return await WebAssembly.compileStreaming(response);
|
||||
}
|
||||
async function instantiateWebAssemblyFromPath(path, importsObj) {
|
||||
const response = readWebAssemblyAsResponse(path);
|
||||
const { instance } = await WebAssembly.instantiateStreaming(response, importsObj);
|
||||
return instance.exports;
|
||||
}
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="../../shared/runtime/runtime-utils.ts" />
|
||||
/// <reference path="../../shared-node/base-externals-utils.ts" />
|
||||
/// <reference path="../../shared-node/node-externals-utils.ts" />
|
||||
/// <reference path="../../shared-node/node-wasm-utils.ts" />
|
||||
/// <reference path="./nodejs-globals.d.ts" />
|
||||
/**
|
||||
* Base Node.js runtime shared between production and development.
|
||||
* Contains chunk loading, module caching, and other non-HMR functionality.
|
||||
*/ process.env.TURBOPACK = '1';
|
||||
const url = require('url');
|
||||
const moduleFactories = new Map();
|
||||
const moduleCache = Object.create(null);
|
||||
/**
|
||||
* Returns an absolute path to the given module's id.
|
||||
*/ function resolvePathFromModule(moduleId) {
|
||||
const exported = this.r(moduleId);
|
||||
const exportedPath = exported?.default ?? exported;
|
||||
if (typeof exportedPath !== 'string') {
|
||||
return exported;
|
||||
}
|
||||
const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);
|
||||
const resolved = path.resolve(RUNTIME_ROOT, strippedAssetPrefix);
|
||||
return url.pathToFileURL(resolved).href;
|
||||
}
|
||||
/**
|
||||
* Exports a URL value. No suffix is added in Node.js runtime.
|
||||
*/ function exportUrl(urlValue, id) {
|
||||
exportValue.call(this, urlValue, id);
|
||||
}
|
||||
function loadRuntimeChunk(sourcePath, chunkData) {
|
||||
if (typeof chunkData === 'string') {
|
||||
loadRuntimeChunkPath(sourcePath, chunkData);
|
||||
} else {
|
||||
loadRuntimeChunkPath(sourcePath, chunkData.path);
|
||||
}
|
||||
}
|
||||
const loadedChunks = new Set();
|
||||
const unsupportedLoadChunk = Promise.resolve(undefined);
|
||||
const loadedChunk = Promise.resolve(undefined);
|
||||
const chunkCache = new Map();
|
||||
function clearChunkCache() {
|
||||
chunkCache.clear();
|
||||
loadedChunks.clear();
|
||||
}
|
||||
function loadRuntimeChunkPath(sourcePath, chunkPath) {
|
||||
if (!isJs(chunkPath)) {
|
||||
// We only support loading JS chunks in Node.js.
|
||||
// This branch can be hit when trying to load a CSS chunk.
|
||||
return;
|
||||
}
|
||||
if (loadedChunks.has(chunkPath)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
|
||||
const chunkModules = require(resolved);
|
||||
installCompressedModuleFactories(chunkModules, 0, moduleFactories);
|
||||
loadedChunks.add(chunkPath);
|
||||
} catch (cause) {
|
||||
let errorMessage = `Failed to load chunk ${chunkPath}`;
|
||||
if (sourcePath) {
|
||||
errorMessage += ` from runtime for chunk ${sourcePath}`;
|
||||
}
|
||||
const error = new Error(errorMessage, {
|
||||
cause
|
||||
});
|
||||
error.name = 'ChunkLoadError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
function loadChunkAsync(chunkData) {
|
||||
const chunkPath = typeof chunkData === 'string' ? chunkData : chunkData.path;
|
||||
if (!isJs(chunkPath)) {
|
||||
// We only support loading JS chunks in Node.js.
|
||||
// This branch can be hit when trying to load a CSS chunk.
|
||||
return unsupportedLoadChunk;
|
||||
}
|
||||
let entry = chunkCache.get(chunkPath);
|
||||
if (entry === undefined) {
|
||||
try {
|
||||
// resolve to an absolute path to simplify `require` handling
|
||||
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
|
||||
// TODO: consider switching to `import()` to enable concurrent chunk loading and async file io
|
||||
// However this is incompatible with hot reloading (since `import` doesn't use the require cache)
|
||||
const chunkModules = require(resolved);
|
||||
installCompressedModuleFactories(chunkModules, 0, moduleFactories);
|
||||
entry = loadedChunk;
|
||||
} catch (cause) {
|
||||
const errorMessage = `Failed to load chunk ${chunkPath} from module ${this.m.id}`;
|
||||
const error = new Error(errorMessage, {
|
||||
cause
|
||||
});
|
||||
error.name = 'ChunkLoadError';
|
||||
// Cache the failure promise, future requests will also get this same rejection
|
||||
entry = Promise.reject(error);
|
||||
}
|
||||
chunkCache.set(chunkPath, entry);
|
||||
}
|
||||
// TODO: Return an instrumented Promise that React can use instead of relying on referential equality.
|
||||
return entry;
|
||||
}
|
||||
contextPrototype.l = loadChunkAsync;
|
||||
function loadChunkAsyncByUrl(chunkUrl) {
|
||||
const path1 = url.fileURLToPath(new URL(chunkUrl, RUNTIME_ROOT));
|
||||
return loadChunkAsync.call(this, path1);
|
||||
}
|
||||
contextPrototype.L = loadChunkAsyncByUrl;
|
||||
function loadWebAssembly(chunkPath, _edgeModule, imports) {
|
||||
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
|
||||
return instantiateWebAssemblyFromPath(resolved, imports);
|
||||
}
|
||||
contextPrototype.w = loadWebAssembly;
|
||||
function loadWebAssemblyModule(chunkPath, _edgeModule) {
|
||||
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
|
||||
return compileWebAssemblyFromPath(resolved);
|
||||
}
|
||||
contextPrototype.u = loadWebAssemblyModule;
|
||||
/**
|
||||
* Creates a Node.js worker thread by instantiating the given WorkerConstructor
|
||||
* with the appropriate path and options, including forwarded globals.
|
||||
*
|
||||
* @param WorkerConstructor The Worker constructor from worker_threads
|
||||
* @param workerPath Path to the worker entry chunk
|
||||
* @param workerOptions options to pass to the Worker constructor (optional)
|
||||
*/ function createWorker(WorkerConstructor, workerPath, workerOptions) {
|
||||
// Build the forwarded globals object
|
||||
const forwardedGlobals = {};
|
||||
for (const name of WORKER_FORWARDED_GLOBALS){
|
||||
forwardedGlobals[name] = globalThis[name];
|
||||
}
|
||||
// Merge workerData with forwarded globals
|
||||
const existingWorkerData = workerOptions?.workerData || {};
|
||||
const options = {
|
||||
...workerOptions,
|
||||
workerData: {
|
||||
...typeof existingWorkerData === 'object' ? existingWorkerData : {},
|
||||
__turbopack_globals__: forwardedGlobals
|
||||
}
|
||||
};
|
||||
return new WorkerConstructor(workerPath, options);
|
||||
}
|
||||
const regexJsUrl = /\.js(?:\?[^#]*)?(?:#.*)?$/;
|
||||
/**
|
||||
* Checks if a given path/URL ends with .js, optionally followed by ?query or #fragment.
|
||||
*/ function isJs(chunkUrlOrPath) {
|
||||
return regexJsUrl.test(chunkUrlOrPath);
|
||||
}
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="./runtime-base.ts" />
|
||||
/**
|
||||
* Production Node.js runtime.
|
||||
* Uses ModuleWithDirection and simple module instantiation without HMR support.
|
||||
*/ // moduleCache and moduleFactories are declared in runtime-base.ts
|
||||
// this is read in runtime-utils.ts so it creates a module with direction for hmr
|
||||
createModuleWithDirectionFlag = true;
|
||||
const nodeContextPrototype = Context.prototype;
|
||||
nodeContextPrototype.q = exportUrl;
|
||||
nodeContextPrototype.M = moduleFactories;
|
||||
// Cast moduleCache to ModuleWithDirection for production mode
|
||||
nodeContextPrototype.c = moduleCache;
|
||||
nodeContextPrototype.R = resolvePathFromModule;
|
||||
nodeContextPrototype.b = createWorker;
|
||||
nodeContextPrototype.C = clearChunkCache;
|
||||
function instantiateModule(id, sourceType, sourceData) {
|
||||
const moduleFactory = moduleFactories.get(id);
|
||||
if (typeof moduleFactory !== 'function') {
|
||||
// This can happen if modules incorrectly handle HMR disposes/updates,
|
||||
// e.g. when they keep a `setTimeout` around which still executes old code
|
||||
// and contains e.g. a `require("something")` call.
|
||||
throw new Error(factoryNotAvailableMessage(id, sourceType, sourceData));
|
||||
}
|
||||
const module1 = createModuleWithDirection(id);
|
||||
const exports = module1.exports;
|
||||
moduleCache[id] = module1;
|
||||
const context = new Context(module1, exports);
|
||||
// NOTE(alexkirsz) This can fail when the module encounters a runtime error.
|
||||
try {
|
||||
moduleFactory(context, module1, exports);
|
||||
} catch (error) {
|
||||
module1.error = error;
|
||||
throw error;
|
||||
}
|
||||
;
|
||||
module1.loaded = true;
|
||||
if (module1.namespaceObject && module1.exports !== module1.namespaceObject) {
|
||||
// in case of a circular dependency: cjs1 -> esm2 -> cjs1
|
||||
interopEsm(module1.exports, module1.namespaceObject);
|
||||
}
|
||||
return module1;
|
||||
}
|
||||
/**
|
||||
* Retrieves a module from the cache, or instantiate it if it is not cached.
|
||||
*/ // @ts-ignore
|
||||
function getOrInstantiateModuleFromParent(id, sourceModule) {
|
||||
const module1 = moduleCache[id];
|
||||
if (module1) {
|
||||
if (module1.error) {
|
||||
throw module1.error;
|
||||
}
|
||||
return module1;
|
||||
}
|
||||
return instantiateModule(id, SourceType.Parent, sourceModule.id);
|
||||
}
|
||||
/**
|
||||
* Instantiates a runtime module.
|
||||
*/ function instantiateRuntimeModule(chunkPath, moduleId) {
|
||||
return instantiateModule(moduleId, SourceType.Runtime, chunkPath);
|
||||
}
|
||||
/**
|
||||
* Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.
|
||||
*/ // @ts-ignore TypeScript doesn't separate this module space from the browser runtime
|
||||
function getOrInstantiateRuntimeModule(chunkPath, moduleId) {
|
||||
const module1 = moduleCache[moduleId];
|
||||
if (module1) {
|
||||
if (module1.error) {
|
||||
throw module1.error;
|
||||
}
|
||||
return module1;
|
||||
}
|
||||
return instantiateRuntimeModule(chunkPath, moduleId);
|
||||
}
|
||||
module.exports = (sourcePath)=>({
|
||||
m: (id)=>getOrInstantiateRuntimeModule(sourcePath, id),
|
||||
c: (chunkData)=>loadRuntimeChunk(sourcePath, chunkData)
|
||||
});
|
||||
|
||||
|
||||
//# sourceMappingURL=%5Bturbopack%5D_runtime.js.map
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"type": "commonjs"}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"previewModeId":"27f0f448c7612d99367a5f2ad3ef640d","previewModeSigningKey":"469588a4123d872c601d6b7e46a81a0293be778414e874ade1dd894e5043ed18","previewModeEncryptionKey":"4a32c4a98be7f6aa59c45d2df6499282db46fc75be9b9c20202a11465a1c588e","expireAt":1782368592282}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"encryption.key":"rwAwLx2fk2wbc+k6wADc7BSosNYJAwa6zblnOMU+nFc=","encryption.expire_at":1782368591986}
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"buildStage": "static-generation",
|
||||
"buildOptions": {
|
||||
"useBuildWorker": "true"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"name":"Next.js","version":"16.2.8"}
|
||||
@@ -0,0 +1,282 @@
|
||||
[
|
||||
{
|
||||
"route": "/dashboard/site-config",
|
||||
"firstLoadUncompressedJsBytes": 582588,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/0r14kfqe43tub.js",
|
||||
".next/static/chunks/2whz8frja7po-.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/companies/[id]",
|
||||
"firstLoadUncompressedJsBytes": 572521,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/0ftm9qkpl7qx7.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/pricing",
|
||||
"firstLoadUncompressedJsBytes": 568782,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/28c_rrttruhlp.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/billing",
|
||||
"firstLoadUncompressedJsBytes": 566874,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/27az1pyngxlsz.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/menu-management",
|
||||
"firstLoadUncompressedJsBytes": 555732,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/2ugxxdv2czoee.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/containers",
|
||||
"firstLoadUncompressedJsBytes": 550410,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/2_lq6leer_gua.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/admin-users",
|
||||
"firstLoadUncompressedJsBytes": 546840,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/32xus5prj3hqj.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/notifications",
|
||||
"firstLoadUncompressedJsBytes": 544442,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/3v_-a-9hx_lw5.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/companies",
|
||||
"firstLoadUncompressedJsBytes": 544223,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/0xq7_2ktak4rb.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/renters",
|
||||
"firstLoadUncompressedJsBytes": 543111,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/0wwp54sprh-2v.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard",
|
||||
"firstLoadUncompressedJsBytes": 541745,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/0tgw0ys6ar29k.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/dashboard/audit-logs",
|
||||
"firstLoadUncompressedJsBytes": 541648,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0uk61hc83wuns.js",
|
||||
".next/static/chunks/1upk0tvhu5p1u.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/reset-password",
|
||||
"firstLoadUncompressedJsBytes": 540430,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/0rygltw2dxjw9.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/forgot-password",
|
||||
"firstLoadUncompressedJsBytes": 538901,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/3t7upkfpy4qk3.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/auth-redirect",
|
||||
"firstLoadUncompressedJsBytes": 523947,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/2r7tgel-fszrc.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/",
|
||||
"firstLoadUncompressedJsBytes": 523181,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/_not-found",
|
||||
"firstLoadUncompressedJsBytes": 523181,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"route": "/login",
|
||||
"firstLoadUncompressedJsBytes": 523181,
|
||||
"firstLoadChunkPaths": [
|
||||
".next/static/chunks/05-c3ty_6dwfk.js",
|
||||
".next/static/chunks/18sotvvmcs59d.js",
|
||||
".next/static/chunks/10txdscg_s8qk.js",
|
||||
".next/static/chunks/3fi7ta8l6_q46.js",
|
||||
".next/static/chunks/2de_cmw_l_puw.js",
|
||||
".next/static/chunks/3svce10uq2e6q.js",
|
||||
".next/static/chunks/40z7xw1jd_fv0.js",
|
||||
".next/static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 1,
|
||||
"hasExportPathMap": false,
|
||||
"exportTrailingSlash": false,
|
||||
"isNextImageImported": false
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"pages": {
|
||||
"/_app": []
|
||||
},
|
||||
"devFiles": [],
|
||||
"polyfillFiles": [],
|
||||
"lowPriorityFiles": [
|
||||
"static/jRlQg50qYlv2hlr5AFzlp/_buildManifest.js",
|
||||
"static/jRlQg50qYlv2hlr5AFzlp/_ssgManifest.js",
|
||||
"static/jRlQg50qYlv2hlr5AFzlp/_clientMiddlewareManifest.js"
|
||||
],
|
||||
"rootMainFiles": []
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"version": 1,
|
||||
"images": {
|
||||
"deviceSizes": [
|
||||
640,
|
||||
750,
|
||||
828,
|
||||
1080,
|
||||
1200,
|
||||
1920,
|
||||
2048,
|
||||
3840
|
||||
],
|
||||
"imageSizes": [
|
||||
32,
|
||||
48,
|
||||
64,
|
||||
96,
|
||||
128,
|
||||
256,
|
||||
384
|
||||
],
|
||||
"path": "/admin/_next/image",
|
||||
"loader": "default",
|
||||
"loaderFile": "",
|
||||
"domains": [],
|
||||
"disableStaticImages": false,
|
||||
"minimumCacheTTL": 14400,
|
||||
"formats": [
|
||||
"image/webp"
|
||||
],
|
||||
"maximumRedirects": 3,
|
||||
"maximumResponseBody": 50000000,
|
||||
"dangerouslyAllowLocalIP": false,
|
||||
"dangerouslyAllowSVG": false,
|
||||
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
|
||||
"contentDispositionType": "attachment",
|
||||
"localPatterns": [
|
||||
{
|
||||
"pathname": "^(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$))(?:(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$)).)*?)\\/?)$",
|
||||
"search": ""
|
||||
}
|
||||
],
|
||||
"remotePatterns": [
|
||||
{
|
||||
"protocol": "https",
|
||||
"hostname": "^(?:^(?:res\\.cloudinary\\.com)$)$",
|
||||
"pathname": "^(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$))(?:(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$)).)*?)\\/?)$"
|
||||
},
|
||||
{
|
||||
"protocol": "http",
|
||||
"hostname": "^(?:^(?:localhost)$)$",
|
||||
"port": "4000",
|
||||
"pathname": "^(?:\\/storage(?:\\/(?!\\.{1,2}(?:\\/|$))(?:(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$)).)*?)|$))$"
|
||||
}
|
||||
],
|
||||
"qualities": [
|
||||
75
|
||||
],
|
||||
"unoptimized": false,
|
||||
"customCacheHandler": false,
|
||||
"sizes": [
|
||||
640,
|
||||
750,
|
||||
828,
|
||||
1080,
|
||||
1200,
|
||||
1920,
|
||||
2048,
|
||||
3840,
|
||||
32,
|
||||
48,
|
||||
64,
|
||||
96,
|
||||
128,
|
||||
256,
|
||||
384
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"type": "commonjs"}
|
||||
@@ -0,0 +1,450 @@
|
||||
{
|
||||
"version": 4,
|
||||
"routes": {
|
||||
"/": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/",
|
||||
"dataRoute": "/index.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/_global-error": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/_global-error",
|
||||
"dataRoute": "/_global-error.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/_not-found": {
|
||||
"initialStatus": 404,
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/_not-found",
|
||||
"dataRoute": "/_not-found.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/auth-redirect": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/auth-redirect",
|
||||
"dataRoute": "/auth-redirect.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard",
|
||||
"dataRoute": "/dashboard.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/admin-users": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/admin-users",
|
||||
"dataRoute": "/dashboard/admin-users.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/audit-logs": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/audit-logs",
|
||||
"dataRoute": "/dashboard/audit-logs.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/billing": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/billing",
|
||||
"dataRoute": "/dashboard/billing.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/companies": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/companies",
|
||||
"dataRoute": "/dashboard/companies.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/containers": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/containers",
|
||||
"dataRoute": "/dashboard/containers.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/menu-management": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/menu-management",
|
||||
"dataRoute": "/dashboard/menu-management.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/notifications": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/notifications",
|
||||
"dataRoute": "/dashboard/notifications.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/pricing": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/pricing",
|
||||
"dataRoute": "/dashboard/pricing.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/renters": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/renters",
|
||||
"dataRoute": "/dashboard/renters.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/dashboard/site-config": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/dashboard/site-config",
|
||||
"dataRoute": "/dashboard/site-config.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/forgot-password": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/forgot-password",
|
||||
"dataRoute": "/forgot-password.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/icon": {
|
||||
"initialHeaders": {
|
||||
"cache-control": "public, max-age=0, must-revalidate",
|
||||
"content-type": "image/png",
|
||||
"x-next-cache-tags": "_N_T_/layout,_N_T_/icon/layout,_N_T_/icon/route,_N_T_/icon"
|
||||
},
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/icon",
|
||||
"dataRoute": null,
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
},
|
||||
"/reset-password": {
|
||||
"experimentalBypassFor": [
|
||||
{
|
||||
"type": "header",
|
||||
"key": "next-action"
|
||||
},
|
||||
{
|
||||
"type": "header",
|
||||
"key": "content-type",
|
||||
"value": "multipart/form-data;.*"
|
||||
}
|
||||
],
|
||||
"initialRevalidateSeconds": false,
|
||||
"srcRoute": "/reset-password",
|
||||
"dataRoute": "/reset-password.rsc",
|
||||
"allowHeader": [
|
||||
"host",
|
||||
"x-matched-path",
|
||||
"x-prerender-revalidate",
|
||||
"x-prerender-revalidate-if-generated",
|
||||
"x-next-revalidated-tags",
|
||||
"x-next-revalidate-tag-token"
|
||||
]
|
||||
}
|
||||
},
|
||||
"dynamicRoutes": {},
|
||||
"notFoundRoutes": [],
|
||||
"preview": {
|
||||
"previewModeId": "27f0f448c7612d99367a5f2ad3ef640d",
|
||||
"previewModeSigningKey": "469588a4123d872c601d6b7e46a81a0293be778414e874ade1dd894e5043ed18",
|
||||
"previewModeEncryptionKey": "4a32c4a98be7f6aa59c45d2df6499282db46fc75be9b9c20202a11465a1c588e"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
self.__SERVER_FILES_MANIFEST={
|
||||
"version": 1,
|
||||
"config": {
|
||||
"env": {},
|
||||
"webpack": null,
|
||||
"typescript": {
|
||||
"ignoreBuildErrors": false
|
||||
},
|
||||
"typedRoutes": false,
|
||||
"distDir": ".next",
|
||||
"cleanDistDir": true,
|
||||
"assetPrefix": "/admin",
|
||||
"cacheMaxMemorySize": 52428800,
|
||||
"configOrigin": "next.config.js",
|
||||
"useFileSystemPublicRoutes": true,
|
||||
"generateEtags": true,
|
||||
"pageExtensions": [
|
||||
"tsx",
|
||||
"ts",
|
||||
"jsx",
|
||||
"js"
|
||||
],
|
||||
"poweredByHeader": true,
|
||||
"compress": true,
|
||||
"images": {
|
||||
"deviceSizes": [
|
||||
640,
|
||||
750,
|
||||
828,
|
||||
1080,
|
||||
1200,
|
||||
1920,
|
||||
2048,
|
||||
3840
|
||||
],
|
||||
"imageSizes": [
|
||||
32,
|
||||
48,
|
||||
64,
|
||||
96,
|
||||
128,
|
||||
256,
|
||||
384
|
||||
],
|
||||
"path": "/admin/_next/image",
|
||||
"loader": "default",
|
||||
"loaderFile": "",
|
||||
"domains": [],
|
||||
"disableStaticImages": false,
|
||||
"minimumCacheTTL": 14400,
|
||||
"formats": [
|
||||
"image/webp"
|
||||
],
|
||||
"maximumRedirects": 3,
|
||||
"maximumResponseBody": 50000000,
|
||||
"dangerouslyAllowLocalIP": false,
|
||||
"dangerouslyAllowSVG": false,
|
||||
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
|
||||
"contentDispositionType": "attachment",
|
||||
"localPatterns": [
|
||||
{
|
||||
"pathname": "**",
|
||||
"search": ""
|
||||
}
|
||||
],
|
||||
"remotePatterns": [
|
||||
{
|
||||
"protocol": "https",
|
||||
"hostname": "res.cloudinary.com"
|
||||
},
|
||||
{
|
||||
"protocol": "http",
|
||||
"hostname": "localhost",
|
||||
"port": "4000",
|
||||
"pathname": "/storage/**"
|
||||
}
|
||||
],
|
||||
"qualities": [
|
||||
75
|
||||
],
|
||||
"unoptimized": false,
|
||||
"customCacheHandler": false
|
||||
},
|
||||
"devIndicators": {
|
||||
"position": "bottom-left"
|
||||
},
|
||||
"onDemandEntries": {
|
||||
"maxInactiveAge": 60000,
|
||||
"pagesBufferLength": 5
|
||||
},
|
||||
"basePath": "/admin",
|
||||
"sassOptions": {},
|
||||
"trailingSlash": false,
|
||||
"i18n": null,
|
||||
"productionBrowserSourceMaps": false,
|
||||
"excludeDefaultMomentLocales": true,
|
||||
"reactProductionProfiling": false,
|
||||
"reactStrictMode": null,
|
||||
"reactMaxHeadersLength": 6000,
|
||||
"httpAgentOptions": {
|
||||
"keepAlive": true
|
||||
},
|
||||
"logging": {
|
||||
"serverFunctions": true,
|
||||
"browserToTerminal": "warn"
|
||||
},
|
||||
"compiler": {},
|
||||
"expireTime": 31536000,
|
||||
"staticPageGenerationTimeout": 60,
|
||||
"modularizeImports": {
|
||||
"@mui/icons-material": {
|
||||
"transform": "@mui/icons-material/{{member}}"
|
||||
},
|
||||
"lodash": {
|
||||
"transform": "lodash/{{member}}"
|
||||
}
|
||||
},
|
||||
"outputFileTracingRoot": "/Volumes/ExternalApps/Documents/alrahma_sunday_school_api",
|
||||
"cacheComponents": false,
|
||||
"cacheLife": {
|
||||
"default": {
|
||||
"stale": 300,
|
||||
"revalidate": 900,
|
||||
"expire": 4294967294
|
||||
},
|
||||
"seconds": {
|
||||
"stale": 30,
|
||||
"revalidate": 1,
|
||||
"expire": 60
|
||||
},
|
||||
"minutes": {
|
||||
"stale": 300,
|
||||
"revalidate": 60,
|
||||
"expire": 3600
|
||||
},
|
||||
"hours": {
|
||||
"stale": 300,
|
||||
"revalidate": 3600,
|
||||
"expire": 86400
|
||||
},
|
||||
"days": {
|
||||
"stale": 300,
|
||||
"revalidate": 86400,
|
||||
"expire": 604800
|
||||
},
|
||||
"weeks": {
|
||||
"stale": 300,
|
||||
"revalidate": 604800,
|
||||
"expire": 2592000
|
||||
},
|
||||
"max": {
|
||||
"stale": 300,
|
||||
"revalidate": 2592000,
|
||||
"expire": 31536000
|
||||
}
|
||||
},
|
||||
"cacheHandlers": {},
|
||||
"experimental": {
|
||||
"appNewScrollHandler": false,
|
||||
"useSkewCookie": false,
|
||||
"cssChunking": true,
|
||||
"multiZoneDraftMode": false,
|
||||
"appNavFailHandling": false,
|
||||
"prerenderEarlyExit": true,
|
||||
"serverMinification": true,
|
||||
"linkNoTouchStart": false,
|
||||
"caseSensitiveRoutes": false,
|
||||
"cachedNavigations": false,
|
||||
"partialFallbacks": false,
|
||||
"dynamicOnHover": false,
|
||||
"varyParams": false,
|
||||
"prefetchInlining": false,
|
||||
"preloadEntriesOnStart": true,
|
||||
"clientRouterFilter": true,
|
||||
"clientRouterFilterRedirects": false,
|
||||
"fetchCacheKeyPrefix": "",
|
||||
"proxyPrefetch": "flexible",
|
||||
"optimisticClientCache": true,
|
||||
"manualClientBasePath": false,
|
||||
"cpus": 9,
|
||||
"memoryBasedWorkersCount": false,
|
||||
"imgOptConcurrency": null,
|
||||
"imgOptTimeoutInSeconds": 7,
|
||||
"imgOptMaxInputPixels": 268402689,
|
||||
"imgOptSequentialRead": null,
|
||||
"imgOptSkipMetadata": null,
|
||||
"isrFlushToDisk": true,
|
||||
"workerThreads": false,
|
||||
"optimizeCss": false,
|
||||
"nextScriptWorkers": false,
|
||||
"scrollRestoration": false,
|
||||
"externalDir": false,
|
||||
"disableOptimizedLoading": false,
|
||||
"gzipSize": true,
|
||||
"craCompat": false,
|
||||
"esmExternals": true,
|
||||
"fullySpecified": false,
|
||||
"swcTraceProfiling": false,
|
||||
"forceSwcTransforms": false,
|
||||
"largePageDataBytes": 128000,
|
||||
"typedEnv": false,
|
||||
"parallelServerCompiles": false,
|
||||
"parallelServerBuildTraces": false,
|
||||
"ppr": false,
|
||||
"authInterrupts": false,
|
||||
"webpackMemoryOptimizations": false,
|
||||
"optimizeServerReact": true,
|
||||
"strictRouteTypes": false,
|
||||
"viewTransition": false,
|
||||
"removeUncaughtErrorAndRejectionListeners": false,
|
||||
"validateRSCRequestHeaders": false,
|
||||
"staleTimes": {
|
||||
"dynamic": 0,
|
||||
"static": 300
|
||||
},
|
||||
"reactDebugChannel": true,
|
||||
"serverComponentsHmrCache": true,
|
||||
"staticGenerationMaxConcurrency": 8,
|
||||
"staticGenerationMinPagesPerWorker": 25,
|
||||
"transitionIndicator": false,
|
||||
"gestureTransition": false,
|
||||
"inlineCss": false,
|
||||
"useCache": false,
|
||||
"globalNotFound": false,
|
||||
"browserDebugInfoInTerminal": "warn",
|
||||
"lockDistDir": true,
|
||||
"proxyClientMaxBodySize": 10485760,
|
||||
"hideLogsAfterAbort": false,
|
||||
"mcpServer": true,
|
||||
"turbopackFileSystemCacheForDev": true,
|
||||
"turbopackFileSystemCacheForBuild": false,
|
||||
"turbopackInferModuleSideEffects": true,
|
||||
"turbopackPluginRuntimeStrategy": "childProcesses",
|
||||
"optimizePackageImports": [
|
||||
"lucide-react",
|
||||
"date-fns",
|
||||
"lodash-es",
|
||||
"ramda",
|
||||
"antd",
|
||||
"react-bootstrap",
|
||||
"ahooks",
|
||||
"@ant-design/icons",
|
||||
"@headlessui/react",
|
||||
"@headlessui-float/react",
|
||||
"@heroicons/react/20/solid",
|
||||
"@heroicons/react/24/solid",
|
||||
"@heroicons/react/24/outline",
|
||||
"@visx/visx",
|
||||
"@tremor/react",
|
||||
"rxjs",
|
||||
"@mui/material",
|
||||
"@mui/icons-material",
|
||||
"recharts",
|
||||
"react-use",
|
||||
"effect",
|
||||
"@effect/schema",
|
||||
"@effect/platform",
|
||||
"@effect/platform-node",
|
||||
"@effect/platform-browser",
|
||||
"@effect/platform-bun",
|
||||
"@effect/sql",
|
||||
"@effect/sql-mssql",
|
||||
"@effect/sql-mysql2",
|
||||
"@effect/sql-pg",
|
||||
"@effect/sql-sqlite-node",
|
||||
"@effect/sql-sqlite-bun",
|
||||
"@effect/sql-sqlite-wasm",
|
||||
"@effect/sql-sqlite-react-native",
|
||||
"@effect/rpc",
|
||||
"@effect/rpc-http",
|
||||
"@effect/typeclass",
|
||||
"@effect/experimental",
|
||||
"@effect/opentelemetry",
|
||||
"@material-ui/core",
|
||||
"@material-ui/icons",
|
||||
"@tabler/icons-react",
|
||||
"mui-core",
|
||||
"react-icons/ai",
|
||||
"react-icons/bi",
|
||||
"react-icons/bs",
|
||||
"react-icons/cg",
|
||||
"react-icons/ci",
|
||||
"react-icons/di",
|
||||
"react-icons/fa",
|
||||
"react-icons/fa6",
|
||||
"react-icons/fc",
|
||||
"react-icons/fi",
|
||||
"react-icons/gi",
|
||||
"react-icons/go",
|
||||
"react-icons/gr",
|
||||
"react-icons/hi",
|
||||
"react-icons/hi2",
|
||||
"react-icons/im",
|
||||
"react-icons/io",
|
||||
"react-icons/io5",
|
||||
"react-icons/lia",
|
||||
"react-icons/lib",
|
||||
"react-icons/lu",
|
||||
"react-icons/md",
|
||||
"react-icons/pi",
|
||||
"react-icons/ri",
|
||||
"react-icons/rx",
|
||||
"react-icons/si",
|
||||
"react-icons/sl",
|
||||
"react-icons/tb",
|
||||
"react-icons/tfi",
|
||||
"react-icons/ti",
|
||||
"react-icons/vsc",
|
||||
"react-icons/wi"
|
||||
],
|
||||
"trustHostHeader": false,
|
||||
"isExperimentalCompile": false
|
||||
},
|
||||
"htmlLimitedBots": "[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight",
|
||||
"bundlePagesRouterDependencies": false,
|
||||
"configFileName": "next.config.js",
|
||||
"transpilePackages": [
|
||||
"@rentaldrivego/types"
|
||||
],
|
||||
"turbopack": {
|
||||
"root": "/Volumes/ExternalApps/Documents/alrahma_sunday_school_api"
|
||||
},
|
||||
"distDirRoot": ".next",
|
||||
"_originalRewrites": {
|
||||
"beforeFiles": [],
|
||||
"afterFiles": [
|
||||
{
|
||||
"source": "/api/:path*",
|
||||
"destination": "http://localhost:4000/api/:path*"
|
||||
}
|
||||
],
|
||||
"fallback": []
|
||||
}
|
||||
},
|
||||
"appDir": "/Volumes/ExternalApps/Documents/alrahma_sunday_school_api/apps/admin",
|
||||
"relativeAppDir": "apps/admin",
|
||||
"files": [
|
||||
".next/package.json",
|
||||
".next/routes-manifest.json",
|
||||
".next/server/pages-manifest.json",
|
||||
".next/build-manifest.json",
|
||||
".next/prerender-manifest.json",
|
||||
".next/server/functions-config-manifest.json",
|
||||
".next/server/middleware-manifest.json",
|
||||
".next/server/middleware-build-manifest.js",
|
||||
".next/server/app-paths-manifest.json",
|
||||
".next/app-path-routes-manifest.json",
|
||||
".next/server/server-reference-manifest.js",
|
||||
".next/server/server-reference-manifest.json",
|
||||
".next/server/prefetch-hints.json",
|
||||
".next/BUILD_ID",
|
||||
".next/server/next-font-manifest.js",
|
||||
".next/server/next-font-manifest.json",
|
||||
".next/required-server-files.json"
|
||||
],
|
||||
"ignore": []
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
{
|
||||
"version": 1,
|
||||
"config": {
|
||||
"env": {},
|
||||
"webpack": null,
|
||||
"typescript": {
|
||||
"ignoreBuildErrors": false
|
||||
},
|
||||
"typedRoutes": false,
|
||||
"distDir": ".next",
|
||||
"cleanDistDir": true,
|
||||
"assetPrefix": "/admin",
|
||||
"cacheMaxMemorySize": 52428800,
|
||||
"configOrigin": "next.config.js",
|
||||
"useFileSystemPublicRoutes": true,
|
||||
"generateEtags": true,
|
||||
"pageExtensions": [
|
||||
"tsx",
|
||||
"ts",
|
||||
"jsx",
|
||||
"js"
|
||||
],
|
||||
"poweredByHeader": true,
|
||||
"compress": true,
|
||||
"images": {
|
||||
"deviceSizes": [
|
||||
640,
|
||||
750,
|
||||
828,
|
||||
1080,
|
||||
1200,
|
||||
1920,
|
||||
2048,
|
||||
3840
|
||||
],
|
||||
"imageSizes": [
|
||||
32,
|
||||
48,
|
||||
64,
|
||||
96,
|
||||
128,
|
||||
256,
|
||||
384
|
||||
],
|
||||
"path": "/admin/_next/image",
|
||||
"loader": "default",
|
||||
"loaderFile": "",
|
||||
"domains": [],
|
||||
"disableStaticImages": false,
|
||||
"minimumCacheTTL": 14400,
|
||||
"formats": [
|
||||
"image/webp"
|
||||
],
|
||||
"maximumRedirects": 3,
|
||||
"maximumResponseBody": 50000000,
|
||||
"dangerouslyAllowLocalIP": false,
|
||||
"dangerouslyAllowSVG": false,
|
||||
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
|
||||
"contentDispositionType": "attachment",
|
||||
"localPatterns": [
|
||||
{
|
||||
"pathname": "**",
|
||||
"search": ""
|
||||
}
|
||||
],
|
||||
"remotePatterns": [
|
||||
{
|
||||
"protocol": "https",
|
||||
"hostname": "res.cloudinary.com"
|
||||
},
|
||||
{
|
||||
"protocol": "http",
|
||||
"hostname": "localhost",
|
||||
"port": "4000",
|
||||
"pathname": "/storage/**"
|
||||
}
|
||||
],
|
||||
"qualities": [
|
||||
75
|
||||
],
|
||||
"unoptimized": false,
|
||||
"customCacheHandler": false
|
||||
},
|
||||
"devIndicators": {
|
||||
"position": "bottom-left"
|
||||
},
|
||||
"onDemandEntries": {
|
||||
"maxInactiveAge": 60000,
|
||||
"pagesBufferLength": 5
|
||||
},
|
||||
"basePath": "/admin",
|
||||
"sassOptions": {},
|
||||
"trailingSlash": false,
|
||||
"i18n": null,
|
||||
"productionBrowserSourceMaps": false,
|
||||
"excludeDefaultMomentLocales": true,
|
||||
"reactProductionProfiling": false,
|
||||
"reactStrictMode": null,
|
||||
"reactMaxHeadersLength": 6000,
|
||||
"httpAgentOptions": {
|
||||
"keepAlive": true
|
||||
},
|
||||
"logging": {
|
||||
"serverFunctions": true,
|
||||
"browserToTerminal": "warn"
|
||||
},
|
||||
"compiler": {},
|
||||
"expireTime": 31536000,
|
||||
"staticPageGenerationTimeout": 60,
|
||||
"modularizeImports": {
|
||||
"@mui/icons-material": {
|
||||
"transform": "@mui/icons-material/{{member}}"
|
||||
},
|
||||
"lodash": {
|
||||
"transform": "lodash/{{member}}"
|
||||
}
|
||||
},
|
||||
"outputFileTracingRoot": "/Volumes/ExternalApps/Documents/alrahma_sunday_school_api",
|
||||
"cacheComponents": false,
|
||||
"cacheLife": {
|
||||
"default": {
|
||||
"stale": 300,
|
||||
"revalidate": 900,
|
||||
"expire": 4294967294
|
||||
},
|
||||
"seconds": {
|
||||
"stale": 30,
|
||||
"revalidate": 1,
|
||||
"expire": 60
|
||||
},
|
||||
"minutes": {
|
||||
"stale": 300,
|
||||
"revalidate": 60,
|
||||
"expire": 3600
|
||||
},
|
||||
"hours": {
|
||||
"stale": 300,
|
||||
"revalidate": 3600,
|
||||
"expire": 86400
|
||||
},
|
||||
"days": {
|
||||
"stale": 300,
|
||||
"revalidate": 86400,
|
||||
"expire": 604800
|
||||
},
|
||||
"weeks": {
|
||||
"stale": 300,
|
||||
"revalidate": 604800,
|
||||
"expire": 2592000
|
||||
},
|
||||
"max": {
|
||||
"stale": 300,
|
||||
"revalidate": 2592000,
|
||||
"expire": 31536000
|
||||
}
|
||||
},
|
||||
"cacheHandlers": {},
|
||||
"experimental": {
|
||||
"appNewScrollHandler": false,
|
||||
"useSkewCookie": false,
|
||||
"cssChunking": true,
|
||||
"multiZoneDraftMode": false,
|
||||
"appNavFailHandling": false,
|
||||
"prerenderEarlyExit": true,
|
||||
"serverMinification": true,
|
||||
"linkNoTouchStart": false,
|
||||
"caseSensitiveRoutes": false,
|
||||
"cachedNavigations": false,
|
||||
"partialFallbacks": false,
|
||||
"dynamicOnHover": false,
|
||||
"varyParams": false,
|
||||
"prefetchInlining": false,
|
||||
"preloadEntriesOnStart": true,
|
||||
"clientRouterFilter": true,
|
||||
"clientRouterFilterRedirects": false,
|
||||
"fetchCacheKeyPrefix": "",
|
||||
"proxyPrefetch": "flexible",
|
||||
"optimisticClientCache": true,
|
||||
"manualClientBasePath": false,
|
||||
"cpus": 9,
|
||||
"memoryBasedWorkersCount": false,
|
||||
"imgOptConcurrency": null,
|
||||
"imgOptTimeoutInSeconds": 7,
|
||||
"imgOptMaxInputPixels": 268402689,
|
||||
"imgOptSequentialRead": null,
|
||||
"imgOptSkipMetadata": null,
|
||||
"isrFlushToDisk": true,
|
||||
"workerThreads": false,
|
||||
"optimizeCss": false,
|
||||
"nextScriptWorkers": false,
|
||||
"scrollRestoration": false,
|
||||
"externalDir": false,
|
||||
"disableOptimizedLoading": false,
|
||||
"gzipSize": true,
|
||||
"craCompat": false,
|
||||
"esmExternals": true,
|
||||
"fullySpecified": false,
|
||||
"swcTraceProfiling": false,
|
||||
"forceSwcTransforms": false,
|
||||
"largePageDataBytes": 128000,
|
||||
"typedEnv": false,
|
||||
"parallelServerCompiles": false,
|
||||
"parallelServerBuildTraces": false,
|
||||
"ppr": false,
|
||||
"authInterrupts": false,
|
||||
"webpackMemoryOptimizations": false,
|
||||
"optimizeServerReact": true,
|
||||
"strictRouteTypes": false,
|
||||
"viewTransition": false,
|
||||
"removeUncaughtErrorAndRejectionListeners": false,
|
||||
"validateRSCRequestHeaders": false,
|
||||
"staleTimes": {
|
||||
"dynamic": 0,
|
||||
"static": 300
|
||||
},
|
||||
"reactDebugChannel": true,
|
||||
"serverComponentsHmrCache": true,
|
||||
"staticGenerationMaxConcurrency": 8,
|
||||
"staticGenerationMinPagesPerWorker": 25,
|
||||
"transitionIndicator": false,
|
||||
"gestureTransition": false,
|
||||
"inlineCss": false,
|
||||
"useCache": false,
|
||||
"globalNotFound": false,
|
||||
"browserDebugInfoInTerminal": "warn",
|
||||
"lockDistDir": true,
|
||||
"proxyClientMaxBodySize": 10485760,
|
||||
"hideLogsAfterAbort": false,
|
||||
"mcpServer": true,
|
||||
"turbopackFileSystemCacheForDev": true,
|
||||
"turbopackFileSystemCacheForBuild": false,
|
||||
"turbopackInferModuleSideEffects": true,
|
||||
"turbopackPluginRuntimeStrategy": "childProcesses",
|
||||
"optimizePackageImports": [
|
||||
"lucide-react",
|
||||
"date-fns",
|
||||
"lodash-es",
|
||||
"ramda",
|
||||
"antd",
|
||||
"react-bootstrap",
|
||||
"ahooks",
|
||||
"@ant-design/icons",
|
||||
"@headlessui/react",
|
||||
"@headlessui-float/react",
|
||||
"@heroicons/react/20/solid",
|
||||
"@heroicons/react/24/solid",
|
||||
"@heroicons/react/24/outline",
|
||||
"@visx/visx",
|
||||
"@tremor/react",
|
||||
"rxjs",
|
||||
"@mui/material",
|
||||
"@mui/icons-material",
|
||||
"recharts",
|
||||
"react-use",
|
||||
"effect",
|
||||
"@effect/schema",
|
||||
"@effect/platform",
|
||||
"@effect/platform-node",
|
||||
"@effect/platform-browser",
|
||||
"@effect/platform-bun",
|
||||
"@effect/sql",
|
||||
"@effect/sql-mssql",
|
||||
"@effect/sql-mysql2",
|
||||
"@effect/sql-pg",
|
||||
"@effect/sql-sqlite-node",
|
||||
"@effect/sql-sqlite-bun",
|
||||
"@effect/sql-sqlite-wasm",
|
||||
"@effect/sql-sqlite-react-native",
|
||||
"@effect/rpc",
|
||||
"@effect/rpc-http",
|
||||
"@effect/typeclass",
|
||||
"@effect/experimental",
|
||||
"@effect/opentelemetry",
|
||||
"@material-ui/core",
|
||||
"@material-ui/icons",
|
||||
"@tabler/icons-react",
|
||||
"mui-core",
|
||||
"react-icons/ai",
|
||||
"react-icons/bi",
|
||||
"react-icons/bs",
|
||||
"react-icons/cg",
|
||||
"react-icons/ci",
|
||||
"react-icons/di",
|
||||
"react-icons/fa",
|
||||
"react-icons/fa6",
|
||||
"react-icons/fc",
|
||||
"react-icons/fi",
|
||||
"react-icons/gi",
|
||||
"react-icons/go",
|
||||
"react-icons/gr",
|
||||
"react-icons/hi",
|
||||
"react-icons/hi2",
|
||||
"react-icons/im",
|
||||
"react-icons/io",
|
||||
"react-icons/io5",
|
||||
"react-icons/lia",
|
||||
"react-icons/lib",
|
||||
"react-icons/lu",
|
||||
"react-icons/md",
|
||||
"react-icons/pi",
|
||||
"react-icons/ri",
|
||||
"react-icons/rx",
|
||||
"react-icons/si",
|
||||
"react-icons/sl",
|
||||
"react-icons/tb",
|
||||
"react-icons/tfi",
|
||||
"react-icons/ti",
|
||||
"react-icons/vsc",
|
||||
"react-icons/wi"
|
||||
],
|
||||
"trustHostHeader": false,
|
||||
"isExperimentalCompile": false
|
||||
},
|
||||
"htmlLimitedBots": "[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight",
|
||||
"bundlePagesRouterDependencies": false,
|
||||
"configFileName": "next.config.js",
|
||||
"transpilePackages": [
|
||||
"@rentaldrivego/types"
|
||||
],
|
||||
"turbopack": {
|
||||
"root": "/Volumes/ExternalApps/Documents/alrahma_sunday_school_api"
|
||||
},
|
||||
"distDirRoot": ".next",
|
||||
"_originalRewrites": {
|
||||
"beforeFiles": [],
|
||||
"afterFiles": [
|
||||
{
|
||||
"source": "/api/:path*",
|
||||
"destination": "http://localhost:4000/api/:path*"
|
||||
}
|
||||
],
|
||||
"fallback": []
|
||||
}
|
||||
},
|
||||
"appDir": "/Volumes/ExternalApps/Documents/alrahma_sunday_school_api/apps/admin",
|
||||
"relativeAppDir": "apps/admin",
|
||||
"files": [
|
||||
".next/package.json",
|
||||
".next/routes-manifest.json",
|
||||
".next/server/pages-manifest.json",
|
||||
".next/build-manifest.json",
|
||||
".next/prerender-manifest.json",
|
||||
".next/server/functions-config-manifest.json",
|
||||
".next/server/middleware-manifest.json",
|
||||
".next/server/middleware-build-manifest.js",
|
||||
".next/server/app-paths-manifest.json",
|
||||
".next/app-path-routes-manifest.json",
|
||||
".next/server/server-reference-manifest.js",
|
||||
".next/server/server-reference-manifest.json",
|
||||
".next/server/prefetch-hints.json",
|
||||
".next/BUILD_ID",
|
||||
".next/server/next-font-manifest.js",
|
||||
".next/server/next-font-manifest.json",
|
||||
".next/required-server-files.json"
|
||||
],
|
||||
"ignore": []
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
{
|
||||
"version": 3,
|
||||
"pages404": true,
|
||||
"appType": "app",
|
||||
"caseSensitive": false,
|
||||
"basePath": "/admin",
|
||||
"redirects": [
|
||||
{
|
||||
"source": "/admin/",
|
||||
"destination": "/admin",
|
||||
"basePath": false,
|
||||
"internal": true,
|
||||
"priority": true,
|
||||
"statusCode": 308,
|
||||
"regex": "^/admin/$"
|
||||
},
|
||||
{
|
||||
"source": "/:path+/",
|
||||
"destination": "/:path+",
|
||||
"internal": true,
|
||||
"priority": true,
|
||||
"statusCode": 308,
|
||||
"regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$"
|
||||
}
|
||||
],
|
||||
"headers": [
|
||||
{
|
||||
"source": "/admin/:path*",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Strict-Transport-Security",
|
||||
"value": "max-age=31536000; includeSubDomains"
|
||||
},
|
||||
{
|
||||
"key": "X-Content-Type-Options",
|
||||
"value": "nosniff"
|
||||
},
|
||||
{
|
||||
"key": "X-Frame-Options",
|
||||
"value": "DENY"
|
||||
},
|
||||
{
|
||||
"key": "Referrer-Policy",
|
||||
"value": "strict-origin-when-cross-origin"
|
||||
},
|
||||
{
|
||||
"key": "Permissions-Policy",
|
||||
"value": "camera=(), microphone=(), geolocation=()"
|
||||
},
|
||||
{
|
||||
"key": "Content-Security-Policy",
|
||||
"value": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self' https: wss:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'"
|
||||
}
|
||||
],
|
||||
"regex": "^/admin(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))?(?:/)?$"
|
||||
}
|
||||
],
|
||||
"onMatchHeaders": [],
|
||||
"rewrites": {
|
||||
"beforeFiles": [],
|
||||
"afterFiles": [
|
||||
{
|
||||
"source": "/admin/api/:path*",
|
||||
"destination": "http://localhost:4000/api/:path*",
|
||||
"regex": "^/admin/api(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))?(?:/)?$"
|
||||
}
|
||||
],
|
||||
"fallback": []
|
||||
},
|
||||
"dynamicRoutes": [
|
||||
{
|
||||
"page": "/dashboard/companies/[id]",
|
||||
"regex": "^/dashboard/companies/([^/]+?)(?:/)?$",
|
||||
"routeKeys": {
|
||||
"nxtPid": "nxtPid"
|
||||
},
|
||||
"namedRegex": "^/dashboard/companies/(?<nxtPid>[^/]+?)(?:/)?$"
|
||||
}
|
||||
],
|
||||
"staticRoutes": [
|
||||
{
|
||||
"page": "/",
|
||||
"regex": "^/(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/_global-error",
|
||||
"regex": "^/_global\\-error(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/_global\\-error(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/_not-found",
|
||||
"regex": "^/_not\\-found(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/_not\\-found(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/auth-redirect",
|
||||
"regex": "^/auth\\-redirect(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/auth\\-redirect(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard",
|
||||
"regex": "^/dashboard(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/admin-users",
|
||||
"regex": "^/dashboard/admin\\-users(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/admin\\-users(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/audit-logs",
|
||||
"regex": "^/dashboard/audit\\-logs(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/audit\\-logs(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/billing",
|
||||
"regex": "^/dashboard/billing(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/billing(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/companies",
|
||||
"regex": "^/dashboard/companies(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/companies(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/containers",
|
||||
"regex": "^/dashboard/containers(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/containers(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/menu-management",
|
||||
"regex": "^/dashboard/menu\\-management(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/menu\\-management(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/notifications",
|
||||
"regex": "^/dashboard/notifications(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/notifications(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/pricing",
|
||||
"regex": "^/dashboard/pricing(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/pricing(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/renters",
|
||||
"regex": "^/dashboard/renters(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/renters(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/dashboard/site-config",
|
||||
"regex": "^/dashboard/site\\-config(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/dashboard/site\\-config(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/favicon.ico",
|
||||
"regex": "^/favicon\\.ico(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/favicon\\.ico(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/forgot-password",
|
||||
"regex": "^/forgot\\-password(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/forgot\\-password(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/icon",
|
||||
"regex": "^/icon(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/icon(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/login",
|
||||
"regex": "^/login(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/login(?:/)?$"
|
||||
},
|
||||
{
|
||||
"page": "/reset-password",
|
||||
"regex": "^/reset\\-password(?:/)?$",
|
||||
"routeKeys": {},
|
||||
"namedRegex": "^/reset\\-password(?:/)?$"
|
||||
}
|
||||
],
|
||||
"dataRoutes": [],
|
||||
"rsc": {
|
||||
"header": "rsc",
|
||||
"varyHeader": "rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch",
|
||||
"prefetchHeader": "next-router-prefetch",
|
||||
"didPostponeHeader": "x-nextjs-postponed",
|
||||
"contentTypeHeader": "text/x-component",
|
||||
"suffix": ".rsc",
|
||||
"prefetchSegmentHeader": "next-router-segment-prefetch",
|
||||
"prefetchSegmentSuffix": ".segment.rsc",
|
||||
"prefetchSegmentDirSuffix": ".segments",
|
||||
"clientParamParsing": false,
|
||||
"dynamicRSCPrerender": false
|
||||
},
|
||||
"rewriteHeaders": {
|
||||
"pathHeader": "x-nextjs-rewritten-path",
|
||||
"queryHeader": "x-nextjs-rewritten-query"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"/_global-error/page": "app/_global-error/page.js",
|
||||
"/_not-found/page": "app/_not-found/page.js",
|
||||
"/auth-redirect/page": "app/auth-redirect/page.js",
|
||||
"/dashboard/admin-users/page": "app/dashboard/admin-users/page.js",
|
||||
"/dashboard/audit-logs/page": "app/dashboard/audit-logs/page.js",
|
||||
"/dashboard/billing/page": "app/dashboard/billing/page.js",
|
||||
"/dashboard/companies/[id]/page": "app/dashboard/companies/[id]/page.js",
|
||||
"/dashboard/companies/page": "app/dashboard/companies/page.js",
|
||||
"/dashboard/containers/page": "app/dashboard/containers/page.js",
|
||||
"/dashboard/menu-management/page": "app/dashboard/menu-management/page.js",
|
||||
"/dashboard/notifications/page": "app/dashboard/notifications/page.js",
|
||||
"/dashboard/page": "app/dashboard/page.js",
|
||||
"/dashboard/pricing/page": "app/dashboard/pricing/page.js",
|
||||
"/dashboard/renters/page": "app/dashboard/renters/page.js",
|
||||
"/dashboard/site-config/page": "app/dashboard/site-config/page.js",
|
||||
"/favicon.ico/route": "app/favicon.ico/route.js",
|
||||
"/forgot-password/page": "app/forgot-password/page.js",
|
||||
"/icon/route": "app/icon/route.js",
|
||||
"/login/page": "app/login/page.js",
|
||||
"/page": "app/page.js",
|
||||
"/reset-password/page": "app/reset-password/page.js"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"status": 500,
|
||||
"headers": {
|
||||
"x-nextjs-stale-time": "300",
|
||||
"x-nextjs-prerender": "1",
|
||||
"x-next-cache-tags": "_N_T_/layout,_N_T_/_global-error/layout,_N_T_/_global-error/page,_N_T_/_global-error"
|
||||
},
|
||||
"segmentPaths": [
|
||||
"/_tree",
|
||||
"/_full",
|
||||
"/__PAGE__",
|
||||
"/_index",
|
||||
"/_head"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
3:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"OutletBoundary"]
|
||||
5:"$Sreact.suspense"
|
||||
8:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"ViewportBoundary"]
|
||||
a:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"MetadataBoundary"]
|
||||
c:I[68027,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default",1]
|
||||
0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
d:[]
|
||||
7:"$Wd"
|
||||
9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
||||
6:null
|
||||
b:[]
|
||||
@@ -0,0 +1,5 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"OutletBoundary"]
|
||||
3:"$Sreact.suspense"
|
||||
0:{"rsc":["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
4:null
|
||||
@@ -0,0 +1,14 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
3:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"OutletBoundary"]
|
||||
5:"$Sreact.suspense"
|
||||
8:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"ViewportBoundary"]
|
||||
a:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"MetadataBoundary"]
|
||||
c:I[68027,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default",1]
|
||||
0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
d:[]
|
||||
7:"$Wd"
|
||||
9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
||||
6:null
|
||||
b:[]
|
||||
@@ -0,0 +1,5 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"ViewportBoundary"]
|
||||
3:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"MetadataBoundary"]
|
||||
4:"$Sreact.suspense"
|
||||
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],null]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1,5 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
3:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:[]
|
||||
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1 @@
|
||||
0:{"tree":{"name":"","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1,9 @@
|
||||
var R=require("../../chunks/ssr/[turbopack]_runtime.js")("server/app/_global-error/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__06ss4iy._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_19--w_z.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1k-d3jf._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__0nu24gp._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
|
||||
R.c("server/chunks/ssr/apps_admin__next-internal_server_app__global-error_page_actions_1gzhnz9.js")
|
||||
R.m(42378)
|
||||
module.exports=R.m(42378).exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/_global-error/page": "app/_global-error/page.js"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"polyfillFiles": [
|
||||
"static/chunks/0cz1d0mv5g_q7.js"
|
||||
],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/3fi7ta8l6_q46.js",
|
||||
"static/chunks/2de_cmw_l_puw.js",
|
||||
"static/chunks/3svce10uq2e6q.js",
|
||||
"static/chunks/40z7xw1jd_fv0.js",
|
||||
"static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
],
|
||||
"pages": {},
|
||||
"ampFirstPages": []
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"pages": {},
|
||||
"app": {},
|
||||
"appUsingSizeAdjust": false,
|
||||
"pagesUsingSizeAdjust": false
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"status": 404,
|
||||
"headers": {
|
||||
"x-nextjs-stale-time": "300",
|
||||
"x-nextjs-prerender": "1",
|
||||
"x-next-cache-tags": "_N_T_/layout,_N_T_/_not-found/layout,_N_T_/_not-found/page,_N_T_/_not-found"
|
||||
},
|
||||
"segmentPaths": [
|
||||
"/_tree",
|
||||
"/_full",
|
||||
"/_not-found/__PAGE__",
|
||||
"/_not-found",
|
||||
"/_index",
|
||||
"/_head"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[51224,["/admin/_next/static/chunks/10txdscg_s8qk.js"],"AdminI18nProvider"]
|
||||
3:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
5:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"OutletBoundary"]
|
||||
6:"$Sreact.suspense"
|
||||
9:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"ViewportBoundary"]
|
||||
b:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"MetadataBoundary"]
|
||||
d:I[68027,["/admin/_next/static/chunks/10txdscg_s8qk.js"],"default",1]
|
||||
:HL["/admin/_next/static/chunks/0_wwjs24psu3a.css","style"]
|
||||
0:{"P":null,"c":["","_not-found"],"q":"","i":false,"f":[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/admin/_next/static/chunks/0_wwjs24psu3a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/admin/_next/static/chunks/10txdscg_s8qk.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"light","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var m=document.cookie.match(/(?:^|; )rentaldrivego-theme=([^;]+)/);var theme=m?decodeURIComponent(m[1]):(localStorage.getItem('rentaldrivego-theme')||localStorage.getItem('admin-theme'));if(theme!=='light'&&theme!=='dark'){theme=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'}document.documentElement.classList.remove('light','dark');document.documentElement.classList.add(theme);document.documentElement.style.colorScheme=theme;document.body&&document.body.setAttribute('data-theme',theme)}catch(e){}})();"}}]}],["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],null,["$","$L5",null,{"children":["$","$6",null,{"name":"Next.MetadataOutlet","children":"$@7"}]}]]}],{},null,false,null]},null,false,"$@8"]},null,false,null],["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L9",null,{"children":"$La"}],["$","div",null,{"hidden":true,"children":["$","$Lb",null,{"children":["$","$6",null,{"name":"Next.Metadata","children":"$Lc"}]}]}],null]}],false]],"m":"$undefined","G":["$d",[["$","link","0",{"rel":"stylesheet","href":"/admin/_next/static/chunks/0_wwjs24psu3a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
e:[]
|
||||
8:"$We"
|
||||
a:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
||||
f:I[27201,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"IconMark"]
|
||||
7:null
|
||||
c:[["$","title","0",{"children":"RentalDriveGo Admin"}],["$","meta","1",{"name":"description","content":"Platform administration for RentalDriveGo."}],["$","link","2",{"rel":"icon","href":"/icon?26e1a3c73d0a3e8c","alt":"$undefined","type":"image/png","sizes":"32x32"}],["$","$Lf","3",{}]]
|
||||
@@ -0,0 +1,17 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[51224,["/admin/_next/static/chunks/10txdscg_s8qk.js"],"AdminI18nProvider"]
|
||||
3:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
5:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"OutletBoundary"]
|
||||
6:"$Sreact.suspense"
|
||||
9:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"ViewportBoundary"]
|
||||
b:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"MetadataBoundary"]
|
||||
d:I[68027,["/admin/_next/static/chunks/10txdscg_s8qk.js"],"default",1]
|
||||
:HL["/admin/_next/static/chunks/0_wwjs24psu3a.css","style"]
|
||||
0:{"P":null,"c":["","_not-found"],"q":"","i":false,"f":[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/admin/_next/static/chunks/0_wwjs24psu3a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/admin/_next/static/chunks/10txdscg_s8qk.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"light","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var m=document.cookie.match(/(?:^|; )rentaldrivego-theme=([^;]+)/);var theme=m?decodeURIComponent(m[1]):(localStorage.getItem('rentaldrivego-theme')||localStorage.getItem('admin-theme'));if(theme!=='light'&&theme!=='dark'){theme=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'}document.documentElement.classList.remove('light','dark');document.documentElement.classList.add(theme);document.documentElement.style.colorScheme=theme;document.body&&document.body.setAttribute('data-theme',theme)}catch(e){}})();"}}]}],["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],null,["$","$L5",null,{"children":["$","$6",null,{"name":"Next.MetadataOutlet","children":"$@7"}]}]]}],{},null,false,null]},null,false,"$@8"]},null,false,null],["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L9",null,{"children":"$La"}],["$","div",null,{"hidden":true,"children":["$","$Lb",null,{"children":["$","$6",null,{"name":"Next.Metadata","children":"$Lc"}]}]}],null]}],false]],"m":"$undefined","G":["$d",[["$","link","0",{"rel":"stylesheet","href":"/admin/_next/static/chunks/0_wwjs24psu3a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
e:[]
|
||||
8:"$We"
|
||||
a:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
||||
f:I[27201,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"IconMark"]
|
||||
7:null
|
||||
c:[["$","title","0",{"children":"RentalDriveGo Admin"}],["$","meta","1",{"name":"description","content":"Platform administration for RentalDriveGo."}],["$","link","2",{"rel":"icon","href":"/icon?26e1a3c73d0a3e8c","alt":"$undefined","type":"image/png","sizes":"32x32"}],["$","$Lf","3",{}]]
|
||||
@@ -0,0 +1,6 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"ViewportBoundary"]
|
||||
3:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"MetadataBoundary"]
|
||||
4:"$Sreact.suspense"
|
||||
5:I[27201,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"IconMark"]
|
||||
0:{"rsc":["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"RentalDriveGo Admin"}],["$","meta","1",{"name":"description","content":"Platform administration for RentalDriveGo."}],["$","link","2",{"rel":"icon","href":"/icon?26e1a3c73d0a3e8c","type":"image/png","sizes":"32x32"}],["$","$L5","3",{}]]}]}]}],null]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1,6 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[51224,["/admin/_next/static/chunks/10txdscg_s8qk.js"],"AdminI18nProvider"]
|
||||
3:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
:HL["/admin/_next/static/chunks/0_wwjs24psu3a.css","style"]
|
||||
0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/admin/_next/static/chunks/0_wwjs24psu3a.css","precedence":"next"}],["$","script","script-0",{"src":"/admin/_next/static/chunks/10txdscg_s8qk.js","async":true}]],["$","html",null,{"lang":"en","className":"light","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var m=document.cookie.match(/(?:^|; )rentaldrivego-theme=([^;]+)/);var theme=m?decodeURIComponent(m[1]):(localStorage.getItem('rentaldrivego-theme')||localStorage.getItem('admin-theme'));if(theme!=='light'&&theme!=='dark'){theme=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'}document.documentElement.classList.remove('light','dark');document.documentElement.classList.add(theme);document.documentElement.style.colorScheme=theme;document.body&&document.body.setAttribute('data-theme',theme)}catch(e){}})();"}}]}],["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1,5 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[39756,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
3:I[37457,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"default"]
|
||||
4:[]
|
||||
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1,5 @@
|
||||
1:"$Sreact.fragment"
|
||||
2:I[97367,["/admin/_next/static/chunks/05-c3ty_6dwfk.js","/admin/_next/static/chunks/18sotvvmcs59d.js"],"OutletBoundary"]
|
||||
3:"$Sreact.suspense"
|
||||
0:{"rsc":["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
4:null
|
||||
@@ -0,0 +1,2 @@
|
||||
:HL["/admin/_next/static/chunks/0_wwjs24psu3a.css","style"]
|
||||
0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"/_not-found","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}},"staleTime":300,"buildId":"jRlQg50qYlv2hlr5AFzlp"}
|
||||
@@ -0,0 +1,14 @@
|
||||
var R=require("../../chunks/ssr/[turbopack]_runtime.js")("server/app/_not-found/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__0ln09ua._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_16dhe4b.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1k-d3jf._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__0nu24gp._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1rskd5f._.js")
|
||||
R.c("server/chunks/ssr/_1cx6y-a._.js")
|
||||
R.c("server/chunks/ssr/apps_admin_src_0ykjik2._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0wpq8j3._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
|
||||
R.c("server/chunks/ssr/apps_admin__next-internal_server_app__not-found_page_actions_158ip1x.js")
|
||||
R.m(313)
|
||||
module.exports=R.m(313).exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/_not-found/page": "app/_not-found/page.js"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"polyfillFiles": [
|
||||
"static/chunks/0cz1d0mv5g_q7.js"
|
||||
],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [
|
||||
"static/chunks/3fi7ta8l6_q46.js",
|
||||
"static/chunks/2de_cmw_l_puw.js",
|
||||
"static/chunks/3svce10uq2e6q.js",
|
||||
"static/chunks/40z7xw1jd_fv0.js",
|
||||
"static/chunks/turbopack-1kvzti-0-yxfi.js"
|
||||
],
|
||||
"pages": {},
|
||||
"ampFirstPages": []
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"pages": {},
|
||||
"app": {},
|
||||
"appUsingSizeAdjust": false,
|
||||
"pagesUsingSizeAdjust": false
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user