refactor: replace PFLog with SyncLog/OpLog and remove obsolete migration scripts

PFLog was named after "Pfapi" which is no longer used. Replace with
SyncLog in sync provider files and OpLog in op-log infrastructure files.
Delete unused migration scripts.
This commit is contained in:
Johannes Millan 2026-02-03 13:01:02 +01:00
parent f6c9714433
commit f78f6f4e39
36 changed files with 297 additions and 500 deletions

View file

@ -1,146 +0,0 @@
#!/usr/bin/env ts-node
import * as fs from 'fs';
import * as path from 'path';
import * as glob from 'glob';
interface Replacement {
pattern: RegExp;
replacement: string;
}
const replacements: Replacement[] = [
// Replace Log.log with PFLog.log
{ pattern: /\bLog\.log\(/g, replacement: 'PFLog.log(' },
// Replace Log.err with PFLog.err
{ pattern: /\bLog\.err\(/g, replacement: 'PFLog.err(' },
// Replace Log.info with PFLog.info
{ pattern: /\bLog\.info\(/g, replacement: 'PFLog.info(' },
// Replace Log.debug with PFLog.debug
{ pattern: /\bLog\.debug\(/g, replacement: 'PFLog.debug(' },
// Replace Log.verbose with PFLog.verbose
{ pattern: /\bLog\.verbose\(/g, replacement: 'PFLog.verbose(' },
// Replace Log.critical with PFLog.critical
{ pattern: /\bLog\.critical\(/g, replacement: 'PFLog.critical(' },
];
function updateImports(content: string): string {
// Check if file already imports PFLog
const hasPFLogImport =
/import\s*{[^}]*\bPFLog\b[^}]*}\s*from\s*['"][^'"]*\/log['"]/.test(content);
if (hasPFLogImport) {
// If PFLog is already imported, just remove Log from the import if it's not used elsewhere
return content;
}
// Find existing Log import and add PFLog to it
const logImportRegex = /import\s*{([^}]*\bLog\b[^}]*)}\s*from\s*(['"][^'"]*\/log['"])/;
const match = content.match(logImportRegex);
if (match) {
const [fullMatch, imports, importPath] = match;
const importList = imports.split(',').map((s) => s.trim());
// Add PFLog if not already there
if (!importList.includes('PFLog')) {
importList.push('PFLog');
}
// Check if Log is still used after replacements
let tempContent = content;
for (const { pattern, replacement } of replacements) {
tempContent = tempContent.replace(pattern, replacement);
}
// Remove the import statement from check
tempContent = tempContent.replace(logImportRegex, '');
// If Log is no longer used, remove it from imports
const logStillUsed = /\bLog\b/.test(tempContent);
if (!logStillUsed) {
const logIndex = importList.indexOf('Log');
if (logIndex > -1) {
importList.splice(logIndex, 1);
}
}
const newImports = importList.join(', ');
const newImportStatement = `import { ${newImports} } from ${importPath}`;
content = content.replace(fullMatch, newImportStatement);
}
return content;
}
function processFile(filePath: string): { modified: boolean; changes: number } {
try {
let content = fs.readFileSync(filePath, 'utf8');
const originalContent = content;
let changeCount = 0;
// Count and apply replacements
for (const { pattern, replacement } of replacements) {
const matches = content.match(pattern);
if (matches) {
changeCount += matches.length;
content = content.replace(pattern, replacement);
}
}
// Update imports if changes were made
if (changeCount > 0) {
content = updateImports(content);
}
const modified = content !== originalContent;
if (modified) {
fs.writeFileSync(filePath, content, 'utf8');
}
return { modified, changes: changeCount };
} catch (error) {
console.error(`Error processing ${filePath}:`, error);
return { modified: false, changes: 0 };
}
}
function main() {
console.log('Migrating Log to PFLog in pfapi directory...\n');
// Find all TypeScript files in pfapi directory
const files = glob.sync('src/app/pfapi/**/*.ts', {
ignore: ['**/*.spec.ts', '**/node_modules/**'],
absolute: true,
});
console.log(`Found ${files.length} TypeScript files in pfapi directory\n`);
const modifiedFiles: { path: string; changes: number }[] = [];
let totalChanges = 0;
for (const file of files) {
const result = processFile(file);
if (result.modified) {
modifiedFiles.push({ path: file, changes: result.changes });
totalChanges += result.changes;
}
}
console.log('\nMigration complete!\n');
console.log(`Total changes: ${totalChanges}`);
console.log(`Modified ${modifiedFiles.length} files:\n`);
modifiedFiles
.sort((a, b) => b.changes - a.changes)
.forEach(({ path: filePath, changes }) => {
console.log(` - ${path.relative(process.cwd(), filePath)} (${changes} changes)`);
});
if (modifiedFiles.length === 0) {
console.log(' No files needed modification.');
}
}
main();

View file

@ -1,64 +0,0 @@
#!/usr/bin/env ts-node
import * as fs from 'fs';
import * as glob from 'glob';
const pfapiFiles = glob.sync('src/app/pfapi/**/*.ts', {
ignore: ['**/*.spec.ts', '**/node_modules/**'],
});
console.log(`Found ${pfapiFiles.length} pfapi files to check`);
let totalFiles = 0;
let totalChanges = 0;
function migrateFile(filePath: string): void {
let content = fs.readFileSync(filePath, 'utf8');
let modified = false;
let localChanges = 0;
// Replace SyncLog with PFLog in code
const syncLogPattern = /\bSyncLog\b/g;
const matches = content.match(syncLogPattern);
if (matches) {
content = content.replace(syncLogPattern, 'PFLog');
modified = true;
localChanges = matches.length;
}
// Update imports - replace SyncLog with PFLog
if (modified) {
// Handle imports that have both SyncLog and PFLog
content = content.replace(
/import\s*{\s*([^}]*)\bSyncLog\b([^}]*)\}\s*from\s*['"][^'"]*core\/log['"]/g,
(match, before, after) => {
const imports = (before + after)
.split(',')
.map((s) => s.trim())
.filter((s) => s && s !== 'SyncLog');
// Only add PFLog if it's not already there
if (!imports.includes('PFLog')) {
imports.push('PFLog');
}
const importPath = match.includes('"')
? match.split('"')[1]
: match.split("'")[1];
return `import { ${imports.join(', ')} } from '${importPath}'`;
},
);
}
if (modified) {
fs.writeFileSync(filePath, content);
console.log(`${filePath} (${localChanges} changes)`);
totalFiles++;
totalChanges += localChanges;
}
}
// Process all files
pfapiFiles.forEach(migrateFile);
console.log(
`\nMigration complete! Modified ${totalFiles} files with ${totalChanges} total changes`,
);

View file

@ -355,7 +355,6 @@ export class Log {
// Pre-configured logger instances for specific contexts
// All context loggers now record to history
export const SyncLog = Log.withContext('sync');
export const PFLog = Log.withContext('pf');
export const OpLog = Log.withContext('ol');
export const PluginLog = Log.withContext('plugin');
export const IssueLog = Log.withContext('issue');

View file

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { openDB, IDBPDatabase } from 'idb';
import { PFLog } from '../log';
import { OpLog } from '../log';
// Database constants - must match PFAPI's storage
const DB_NAME = 'pf';
@ -49,7 +49,7 @@ export class ClientIdService {
const isNewFormat = /^[BEAI]_[a-zA-Z0-9]{4}$/.test(clientId);
if (!isOldFormat && !isNewFormat) {
PFLog.critical('ClientIdService.loadClientId() Invalid clientId loaded:', {
OpLog.critical('ClientIdService.loadClientId() Invalid clientId loaded:', {
clientId,
length: clientId.length,
});
@ -57,7 +57,7 @@ export class ClientIdService {
}
this._cachedClientId = clientId;
PFLog.normal('ClientIdService.loadClientId() loaded:', { clientId });
OpLog.normal('ClientIdService.loadClientId() loaded:', { clientId });
return clientId;
}
@ -76,7 +76,7 @@ export class ClientIdService {
await db.put(DB_STORE_NAME, newClientId, CLIENT_ID_KEY);
this._cachedClientId = newClientId;
PFLog.normal('ClientIdService.generateNewClientId() generated:', { newClientId });
OpLog.normal('ClientIdService.generateNewClientId() generated:', { newClientId });
return newClientId;
}

View file

@ -1,4 +1,4 @@
import { PFLog } from '../log';
import { OpLog } from '../log';
import {
VectorClock as SharedVectorClock,
compareVectorClocks as sharedCompareVectorClocks,
@ -114,7 +114,7 @@ export const sanitizeVectorClock = (clock: any): VectorClock => {
}
}
} catch (e) {
PFLog.error('Error sanitizing vector clock', e);
OpLog.error('Error sanitizing vector clock', e);
return {};
}
@ -170,7 +170,7 @@ export const incrementVectorClock = (
typeof clientId !== 'string' ||
clientId.length < MIN_CLIENT_ID_LENGTH
) {
PFLog.critical('incrementVectorClock: Invalid clientId', {
OpLog.critical('incrementVectorClock: Invalid clientId', {
clientId,
type: typeof clientId,
length: clientId?.length,
@ -183,7 +183,7 @@ export const incrementVectorClock = (
const currentValue = newClock[clientId] || 0;
// Log for debugging
PFLog.verbose('incrementVectorClock', {
OpLog.verbose('incrementVectorClock', {
clientId,
currentValue,
allClients: Object.keys(newClock),
@ -193,7 +193,7 @@ export const incrementVectorClock = (
// Resetting to 1 would break causality (new ops appear older than previous ops)
// User must do a SYNC_IMPORT to properly reset clocks across all clients
if (currentValue >= Number.MAX_SAFE_INTEGER - 1000) {
PFLog.critical('Vector clock component overflow detected', {
OpLog.critical('Vector clock component overflow detected', {
clientId,
currentValue,
});
@ -294,7 +294,7 @@ export const hasVectorClockChanges = (
} else {
// Current clock is small enough that pruning couldn't have removed this key.
hasMissingUnpruned = true;
PFLog.warn('Vector clock change detected: client missing from current', {
OpLog.warn('Vector clock change detected: client missing from current', {
clientId,
refValue: refVal,
currentClock: vectorClockToString(current),
@ -306,7 +306,7 @@ export const hasVectorClockChanges = (
}
if (missingPrunedKeys.length > 0) {
PFLog.verbose(
OpLog.verbose(
`Vector clock: ${missingPrunedKeys.length} reference client(s) missing from current (likely pruned)`,
{ missingKeys: missingPrunedKeys },
);
@ -358,7 +358,7 @@ export const limitVectorClockSize = (
// This means some "protected" IDs will be dropped, which could cause
// incorrect CONCURRENT comparisons with full-state operations.
if (allPreserveIds.length > MAX_VECTOR_CLOCK_SIZE) {
PFLog.warn(
OpLog.warn(
'Vector clock pruning: preserveClientIds exceeds MAX_VECTOR_CLOCK_SIZE, some protected IDs will be dropped',
{
preserveCount: allPreserveIds.length,
@ -368,7 +368,7 @@ export const limitVectorClockSize = (
);
}
PFLog.info('Vector clock pruning triggered', {
OpLog.info('Vector clock pruning triggered', {
originalSize: entries.length,
maxSize: MAX_VECTOR_CLOCK_SIZE,
currentClientId,

View file

@ -3,7 +3,7 @@ import { Subject } from 'rxjs';
import { App, URLOpenListenerEvent } from '@capacitor/app';
import { PluginListenerHandle } from '@capacitor/core';
import { IS_NATIVE_PLATFORM } from '../../util/is-native-platform';
import { PFLog } from '../../core/log';
import { SyncLog } from '../../core/log';
export interface OAuthCallbackData {
code?: string;
@ -36,21 +36,21 @@ export class OAuthCallbackHandlerService implements OnDestroy {
this._urlListenerHandle = await App.addListener(
'appUrlOpen',
(event: URLOpenListenerEvent) => {
PFLog.log('OAuthCallbackHandler: Received URL', event.url);
SyncLog.log('OAuthCallbackHandler: Received URL', event.url);
if (event.url.startsWith('com.super-productivity.app://oauth-callback')) {
const callbackData = this._parseOAuthCallback(event.url);
if (callbackData.code) {
PFLog.log('OAuthCallbackHandler: Extracted auth code');
SyncLog.log('OAuthCallbackHandler: Extracted auth code');
} else if (callbackData.error) {
PFLog.warn(
SyncLog.warn(
'OAuthCallbackHandler: OAuth error',
callbackData.error,
callbackData.error_description,
);
} else {
PFLog.warn('OAuthCallbackHandler: No auth code or error in URL', event.url);
SyncLog.warn('OAuthCallbackHandler: No auth code or error in URL', event.url);
}
this._authCodeReceived$.next(callbackData);
@ -73,7 +73,7 @@ export class OAuthCallbackHandlerService implements OnDestroy {
provider: 'dropbox',
};
} catch (e) {
PFLog.err('OAuthCallbackHandler: Failed to parse URL', url, e);
SyncLog.err('OAuthCallbackHandler: Failed to parse URL', url, e);
return {
error: 'parse_error',
error_description: 'Failed to parse OAuth callback URL',

View file

@ -13,7 +13,7 @@ import { loadAllData } from '../../root-store/meta/load-all-data.action';
import { validateFull } from '../validation/validation-fn';
import { dataRepair } from '../validation/data-repair';
import { isDataRepairPossible } from '../validation/is-data-repair-possible.util';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import {
AppDataComplete,
CROSS_MODEL_VERSION,
@ -96,7 +96,7 @@ export class BackupService {
// 2. Migrate legacy backups (pre-v14) that have the old data shape
if (isLegacyBackupData(backupData as unknown as Record<string, unknown>)) {
PFLog.normal(
OpLog.normal(
'BackupService: Detected legacy backup format, running migration...',
);
backupData = migrateLegacyBackup(
@ -110,7 +110,7 @@ export class BackupService {
if (!validationResult.isValid) {
// Try to repair
PFLog.normal('BackupService: Validation failed, attempting repair...', {
OpLog.normal('BackupService: Validation failed, attempting repair...', {
success: validationResult.typiaResult.success,
errors:
'errors' in validationResult.typiaResult
@ -157,24 +157,24 @@ export class BackupService {
importedData: AppDataComplete,
isForceConflict: boolean,
): Promise<void> {
PFLog.normal('BackupService: Persisting import to operation log...');
OpLog.normal('BackupService: Persisting import to operation log...');
// 1. Backup current state before clearing operations
let backupSucceeded = true;
try {
const existingStateCache = await this._opLogStore.loadStateCache();
if (existingStateCache?.state) {
PFLog.normal('BackupService: Backing up current state before import...');
OpLog.normal('BackupService: Backing up current state before import...');
await this._opLogStore.saveImportBackup(existingStateCache.state);
}
} catch (e) {
PFLog.warn('BackupService: Failed to backup state before import:', e);
OpLog.warn('BackupService: Failed to backup state before import:', e);
backupSucceeded = false;
}
// 2. Clear all old operations to prevent IndexedDB bloat
if (backupSucceeded) {
PFLog.normal('BackupService: Clearing old operations before import...');
OpLog.normal('BackupService: Clearing old operations before import...');
await this._opLogStore.clearAllOperations();
}
@ -219,7 +219,7 @@ export class BackupService {
schemaVersion: CURRENT_SCHEMA_VERSION,
});
PFLog.normal('BackupService: Import persisted to operation log.');
OpLog.normal('BackupService: Import persisted to operation log.');
}
/**

View file

@ -42,7 +42,7 @@ import {
initialPluginMetaDataState,
} from '../../plugins/plugin-persistence.model';
import { AppDataComplete } from '../model/model-config';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
const LEGACY_INBOX_PROJECT_ID = 'INBOX' as const;
@ -79,7 +79,7 @@ export const isLegacyBackupData = (data: Record<string, unknown>): boolean => {
export const migrateLegacyBackup = (
legacyData: Record<string, unknown>,
): AppDataComplete => {
PFLog.log('migrateLegacyBackup: Starting legacy backup migration');
OpLog.log('migrateLegacyBackup: Starting legacy backup migration');
let data = { ...legacyData } as Record<string, any>;
@ -113,7 +113,7 @@ export const migrateLegacyBackup = (
// === Final: Strip legacy keys that are not in v17's schema ===
data = _stripLegacyKeys(data);
PFLog.log('migrateLegacyBackup: Migration complete');
OpLog.log('migrateLegacyBackup: Migration complete');
return data as unknown as AppDataComplete;
};
@ -132,7 +132,7 @@ function _migration2ArchiveSplitAndTimeTracking(
if (data.archiveYoung && data.archiveOld && data.timeTracking && !data.taskArchive) {
return data;
}
PFLog.log('migrateLegacyBackup: Running migration 2 (archive split + time tracking)');
OpLog.log('migrateLegacyBackup: Running migration 2 (archive split + time tracking)');
// Extract project time tracking data
const projectTimeTracking: TTWorkContextSessionMap = {};
@ -334,7 +334,7 @@ function _migrateTaskDictionary(taskDict: Dictionary<TaskCopy>): void {
// ---------------------------------------------------------------------------
function _migration3PlannerAndInbox(data: Record<string, any>): Record<string, any> {
PFLog.log('migrateLegacyBackup: Running migration 3 (planner + inbox)');
OpLog.log('migrateLegacyBackup: Running migration 3 (planner + inbox)');
// Migrate planner days → task.dueDay
if (data.planner?.days) {
@ -531,7 +531,7 @@ function _migrateTasksForMigration3(
// ---------------------------------------------------------------------------
function _migration4TaskDateTimeFields(data: Record<string, any>): Record<string, any> {
PFLog.log('migrateLegacyBackup: Running migration 4 (task datetime fields)');
OpLog.log('migrateLegacyBackup: Running migration 4 (task datetime fields)');
if (data.improvement && !Array.isArray(data.improvement.hiddenImprovementBannerItems)) {
data.improvement.hiddenImprovementBannerItems = [];
@ -806,7 +806,7 @@ function _stripLegacyKeys(data: Record<string, any>): Record<string, any> {
if (V17_VALID_KEYS.has(key)) {
stripped[key] = data[key];
} else {
PFLog.log(`migrateLegacyBackup: Stripping legacy key "${key}"`);
OpLog.log(`migrateLegacyBackup: Stripping legacy key "${key}"`);
}
}
return stripped;

View file

@ -1,5 +1,5 @@
import { IValidation } from 'typia';
import { PFLog } from '../../../core/log';
import { OpLog } from '../../../core/log';
/**
* Extracts a meaningful error message from various error shapes.
@ -76,13 +76,13 @@ class AdditionalLogErrorBase<T = unknown[]> extends Error {
super(extractedMessage ?? 'Unknown error');
if (additional.length > 0) {
PFLog.log(this.name, ...additional);
OpLog.log(this.name, ...additional);
try {
// Sanitize before logging to avoid exposing tokens in logs
const sanitized = additional.map(sanitizeForLogging);
PFLog.log('additional error log: ' + JSON.stringify(sanitized));
OpLog.log('additional error log: ' + JSON.stringify(sanitized));
} catch (e) {
PFLog.log('additional error log not stringified: ', additional, e);
OpLog.log('additional error log not stringified: ', additional, e);
}
}
this.additionalLog = additional as T;
@ -376,7 +376,7 @@ export class JsonParseError extends Error {
this.dataSample = `...${dataStr.substring(start, end)}...`;
}
PFLog.err('JsonParseError:', {
OpLog.err('JsonParseError:', {
message: this.message,
position: this.position,
dataSample: this.dataSample,
@ -441,24 +441,24 @@ export class ModelValidationError extends Error {
e?: unknown;
}) {
super('ModelValidationError');
PFLog.log(`ModelValidationError for model ${params.id}:`, params);
OpLog.log(`ModelValidationError for model ${params.id}:`, params);
if (params.validationResult) {
PFLog.log('validation result: ', params.validationResult);
OpLog.log('validation result: ', params.validationResult);
try {
if ('errors' in params.validationResult) {
const str = JSON.stringify(params.validationResult.errors);
PFLog.log('validation errors: ' + str);
OpLog.log('validation errors: ' + str);
this.additionalLog = `Model: ${params.id}, Errors: ${str.substring(0, 400)}`;
}
} catch (e) {
PFLog.err('Error stringifying validation errors:', e);
OpLog.err('Error stringifying validation errors:', e);
}
}
if (params.e) {
PFLog.log('Additional error:', params.e);
OpLog.log('Additional error:', params.e);
}
}
}
@ -470,17 +470,17 @@ export class DataValidationFailedError extends Error {
constructor(validationResult: IValidation<unknown>) {
const errorSummary = DataValidationFailedError._buildErrorSummary(validationResult);
super(errorSummary);
PFLog.log('validation result: ', validationResult);
OpLog.log('validation result: ', validationResult);
try {
if ('errors' in validationResult) {
const str = JSON.stringify(validationResult.errors);
PFLog.log('validation errors_: ' + str);
OpLog.log('validation errors_: ' + str);
this.additionalLog = str.substring(0, 400);
}
PFLog.log('validation result_: ' + JSON.stringify(validationResult));
OpLog.log('validation result_: ' + JSON.stringify(validationResult));
} catch (e) {
PFLog.err('Failed to stringify validation errors:', e);
OpLog.err('Failed to stringify validation errors:', e);
}
}

View file

@ -1,4 +1,4 @@
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import { DecompressError } from '../core/errors/sync-errors';
import {
compressWithGzip,
@ -8,7 +8,7 @@ import {
describe('compression-handler', () => {
beforeEach(() => {
spyOn(PFLog, 'err').and.stub();
spyOn(OpLog, 'err').and.stub();
spyOn(console, 'log').and.stub();
});

View file

@ -1,5 +1,5 @@
import { CompressError, DecompressError } from '../core/errors/sync-errors';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
/**
* Compresses a string using gzip and returns the raw bytes.
@ -15,7 +15,7 @@ export async function compressWithGzip(input: string): Promise<Uint8Array> {
const compressed = await new Response(stream.readable).arrayBuffer();
return new Uint8Array(compressed);
} catch (error) {
PFLog.err(error);
OpLog.err(error);
throw new CompressError(error);
}
}
@ -45,7 +45,7 @@ export async function compressWithGzipToString(input: string): Promise<string> {
reader.readAsDataURL(new Blob([compressed]));
});
} catch (error) {
PFLog.err(error);
OpLog.err(error);
throw new CompressError(error);
}
}
@ -73,7 +73,7 @@ export async function decompressGzipFromString(
const decoded = new TextDecoder().decode(decompressed);
return decoded;
} catch (error) {
PFLog.err(error);
OpLog.err(error);
throw new DecompressError(error);
}
}

View file

@ -1,4 +1,4 @@
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import { JsonParseError } from '../core/errors/sync-errors';
import { EncryptAndCompressHandlerService } from './encrypt-and-compress-handler.service';
import { getErrorTxt } from '../../util/get-error-text';
@ -12,9 +12,9 @@ describe('EncryptAndCompressHandlerService', () => {
beforeEach(() => {
service = new EncryptAndCompressHandlerService();
spyOn(PFLog, 'err').and.stub();
spyOn(PFLog, 'normal').and.stub();
spyOn(PFLog, 'log').and.stub();
spyOn(OpLog, 'err').and.stub();
spyOn(OpLog, 'normal').and.stub();
spyOn(OpLog, 'log').and.stub();
});
describe('decompressAndDecrypt', () => {
@ -112,7 +112,7 @@ describe('EncryptAndCompressHandlerService', () => {
describe('JsonParseError', () => {
beforeEach(() => {
spyOn(PFLog, 'err').and.stub();
spyOn(OpLog, 'err').and.stub();
});
it('should extract position from SyntaxError message', () => {

View file

@ -2,7 +2,7 @@ import {
extractSyncFileStateFromPrefix,
getSyncFilePrefix,
} from '../util/sync-file-prefix';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import {
deriveKeyFromPassword,
encryptWithDerivedKey,
@ -72,7 +72,7 @@ export class EncryptAndCompressHandlerService {
isEncrypt,
modelVersion,
});
PFLog.normal(
OpLog.normal(
`${EncryptAndCompressHandlerService.L}.${this.compressAndEncrypt.name}()`,
{
prefix,
@ -110,7 +110,7 @@ export class EncryptAndCompressHandlerService {
}> {
const { isCompressed, isEncrypted, modelVersion, cleanDataStr } =
extractSyncFileStateFromPrefix(dataStr);
PFLog.normal(
OpLog.normal(
`${EncryptAndCompressHandlerService.L}.${this.decompressAndDecrypt.name}()`,
{ isCompressed, isEncrypted, modelVersion },
);

View file

@ -47,7 +47,7 @@ import { initialTimeTrackingState } from '../../features/time-tracking/store/tim
import { appDataValidators, validateFull } from '../validation/validation-fn';
import { fixEntityStateConsistency } from '../../util/check-fix-entity-state-consistency';
import { IValidation } from 'typia';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import { alertDialog } from '../../util/native-dialogs';
import {
initialPluginMetaDataState,
@ -237,7 +237,7 @@ export const SYNC_CONFIG: BaseSyncConfig<AllModelConfig> = {
const result = validateFull(data);
if (!environment.production && !result.isValid) {
PFLog.log(result);
OpLog.log(result);
alertDialog('VALIDATION ERROR');
}
@ -262,7 +262,7 @@ export const SYNC_CONFIG: BaseSyncConfig<AllModelConfig> = {
return result.typiaResult;
},
onDbError: (err) => {
PFLog.err(err);
OpLog.err(err);
alertDialog('DB ERROR: ' + err);
},
repair: (data: unknown, errors: IValidation.IError[]) => {

View file

@ -1,7 +1,7 @@
import { DBSchema, IDBPDatabase, openDB } from 'idb';
import { SyncProviderId, PRIVATE_CFG_PREFIX } from './provider.const';
import { PrivateCfgByProviderId } from '../core/types/sync.types';
import { PFLog } from '../../core/log';
import { SyncLog } from '../../core/log';
/**
* New database configuration for sync credentials.
@ -78,7 +78,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
* Automatically migrates from legacy database if needed.
*/
async load(): Promise<PrivateCfgByProviderId<PID> | null> {
PFLog.verbose(
SyncLog.verbose(
`${SyncCredentialStore.L}.${this.load.name}`,
this._providerId,
typeof this._privateCfgInMemory,
@ -109,7 +109,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
return loadedConfig ?? null;
} catch (error) {
PFLog.critical(`Failed to load credentials: ${error}`);
SyncLog.critical(`Failed to load credentials: ${error}`);
throw new Error(`Failed to load credentials: ${error}`);
}
}
@ -149,7 +149,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
* Clears the provider's credentials.
*/
async clear(): Promise<void> {
PFLog.normal(`${SyncCredentialStore.L}.clear()`, this._providerId);
SyncLog.normal(`${SyncCredentialStore.L}.clear()`, this._providerId);
this._privateCfgInMemory = undefined;
@ -157,7 +157,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
const db = await this._ensureDb();
await db.delete(DB_STORE_NAME, this._dbKey);
} catch (error) {
PFLog.critical(`Failed to clear credentials: ${error}`);
SyncLog.critical(`Failed to clear credentials: ${error}`);
throw new Error(`Failed to clear credentials: ${error}`);
}
}
@ -181,17 +181,17 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
// Create the credentials store if it doesn't exist
if (!database.objectStoreNames.contains(DB_STORE_NAME)) {
database.createObjectStore(DB_STORE_NAME);
PFLog.normal(
SyncLog.normal(
`[${SyncCredentialStore.L}] Created ${DB_STORE_NAME} object store`,
);
}
},
});
PFLog.verbose(
SyncLog.verbose(
`[${SyncCredentialStore.L}] Database connection initialized for ${this._providerId}`,
);
} catch (e) {
PFLog.err(`[${SyncCredentialStore.L}] Failed to initialize database`, e);
SyncLog.err(`[${SyncCredentialStore.L}] Failed to initialize database`, e);
this._initPromise = undefined; // Allow retry
throw e;
}
@ -239,7 +239,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
legacyDb.close();
if (legacyConfig) {
PFLog.normal(
SyncLog.normal(
`[${SyncCredentialStore.L}] Migrating credentials for ${this._providerId} from legacy database`,
);
@ -250,7 +250,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
return null;
} catch (error) {
PFLog.warn(
SyncLog.warn(
`[${SyncCredentialStore.L}] Failed to migrate from legacy database (this is ok for new installs): ${error}`,
);
return null;
@ -266,7 +266,7 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
const encryptKeyInfo = cfgWithRedacted?.encryptKey
? `[length=${cfgWithRedacted.encryptKey.length}]`
: '[not set]';
PFLog.normal(
SyncLog.normal(
`${SyncCredentialStore.L}._save()`,
this._providerId,
`encryptKey=${encryptKeyInfo}`,
@ -286,13 +286,13 @@ export class SyncCredentialStore<PID extends SyncProviderId> {
try {
const db = await this._ensureDb();
await db.put(DB_STORE_NAME, privateCfg, this._dbKey);
PFLog.normal(
SyncLog.normal(
`${SyncCredentialStore.L}._save() SUCCESS`,
this._providerId,
`wrote to ${DB_STORE_NAME}/${this._dbKey}`,
);
} catch (error) {
PFLog.critical(`Failed to save credentials: ${error}`);
SyncLog.critical(`Failed to save credentials: ${error}`);
throw new Error(`Failed to save credentials: ${error}`);
}
}

View file

@ -14,7 +14,7 @@ import {
TooManyRequestsAPIError,
UploadRevToMatchMismatchAPIError,
} from '../../../core/errors/sync-errors';
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
import { SyncProviderServiceInterface } from '../../provider.interface';
import { SyncProviderId } from '../../provider.const';
import { tryCatchInlineAsync } from '../../../../util/try-catch-inline';
@ -100,7 +100,7 @@ export class DropboxApi {
* List folder contents
*/
async listFiles(path: string): Promise<string[]> {
PFLog.normal(`${DropboxApi.L}.listFiles() for path: ${path}`);
SyncLog.normal(`${DropboxApi.L}.listFiles() for path: ${path}`);
try {
const response = await this._request({
method: 'POST',
@ -116,7 +116,7 @@ export class DropboxApi {
.filter((entry) => entry['.tag'] === 'file') // Only return files
.map((entry) => entry.path_lower); // Return full path in lower case
} catch (e) {
PFLog.critical(`${DropboxApi.L}.listFiles() error for path: ${path}`, e);
SyncLog.critical(`${DropboxApi.L}.listFiles() error for path: ${path}`, e);
this._checkCommonErrors(e, path);
throw e;
}
@ -140,7 +140,7 @@ export class DropboxApi {
});
return response.json();
} catch (e) {
PFLog.critical(`${DropboxApi.L}.getMetaData() error for path: ${path}`, e);
SyncLog.critical(`${DropboxApi.L}.getMetaData() error for path: ${path}`, e);
this._checkCommonErrors(e, path);
throw e;
}
@ -183,7 +183,7 @@ export class DropboxApi {
return { meta, data: data as unknown as T };
} catch (e) {
PFLog.critical(`${DropboxApi.L}.download() error for path: ${path}`, e);
SyncLog.critical(`${DropboxApi.L}.download() error for path: ${path}`, e);
this._checkCommonErrors(e, path);
throw e;
}
@ -236,7 +236,7 @@ export class DropboxApi {
return result;
} catch (e) {
PFLog.critical(`${DropboxApi.L}.upload() error for path: ${path}`, e);
SyncLog.critical(`${DropboxApi.L}.upload() error for path: ${path}`, e);
this._checkCommonErrors(e, path);
throw e;
}
@ -255,7 +255,7 @@ export class DropboxApi {
});
return response.json();
} catch (e) {
PFLog.critical(`${DropboxApi.L}.remove() error for path: ${path}`, e);
SyncLog.critical(`${DropboxApi.L}.remove() error for path: ${path}`, e);
this._checkCommonErrors(e, path);
throw e;
}
@ -278,7 +278,7 @@ export class DropboxApi {
});
return response.json();
} catch (e) {
PFLog.critical(`${DropboxApi.L}.checkUser() error`, e);
SyncLog.critical(`${DropboxApi.L}.checkUser() error`, e);
this._checkCommonErrors(e, 'check/user');
throw e;
}
@ -288,13 +288,13 @@ export class DropboxApi {
* Refresh access token using refresh token
*/
async updateAccessTokenFromRefreshTokenIfAvailable(): Promise<void> {
PFLog.normal(`${DropboxApi.L}.updateAccessTokenFromRefreshTokenIfAvailable()`);
SyncLog.normal(`${DropboxApi.L}.updateAccessTokenFromRefreshTokenIfAvailable()`);
const privateCfg = await this._parent.privateCfg.load();
const refreshToken = privateCfg?.refreshToken;
if (!refreshToken) {
PFLog.critical('Dropbox: No refresh token available');
SyncLog.critical('Dropbox: No refresh token available');
await this._clearTokensIfPresent(privateCfg);
throw new MissingRefreshTokenAPIError();
}
@ -362,14 +362,14 @@ export class DropboxApi {
data = (await response.json()) as TokenResponse;
}
PFLog.normal('Dropbox: Refresh access token Response', data);
SyncLog.normal('Dropbox: Refresh access token Response', data);
await this._parent.privateCfg.updatePartial({
accessToken: data.access_token,
refreshToken: data.refresh_token || privateCfg?.refreshToken,
});
} catch (e) {
PFLog.critical('Failed to refresh Dropbox access token', e);
SyncLog.critical('Failed to refresh Dropbox access token', e);
throw e;
}
}
@ -470,7 +470,7 @@ export class DropboxApi {
expiresAt: +data.expires_in * 1000 + Date.now(),
};
} catch (e) {
PFLog.critical(`${DropboxApi.L}.getTokensFromAuthCode() error`, e);
SyncLog.critical(`${DropboxApi.L}.getTokensFromAuthCode() error`, e);
throw e;
}
}
@ -530,7 +530,7 @@ export class DropboxApi {
}
try {
PFLog.log(`${DropboxApi.L}._requestNative() ${method} ${requestUrl}`);
SyncLog.log(`${DropboxApi.L}._requestNative() ${method} ${requestUrl}`);
const capacitorResponse = await CapacitorHttp.request({
url: requestUrl,
@ -570,7 +570,7 @@ export class DropboxApi {
return response;
} catch (e) {
PFLog.critical(`${DropboxApi.L}._requestNative() error for ${url}`, e);
SyncLog.critical(`${DropboxApi.L}._requestNative() error for ${url}`, e);
this._checkCommonErrors(e, url);
throw e;
}
@ -693,7 +693,7 @@ export class DropboxApi {
return response;
} catch (e) {
PFLog.critical(`${DropboxApi.L}._request() error for ${url}`, e);
SyncLog.critical(`${DropboxApi.L}._request() error for ${url}`, e);
this._checkCommonErrors(e, url);
throw e;
}
@ -773,7 +773,7 @@ export class DropboxApi {
return new Promise((resolve, reject) => {
setTimeout(
() => {
PFLog.normal(`Too many requests ${path}, retrying in ${retryAfter}s...`);
SyncLog.normal(`Too many requests ${path}, retrying in ${retryAfter}s...`);
originalRequestExecutor()
.then(resolve as (value: unknown) => void)
.catch(reject);

View file

@ -9,7 +9,7 @@ import {
RemoteFileNotFoundAPIError,
NoRevAPIError,
} from '../../../core/errors/sync-errors';
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
import { DropboxApi } from './dropbox-api';
import { generatePKCECodes } from './generate-pkce-codes';
import { SyncCredentialStore } from '../../credential-store.service';
@ -87,7 +87,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
};
} catch (e) {
if (this._isTokenError(e)) {
PFLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
SyncLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
await this._api.updateAccessTokenFromRefreshTokenIfAvailable();
return this.getFileRev(targetPath, localRev);
}
@ -128,7 +128,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
}
if (typeof r.data !== 'string') {
PFLog.critical(`${Dropbox.L}.${this.downloadFile.name}() data`, r.data);
SyncLog.critical(`${Dropbox.L}.${this.downloadFile.name}() data`, r.data);
throw new InvalidDataSPError(r.data);
}
@ -138,7 +138,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
};
} catch (e) {
if (this._isTokenError(e)) {
PFLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
SyncLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
await this._api.updateAccessTokenFromRefreshTokenIfAvailable();
return this.downloadFile(targetPath);
}
@ -168,7 +168,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
try {
const current = await this.getFileRev(targetPath, '');
effectiveRev = current.rev;
PFLog.normal(
SyncLog.normal(
`${Dropbox.L}.${this.uploadFile.name}() got current rev for conditional upload: ${effectiveRev}`,
);
} catch (e) {
@ -176,7 +176,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
throw e;
}
// File doesn't exist - proceed without rev (will create new)
PFLog.normal(
SyncLog.normal(
`${Dropbox.L}.${this.uploadFile.name}() file does not exist, will create new`,
);
}
@ -199,7 +199,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
};
} catch (e) {
if (this._isTokenError(e)) {
PFLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
SyncLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
await this._api.updateAccessTokenFromRefreshTokenIfAvailable();
return this.uploadFile(targetPath, dataStr, revToMatch, isForceOverwrite);
}
@ -218,7 +218,7 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
await this._api.remove(this._getPath(targetPath));
} catch (e) {
if (this._isTokenError(e)) {
PFLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
SyncLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
await this._api.updateAccessTokenFromRefreshTokenIfAvailable();
return this.removeFile(targetPath);
}
@ -236,13 +236,13 @@ export class Dropbox implements SyncProviderServiceInterface<SyncProviderId.Drop
}
async listFiles(dirPath: string): Promise<string[]> {
PFLog.normal(`${Dropbox.L}.${this.listFiles.name}()`, { dirPath });
SyncLog.normal(`${Dropbox.L}.${this.listFiles.name}()`, { dirPath });
try {
// DropboxApi.listFiles now returns full paths, so no need to prepend _getPath
return await this._api.listFiles(this._getPath(dirPath));
} catch (e) {
if (this._isTokenError(e)) {
PFLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
SyncLog.critical('EXPIRED or INVALID TOKEN, trying to refresh');
await this._api.updateAccessTokenFromRefreshTokenIfAvailable();
return this.listFiles(dirPath);
}

View file

@ -111,7 +111,7 @@ describe('SafFileAdapter', () => {
await adapter.deleteFile('missing.json');
expect(console.error).toHaveBeenCalledWith(
'[pf]',
'[sync]',
'File not found for deletion: missing.json',
);
});

View file

@ -1,6 +1,6 @@
import { FileAdapter } from '../file-adapter.interface';
import { SafService } from './saf.service';
import { PFLog } from '../../../../../core/log';
import { SyncLog } from '../../../../../core/log';
export class SafFileAdapter implements FileAdapter {
constructor(private getUri: () => Promise<string | undefined>) {}
@ -38,7 +38,7 @@ export class SafFileAdapter implements FileAdapter {
} catch (error) {
// Ignore file not found errors
if (error?.toString?.().includes('File not found')) {
PFLog.err(`File not found for deletion: ${filePath}`);
SyncLog.err(`File not found for deletion: ${filePath}`);
return;
}
throw error;
@ -53,7 +53,7 @@ export class SafFileAdapter implements FileAdapter {
// TODO: implement for operation log sync
async listFiles?(dirPath: string): Promise<string[]> {
PFLog.warn('SafFileAdapter: listFiles is not yet implemented for Android SAF.');
SyncLog.warn('SafFileAdapter: listFiles is not yet implemented for Android SAF.');
throw new Error('SafFileAdapter: listFiles is not yet implemented.');
}
}

View file

@ -1,6 +1,6 @@
/* eslint-disable */
import { Capacitor, registerPlugin } from '@capacitor/core';
import { PFLog } from '../../../../../core/log';
import { SyncLog } from '../../../../../core/log';
// Define the plugin interface for SAF operations
export interface SafPlugin {
@ -71,7 +71,7 @@ export class SafService {
const result = await SafBridge.checkUriPermission({ uri });
return result.hasPermission;
} catch (error) {
PFLog.err('Error checking SAF permission:', error);
SyncLog.err('Error checking SAF permission:', error);
return false;
}
}
@ -110,7 +110,7 @@ export class SafService {
const result = await SafBridge.checkFileExists({ uri, fileName });
return result.exists;
} catch (error) {
PFLog.err('Error checking file existence:', error);
SyncLog.err('Error checking file existence:', error);
return false;
}
}

View file

@ -60,7 +60,7 @@ export class ElectronFileAdapter implements FileAdapter {
// }
// return result;
// } catch (e) {
// PFLog.critical( `ElectronFileAdapter.checkDirExists() error`, e);
// SyncLog.critical( `ElectronFileAdapter.checkDirExists() error`, e);
// return false;
// }
// }
@ -69,7 +69,7 @@ export class ElectronFileAdapter implements FileAdapter {
// try {
// return await this.ea.pickDirectory();
// } catch (e) {
// PFLog.critical( `ElectronFileAdapter.pickDirectory() error`, e);
// SyncLog.critical( `ElectronFileAdapter.pickDirectory() error`, e);
// throw e;
// }
// }

View file

@ -3,7 +3,7 @@ import { LocalFileSyncBase } from './local-file-sync-base';
import { LocalFileSyncPrivateCfg } from '../../../core/types/sync.types';
import { SafService } from './droid-saf/saf.service';
import { SafFileAdapter } from './droid-saf/saf-file-adapter';
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
export class LocalFileSyncAndroid extends LocalFileSyncBase {
constructor(public directory = Directory.Documents) {
@ -38,7 +38,7 @@ export class LocalFileSyncAndroid extends LocalFileSyncBase {
});
return uri;
} catch (error) {
PFLog.err('Failed to setup SAF:', error);
SyncLog.err('Failed to setup SAF:', error);
return undefined;
}
}

View file

@ -11,7 +11,7 @@ import {
WebCryptoNotAvailableError,
} from '../../../core/errors/sync-errors';
import { md5HashPromise } from '../../../../util/md5-hash';
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
import { PrivateCfgByProviderId } from '../../../core/types/sync.types';
export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<SyncProviderId.LocalFile> {
@ -36,7 +36,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
protected abstract getFilePath(targetPath: string): Promise<string>;
async listFiles(dirPath: string): Promise<string[]> {
PFLog.normal(`${LocalFileSyncBase.LB}.${this.listFiles.name}()`, { dirPath });
SyncLog.normal(`${LocalFileSyncBase.LB}.${this.listFiles.name}()`, { dirPath });
if (!this.fileAdapter.listFiles) {
throw new Error('FileAdapter does not support listFiles');
}
@ -46,7 +46,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
}
async getFileRev(targetPath: string, localRev: string): Promise<{ rev: string }> {
PFLog.normal(`${LocalFileSyncBase.LB}.${this.getFileRev.name}`, {
SyncLog.normal(`${LocalFileSyncBase.LB}.${this.getFileRev.name}`, {
targetPath,
localRev,
});
@ -54,13 +54,13 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
const r = await this.downloadFile(targetPath);
return { rev: r.rev };
} catch (e) {
PFLog.critical(`${LocalFileSyncBase.LB}.${this.getFileRev.name} error`, e);
SyncLog.critical(`${LocalFileSyncBase.LB}.${this.getFileRev.name} error`, e);
throw e;
}
}
async downloadFile(targetPath: string): Promise<{ rev: string; dataStr: string }> {
PFLog.normal(`${LocalFileSyncBase.LB}.${this.downloadFile.name}()`, {
SyncLog.normal(`${LocalFileSyncBase.LB}.${this.downloadFile.name}()`, {
targetPath,
});
@ -90,7 +90,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
throw new RemoteFileNotFoundAPIError(targetPath);
}
PFLog.critical(`${LocalFileSyncBase.LB}.${this.downloadFile.name}() error`, e);
SyncLog.critical(`${LocalFileSyncBase.LB}.${this.downloadFile.name}() error`, e);
throw e;
}
}
@ -101,7 +101,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
revToMatch: string | null,
isForceOverwrite: boolean = false,
): Promise<{ rev: string }> {
PFLog.normal(`${LocalFileSyncBase.LB}.${this.uploadFile.name}()`, {
SyncLog.normal(`${LocalFileSyncBase.LB}.${this.uploadFile.name}()`, {
targetPath,
dataLength: dataStr?.length,
revToMatch,
@ -114,7 +114,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
try {
const existingFile = await this.downloadFile(targetPath);
if (existingFile.rev !== revToMatch) {
PFLog.critical(
SyncLog.critical(
`${LocalFileSyncBase.LB}.${this.uploadFile.name}() rev mismatch`,
existingFile.rev,
revToMatch,
@ -135,13 +135,13 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
const newRev = await this._getLocalRev(dataStr);
return { rev: newRev };
} catch (e) {
PFLog.critical(`${LocalFileSyncBase.LB}.${this.uploadFile.name}() error`, e);
SyncLog.critical(`${LocalFileSyncBase.LB}.${this.uploadFile.name}() error`, e);
throw e;
}
}
async removeFile(targetPath: string): Promise<void> {
PFLog.normal(`${LocalFileSyncBase.LB}.${this.removeFile.name}`, { targetPath });
SyncLog.normal(`${LocalFileSyncBase.LB}.${this.removeFile.name}`, { targetPath });
try {
const filePath = await this.getFilePath(targetPath);
await this.fileAdapter.deleteFile(filePath);
@ -152,7 +152,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
e?.toString?.().includes('File does not exist') ||
e?.toString?.().includes('ENOENT')
) {
PFLog.normal(
SyncLog.normal(
`${LocalFileSyncBase.LB}.${this.removeFile.name} - file doesn't exist`,
{
targetPath,
@ -161,7 +161,7 @@ export abstract class LocalFileSyncBase implements SyncProviderServiceInterface<
return;
}
PFLog.critical(`${LocalFileSyncBase.LB}.${this.removeFile.name} error`, e);
SyncLog.critical(`${LocalFileSyncBase.LB}.${this.removeFile.name} error`, e);
throw e;
}
}

View file

@ -1,6 +1,6 @@
import { LocalFileSyncBase } from './local-file-sync-base';
import { IS_ELECTRON } from '../../../../app.constants';
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
import { ElectronFileAdapter } from './electron-file-adapter';
import { LocalFileSyncPrivateCfg } from '../../../core/types/sync.types';
@ -33,7 +33,7 @@ export class LocalFileSyncElectron extends LocalFileSyncBase {
}
private async _checkDirAndOpenPickerIfNotExists(): Promise<void> {
PFLog.normal(
SyncLog.normal(
`${LocalFileSyncElectron.L}.${this._checkDirAndOpenPickerIfNotExists.name}`,
);
@ -42,11 +42,13 @@ export class LocalFileSyncElectron extends LocalFileSyncBase {
const isDirExists = await this._checkDirExists(folderPath);
if (!isDirExists) {
PFLog.critical(`${LocalFileSyncElectron.L} - No valid directory, opening picker`);
SyncLog.critical(
`${LocalFileSyncElectron.L} - No valid directory, opening picker`,
);
await this.pickDirectory();
}
} catch (err) {
PFLog.error(
SyncLog.error(
`${LocalFileSyncElectron.L}.${this._checkDirAndOpenPickerIfNotExists.name}() error`,
err,
);
@ -73,7 +75,7 @@ export class LocalFileSyncElectron extends LocalFileSyncBase {
}
return r;
} catch (e) {
PFLog.critical(
SyncLog.critical(
`${LocalFileSyncElectron.L}.${this._checkDirExists.name}() error`,
e,
);
@ -82,7 +84,7 @@ export class LocalFileSyncElectron extends LocalFileSyncBase {
}
async pickDirectory(): Promise<string | void> {
PFLog.normal(`${LocalFileSyncElectron.L}.pickDirectory()`);
SyncLog.normal(`${LocalFileSyncElectron.L}.pickDirectory()`);
try {
const dir = await (window as any).ea.pickDirectory();
@ -91,7 +93,7 @@ export class LocalFileSyncElectron extends LocalFileSyncBase {
}
return dir;
} catch (e) {
PFLog.critical(`${LocalFileSyncElectron.L}.pickDirectory() error`, e);
SyncLog.critical(`${LocalFileSyncElectron.L}.pickDirectory() error`, e);
throw e;
}
}

View file

@ -1,5 +1,5 @@
import { WebdavPrivateCfg } from './webdav.model';
import { Log, PFLog } from '../../../../core/log';
import { Log, SyncLog } from '../../../../core/log';
import { FileMeta, WebdavXmlParser } from './webdav-xml-parser';
import { WebDavHttpAdapter, WebDavHttpResponse } from './webdav-http-adapter';
import {
@ -63,7 +63,7 @@ export class WebdavApi {
});
throw new HttpNotOkAPIError(errorResponse); // Other errors
} catch (e) {
PFLog.error(`${WebdavApi.L}.listFiles() error for path: ${dirPath}`, e);
SyncLog.error(`${WebdavApi.L}.listFiles() error for path: ${dirPath}`, e);
// Handle "Not Found" error specifically to return empty array
if (
e instanceof HttpNotOkAPIError &&
@ -102,7 +102,7 @@ export class WebdavApi {
const files = this.xmlParser.parseMultiplePropsFromXml(response.data, path);
if (files && files.length > 0) {
const meta = files[0];
PFLog.verbose(`${WebdavApi.L}.getFileMeta() PROPFIND success for ${path}`, {
SyncLog.verbose(`${WebdavApi.L}.getFileMeta() PROPFIND success for ${path}`, {
lastmod: meta.lastmod,
});
return meta;
@ -111,14 +111,14 @@ export class WebdavApi {
} catch (e) {
// If PROPFIND fails and fallback is enabled, try HEAD
if (useGetFallback) {
PFLog.verbose(
SyncLog.verbose(
`${WebdavApi.L}.getFileMeta() PROPFIND failed, trying HEAD fallback`,
e,
);
try {
return await this._getFileMetaViaHead(fullPath);
} catch (headErr) {
PFLog.warn(
SyncLog.warn(
`${WebdavApi.L}.getFileMeta() HEAD fallback failed for ${path}`,
headErr,
);
@ -126,7 +126,7 @@ export class WebdavApi {
// Usually the original PROPFIND error is more informative about connectivity
}
}
PFLog.error(`${WebdavApi.L}.getFileMeta() error`, { path, error: e });
SyncLog.error(`${WebdavApi.L}.getFileMeta() error`, { path, error: e });
throw e;
}
@ -183,7 +183,7 @@ export class WebdavApi {
// Fallback: Some servers may omit Last-Modified on GET, so request metadata separately
if (isLastModifiedMissing) {
PFLog.verbose(
SyncLog.verbose(
`${WebdavApi.L}.download() missing Last-Modified header, trying metadata fallback for ${path}`,
);
try {
@ -199,20 +199,23 @@ export class WebdavApi {
}
}
} catch (e) {
PFLog.warn(`${WebdavApi.L}.download() metadata fallback failed for ${path}`, e);
SyncLog.warn(
`${WebdavApi.L}.download() metadata fallback failed for ${path}`,
e,
);
}
}
// Fallback to ETag if Last-Modified is still not available
if (!rev && legacyRev) {
rev = legacyRev;
PFLog.warn(
SyncLog.warn(
`${WebdavApi.L}.download() no Last-Modified for ${path}, using ETag as revision.`,
);
}
if (!rev) {
PFLog.err(
SyncLog.err(
`${WebdavApi.L}.download() no revision markers (Last-Modified or ETag) found for ${path}. ` +
`Check your WebDAV server or reverse proxy configuration.`,
);
@ -226,7 +229,7 @@ export class WebdavApi {
lastModified,
};
} catch (e) {
PFLog.error(`${WebdavApi.L}.download() error`, { path, error: e });
SyncLog.error(`${WebdavApi.L}.download() error`, { path, error: e });
throw e;
}
}
@ -308,7 +311,7 @@ export class WebdavApi {
// If we get a 409 Conflict, it might be because parent directory doesn't exist
uploadError.response.status === WebDavHttpStatus.CONFLICT)
) {
PFLog.debug(
SyncLog.debug(
`${WebdavApi.L}.upload() got 409 Conflict for ${fullPath}. ` +
`This often indicates the sync folder path is misconfigured. ` +
`Attempting to create parent directory...`,
@ -332,7 +335,7 @@ export class WebdavApi {
retryError.response &&
retryError.response.status === WebDavHttpStatus.CONFLICT
) {
PFLog.err(
SyncLog.err(
`${WebdavApi.L}.upload() 409 Conflict persists for ${fullPath} after creating parent directory. ` +
`Verify your syncFolderPath is relative to the WebDAV server root, ` +
`not your server's internal directory path.`,
@ -358,7 +361,7 @@ export class WebdavApi {
if (!rev) {
// Some WebDAV servers don't return Last-Modified on PUT
// Try to get it from a HEAD request first (cheaper than PROPFIND)
PFLog.verbose(
SyncLog.verbose(
`${WebdavApi.L}.upload() no Last-Modified in PUT response, fetching via HEAD`,
);
try {
@ -378,7 +381,7 @@ export class WebdavApi {
return { rev, legacyRev: headLegacyRev, lastModified: rev };
}
} catch (headError) {
PFLog.verbose(
SyncLog.verbose(
`${WebdavApi.L}.upload() HEAD request failed, falling back to PROPFIND`,
headError,
);
@ -398,7 +401,7 @@ export class WebdavApi {
return { rev, legacyRev, lastModified };
} catch (e) {
PFLog.error(`${WebdavApi.L}.upload() error`, { path, error: e });
SyncLog.error(`${WebdavApi.L}.upload() error`, { path, error: e });
throw e;
}
}
@ -427,9 +430,9 @@ export class WebdavApi {
headers,
});
PFLog.verbose(`${WebdavApi.L}.remove() success for ${path}`);
SyncLog.verbose(`${WebdavApi.L}.remove() success for ${path}`);
} catch (e) {
PFLog.error(`${WebdavApi.L}.remove() error`, { path, error: e });
SyncLog.error(`${WebdavApi.L}.remove() error`, { path, error: e });
throw e;
}
}
@ -438,7 +441,7 @@ export class WebdavApi {
cfg: WebdavPrivateCfg,
): Promise<{ success: boolean; error?: string; fullUrl: string }> {
const fullPath = this._buildFullPath(cfg.baseUrl, cfg.syncFolderPath || '/');
PFLog.verbose(`${WebdavApi.L}.testConnection() testing ${fullPath}`);
SyncLog.verbose(`${WebdavApi.L}.testConnection() testing ${fullPath}`);
try {
// Build authorization header
@ -461,7 +464,7 @@ export class WebdavApi {
response.status === WebDavHttpStatus.MULTI_STATUS ||
response.status === WebDavHttpStatus.OK
) {
PFLog.verbose(`${WebdavApi.L}.testConnection() success for ${fullPath}`);
SyncLog.verbose(`${WebdavApi.L}.testConnection() success for ${fullPath}`);
return { success: true, fullUrl: fullPath };
}
@ -472,7 +475,7 @@ export class WebdavApi {
};
} catch (e) {
const errorMessage = e instanceof Error ? e.message : 'Unknown error occurred';
PFLog.warn(`${WebdavApi.L}.testConnection() failed for ${fullPath}`, e);
SyncLog.warn(`${WebdavApi.L}.testConnection() failed for ${fullPath}`, e);
return { success: false, error: errorMessage, fullUrl: fullPath };
}
}
@ -492,7 +495,7 @@ export class WebdavApi {
*/
async testConditionalHeaders(testPath: string): Promise<boolean> {
const testContent = `test-${Date.now()}`;
PFLog.normal(
SyncLog.normal(
`${WebdavApi.L}.testConditionalHeaders() testing with path: ${testPath}`,
);
@ -509,7 +512,7 @@ export class WebdavApi {
const currentRev = meta.lastmod;
if (!currentRev) {
PFLog.warn(
SyncLog.warn(
`${WebdavApi.L}.testConditionalHeaders() Server did not return lastmod - cannot test conditional headers`,
);
return false;
@ -524,13 +527,13 @@ export class WebdavApi {
expectedRev: oldDate,
});
// Upload succeeded when it should have failed with 412
PFLog.warn(
SyncLog.warn(
`${WebdavApi.L}.testConditionalHeaders() Server ignored If-Unmodified-Since header - conditional headers NOT supported`,
);
return false; // Headers NOT supported
} catch (e) {
if (e instanceof RemoteFileChangedUnexpectedly) {
PFLog.normal(
SyncLog.normal(
`${WebdavApi.L}.testConditionalHeaders() Server properly returned 412 - conditional headers ARE supported`,
);
return true; // Headers ARE supported (got 412 as expected)
@ -594,7 +597,7 @@ export class WebdavApi {
// Check if we're already creating this directory
const existingPromise = this.directoryCreationQueue.get(parentPath);
if (existingPromise) {
PFLog.verbose(
SyncLog.verbose(
`${WebdavApi.L}._ensureParentDirectory() waiting for existing creation of ${parentPath}`,
);
await existingPromise;
@ -620,7 +623,7 @@ export class WebdavApi {
url: path,
method: WebDavHttpMethod.MKCOL,
});
PFLog.verbose(`${WebdavApi.L}._createDirectory() created ${path}`);
SyncLog.verbose(`${WebdavApi.L}._createDirectory() created ${path}`);
} catch (e) {
// Check if error is due to directory already existing (405 Method Not Allowed or 409 Conflict)
if (
@ -631,12 +634,12 @@ export class WebdavApi {
e.response.status === WebDavHttpStatus.MOVED_PERMANENTLY || // Moved permanently - directory exists
e.response.status === WebDavHttpStatus.OK) // OK - directory exists
) {
PFLog.verbose(
SyncLog.verbose(
`${WebdavApi.L}._createDirectory() directory likely exists: ${path} (status: ${e.response.status})`,
);
} else {
// Log other errors but don't throw - we'll let the actual upload fail if needed
PFLog.warn(`${WebdavApi.L}._createDirectory() unexpected error for ${path}`, e);
SyncLog.warn(`${WebdavApi.L}._createDirectory() unexpected error for ${path}`, e);
}
}
}
@ -742,7 +745,7 @@ export class WebdavApi {
let effectiveLastmod = lastModified;
if (!lastModified && etag) {
effectiveLastmod = this._cleanRev(etag);
PFLog.warn(
SyncLog.warn(
`${WebdavApi.L}._getFileMetaViaHead() No Last-Modified header for ${fullPath}, using ETag as revision. ` +
`This may indicate a reverse proxy or server configuration issue.`,
);
@ -767,7 +770,7 @@ export class WebdavApi {
size = parsedSize;
}
} catch (e) {
PFLog.warn(
SyncLog.warn(
`${WebdavApi.L}._getFileMetaViaHead() invalid content-length: ${contentLength}`,
);
}

View file

@ -1,5 +1,5 @@
import { registerPlugin } from '@capacitor/core';
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
import {
AuthFailSPError,
PotentialCorsError,
@ -59,7 +59,7 @@ export class WebDavHttpAdapter {
// On native platforms (Android + iOS), use the WebDavHttp plugin.
// This bypasses CapacitorHttp which has issues with WebDAV responses
// (empty bodies on Android/Koofr, broken JSON auto-parsing on iOS).
PFLog.log(
SyncLog.log(
`${WebDavHttpAdapter.L}.request() using WebDavHttp for ${options.method}`,
);
const webdavResponse = await WebDavHttp.request({
@ -105,7 +105,7 @@ export class WebDavHttpAdapter {
throw e;
}
PFLog.error(`${WebDavHttpAdapter.L}.request() error`, {
SyncLog.error(`${WebDavHttpAdapter.L}.request() error`, {
url: options.url,
method: options.method,
error: e,
@ -198,7 +198,7 @@ export class WebDavHttpAdapter {
// However, without making a test request, we can't be certain
// Log a warning about the ambiguity
PFLog.warn(
SyncLog.warn(
`${WebDavHttpAdapter.L}._isCorsError() Ambiguous network error - might be CORS:`,
error,
);

View file

@ -1,4 +1,4 @@
import { PFLog } from '../../../../core/log';
import { SyncLog } from '../../../../core/log';
import { RemoteFileNotFoundAPIError } from '../../../core/errors/sync-errors';
export interface FileMeta {
@ -48,7 +48,7 @@ export class WebdavXmlParser {
: WebdavXmlParser.MAX_XML_SIZE * 10; // Allow larger files for actual file content (100MB)
if (content.length > maxSize) {
PFLog.error(
SyncLog.error(
`${WebdavXmlParser.L}.validateResponseContent() Content too large: ${content.length} bytes`,
);
throw new Error(
@ -57,7 +57,7 @@ export class WebdavXmlParser {
}
if (this.isHtmlResponse(content)) {
PFLog.error(
SyncLog.error(
`${WebdavXmlParser.L}.${operation}() received HTML error page instead of ${expectedContentDescription}`,
{
path,
@ -86,7 +86,7 @@ export class WebdavXmlParser {
parseMultiplePropsFromXml(xmlText: string, basePath: string): FileMeta[] {
// Validate XML size
if (xmlText.length > WebdavXmlParser.MAX_XML_SIZE) {
PFLog.error(
SyncLog.error(
`${WebdavXmlParser.L}.parseMultiplePropsFromXml() XML too large: ${xmlText.length} bytes`,
);
throw new RemoteFileNotFoundAPIError(
@ -96,7 +96,7 @@ export class WebdavXmlParser {
// Basic XML validation
if (!xmlText.trim().startsWith('<?xml') && !xmlText.trim().startsWith('<')) {
PFLog.error(
SyncLog.error(
`${WebdavXmlParser.L}.parseMultiplePropsFromXml() Invalid XML: doesn't start with <?xml or <`,
);
return [];
@ -108,7 +108,7 @@ export class WebdavXmlParser {
const parserError = xmlDoc.querySelector('parsererror');
if (parserError) {
PFLog.err(
SyncLog.err(
`${WebdavXmlParser.L}.parseMultiplePropsFromXml() XML parsing error`,
parserError.textContent,
);
@ -147,7 +147,10 @@ export class WebdavXmlParser {
return results;
} catch (error) {
PFLog.err(`${WebdavXmlParser.L}.parseMultiplePropsFromXml() parsing error`, error);
SyncLog.err(
`${WebdavXmlParser.L}.parseMultiplePropsFromXml() parsing error`,
error,
);
return [];
}
}

View file

@ -11,7 +11,7 @@ import {
import { Store } from '@ngrx/store';
import { selectSyncConfig } from '../../features/config/store/global-config.reducer';
import { DataInitStateService } from '../../core/data-init/data-init-state.service';
import { PFLog } from '../../core/log';
import { SyncLog } from '../../core/log';
import { SyncProviderId, toSyncProviderId } from './provider.const';
import { SyncProviderServiceInterface } from './provider.interface';
import {
@ -177,11 +177,11 @@ export class SyncProviderManager {
};
}
} catch (e) {
PFLog.err('SyncProviderManager: Failed to set sync provider:', e);
SyncLog.err('SyncProviderManager: Failed to set sync provider:', e);
}
});
PFLog.normal('SyncProviderManager: Initialized');
SyncLog.normal('SyncProviderManager: Initialized');
}
/**
@ -296,9 +296,9 @@ export class SyncProviderManager {
});
});
PFLog.normal(`SyncProviderManager: Active provider set to ${providerId}`);
SyncLog.normal(`SyncProviderManager: Active provider set to ${providerId}`);
} else {
PFLog.err(`SyncProviderManager: Provider not found: ${providerId}`);
SyncLog.err(`SyncProviderManager: Provider not found: ${providerId}`);
}
}
}

View file

@ -3,7 +3,7 @@ import { createAppDataCompleteMock } from '../../util/app-data-mock';
import { createValidate } from 'typia';
import { initialTaskState } from '../../features/tasks/store/task.reducer';
import { DEFAULT_TASK, TaskState } from '../../features/tasks/task.model';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
interface TestInterface {
globalConfig: {
@ -24,8 +24,8 @@ describe('autoFixTypiaErrors', () => {
let errSpy: jasmine.Spy;
beforeEach(() => {
// Spy on PFLog.err to prevent test output cluttering
errSpy = spyOn(PFLog, 'err').and.stub();
// Spy on OpLog.err to prevent test output cluttering
errSpy = spyOn(OpLog, 'err').and.stub();
});
afterEach(() => {

View file

@ -1,7 +1,7 @@
import { AppDataComplete } from '../model/model-config';
import { IValidation } from 'typia';
import { DEFAULT_GLOBAL_CONFIG } from '../../features/config/default-global-config.const';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
export const autoFixTypiaErrors = (
data: AppDataComplete,
@ -16,7 +16,7 @@ export const autoFixTypiaErrors = (
const path = error.path.replace('$input.', '');
const keys = parsePath(path);
const value = getValueByPath(data, keys);
PFLog.err('Auto-fixing error:', error, keys, value);
OpLog.err('Auto-fixing error:', error, keys, value);
if (
error.expected.includes('number') &&
@ -25,38 +25,38 @@ export const autoFixTypiaErrors = (
) {
const parsedValue = parseFloat(value);
setValueByPath(data, keys, parsedValue);
PFLog.err(`Fixed: ${path} from string "${value}" to number ${parsedValue}`);
OpLog.err(`Fixed: ${path} from string "${value}" to number ${parsedValue}`);
} else if (keys[0] === 'globalConfig') {
const defaultValue = getValueByPath(DEFAULT_GLOBAL_CONFIG, keys.slice(1));
setValueByPath(data, keys, defaultValue);
PFLog.warn(
OpLog.warn(
`Warning: ${path} had an invalid value and was set to default: ${defaultValue}`,
);
} else if (error.expected.includes('undefined') && value === null) {
setValueByPath(data, keys, undefined);
PFLog.err(`Fixed: ${path} from null to undefined`);
OpLog.err(`Fixed: ${path} from null to undefined`);
} else if (error.expected.includes('null') && value === 'null') {
setValueByPath(data, keys, null);
PFLog.err(`Fixed: ${path} from string null to null`);
OpLog.err(`Fixed: ${path} from string null to null`);
} else if (error.expected.includes('undefined') && value === 'null') {
setValueByPath(data, keys, undefined);
PFLog.err(`Fixed: ${path} from string null to null`);
OpLog.err(`Fixed: ${path} from string null to null`);
} else if (error.expected.includes('null') && value === undefined) {
setValueByPath(data, keys, null);
PFLog.err(`Fixed: ${path} from undefined to null`);
OpLog.err(`Fixed: ${path} from undefined to null`);
} else if (error.expected.includes('boolean') && !value) {
setValueByPath(data, keys, false);
PFLog.err(`Fixed: ${path} to false (was ${value})`);
OpLog.err(`Fixed: ${path} to false (was ${value})`);
} else if (keys[0] === 'task' && error.expected.includes('number')) {
// If the value is a string that can be parsed to a number, parse it
if (typeof value === 'string' && !isNaN(parseFloat(value))) {
setValueByPath(data, keys, parseFloat(value));
PFLog.err(
OpLog.err(
`Fixed: ${path} from string "${value}" to number ${parseFloat(value)}`,
);
} else {
setValueByPath(data, keys, 0);
PFLog.err(`Fixed: ${path} to 0 (was ${value})`);
OpLog.err(`Fixed: ${path} to 0 (was ${value})`);
}
} else if (
keys[0] === 'simpleCounter' &&
@ -68,7 +68,7 @@ export const autoFixTypiaErrors = (
) {
// Fix for issue #4593: simpleCounter countOnDay null value
setValueByPath(data, keys, 0);
PFLog.err(`Fixed: ${path} from null to 0 for simpleCounter`);
OpLog.err(`Fixed: ${path} from null to 0 for simpleCounter`);
} else if (
keys[0] === 'taskRepeatCfg' &&
keys[1] === 'entities' &&
@ -84,7 +84,7 @@ export const autoFixTypiaErrors = (
const orderIndex = ids.indexOf(entityId);
const orderValue = orderIndex >= 0 ? orderIndex : 0;
setValueByPath(data, keys, orderValue);
PFLog.err(`Fixed: ${path} from null to ${orderValue} for taskRepeatCfg order`);
OpLog.err(`Fixed: ${path} from null to ${orderValue} for taskRepeatCfg order`);
} else if (
keys[0] === 'metric' &&
keys[1] === 'entities' &&
@ -97,7 +97,7 @@ export const autoFixTypiaErrors = (
// Fix deprecated metric array fields (obstructions, improvements, improvementsTomorrow)
// These fields are marked "TODO remove" and will be removed in future
setValueByPath(data, keys, []);
PFLog.err(`Fixed: ${path} to empty array for deprecated metric field`);
OpLog.err(`Fixed: ${path} to empty array for deprecated metric field`);
} else if (
keys[0] === 'improvement' &&
keys[1] === 'hiddenImprovementBannerItems' &&
@ -105,7 +105,7 @@ export const autoFixTypiaErrors = (
) {
// Fix improvement.hiddenImprovementBannerItems (deprecated)
setValueByPath(data, keys, []);
PFLog.err(`Fixed: ${path} to empty array for deprecated improvement field`);
OpLog.err(`Fixed: ${path} to empty array for deprecated improvement field`);
}
}
});
@ -159,7 +159,7 @@ const setValueByPath = (
value: unknown,
): void => {
if (!Array.isArray(path) || path.length === 0) return;
PFLog.err('Auto-fixing error =>', path, value);
OpLog.err('Auto-fixing error =>', path, value);
let current: Record<string | number, unknown> = obj;
for (let i = 0; i < path.length - 1; i++) {

View file

@ -14,7 +14,7 @@ import { AppDataComplete } from '../model/model-config';
import { INBOX_PROJECT } from '../../features/project/project.const';
import { autoFixTypiaErrors } from './auto-fix-typia-errors';
import { IValidation } from 'typia';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import { repairMenuTree } from './repair-menu-tree';
import { initialTimeTrackingState } from '../../features/time-tracking/store/time-tracking.reducer';
@ -141,7 +141,7 @@ const _fixTaskRepeatCfgInvalidQuickSetting = (data: AppDataComplete): AppDataCom
quickSettingsRequiringStartDate.includes(cfg.quickSetting) &&
!cfg.startDate
) {
PFLog.log(
OpLog.log(
`Fixing repeat config ${cfg.id}: ${cfg.quickSetting} with missing startDate -> CUSTOM`,
);
cfg.quickSetting = 'CUSTOM';
@ -203,7 +203,7 @@ const _removeDuplicatesFromArchive = (data: AppDataComplete): AppDataComplete =>
}
});
if (duplicateYoungIds.length > 0) {
PFLog.log(duplicateYoungIds.length + ' duplicates removed from archiveYoung.');
OpLog.log(duplicateYoungIds.length + ' duplicates removed from archiveYoung.');
}
}
@ -219,7 +219,7 @@ const _removeDuplicatesFromArchive = (data: AppDataComplete): AppDataComplete =>
}
});
if (duplicateOldIds.length > 0) {
PFLog.log(duplicateOldIds.length + ' duplicates removed from archiveOld.');
OpLog.log(duplicateOldIds.length + ' duplicates removed from archiveOld.');
}
}
@ -237,7 +237,7 @@ const _removeDuplicatesFromArchive = (data: AppDataComplete): AppDataComplete =>
}
});
if (duplicateBetweenArchives.length > 0) {
PFLog.log(
OpLog.log(
duplicateBetweenArchives.length +
' duplicates removed from archiveYoung (kept in archiveOld).',
);
@ -280,7 +280,7 @@ const _moveArchivedSubTasksToUnarchivedParents = (
!taskArchiveOldState.ids.includes(t.parentId),
);
PFLog.log('orphanArchivedYoungSubTasks', orphanArchivedYoungSubTasks);
OpLog.log('orphanArchivedYoungSubTasks', orphanArchivedYoungSubTasks);
const promotedYoungSubTaskIds: string[] = [];
orphanArchivedYoungSubTasks.forEach((t: TaskCopy) => {
// delete archived if duplicate
@ -312,7 +312,7 @@ const _moveArchivedSubTasksToUnarchivedParents = (
}
});
if (promotedYoungSubTaskIds.length > 0) {
PFLog.warn(
OpLog.warn(
`[data-repair] ${promotedYoungSubTaskIds.length} archived subtask(s) promoted to standalone tasks due to missing parent:`,
promotedYoungSubTaskIds,
);
@ -328,7 +328,7 @@ const _moveArchivedSubTasksToUnarchivedParents = (
!taskArchiveYoungState.ids.includes(t.parentId),
);
PFLog.log('orphanArchivedOldSubTasks', orphanArchivedOldSubTasks);
OpLog.log('orphanArchivedOldSubTasks', orphanArchivedOldSubTasks);
const promotedOldSubTaskIds: string[] = [];
orphanArchivedOldSubTasks.forEach((t: TaskCopy) => {
// delete archived if duplicate
@ -360,7 +360,7 @@ const _moveArchivedSubTasksToUnarchivedParents = (
}
});
if (promotedOldSubTaskIds.length > 0) {
PFLog.warn(
OpLog.warn(
`[data-repair] ${promotedOldSubTaskIds.length} old archived subtask(s) promoted to standalone tasks due to missing parent:`,
promotedOldSubTaskIds,
);
@ -380,7 +380,7 @@ const _moveUnArchivedSubTasksToArchivedParents = (
.map((id: string) => taskState.entities[id] as TaskCopy)
.filter((t: TaskCopy) => t.parentId && !taskState.ids.includes(t.parentId));
PFLog.log('orphanUnArchivedSubTasks', orphanUnArchivedSubTasks);
OpLog.log('orphanUnArchivedSubTasks', orphanUnArchivedSubTasks);
const promotedUnArchivedSubTaskIds: string[] = [];
orphanUnArchivedSubTasks.forEach((t: TaskCopy) => {
// delete un-archived if duplicate in either archive
@ -434,7 +434,7 @@ const _moveUnArchivedSubTasksToArchivedParents = (
}
});
if (promotedUnArchivedSubTaskIds.length > 0) {
PFLog.warn(
OpLog.warn(
`[data-repair] ${promotedUnArchivedSubTaskIds.length} unarchived subtask(s) promoted to standalone tasks due to missing parent:`,
promotedUnArchivedSubTaskIds,
);
@ -498,7 +498,7 @@ const _removeMissingTasksFromListsOrRestoreFromArchive = (
);
if (taskIdsToRestoreFromArchive.length > 0) {
PFLog.log(
OpLog.log(
taskIdsToRestoreFromArchive.length + ' missing tasks restored from archive.',
);
}
@ -561,7 +561,7 @@ const _addOrphanedTasksToProjectLists = (data: AppDataComplete): AppDataComplete
});
if (orphanedTaskIds.length > 0) {
PFLog.log(orphanedTaskIds.length + ' orphaned tasks found & restored.');
OpLog.log(orphanedTaskIds.length + ' orphaned tasks found & restored.');
}
return data;
@ -584,7 +584,7 @@ const _addInboxProjectIdIfNecessary = (data: AppDataComplete): AppDataComplete =
taskIds.forEach((id) => {
const t = task.entities[id] as TaskCopy;
if (!t.projectId) {
PFLog.log('Set inbox project id for task ' + t.id);
OpLog.log('Set inbox project id for task ' + t.id);
const inboxProject = data.project.entities[INBOX_PROJECT.id]!;
data.project.entities[INBOX_PROJECT.id] = {
@ -600,13 +600,13 @@ const _addInboxProjectIdIfNecessary = (data: AppDataComplete): AppDataComplete =
}
});
PFLog.log(taskArchiveYoungIds);
PFLog.log(Object.keys(archiveYoung.task.entities));
OpLog.log(taskArchiveYoungIds);
OpLog.log(Object.keys(archiveYoung.task.entities));
taskArchiveYoungIds.forEach((id) => {
const t = archiveYoung.task.entities[id] as TaskCopy;
if (!t.projectId) {
PFLog.log('Set inbox project for missing project id from archive task ' + t.id);
OpLog.log('Set inbox project for missing project id from archive task ' + t.id);
t.projectId = INBOX_PROJECT.id;
}
// while we are at it, we also cleanup the today tag
@ -615,13 +615,13 @@ const _addInboxProjectIdIfNecessary = (data: AppDataComplete): AppDataComplete =
}
});
PFLog.log(taskArchiveOldIds);
PFLog.log(Object.keys(archiveOld.task.entities));
OpLog.log(taskArchiveOldIds);
OpLog.log(Object.keys(archiveOld.task.entities));
taskArchiveOldIds.forEach((id) => {
const t = archiveOld.task.entities[id] as TaskCopy;
if (!t.projectId) {
PFLog.log('Set inbox project for missing project id from old archive task ' + t.id);
OpLog.log('Set inbox project for missing project id from old archive task ' + t.id);
t.projectId = INBOX_PROJECT.id;
}
// while we are at it, we also cleanup the today tag
@ -659,29 +659,29 @@ const _removeNonExistentProjectIdsFromTasks = (
taskIds.forEach((id) => {
const t = task.entities[id] as TaskCopy;
if (t.projectId && !projectIds.includes(t.projectId)) {
PFLog.log('Delete missing project id from task ' + t.projectId);
OpLog.log('Delete missing project id from task ' + t.projectId);
t.projectId = INBOX_PROJECT.id;
}
});
PFLog.log(taskArchiveYoungIds);
PFLog.log(Object.keys(archiveYoung.task.entities));
OpLog.log(taskArchiveYoungIds);
OpLog.log(Object.keys(archiveYoung.task.entities));
taskArchiveYoungIds.forEach((id) => {
const t = archiveYoung.task.entities[id] as TaskCopy;
if (t.projectId && !projectIds.includes(t.projectId)) {
PFLog.log('Delete missing project id from archive task ' + t.projectId);
OpLog.log('Delete missing project id from archive task ' + t.projectId);
t.projectId = INBOX_PROJECT.id;
}
});
PFLog.log(taskArchiveOldIds);
PFLog.log(Object.keys(archiveOld.task.entities));
OpLog.log(taskArchiveOldIds);
OpLog.log(Object.keys(archiveOld.task.entities));
taskArchiveOldIds.forEach((id) => {
const t = archiveOld.task.entities[id] as TaskCopy;
if (t.projectId && !projectIds.includes(t.projectId)) {
PFLog.log('Delete missing project id from old archive task ' + t.projectId);
OpLog.log('Delete missing project id from old archive task ' + t.projectId);
t.projectId = INBOX_PROJECT.id;
}
});
@ -719,7 +719,7 @@ const _removeNonExistentTagsFromTasks = (data: AppDataComplete): AppDataComplete
(tagId) => !tagIds.includes(tagId) && tagId !== TODAY_TAG.id,
);
if (removedTags.length > 0) {
PFLog.log(
OpLog.log(
`Removing non-existent tags from task ${t.id}: ${removedTags.join(', ')}`,
);
removedCount += removedTags.length;
@ -739,7 +739,7 @@ const _removeNonExistentTagsFromTasks = (data: AppDataComplete): AppDataComplete
(tagId) => !tagIds.includes(tagId) && tagId !== TODAY_TAG.id,
);
if (removedTags.length > 0) {
PFLog.log(
OpLog.log(
`Removing non-existent tags from archive task ${t.id}: ${removedTags.join(', ')}`,
);
removedCount += removedTags.length;
@ -759,7 +759,7 @@ const _removeNonExistentTagsFromTasks = (data: AppDataComplete): AppDataComplete
(tagId) => !tagIds.includes(tagId) && tagId !== TODAY_TAG.id,
);
if (removedTags.length > 0) {
PFLog.log(
OpLog.log(
`Removing non-existent tags from old archive task ${t.id}: ${removedTags.join(', ')}`,
);
removedCount += removedTags.length;
@ -770,7 +770,7 @@ const _removeNonExistentTagsFromTasks = (data: AppDataComplete): AppDataComplete
});
if (removedCount > 0) {
PFLog.log(`Total non-existent tags removed from tasks: ${removedCount}`);
OpLog.log(`Total non-existent tags removed from tasks: ${removedCount}`);
}
return data;
@ -785,7 +785,7 @@ const _removeNonExistentProjectIdsFromIssueProviders = (
issueProviderIds.forEach((id) => {
const t = issueProvider.entities[id] as IssueProvider;
if (t.defaultProjectId && !projectIds.includes(t.defaultProjectId)) {
PFLog.log('Delete missing project id from issueProvider ' + t.defaultProjectId);
OpLog.log('Delete missing project id from issueProvider ' + t.defaultProjectId);
t.defaultProjectId = null;
}
});
@ -803,7 +803,7 @@ const _removeNonExistentProjectIdsFromTaskRepeatCfg = (
const repeatCfg = taskRepeatCfg.entities[id] as TaskRepeatCfgCopy;
if (repeatCfg.projectId && !projectIds.includes(repeatCfg.projectId)) {
if (repeatCfg.tagIds.length) {
PFLog.log(
OpLog.log(
'Delete missing project id from task repeat cfg ' + repeatCfg.projectId,
);
repeatCfg.projectId = null;
@ -812,7 +812,7 @@ const _removeNonExistentProjectIdsFromTaskRepeatCfg = (
(rid: string) => rid !== repeatCfg.id,
);
delete taskRepeatCfg.entities[repeatCfg.id];
PFLog.log('Delete task repeat cfg with missing project id' + repeatCfg.projectId);
OpLog.log('Delete task repeat cfg with missing project id' + repeatCfg.projectId);
}
}
});
@ -833,7 +833,7 @@ const _removeNonExistentRepeatCfgIdsFromTasks = (
taskIds.forEach((id) => {
const t = task.entities[id] as TaskCopy;
if (t.repeatCfgId && !repeatCfgIds.includes(t.repeatCfgId)) {
PFLog.log(`Clearing non-existent repeatCfgId from task ${t.id}: ${t.repeatCfgId}`);
OpLog.log(`Clearing non-existent repeatCfgId from task ${t.id}: ${t.repeatCfgId}`);
t.repeatCfgId = undefined;
removedCount++;
}
@ -843,7 +843,7 @@ const _removeNonExistentRepeatCfgIdsFromTasks = (
taskArchiveYoungIds.forEach((id) => {
const t = archiveYoung.task.entities[id] as TaskCopy;
if (t.repeatCfgId && !repeatCfgIds.includes(t.repeatCfgId)) {
PFLog.log(
OpLog.log(
`Clearing non-existent repeatCfgId from archive task ${t.id}: ${t.repeatCfgId}`,
);
t.repeatCfgId = undefined;
@ -855,7 +855,7 @@ const _removeNonExistentRepeatCfgIdsFromTasks = (
taskArchiveOldIds.forEach((id) => {
const t = archiveOld.task.entities[id] as TaskCopy;
if (t.repeatCfgId && !repeatCfgIds.includes(t.repeatCfgId)) {
PFLog.log(
OpLog.log(
`Clearing non-existent repeatCfgId from old archive task ${t.id}: ${t.repeatCfgId}`,
);
t.repeatCfgId = undefined;
@ -864,7 +864,7 @@ const _removeNonExistentRepeatCfgIdsFromTasks = (
});
if (removedCount > 0) {
PFLog.log(`Total non-existent repeatCfgIds cleared from tasks: ${removedCount}`);
OpLog.log(`Total non-existent repeatCfgIds cleared from tasks: ${removedCount}`);
}
return data;
@ -875,7 +875,7 @@ const _cleanupNonExistingTasksFromLists = (data: AppDataComplete): AppDataComple
projectIds.forEach((pid) => {
const projectItem = data.project.entities[pid];
if (!projectItem) {
PFLog.log(data.project);
OpLog.log(data.project);
throw new Error('No project');
}
(projectItem as ProjectCopy).taskIds = projectItem.taskIds.filter(
@ -890,7 +890,7 @@ const _cleanupNonExistingTasksFromLists = (data: AppDataComplete): AppDataComple
.map((id) => data.tag.entities[id])
.forEach((tagItem) => {
if (!tagItem) {
PFLog.log(data.tag);
OpLog.log(data.tag);
throw new Error('No tag');
}
(tagItem as TagCopy).taskIds = tagItem.taskIds.filter(
@ -905,7 +905,7 @@ const _cleanupNonExistingNotesFromLists = (data: AppDataComplete): AppDataComple
projectIds.forEach((pid) => {
const projectItem = data.project.entities[pid];
if (!projectItem) {
PFLog.log(data.project);
OpLog.log(data.project);
throw new Error('No project');
}
(projectItem as ProjectCopy).noteIds = (projectItem as ProjectCopy).noteIds
@ -926,14 +926,14 @@ const _fixOrphanedNotes = (data: AppDataComplete): AppDataComplete => {
noteIds.forEach((nId) => {
const note = data.note.entities[nId];
if (!note) {
PFLog.log(data.note);
OpLog.log(data.note);
throw new Error('No note');
}
// missing project case
if (note.projectId) {
if (data.project.entities[note.projectId]) {
if (!data.project.entities[note.projectId]!.noteIds.includes(note.id)) {
PFLog.log(
OpLog.log(
'Add orphaned note back to project list ' + note.projectId + ' ' + note.id,
);
@ -944,7 +944,7 @@ const _fixOrphanedNotes = (data: AppDataComplete): AppDataComplete => {
};
}
} else {
PFLog.log('Delete missing project id from note ' + note.id);
OpLog.log('Delete missing project id from note ' + note.id);
note.projectId = null;
if (!data.note.todayOrder.includes(note.id)) {
@ -953,7 +953,7 @@ const _fixOrphanedNotes = (data: AppDataComplete): AppDataComplete => {
}
} // orphaned note case
else if (!data.note.todayOrder.includes(note.id)) {
PFLog.log('Add orphaned note to today list ' + note.id);
OpLog.log('Add orphaned note to today list ' + note.id);
if (!data.note.todayOrder.includes(note.id)) {
data.note.todayOrder = [...data.note.todayOrder, note.id];
@ -970,7 +970,7 @@ const _fixInconsistentProjectId = (data: AppDataComplete): AppDataComplete => {
.map((id) => data.project.entities[id])
.forEach((projectItem) => {
if (!projectItem) {
PFLog.log(data.project);
OpLog.log(data.project);
throw new Error('No project');
}
projectItem.taskIds.forEach((tid) => {
@ -1015,7 +1015,7 @@ const _fixInconsistentTagId = (data: AppDataComplete): AppDataComplete => {
.map((id) => data.tag.entities[id])
.forEach((tagItem) => {
if (!tagItem) {
PFLog.log(data.tag);
OpLog.log(data.tag);
throw new Error('No tag');
}
tagItem.taskIds.forEach((tid) => {
@ -1037,7 +1037,7 @@ const _setTaskProjectIdAccordingToParent = (data: AppDataComplete): AppDataCompl
.map((id) => data.task.entities[id])
.forEach((taskItem) => {
if (!taskItem) {
PFLog.log(data.task);
OpLog.log(data.task);
throw new Error('No task');
}
if (taskItem.subTaskIds) {
@ -1059,7 +1059,7 @@ const _setTaskProjectIdAccordingToParent = (data: AppDataComplete): AppDataCompl
.map((id) => data.archiveYoung.task.entities[id])
.forEach((taskItem) => {
if (!taskItem) {
PFLog.log(data.archiveYoung.task);
OpLog.log(data.archiveYoung.task);
throw new Error('No archive task');
}
if (taskItem.subTaskIds) {
@ -1081,7 +1081,7 @@ const _setTaskProjectIdAccordingToParent = (data: AppDataComplete): AppDataCompl
.map((id) => data.archiveOld.task.entities[id])
.forEach((taskItem) => {
if (!taskItem) {
PFLog.log(data.archiveOld.task);
OpLog.log(data.archiveOld.task);
throw new Error('No old archive task');
}
if (taskItem.subTaskIds) {
@ -1108,7 +1108,7 @@ const _cleanupOrphanedSubTasks = (data: AppDataComplete): AppDataComplete => {
.map((id) => data.task.entities[id])
.forEach((taskItem) => {
if (!taskItem) {
PFLog.log(data.task);
OpLog.log(data.task);
throw new Error('No task');
}
@ -1117,7 +1117,7 @@ const _cleanupOrphanedSubTasks = (data: AppDataComplete): AppDataComplete => {
while (i >= 0) {
const sid = taskItem.subTaskIds[i];
if (!data.task.entities[sid]) {
PFLog.log('Delete orphaned sub task for ', taskItem);
OpLog.log('Delete orphaned sub task for ', taskItem);
taskItem.subTaskIds.splice(i, 1);
}
i -= 1;
@ -1130,7 +1130,7 @@ const _cleanupOrphanedSubTasks = (data: AppDataComplete): AppDataComplete => {
.map((id) => data.archiveYoung.task.entities[id])
.forEach((taskItem) => {
if (!taskItem) {
PFLog.log(data.archiveYoung.task);
OpLog.log(data.archiveYoung.task);
throw new Error('No archive task');
}
@ -1139,7 +1139,7 @@ const _cleanupOrphanedSubTasks = (data: AppDataComplete): AppDataComplete => {
while (i >= 0) {
const sid = taskItem.subTaskIds[i];
if (!data.archiveYoung.task.entities[sid]) {
PFLog.log('Delete orphaned archive sub task for ', taskItem);
OpLog.log('Delete orphaned archive sub task for ', taskItem);
taskItem.subTaskIds.splice(i, 1);
}
i -= 1;
@ -1152,7 +1152,7 @@ const _cleanupOrphanedSubTasks = (data: AppDataComplete): AppDataComplete => {
.map((id) => data.archiveOld.task.entities[id])
.forEach((taskItem) => {
if (!taskItem) {
PFLog.log(data.archiveOld.task);
OpLog.log(data.archiveOld.task);
throw new Error('No old archive task');
}
@ -1161,7 +1161,7 @@ const _cleanupOrphanedSubTasks = (data: AppDataComplete): AppDataComplete => {
while (i >= 0) {
const sid = taskItem.subTaskIds[i];
if (!data.archiveOld.task.entities[sid]) {
PFLog.log('Delete orphaned old archive sub task for ', taskItem);
OpLog.log('Delete orphaned old archive sub task for ', taskItem);
taskItem.subTaskIds.splice(i, 1);
}
i -= 1;

View file

@ -1,18 +1,18 @@
import { AppDataComplete } from '../model/model-config';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import { TODAY_TAG } from '../../features/tag/tag.const';
describe('isRelatedModelDataValid', () => {
let isRelatedModelDataValid: any;
beforeEach(() => {
// Suppress PFLog output during tests by spying on the methods
spyOn(PFLog, 'log');
spyOn(PFLog, 'info');
spyOn(PFLog, 'error');
spyOn(PFLog, 'warn');
spyOn(PFLog, 'err');
spyOn(PFLog, 'critical');
// Suppress OpLog output during tests by spying on the methods
spyOn(OpLog, 'log');
spyOn(OpLog, 'info');
spyOn(OpLog, 'error');
spyOn(OpLog, 'warn');
spyOn(OpLog, 'err');
spyOn(OpLog, 'critical');
/* eslint-disable @typescript-eslint/no-require-imports */
// Reset modules to allow re-importing with mocks
// @ts-ignore
@ -158,7 +158,7 @@ describe('isRelatedModelDataValid', () => {
// Should pass because TODAY_TAG orphans are harmless (virtual tag)
expect(result).toBe(true);
// Verify warning was logged
expect(PFLog.info).toHaveBeenCalledWith(
expect(OpLog.info).toHaveBeenCalledWith(
jasmine.stringContaining('TODAY_TAG has 2 orphaned task IDs (harmless)'),
jasmine.any(Object),
);
@ -290,7 +290,7 @@ describe('isRelatedModelDataValid', () => {
expect(result).toBe(true);
// Should not log any self-healing warning
expect(PFLog.warn).not.toHaveBeenCalled();
expect(OpLog.warn).not.toHaveBeenCalled();
});
});
});

View file

@ -1,7 +1,7 @@
import { devError } from '../../util/dev-error';
import { environment } from '../../../environments/environment';
import { AppDataComplete } from '../model/model-config';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import {
MenuTreeKind,
MenuTreeTreeNode,
@ -100,12 +100,12 @@ export const getLastValidityError = (): string | undefined => lastValidityError;
const _validityError = (errTxt: string, additionalInfo?: any): void => {
if (additionalInfo) {
PFLog.log('Validity Error Info: ', additionalInfo);
OpLog.log('Validity Error Info: ', additionalInfo);
if (environment.production) {
try {
PFLog.log('Validity Error Info string: ', JSON.stringify(additionalInfo));
OpLog.log('Validity Error Info string: ', JSON.stringify(additionalInfo));
} catch (e) {
PFLog.warn('Failed to stringify validity error info:', e);
OpLog.warn('Failed to stringify validity error info:', e);
}
}
}
@ -113,9 +113,9 @@ const _validityError = (errTxt: string, additionalInfo?: any): void => {
devError(errTxt);
} else {
if (errorCount === 4) {
PFLog.err('too many validity errors, only logging from now on');
OpLog.err('too many validity errors, only logging from now on');
}
PFLog.err(errTxt);
OpLog.err(errTxt);
}
lastValidityError = errTxt;
errorCount++;
@ -288,7 +288,7 @@ const validateTasksToProjectsAndTags = (
if (tagId === TODAY_TAG.id) {
const orphanedIds = tag.taskIds.filter((tid) => !taskIds.has(tid));
if (orphanedIds.length > 0) {
PFLog.info(
OpLog.info(
`[ValidateState] TODAY_TAG has ${orphanedIds.length} orphaned task IDs (harmless)`,
{ orphanedIds },
);

View file

@ -3,7 +3,7 @@ import {
MenuTreeState,
MenuTreeTreeNode,
} from '../../features/menu-tree/store/menu-tree.model';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
/**
* Repairs menuTree by removing orphaned project/tag references
@ -17,7 +17,7 @@ export const repairMenuTree = (
validProjectIds: Set<string>,
validTagIds: Set<string>,
): MenuTreeState => {
PFLog.log('Repairing menuTree - removing orphaned references');
OpLog.log('Repairing menuTree - removing orphaned references');
/**
* Recursively filters tree nodes, removing orphaned project/tag references
@ -41,18 +41,18 @@ export const repairMenuTree = (
if (validProjectIds.has(node.id)) {
filtered.push(node);
} else {
PFLog.log(`Removing orphaned project reference ${node.id} from ${treeType}`);
OpLog.log(`Removing orphaned project reference ${node.id} from ${treeType}`);
}
} else if (treeType === 'tagTree' && node.k === MenuTreeKind.TAG) {
// Keep tag only if it exists
if (validTagIds.has(node.id)) {
filtered.push(node);
} else {
PFLog.log(`Removing orphaned tag reference ${node.id} from ${treeType}`);
OpLog.log(`Removing orphaned tag reference ${node.id} from ${treeType}`);
}
} else {
// kind mismatch or unknown
PFLog.warn(`Removing invalid node from ${treeType}:`, node);
OpLog.warn(`Removing invalid node from ${treeType}:`, node);
}
}

View file

@ -45,7 +45,7 @@ import {
tagSharedMetaReducer,
plannerSharedMetaReducer,
} from '../../root-store/meta/task-shared-meta-reducers';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import { getDbDateStr } from '../../util/get-db-date-str';
import { TaskWithSubTasks } from '../../features/tasks/task.model';
import {
@ -82,13 +82,13 @@ import {
} from '../../features/menu-tree/store/menu-tree.model';
describe('State Validity After Actions', () => {
// Suppress PFLog output during tests
// Suppress OpLog output during tests
beforeAll(() => {
spyOn(PFLog, 'log');
spyOn(PFLog, 'error');
spyOn(PFLog, 'warn');
spyOn(PFLog, 'err');
spyOn(PFLog, 'critical');
spyOn(OpLog, 'log');
spyOn(OpLog, 'error');
spyOn(OpLog, 'warn');
spyOn(OpLog, 'err');
spyOn(OpLog, 'critical');
});
/**

View file

@ -23,7 +23,7 @@ import { MetricState } from '../../features/metric/metric.model';
import { GlobalConfigState } from '../../features/config/global-config.model';
import { AppDataComplete } from '../model/model-config';
import { ValidationResult } from '../core/types/sync.types';
import { PFLog } from '../../core/log';
import { OpLog } from '../../core/log';
import {
PluginMetaDataState,
PluginUserDataState,
@ -106,7 +106,7 @@ export const appDataValidators: {
const validateArchiveModel = <R>(d: ArchiveModel | R): ValidationResult<ArchiveModel> => {
const r = _validateArchive(d);
if (!r.success) {
PFLog.log('Validation failed', (r as any)?.errors, r.data);
OpLog.log('Validation failed', (r as any)?.errors, r.data);
}
if (!isEntityStateConsistent((d as ArchiveModel).task)) {
return {
@ -131,7 +131,7 @@ const _wrapValidate = <R>(
isEntityCheck = false,
): ValidationResult<R> => {
if (!result.success) {
PFLog.log('Validation failed', (result as any)?.errors, result, d);
OpLog.log('Validation failed', (result as any)?.errors, result, d);
}
if (isEntityCheck && !isEntityStateConsistent(d as any)) {
return {