feat: update TypeScript config for platform services
- Add useDefineForClassFields for class field initialization - Remove test-playwright from includes - Add tsconfig.node.json reference - Remove redundant node_modules exclude
This commit is contained in:
20
src/services/PlatformService.ts
Normal file
20
src/services/PlatformService.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export interface PlatformService {
|
||||||
|
// File system operations
|
||||||
|
readFile(path: string): Promise<string>;
|
||||||
|
writeFile(path: string, content: string): Promise<void>;
|
||||||
|
deleteFile(path: string): Promise<void>;
|
||||||
|
listFiles(directory: string): Promise<string[]>;
|
||||||
|
|
||||||
|
// Camera operations
|
||||||
|
takePicture(): Promise<string>;
|
||||||
|
pickImage(): Promise<string>;
|
||||||
|
|
||||||
|
// Platform specific features
|
||||||
|
isCapacitor(): boolean;
|
||||||
|
isElectron(): boolean;
|
||||||
|
isPyWebView(): boolean;
|
||||||
|
isWeb(): boolean;
|
||||||
|
|
||||||
|
// Deep linking
|
||||||
|
handleDeepLink(url: string): Promise<void>;
|
||||||
|
}
|
||||||
36
src/services/PlatformServiceFactory.ts
Normal file
36
src/services/PlatformServiceFactory.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { Capacitor } from "@capacitor/core";
|
||||||
|
import { PlatformService } from "./PlatformService";
|
||||||
|
import { WebPlatformService } from "./platforms/WebPlatformService";
|
||||||
|
import { CapacitorPlatformService } from "./platforms/CapacitorPlatformService";
|
||||||
|
import { ElectronPlatformService } from "./platforms/ElectronPlatformService";
|
||||||
|
import { PyWebViewPlatformService } from "./platforms/PyWebViewPlatformService";
|
||||||
|
|
||||||
|
export class PlatformServiceFactory {
|
||||||
|
private static instance: PlatformService | null = null;
|
||||||
|
|
||||||
|
public static getInstance(): PlatformService {
|
||||||
|
if (PlatformServiceFactory.instance) {
|
||||||
|
return PlatformServiceFactory.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
const platform = process.env.VITE_PLATFORM || "web";
|
||||||
|
|
||||||
|
switch (platform) {
|
||||||
|
case "capacitor":
|
||||||
|
PlatformServiceFactory.instance = new CapacitorPlatformService();
|
||||||
|
break;
|
||||||
|
case "electron":
|
||||||
|
PlatformServiceFactory.instance = new ElectronPlatformService();
|
||||||
|
break;
|
||||||
|
case "pywebview":
|
||||||
|
PlatformServiceFactory.instance = new PyWebViewPlatformService();
|
||||||
|
break;
|
||||||
|
case "web":
|
||||||
|
default:
|
||||||
|
PlatformServiceFactory.instance = new WebPlatformService();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PlatformServiceFactory.instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
80
src/services/platforms/CapacitorPlatformService.ts
Normal file
80
src/services/platforms/CapacitorPlatformService.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import { PlatformService } from "../PlatformService";
|
||||||
|
import { Capacitor } from "@capacitor/core";
|
||||||
|
import { Filesystem, Directory } from "@capacitor/filesystem";
|
||||||
|
import { Camera, CameraResultType, CameraSource } from "@capacitor/camera";
|
||||||
|
import { App } from "@capacitor/app";
|
||||||
|
|
||||||
|
export class CapacitorPlatformService implements PlatformService {
|
||||||
|
async readFile(path: string): Promise<string> {
|
||||||
|
const file = await Filesystem.readFile({
|
||||||
|
path,
|
||||||
|
directory: Directory.Data,
|
||||||
|
});
|
||||||
|
return file.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeFile(path: string, content: string): Promise<void> {
|
||||||
|
await Filesystem.writeFile({
|
||||||
|
path,
|
||||||
|
data: content,
|
||||||
|
directory: Directory.Data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteFile(path: string): Promise<void> {
|
||||||
|
await Filesystem.deleteFile({
|
||||||
|
path,
|
||||||
|
directory: Directory.Data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async listFiles(directory: string): Promise<string[]> {
|
||||||
|
const result = await Filesystem.readdir({
|
||||||
|
path: directory,
|
||||||
|
directory: Directory.Data,
|
||||||
|
});
|
||||||
|
return result.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
async takePicture(): Promise<string> {
|
||||||
|
const image = await Camera.getPhoto({
|
||||||
|
quality: 90,
|
||||||
|
allowEditing: true,
|
||||||
|
resultType: CameraResultType.Uri,
|
||||||
|
source: CameraSource.Camera,
|
||||||
|
});
|
||||||
|
return image.webPath || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
async pickImage(): Promise<string> {
|
||||||
|
const image = await Camera.getPhoto({
|
||||||
|
quality: 90,
|
||||||
|
allowEditing: true,
|
||||||
|
resultType: CameraResultType.Uri,
|
||||||
|
source: CameraSource.Photos,
|
||||||
|
});
|
||||||
|
return image.webPath || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
isCapacitor(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
isElectron(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isPyWebView(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isWeb(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleDeepLink(url: string): Promise<void> {
|
||||||
|
// Capacitor handles deep links automatically
|
||||||
|
// This is just a placeholder for the interface
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/services/platforms/ElectronPlatformService.ts
Normal file
47
src/services/platforms/ElectronPlatformService.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { PlatformService } from '../PlatformService';
|
||||||
|
|
||||||
|
export class ElectronPlatformService implements PlatformService {
|
||||||
|
async readFile(path: string): Promise<string> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeFile(path: string, content: string): Promise<void> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteFile(path: string): Promise<void> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async listFiles(directory: string): Promise<string[]> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async takePicture(): Promise<string> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async pickImage(): Promise<string> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
isCapacitor(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isElectron(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
isPyWebView(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isWeb(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleDeepLink(url: string): Promise<void> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/services/platforms/PyWebViewPlatformService.ts
Normal file
47
src/services/platforms/PyWebViewPlatformService.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { PlatformService } from '../PlatformService';
|
||||||
|
|
||||||
|
export class PyWebViewPlatformService implements PlatformService {
|
||||||
|
async readFile(path: string): Promise<string> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeFile(path: string, content: string): Promise<void> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteFile(path: string): Promise<void> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async listFiles(directory: string): Promise<string[]> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async takePicture(): Promise<string> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
async pickImage(): Promise<string> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
|
isCapacitor(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isElectron(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isPyWebView(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
isWeb(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleDeepLink(url: string): Promise<void> {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/services/platforms/WebPlatformService.ts
Normal file
87
src/services/platforms/WebPlatformService.ts
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import { PlatformService } from "../PlatformService";
|
||||||
|
|
||||||
|
export class WebPlatformService implements PlatformService {
|
||||||
|
async readFile(path: string): Promise<string> {
|
||||||
|
throw new Error("File system access not available in web platform");
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeFile(path: string, content: string): Promise<void> {
|
||||||
|
throw new Error("File system access not available in web platform");
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteFile(path: string): Promise<void> {
|
||||||
|
throw new Error("File system access not available in web platform");
|
||||||
|
}
|
||||||
|
|
||||||
|
async listFiles(directory: string): Promise<string[]> {
|
||||||
|
throw new Error("File system access not available in web platform");
|
||||||
|
}
|
||||||
|
|
||||||
|
async takePicture(): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "file";
|
||||||
|
input.accept = "image/*";
|
||||||
|
input.capture = "environment";
|
||||||
|
|
||||||
|
input.onchange = (e) => {
|
||||||
|
const file = (e.target as HTMLInputElement).files?.[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (event) => {
|
||||||
|
resolve(event.target?.result as string);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
} else {
|
||||||
|
reject(new Error("No file selected"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
input.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async pickImage(): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.type = "file";
|
||||||
|
input.accept = "image/*";
|
||||||
|
|
||||||
|
input.onchange = (e) => {
|
||||||
|
const file = (e.target as HTMLInputElement).files?.[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (event) => {
|
||||||
|
resolve(event.target?.result as string);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
} else {
|
||||||
|
reject(new Error("No file selected"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
input.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isCapacitor(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isElectron(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isPyWebView(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isWeb(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleDeepLink(url: string): Promise<void> {
|
||||||
|
// Web platform can handle deep links through URL parameters
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
tsconfig.node.json
Normal file
10
tsconfig.node.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.*"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user