diff --git a/.env.development b/.env.development index 70091e74..726f3b7a 100644 --- a/.env.development +++ b/.env.development @@ -1,10 +1,14 @@ - # Only the variables that start with VITE_ are seen in the application import.meta.env in Vue. +# Logging Configuration - Development environment gets maximum visibility +VITE_LOG_LEVEL=debug + # iOS doesn't like spaces in the app title. TIME_SAFARI_APP_TITLE="TimeSafari_Dev" VITE_APP_SERVER=http://localhost:8080 -# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production). +# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not + + VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 # Using shared server by default to ease setup, which works for shared test users. diff --git a/.env.production b/.env.production index bbf73a08..aef4d6a4 100644 --- a/.env.production +++ b/.env.production @@ -1,6 +1,7 @@ # Only the variables that start with VITE_ are seen in the application import.meta.env in Vue. - +# Logging Configuration - Production environment gets minimal logging for performance +VITE_LOG_LEVEL=warn VITE_APP_SERVER=https://timesafari.app # This is the claim ID for actions in the BVC project. diff --git a/.env.test b/.env.test index a01c323c..5776e66c 100644 --- a/.env.test +++ b/.env.test @@ -1,9 +1,14 @@ # Only the variables that start with VITE_ are seen in the application import.meta.env in Vue. +# Logging Configuration - Test environment gets balanced logging for debugging +VITE_LOG_LEVEL=info + # iOS doesn't like spaces in the app title. TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_APP_SERVER=https://test.timesafari.app -# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production). +# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not + production). + VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch diff --git a/BUILDING.md b/BUILDING.md index ba5649da..e1e94fcd 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -8,8 +8,10 @@ This guide explains how to build TimeSafari for different platforms using the co ```bash # 🖥️ Web Development -npm run build:web:dev # Start development server with hot reload -npm run build:web:prod # Production build +npm install # setup -- and pkgx.dev `dev` command before this will set environment with npm, etc +npm run build:web:serve -- --test # Start with test endorser server +npm run build:web:dev # Start development server with hot reload with local endorser server +npm run build:web:prod # Production build # 📱 Mobile Development npm run build:ios # iOS build (opens Xcode) @@ -2401,4 +2403,4 @@ All scripts use consistent error handling: --- -**Note**: This documentation is maintained alongside the build system. For the most up-to-date information, refer to the actual script files and Vite configuration files in the repository. \ No newline at end of file +**Note**: This documentation is maintained alongside the build system. For the most up-to-date information, refer to the actual script files and Vite configuration files in the repository. diff --git a/README.md b/README.md index 6d987467..6992ba09 100644 --- a/README.md +++ b/README.md @@ -3,36 +3,9 @@ [Time Safari](https://timesafari.org/) allows people to ease into collaboration: start with expressions of gratitude and expand to crowd-fund with time & money, then record and see the impact of contributions. -## Database Migration Status - -**Current Status**: The application is undergoing a migration from Dexie (IndexedDB) to SQLite using absurd-sql. This migration is in **Phase 2** with a well-defined migration fence in place. - -### Migration Progress -- ✅ **SQLite Database Service**: Fully implemented with absurd-sql -- ✅ **Platform Service Layer**: Unified database interface across platforms -- ✅ **Settings Migration**: Core user settings transferred -- ✅ **Account Migration**: Identity and key management -- 🔄 **Contact Migration**: User contact data (via import interface) -- 📋 **Code Cleanup**: Remove unused Dexie imports - -### Migration Fence -The migration is controlled by a **migration fence** that separates legacy Dexie code from the new SQLite implementation. See [Migration Fence Definition](doc/migration-fence-definition.md) for complete details. - -**Key Points**: -- Legacy Dexie database is disabled by default -- All database operations go through `PlatformServiceMixin` -- Migration tools provide controlled access to both databases -- Clear separation between legacy and new code - -### Migration Documentation -- [Migration Guide](doc/migration-to-wa-sqlite.md) - Complete migration process -- [Migration Fence Definition](doc/migration-fence-definition.md) - Fence boundaries and rules -- [Database Migration Guide](doc/database-migration-guide.md) - User-facing migration tools - ## Roadmap -See [project.task.yaml](project.task.yaml) for current priorities. -(Numbers at the beginning of lines are estimated hours. See [taskyaml.org](https://taskyaml.org/) for details.) +See [ClickUp](https://sharing.clickup.com/9014278710/l/h/8cmnyhp-174/10573fec74e2ba0) for current priorities. ## Setup & Building @@ -42,14 +15,45 @@ Quick start: ```bash npm install -npm run dev +npm run build:web:serve -- --test ``` +To be able to make submissions: go to "profile" (bottom left), go to the bottom and expand "Show Advanced Settings", go to the bottom and to the "Test Page", and finally "Become User 0" to see all the functionality. + See [BUILDING.md](BUILDING.md) for comprehensive build instructions for all platforms (Web, Electron, iOS, Android, Docker). ## Development Database Clearing -TimeSafari provides a simple script-based approach to clear the database for development purposes. +TimeSafari provides a simple script-based approach to clear the local database (not the claim server) for development purposes. + +## Logging Configuration + +TimeSafari supports configurable logging levels via the `VITE_LOG_LEVEL` environment variable. This allows developers to control console output verbosity without modifying code. + +### Quick Usage + +```bash +# Show only errors +VITE_LOG_LEVEL=error npm run dev + +# Show warnings and errors +VITE_LOG_LEVEL=warn npm run dev + +# Show info, warnings, and errors (default) +VITE_LOG_LEVEL=info npm run dev + +# Show all log levels including debug +VITE_LOG_LEVEL=debug npm run dev +``` + +### Available Levels + +- **`error`**: Critical errors only +- **`warn`**: Warnings and errors (default for production web) +- **`info`**: Info, warnings, and errors (default for development/capacitor) +- **`debug`**: All log levels including verbose debugging + +See [Logging Configuration Guide](doc/logging-configuration.md) for complete details. ### Quick Usage ```bash @@ -126,7 +130,6 @@ const apiUrl = `${APP_SERVER}/api/claim/123`; ### Documentation -- [Domain Configuration System](docs/domain-configuration.md) - Complete guide - [Constants and Configuration](src/constants/app.ts) - Core constants ## Tests diff --git a/doc/logging-configuration.md b/doc/logging-configuration.md new file mode 100644 index 00000000..2ef2a6d2 --- /dev/null +++ b/doc/logging-configuration.md @@ -0,0 +1,117 @@ +# Logging Configuration Guide + +## Overview + +TimeSafari now supports configurable logging levels via the `VITE_LOG_LEVEL` environment variable. This allows developers to control the verbosity of console output without modifying code. + +## Available Log Levels + +| Level | Value | Description | Console Output | +|-------|-------|-------------|----------------| +| `error` | 0 | Errors only | Critical errors only | +| `warn` | 1 | Warnings and errors | Warnings and errors | +| `info` | 2 | Info, warnings, and errors | General information, warnings, and errors | +| `debug` | 3 | All log levels | Verbose debugging information | + +## Environment Variable + +Set the `VITE_LOG_LEVEL` environment variable to control logging: + +```bash +# Show only errors +VITE_LOG_LEVEL=error + +# Show warnings and errors (default for production web) +VITE_LOG_LEVEL=warn + +# Show info, warnings, and errors (default for development/capacitor) +VITE_LOG_LEVEL=info + +# Show all log levels including debug +VITE_LOG_LEVEL=debug +``` + +## Default Behavior by Platform + +The logger automatically selects appropriate default log levels based on your platform and environment: + +- **Production Web**: `warn` (warnings and errors only) +- **Electron**: `error` (errors only - very quiet) +- **Development/Capacitor**: `info` (info and above) + +## Usage Examples + +### Setting Log Level in Development + +```bash +# In your terminal before running the app +export VITE_LOG_LEVEL=debug +npm run dev + +# Or inline +VITE_LOG_LEVEL=debug npm run dev +``` + +### Setting Log Level in Production + +```bash +# For verbose production logging +VITE_LOG_LEVEL=info npm run build:web + +# For minimal production logging +VITE_LOG_LEVEL=warn npm run build:web +``` + +### Programmatic Access + +The logger provides methods to check current configuration: + +```typescript +import { logger } from '@/utils/logger'; + +// Get current log level +const currentLevel = logger.getCurrentLevel(); // 'info' + +// Check if a level is enabled +const debugEnabled = logger.isLevelEnabled('debug'); // false if level < debug + +// Get available levels +const levels = logger.getAvailableLevels(); // ['error', 'warn', 'info', 'debug'] +``` + +## Database Logging + +Database logging continues to work regardless of console log level settings. All log messages are still stored in the database for debugging and audit purposes. + +## Migration Notes + +- **Existing code**: No changes required - logging behavior remains the same +- **New feature**: Use `VITE_LOG_LEVEL` to override default behavior +- **Backward compatible**: All existing logging calls work as before + +## Best Practices + +1. **Development**: Use `VITE_LOG_LEVEL=debug` for maximum visibility +2. **Testing**: Use `VITE_LOG_LEVEL=info` for balanced output +3. **Production**: Use `VITE_LOG_LEVEL=warn` for minimal noise +4. **Debugging**: Temporarily set `VITE_LOG_LEVEL=debug` to troubleshoot issues + +## Troubleshooting + +### No Logs Appearing + +Check your `VITE_LOG_LEVEL` setting: +```bash +echo $VITE_LOG_LEVEL +``` + +### Too Many Logs + +Reduce verbosity by setting a lower log level: +```bash +VITE_LOG_LEVEL=warn +``` + +### Platform-Specific Issues + +Remember that Electron is very quiet by default. Use `VITE_LOG_LEVEL=info` to see more output in Electron builds. diff --git a/package-lock.json b/package-lock.json index 6d19bd08..814a71ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "timesafari", - "version": "1.0.6", + "version": "1.0.7-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "timesafari", - "version": "1.0.6", + "version": "1.0.7-beta", "dependencies": { "@capacitor-community/electron": "^5.0.1", "@capacitor-community/sqlite": "6.0.2", @@ -96,7 +96,7 @@ }, "devDependencies": { "@capacitor/assets": "^3.0.5", - "@playwright/test": "^1.45.2", + "@playwright/test": "^1.54.2", "@types/dom-webcodecs": "^0.1.7", "@types/jest": "^30.0.0", "@types/js-yaml": "^4.0.9", diff --git a/package.json b/package.json index cd34bc17..7b27258d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "timesafari", - "version": "1.0.6", + "version": "1.0.7-beta", "description": "Time Safari Application", "author": { "name": "Time Safari Team" @@ -204,7 +204,7 @@ }, "devDependencies": { "@capacitor/assets": "^3.0.5", - "@playwright/test": "^1.45.2", + "@playwright/test": "^1.54.2", "@types/dom-webcodecs": "^0.1.7", "@types/jest": "^30.0.0", "@types/js-yaml": "^4.0.9", diff --git a/scripts/build-web.sh b/scripts/build-web.sh index c01bd55d..de0710a2 100755 --- a/scripts/build-web.sh +++ b/scripts/build-web.sh @@ -300,18 +300,20 @@ serve_build() { exit 5 fi - # Use a simple HTTP server to serve the build - if command -v python3 &> /dev/null; then + # Use a server that supports SPA routing (serves index.html for all routes) + if command -v npx &> /dev/null; then + log_info "Starting npx serve with SPA support on port 8080..." + npx serve -s dist -l 8080 + elif command -v python3 &> /dev/null; then + log_warn "Python HTTP server doesn't support SPA routing. Routes like /discover, /account will return 404." log_info "Starting Python HTTP server on port 8080..." cd dist && python3 -m http.server 8080 elif command -v python &> /dev/null; then + log_warn "Python HTTP server doesn't support SPA routing. Routes like /discover, /account will return 404." log_info "Starting Python HTTP server on port 8080..." cd dist && python -m SimpleHTTPServer 8080 - elif command -v npx &> /dev/null; then - log_info "Starting npx serve on port 8080..." - npx serve -s dist -l 8080 else - log_error "No suitable HTTP server found. Install Python or npx serve." + log_error "No suitable HTTP server found. Install npx serve or Python." exit 5 fi } diff --git a/src/components/ActivityListItem.vue b/src/components/ActivityListItem.vue index d1525e8d..257259b9 100644 --- a/src/components/ActivityListItem.vue +++ b/src/components/ActivityListItem.vue @@ -73,7 +73,6 @@ class="w-full h-auto max-w-lg max-h-96 object-contain mx-auto drop-shadow-md" :src="record.image" alt="Activity image" - @load="handleImageLoad(record.image)" /> @@ -272,13 +271,6 @@ export default class ActivityListItem extends Vue { @Prop() isRegistered!: boolean; @Prop() activeDid!: string; - /** - * Function prop for handling image caching - * Called when an image loads successfully, allowing parent to control caching behavior - */ - @Prop({ type: Function, default: () => {} }) - onImageCache!: (imageUrl: string) => void | Promise; - isHiddenDid = isHiddenDid; notify!: ReturnType; $notify!: (notification: any, timeout?: number) => void; @@ -295,14 +287,6 @@ export default class ActivityListItem extends Vue { this.notify.warning(NOTIFY_UNKNOWN_PERSON.message, TIMEOUTS.STANDARD); } - /** - * Handle image load event - call function prop for caching - * Allows parent to control caching behavior and validation - */ - handleImageLoad(imageUrl: string): void { - this.onImageCache(imageUrl); - } - get fetchAmount(): string { const claim = (this.record.fullClaim as any)?.claim || this.record.fullClaim; diff --git a/src/components/ContactInputForm.vue b/src/components/ContactInputForm.vue index 35c693e4..dbbc1485 100644 --- a/src/components/ContactInputForm.vue +++ b/src/components/ContactInputForm.vue @@ -167,7 +167,7 @@ export default class ContactInputForm extends Vue { */ @Emit("qr-scan") private handleQRScan(): void { - console.log("[ContactInputForm] QR scan button clicked"); + // QR scan button clicked - event emitted for parent handling } } diff --git a/src/components/ImageViewer.vue b/src/components/ImageViewer.vue index 07486705..3e8e577f 100644 --- a/src/components/ImageViewer.vue +++ b/src/components/ImageViewer.vue @@ -45,7 +45,6 @@ import { logger } from "../utils/logger"; @Component({ emits: ["update:isOpen"] }) export default class ImageViewer extends Vue { @Prop() imageUrl!: string; - @Prop() imageData!: Blob | null; @Prop() isOpen!: boolean; userAgent = new UAParser(); diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts index e28b3ac9..735252f7 100644 --- a/src/libs/endorserServer.ts +++ b/src/libs/endorserServer.ts @@ -1348,12 +1348,12 @@ export async function createEndorserJwtVcFromClaim( } /** - * Create a JWT for a RegisterAction claim. + * Create a JWT for a RegisterAction claim, used for registrations & invites. * * @param activeDid - The DID of the user creating the invite - * @param contact - The contact to register, with a 'did' field (all optional for invites) - * @param identifier - The identifier for the invite, usually random - * @param expiresIn - The number of seconds until the invite expires + * @param contact - Optional - The contact to register, with a 'did' field (all optional for invites) + * @param identifier - Optional - The identifier for the invite, usually random + * @param expiresIn - Optional - The number of seconds until the invite expires * @returns The JWT for the RegisterAction claim */ export async function createInviteJwt( @@ -1367,7 +1367,7 @@ export async function createInviteJwt( "@type": "RegisterAction", agent: { identifier: activeDid }, object: SERVICE_ID, - identifier: identifier, + identifier: identifier, // not sent if undefined }; if (contact?.did) { vcClaim.participant = { identifier: contact.did }; diff --git a/src/router/index.ts b/src/router/index.ts index 7d1e738c..043d3d0c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -82,6 +82,15 @@ const routes: Array = [ name: "database-migration", component: () => import("../views/DatabaseMigration.vue"), }, + { + path: "/deep-link-error", + name: "deep-link-error", + component: () => import("../views/DeepLinkErrorView.vue"), + meta: { + title: "Invalid Deep Link", + requiresAuth: false, + }, + }, { path: "/did/:did?", name: "did", @@ -276,15 +285,6 @@ const routes: Array = [ name: "user-profile", component: () => import("../views/UserProfileView.vue"), }, - { - path: "/deep-link-error", - name: "deep-link-error", - component: () => import("../views/DeepLinkErrorView.vue"), - meta: { - title: "Invalid Deep Link", - requiresAuth: false, - }, - }, ]; const isElectron = window.location.protocol === "file:"; diff --git a/src/services/deepLinks.ts b/src/services/deepLinks.ts index 62ae7b15..d8445607 100644 --- a/src/services/deepLinks.ts +++ b/src/services/deepLinks.ts @@ -179,7 +179,7 @@ export class DeepLinkHandler { const validRoute = routeSchema.parse(path) as DeepLinkRoute; routeName = ROUTE_MAP[validRoute].name; } catch (error) { - console.error(`[DeepLink] Invalid route path: ${path}`); + logger.error(`[DeepLink] Invalid route path: ${path}`); // Redirect to error page with information about the invalid link await this.router.replace({ diff --git a/src/services/platforms/WebPlatformService.ts b/src/services/platforms/WebPlatformService.ts index 7ec13c01..a731ee22 100644 --- a/src/services/platforms/WebPlatformService.ts +++ b/src/services/platforms/WebPlatformService.ts @@ -693,7 +693,8 @@ export class WebPlatformService implements PlatformService { const setClause = keys.map((key) => `${key} = ?`).join(", "); const sql = `UPDATE settings SET ${setClause} WHERE accountDid = ?`; const params = [...keys.map((key) => settings[key]), did]; - console.log( + // Log update operation for debugging + logger.debug( "[WebPlatformService] updateDidSpecificSettings", sql, JSON.stringify(params, null, 2), diff --git a/src/test/index.ts b/src/test/index.ts index 28b0e349..8974713b 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -1,9 +1,29 @@ import axios from "axios"; import * as didJwt from "did-jwt"; import { SERVICE_ID } from "../libs/endorserServer"; -import { deriveAddress, newIdentifier } from "../libs/crypto"; +import { + DEFAULT_ROOT_DERIVATION_PATH, + deriveAddress, + newIdentifier, +} from "../libs/crypto"; import { logger } from "../utils/logger"; import { AppString } from "../constants/app"; +import { saveNewIdentity } from "@/libs/util"; +import { PlatformServiceFactory } from "@/services/PlatformServiceFactory"; + +const TEST_USER_0_MNEMONIC = + "rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage"; + +export async function testBecomeUser0() { + const [addr, privateHex, publicHex, deriPath] = deriveAddress(TEST_USER_0_MNEMONIC); + + const identity0 = newIdentifier(addr, publicHex, privateHex, deriPath); + await saveNewIdentity(identity0, TEST_USER_0_MNEMONIC, DEFAULT_ROOT_DERIVATION_PATH); + const platformService = await PlatformServiceFactory.getInstance(); + await platformService.updateDidSpecificSettings(identity0.did, { + isRegistered: true, + }); +} /** * Get User #0 to sign & submit a RegisterAction for the user's activeDid. @@ -15,10 +35,7 @@ import { AppString } from "../constants/app"; * @throws Error if registration fails or database access fails */ export async function testServerRegisterUser() { - const testUser0Mnem = - "seminar accuse mystery assist delay law thing deal image undo guard initial shallow wrestle list fragile borrow velvet tomorrow awake explain test offer control"; - - const [addr, privateHex, publicHex, deriPath] = deriveAddress(testUser0Mnem); + const [addr, privateHex, publicHex, deriPath] = deriveAddress(TEST_USER_0_MNEMONIC); const identity0 = newIdentifier(addr, publicHex, privateHex, deriPath); @@ -32,9 +49,9 @@ export async function testServerRegisterUser() { const vcClaim = { "@context": "https://schema.org", "@type": "RegisterAction", - agent: { did: identity0.did }, + agent: { identifier: identity0.did }, object: SERVICE_ID, - participant: { did: settings.activeDid }, + participant: { identifier: settings.activeDid }, }; // Make a payload for the claim @@ -71,4 +88,5 @@ export async function testServerRegisterUser() { const resp = await axios.post(url, payload, { headers }); logger.log("User registration result:", resp); + return resp; } diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 4b78ed3a..52ae5daa 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -2,9 +2,10 @@ * Enhanced logger with self-contained database logging * * Provides comprehensive logging with console and database output. + * Supports configurable log levels via VITE_LOG_LEVEL environment variable. * * @author Matthew Raymer - * @version 2.0.0 + * @version 2.1.0 * @since 2025-01-25 */ @@ -46,6 +47,42 @@ export function safeStringify(obj: unknown) { const isElectron = process.env.VITE_PLATFORM === "electron"; const isProduction = process.env.NODE_ENV === "production"; +// Log level configuration via environment variable +const LOG_LEVELS = { + error: 0, + warn: 1, + info: 2, + debug: 3, +} as const; + +type LogLevel = keyof typeof LOG_LEVELS; + +// Parse VITE_LOG_LEVEL environment variable +const getLogLevel = (): LogLevel => { + const envLogLevel = process.env.VITE_LOG_LEVEL?.toLowerCase(); + + if (envLogLevel && envLogLevel in LOG_LEVELS) { + return envLogLevel as LogLevel; + } + + // Default log levels based on environment + if (isProduction && !isElectron) { + return "warn"; // Production web: warnings and errors only + } else if (isElectron) { + return "error"; // Electron: errors only + } else { + return "info"; // Development/Capacitor: info and above + } +}; + +const currentLogLevel = getLogLevel(); +const currentLevelValue = LOG_LEVELS[currentLogLevel]; + +// Helper function to check if a log level should be displayed +const shouldLog = (level: LogLevel): boolean => { + return LOG_LEVELS[level] <= currentLevelValue; +}; + // Track initialization state to prevent circular dependencies let isInitializing = true; @@ -105,11 +142,11 @@ async function logToDatabase( } } -// Enhanced logger with self-contained database methods +// Enhanced logger with self-contained database methods and log level control export const logger = { debug: (message: string, ...args: unknown[]) => { - // Debug logs are very verbose - only show in development mode for web - if (!isProduction && !isElectron) { + // Debug logs only show if VITE_LOG_LEVEL allows it + if (shouldLog("debug")) { // eslint-disable-next-line no-console console.debug(message, ...args); } @@ -117,11 +154,8 @@ export const logger = { }, log: (message: string, ...args: unknown[]) => { - // Regular logs - show in development or for capacitor, but quiet for Electron - if ( - (!isProduction && !isElectron) || - process.env.VITE_PLATFORM === "capacitor" - ) { + // Regular logs - show if VITE_LOG_LEVEL allows info level + if (shouldLog("info")) { // eslint-disable-next-line no-console console.log(message, ...args); } @@ -132,11 +166,7 @@ export const logger = { }, info: (message: string, ...args: unknown[]) => { - if ( - process.env.NODE_ENV !== "production" || - process.env.VITE_PLATFORM === "capacitor" || - process.env.VITE_PLATFORM === "electron" - ) { + if (shouldLog("info")) { // eslint-disable-next-line no-console console.info(message, ...args); } @@ -147,8 +177,7 @@ export const logger = { }, warn: (message: string, ...args: unknown[]) => { - // Always show warnings, but for Electron, suppress routine database warnings - if (!isElectron || !message.includes("[CapacitorPlatformService]")) { + if (shouldLog("warn")) { // eslint-disable-next-line no-console console.warn(message, ...args); } @@ -159,9 +188,10 @@ export const logger = { }, error: (message: string, ...args: unknown[]) => { - // Errors will always be logged to console - // eslint-disable-next-line no-console - console.error(message, ...args); + if (shouldLog("error")) { + // eslint-disable-next-line no-console + console.error(message, ...args); + } // Database logging const messageString = safeStringify(message); @@ -175,11 +205,11 @@ export const logger = { }, toConsoleAndDb: async (message: string, isError = false): Promise => { - // Console output - if (isError) { + // Console output based on log level + if (isError && shouldLog("error")) { // eslint-disable-next-line no-console console.error(message); - } else { + } else if (!isError && shouldLog("info")) { // eslint-disable-next-line no-console console.log(message); } @@ -194,6 +224,12 @@ export const logger = { error: (message: string) => logToDatabase(`[${componentName}] ${message}`, "error"), }), + + // Log level information methods + getCurrentLevel: (): LogLevel => currentLogLevel, + getCurrentLevelValue: (): number => currentLevelValue, + isLevelEnabled: (level: LogLevel): boolean => shouldLog(level), + getAvailableLevels: (): LogLevel[] => Object.keys(LOG_LEVELS) as LogLevel[], }; // Function to manually mark initialization as complete diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index 892e1ebc..81c2978e 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -61,7 +61,8 @@ /> - +

- + @@ -255,11 +254,7 @@ Raymer * @version 1.0.0 */ - +