Browse Source

Integrate TypeScript type checking into build process with conditional execution

- Add type checking to build scripts for production/test builds only
- Fix TypeScript errors in migration service, router, and platform services
- Add electronAPI type declarations for Electron platform
- Remove type checking from development builds for faster hot reload
- Update tsconfig.node.json to resolve configuration conflicts
- Ensure type safety for production while maintaining fast development workflow
pull/158/head
Matthew Raymer 2 weeks ago
parent
commit
c30b94dcc7
  1. 1
      package.json
  2. 29
      scripts/build-web.sh
  3. 2
      src/db-sql/migration.ts
  4. 2
      src/main.electron.ts
  5. 2
      src/router/index.ts
  6. 6
      src/services/AbsurdSqlDatabaseService.ts
  7. 9
      src/services/platforms/CapacitorPlatformService.ts
  8. 13
      src/types/electron.d.ts
  9. 4
      tsconfig.node.json

1
package.json

@ -8,6 +8,7 @@
"scripts": {
"lint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore src",
"lint-fix": "eslint --ext .js,.ts,.vue --ignore-path .gitignore --fix src",
"type-check": "tsc --noEmit",
"prebuild": "eslint --ext .js,.ts,.vue --ignore-path .gitignore src && node sw_combine.js && node scripts/copy-wasm.js",
"test:prerequisites": "node scripts/check-prerequisites.js",
"test:web": "npx playwright test -c playwright.config-local.ts --trace on",

29
scripts/build-web.sh

@ -252,6 +252,25 @@ execute_docker_build() {
log_info "Docker image available as: $image_tag:$mode"
}
# Function to run type checking based on build mode
run_type_checking() {
local mode="$1"
# Only run type checking for production and test builds
if [ "$mode" = "production" ] || [ "$mode" = "test" ]; then
log_info "Running TypeScript type checking for $mode mode..."
if ! measure_time npm run type-check; then
log_error "TypeScript type checking failed for $mode mode!"
exit 2
fi
log_success "TypeScript type checking completed for $mode mode"
else
log_debug "Skipping TypeScript type checking for development mode"
fi
}
# Function to start Vite development server
start_dev_server() {
log_info "Starting Vite development server..."
@ -333,7 +352,10 @@ elif [ "$SERVE_BUILD" = true ]; then
log_info "Cleaning dist directory..."
clean_build_artifacts "dist"
# Step 2: Execute Vite build
# Step 2: Run type checking (for production/test builds)
safe_execute "Type checking for $BUILD_MODE mode" "run_type_checking $BUILD_MODE" || exit 2
# Step 3: Execute Vite build
safe_execute "Vite build for $BUILD_MODE mode" "execute_vite_build $BUILD_MODE" || exit 3
# Step 3: Serve the build
@ -348,7 +370,10 @@ else
log_info "Cleaning dist directory..."
clean_build_artifacts "dist"
# Step 2: Execute Vite build
# Step 2: Run type checking (for production/test builds)
safe_execute "Type checking for $BUILD_MODE mode" "run_type_checking $BUILD_MODE" || exit 2
# Step 3: Execute Vite build
safe_execute "Vite build for $BUILD_MODE mode" "execute_vite_build $BUILD_MODE" || exit 3
# Step 3: Execute Docker build if requested

2
src/db-sql/migration.ts

@ -131,7 +131,7 @@ const MIGRATIONS = [
* @param extractMigrationNames - A function that extracts the names (string array) from "select name from migrations"
*/
export async function runMigrations<T>(
sqlExec: (sql: string, params?: unknown[]) => Promise<unknown>,
sqlExec: (sql: string, params?: unknown[]) => Promise<void>,
sqlQuery: (sql: string, params?: unknown[]) => Promise<T>,
extractMigrationNames: (result: T) => Set<string>,
): Promise<void> {

2
src/main.electron.ts

@ -79,7 +79,7 @@ window.addEventListener("unhandledrejection", (event) => {
});
// Electron-specific initialization
if (typeof window !== "undefined" && window.require) {
if (typeof window !== "undefined" && typeof window.require === "function") {
// We're in an Electron renderer process
logger.log("[Electron] Detected Electron renderer process");

2
src/router/index.ts

@ -338,7 +338,7 @@ router.onError(errorHandler); // Assign the error handler to the router instance
* @param from - Source route
* @param next - Navigation function
*/
router.beforeEach(async (to, from, next) => {
router.beforeEach(async (to, _from, next) => {
try {
// Skip identity check for routes that handle identity creation manually
const skipIdentityRoutes = [

6
src/services/AbsurdSqlDatabaseService.ts

@ -134,7 +134,11 @@ class AbsurdSqlDatabaseService implements DatabaseService {
// An error is thrown without this pragma: "File has invalid page size. (the first block of a new file must be written first)"
await this.db.exec(`PRAGMA journal_mode=MEMORY;`);
const sqlExec = this.db.run.bind(this.db);
// Create wrapper functions that match the expected signatures
const sqlExec = async (sql: string, params?: unknown[]): Promise<void> => {
await this.db!.run(sql, params);
};
const sqlQuery = this.db.exec.bind(this.db);
// Extract the migration names for the absurd-sql format

9
src/services/platforms/CapacitorPlatformService.ts

@ -11,7 +11,6 @@ import {
SQLiteConnection,
SQLiteDBConnection,
CapacitorSQLite,
capSQLiteChanges,
DBSQLiteValues,
} from "@capacitor-community/sqlite";
@ -496,19 +495,17 @@ export class CapacitorPlatformService implements PlatformService {
const sqlExec = async (
sql: string,
params?: unknown[],
): Promise<capSQLiteChanges> => {
): Promise<void> => {
logger.debug(`🔧 [CapacitorMigration] Executing SQL:`, sql);
if (params && params.length > 0) {
// Use run method for parameterized queries (prepared statements)
// This is essential for proper parameter binding and SQL injection prevention
const result = await this.db!.run(sql, params);
return result;
await this.db!.run(sql, params);
} else {
// Use execute method for non-parameterized queries
// This is more efficient for simple DDL statements
const result = await this.db!.execute(sql);
return result;
await this.db!.execute(sql);
}
};

13
src/types/electron.d.ts

@ -0,0 +1,13 @@
declare global {
interface Window {
electronAPI?: {
exportData: (fileName: string, content: string) => Promise<{
success: boolean;
path?: string;
error?: string;
}>;
};
}
}
export {};

4
tsconfig.node.json

@ -4,9 +4,7 @@
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"allowImportingTsExtensions": true,
"noEmit": true
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.*"]
}
Loading…
Cancel
Save