forked from jsnbuchanan/crowd-funder-for-time-pwa
WIP: add Electron platform configuration to Capacitor
- Add electron platform section to capacitor.config.json - Configure deep linking with timesafari:// scheme - Set up build options for macOS, Windows, and Linux - Configure output directory and file inclusion - Add platform-specific build targets (DMG, NSIS, AppImage) - Support both x64 and arm64 architectures for macOS - Set appropriate app categories for each platform This enables building TimeSafari as a native desktop application using Capacitor's Electron platform while maintaining existing mobile and web functionality.
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
VM4 sandbox_bundle:2 Unable to load preload script: /home/noone/projects/timesafari/crowd-master/preload.js
|
|
||||||
(anonymous) @ VM4 sandbox_bundle:2
|
|
||||||
VM4 sandbox_bundle:2 Error: ENOENT: no such file or directory, open '/home/noone/projects/timesafari/crowd-master/preload.js'
|
|
||||||
at async open (node:internal/fs/promises:639:25)
|
|
||||||
at async Object.readFile (node:internal/fs/promises:1246:14)
|
|
||||||
at async node:electron/js2c/browser_init:2:108714
|
|
||||||
at async Promise.all (index 0)
|
|
||||||
at async node:electron/js2c/browser_init:2:108650
|
|
||||||
at async IpcMainImpl.<anonymous> (node:electron/js2c/browser_init:2:105615)
|
|
||||||
(anonymous) @ VM4 sandbox_bundle:2
|
|
||||||
main.electron.ts:1
|
|
||||||
|
|
||||||
|
|
||||||
Failed to load resource: net::ERR_FILE_NOT_FOUND
|
|
||||||
index.html:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: file:///tmp/.mount_TimeSaGVOt4a/resources/app.asar/dist-electron/www/src/main.electron.ts
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
main.electron.js:1
|
|
||||||
|
|
||||||
|
|
||||||
Failed to load resource: net::ERR_FILE_NOT_FOUND
|
|
||||||
216
BUILDING.md
216
BUILDING.md
@@ -9,7 +9,8 @@ For a quick dev environment setup, use [pkgx](https://pkgx.dev).
|
|||||||
- Node.js (LTS version recommended)
|
- Node.js (LTS version recommended)
|
||||||
- npm (comes with Node.js)
|
- npm (comes with Node.js)
|
||||||
- Git
|
- Git
|
||||||
- For desktop builds: Additional build tools based on your OS
|
- For mobile builds: Android Studio (Android) or Xcode (iOS)
|
||||||
|
- For desktop builds: Capacitor Electron platform
|
||||||
|
|
||||||
## Unified Build Scripts
|
## Unified Build Scripts
|
||||||
|
|
||||||
@@ -28,8 +29,6 @@ TimeSafari now uses unified build scripts that automatically handle environment
|
|||||||
|
|
||||||
| Script | Purpose | Command |
|
| Script | Purpose | Command |
|
||||||
|--------|---------|---------|
|
|--------|---------|---------|
|
||||||
| `electron-dev.sh` | Electron development | `./scripts/electron-dev.sh` |
|
|
||||||
| `electron-build.sh` | Electron build | `./scripts/build-electron.sh` |
|
|
||||||
| `capacitor-dev.sh` | Capacitor development | `./scripts/capacitor-dev.sh` |
|
| `capacitor-dev.sh` | Capacitor development | `./scripts/capacitor-dev.sh` |
|
||||||
| `capacitor-build.sh` | Capacitor build | `./scripts/build-capacitor.sh` |
|
| `capacitor-build.sh` | Capacitor build | `./scripts/build-capacitor.sh` |
|
||||||
| `web-dev.sh` | Web development | `./scripts/web-dev.sh` |
|
| `web-dev.sh` | Web development | `./scripts/web-dev.sh` |
|
||||||
@@ -41,25 +40,22 @@ All scripts automatically set the correct environment variables for their build
|
|||||||
|
|
||||||
| Build Type | VITE_PLATFORM | VITE_PWA_ENABLED | VITE_DISABLE_PWA | NODE_ENV |
|
| Build Type | VITE_PLATFORM | VITE_PWA_ENABLED | VITE_DISABLE_PWA | NODE_ENV |
|
||||||
|------------|---------------|------------------|------------------|----------|
|
|------------|---------------|------------------|------------------|----------|
|
||||||
| `electron` | electron | false | true | production* |
|
|
||||||
| `capacitor` | capacitor | false | true | - |
|
| `capacitor` | capacitor | false | true | - |
|
||||||
| `web` | web | true | false | - |
|
| `web` | web | true | false | - |
|
||||||
|
|
||||||
*NODE_ENV=production only set when production mode is enabled
|
|
||||||
|
|
||||||
### CLI Options
|
### CLI Options
|
||||||
|
|
||||||
All scripts support these options:
|
All scripts support these options:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Show help
|
# Show help
|
||||||
./scripts/build-electron.sh --help
|
./scripts/build-capacitor.sh --help
|
||||||
|
|
||||||
# Enable verbose logging
|
# Enable verbose logging
|
||||||
./scripts/build-electron.sh --verbose
|
./scripts/build-capacitor.sh --verbose
|
||||||
|
|
||||||
# Show environment variables
|
# Show environment variables
|
||||||
./scripts/build-electron.sh --env
|
./scripts/build-capacitor.sh --env
|
||||||
```
|
```
|
||||||
|
|
||||||
## Forks
|
## Forks
|
||||||
@@ -102,12 +98,14 @@ npx jsr add @nostr/tools
|
|||||||
**Reason**: Resolved Vite/Rollup build issues with deep imports
|
**Reason**: Resolved Vite/Rollup build issues with deep imports
|
||||||
|
|
||||||
**Before** (npm):
|
**Before** (npm):
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { finalizeEvent } from "nostr-tools/lib/cjs/index.js";
|
import { finalizeEvent } from "nostr-tools/lib/cjs/index.js";
|
||||||
import { accountFromExtendedKey } from "nostr-tools/lib/cjs/nip06.js";
|
import { accountFromExtendedKey } from "nostr-tools/lib/cjs/nip06.js";
|
||||||
```
|
```
|
||||||
|
|
||||||
**After** (JSR):
|
**After** (JSR):
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { finalizeEvent } from "@nostr/tools";
|
import { finalizeEvent } from "@nostr/tools";
|
||||||
import { accountFromExtendedKey } from "@nostr/tools/nip06";
|
import { accountFromExtendedKey } from "@nostr/tools/nip06";
|
||||||
@@ -210,102 +208,92 @@ VITE_DEFAULT_PUSH_SERVER=https://timesafari.app
|
|||||||
VITE_PASSKEYS_ENABLED=true
|
VITE_PASSKEYS_ENABLED=true
|
||||||
```
|
```
|
||||||
|
|
||||||
## Desktop Build (Electron)
|
## Desktop Build (Capacitor Electron)
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
1. Install Capacitor CLI:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g @capacitor/cli
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add Electron platform:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx cap add electron
|
||||||
|
```
|
||||||
|
|
||||||
### Development
|
### Development
|
||||||
|
|
||||||
For development with automatic environment setup:
|
For development with automatic environment setup:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/electron-dev.sh
|
# Build web assets
|
||||||
|
npm run build:capacitor
|
||||||
|
|
||||||
|
# Sync with Capacitor
|
||||||
|
npx cap sync electron
|
||||||
|
|
||||||
|
# Open in Electron
|
||||||
|
npx cap open electron
|
||||||
```
|
```
|
||||||
|
|
||||||
### Production Build
|
### Production Build
|
||||||
|
|
||||||
For production builds with automatic environment setup:
|
For production builds:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/build-electron.sh
|
# Build web assets
|
||||||
|
npm run build:capacitor
|
||||||
|
|
||||||
|
# Sync with Capacitor
|
||||||
|
npx cap sync electron
|
||||||
|
|
||||||
|
# Build Electron app
|
||||||
|
npx cap build electron
|
||||||
```
|
```
|
||||||
|
|
||||||
### Linux Packaging
|
### Packaging
|
||||||
|
|
||||||
```bash
|
Capacitor Electron uses electron-builder for packaging. Configure the build in `capacitor.config.json`:
|
||||||
# Build AppImage (recommended)
|
|
||||||
./scripts/build-electron-linux.sh
|
|
||||||
|
|
||||||
# Build .deb package
|
```json
|
||||||
./scripts/build-electron-linux.sh deb
|
{
|
||||||
|
"plugins": {
|
||||||
# Build production AppImage
|
"ElectronBuilder": {
|
||||||
./scripts/build-electron-linux.sh prod
|
"buildOptions": {
|
||||||
|
"appId": "app.timesafari.app",
|
||||||
|
"productName": "TimeSafari",
|
||||||
|
"directories": {
|
||||||
|
"output": "dist-electron-packages"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/**/*",
|
||||||
|
"electron/**/*"
|
||||||
|
],
|
||||||
|
"linux": {
|
||||||
|
"target": ["AppImage", "deb"],
|
||||||
|
"category": "Office"
|
||||||
|
},
|
||||||
|
"mac": {
|
||||||
|
"target": ["dmg", "zip"],
|
||||||
|
"category": "public.app-category.productivity"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"target": ["nsis", "portable"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The packaged applications will be in `dist-electron-packages/`:
|
|
||||||
- AppImage: `dist-electron-packages/TimeSafari-x.x.x.AppImage`
|
|
||||||
- DEB: `dist-electron-packages/timesafari_x.x.x_amd64.deb`
|
|
||||||
|
|
||||||
### macOS Packaging
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build standard Mac package
|
|
||||||
./scripts/build-electron-mac.sh
|
|
||||||
|
|
||||||
# Build universal package (Intel + Apple Silicon)
|
|
||||||
./scripts/build-electron-mac.sh universal
|
|
||||||
```
|
|
||||||
|
|
||||||
The packaged applications will be in `dist-electron-packages/`:
|
|
||||||
- `.app` bundle: `TimeSafari.app`
|
|
||||||
- `.dmg` installer: `TimeSafari-x.x.x.dmg`
|
|
||||||
- `.zip` archive: `TimeSafari-x.x.x-mac.zip`
|
|
||||||
|
|
||||||
### Code Signing and Notarization (macOS)
|
|
||||||
|
|
||||||
For public distribution on macOS, you need to code sign and notarize your app:
|
|
||||||
|
|
||||||
1. Set up environment variables in `.env` file:
|
|
||||||
```bash
|
|
||||||
CSC_LINK=/path/to/your/certificate.p12
|
|
||||||
CSC_KEY_PASSWORD=your_certificate_password
|
|
||||||
APPLE_ID=your_apple_id
|
|
||||||
APPLE_ID_PASSWORD=your_app_specific_password
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Build with signing:
|
|
||||||
```bash
|
|
||||||
./scripts/build-electron-mac.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Running the Packaged App
|
### Running the Packaged App
|
||||||
|
|
||||||
- **Linux**:
|
- **Linux**: AppImage files are self-contained executables
|
||||||
- AppImage: Make executable and run
|
- **macOS**: `.app` bundles can be dragged to Applications folder
|
||||||
```bash
|
- **Windows**: `.exe` installers or portable executables
|
||||||
chmod +x dist-electron-packages/TimeSafari-*.AppImage
|
|
||||||
./dist-electron-packages/TimeSafari-*.AppImage
|
|
||||||
```
|
|
||||||
- DEB: Install and run
|
|
||||||
```bash
|
|
||||||
sudo dpkg -i dist-electron-packages/timesafari_*_amd64.deb
|
|
||||||
timesafari
|
|
||||||
```
|
|
||||||
|
|
||||||
- **macOS**:
|
|
||||||
- `.app` bundle: Double-click `TimeSafari.app` in Finder
|
|
||||||
- `.dmg` installer:
|
|
||||||
1. Double-click the `.dmg` file
|
|
||||||
2. Drag the app to your Applications folder
|
|
||||||
3. Launch from Applications
|
|
||||||
- `.zip` archive:
|
|
||||||
1. Extract the `.zip` file
|
|
||||||
2. Move `TimeSafari.app` to your Applications folder
|
|
||||||
3. Launch from Applications
|
|
||||||
|
|
||||||
Note: If you get a security warning when running the app:
|
|
||||||
1. Right-click the app
|
|
||||||
2. Select "Open"
|
|
||||||
3. Click "Open" in the security dialog
|
|
||||||
|
|
||||||
## Mobile Builds (Capacitor)
|
## Mobile Builds (Capacitor)
|
||||||
|
|
||||||
@@ -601,12 +589,12 @@ For iOS deep links, configure the URL scheme in Xcode:
|
|||||||
### Common Issues
|
### Common Issues
|
||||||
|
|
||||||
1. **Environment Variables Not Set**
|
1. **Environment Variables Not Set**
|
||||||
- Use `--env` flag to check current environment: `./scripts/build-electron.sh --env`
|
- Use `--env` flag to check current environment: `./scripts/build-capacitor.sh --env`
|
||||||
- Verify `.env` file exists and is properly formatted
|
- Verify `.env` file exists and is properly formatted
|
||||||
- Check script output for environment setup messages
|
- Check script output for environment setup messages
|
||||||
|
|
||||||
2. **Build Failures**
|
2. **Build Failures**
|
||||||
- Use `--verbose` flag for detailed logging: `./scripts/build-electron.sh --verbose`
|
- Use `--verbose` flag for detailed logging: `./scripts/build-capacitor.sh --verbose`
|
||||||
- Check prerequisites are installed
|
- Check prerequisites are installed
|
||||||
- Verify all dependencies are installed: `npm install`
|
- Verify all dependencies are installed: `npm install`
|
||||||
|
|
||||||
@@ -615,14 +603,13 @@ For iOS deep links, configure the URL scheme in Xcode:
|
|||||||
- Check file permissions on build directories
|
- Check file permissions on build directories
|
||||||
|
|
||||||
4. **Platform-Specific Issues**
|
4. **Platform-Specific Issues**
|
||||||
- **Linux**: Ensure AppImage dependencies are installed
|
|
||||||
- **macOS**: Check code signing certificates and entitlements
|
|
||||||
- **Android**: Verify Android Studio and SDK are properly configured
|
- **Android**: Verify Android Studio and SDK are properly configured
|
||||||
- **iOS**: Ensure Xcode and certificates are set up correctly
|
- **iOS**: Ensure Xcode and certificates are set up correctly
|
||||||
|
- **Electron**: Check Capacitor Electron platform installation
|
||||||
|
|
||||||
### Getting Help
|
### Getting Help
|
||||||
|
|
||||||
- Check script help: `./scripts/build-electron.sh --help`
|
- Check script help: `./scripts/build-capacitor.sh --help`
|
||||||
- Review script documentation in `scripts/README.md`
|
- Review script documentation in `scripts/README.md`
|
||||||
- Test environment setup: `./scripts/test-env.sh`
|
- Test environment setup: `./scripts/test-env.sh`
|
||||||
- Test common utilities: `./scripts/test-common.sh`
|
- Test common utilities: `./scripts/test-common.sh`
|
||||||
@@ -633,20 +620,47 @@ For iOS deep links, configure the URL scheme in Xcode:
|
|||||||
|----------|------|-------------|-----------------|-------|
|
|----------|------|-------------|-----------------|-------|
|
||||||
| `web` | web | true | false | Standard web browser |
|
| `web` | web | true | false | Standard web browser |
|
||||||
| `capacitor` | capacitor | false | true | Mobile app (iOS/Android) |
|
| `capacitor` | capacitor | false | true | Mobile app (iOS/Android) |
|
||||||
| `electron` | electron | false | true | Desktop app (Windows/macOS/Linux) |
|
| `electron` | capacitor | false | true | Desktop app (via Capacitor Electron) |
|
||||||
|
|
||||||
## Electron Build: CSS Injection
|
## Platform Service Architecture
|
||||||
|
|
||||||
The Electron build now uses Vite's built-in CSS handling with a custom plugin (`electron-css-injection`) that automatically injects CSS links into the generated `index.html` file. This replaces the previous manual CSS injection script.
|
TimeSafari uses a unified platform service architecture that works across all platforms:
|
||||||
|
|
||||||
**Plugin:** `vite.config.electron.mts` - `electron-css-injection` plugin
|
### Platform Detection
|
||||||
|
|
||||||
**Features:**
|
The `CapacitorPlatformService` automatically detects the platform and adjusts capabilities:
|
||||||
- Automatically detects and injects CSS files generated by Vite
|
|
||||||
- Ensures proper relative paths for Electron builds
|
|
||||||
- Handles multiple CSS files if present
|
|
||||||
- Provides detailed logging during build process
|
|
||||||
|
|
||||||
**No manual intervention required** - CSS injection is handled automatically during the Vite build process.
|
```typescript
|
||||||
|
getCapabilities(): PlatformCapabilities {
|
||||||
|
const platform = Capacitor.getPlatform();
|
||||||
|
const isElectron = platform === "electron";
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasFileSystem: true,
|
||||||
|
hasCamera: true,
|
||||||
|
isMobile: !isElectron, // false for Electron, true for mobile
|
||||||
|
isIOS: platform === "ios",
|
||||||
|
hasFileDownload: isElectron, // Electron can download files directly
|
||||||
|
needsFileHandlingInstructions: !isElectron, // Mobile needs instructions
|
||||||
|
isNativeApp: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Author:** Matthew Raymer
|
### Unified Database Layer
|
||||||
|
|
||||||
|
All platforms use the same SQLite database through Capacitor plugins:
|
||||||
|
|
||||||
|
- **Mobile**: `@capacitor-community/sqlite` plugin
|
||||||
|
- **Desktop**: Same plugin via Capacitor Electron
|
||||||
|
- **Web**: IndexedDB fallback with absurd-sql
|
||||||
|
|
||||||
|
### Feature Parity
|
||||||
|
|
||||||
|
The same Capacitor plugins work across all platforms:
|
||||||
|
|
||||||
|
- File system operations
|
||||||
|
- Camera access
|
||||||
|
- SQLite database
|
||||||
|
- Deep linking
|
||||||
|
- Sharing functionality
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
"appId": "app.timesafari",
|
"appId": "app.timesafari",
|
||||||
"appName": "TimeSafari",
|
"appName": "TimeSafari",
|
||||||
"webDir": "dist",
|
"webDir": "dist",
|
||||||
"bundledWebRuntime": false,
|
|
||||||
"server": {
|
"server": {
|
||||||
"cleartext": true
|
"cleartext": true
|
||||||
},
|
},
|
||||||
@@ -52,5 +51,47 @@
|
|||||||
"*.jsdelivr.net",
|
"*.jsdelivr.net",
|
||||||
"api.endorser.ch"
|
"api.endorser.ch"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"electron": {
|
||||||
|
"deepLinking": {
|
||||||
|
"schemes": ["timesafari"]
|
||||||
|
},
|
||||||
|
"buildOptions": {
|
||||||
|
"appId": "app.timesafari",
|
||||||
|
"productName": "TimeSafari",
|
||||||
|
"directories": {
|
||||||
|
"output": "dist-electron-packages"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/**/*",
|
||||||
|
"electron/**/*"
|
||||||
|
],
|
||||||
|
"mac": {
|
||||||
|
"category": "public.app-category.productivity",
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"target": "dmg",
|
||||||
|
"arch": ["x64", "arm64"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"target": "nsis",
|
||||||
|
"arch": ["x64"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"target": "AppImage",
|
||||||
|
"arch": ["x64"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"category": "Utility"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
case 'capacitor':
|
case 'capacitor':
|
||||||
import('./src/main.capacitor.ts');
|
import('./src/main.capacitor.ts');
|
||||||
break;
|
break;
|
||||||
case 'electron':
|
|
||||||
import('./src/main.electron.ts');
|
|
||||||
break;
|
|
||||||
case 'web':
|
case 'web':
|
||||||
default:
|
default:
|
||||||
import('./src/main.web.ts');
|
import('./src/main.web.ts');
|
||||||
|
|||||||
447
package-lock.json
generated
447
package-lock.json
generated
@@ -7549,24 +7549,33 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@noble/ciphers": {
|
"node_modules/@noble/ciphers": {
|
||||||
"version": "0.4.1",
|
"version": "0.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz",
|
||||||
"integrity": "sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==",
|
"integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@noble/curves": {
|
"node_modules/@noble/curves": {
|
||||||
"version": "1.9.2",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
|
||||||
"integrity": "sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==",
|
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/hashes": "1.8.0"
|
"@noble/hashes": "1.3.2"
|
||||||
},
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@noble/curves/node_modules/@noble/hashes": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
||||||
|
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.21.3 || >=16"
|
"node": ">= 16"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
@@ -7586,12 +7595,12 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/@noble/hashes": {
|
"node_modules/@noble/hashes": {
|
||||||
"version": "1.8.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz",
|
||||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
"integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.21.3 || >=16"
|
"node": ">= 16"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
@@ -7650,102 +7659,6 @@
|
|||||||
"nostr-wasm": "0.1.0"
|
"nostr-wasm": "0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@nostr/tools/node_modules/@noble/ciphers": {
|
|
||||||
"version": "0.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz",
|
|
||||||
"integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@noble/curves": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/hashes": "1.3.2"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@noble/curves/node_modules/@noble/hashes": {
|
|
||||||
"version": "1.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
|
||||||
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@noble/hashes": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@scure/base": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@scure/bip32": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/curves": "~1.1.0",
|
|
||||||
"@noble/hashes": "~1.3.1",
|
|
||||||
"@scure/base": "~1.1.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@scure/bip32/node_modules/@noble/curves": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/hashes": "1.3.1"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nostr/tools/node_modules/@scure/bip39": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/hashes": "~1.3.0",
|
|
||||||
"@scure/base": "~1.1.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@npmcli/fs": {
|
"node_modules/@npmcli/fs": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
|
||||||
@@ -8724,95 +8637,56 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@scure/base": {
|
"node_modules/@scure/base": {
|
||||||
"version": "1.2.6",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz",
|
||||||
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
"integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==",
|
||||||
"license": "MIT",
|
"funding": [
|
||||||
"funding": {
|
{
|
||||||
"url": "https://paulmillr.com/funding/"
|
"type": "individual",
|
||||||
}
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@scure/bip32": {
|
"node_modules/@scure/bip32": {
|
||||||
"version": "1.4.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz",
|
||||||
"integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==",
|
"integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/curves": "~1.4.0",
|
"@noble/curves": "~1.1.0",
|
||||||
"@noble/hashes": "~1.4.0",
|
"@noble/hashes": "~1.3.1",
|
||||||
"@scure/base": "~1.1.6"
|
"@scure/base": "~1.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@scure/bip32/node_modules/@noble/curves": {
|
"node_modules/@scure/bip32/node_modules/@noble/curves": {
|
||||||
"version": "1.4.2",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz",
|
||||||
"integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==",
|
"integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/hashes": "1.4.0"
|
"@noble/hashes": "1.3.1"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@scure/bip32/node_modules/@noble/hashes": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@scure/bip32/node_modules/@scure/base": {
|
|
||||||
"version": "1.1.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz",
|
|
||||||
"integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@scure/bip39": {
|
"node_modules/@scure/bip39": {
|
||||||
"version": "1.3.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz",
|
||||||
"integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==",
|
"integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/hashes": "~1.4.0",
|
"@noble/hashes": "~1.3.0",
|
||||||
"@scure/base": "~1.1.6"
|
"@scure/base": "~1.1.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@scure/bip39/node_modules/@noble/hashes": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@scure/bip39/node_modules/@scure/base": {
|
|
||||||
"version": "1.1.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz",
|
|
||||||
"integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@simplewebauthn/browser": {
|
"node_modules/@simplewebauthn/browser": {
|
||||||
"version": "10.0.0",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-10.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-10.0.0.tgz",
|
||||||
@@ -9704,9 +9578,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/leaflet": {
|
"node_modules/@types/leaflet": {
|
||||||
"version": "1.9.18",
|
"version": "1.9.19",
|
||||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.18.tgz",
|
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.19.tgz",
|
||||||
"integrity": "sha512-ht2vsoPjezor5Pmzi5hdsA7F++v5UGq9OlUduWHmMZiuQGIpJ2WS5+Gg9HaAA79gNh1AIPtCqhzejcIZ3lPzXQ==",
|
"integrity": "sha512-pB+n2daHcZPF2FDaWa+6B0a0mSDf4dPU35y5iTXsx7x/PzzshiX5atYiS1jlBn43X7XvM8AP+AB26lnSk0J4GA==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -10409,6 +10283,15 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@veramo/did-provider-peer/node_modules/@scure/base": {
|
||||||
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@veramo/did-provider-peer/node_modules/@veramo/core-types": {
|
"node_modules/@veramo/did-provider-peer/node_modules/@veramo/core-types": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@veramo/core-types/-/core-types-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@veramo/core-types/-/core-types-6.0.0.tgz",
|
||||||
@@ -11834,7 +11717,6 @@
|
|||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"possible-typed-array-names": "^1.0.0"
|
"possible-typed-array-names": "^1.0.0"
|
||||||
@@ -12602,9 +12484,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.25.0",
|
"version": "4.25.1",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
|
||||||
"integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==",
|
"integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -12622,8 +12504,8 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001718",
|
"caniuse-lite": "^1.0.30001726",
|
||||||
"electron-to-chromium": "^1.5.160",
|
"electron-to-chromium": "^1.5.173",
|
||||||
"node-releases": "^2.0.19",
|
"node-releases": "^2.0.19",
|
||||||
"update-browserslist-db": "^1.1.3"
|
"update-browserslist-db": "^1.1.3"
|
||||||
},
|
},
|
||||||
@@ -12961,7 +12843,6 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||||
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.0",
|
"call-bind-apply-helpers": "^1.0.0",
|
||||||
@@ -12993,7 +12874,6 @@
|
|||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.2",
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
@@ -13103,9 +12983,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001723",
|
"version": "1.0.30001726",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz",
|
||||||
"integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
|
"integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -14860,7 +14740,6 @@
|
|||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-define-property": "^1.0.0",
|
"es-define-property": "^1.0.0",
|
||||||
@@ -15091,6 +14970,24 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/did-jwt/node_modules/@noble/ciphers": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/did-jwt/node_modules/@scure/base": {
|
||||||
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/did-jwt/node_modules/multiformats": {
|
"node_modules/did-jwt/node_modules/multiformats": {
|
||||||
"version": "9.9.0",
|
"version": "9.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
|
||||||
@@ -15582,9 +15479,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.170",
|
"version": "1.5.173",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.173.tgz",
|
||||||
"integrity": "sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==",
|
"integrity": "sha512-2bFhXP2zqSfQHugjqJIDFVwa+qIxyNApenmXTp9EjaKtdPrES5Qcn9/aSFy/NaP2E+fWG/zxKu/LBvY36p5VNQ==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -16016,9 +15913,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-prettier": {
|
"node_modules/eslint-plugin-prettier": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.1.tgz",
|
||||||
"integrity": "sha512-8qsOYwkkGrahrgoUv76NZi23koqXOGiiEzXMrT8Q7VcYaUISR+5MorIUxfWqYXN0fN/31WbSrxCxFkVQ43wwrA==",
|
"integrity": "sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -16238,6 +16135,18 @@
|
|||||||
"@noble/hashes": "^1.4.0"
|
"@noble/hashes": "^1.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.21.3 || >=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ethereum-cryptography": {
|
"node_modules/ethereum-cryptography": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz",
|
||||||
@@ -16274,6 +16183,42 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ethereum-cryptography/node_modules/@scure/base": {
|
||||||
|
"version": "1.1.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz",
|
||||||
|
"integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ethereum-cryptography/node_modules/@scure/bip32": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@noble/curves": "~1.4.0",
|
||||||
|
"@noble/hashes": "~1.4.0",
|
||||||
|
"@scure/base": "~1.1.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ethereum-cryptography/node_modules/@scure/bip39": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@noble/hashes": "~1.4.0",
|
||||||
|
"@scure/base": "~1.1.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ethereumjs-util": {
|
"node_modules/ethereumjs-util": {
|
||||||
"version": "7.1.5",
|
"version": "7.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz",
|
||||||
@@ -16341,18 +16286,6 @@
|
|||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ethers/node_modules/@noble/curves": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/hashes": "1.3.2"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ethers/node_modules/@noble/hashes": {
|
"node_modules/ethers/node_modules/@noble/hashes": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
||||||
@@ -16446,6 +16379,15 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ethr-did/node_modules/@scure/base": {
|
||||||
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ethr-did/node_modules/did-jwt": {
|
"node_modules/ethr-did/node_modules/did-jwt": {
|
||||||
"version": "8.0.17",
|
"version": "8.0.17",
|
||||||
"resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.17.tgz",
|
"resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.17.tgz",
|
||||||
@@ -17222,7 +17164,6 @@
|
|||||||
"version": "0.3.5",
|
"version": "0.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||||
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
|
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-callable": "^1.2.7"
|
"is-callable": "^1.2.7"
|
||||||
@@ -18102,7 +18043,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"es-define-property": "^1.0.0"
|
"es-define-property": "^1.0.0"
|
||||||
@@ -18705,7 +18645,6 @@
|
|||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||||
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -19149,7 +19088,6 @@
|
|||||||
"version": "1.1.15",
|
"version": "1.1.15",
|
||||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
||||||
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"which-typed-array": "^1.1.16"
|
"which-typed-array": "^1.1.16"
|
||||||
@@ -19236,7 +19174,6 @@
|
|||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/isbinaryfile": {
|
"node_modules/isbinaryfile": {
|
||||||
@@ -23979,21 +23916,53 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pbkdf2": {
|
"node_modules/pbkdf2": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz",
|
||||||
"integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
|
"integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"create-hash": "^1.1.2",
|
"create-hash": "~1.1.3",
|
||||||
"create-hmac": "^1.1.4",
|
"create-hmac": "^1.1.7",
|
||||||
"ripemd160": "^2.0.1",
|
"ripemd160": "=2.0.1",
|
||||||
"safe-buffer": "^5.0.1",
|
"safe-buffer": "^5.2.1",
|
||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.11",
|
||||||
|
"to-buffer": "^1.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pbkdf2/node_modules/create-hash": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cipher-base": "^1.0.1",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
|
"ripemd160": "^2.0.0",
|
||||||
|
"sha.js": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pbkdf2/node_modules/hash-base": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pbkdf2/node_modules/ripemd160": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hash-base": "^2.0.0",
|
||||||
|
"inherits": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pe-library": {
|
"node_modules/pe-library": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz",
|
||||||
@@ -24163,7 +24132,6 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||||
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
|
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@@ -24373,9 +24341,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.5.3",
|
"version": "3.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.1.tgz",
|
||||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
"integrity": "sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -24535,9 +24503,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/protons-runtime": {
|
"node_modules/protons-runtime": {
|
||||||
"version": "5.5.0",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.6.0.tgz",
|
||||||
"integrity": "sha512-EsALjF9QsrEk6gbCx3lmfHxVN0ah7nG3cY7GySD4xf4g8cr7g543zB88Foh897Sr1RQJ9yDCUsoT1i1H/cVUFA==",
|
"integrity": "sha512-/Kde+sB9DsMFrddJT/UZWe6XqvL7SL5dbag/DBCElFKhkwDj7XKt53S+mzLyaDP5OqS0wXjV5SA572uWDaT0Hg==",
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"uint8-varint": "^2.0.2",
|
"uint8-varint": "^2.0.2",
|
||||||
@@ -24744,9 +24712,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qrcode-generator": {
|
"node_modules/qrcode-generator": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.5.1.tgz",
|
||||||
"integrity": "sha512-sqo7otiDq5rA4djRkFI7IjLQqxRrLpIou0d3rqr03JJLUGf5raPh91xCio+lFFbQf0SlcVckStz0EmDEX3EeZA==",
|
"integrity": "sha512-u0zerMlMtKBgkDlDzWXG/7F7jo2En1d7bivC7V33HGqP62XxGiHGnbCJNkSCMxGfNlhXGBGEIamNMHbZ4P4mLg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/qrcode-terminal": {
|
"node_modules/qrcode-terminal": {
|
||||||
@@ -26906,7 +26874,6 @@
|
|||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.1.4",
|
"define-data-property": "^1.1.4",
|
||||||
@@ -28836,6 +28803,20 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/to-buffer": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": "^2.0.5",
|
||||||
|
"safe-buffer": "^5.2.1",
|
||||||
|
"typed-array-buffer": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
@@ -29080,7 +29061,6 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||||
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
|
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
@@ -29169,9 +29149,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/typeorm": {
|
"node_modules/typeorm": {
|
||||||
"version": "0.3.24",
|
"version": "0.3.25",
|
||||||
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.24.tgz",
|
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.25.tgz",
|
||||||
"integrity": "sha512-4IrHG7A0tY8l5gEGXfW56VOMfUVWEkWlH/h5wmcyZ+V8oCiLj7iTPp0lEjMEZVrxEkGSdP9ErgTKHKXQApl/oA==",
|
"integrity": "sha512-fTKDFzWXKwAaBdEMU4k661seZewbNYET4r1J/z3Jwf+eAvlzMVpTLKAVcAzg75WwQk7GDmtsmkZ5MfkmXCiFWg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sqltools/formatter": "^1.2.5",
|
"@sqltools/formatter": "^1.2.5",
|
||||||
@@ -30352,7 +30332,6 @@
|
|||||||
"version": "1.1.19",
|
"version": "1.1.19",
|
||||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
|
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
|
||||||
"integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
|
"integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"available-typed-arrays": "^1.0.7",
|
"available-typed-arrays": "^1.0.7",
|
||||||
|
|||||||
70
package.json
70
package.json
@@ -20,25 +20,14 @@
|
|||||||
"test:ios": "node scripts/test-ios.js",
|
"test:ios": "node scripts/test-ios.js",
|
||||||
"check:android-device": "adb devices | grep -w 'device' || (echo 'No Android device connected' && exit 1)",
|
"check:android-device": "adb devices | grep -w 'device' || (echo 'No Android device connected' && exit 1)",
|
||||||
"check:ios-device": "xcrun xctrace list devices 2>&1 | grep -w 'Booted' || (echo 'No iOS simulator running' && exit 1)",
|
"check:ios-device": "xcrun xctrace list devices 2>&1 | grep -w 'Booted' || (echo 'No iOS simulator running' && exit 1)",
|
||||||
"clean:electron": "rimraf dist-electron",
|
"build:capacitor": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --mode capacitor --config vite.config.capacitor.mts",
|
||||||
"build:electron": "./scripts/build-electron.sh && npm run build:electron-renderer",
|
|
||||||
"build:electron-renderer": "vite build --config vite.config.electron.renderer.mts",
|
|
||||||
"build:capacitor": "vite build --mode capacitor --config vite.config.capacitor.mts",
|
|
||||||
"build:web": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.web.mts",
|
"build:web": "VITE_GIT_HASH=`git log -1 --pretty=format:%h` vite build --config vite.config.web.mts",
|
||||||
"electron:dev": "./scripts/electron-dev.sh",
|
|
||||||
"electron:start": "electron .",
|
|
||||||
"clean:android": "adb uninstall app.timesafari.app || true",
|
"clean:android": "adb uninstall app.timesafari.app || true",
|
||||||
"build:android": "./scripts/build-android.sh",
|
"build:android": "./scripts/build-android.sh",
|
||||||
"electron:build-linux": "./scripts/build-electron-linux.sh",
|
|
||||||
"electron:build-linux-deb": "./scripts/build-electron-linux.sh deb",
|
|
||||||
"electron:build-linux-prod": "./scripts/build-electron-linux.sh prod",
|
|
||||||
"build:electron-prod": "NODE_ENV=production npm run build:electron",
|
|
||||||
"fastlane:ios:beta": "cd ios && fastlane beta",
|
"fastlane:ios:beta": "cd ios && fastlane beta",
|
||||||
"fastlane:ios:release": "cd ios && fastlane release",
|
"fastlane:ios:release": "cd ios && fastlane release",
|
||||||
"fastlane:android:beta": "cd android && fastlane beta",
|
"fastlane:android:beta": "cd android && fastlane beta",
|
||||||
"fastlane:android:release": "cd android && fastlane release",
|
"fastlane:android:release": "cd android && fastlane release"
|
||||||
"electron:build-mac": "./scripts/build-electron-mac.sh",
|
|
||||||
"electron:build-mac-universal": "./scripts/build-electron-mac.sh universal"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor-community/sqlite": "6.0.2",
|
"@capacitor-community/sqlite": "6.0.2",
|
||||||
@@ -145,8 +134,6 @@
|
|||||||
"browserify-fs": "^1.0.0",
|
"browserify-fs": "^1.0.0",
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^8.2.2",
|
||||||
"crypto-browserify": "^3.12.1",
|
"crypto-browserify": "^3.12.1",
|
||||||
"electron": "^33.2.1",
|
|
||||||
"electron-builder": "^25.1.8",
|
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
@@ -163,58 +150,5 @@
|
|||||||
"typescript": "~5.2.2",
|
"typescript": "~5.2.2",
|
||||||
"vite": "^5.2.0",
|
"vite": "^5.2.0",
|
||||||
"vite-plugin-pwa": "^1.0.0"
|
"vite-plugin-pwa": "^1.0.0"
|
||||||
},
|
|
||||||
"main": "./dist-electron/main.js",
|
|
||||||
"build": {
|
|
||||||
"appId": "app.timesafari.app",
|
|
||||||
"productName": "TimeSafari",
|
|
||||||
"directories": {
|
|
||||||
"output": "dist-electron-packages"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist-electron/**/*",
|
|
||||||
"dist/**/*"
|
|
||||||
],
|
|
||||||
"extraResources": [
|
|
||||||
{
|
|
||||||
"from": "dist-electron/www",
|
|
||||||
"to": "www"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"linux": {
|
|
||||||
"target": [
|
|
||||||
"AppImage",
|
|
||||||
"deb"
|
|
||||||
],
|
|
||||||
"category": "Office",
|
|
||||||
"icon": "build/icon.png"
|
|
||||||
},
|
|
||||||
"asar": true,
|
|
||||||
"mac": {
|
|
||||||
"target": [
|
|
||||||
"dmg",
|
|
||||||
"zip"
|
|
||||||
],
|
|
||||||
"category": "public.app-category.productivity",
|
|
||||||
"icon": "build/icon.png",
|
|
||||||
"hardenedRuntime": true,
|
|
||||||
"gatekeeperAssess": false,
|
|
||||||
"entitlements": "ios/App/App/entitlements.mac.plist",
|
|
||||||
"entitlementsInherit": "ios/App/App/entitlements.mac.plist"
|
|
||||||
},
|
|
||||||
"dmg": {
|
|
||||||
"contents": [
|
|
||||||
{
|
|
||||||
"x": 130,
|
|
||||||
"y": 220
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 410,
|
|
||||||
"y": 220,
|
|
||||||
"type": "link",
|
|
||||||
"path": "/Applications"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ All scripts automatically handle environment variables for different build types
|
|||||||
|----------|------|-------------|-----------------|--------------|
|
|----------|------|-------------|-----------------|--------------|
|
||||||
| `web` | web | true | false | `build-web.sh` |
|
| `web` | web | true | false | `build-web.sh` |
|
||||||
| `capacitor` | capacitor | false | true | `build-capacitor.sh` |
|
| `capacitor` | capacitor | false | true | `build-capacitor.sh` |
|
||||||
| `electron` | electron | false | true | `build-electron.sh` |
|
|
||||||
|
|
||||||
#### Automatic Environment Setup
|
#### Automatic Environment Setup
|
||||||
|
|
||||||
@@ -96,10 +95,7 @@ exit 0
|
|||||||
|
|
||||||
### Build Scripts
|
### Build Scripts
|
||||||
|
|
||||||
- **`build-electron.sh`**: Complete Electron build process
|
|
||||||
- **`build-android.sh`**: Complete Android build process
|
- **`build-android.sh`**: Complete Android build process
|
||||||
- **`build-electron-linux.sh`**: Linux Electron packaging (AppImage, .deb)
|
|
||||||
- **`build-electron-mac.sh`**: macOS Electron packaging (standard, universal)
|
|
||||||
|
|
||||||
### Development Scripts
|
### Development Scripts
|
||||||
|
|
||||||
@@ -152,10 +148,8 @@ print_footer "Script Title"
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Building Applications
|
### Building Applications
|
||||||
```bash
|
|
||||||
# Build Electron
|
|
||||||
./scripts/build-electron.sh
|
|
||||||
|
|
||||||
|
```bash
|
||||||
# Build Android
|
# Build Android
|
||||||
./scripts/build-android.sh
|
./scripts/build-android.sh
|
||||||
|
|
||||||
@@ -170,19 +164,21 @@ print_footer "Script Title"
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Development Workflows
|
### Development Workflows
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Start Electron development
|
# Start development
|
||||||
./scripts/electron-dev.sh
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment Variable Features
|
## Environment Variable Features
|
||||||
|
|
||||||
### Automatic Setup
|
### Automatic Setup
|
||||||
|
|
||||||
All scripts automatically configure the correct environment variables for their build type:
|
All scripts automatically configure the correct environment variables for their build type:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Electron builds automatically get:
|
# Capacitor builds automatically get:
|
||||||
export VITE_PLATFORM=electron
|
export VITE_PLATFORM=capacitor
|
||||||
export VITE_PWA_ENABLED=false
|
export VITE_PWA_ENABLED=false
|
||||||
export VITE_DISABLE_PWA=true
|
export VITE_DISABLE_PWA=true
|
||||||
export DEBUG_MIGRATIONS=0
|
export DEBUG_MIGRATIONS=0
|
||||||
@@ -214,7 +210,6 @@ validate_env_vars "VITE_API_URL" "VITE_DEBUG" || exit 1
|
|||||||
View current environment variables with the `--env` flag:
|
View current environment variables with the `--env` flag:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/build-electron.sh --env
|
|
||||||
./scripts/test-env.sh --env
|
./scripts/test-env.sh --env
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# build-electron-linux.sh
|
|
||||||
# Author: Matthew Raymer
|
|
||||||
# Description: Electron Linux build script for TimeSafari application
|
|
||||||
# This script builds Electron packages for Linux with support for different formats.
|
|
||||||
#
|
|
||||||
# Usage: ./scripts/build-electron-linux.sh [deb|prod]
|
|
||||||
# - No argument: Builds AppImage
|
|
||||||
# - deb: Builds .deb package
|
|
||||||
# - prod: Builds production AppImage
|
|
||||||
#
|
|
||||||
# Exit Codes:
|
|
||||||
# 1 - Build failed
|
|
||||||
# 2 - Invalid argument
|
|
||||||
|
|
||||||
# Exit on any error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Source common utilities
|
|
||||||
source "$(dirname "$0")/common.sh"
|
|
||||||
|
|
||||||
# Parse command line arguments
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
# Parse build type argument
|
|
||||||
BUILD_TYPE=${1:-"appimage"}
|
|
||||||
PRODUCTION=false
|
|
||||||
|
|
||||||
case $BUILD_TYPE in
|
|
||||||
"deb")
|
|
||||||
BUILD_TARGET="deb"
|
|
||||||
log_info "Building .deb package"
|
|
||||||
;;
|
|
||||||
"prod")
|
|
||||||
BUILD_TARGET="AppImage"
|
|
||||||
PRODUCTION=true
|
|
||||||
log_info "Building production AppImage"
|
|
||||||
;;
|
|
||||||
"appimage"|"")
|
|
||||||
BUILD_TARGET="AppImage"
|
|
||||||
log_info "Building AppImage"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
log_error "Invalid build type: $BUILD_TYPE"
|
|
||||||
log_error "Usage: $0 [deb|prod]"
|
|
||||||
exit 2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Print build header
|
|
||||||
print_header "TimeSafari Electron Linux Build"
|
|
||||||
log_info "Starting Linux build process at $(date)"
|
|
||||||
log_info "Build type: $BUILD_TYPE"
|
|
||||||
log_info "Build target: $BUILD_TARGET"
|
|
||||||
log_info "Production mode: $PRODUCTION"
|
|
||||||
|
|
||||||
# Setup environment for Electron build
|
|
||||||
setup_build_env "electron" "$PRODUCTION"
|
|
||||||
|
|
||||||
# Setup application directories
|
|
||||||
setup_app_directories
|
|
||||||
|
|
||||||
# Load environment from .env file if it exists
|
|
||||||
load_env_file ".env"
|
|
||||||
|
|
||||||
# Step 1: Build Electron application
|
|
||||||
if [ "$PRODUCTION" = true ]; then
|
|
||||||
safe_execute "Building production Electron application" "npm run build:electron-prod" || exit 1
|
|
||||||
else
|
|
||||||
safe_execute "Building Electron application" "npm run build:electron" || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 2: Build package
|
|
||||||
safe_execute "Building Linux package" "npx electron-builder --linux $BUILD_TARGET" || exit 1
|
|
||||||
|
|
||||||
# Print build summary
|
|
||||||
log_success "Linux build completed successfully!"
|
|
||||||
log_info "Package type: $BUILD_TARGET"
|
|
||||||
print_footer "Linux Build"
|
|
||||||
|
|
||||||
# Exit with success
|
|
||||||
exit 0
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# build-electron-mac.sh
|
|
||||||
# Author: Matthew Raymer
|
|
||||||
# Description: Electron Mac build script for TimeSafari application
|
|
||||||
# This script builds Electron packages for macOS with support for universal builds.
|
|
||||||
#
|
|
||||||
# Usage: ./scripts/build-electron-mac.sh [universal]
|
|
||||||
# - No argument: Builds standard Mac package
|
|
||||||
# - universal: Builds universal Mac package (Intel + Apple Silicon)
|
|
||||||
#
|
|
||||||
# Exit Codes:
|
|
||||||
# 1 - Build failed
|
|
||||||
# 2 - Invalid argument
|
|
||||||
|
|
||||||
# Exit on any error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Source common utilities
|
|
||||||
source "$(dirname "$0")/common.sh"
|
|
||||||
|
|
||||||
# Parse command line arguments
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
# Parse build type argument
|
|
||||||
BUILD_TYPE=${1:-"standard"}
|
|
||||||
UNIVERSAL=false
|
|
||||||
|
|
||||||
case $BUILD_TYPE in
|
|
||||||
"universal")
|
|
||||||
UNIVERSAL=true
|
|
||||||
log_info "Building universal Mac package (Intel + Apple Silicon)"
|
|
||||||
;;
|
|
||||||
"standard"|"")
|
|
||||||
log_info "Building standard Mac package"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
log_error "Invalid build type: $BUILD_TYPE"
|
|
||||||
log_error "Usage: $0 [universal]"
|
|
||||||
exit 2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Print build header
|
|
||||||
print_header "TimeSafari Electron Mac Build"
|
|
||||||
log_info "Starting Mac build process at $(date)"
|
|
||||||
log_info "Build type: $BUILD_TYPE"
|
|
||||||
log_info "Universal build: $UNIVERSAL"
|
|
||||||
|
|
||||||
# Setup environment for Electron build (production mode for packaging)
|
|
||||||
setup_build_env "electron" "true"
|
|
||||||
|
|
||||||
# Setup application directories
|
|
||||||
setup_app_directories
|
|
||||||
|
|
||||||
# Load environment from .env file if it exists
|
|
||||||
load_env_file ".env"
|
|
||||||
|
|
||||||
# Step 1: Build Electron application
|
|
||||||
safe_execute "Building Electron application" "npm run build:electron-prod" || exit 1
|
|
||||||
|
|
||||||
# Step 2: Build package
|
|
||||||
if [ "$UNIVERSAL" = true ]; then
|
|
||||||
safe_execute "Building universal Mac package" "npx electron-builder --mac --universal" || exit 1
|
|
||||||
else
|
|
||||||
safe_execute "Building Mac package" "npx electron-builder --mac" || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print build summary
|
|
||||||
log_success "Mac build completed successfully!"
|
|
||||||
log_info "Package type: $([ "$UNIVERSAL" = true ] && echo "Universal" || echo "Standard")"
|
|
||||||
print_footer "Mac Build"
|
|
||||||
|
|
||||||
# Exit with success
|
|
||||||
exit 0
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
console.log('Starting electron build process...');
|
|
||||||
|
|
||||||
// Define paths
|
|
||||||
const electronDistPath = path.join(__dirname, '..', 'dist-electron');
|
|
||||||
const wwwPath = path.join(electronDistPath, 'www');
|
|
||||||
|
|
||||||
// Create www directory if it doesn't exist
|
|
||||||
if (!fs.existsSync(wwwPath)) {
|
|
||||||
fs.mkdirSync(wwwPath, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the Vite-built index.html to www directory
|
|
||||||
const viteIndexPath = path.join(electronDistPath, 'index.html');
|
|
||||||
const wwwIndexPath = path.join(wwwPath, 'index.html');
|
|
||||||
|
|
||||||
if (fs.existsSync(viteIndexPath)) {
|
|
||||||
console.log('Copying Vite-built index.html to www directory...');
|
|
||||||
fs.copyFileSync(viteIndexPath, wwwIndexPath);
|
|
||||||
|
|
||||||
// Remove the original index.html from dist-electron root
|
|
||||||
fs.unlinkSync(viteIndexPath);
|
|
||||||
console.log('Moved index.html to www directory');
|
|
||||||
} else {
|
|
||||||
console.error('Vite-built index.html not found at:', viteIndexPath);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy assets directory if it exists in dist-electron
|
|
||||||
const assetsSrc = path.join(electronDistPath, 'assets');
|
|
||||||
const assetsDest = path.join(wwwPath, 'assets');
|
|
||||||
|
|
||||||
if (fs.existsSync(assetsSrc)) {
|
|
||||||
console.log('Moving assets directory to www...');
|
|
||||||
if (fs.existsSync(assetsDest)) {
|
|
||||||
fs.rmSync(assetsDest, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
fs.renameSync(assetsSrc, assetsDest);
|
|
||||||
console.log('Moved assets directory to www');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy favicon if it exists
|
|
||||||
const faviconSrc = path.join(electronDistPath, 'favicon.ico');
|
|
||||||
const faviconDest = path.join(wwwPath, 'favicon.ico');
|
|
||||||
|
|
||||||
if (fs.existsSync(faviconSrc)) {
|
|
||||||
console.log('Moving favicon to www...');
|
|
||||||
fs.renameSync(faviconSrc, faviconDest);
|
|
||||||
console.log('Moved favicon to www');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove service worker files from www directory
|
|
||||||
const swFilesToRemove = [
|
|
||||||
'sw.js',
|
|
||||||
'sw.js.map',
|
|
||||||
'workbox-*.js',
|
|
||||||
'workbox-*.js.map',
|
|
||||||
'registerSW.js',
|
|
||||||
'manifest.webmanifest'
|
|
||||||
];
|
|
||||||
|
|
||||||
console.log('Removing service worker files...');
|
|
||||||
swFilesToRemove.forEach(pattern => {
|
|
||||||
const files = fs.readdirSync(wwwPath).filter(file =>
|
|
||||||
file.match(new RegExp(pattern.replace(/\*/g, '.*')))
|
|
||||||
);
|
|
||||||
files.forEach(file => {
|
|
||||||
const filePath = path.join(wwwPath, file);
|
|
||||||
console.log(`Removing ${filePath}`);
|
|
||||||
try {
|
|
||||||
fs.unlinkSync(filePath);
|
|
||||||
} catch (err) {
|
|
||||||
console.warn(`Could not remove ${filePath}:`, err.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Also check and remove from assets directory
|
|
||||||
if (fs.existsSync(assetsDest)) {
|
|
||||||
swFilesToRemove.forEach(pattern => {
|
|
||||||
const files = fs.readdirSync(assetsDest).filter(file =>
|
|
||||||
file.match(new RegExp(pattern.replace(/\*/g, '.*')))
|
|
||||||
);
|
|
||||||
files.forEach(file => {
|
|
||||||
const filePath = path.join(assetsDest, file);
|
|
||||||
console.log(`Removing ${filePath}`);
|
|
||||||
try {
|
|
||||||
fs.unlinkSync(filePath);
|
|
||||||
} catch (err) {
|
|
||||||
console.warn(`Could not remove ${filePath}:`, err.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the final index.html structure
|
|
||||||
const finalIndexContent = fs.readFileSync(wwwIndexPath, 'utf8');
|
|
||||||
console.log('Final index.html structure:');
|
|
||||||
console.log('- Has CSS link:', finalIndexContent.includes('<link rel="stylesheet"'));
|
|
||||||
console.log('- Has main script:', finalIndexContent.includes('main.electron.js'));
|
|
||||||
console.log('- No service worker references:', !finalIndexContent.includes('serviceWorker'));
|
|
||||||
|
|
||||||
// Copy main process files to the correct location
|
|
||||||
console.log('Setting up main process files...');
|
|
||||||
|
|
||||||
// The main process files are already in the correct location
|
|
||||||
// Just verify they exist and are ready
|
|
||||||
const mainPath = path.join(electronDistPath, 'main.js');
|
|
||||||
const preloadPath = path.join(electronDistPath, 'preload.js');
|
|
||||||
|
|
||||||
if (fs.existsSync(mainPath)) {
|
|
||||||
console.log('Main process file ready at:', mainPath);
|
|
||||||
} else {
|
|
||||||
console.error('Main process file not found at:', mainPath);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.existsSync(preloadPath)) {
|
|
||||||
console.log('Preload script ready at:', preloadPath);
|
|
||||||
} else {
|
|
||||||
console.warn('Preload script not found at:', preloadPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up any remaining files in dist-electron root (except main.js, preload.js, and www directory)
|
|
||||||
const remainingFiles = fs.readdirSync(electronDistPath);
|
|
||||||
remainingFiles.forEach(file => {
|
|
||||||
if (file !== 'main.js' && file !== 'preload.js' && file !== 'www') {
|
|
||||||
const filePath = path.join(electronDistPath, file);
|
|
||||||
console.log(`Removing remaining file: ${file}`);
|
|
||||||
try {
|
|
||||||
if (fs.statSync(filePath).isDirectory()) {
|
|
||||||
fs.rmSync(filePath, { recursive: true, force: true });
|
|
||||||
} else {
|
|
||||||
fs.unlinkSync(filePath);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.warn(`Could not remove ${filePath}:`, err.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Electron build process completed successfully');
|
|
||||||
console.log('Final structure:');
|
|
||||||
console.log('- Main process:', path.join(electronDistPath, 'main.js'));
|
|
||||||
console.log('- Preload script:', path.join(electronDistPath, 'preload.js'));
|
|
||||||
console.log('- Web assets:', path.join(electronDistPath, 'www'));
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# build-electron.sh
|
|
||||||
# Author: Matthew Raymer
|
|
||||||
# Description: Electron build script for TimeSafari application
|
|
||||||
# This script handles the complete Electron build process including cleanup,
|
|
||||||
# TypeScript compilation, Vite build, and Electron-specific setup.
|
|
||||||
#
|
|
||||||
# Exit Codes:
|
|
||||||
# 1 - Cleanup failed
|
|
||||||
# 2 - TypeScript compilation failed
|
|
||||||
# 3 - Vite build failed
|
|
||||||
# 4 - Electron build script failed
|
|
||||||
|
|
||||||
# Exit on any error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Source common utilities
|
|
||||||
source "$(dirname "$0")/common.sh"
|
|
||||||
|
|
||||||
# Parse command line arguments
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
# Print build header
|
|
||||||
print_header "TimeSafari Electron Build Process"
|
|
||||||
log_info "Starting Electron build process at $(date)"
|
|
||||||
|
|
||||||
# Setup environment for Electron build
|
|
||||||
setup_build_env "electron"
|
|
||||||
|
|
||||||
# Setup application directories
|
|
||||||
setup_app_directories
|
|
||||||
|
|
||||||
# Load environment from .env file if it exists
|
|
||||||
load_env_file ".env"
|
|
||||||
|
|
||||||
# Step 1: Clean previous builds
|
|
||||||
safe_execute "Cleaning previous builds" "npm run clean:electron" || exit 1
|
|
||||||
|
|
||||||
# Step 2: Compile TypeScript for Electron
|
|
||||||
safe_execute "Compiling TypeScript for Electron" "npx tsc -p tsconfig.electron.json" || exit 2
|
|
||||||
|
|
||||||
# Step 3: Build with Vite
|
|
||||||
safe_execute "Building with Vite" "npx vite build --config vite.config.electron.mts" || exit 3
|
|
||||||
|
|
||||||
# Step 4: Run Electron build script
|
|
||||||
safe_execute "Running Electron build script" "node scripts/build-electron.js" || exit 4
|
|
||||||
|
|
||||||
# Print build summary
|
|
||||||
log_success "Electron build completed successfully!"
|
|
||||||
print_footer "Electron Build"
|
|
||||||
|
|
||||||
# Exit with success
|
|
||||||
exit 0
|
|
||||||
@@ -176,16 +176,6 @@ setup_build_env() {
|
|||||||
log_debug "Set VITE_GIT_HASH=$git_hash"
|
log_debug "Set VITE_GIT_HASH=$git_hash"
|
||||||
|
|
||||||
case $build_type in
|
case $build_type in
|
||||||
"electron")
|
|
||||||
export VITE_PLATFORM=electron
|
|
||||||
export VITE_PWA_ENABLED=false
|
|
||||||
export VITE_DISABLE_PWA=true
|
|
||||||
export DEBUG_MIGRATIONS=0
|
|
||||||
if [ "$production" = true ]; then
|
|
||||||
export NODE_ENV=production
|
|
||||||
log_debug "Set production mode for Electron"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"capacitor")
|
"capacitor")
|
||||||
export VITE_PLATFORM=capacitor
|
export VITE_PLATFORM=capacitor
|
||||||
export VITE_PWA_ENABLED=false
|
export VITE_PWA_ENABLED=false
|
||||||
@@ -227,7 +217,6 @@ setup_app_directories() {
|
|||||||
|
|
||||||
# Create build directories if they don't exist
|
# Create build directories if they don't exist
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
mkdir -p dist-electron
|
|
||||||
|
|
||||||
log_debug "Application directories created"
|
log_debug "Application directories created"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# electron-dev.sh
|
|
||||||
# Author: Matthew Raymer
|
|
||||||
# Description: Electron development script for TimeSafari application
|
|
||||||
# This script builds the application and starts Electron for development.
|
|
||||||
#
|
|
||||||
# Exit Codes:
|
|
||||||
# 1 - Build failed
|
|
||||||
# 2 - Electron start failed
|
|
||||||
|
|
||||||
# Exit on any error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Source common utilities
|
|
||||||
source "$(dirname "$0")/common.sh"
|
|
||||||
|
|
||||||
# Parse command line arguments
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
# Print dev header
|
|
||||||
print_header "TimeSafari Electron Development"
|
|
||||||
log_info "Starting Electron development at $(date)"
|
|
||||||
|
|
||||||
# Setup environment for Electron development
|
|
||||||
setup_build_env "electron"
|
|
||||||
|
|
||||||
# Setup application directories
|
|
||||||
setup_app_directories
|
|
||||||
|
|
||||||
# Load environment from .env file if it exists
|
|
||||||
load_env_file ".env"
|
|
||||||
|
|
||||||
# Step 1: Build the application
|
|
||||||
safe_execute "Building application" "npm run build" || exit 1
|
|
||||||
|
|
||||||
# Step 2: Start Electron
|
|
||||||
safe_execute "Starting Electron" "electron ." || exit 2
|
|
||||||
|
|
||||||
# Print dev summary
|
|
||||||
log_success "Electron development session ended"
|
|
||||||
print_footer "Electron Development"
|
|
||||||
|
|
||||||
# Exit with success
|
|
||||||
exit 0
|
|
||||||
@@ -17,37 +17,34 @@ parse_args "$@"
|
|||||||
print_header "Environment Variable Test"
|
print_header "Environment Variable Test"
|
||||||
log_info "Testing environment variable handling at $(date)"
|
log_info "Testing environment variable handling at $(date)"
|
||||||
|
|
||||||
# Test 1: Electron environment
|
# Test 1: Capacitor environment
|
||||||
log_info "Test 1: Setting up Electron environment..."
|
log_info "Test 1: Setting up Capacitor environment..."
|
||||||
setup_build_env "electron"
|
|
||||||
print_env_vars "VITE_"
|
|
||||||
|
|
||||||
# Test 2: Capacitor environment
|
|
||||||
log_info "Test 2: Setting up Capacitor environment..."
|
|
||||||
setup_build_env "capacitor"
|
setup_build_env "capacitor"
|
||||||
print_env_vars "VITE_"
|
print_env_vars "VITE_"
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Test 3: Web environment
|
# Test 2: Web environment
|
||||||
log_info "Test 3: Setting up Web environment..."
|
log_info "Test 2: Setting up Web environment..."
|
||||||
setup_build_env "web"
|
setup_build_env "web"
|
||||||
print_env_vars "VITE_"
|
print_env_vars "VITE_"
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Test 4: Production Electron environment
|
# Test 3: Production Capacitor environment
|
||||||
log_info "Test 4: Setting up Production Electron environment..."
|
log_info "Test 3: Setting up Production Capacitor environment..."
|
||||||
setup_build_env "electron" "true"
|
setup_build_env "capacitor" "true"
|
||||||
print_env_vars "VITE_"
|
print_env_vars "VITE_"
|
||||||
print_env_vars "NODE_ENV"
|
echo ""
|
||||||
|
|
||||||
# Test 5: Application directories
|
# Test 4: Application directories
|
||||||
log_info "Test 5: Setting up application directories..."
|
log_info "Test 4: Setting up application directories..."
|
||||||
setup_app_directories
|
setup_app_directories
|
||||||
|
|
||||||
# Test 6: Load .env file (if it exists)
|
# Test 5: Load .env file (if it exists)
|
||||||
log_info "Test 6: Loading .env file..."
|
log_info "Test 5: Loading .env file..."
|
||||||
load_env_file ".env"
|
load_env_file ".env"
|
||||||
|
|
||||||
# Test 7: Git hash
|
# Test 6: Git hash
|
||||||
log_info "Test 7: Getting git hash..."
|
log_info "Test 6: Getting git hash..."
|
||||||
GIT_HASH=$(get_git_hash)
|
GIT_HASH=$(get_git_hash)
|
||||||
log_info "Git hash: $GIT_HASH"
|
log_info "Git hash: $GIT_HASH"
|
||||||
|
|
||||||
|
|||||||
@@ -1,174 +0,0 @@
|
|||||||
const { app, BrowserWindow } = require("electron");
|
|
||||||
const path = require("path");
|
|
||||||
const fs = require("fs");
|
|
||||||
const logger = require("../utils/logger");
|
|
||||||
|
|
||||||
// Check if running in dev mode
|
|
||||||
const isDev = process.argv.includes("--inspect");
|
|
||||||
|
|
||||||
function createWindow() {
|
|
||||||
// Add before createWindow function
|
|
||||||
const preloadPath = path.join(__dirname, "preload.js");
|
|
||||||
logger.log("Checking preload path:", preloadPath);
|
|
||||||
logger.log("Preload exists:", fs.existsSync(preloadPath));
|
|
||||||
|
|
||||||
// Create the browser window.
|
|
||||||
const mainWindow = new BrowserWindow({
|
|
||||||
width: 1200,
|
|
||||||
height: 800,
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: false,
|
|
||||||
contextIsolation: true,
|
|
||||||
webSecurity: true,
|
|
||||||
allowRunningInsecureContent: false,
|
|
||||||
preload: path.join(__dirname, "preload.js"),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Always open DevTools for now
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
|
|
||||||
// Intercept requests to fix asset paths
|
|
||||||
mainWindow.webContents.session.webRequest.onBeforeRequest(
|
|
||||||
{
|
|
||||||
urls: [
|
|
||||||
"file://*/*/assets/*",
|
|
||||||
"file://*/assets/*",
|
|
||||||
"file:///assets/*", // Catch absolute paths
|
|
||||||
"<all_urls>", // Catch all URLs as a fallback
|
|
||||||
],
|
|
||||||
},
|
|
||||||
(details, callback) => {
|
|
||||||
let url = details.url;
|
|
||||||
|
|
||||||
// Handle paths that don't start with file://
|
|
||||||
if (!url.startsWith("file://") && url.includes("/assets/")) {
|
|
||||||
url = `file://${path.join(__dirname, "www", url)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle absolute paths starting with /assets/
|
|
||||||
if (url.includes("/assets/") && !url.includes("/www/assets/")) {
|
|
||||||
const baseDir = url.includes("dist-electron")
|
|
||||||
? url.substring(
|
|
||||||
0,
|
|
||||||
url.indexOf("/dist-electron") + "/dist-electron".length,
|
|
||||||
)
|
|
||||||
: `file://${__dirname}`;
|
|
||||||
const assetPath = url.split("/assets/")[1];
|
|
||||||
const newUrl = `${baseDir}/www/assets/${assetPath}`;
|
|
||||||
callback({ redirectURL: newUrl });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
callback({}); // No redirect for other URLs
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDev) {
|
|
||||||
// Debug info
|
|
||||||
logger.log("Debug Info:");
|
|
||||||
logger.log("Running in dev mode:", isDev);
|
|
||||||
logger.log("App is packaged:", app.isPackaged);
|
|
||||||
logger.log("Process resource path:", process.resourcesPath);
|
|
||||||
logger.log("App path:", app.getAppPath());
|
|
||||||
logger.log("__dirname:", __dirname);
|
|
||||||
logger.log("process.cwd():", process.cwd());
|
|
||||||
}
|
|
||||||
|
|
||||||
const indexPath = path.join(__dirname, "www", "index.html");
|
|
||||||
|
|
||||||
if (isDev) {
|
|
||||||
logger.log("Loading index from:", indexPath);
|
|
||||||
logger.log("www path:", path.join(__dirname, "www"));
|
|
||||||
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(indexPath)) {
|
|
||||||
logger.error(`Index file not found at: ${indexPath}`);
|
|
||||||
throw new Error("Index file not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add CSP headers to allow API connections
|
|
||||||
mainWindow.webContents.session.webRequest.onHeadersReceived(
|
|
||||||
(details, callback) => {
|
|
||||||
callback({
|
|
||||||
responseHeaders: {
|
|
||||||
...details.responseHeaders,
|
|
||||||
"Content-Security-Policy": [
|
|
||||||
"default-src 'self';" +
|
|
||||||
"connect-src 'self' https://api.endorser.ch https://*.timesafari.app;" +
|
|
||||||
"img-src 'self' data: https: blob:;" +
|
|
||||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval';" +
|
|
||||||
"style-src 'self' 'unsafe-inline';" +
|
|
||||||
"font-src 'self' data:;",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load the index.html
|
|
||||||
mainWindow
|
|
||||||
.loadFile(indexPath)
|
|
||||||
.then(() => {
|
|
||||||
logger.log("Successfully loaded index.html");
|
|
||||||
if (isDev) {
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
logger.log("DevTools opened - running in dev mode");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error("Failed to load index.html:", err);
|
|
||||||
logger.error("Attempted path:", indexPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for console messages from the renderer
|
|
||||||
mainWindow.webContents.on("console-message", (_event, level, message) => {
|
|
||||||
logger.log("Renderer Console:", message);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add right after creating the BrowserWindow
|
|
||||||
mainWindow.webContents.on(
|
|
||||||
"did-fail-load",
|
|
||||||
(event, errorCode, errorDescription) => {
|
|
||||||
logger.error("Page failed to load:", errorCode, errorDescription);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
mainWindow.webContents.on("preload-error", (event, preloadPath, error) => {
|
|
||||||
logger.error("Preload script error:", preloadPath, error);
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindow.webContents.on(
|
|
||||||
"console-message",
|
|
||||||
(event, level, message, line, sourceId) => {
|
|
||||||
logger.log("Renderer Console:", line, sourceId, message);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable remote debugging when in dev mode
|
|
||||||
if (isDev) {
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle app ready
|
|
||||||
app.whenReady().then(createWindow);
|
|
||||||
|
|
||||||
// Handle all windows closed
|
|
||||||
app.on("window-all-closed", () => {
|
|
||||||
if (process.platform !== "darwin") {
|
|
||||||
app.quit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on("activate", () => {
|
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
|
||||||
createWindow();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle any errors
|
|
||||||
process.on("uncaughtException", (error) => {
|
|
||||||
logger.error("Uncaught Exception:", error);
|
|
||||||
});
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
import { app, BrowserWindow } from "electron";
|
|
||||||
import path from "path";
|
|
||||||
import fs from "fs";
|
|
||||||
|
|
||||||
// Simple logger implementation
|
|
||||||
const logger = {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
log: (...args: unknown[]) => console.log(...args),
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
error: (...args: unknown[]) => console.error(...args),
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
info: (...args: unknown[]) => console.info(...args),
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
warn: (...args: unknown[]) => console.warn(...args),
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
debug: (...args: unknown[]) => console.debug(...args),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if running in dev mode
|
|
||||||
const isDev = process.argv.includes("--inspect");
|
|
||||||
|
|
||||||
async function createWindow(): Promise<void> {
|
|
||||||
// Add before createWindow function
|
|
||||||
const preloadPath = app.isPackaged
|
|
||||||
? path.join(app.getAppPath(), "dist-electron", "preload.js")
|
|
||||||
: path.join(__dirname, "preload.js");
|
|
||||||
logger.log("Checking preload path:", preloadPath);
|
|
||||||
logger.log("Preload exists:", fs.existsSync(preloadPath));
|
|
||||||
|
|
||||||
// Log environment and paths
|
|
||||||
logger.log("process.cwd():", process.cwd());
|
|
||||||
logger.log("__dirname:", __dirname);
|
|
||||||
logger.log("app.getAppPath():", app.getAppPath());
|
|
||||||
logger.log("app.isPackaged:", app.isPackaged);
|
|
||||||
|
|
||||||
// List files in __dirname and __dirname/www
|
|
||||||
try {
|
|
||||||
logger.log("Files in __dirname:", fs.readdirSync(__dirname));
|
|
||||||
const wwwDir = path.join(__dirname, "www");
|
|
||||||
if (fs.existsSync(wwwDir)) {
|
|
||||||
logger.log("Files in www:", fs.readdirSync(wwwDir));
|
|
||||||
} else {
|
|
||||||
logger.log("www directory does not exist in __dirname");
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
logger.error("Error reading directories:", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the browser window.
|
|
||||||
const mainWindow = new BrowserWindow({
|
|
||||||
width: 1200,
|
|
||||||
height: 800,
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: false,
|
|
||||||
contextIsolation: true,
|
|
||||||
webSecurity: true,
|
|
||||||
allowRunningInsecureContent: false,
|
|
||||||
preload: preloadPath,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Always open DevTools for now
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
|
|
||||||
// Intercept requests to robustly fix asset paths for Electron
|
|
||||||
mainWindow.webContents.session.webRequest.onBeforeRequest(
|
|
||||||
{ urls: ["*://*/*"] },
|
|
||||||
(details, callback) => {
|
|
||||||
const url = details.url;
|
|
||||||
logger.log('[main.ts] Intercepted request:', url);
|
|
||||||
|
|
||||||
// Match both file:///assets/... and /assets/...
|
|
||||||
const assetMatch = url.match(/(?:file:\/\/\/|file:\/\/|https?:\/\/[^\/]+)?\/assets\/(.+)/);
|
|
||||||
if (assetMatch) {
|
|
||||||
const assetRelPath = assetMatch[1];
|
|
||||||
const assetAbsPath = path.join(app.getAppPath(), "dist-electron", "www", "assets", assetRelPath);
|
|
||||||
logger.log('[main.ts] Asset request detected:', {
|
|
||||||
originalUrl: url,
|
|
||||||
assetRelPath,
|
|
||||||
assetAbsPath,
|
|
||||||
exists: fs.existsSync(assetAbsPath)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (fs.existsSync(assetAbsPath)) {
|
|
||||||
const newUrl = `file://${assetAbsPath}`;
|
|
||||||
logger.log('[main.ts] Redirecting to:', newUrl);
|
|
||||||
callback({ redirectURL: newUrl });
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
logger.error('[main.ts] Asset file not found:', assetAbsPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback({});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDev) {
|
|
||||||
// Debug info
|
|
||||||
logger.log("Debug Info:");
|
|
||||||
logger.log("Running in dev mode:", isDev);
|
|
||||||
logger.log("App is packaged:", app.isPackaged);
|
|
||||||
logger.log("Process resource path:", process.resourcesPath);
|
|
||||||
logger.log("App path:", app.getAppPath());
|
|
||||||
logger.log("__dirname:", __dirname);
|
|
||||||
logger.log("process.cwd():", process.cwd());
|
|
||||||
}
|
|
||||||
|
|
||||||
let indexPath: string;
|
|
||||||
if (app.isPackaged) {
|
|
||||||
indexPath = path.join(
|
|
||||||
app.getAppPath(),
|
|
||||||
"dist-electron",
|
|
||||||
"www",
|
|
||||||
"index.html",
|
|
||||||
);
|
|
||||||
logger.log("[main.ts] Using packaged indexPath:", indexPath);
|
|
||||||
} else {
|
|
||||||
indexPath = path.resolve(
|
|
||||||
process.cwd(),
|
|
||||||
"dist-electron",
|
|
||||||
"www",
|
|
||||||
"index.html",
|
|
||||||
);
|
|
||||||
logger.log("[main.ts] Using dev indexPath:", indexPath);
|
|
||||||
if (!fs.existsSync(indexPath)) {
|
|
||||||
logger.error("[main.ts] Dev index.html not found:", indexPath);
|
|
||||||
throw new Error("Index file not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDev) {
|
|
||||||
logger.log("Loading index from:", indexPath);
|
|
||||||
logger.log("www path:", path.join(__dirname, "www"));
|
|
||||||
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add CSP headers to allow API connections
|
|
||||||
mainWindow.webContents.session.webRequest.onHeadersReceived(
|
|
||||||
(details, callback) => {
|
|
||||||
callback({
|
|
||||||
responseHeaders: {
|
|
||||||
...details.responseHeaders,
|
|
||||||
"Content-Security-Policy": [
|
|
||||||
"default-src 'self';" +
|
|
||||||
"connect-src 'self' https://api.endorser.ch https://*.timesafari.app;" +
|
|
||||||
"img-src 'self' data: https: blob:;" +
|
|
||||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval';" +
|
|
||||||
"style-src 'self' 'unsafe-inline';" +
|
|
||||||
"font-src 'self' data:;",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load the index.html with the correct base URL for assets
|
|
||||||
const baseURL = `file://${path.dirname(indexPath)}/`;
|
|
||||||
logger.log('[main.ts] Loading with base URL:', baseURL);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await mainWindow.loadURL(`file://${indexPath}`);
|
|
||||||
logger.log("Successfully loaded index.html");
|
|
||||||
if (isDev) {
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
logger.log("DevTools opened - running in dev mode");
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("Failed to load index.html:", err);
|
|
||||||
logger.error("Attempted path:", indexPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for console messages from the renderer
|
|
||||||
mainWindow.webContents.on("console-message", (_event, _level, message) => {
|
|
||||||
logger.log("Renderer Console:", message);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add right after creating the BrowserWindow
|
|
||||||
mainWindow.webContents.on(
|
|
||||||
"did-fail-load",
|
|
||||||
(_event, errorCode, errorDescription) => {
|
|
||||||
logger.error("Page failed to load:", errorCode, errorDescription);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
mainWindow.webContents.on("preload-error", (_event, preloadPath, error) => {
|
|
||||||
logger.error("Preload script error:", preloadPath, error);
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindow.webContents.on(
|
|
||||||
"console-message",
|
|
||||||
(_event, _level, message, line, sourceId) => {
|
|
||||||
logger.log("Renderer Console:", line, sourceId, message);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable remote debugging when in dev mode
|
|
||||||
if (isDev) {
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle app ready
|
|
||||||
app.whenReady().then(createWindow);
|
|
||||||
|
|
||||||
// Handle all windows closed
|
|
||||||
app.on("window-all-closed", () => {
|
|
||||||
if (process.platform !== "darwin") {
|
|
||||||
app.quit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on("activate", () => {
|
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
|
||||||
createWindow();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle any errors
|
|
||||||
process.on("uncaughtException", (error) => {
|
|
||||||
logger.error("Uncaught Exception:", error);
|
|
||||||
});
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
const { contextBridge, ipcRenderer } = require("electron");
|
|
||||||
|
|
||||||
const logger = {
|
|
||||||
log: (message, ...args) => {
|
|
||||||
// Always log in development, log with context in production
|
|
||||||
if (process.env.NODE_ENV !== "production") {
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.log(`[Preload] ${message}`, ...args);
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
}
|
|
||||||
},
|
|
||||||
warn: (message, ...args) => {
|
|
||||||
// Always log warnings
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.warn(`[Preload] ${message}`, ...args);
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
},
|
|
||||||
error: (message, ...args) => {
|
|
||||||
// Always log errors
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.error(`[Preload] ${message}`, ...args);
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
},
|
|
||||||
info: (message, ...args) => {
|
|
||||||
// Always log info in development, log with context in production
|
|
||||||
if (process.env.NODE_ENV !== "production") {
|
|
||||||
/* eslint-disable no-console */
|
|
||||||
console.info(`[Preload] ${message}`, ...args);
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use a more direct path resolution approach
|
|
||||||
const getPath = (pathType) => {
|
|
||||||
switch (pathType) {
|
|
||||||
case "userData":
|
|
||||||
return (
|
|
||||||
process.env.APPDATA ||
|
|
||||||
(process.platform === "darwin"
|
|
||||||
? `${process.env.HOME}/Library/Application Support`
|
|
||||||
: `${process.env.HOME}/.local/share`)
|
|
||||||
);
|
|
||||||
case "home":
|
|
||||||
return process.env.HOME;
|
|
||||||
case "appPath":
|
|
||||||
return process.resourcesPath;
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
logger.info("Preload script starting...");
|
|
||||||
|
|
||||||
// Force electron platform in the renderer process
|
|
||||||
window.process = { env: { VITE_PLATFORM: "electron" } };
|
|
||||||
|
|
||||||
try {
|
|
||||||
contextBridge.exposeInMainWorld("electronAPI", {
|
|
||||||
// Path utilities
|
|
||||||
getPath,
|
|
||||||
|
|
||||||
// IPC functions
|
|
||||||
send: (channel, data) => {
|
|
||||||
const validChannels = ["toMain"];
|
|
||||||
if (validChannels.includes(channel)) {
|
|
||||||
ipcRenderer.send(channel, data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
receive: (channel, func) => {
|
|
||||||
const validChannels = ["fromMain"];
|
|
||||||
if (validChannels.includes(channel)) {
|
|
||||||
ipcRenderer.on(channel, (event, ...args) => func(...args));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Environment info
|
|
||||||
env: {
|
|
||||||
isElectron: true,
|
|
||||||
isDev: process.env.NODE_ENV === "development",
|
|
||||||
platform: "electron", // Explicitly set platform
|
|
||||||
},
|
|
||||||
// Path utilities
|
|
||||||
getBasePath: () => {
|
|
||||||
return process.env.NODE_ENV === "development" ? "/" : "./";
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.info("Preload script completed successfully");
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Error in preload script:", error);
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import './assets/styles/tailwind.css';
|
|
||||||
import { initializeApp } from "./main.common";
|
|
||||||
import { logger } from "./utils/logger";
|
|
||||||
|
|
||||||
const platform = process.env.VITE_PLATFORM;
|
|
||||||
const pwa_enabled = process.env.VITE_PWA_ENABLED === "true";
|
|
||||||
|
|
||||||
logger.info("[Electron] Initializing app");
|
|
||||||
logger.info("[Electron] Platform:", { platform });
|
|
||||||
logger.info("[Electron] PWA enabled:", { pwa_enabled });
|
|
||||||
|
|
||||||
if (pwa_enabled) {
|
|
||||||
logger.warn("[Electron] PWA is enabled, but not supported in electron");
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = initializeApp();
|
|
||||||
app.mount("#app");
|
|
||||||
@@ -6,7 +6,7 @@ const platform = process.env.VITE_PLATFORM;
|
|||||||
const pwa_enabled = process.env.VITE_PWA_ENABLED === "true";
|
const pwa_enabled = process.env.VITE_PWA_ENABLED === "true";
|
||||||
|
|
||||||
// Only import service worker for web builds
|
// Only import service worker for web builds
|
||||||
if (platform !== "electron" && pwa_enabled) {
|
if (pwa_enabled) {
|
||||||
import("./registerServiceWorker"); // Web PWA support
|
import("./registerServiceWorker"); // Web PWA support
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,10 @@
|
|||||||
|
|
||||||
import { register } from "register-service-worker";
|
import { register } from "register-service-worker";
|
||||||
|
|
||||||
// Check if we're in an Electron environment
|
|
||||||
const isElectron =
|
|
||||||
process.env.VITE_PLATFORM === "electron" ||
|
|
||||||
process.env.VITE_DISABLE_PWA === "true" ||
|
|
||||||
window.navigator.userAgent.toLowerCase().includes("electron");
|
|
||||||
|
|
||||||
// Only register service worker if:
|
// Only register service worker if:
|
||||||
// 1. Not in Electron
|
// 1. PWA is explicitly enabled
|
||||||
// 2. PWA is explicitly enabled
|
// 2. In production mode
|
||||||
// 3. In production mode
|
|
||||||
if (
|
if (
|
||||||
!isElectron &&
|
|
||||||
process.env.VITE_PWA_ENABLED === "true" &&
|
process.env.VITE_PWA_ENABLED === "true" &&
|
||||||
process.env.NODE_ENV === "production"
|
process.env.NODE_ENV === "production"
|
||||||
) {
|
) {
|
||||||
@@ -45,11 +37,9 @@ if (
|
|||||||
} else {
|
} else {
|
||||||
console.log(
|
console.log(
|
||||||
`Service worker registration skipped - ${
|
`Service worker registration skipped - ${
|
||||||
isElectron
|
process.env.VITE_PWA_ENABLED !== "true"
|
||||||
? "running in Electron"
|
? "PWA not enabled"
|
||||||
: process.env.VITE_PWA_ENABLED !== "true"
|
: "not in production mode"
|
||||||
? "PWA not enabled"
|
|
||||||
: "not in production mode"
|
|
||||||
}`,
|
}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,14 +277,9 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const isElectron = window.location.protocol === "file:";
|
const initialPath = window.location.pathname;
|
||||||
const initialPath = isElectron
|
|
||||||
? window.location.pathname.split("/dist-electron/www/")[1] || "/"
|
|
||||||
: window.location.pathname;
|
|
||||||
|
|
||||||
const history = isElectron
|
const history = createWebHistory("/"); // Add base path for web apps
|
||||||
? createMemoryHistory() // Memory history for Electron
|
|
||||||
: createWebHistory("/"); // Add base path for web apps
|
|
||||||
|
|
||||||
/** @type {*} */
|
/** @type {*} */
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { PlatformService } from "./PlatformService";
|
import { PlatformService } from "./PlatformService";
|
||||||
import { WebPlatformService } from "./platforms/WebPlatformService";
|
import { WebPlatformService } from "./platforms/WebPlatformService";
|
||||||
import { CapacitorPlatformService } from "./platforms/CapacitorPlatformService";
|
import { CapacitorPlatformService } from "./platforms/CapacitorPlatformService";
|
||||||
import { ElectronPlatformService } from "./platforms/ElectronPlatformService";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory class for creating platform-specific service implementations.
|
* Factory class for creating platform-specific service implementations.
|
||||||
@@ -10,7 +9,6 @@ import { ElectronPlatformService } from "./platforms/ElectronPlatformService";
|
|||||||
* The factory determines which platform implementation to use based on the VITE_PLATFORM
|
* The factory determines which platform implementation to use based on the VITE_PLATFORM
|
||||||
* environment variable. Supported platforms are:
|
* environment variable. Supported platforms are:
|
||||||
* - capacitor: Mobile platform using Capacitor
|
* - capacitor: Mobile platform using Capacitor
|
||||||
* - electron: Desktop platform using Electron
|
|
||||||
* - web: Default web platform (fallback)
|
* - web: Default web platform (fallback)
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
@@ -39,9 +37,6 @@ export class PlatformServiceFactory {
|
|||||||
case "capacitor":
|
case "capacitor":
|
||||||
PlatformServiceFactory.instance = new CapacitorPlatformService();
|
PlatformServiceFactory.instance = new CapacitorPlatformService();
|
||||||
break;
|
break;
|
||||||
case "electron":
|
|
||||||
PlatformServiceFactory.instance = new ElectronPlatformService();
|
|
||||||
break;
|
|
||||||
case "web":
|
case "web":
|
||||||
default:
|
default:
|
||||||
PlatformServiceFactory.instance = new WebPlatformService();
|
PlatformServiceFactory.instance = new WebPlatformService();
|
||||||
|
|||||||
@@ -244,13 +244,15 @@ export class CapacitorPlatformService implements PlatformService {
|
|||||||
* @returns Platform capabilities object
|
* @returns Platform capabilities object
|
||||||
*/
|
*/
|
||||||
getCapabilities(): PlatformCapabilities {
|
getCapabilities(): PlatformCapabilities {
|
||||||
|
const platform = Capacitor.getPlatform();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasFileSystem: true,
|
hasFileSystem: true,
|
||||||
hasCamera: true,
|
hasCamera: true,
|
||||||
isMobile: true,
|
isMobile: true, // Capacitor is always mobile
|
||||||
isIOS: Capacitor.getPlatform() === "ios",
|
isIOS: platform === "ios",
|
||||||
hasFileDownload: false,
|
hasFileDownload: false, // Mobile platforms need sharing
|
||||||
needsFileHandlingInstructions: true,
|
needsFileHandlingInstructions: true, // Mobile needs instructions
|
||||||
isNativeApp: true,
|
isNativeApp: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,358 +0,0 @@
|
|||||||
import {
|
|
||||||
ImageResult,
|
|
||||||
PlatformService,
|
|
||||||
PlatformCapabilities,
|
|
||||||
} from "../PlatformService";
|
|
||||||
import { logger } from "../../utils/logger";
|
|
||||||
import { QueryExecResult, SqlValue } from "@/interfaces/database";
|
|
||||||
import {
|
|
||||||
SQLiteConnection,
|
|
||||||
SQLiteDBConnection,
|
|
||||||
CapacitorSQLite,
|
|
||||||
Changes,
|
|
||||||
} from "@capacitor-community/sqlite";
|
|
||||||
import { DEFAULT_ENDORSER_API_SERVER } from "@/constants/app";
|
|
||||||
|
|
||||||
interface Migration {
|
|
||||||
name: string;
|
|
||||||
sql: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Platform service implementation for Electron (desktop) platform.
|
|
||||||
* Provides native desktop functionality through Electron and Capacitor plugins for:
|
|
||||||
* - File system operations (TODO)
|
|
||||||
* - Camera integration (TODO)
|
|
||||||
* - SQLite database operations
|
|
||||||
* - System-level features (TODO)
|
|
||||||
*/
|
|
||||||
export class ElectronPlatformService implements PlatformService {
|
|
||||||
private sqlite: SQLiteConnection;
|
|
||||||
private db: SQLiteDBConnection | null = null;
|
|
||||||
private dbName = "timesafari.db";
|
|
||||||
private initialized = false;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.sqlite = new SQLiteConnection(CapacitorSQLite);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async initializeDatabase(): Promise<void> {
|
|
||||||
if (this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Create/Open database
|
|
||||||
this.db = await this.sqlite.createConnection(
|
|
||||||
this.dbName,
|
|
||||||
false,
|
|
||||||
"no-encryption",
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.db.open();
|
|
||||||
|
|
||||||
// Set journal mode to WAL for better performance
|
|
||||||
await this.db.execute("PRAGMA journal_mode=WAL;");
|
|
||||||
|
|
||||||
// Run migrations
|
|
||||||
await this.runMigrations();
|
|
||||||
|
|
||||||
this.initialized = true;
|
|
||||||
logger.log(
|
|
||||||
"[ElectronPlatformService] SQLite database initialized successfully",
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(
|
|
||||||
"[ElectronPlatformService] Error initializing SQLite database:",
|
|
||||||
error,
|
|
||||||
);
|
|
||||||
throw new Error(
|
|
||||||
"[ElectronPlatformService] Failed to initialize database",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async runMigrations(): Promise<void> {
|
|
||||||
if (!this.db) {
|
|
||||||
throw new Error("Database not initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create migrations table if it doesn't exist
|
|
||||||
await this.db.execute(`
|
|
||||||
CREATE TABLE IF NOT EXISTS migrations (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
name TEXT NOT NULL UNIQUE,
|
|
||||||
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
`);
|
|
||||||
|
|
||||||
// Get list of executed migrations
|
|
||||||
const result = await this.db.query("SELECT name FROM migrations;");
|
|
||||||
const executedMigrations = new Set(
|
|
||||||
result.values?.map((row) => row[0]) || [],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Run pending migrations in order
|
|
||||||
const migrations: Migration[] = [
|
|
||||||
{
|
|
||||||
name: "001_initial",
|
|
||||||
sql: `
|
|
||||||
CREATE TABLE IF NOT EXISTS accounts (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
dateCreated TEXT NOT NULL,
|
|
||||||
derivationPath TEXT,
|
|
||||||
did TEXT NOT NULL,
|
|
||||||
identityEncrBase64 TEXT,
|
|
||||||
mnemonicEncrBase64 TEXT,
|
|
||||||
passkeyCredIdHex TEXT,
|
|
||||||
publicKeyHex TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_accounts_did ON accounts(did);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS secret (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
secretBase64 TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS settings (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
accountDid TEXT,
|
|
||||||
activeDid TEXT,
|
|
||||||
apiServer TEXT,
|
|
||||||
filterFeedByNearby BOOLEAN,
|
|
||||||
filterFeedByVisible BOOLEAN,
|
|
||||||
finishedOnboarding BOOLEAN,
|
|
||||||
firstName TEXT,
|
|
||||||
hideRegisterPromptOnNewContact BOOLEAN,
|
|
||||||
isRegistered BOOLEAN,
|
|
||||||
lastName TEXT,
|
|
||||||
lastAckedOfferToUserJwtId TEXT,
|
|
||||||
lastAckedOfferToUserProjectsJwtId TEXT,
|
|
||||||
lastNotifiedClaimId TEXT,
|
|
||||||
lastViewedClaimId TEXT,
|
|
||||||
notifyingNewActivityTime TEXT,
|
|
||||||
notifyingReminderMessage TEXT,
|
|
||||||
notifyingReminderTime TEXT,
|
|
||||||
partnerApiServer TEXT,
|
|
||||||
passkeyExpirationMinutes INTEGER,
|
|
||||||
profileImageUrl TEXT,
|
|
||||||
searchBoxes TEXT,
|
|
||||||
showContactGivesInline BOOLEAN,
|
|
||||||
showGeneralAdvanced BOOLEAN,
|
|
||||||
showShortcutBvc BOOLEAN,
|
|
||||||
vapid TEXT,
|
|
||||||
warnIfProdServer BOOLEAN,
|
|
||||||
warnIfTestServer BOOLEAN,
|
|
||||||
webPushServer TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_settings_accountDid ON settings(accountDid);
|
|
||||||
|
|
||||||
INSERT INTO settings (id, apiServer) VALUES (1, '${DEFAULT_ENDORSER_API_SERVER}');
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS contacts (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
did TEXT NOT NULL,
|
|
||||||
name TEXT,
|
|
||||||
contactMethods TEXT,
|
|
||||||
nextPubKeyHashB64 TEXT,
|
|
||||||
notes TEXT,
|
|
||||||
profileImageUrl TEXT,
|
|
||||||
publicKeyBase64 TEXT,
|
|
||||||
seesMe BOOLEAN,
|
|
||||||
registered BOOLEAN
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_contacts_did ON contacts(did);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(name);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS logs (
|
|
||||||
date TEXT PRIMARY KEY,
|
|
||||||
message TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS temp (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
blobB64 TEXT
|
|
||||||
);
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const migration of migrations) {
|
|
||||||
if (!executedMigrations.has(migration.name)) {
|
|
||||||
await this.db.execute(migration.sql);
|
|
||||||
await this.db.run("INSERT INTO migrations (name) VALUES (?)", [
|
|
||||||
migration.name,
|
|
||||||
]);
|
|
||||||
logger.log(`Migration ${migration.name} executed successfully`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the capabilities of the Electron platform
|
|
||||||
* @returns Platform capabilities object
|
|
||||||
*/
|
|
||||||
getCapabilities(): PlatformCapabilities {
|
|
||||||
return {
|
|
||||||
hasFileSystem: false, // Not implemented yet
|
|
||||||
hasCamera: false, // Not implemented yet
|
|
||||||
isMobile: false,
|
|
||||||
isIOS: false,
|
|
||||||
hasFileDownload: false, // Not implemented yet
|
|
||||||
needsFileHandlingInstructions: false,
|
|
||||||
isNativeApp: true, // Electron is a native app
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a file from the filesystem.
|
|
||||||
* @param _path - Path to the file to read
|
|
||||||
* @returns Promise that should resolve to file contents
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement file reading using Electron's file system API
|
|
||||||
*/
|
|
||||||
async readFile(_path: string): Promise<string> {
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes content to a file.
|
|
||||||
* @param _path - Path where to write the file
|
|
||||||
* @param _content - Content to write to the file
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement file writing using Electron's file system API
|
|
||||||
*/
|
|
||||||
async writeFile(_path: string, _content: string): Promise<void> {
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes content to a file and opens the system share dialog.
|
|
||||||
* @param _fileName - Name of the file to create
|
|
||||||
* @param _content - Content to write to the file
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement using Electron's dialog and file system APIs
|
|
||||||
*/
|
|
||||||
async writeAndShareFile(_fileName: string, _content: string): Promise<void> {
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a file from the filesystem.
|
|
||||||
* @param _path - Path to the file to delete
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement file deletion using Electron's file system API
|
|
||||||
*/
|
|
||||||
async deleteFile(_path: string): Promise<void> {
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lists files in the specified directory.
|
|
||||||
* @param _directory - Path to the directory to list
|
|
||||||
* @returns Promise that should resolve to array of filenames
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement directory listing using Electron's file system API
|
|
||||||
*/
|
|
||||||
async listFiles(_directory: string): Promise<string[]> {
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should open system camera to take a picture.
|
|
||||||
* @returns Promise that should resolve to captured image data
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement camera access using Electron's media APIs
|
|
||||||
*/
|
|
||||||
async takePicture(): Promise<ImageResult> {
|
|
||||||
logger.error("takePicture not implemented in Electron platform");
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should open system file picker for selecting an image.
|
|
||||||
* @returns Promise that should resolve to selected image data
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement file picker using Electron's dialog API
|
|
||||||
*/
|
|
||||||
async pickImage(): Promise<ImageResult> {
|
|
||||||
logger.error("pickImage not implemented in Electron platform");
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should handle deep link URLs for the desktop application.
|
|
||||||
* @param _url - The deep link URL to handle
|
|
||||||
* @throws Error with "Not implemented" message
|
|
||||||
* @todo Implement deep link handling using Electron's protocol handler
|
|
||||||
*/
|
|
||||||
async handleDeepLink(_url: string): Promise<void> {
|
|
||||||
logger.error("handleDeepLink not implemented in Electron platform");
|
|
||||||
throw new Error("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see PlatformService.dbQuery
|
|
||||||
*/
|
|
||||||
async dbQuery(sql: string, params?: unknown[]): Promise<QueryExecResult> {
|
|
||||||
await this.initializeDatabase();
|
|
||||||
if (!this.db) {
|
|
||||||
throw new Error("Database not initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await this.db.query(sql, params || []);
|
|
||||||
const values = result.values || [];
|
|
||||||
return {
|
|
||||||
columns: [], // SQLite plugin doesn't provide column names in query result
|
|
||||||
values: values as SqlValue[][],
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Error executing query:", error);
|
|
||||||
throw new Error(
|
|
||||||
`Database query failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see PlatformService.dbExec
|
|
||||||
*/
|
|
||||||
async dbExec(
|
|
||||||
sql: string,
|
|
||||||
params?: unknown[],
|
|
||||||
): Promise<{ changes: number; lastId?: number }> {
|
|
||||||
await this.initializeDatabase();
|
|
||||||
if (!this.db) {
|
|
||||||
throw new Error("Database not initialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await this.db.run(sql, params || []);
|
|
||||||
const changes = result.changes as Changes;
|
|
||||||
return {
|
|
||||||
changes: changes?.changes || 0,
|
|
||||||
lastId: changes?.lastId,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Error executing statement:", error);
|
|
||||||
throw new Error(
|
|
||||||
`Database execution failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates the camera between front and back cameras.
|
|
||||||
* @returns Promise that resolves when the camera is rotated
|
|
||||||
* @throws Error indicating camera rotation is not implemented in Electron
|
|
||||||
*/
|
|
||||||
async rotateCamera(): Promise<void> {
|
|
||||||
throw new Error("Camera rotation not implemented in Electron platform");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "ESNext",
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"target": "ES2020",
|
|
||||||
"outDir": "dist-electron",
|
|
||||||
"rootDir": "src",
|
|
||||||
"sourceMap": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowJs": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"types": ["vite/client"],
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
},
|
|
||||||
"typeRoots": ["./node_modules/@types", "./src/types"]
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src/**/*.ts",
|
|
||||||
"src/**/*.d.ts",
|
|
||||||
"src/**/*.tsx",
|
|
||||||
"src/**/*.vue"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -13,28 +13,27 @@ const __dirname = path.dirname(__filename);
|
|||||||
|
|
||||||
export async function createBuildConfig(mode: string): Promise<UserConfig> {
|
export async function createBuildConfig(mode: string): Promise<UserConfig> {
|
||||||
const appConfig = await loadAppConfig();
|
const appConfig = await loadAppConfig();
|
||||||
const isElectron = mode === "electron";
|
|
||||||
const isCapacitor = mode === "capacitor";
|
const isCapacitor = mode === "capacitor";
|
||||||
const isNative = isElectron || isCapacitor;
|
const isNative = isCapacitor;
|
||||||
|
|
||||||
// Explicitly set platform and disable PWA for Electron
|
// Set platform and disable PWA for native platforms
|
||||||
process.env.VITE_PLATFORM = mode;
|
process.env.VITE_PLATFORM = mode;
|
||||||
process.env.VITE_PWA_ENABLED = isElectron ? 'false' : 'true';
|
process.env.VITE_PWA_ENABLED = isCapacitor ? 'false' : 'true';
|
||||||
process.env.VITE_DISABLE_PWA = isElectron ? 'true' : 'false';
|
process.env.VITE_DISABLE_PWA = isCapacitor ? 'true' : 'false';
|
||||||
|
|
||||||
if (isElectron || isCapacitor) {
|
if (isCapacitor) {
|
||||||
process.env.VITE_PWA_ENABLED = 'false';
|
process.env.VITE_PWA_ENABLED = 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
base: isElectron ? "./" : "/",
|
base: "/",
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
server: {
|
server: {
|
||||||
port: parseInt(process.env.VITE_PORT || "8080"),
|
port: parseInt(process.env.VITE_PORT || "8080"),
|
||||||
fs: { strict: false },
|
fs: { strict: false },
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: isElectron ? "dist-electron" : "dist",
|
outDir: "dist",
|
||||||
assetsDir: 'assets',
|
assetsDir: 'assets',
|
||||||
chunkSizeWarningLimit: 1000,
|
chunkSizeWarningLimit: 1000,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
@@ -57,9 +56,9 @@ export async function createBuildConfig(mode: string): Promise<UserConfig> {
|
|||||||
define: {
|
define: {
|
||||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||||
'process.env.VITE_PLATFORM': JSON.stringify(mode),
|
'process.env.VITE_PLATFORM': JSON.stringify(mode),
|
||||||
'process.env.VITE_PWA_ENABLED': JSON.stringify(!isElectron),
|
'process.env.VITE_PWA_ENABLED': JSON.stringify(!isCapacitor),
|
||||||
'process.env.VITE_DISABLE_PWA': JSON.stringify(isElectron),
|
'process.env.VITE_DISABLE_PWA': JSON.stringify(isCapacitor),
|
||||||
__dirname: isElectron ? JSON.stringify(process.cwd()) : '""',
|
__dirname: JSON.stringify(process.cwd()),
|
||||||
__IS_MOBILE__: JSON.stringify(isCapacitor),
|
__IS_MOBILE__: JSON.stringify(isCapacitor),
|
||||||
__USE_QR_READER__: JSON.stringify(!isCapacitor),
|
__USE_QR_READER__: JSON.stringify(!isCapacitor),
|
||||||
'process.platform': JSON.stringify('browser'),
|
'process.platform': JSON.stringify('browser'),
|
||||||
@@ -88,7 +87,7 @@ export async function createBuildConfig(mode: string): Promise<UserConfig> {
|
|||||||
'@nostr/tools',
|
'@nostr/tools',
|
||||||
'@nostr/tools/nip06',
|
'@nostr/tools/nip06',
|
||||||
],
|
],
|
||||||
exclude: isElectron ? [
|
exclude: isCapacitor ? [
|
||||||
'register-service-worker',
|
'register-service-worker',
|
||||||
'workbox-window',
|
'workbox-window',
|
||||||
'web-push',
|
'web-push',
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
import { defineConfig, mergeConfig } from "vite";
|
|
||||||
import { createBuildConfig } from "./vite.config.common.mts";
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
export default defineConfig(async () => {
|
|
||||||
const baseConfig = await createBuildConfig('electron');
|
|
||||||
|
|
||||||
return mergeConfig(baseConfig, {
|
|
||||||
build: {
|
|
||||||
outDir: 'dist-electron',
|
|
||||||
rollupOptions: {
|
|
||||||
input: {
|
|
||||||
// Main process entry points
|
|
||||||
main: path.resolve(__dirname, 'src/electron/main.ts'),
|
|
||||||
preload: path.resolve(__dirname, 'src/electron/preload.js'),
|
|
||||||
// Renderer process entry point (the web app)
|
|
||||||
app: path.resolve(__dirname, 'index.html'),
|
|
||||||
},
|
|
||||||
external: ['electron'],
|
|
||||||
output: {
|
|
||||||
format: 'cjs',
|
|
||||||
entryFileNames: (chunkInfo) => {
|
|
||||||
// Use different formats for main process vs renderer
|
|
||||||
if (chunkInfo.name === 'main' || chunkInfo.name === 'preload') {
|
|
||||||
return '[name].js';
|
|
||||||
}
|
|
||||||
return 'assets/[name].[hash].js';
|
|
||||||
},
|
|
||||||
assetFileNames: (assetInfo) => {
|
|
||||||
// Keep main process files in root, others in assets
|
|
||||||
if (assetInfo.name === 'main.js' || assetInfo.name === 'preload.js') {
|
|
||||||
return '[name].[ext]';
|
|
||||||
}
|
|
||||||
return 'assets/[name].[hash].[ext]';
|
|
||||||
},
|
|
||||||
chunkFileNames: 'assets/[name].[hash].js',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
target: 'node18',
|
|
||||||
minify: false,
|
|
||||||
sourcemap: true,
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, 'src'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
optimizeDeps: {
|
|
||||||
include: ['@/utils/logger']
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
{
|
|
||||||
name: 'typescript-transform',
|
|
||||||
transform(code: string, id: string) {
|
|
||||||
if (id.endsWith('main.ts')) {
|
|
||||||
// Replace the logger import with inline logger
|
|
||||||
return code.replace(
|
|
||||||
/import\s*{\s*logger\s*}\s*from\s*['"]@\/utils\/logger['"];?/,
|
|
||||||
`const logger = {
|
|
||||||
log: (...args) => console.log(...args),
|
|
||||||
error: (...args) => console.error(...args),
|
|
||||||
info: (...args) => console.info(...args),
|
|
||||||
warn: (...args) => console.warn(...args),
|
|
||||||
debug: (...args) => console.debug(...args),
|
|
||||||
};`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'remove-sw-imports',
|
|
||||||
transform(code: string, id: string) {
|
|
||||||
// Remove service worker imports and registrations
|
|
||||||
if (id.includes('registerServiceWorker') ||
|
|
||||||
id.includes('register-service-worker') ||
|
|
||||||
id.includes('sw_scripts') ||
|
|
||||||
id.includes('PushNotificationPermission') ||
|
|
||||||
code.includes('navigator.serviceWorker')) {
|
|
||||||
return {
|
|
||||||
code: code
|
|
||||||
.replace(/import.*registerServiceWorker.*$/mg, '')
|
|
||||||
.replace(/import.*register-service-worker.*$/mg, '')
|
|
||||||
.replace(/navigator\.serviceWorker/g, 'undefined')
|
|
||||||
.replace(/if\s*\([^)]*serviceWorker[^)]*\)\s*{[^}]*}/g, '')
|
|
||||||
.replace(/import.*workbox.*$/mg, '')
|
|
||||||
.replace(/importScripts\([^)]*\)/g, '')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'remove-sw-files',
|
|
||||||
enforce: 'pre',
|
|
||||||
resolveId(id: string) {
|
|
||||||
// Prevent service worker files from being included
|
|
||||||
if (id.includes('sw.js') ||
|
|
||||||
id.includes('workbox') ||
|
|
||||||
id.includes('registerSW.js') ||
|
|
||||||
id.includes('manifest.webmanifest')) {
|
|
||||||
return '\0empty';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
load(id: string) {
|
|
||||||
if (id === '\0empty') {
|
|
||||||
return 'export default {}';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'electron-css-injection',
|
|
||||||
enforce: 'post',
|
|
||||||
generateBundle(options, bundle) {
|
|
||||||
// Find the main CSS file
|
|
||||||
const cssAsset = Object.values(bundle).find(
|
|
||||||
(asset: any) => asset.type === 'asset' && asset.fileName?.endsWith('.css')
|
|
||||||
) as any;
|
|
||||||
|
|
||||||
if (cssAsset) {
|
|
||||||
// Find the HTML file and inject CSS link
|
|
||||||
const htmlAsset = Object.values(bundle).find(
|
|
||||||
(asset: any) => asset.type === 'asset' && asset.fileName?.endsWith('.html')
|
|
||||||
) as any;
|
|
||||||
|
|
||||||
if (htmlAsset) {
|
|
||||||
const cssHref = `./${cssAsset.fileName}`;
|
|
||||||
const cssLink = ` <link rel="stylesheet" href="${cssHref}">\n`;
|
|
||||||
|
|
||||||
// Check if CSS link already exists
|
|
||||||
if (!htmlAsset.source.includes(cssHref)) {
|
|
||||||
// Inject CSS link after the title tag
|
|
||||||
htmlAsset.source = htmlAsset.source.replace(
|
|
||||||
/(<title>.*?<\/title>)/,
|
|
||||||
`$1\n${cssLink}`
|
|
||||||
);
|
|
||||||
console.log(`[electron-css-injection] Injected CSS link: ${cssHref}`);
|
|
||||||
} else {
|
|
||||||
console.log(`[electron-css-injection] CSS link already present: ${cssHref}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
ssr: {
|
|
||||||
noExternal: ['@/utils/logger']
|
|
||||||
},
|
|
||||||
base: './',
|
|
||||||
publicDir: 'public',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { defineConfig } from 'vite';
|
|
||||||
import vue from '@vitejs/plugin-vue';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [vue()],
|
|
||||||
base: './',
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, 'src'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
outDir: 'dist-electron/www',
|
|
||||||
emptyOutDir: false,
|
|
||||||
assetsDir: 'assets',
|
|
||||||
cssCodeSplit: false,
|
|
||||||
rollupOptions: {
|
|
||||||
input: path.resolve(__dirname, 'src/main.electron.ts'),
|
|
||||||
output: {
|
|
||||||
entryFileNames: 'main.electron.js',
|
|
||||||
assetFileNames: 'assets/[name]-[hash][extname]',
|
|
||||||
chunkFileNames: 'assets/[name]-[hash].js',
|
|
||||||
manualChunks: undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
commonjsOptions: {
|
|
||||||
transformMixedEsModules: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user