@striae-org/striae 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +100 -0
- package/LICENSE +190 -0
- package/NOTICE +18 -0
- package/README.md +133 -0
- package/app/components/actions/case-export/core-export.ts +328 -0
- package/app/components/actions/case-export/data-processing.ts +167 -0
- package/app/components/actions/case-export/download-handlers.ts +900 -0
- package/app/components/actions/case-export/index.ts +41 -0
- package/app/components/actions/case-export/metadata-helpers.ts +107 -0
- package/app/components/actions/case-export/types-constants.ts +56 -0
- package/app/components/actions/case-export/validation-utils.ts +25 -0
- package/app/components/actions/case-export.ts +4 -0
- package/app/components/actions/case-import/annotation-import.ts +35 -0
- package/app/components/actions/case-import/confirmation-import.ts +363 -0
- package/app/components/actions/case-import/image-operations.ts +61 -0
- package/app/components/actions/case-import/index.ts +39 -0
- package/app/components/actions/case-import/orchestrator.ts +420 -0
- package/app/components/actions/case-import/storage-operations.ts +270 -0
- package/app/components/actions/case-import/validation.ts +189 -0
- package/app/components/actions/case-import/zip-processing.ts +413 -0
- package/app/components/actions/case-manage.ts +524 -0
- package/app/components/actions/case-review.ts +4 -0
- package/app/components/actions/confirm-export.ts +351 -0
- package/app/components/actions/generate-pdf.ts +210 -0
- package/app/components/actions/image-manage.ts +385 -0
- package/app/components/actions/notes-manage.ts +33 -0
- package/app/components/actions/signout.module.css +15 -0
- package/app/components/actions/signout.tsx +50 -0
- package/app/components/audit/user-audit-viewer.tsx +975 -0
- package/app/components/audit/user-audit.module.css +568 -0
- package/app/components/auth/auth-provider.tsx +78 -0
- package/app/components/auth/mfa-enrollment.module.css +268 -0
- package/app/components/auth/mfa-enrollment.tsx +398 -0
- package/app/components/auth/mfa-verification.module.css +251 -0
- package/app/components/auth/mfa-verification.tsx +295 -0
- package/app/components/button/button.module.css +63 -0
- package/app/components/button/button.tsx +46 -0
- package/app/components/canvas/box-annotations/box-annotations.module.css +170 -0
- package/app/components/canvas/box-annotations/box-annotations.tsx +634 -0
- package/app/components/canvas/canvas.module.css +314 -0
- package/app/components/canvas/canvas.tsx +449 -0
- package/app/components/canvas/confirmation/confirmation.module.css +187 -0
- package/app/components/canvas/confirmation/confirmation.tsx +214 -0
- package/app/components/colors/colors.module.css +59 -0
- package/app/components/colors/colors.tsx +68 -0
- package/app/components/form/base-form.tsx +21 -0
- package/app/components/form/form-button.tsx +28 -0
- package/app/components/form/form-field.tsx +53 -0
- package/app/components/form/form-message.tsx +17 -0
- package/app/components/form/form-toggle.tsx +23 -0
- package/app/components/form/form.module.css +427 -0
- package/app/components/form/index.ts +6 -0
- package/app/components/icon/icon.module.css +3 -0
- package/app/components/icon/icon.tsx +27 -0
- package/app/components/icon/icons.svg +102 -0
- package/app/components/icon/manifest.json +110 -0
- package/app/components/sidebar/case-export/case-export.module.css +386 -0
- package/app/components/sidebar/case-export/case-export.tsx +317 -0
- package/app/components/sidebar/case-import/case-import.module.css +626 -0
- package/app/components/sidebar/case-import/case-import.tsx +404 -0
- package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +72 -0
- package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +72 -0
- package/app/components/sidebar/case-import/components/ConfirmationPreviewSection.tsx +71 -0
- package/app/components/sidebar/case-import/components/ExistingCaseSection.tsx +40 -0
- package/app/components/sidebar/case-import/components/FileSelector.tsx +161 -0
- package/app/components/sidebar/case-import/components/ProgressSection.tsx +46 -0
- package/app/components/sidebar/case-import/hooks/useFilePreview.ts +101 -0
- package/app/components/sidebar/case-import/hooks/useImportExecution.ts +152 -0
- package/app/components/sidebar/case-import/hooks/useImportState.ts +88 -0
- package/app/components/sidebar/case-import/index.ts +18 -0
- package/app/components/sidebar/case-import/utils/file-validation.ts +43 -0
- package/app/components/sidebar/cases/case-sidebar.tsx +827 -0
- package/app/components/sidebar/cases/cases-modal.module.css +166 -0
- package/app/components/sidebar/cases/cases-modal.tsx +201 -0
- package/app/components/sidebar/cases/cases.module.css +713 -0
- package/app/components/sidebar/files/files-modal.module.css +209 -0
- package/app/components/sidebar/files/files-modal.tsx +239 -0
- package/app/components/sidebar/hash/hash-utility.module.css +366 -0
- package/app/components/sidebar/hash/hash-utility.tsx +982 -0
- package/app/components/sidebar/notes/notes-modal.tsx +51 -0
- package/app/components/sidebar/notes/notes-sidebar.tsx +491 -0
- package/app/components/sidebar/notes/notes.module.css +360 -0
- package/app/components/sidebar/sidebar-container.tsx +149 -0
- package/app/components/sidebar/sidebar.module.css +321 -0
- package/app/components/sidebar/sidebar.tsx +215 -0
- package/app/components/sidebar/upload/image-upload-zone.module.css +123 -0
- package/app/components/sidebar/upload/image-upload-zone.tsx +330 -0
- package/app/components/theme-provider/theme-provider.tsx +131 -0
- package/app/components/theme-provider/theme.ts +155 -0
- package/app/components/toast/toast.module.css +137 -0
- package/app/components/toast/toast.tsx +56 -0
- package/app/components/toolbar/toolbar-color-selector.module.css +171 -0
- package/app/components/toolbar/toolbar-color-selector.tsx +129 -0
- package/app/components/toolbar/toolbar.module.css +42 -0
- package/app/components/toolbar/toolbar.tsx +167 -0
- package/app/components/user/delete-account.module.css +274 -0
- package/app/components/user/delete-account.tsx +471 -0
- package/app/components/user/inactivity-warning.module.css +145 -0
- package/app/components/user/inactivity-warning.tsx +84 -0
- package/app/components/user/manage-profile.module.css +190 -0
- package/app/components/user/manage-profile.tsx +253 -0
- package/app/components/user/mfa-phone-update.tsx +739 -0
- package/app/config-example/admin-service.json +13 -0
- package/app/config-example/config.json +17 -0
- package/app/config-example/firebase.ts +21 -0
- package/app/config-example/inactivity.ts +13 -0
- package/app/config-example/meta-config.json +6 -0
- package/app/contexts/auth.context.ts +12 -0
- package/app/entry.client.tsx +12 -0
- package/app/entry.server.tsx +44 -0
- package/app/hooks/useInactivityTimeout.ts +110 -0
- package/app/root.tsx +170 -0
- package/app/routes/_index.tsx +16 -0
- package/app/routes/auth/emailActionHandler.module.css +232 -0
- package/app/routes/auth/emailActionHandler.tsx +405 -0
- package/app/routes/auth/emailVerification.tsx +120 -0
- package/app/routes/auth/login.module.css +523 -0
- package/app/routes/auth/login.tsx +654 -0
- package/app/routes/auth/passwordReset.module.css +274 -0
- package/app/routes/auth/passwordReset.tsx +154 -0
- package/app/routes/auth/route.ts +16 -0
- package/app/routes/mobile-prevented/mobilePrevented.module.css +47 -0
- package/app/routes/mobile-prevented/mobilePrevented.tsx +26 -0
- package/app/routes/mobile-prevented/route.ts +14 -0
- package/app/routes/striae/striae.module.css +30 -0
- package/app/routes/striae/striae.tsx +417 -0
- package/app/services/audit-export.service.ts +755 -0
- package/app/services/audit.service.ts +1454 -0
- package/app/services/firebase-errors.ts +106 -0
- package/app/services/firebase.ts +15 -0
- package/app/styles/legal-pages.module.css +113 -0
- package/app/styles/root.module.css +146 -0
- package/app/tailwind.css +225 -0
- package/app/types/annotations.ts +45 -0
- package/app/types/audit.ts +301 -0
- package/app/types/case.ts +90 -0
- package/app/types/export.ts +8 -0
- package/app/types/file.ts +30 -0
- package/app/types/import.ts +107 -0
- package/app/types/index.ts +24 -0
- package/app/types/user.ts +38 -0
- package/app/utils/SHA256.ts +461 -0
- package/app/utils/annotation-timestamp.ts +25 -0
- package/app/utils/audit-export-signature.ts +117 -0
- package/app/utils/auth-action-settings.ts +48 -0
- package/app/utils/auth.ts +34 -0
- package/app/utils/batch-operations.ts +135 -0
- package/app/utils/confirmation-signature.ts +193 -0
- package/app/utils/data-operations.ts +871 -0
- package/app/utils/device-detection.ts +5 -0
- package/app/utils/html-sanitizer.ts +80 -0
- package/app/utils/id-generator.ts +36 -0
- package/app/utils/meta.ts +48 -0
- package/app/utils/mfa-phone.ts +97 -0
- package/app/utils/mfa.ts +79 -0
- package/app/utils/password-policy.ts +28 -0
- package/app/utils/permissions.ts +562 -0
- package/app/utils/signature-utils.ts +160 -0
- package/app/utils/style.ts +83 -0
- package/app/utils/version.ts +5 -0
- package/firebase.json +11 -0
- package/functions/[[path]].ts +10 -0
- package/package.json +138 -0
- package/postcss.config.js +6 -0
- package/public/.well-known/publickey.info@striae.org.asc +17 -0
- package/public/.well-known/security.txt +7 -0
- package/public/_headers +28 -0
- package/public/_routes.json +13 -0
- package/public/assets/striae.jpg +0 -0
- package/public/clear.jpg +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +9 -0
- package/public/icon-256.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/logo-dark.png +0 -0
- package/public/manifest.json +25 -0
- package/public/oin-badge.png +0 -0
- package/public/shortcut.png +0 -0
- package/public/social-image.png +0 -0
- package/public/striae-ascii.txt +10 -0
- package/scripts/deploy-all.sh +100 -0
- package/scripts/deploy-config.sh +940 -0
- package/scripts/deploy-pages.sh +34 -0
- package/scripts/deploy-worker-secrets.sh +215 -0
- package/scripts/dev.cjs +23 -0
- package/scripts/install-workers.sh +88 -0
- package/scripts/run-eslint.cjs +35 -0
- package/scripts/update-compatibility-dates.cjs +124 -0
- package/scripts/update-markdown-versions.cjs +43 -0
- package/tailwind.config.ts +22 -0
- package/tsconfig.json +33 -0
- package/vite.config.ts +35 -0
- package/worker-configuration.d.ts +7490 -0
- package/workers/audit-worker/package.json +17 -0
- package/workers/audit-worker/src/audit-worker.example.ts +195 -0
- package/workers/audit-worker/worker-configuration.d.ts +7448 -0
- package/workers/audit-worker/wrangler.jsonc.example +29 -0
- package/workers/data-worker/package.json +17 -0
- package/workers/data-worker/src/data-worker.example.ts +267 -0
- package/workers/data-worker/src/signature-utils.ts +79 -0
- package/workers/data-worker/src/signing-payload-utils.ts +290 -0
- package/workers/data-worker/worker-configuration.d.ts +7448 -0
- package/workers/data-worker/wrangler.jsonc.example +30 -0
- package/workers/image-worker/package.json +17 -0
- package/workers/image-worker/src/image-worker.example.ts +180 -0
- package/workers/image-worker/worker-configuration.d.ts +7447 -0
- package/workers/image-worker/wrangler.jsonc.example +22 -0
- package/workers/keys-worker/package.json +17 -0
- package/workers/keys-worker/src/keys.example.ts +66 -0
- package/workers/keys-worker/src/keys.ts +66 -0
- package/workers/keys-worker/worker-configuration.d.ts +7447 -0
- package/workers/keys-worker/wrangler.jsonc.example +22 -0
- package/workers/pdf-worker/package.json +17 -0
- package/workers/pdf-worker/src/format-striae.ts +534 -0
- package/workers/pdf-worker/src/pdf-worker.example.ts +119 -0
- package/workers/pdf-worker/src/report-types.ts +69 -0
- package/workers/pdf-worker/worker-configuration.d.ts +7448 -0
- package/workers/pdf-worker/wrangler.jsonc.example +26 -0
- package/workers/user-worker/package.json +17 -0
- package/workers/user-worker/src/user-worker.example.ts +636 -0
- package/workers/user-worker/worker-configuration.d.ts +7448 -0
- package/workers/user-worker/wrangler.jsonc.example +29 -0
- package/wrangler.toml.example +8 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# ======================================
|
|
4
|
+
# STRIAE PAGES DEPLOYMENT SCRIPT
|
|
5
|
+
# ======================================
|
|
6
|
+
# This script deploys the Striae frontend to Cloudflare Pages
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
# Colors for output
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
GREEN='\033[0;32m'
|
|
13
|
+
YELLOW='\033[1;33m'
|
|
14
|
+
BLUE='\033[0;34m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
echo -e "${BLUE}📄 Striae Pages Deployment Script${NC}"
|
|
18
|
+
echo "=================================="
|
|
19
|
+
|
|
20
|
+
# Deploy to Cloudflare Pages (includes build step)
|
|
21
|
+
echo -e "${YELLOW}🚀 Building and deploying to Cloudflare Pages...${NC}"
|
|
22
|
+
if ! npm run deploy; then
|
|
23
|
+
echo -e "${RED}❌ Deployment failed!${NC}"
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
echo -e "${GREEN}✅ Pages deployment completed successfully${NC}"
|
|
28
|
+
|
|
29
|
+
echo -e "\n${BLUE}💡 Next Steps:${NC}"
|
|
30
|
+
echo " 1. Deploy Pages secrets: npm run deploy-pages:secrets"
|
|
31
|
+
echo " 2. Configure custom domain (optional)"
|
|
32
|
+
echo " 3. Test your application"
|
|
33
|
+
|
|
34
|
+
echo -e "\n${GREEN}✨ Pages deployment complete!${NC}"
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# ======================================
|
|
4
|
+
# STRIAE WORKER SECRETS DEPLOYMENT SCRIPT
|
|
5
|
+
# ======================================
|
|
6
|
+
# This script deploys environment variables/secrets to Cloudflare Workers
|
|
7
|
+
# Run this AFTER workers are deployed to avoid deployment errors
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
# Colors for output
|
|
12
|
+
RED='\033[0;31m'
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
YELLOW='\033[1;33m'
|
|
15
|
+
BLUE='\033[0;34m'
|
|
16
|
+
NC='\033[0m' # No Color
|
|
17
|
+
|
|
18
|
+
echo -e "${BLUE}🔐 Striae Worker Secrets Deployment Script${NC}"
|
|
19
|
+
echo "=========================================="
|
|
20
|
+
|
|
21
|
+
# Check if .env file exists
|
|
22
|
+
if [ ! -f ".env" ]; then
|
|
23
|
+
echo -e "${RED}❌ Error: .env file not found!${NC}"
|
|
24
|
+
echo "Please copy .env.example to .env and fill in your values."
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Source the .env file
|
|
29
|
+
echo -e "${YELLOW}📖 Loading environment variables from .env...${NC}"
|
|
30
|
+
source .env
|
|
31
|
+
|
|
32
|
+
is_admin_service_placeholder() {
|
|
33
|
+
local value="$1"
|
|
34
|
+
local normalized=$(echo "$value" | tr '[:upper:]' '[:lower:]')
|
|
35
|
+
|
|
36
|
+
[[ -z "$normalized" || "$normalized" == your-* || "$normalized" == *"your_private_key"* ]]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
load_required_admin_service_credentials() {
|
|
40
|
+
local admin_service_path="app/config/admin-service.json"
|
|
41
|
+
|
|
42
|
+
if [ ! -f "$admin_service_path" ]; then
|
|
43
|
+
echo -e "${RED}❌ Error: Required Firebase admin service file not found: $admin_service_path${NC}"
|
|
44
|
+
echo -e "${YELLOW} Create app/config/admin-service.json before deploying worker secrets.${NC}"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
local service_project_id
|
|
49
|
+
local service_client_email
|
|
50
|
+
local service_private_key
|
|
51
|
+
|
|
52
|
+
if ! service_project_id=$(node -e "const fs=require('fs'); const data=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); process.stdout.write(data.project_id || '');" "$admin_service_path"); then
|
|
53
|
+
echo -e "${RED}❌ Error: Could not parse project_id from $admin_service_path${NC}"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if ! service_client_email=$(node -e "const fs=require('fs'); const data=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); process.stdout.write(data.client_email || '');" "$admin_service_path"); then
|
|
58
|
+
echo -e "${RED}❌ Error: Could not parse client_email from $admin_service_path${NC}"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
if ! service_private_key=$(node -e "const fs=require('fs'); const data=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); process.stdout.write(data.private_key || '');" "$admin_service_path"); then
|
|
63
|
+
echo -e "${RED}❌ Error: Could not parse private_key from $admin_service_path${NC}"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
local normalized_private_key="${service_private_key//$'\r'/}"
|
|
68
|
+
normalized_private_key="${normalized_private_key//$'\n'/\\n}"
|
|
69
|
+
|
|
70
|
+
if is_admin_service_placeholder "$service_project_id"; then
|
|
71
|
+
echo -e "${RED}❌ Error: project_id in $admin_service_path is missing or placeholder${NC}"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
if is_admin_service_placeholder "$service_client_email" || [[ "$service_client_email" != *".gserviceaccount.com"* ]]; then
|
|
76
|
+
echo -e "${RED}❌ Error: client_email in $admin_service_path is invalid${NC}"
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if is_admin_service_placeholder "$normalized_private_key" || [[ "$normalized_private_key" != *"-----BEGIN PRIVATE KEY-----"* ]] || [[ "$normalized_private_key" != *"-----END PRIVATE KEY-----"* ]]; then
|
|
81
|
+
echo -e "${RED}❌ Error: private_key in $admin_service_path is invalid${NC}"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
PROJECT_ID="$service_project_id"
|
|
86
|
+
FIREBASE_SERVICE_ACCOUNT_EMAIL="$service_client_email"
|
|
87
|
+
FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY="$normalized_private_key"
|
|
88
|
+
|
|
89
|
+
export PROJECT_ID
|
|
90
|
+
export FIREBASE_SERVICE_ACCOUNT_EMAIL
|
|
91
|
+
export FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY
|
|
92
|
+
|
|
93
|
+
echo -e "${GREEN}✅ Loaded Firebase service account credentials from $admin_service_path${NC}"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
load_required_admin_service_credentials
|
|
97
|
+
|
|
98
|
+
# Function to set worker secrets
|
|
99
|
+
set_worker_secrets() {
|
|
100
|
+
local worker_name=$1
|
|
101
|
+
local worker_path=$2
|
|
102
|
+
shift 2
|
|
103
|
+
local secrets=("$@")
|
|
104
|
+
|
|
105
|
+
echo -e "\n${BLUE}🔧 Setting secrets for $worker_name...${NC}"
|
|
106
|
+
|
|
107
|
+
# Check if worker has a wrangler configuration file
|
|
108
|
+
if [ ! -f "$worker_path/wrangler.jsonc" ] && [ ! -f "$worker_path/wrangler.toml" ]; then
|
|
109
|
+
echo -e "${RED}❌ Error: No wrangler configuration found for $worker_name${NC}"
|
|
110
|
+
echo -e "${YELLOW} Please copy wrangler.jsonc.example to wrangler.jsonc and configure it first.${NC}"
|
|
111
|
+
return 1
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Change to worker directory
|
|
115
|
+
pushd "$worker_path" > /dev/null
|
|
116
|
+
|
|
117
|
+
# Get the worker name from the configuration file
|
|
118
|
+
local config_worker_name
|
|
119
|
+
if [ -f "wrangler.jsonc" ]; then
|
|
120
|
+
config_worker_name=$(grep -o '"name"[[:space:]]*:[[:space:]]*"[^"]*"' wrangler.jsonc | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
121
|
+
elif [ -f "wrangler.toml" ]; then
|
|
122
|
+
config_worker_name=$(grep '^name[[:space:]]*=' wrangler.toml | sed 's/.*=[[:space:]]*["\x27]\([^"\x27]*\)["\x27].*/\1/')
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
if [ -z "$config_worker_name" ]; then
|
|
126
|
+
echo -e "${RED}❌ Error: Could not determine worker name from configuration${NC}"
|
|
127
|
+
popd > /dev/null
|
|
128
|
+
return 1
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
echo -e "${YELLOW} Using worker name: $config_worker_name${NC}"
|
|
132
|
+
|
|
133
|
+
for secret in "${secrets[@]}"; do
|
|
134
|
+
echo -e "${YELLOW} Setting $secret...${NC}"
|
|
135
|
+
if ! echo "${!secret}" | wrangler secret put "$secret" --name "$config_worker_name"; then
|
|
136
|
+
echo -e "${RED}❌ Failed to set $secret for $worker_name${NC}"
|
|
137
|
+
popd > /dev/null
|
|
138
|
+
return 1
|
|
139
|
+
fi
|
|
140
|
+
done
|
|
141
|
+
|
|
142
|
+
echo -e "${GREEN}✅ $worker_name secrets configured${NC}"
|
|
143
|
+
popd > /dev/null
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# Deploy secrets to each worker
|
|
147
|
+
echo -e "\n${BLUE}🔐 Deploying secrets to workers...${NC}"
|
|
148
|
+
|
|
149
|
+
# Check if workers are configured
|
|
150
|
+
echo -e "${YELLOW}🔍 Checking worker configurations...${NC}"
|
|
151
|
+
workers_configured=0
|
|
152
|
+
total_workers=6
|
|
153
|
+
|
|
154
|
+
for worker_dir in workers/*/; do
|
|
155
|
+
if [ -f "$worker_dir/wrangler.jsonc" ] || [ -f "$worker_dir/wrangler.toml" ]; then
|
|
156
|
+
workers_configured=$((workers_configured + 1))
|
|
157
|
+
fi
|
|
158
|
+
done
|
|
159
|
+
|
|
160
|
+
if [ $workers_configured -eq 0 ]; then
|
|
161
|
+
echo -e "${RED}❌ No workers are configured!${NC}"
|
|
162
|
+
echo -e "${YELLOW} Please copy wrangler.jsonc.example to wrangler.jsonc in each worker directory and configure them.${NC}"
|
|
163
|
+
echo -e "${YELLOW} Then run this script again.${NC}"
|
|
164
|
+
exit 1
|
|
165
|
+
elif [ $workers_configured -lt $total_workers ]; then
|
|
166
|
+
echo -e "${YELLOW}⚠️ Warning: Only $workers_configured of $total_workers workers are configured.${NC}"
|
|
167
|
+
echo -e "${YELLOW} Some workers may not have their secrets deployed.${NC}"
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Audit Worker
|
|
171
|
+
if ! set_worker_secrets "Audit Worker" "workers/audit-worker" \
|
|
172
|
+
"R2_KEY_SECRET"; then
|
|
173
|
+
echo -e "${YELLOW}⚠️ Skipping Audit Worker (not configured)${NC}"
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
# Keys Worker
|
|
177
|
+
if ! set_worker_secrets "Keys Worker" "workers/keys-worker" \
|
|
178
|
+
"KEYS_AUTH" "USER_DB_AUTH" "R2_KEY_SECRET" "ACCOUNT_HASH" "IMAGES_API_TOKEN"; then
|
|
179
|
+
echo -e "${YELLOW}⚠️ Skipping Keys Worker (not configured)${NC}"
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# User Worker
|
|
183
|
+
if ! set_worker_secrets "User Worker" "workers/user-worker" \
|
|
184
|
+
"USER_DB_AUTH" "R2_KEY_SECRET" "IMAGES_API_TOKEN" "PROJECT_ID" "FIREBASE_SERVICE_ACCOUNT_EMAIL" "FIREBASE_SERVICE_ACCOUNT_PRIVATE_KEY"; then
|
|
185
|
+
echo -e "${YELLOW}⚠️ Skipping User Worker (not configured)${NC}"
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
# Data Worker
|
|
189
|
+
if ! set_worker_secrets "Data Worker" "workers/data-worker" \
|
|
190
|
+
"R2_KEY_SECRET" "MANIFEST_SIGNING_PRIVATE_KEY" "MANIFEST_SIGNING_KEY_ID"; then
|
|
191
|
+
echo -e "${YELLOW}⚠️ Skipping Data Worker (not configured)${NC}"
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
# Images Worker
|
|
195
|
+
if ! set_worker_secrets "Images Worker" "workers/image-worker" \
|
|
196
|
+
"ACCOUNT_ID" "API_TOKEN" "HMAC_KEY"; then
|
|
197
|
+
echo -e "${YELLOW}⚠️ Skipping Images Worker (not configured)${NC}"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# PDF Worker (no secrets needed)
|
|
201
|
+
echo -e "\n${BLUE}📄 PDF Worker: No environment variables needed${NC}"
|
|
202
|
+
|
|
203
|
+
echo -e "\n${GREEN}🎉 Worker secrets deployment completed!${NC}"
|
|
204
|
+
|
|
205
|
+
echo -e "\n${YELLOW}⚠️ WORKER CONFIGURATION REMINDERS:${NC}"
|
|
206
|
+
echo " - Copy wrangler.jsonc.example to wrangler.jsonc in each worker directory"
|
|
207
|
+
echo " - Configure KV namespace ID in workers/user-worker/wrangler.jsonc"
|
|
208
|
+
echo " - Configure R2 bucket name in workers/data-worker/wrangler.jsonc"
|
|
209
|
+
echo " - Configure R2 bucket name in workers/audit-worker/wrangler.jsonc"
|
|
210
|
+
echo " - Update ACCOUNT_ID and custom domains in all worker configurations"
|
|
211
|
+
|
|
212
|
+
echo -e "\n${BLUE}📝 For manual deployment, use these commands:${NC}"
|
|
213
|
+
echo " cd workers/[worker-name]"
|
|
214
|
+
echo " wrangler secret put VARIABLE_NAME --name [worker-name]"
|
|
215
|
+
echo -e "\n${GREEN}✨ Worker secrets deployment complete!${NC}"
|
package/scripts/dev.cjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { updateMarkdownVersions } = require('./update-markdown-versions.cjs');
|
|
4
|
+
const { updateCompatibilityDates } = require('./update-compatibility-dates.cjs');
|
|
5
|
+
|
|
6
|
+
// Read the ASCII art file from the filesystem
|
|
7
|
+
const asciiArtPath = path.join(__dirname, '..', 'public', 'striae-ascii.txt');
|
|
8
|
+
let asciiArt;
|
|
9
|
+
try {
|
|
10
|
+
asciiArt = fs.readFileSync(asciiArtPath, 'utf8');
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.warn(`Warning: Unable to read ASCII art file at ${asciiArtPath}.\n${err.message}`);
|
|
13
|
+
asciiArt = "(ASCII art unavailable)\n";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Pop a lil' logo in the terminal
|
|
17
|
+
console.info(asciiArt);
|
|
18
|
+
|
|
19
|
+
// Update markdown files with current version
|
|
20
|
+
updateMarkdownVersions();
|
|
21
|
+
|
|
22
|
+
// Update compatibility dates to current date
|
|
23
|
+
updateCompatibilityDates();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# ======================================
|
|
4
|
+
# STRIAE WORKERS NPM INSTALL SCRIPT
|
|
5
|
+
# ======================================
|
|
6
|
+
# This script installs npm dependencies for all Striae workers:
|
|
7
|
+
# 1. audit-worker
|
|
8
|
+
# 2. data-worker
|
|
9
|
+
# 3. image-worker
|
|
10
|
+
# 4. keys-worker
|
|
11
|
+
# 5. pdf-worker
|
|
12
|
+
# 6. user-worker
|
|
13
|
+
|
|
14
|
+
# Colors for output
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
BLUE='\033[0;34m'
|
|
19
|
+
PURPLE='\033[0;35m'
|
|
20
|
+
NC='\033[0m' # No Color
|
|
21
|
+
|
|
22
|
+
echo -e "${BLUE}📦 Striae Workers NPM Install Script${NC}"
|
|
23
|
+
echo "========================================"
|
|
24
|
+
echo ""
|
|
25
|
+
|
|
26
|
+
# Get the script directory and project root
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
29
|
+
WORKERS_DIR="$PROJECT_ROOT/workers"
|
|
30
|
+
|
|
31
|
+
# Check if workers directory exists
|
|
32
|
+
if [ ! -d "$WORKERS_DIR" ]; then
|
|
33
|
+
echo -e "${RED}❌ Error: Workers directory not found at $WORKERS_DIR${NC}"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# List of workers
|
|
38
|
+
WORKERS=("audit-worker" "data-worker" "image-worker" "keys-worker" "pdf-worker" "user-worker")
|
|
39
|
+
|
|
40
|
+
echo -e "${PURPLE}Installing npm dependencies for all workers...${NC}"
|
|
41
|
+
echo ""
|
|
42
|
+
|
|
43
|
+
# Counter for progress
|
|
44
|
+
total=${#WORKERS[@]}
|
|
45
|
+
current=0
|
|
46
|
+
|
|
47
|
+
# Install dependencies for each worker
|
|
48
|
+
for worker in "${WORKERS[@]}"; do
|
|
49
|
+
current=$((current + 1))
|
|
50
|
+
worker_path="$WORKERS_DIR/$worker"
|
|
51
|
+
|
|
52
|
+
echo -e "${YELLOW}[$current/$total] Installing dependencies for $worker...${NC}"
|
|
53
|
+
|
|
54
|
+
# Check if worker directory exists
|
|
55
|
+
if [ ! -d "$worker_path" ]; then
|
|
56
|
+
echo -e "${RED}❌ Warning: Worker directory not found: $worker_path${NC}"
|
|
57
|
+
continue
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Check if package.json exists
|
|
61
|
+
if [ ! -f "$worker_path/package.json" ]; then
|
|
62
|
+
echo -e "${RED}❌ Warning: package.json not found in $worker_path${NC}"
|
|
63
|
+
continue
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Change to worker directory and install dependencies
|
|
67
|
+
cd "$worker_path"
|
|
68
|
+
|
|
69
|
+
echo " Running npm install in $worker_path..."
|
|
70
|
+
if npm install; then
|
|
71
|
+
echo -e "${GREEN}✅ Successfully installed dependencies for $worker${NC}"
|
|
72
|
+
else
|
|
73
|
+
echo -e "${RED}❌ Failed to install dependencies for $worker${NC}"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo ""
|
|
78
|
+
done
|
|
79
|
+
|
|
80
|
+
# Return to original directory
|
|
81
|
+
cd "$PROJECT_ROOT"
|
|
82
|
+
|
|
83
|
+
echo -e "${GREEN}🎉 All worker dependencies installed successfully!${NC}"
|
|
84
|
+
echo ""
|
|
85
|
+
echo -e "${BLUE}Summary:${NC}"
|
|
86
|
+
echo "- Installed dependencies for $total workers"
|
|
87
|
+
echo "- All workers are ready for development/deployment"
|
|
88
|
+
echo ""
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const { spawnSync } = require('node:child_process');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
|
|
4
|
+
const eslintApiPath = require.resolve('eslint');
|
|
5
|
+
const eslintCliPath = path.resolve(path.dirname(eslintApiPath), '..', 'bin', 'eslint.js');
|
|
6
|
+
|
|
7
|
+
const defaultArgs = [
|
|
8
|
+
'--ignore-path',
|
|
9
|
+
'.gitignore',
|
|
10
|
+
'--cache',
|
|
11
|
+
'--cache-location',
|
|
12
|
+
'./node_modules/.cache/eslint',
|
|
13
|
+
'.',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const passthroughArgs = process.argv.slice(2);
|
|
17
|
+
const eslintArgs = passthroughArgs.length > 0 ? passthroughArgs : defaultArgs;
|
|
18
|
+
|
|
19
|
+
const result = spawnSync(process.execPath, [eslintCliPath, ...eslintArgs], {
|
|
20
|
+
stdio: 'inherit',
|
|
21
|
+
env: {
|
|
22
|
+
...process.env,
|
|
23
|
+
ESLINT_USE_FLAT_CONFIG: 'false',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
if (typeof result.status === 'number') {
|
|
28
|
+
process.exit(result.status);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (result.error) {
|
|
32
|
+
console.error(result.error);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
process.exit(1);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
5
|
+
|
|
6
|
+
function getCurrentDate() {
|
|
7
|
+
const now = new Date();
|
|
8
|
+
const year = now.getFullYear();
|
|
9
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
10
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
11
|
+
return `${year}-${month}-${day}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function replaceTomlCompatibilityDate(content, date) {
|
|
15
|
+
return content.replace(
|
|
16
|
+
/(compatibility_date\s*=\s*")\d{4}-\d{2}-\d{2}(")/,
|
|
17
|
+
`$1${date}$2`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function replaceJsoncCompatibilityDate(content, date) {
|
|
22
|
+
return content.replace(
|
|
23
|
+
/("compatibility_date"\s*:\s*")\d{4}-\d{2}-\d{2}(",?)/,
|
|
24
|
+
`$1${date}$2`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function updateFile(filePath, date, replacer) {
|
|
29
|
+
if (!fs.existsSync(filePath)) {
|
|
30
|
+
return { filePath, status: 'missing' };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const original = fs.readFileSync(filePath, 'utf8');
|
|
34
|
+
const updated = replacer(original, date);
|
|
35
|
+
|
|
36
|
+
if (original === updated) {
|
|
37
|
+
return { filePath, status: 'unchanged' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fs.writeFileSync(filePath, updated, 'utf8');
|
|
41
|
+
return { filePath, status: 'updated' };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function updateCompatibilityDates(date = getCurrentDate()) {
|
|
45
|
+
if (!DATE_PATTERN.test(date)) {
|
|
46
|
+
throw new Error(`Invalid date format: ${date}. Use YYYY-MM-DD.`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
50
|
+
const workersDir = path.join(rootDir, 'workers');
|
|
51
|
+
|
|
52
|
+
const results = [];
|
|
53
|
+
|
|
54
|
+
results.push(
|
|
55
|
+
updateFile(
|
|
56
|
+
path.join(rootDir, 'wrangler.toml'),
|
|
57
|
+
date,
|
|
58
|
+
replaceTomlCompatibilityDate
|
|
59
|
+
)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
results.push(
|
|
63
|
+
updateFile(
|
|
64
|
+
path.join(rootDir, 'wrangler.toml.example'),
|
|
65
|
+
date,
|
|
66
|
+
replaceTomlCompatibilityDate
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (fs.existsSync(workersDir)) {
|
|
71
|
+
const workerDirs = fs
|
|
72
|
+
.readdirSync(workersDir, { withFileTypes: true })
|
|
73
|
+
.filter((entry) => entry.isDirectory())
|
|
74
|
+
.map((entry) => entry.name);
|
|
75
|
+
|
|
76
|
+
for (const workerDir of workerDirs) {
|
|
77
|
+
const workerPath = path.join(workersDir, workerDir);
|
|
78
|
+
results.push(
|
|
79
|
+
updateFile(
|
|
80
|
+
path.join(workerPath, 'wrangler.jsonc.example'),
|
|
81
|
+
date,
|
|
82
|
+
replaceJsoncCompatibilityDate
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
results.push(
|
|
86
|
+
updateFile(
|
|
87
|
+
path.join(workerPath, 'wrangler.jsonc'),
|
|
88
|
+
date,
|
|
89
|
+
replaceJsoncCompatibilityDate
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const updatedCount = results.filter((result) => result.status === 'updated').length;
|
|
96
|
+
const unchangedCount = results.filter((result) => result.status === 'unchanged').length;
|
|
97
|
+
const missingCount = results.filter((result) => result.status === 'missing').length;
|
|
98
|
+
|
|
99
|
+
console.log(`Updated compatibility dates to ${date}`);
|
|
100
|
+
console.log(`- Updated: ${updatedCount}`);
|
|
101
|
+
console.log(`- Unchanged: ${unchangedCount}`);
|
|
102
|
+
console.log(`- Missing: ${missingCount}`);
|
|
103
|
+
|
|
104
|
+
for (const result of results) {
|
|
105
|
+
if (result.status !== 'updated') {
|
|
106
|
+
console.log(` ${result.status.toUpperCase()}: ${path.relative(rootDir, result.filePath)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (require.main === module) {
|
|
114
|
+
const dateArg = process.argv[2] || getCurrentDate();
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
updateCompatibilityDates(dateArg);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error(error.message);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = { updateCompatibilityDates };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const packageJson = require('../package.json');
|
|
4
|
+
|
|
5
|
+
const markdownFiles = [
|
|
6
|
+
'.github/SECURITY.md',
|
|
7
|
+
// Add other markdown files that need version updates
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
function updateMarkdownVersions() {
|
|
11
|
+
console.log(`📝 Updating markdown files with version ${packageJson.version}...`);
|
|
12
|
+
|
|
13
|
+
markdownFiles.forEach(filePath => {
|
|
14
|
+
const fullPath = path.join(__dirname, '..', filePath);
|
|
15
|
+
|
|
16
|
+
if (!fs.existsSync(fullPath)) {
|
|
17
|
+
console.log(`⚠️ Skipping ${filePath} (file not found)`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
let content = fs.readFileSync(fullPath, 'utf8');
|
|
23
|
+
|
|
24
|
+
// Replace version placeholders
|
|
25
|
+
content = content.replace(/{{VERSION}}/g, packageJson.version);
|
|
26
|
+
content = content.replace(/v\d+\.\d+\.\d+(-\w+)?/g, `v${packageJson.version}`);
|
|
27
|
+
|
|
28
|
+
fs.writeFileSync(fullPath, content);
|
|
29
|
+
console.log(`✅ Updated ${filePath}`);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(`❌ Error updating ${filePath}:`, error.message);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
console.log('🎉 Markdown version update complete!');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Run if called directly
|
|
39
|
+
if (require.main === module) {
|
|
40
|
+
updateMarkdownVersions();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = { updateMarkdownVersions };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Config } from "tailwindcss";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"],
|
|
5
|
+
theme: {
|
|
6
|
+
extend: {
|
|
7
|
+
fontFamily: {
|
|
8
|
+
sans: [
|
|
9
|
+
"Inter",
|
|
10
|
+
"ui-sans-serif",
|
|
11
|
+
"system-ui",
|
|
12
|
+
"sans-serif",
|
|
13
|
+
"Apple Color Emoji",
|
|
14
|
+
"Segoe UI Emoji",
|
|
15
|
+
"Segoe UI Symbol",
|
|
16
|
+
"Noto Color Emoji",
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
plugins: [],
|
|
22
|
+
} satisfies Config;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": [
|
|
3
|
+
"**/*.ts",
|
|
4
|
+
"**/*.tsx",
|
|
5
|
+
"**/.server/**/*.ts",
|
|
6
|
+
"**/.server/**/*.tsx",
|
|
7
|
+
"**/.client/**/*.ts",
|
|
8
|
+
"**/.client/**/*.tsx"
|
|
9
|
+
],
|
|
10
|
+
"compilerOptions": {
|
|
11
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
12
|
+
"types": [
|
|
13
|
+
"@remix-run/cloudflare",
|
|
14
|
+
"vite/client"
|
|
15
|
+
],
|
|
16
|
+
"isolatedModules": true,
|
|
17
|
+
"esModuleInterop": true,
|
|
18
|
+
"jsx": "react-jsx",
|
|
19
|
+
"module": "ESNext",
|
|
20
|
+
"moduleResolution": "Bundler",
|
|
21
|
+
"resolveJsonModule": true,
|
|
22
|
+
"target": "ES2022",
|
|
23
|
+
"strict": true,
|
|
24
|
+
"allowJs": true,
|
|
25
|
+
"skipLibCheck": true,
|
|
26
|
+
"forceConsistentCasingInFileNames": true,
|
|
27
|
+
"paths": {
|
|
28
|
+
"~/*": ["./app/*"]
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
"noEmit": true
|
|
32
|
+
}
|
|
33
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
vitePlugin as remix,
|
|
3
|
+
cloudflareDevProxyVitePlugin as remixCloudflareDevProxy,
|
|
4
|
+
} from "@remix-run/dev";
|
|
5
|
+
import { defineConfig } from "vite";
|
|
6
|
+
import tsconfigPaths from "vite-tsconfig-paths";
|
|
7
|
+
|
|
8
|
+
declare module "@remix-run/cloudflare" {
|
|
9
|
+
interface Future {
|
|
10
|
+
v3_singleFetch: true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
server: {
|
|
16
|
+
port: 7777,
|
|
17
|
+
},
|
|
18
|
+
build: {
|
|
19
|
+
chunkSizeWarningLimit: 500,
|
|
20
|
+
minify: true,
|
|
21
|
+
},
|
|
22
|
+
plugins: [
|
|
23
|
+
remixCloudflareDevProxy(),
|
|
24
|
+
remix({
|
|
25
|
+
future: {
|
|
26
|
+
v3_fetcherPersist: true,
|
|
27
|
+
v3_relativeSplatPath: true,
|
|
28
|
+
v3_throwAbortReason: true,
|
|
29
|
+
v3_singleFetch: true,
|
|
30
|
+
v3_lazyRouteDiscovery: true,
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
tsconfigPaths()
|
|
34
|
+
],
|
|
35
|
+
});
|