diff --git a/src/common/reportTool.ts b/src/common/reportTool.ts index e74dc2f..044c40d 100644 --- a/src/common/reportTool.ts +++ b/src/common/reportTool.ts @@ -1,7 +1,7 @@ import { REMOTE_COUCHDB, REMOTE_MINIO } from "@lib/common/models/setting.const"; import type { ObsidianLiveSyncSettings } from "@lib/common/models/setting.type"; import { generateCredentialObject } from "@lib/replication/httplib"; -import { parseHeaderValues } from "@lib/common/utils"; +import { parseHeaderValues } from "@lib/common/utils.misc"; import { requestToCouchDBWithCredentials } from "./utils"; import { LOG_LEVEL_VERBOSE, Logger } from "@lib/common/logger"; import { DEFAULT_SETTINGS } from "@lib/common/models/setting.const.defaults"; diff --git a/src/common/utils.ts b/src/common/utils.ts index 55a676f..f9be0f9 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -204,7 +204,7 @@ export function requestToCouchDBWithCredentials( import { BASE_IS_NEW, EVEN, TARGET_IS_NEW } from "@lib/common/models/shared.const.symbols.ts"; export { BASE_IS_NEW, EVEN, TARGET_IS_NEW }; // Why 2000? : ZIP FILE Does not have enough resolution. -import { compareMTime } from "@lib/common/utils.ts"; +import { compareMTime } from "@lib/common/utils.database.ts"; import { _fetch } from "@/lib/src/common/coreEnvFunctions.ts"; export { compareMTime }; function getKey(file: AnyEntry | string | UXFileInfoStub) { diff --git a/src/features/ConfigSync/CmdConfigSync.ts b/src/features/ConfigSync/CmdConfigSync.ts index b4b112d..dae5dfa 100644 --- a/src/features/ConfigSync/CmdConfigSync.ts +++ b/src/features/ConfigSync/CmdConfigSync.ts @@ -10,7 +10,14 @@ import { addIcon, } from "@/deps.ts"; import type { EntryDoc } from "@lib/common/models/db.definition"; -import type { LoadedEntry, InternalFileEntry, FilePathWithPrefix, FilePath, AnyEntry, SavingEntry } from "@lib/common/models/db.type"; +import type { + LoadedEntry, + InternalFileEntry, + FilePathWithPrefix, + FilePath, + AnyEntry, + SavingEntry, +} from "@lib/common/models/db.type"; import type { diff_result } from "@lib/common/models/diff.definition"; import { CANCELLED, LEAVE_TO_SUBSEQUENT } from "@lib/common/models/shared.const.symbols"; import { MODE_SELECTIVE, MODE_SHINY } from "@lib/common/models/setting.const"; @@ -21,14 +28,12 @@ import { createBlob, createSavingEntryFromLoadedEntry, createTextBlob, - delay, - fireAndForget, getDocData, getDocDataAsArray, isDocContentSame, isLoadedEntry, - isObjectDifferent, -} from "@lib/common/utils.ts"; +} from "@lib/common/utils.database.ts"; +import { delay, fireAndForget, isObjectDifferent } from "@lib/common/utils.ts"; import { digestHash } from "@lib/string_and_binary/hash.ts"; import { arrayBufferToBase64, decodeBinary, readString } from "@lib/string_and_binary/convert.ts"; import { serialized, shareRunningResult } from "octagonal-wheels/concurrency/lock"; diff --git a/src/features/HiddenFileSync/CmdHiddenFileSync.ts b/src/features/HiddenFileSync/CmdHiddenFileSync.ts index ee3f6d5..56aee18 100644 --- a/src/features/HiddenFileSync/CmdHiddenFileSync.ts +++ b/src/features/HiddenFileSync/CmdHiddenFileSync.ts @@ -1,22 +1,24 @@ import { type PluginManifest, type ListedFiles } from "@/deps.ts"; -import type { LoadedEntry, FilePathWithPrefix, FilePath, SavingEntry, DocumentID, MetaEntry } from "@lib/common/models/db.type"; +import type { + LoadedEntry, + FilePathWithPrefix, + FilePath, + SavingEntry, + DocumentID, + MetaEntry, +} from "@lib/common/models/db.type"; import { MODE_SELECTIVE, MODE_PAUSED } from "@lib/common/models/setting.const"; import type { UXFileInfo, UXStat, UXDataWriteOptions } from "@lib/common/models/fileaccess.type"; import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE, LOG_LEVEL_DEBUG } from "@lib/common/logger"; import { ICHeader, ICHeaderEnd } from "@lib/common/models/fileaccess.const"; import { type InternalFileInfo } from "@/common/types.ts"; +import { readAsBlob, isDocContentSame, readContent, createBlob } from "@lib/common/utils.database.ts"; +import type { CustomRegExp } from "@lib/common/utils.regexp.ts"; +import { getFileRegExp } from "@lib/common/utils.regexp.ts"; +import { sendSignal, fireAndForget } from "@lib/common/utils.ts"; +import { compareMTime } from "@lib/common/utils.database.ts"; +import { displayRev } from "@lib/common/utils.notations.ts"; import { - readAsBlob, - isDocContentSame, - sendSignal, - readContent, - createBlob, - fireAndForget, - type CustomRegExp, - getFileRegExp, -} from "@lib/common/utils.ts"; -import { - compareMTime, isInternalMetadata, TARGET_IS_NEW, scheduleTask, @@ -26,7 +28,6 @@ import { onlyInNTimes, BASE_IS_NEW, EVEN, - displayRev, } from "@/common/utils.ts"; import { PeriodicProcessor } from "@/common/PeriodicProcessor.ts"; import { serialized, skipIfDuplicated } from "octagonal-wheels/concurrency/lock"; diff --git a/src/lib b/src/lib index 0b5947a..d82503b 160000 --- a/src/lib +++ b/src/lib @@ -1 +1 @@ -Subproject commit 0b5947a3fc89905fd5f0b44f229256813a8b6e36 +Subproject commit d82503b665b4275806f577db0e2647b8bc803e56 diff --git a/src/modules/core/ReplicateResultProcessor.ts b/src/modules/core/ReplicateResultProcessor.ts index d8c74b4..34e4c57 100644 --- a/src/modules/core/ReplicateResultProcessor.ts +++ b/src/modules/core/ReplicateResultProcessor.ts @@ -17,7 +17,8 @@ import { Logger, type LOG_LEVEL, } from "@lib/common/logger"; -import { fireAndForget, isAnyNote, throttle } from "@lib/common/utils"; +import { isAnyNote } from "@lib/common/utils.database"; +import { fireAndForget, throttle } from "@lib/common/utils"; import { isNotFoundError } from "@lib/common/utils.doc.ts"; import { Semaphore } from "octagonal-wheels/concurrency/semaphore_v2"; import { serialized } from "octagonal-wheels/concurrency/lock"; diff --git a/src/modules/coreFeatures/ModuleConflictResolver.ts b/src/modules/coreFeatures/ModuleConflictResolver.ts index 80362a9..8c40b19 100644 --- a/src/modules/coreFeatures/ModuleConflictResolver.ts +++ b/src/modules/coreFeatures/ModuleConflictResolver.ts @@ -13,7 +13,8 @@ import { } from "@lib/common/types"; import { isCustomisationSyncMetadata, isPluginMetadata } from "@lib/common/typeUtils.ts"; import { TARGET_IS_NEW } from "@lib/common/models/shared.const.symbols.ts"; -import { compareMTime, displayRev } from "@lib/common/utils.ts"; +import { compareMTime } from "@lib/common/utils.database.ts"; +import { displayRev } from "@lib/common/utils.notations.ts"; import diff_match_patch from "diff-match-patch"; import { stripAllPrefixes, isPlainText } from "@lib/string_and_binary/path"; import { eventHub } from "@/common/events.ts"; diff --git a/src/modules/coreFeatures/ModuleResolveMismatchedTweaks.ts b/src/modules/coreFeatures/ModuleResolveMismatchedTweaks.ts index 9b742af..bcadd01 100644 --- a/src/modules/coreFeatures/ModuleResolveMismatchedTweaks.ts +++ b/src/modules/coreFeatures/ModuleResolveMismatchedTweaks.ts @@ -1,10 +1,16 @@ import { Logger, LOG_LEVEL_NOTICE } from "octagonal-wheels/common/logger"; import { extractObject } from "octagonal-wheels/object"; import type { TweakValues } from "@lib/common/models/tweak.definition"; -import { TweakValuesShouldMatchedTemplate, TweakValuesTemplate, IncompatibleChanges, IncompatibleChangesInSpecificPattern, CompatibleButLossyChanges } from "@lib/common/models/tweak.definition"; +import { + TweakValuesShouldMatchedTemplate, + TweakValuesTemplate, + IncompatibleChanges, + IncompatibleChangesInSpecificPattern, + CompatibleButLossyChanges, +} from "@lib/common/models/tweak.definition"; import { confName } from "@lib/common/models/shared.definition.configNames"; import type { ObsidianLiveSyncSettings, RemoteDBSettings } from "@lib/common/models/setting.type"; -import { escapeMarkdownValue } from "@lib/common/utils.ts"; +import { escapeMarkdownValue } from "@lib/common/utils.notations.ts"; import { AbstractModule } from "@/modules/AbstractModule.ts"; import { $msg } from "@lib/common/i18n.ts"; import type { InjectableServiceHub } from "@lib/services/InjectableServices.ts"; diff --git a/src/modules/coreObsidian/storageLib/utilObsidian.ts b/src/modules/coreObsidian/storageLib/utilObsidian.ts index 1029f61..aa221c5 100644 --- a/src/modules/coreObsidian/storageLib/utilObsidian.ts +++ b/src/modules/coreObsidian/storageLib/utilObsidian.ts @@ -4,9 +4,14 @@ import { TFile, type TAbstractFile, type TFolder } from "@/deps.ts"; import { ICHeader } from "@lib/common/models/fileaccess.const"; import { addPrefix, isPlainText } from "@lib/string_and_binary/path.ts"; import { LOG_LEVEL_VERBOSE, Logger } from "octagonal-wheels/common/logger"; -import { createBlob } from "@lib/common/utils.ts"; +import { createBlob } from "@lib/common/utils.database.ts"; import type { FilePath, FilePathWithPrefix } from "@lib/common/models/db.type"; -import type { UXFileInfo, UXFileInfoStub, UXFolderInfo, UXInternalFileInfoStub } from "@lib/common/models/fileaccess.type"; +import type { + UXFileInfo, + UXFileInfoStub, + UXFolderInfo, + UXInternalFileInfoStub, +} from "@lib/common/models/fileaccess.type"; import type { LiveSyncCore } from "@/main.ts"; import type { FileAccessObsidian } from "@/serviceModules/FileAccessObsidian.ts"; diff --git a/src/modules/essential/ModuleMigration.ts b/src/modules/essential/ModuleMigration.ts index 71136eb..ab5953c 100644 --- a/src/modules/essential/ModuleMigration.ts +++ b/src/modules/essential/ModuleMigration.ts @@ -12,7 +12,7 @@ import { $msg } from "@lib/common/i18n.ts"; import { performDoctorConsultation, RebuildOptions } from "@lib/common/configForDoc.ts"; import { isValidPath } from "@/common/utils.ts"; import { isMetaEntry } from "@lib/common/models/db.definition"; -import { isDeletedEntry, isDocContentSame, isLoadedEntry, readAsBlob } from "@lib/common/utils.ts"; +import { isDeletedEntry, isDocContentSame, isLoadedEntry, readAsBlob } from "@lib/common/utils.database.ts"; import { countCompromisedChunks } from "@lib/pouchdb/negotiation.ts"; import type { LiveSyncCore } from "@/main.ts"; import { SetupManager } from "@/modules/features/SetupManager.ts"; diff --git a/src/modules/features/DocumentHistory/DocumentHistoryModal.ts b/src/modules/features/DocumentHistory/DocumentHistoryModal.ts index cebde0c..0109ba7 100644 --- a/src/modules/features/DocumentHistory/DocumentHistoryModal.ts +++ b/src/modules/features/DocumentHistory/DocumentHistoryModal.ts @@ -6,7 +6,8 @@ import type { DocumentID, FilePathWithPrefix, LoadedEntry } from "@lib/common/mo import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "@lib/common/logger"; import { Logger } from "@lib/common/logger.ts"; import { isErrorOfMissingDoc } from "@lib/pouchdb/utils_couchdb.ts"; -import { fireAndForget, getDocData, readContent } from "@lib/common/utils.ts"; +import { getDocData, readContent } from "@lib/common/utils.database.ts"; +import { fireAndForget } from "@lib/common/utils.ts"; import { isPlainText, stripPrefix } from "@lib/string_and_binary/path.ts"; import { scheduleOnceIfDuplicated } from "octagonal-wheels/concurrency/lock"; import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore.ts"; diff --git a/src/modules/features/ModuleInteractiveConflictResolver.ts b/src/modules/features/ModuleInteractiveConflictResolver.ts index c6f1910..367ba65 100644 --- a/src/modules/features/ModuleInteractiveConflictResolver.ts +++ b/src/modules/features/ModuleInteractiveConflictResolver.ts @@ -4,7 +4,7 @@ import type { diff_result } from "@lib/common/models/diff.definition"; import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "@lib/common/logger"; import { ConflictResolveModal } from "./InteractiveConflictResolving/ConflictResolveModal.ts"; import { AbstractObsidianModule } from "@/modules/AbstractObsidianModule.ts"; -import { displayRev } from "@/common/utils.ts"; +import { displayRev } from "@lib/common/utils.notations.ts"; import { fireAndForget } from "octagonal-wheels/promises"; import { serialized } from "octagonal-wheels/concurrency/lock"; import type { LiveSyncCore } from "@/main.ts"; diff --git a/src/modules/features/ModuleLog.ts b/src/modules/features/ModuleLog.ts index 0fd0db5..f56c7cc 100644 --- a/src/modules/features/ModuleLog.ts +++ b/src/modules/features/ModuleLog.ts @@ -4,7 +4,8 @@ import type { DatabaseConnectingStatus } from "@lib/common/models/shared.definit import { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_VERBOSE } from "@lib/common/logger"; import type { LOG_LEVEL } from "@lib/common/logger"; import { cancelTask, scheduleTask } from "octagonal-wheels/concurrency/task"; -import { fireAndForget, isDirty, throttle } from "@lib/common/utils.ts"; +import { isDirty } from "@lib/common/utils.misc.ts"; +import { fireAndForget, throttle } from "@lib/common/utils.ts"; import { collectingChunks, pluginScanningCount, diff --git a/src/modules/features/SettingDialogue/PaneHatch.ts b/src/modules/features/SettingDialogue/PaneHatch.ts index f843502..c48469f 100644 --- a/src/modules/features/SettingDialogue/PaneHatch.ts +++ b/src/modules/features/SettingDialogue/PaneHatch.ts @@ -1,6 +1,7 @@ import type { FilePathWithPrefix, DocumentID, LoadedEntry, MetaEntry, FilePath } from "@lib/common/models/db.type"; import { LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "@lib/common/logger"; -import { createBlob, getFileRegExp, isDocContentSame, readAsBlob } from "@lib/common/utils.ts"; +import { createBlob, isDocContentSame, readAsBlob } from "@lib/common/utils.database.ts"; +import { getFileRegExp } from "@lib/common/utils.regexp.ts"; import { Logger } from "@lib/common/logger.ts"; import { addPrefix, shouldBeIgnored, stripAllPrefixes } from "@lib/string_and_binary/path.ts"; import { $msg } from "@lib/common/i18n.ts"; diff --git a/src/modules/features/SettingDialogue/PaneSelector.ts b/src/modules/features/SettingDialogue/PaneSelector.ts index f74242d..609f4bd 100644 --- a/src/modules/features/SettingDialogue/PaneSelector.ts +++ b/src/modules/features/SettingDialogue/PaneSelector.ts @@ -1,6 +1,6 @@ import { LEVEL_ADVANCED } from "@lib/common/models/shared.definition.configNames"; import type { CustomRegExpSource } from "@lib/common/models/shared.type.util"; -import { constructCustomRegExpList, splitCustomRegExpList } from "@lib/common/utils.ts"; +import { constructCustomRegExpList, splitCustomRegExpList } from "@lib/common/utils.regexp.ts"; import MultipleRegExpControl from "./MultipleRegExpControl.svelte"; import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts"; import { mount } from "svelte"; diff --git a/src/modules/features/SettingDialogue/remoteConfigBuffer.ts b/src/modules/features/SettingDialogue/remoteConfigBuffer.ts index 4a52b14..0c1dc95 100644 --- a/src/modules/features/SettingDialogue/remoteConfigBuffer.ts +++ b/src/modules/features/SettingDialogue/remoteConfigBuffer.ts @@ -1,4 +1,4 @@ -import { pickBucketSyncSettings, pickCouchDBSyncSettings, pickP2PSyncSettings } from "@lib/common/utils.ts"; +import { pickBucketSyncSettings, pickCouchDBSyncSettings, pickP2PSyncSettings } from "@lib/common/utils.settings.ts"; import type { ObsidianLiveSyncSettings } from "@lib/common/models/setting.type"; // Keep the setting dialogue buffer aligned with the current core settings before persisting other dirty keys. // This also clears stale dirty values left from editing a different remote type before switching active remotes. diff --git a/src/modules/features/SettingDialogue/settingUtils.ts b/src/modules/features/SettingDialogue/settingUtils.ts index 67bf7bd..1445d06 100644 --- a/src/modules/features/SettingDialogue/settingUtils.ts +++ b/src/modules/features/SettingDialogue/settingUtils.ts @@ -5,7 +5,7 @@ import { pickBucketSyncSettings, pickP2PSyncSettings, pickEncryptionSettings, -} from "@lib/common/utils"; +} from "@lib/common/utils.settings"; import { getConfig, type AllSettingItemKey } from "./settingConstants"; import { LOG_LEVEL_NOTICE, Logger } from "octagonal-wheels/common/logger"; import { isNotFoundError } from "@lib/common/utils.doc.ts"; diff --git a/src/modules/features/SettingDialogue/utilFixCouchDBSetting.ts b/src/modules/features/SettingDialogue/utilFixCouchDBSetting.ts index 5e04368..31f9beb 100644 --- a/src/modules/features/SettingDialogue/utilFixCouchDBSetting.ts +++ b/src/modules/features/SettingDialogue/utilFixCouchDBSetting.ts @@ -2,7 +2,8 @@ import { requestToCouchDBWithCredentials } from "@/common/utils"; import { $msg } from "@lib/common/i18n"; import { LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE, Logger } from "@lib/common/logger"; import type { ObsidianLiveSyncSettings } from "@lib/common/types"; -import { fireAndForget, parseHeaderValues } from "@lib/common/utils"; +import { parseHeaderValues } from "@lib/common/utils.misc"; +import { fireAndForget } from "@lib/common/utils"; import { isCloudantURI } from "@lib/pouchdb/utils_couchdb"; import { generateCredentialObject } from "@lib/replication/httplib"; diff --git a/src/modules/features/SetupManager.ts b/src/modules/features/SetupManager.ts index 818d1a6..5d6854f 100644 --- a/src/modules/features/SetupManager.ts +++ b/src/modules/features/SetupManager.ts @@ -1,4 +1,10 @@ -import type { BucketSyncSetting, CouchDBConnection, EncryptionSettings, ObsidianLiveSyncSettings, P2PSyncSetting } from "@lib/common/models/setting.type"; +import type { + BucketSyncSetting, + CouchDBConnection, + EncryptionSettings, + ObsidianLiveSyncSettings, + P2PSyncSetting, +} from "@lib/common/models/setting.type"; import { DEFAULT_SETTINGS } from "@lib/common/models/setting.const.defaults"; import { REMOTE_COUCHDB, REMOTE_MINIO, REMOTE_P2P } from "@lib/common/models/setting.const"; import { LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "@lib/common/logger"; diff --git a/src/modules/features/SetupWizard/dialogs/utilCheckCouchDB.ts b/src/modules/features/SetupWizard/dialogs/utilCheckCouchDB.ts index ffcd09b..4d760a1 100644 --- a/src/modules/features/SetupWizard/dialogs/utilCheckCouchDB.ts +++ b/src/modules/features/SetupWizard/dialogs/utilCheckCouchDB.ts @@ -2,7 +2,7 @@ import { requestToCouchDBWithCredentials } from "@/common/utils"; import { $msg } from "@lib/common/i18n"; import { Logger } from "@lib/common/logger"; import type { ObsidianLiveSyncSettings } from "@lib/common/types"; -import { parseHeaderValues } from "@lib/common/utils"; +import { parseHeaderValues } from "@lib/common/utils.misc"; import { isCloudantURI } from "@lib/pouchdb/utils_couchdb"; import { generateCredentialObject } from "@lib/replication/httplib"; export type ResultMessage = { message: string; classes: string[] }; diff --git a/test/suite/db_common.ts b/test/suite/db_common.ts index f81f084..be17ead 100644 --- a/test/suite/db_common.ts +++ b/test/suite/db_common.ts @@ -1,7 +1,8 @@ -import { compareMTime, EVEN } from "@/common/utils"; +import { compareMTime } from "@lib/common/utils.database"; +import { EVEN } from "@/common/utils"; import { TFile, type DataWriteOptions } from "@/deps"; import type { FilePath } from "@/lib/src/common/types"; -import { isDocContentSame, readContent } from "@/lib/src/common/utils"; +import { isDocContentSame, readContent } from "@lib/common/utils.database"; import { waitForIdle, type LiveSyncHarness } from "../harness/harness"; import { expect } from "vitest"; diff --git a/test/suite/onlylocaldb.test.ts b/test/suite/onlylocaldb.test.ts index acfbb65..aadcd85 100644 --- a/test/suite/onlylocaldb.test.ts +++ b/test/suite/onlylocaldb.test.ts @@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it, test } from "vitest"; import { generateHarness, waitForIdle, waitForReady, type LiveSyncHarness } from "../harness/harness"; import { TFile } from "@/deps.ts"; import { DEFAULT_SETTINGS, type FilePath, type ObsidianLiveSyncSettings } from "@/lib/src/common/types"; -import { isDocContentSame, readContent } from "@/lib/src/common/utils"; +import { isDocContentSame, readContent } from "@lib/common/utils.database"; import { DummyFileSourceInisialised, generateBinaryFile, generateFile, init } from "../utils/dummyfile"; const localdb_test_setting = { diff --git a/test/utils/dummyfile.ts b/test/utils/dummyfile.ts index ab4b8b3..7d60f30 100644 --- a/test/utils/dummyfile.ts +++ b/test/utils/dummyfile.ts @@ -1,4 +1,4 @@ -import { DEFAULT_SETTINGS } from "@/lib/src/common/types.ts"; +import { DEFAULT_SETTINGS } from "@lib/common/models/setting.const.defaults"; import { readFile } from "../utils/fileapi.vite.ts"; let charset = ""; export async function init() { diff --git a/utilsdeno/refactor-import-utils.ts b/utilsdeno/refactor-import-utils.ts new file mode 100644 index 0000000..721421b --- /dev/null +++ b/utilsdeno/refactor-import-utils.ts @@ -0,0 +1,186 @@ +// Delete references to utils.ts and replace them with new imports based on the importMap. +// Use this script by running `deno run --allow-read --allow-write --allow-run refactor-import-utils.ts` from the utilsdeno directory. +import { Project } from "npm:ts-morph"; + +const isDryRun = !Deno.args.includes("--run"); + +if (isDryRun) { + console.log("=== DRY RUN MODE ==="); + console.log( + "To apply changes, run with: deno run --allow-read --allow-write --allow-run refactor-import-utils.ts --run\n" + ); +} + +const project = new Project({ tsConfigFilePath: "../tsconfig.json" }); + +const importMap = new Map(); + +const targetFiles = [ + "utils.concurrency.ts", + "utils.timer.ts", + "utils.notations.ts", + "utils.database.ts", + "utils.regexp.ts", + "utils.settings.ts", + "utils.patch.ts", + "utils.misc.ts", +]; + +// 1. Map exports from our newly created subfiles +for (const sourceFile of project.getSourceFiles()) { + const filePath = sourceFile.getFilePath(); + const fileName = sourceFile.getBaseName(); + if (filePath.includes("src/lib/src/common/") && targetFiles.includes(fileName)) { + const exports = sourceFile.getExportedDeclarations(); + for (const [name] of exports) { + const relativePath = filePath.split("src/lib/src/")[1].replace(/\.ts$/, ""); + importMap.set(name, `@lib/${relativePath}`); + } + } +} + +// 2. Map exports/imports of octagonal-wheels in utils.ts +const utilsFile = project.getSourceFile("src/lib/src/common/utils.ts"); +if (utilsFile) { + // Parse imports from octagonal-wheels + for (const imp of utilsFile.getImportDeclarations()) { + const moduleSpec = imp.getModuleSpecifierValue(); + if (moduleSpec.startsWith("octagonal-wheels")) { + for (const namedImport of imp.getNamedImports()) { + importMap.set(namedImport.getName(), moduleSpec); + } + } + } + // Parse export declarations from octagonal-wheels + for (const exp of utilsFile.getExportDeclarations()) { + const moduleSpec = exp.getModuleSpecifierValue(); + if (moduleSpec && moduleSpec.startsWith("octagonal-wheels")) { + for (const namedExport of exp.getNamedExports()) { + importMap.set(namedExport.getName(), moduleSpec); + } + } + } +} + +console.log(`Built importMap with ${importMap.size} mappings.\n`); + +let modifiedFilesCount = 0; + +// 3. Loop through all source files and replace imports +for (const sourceFile of project.getSourceFiles()) { + let fileModified = false; + const imports = sourceFile.getImportDeclarations(); + + for (const imp of imports) { + const moduleSpec = imp.getModuleSpecifierValue(); + const isUtilsImport = + moduleSpec === "@lib/common/utils" || + moduleSpec === "@lib/common/utils.ts" || + moduleSpec.endsWith("/common/utils") || + moduleSpec.endsWith("/common/utils.ts"); + + if (isUtilsImport) { + const namedImports = imp.getNamedImports(); + const defaultImport = imp.getDefaultImport(); + + const importsToReplace: Record = {}; + for (const namedImport of namedImports) { + const name = namedImport.getName(); + let newPath = importMap.get(name); + if (newPath) { + // If original ended with .ts and the new path starts with @lib, keep .ts + if (moduleSpec.endsWith(".ts") && newPath.startsWith("@lib/")) { + newPath = newPath + ".ts"; + } + if (!importsToReplace[newPath]) { + importsToReplace[newPath] = []; + } + importsToReplace[newPath].push({ + name, + newPath, + isTypeOnly: namedImport.isTypeOnly() || imp.isTypeOnly(), + }); + } + } + + if (Object.keys(importsToReplace).length > 0 || (defaultImport && importMap.has(defaultImport.getText()))) { + fileModified = true; + + console.log(`File: ${sourceFile.getFilePath().split("obsidian-livesync/")[1]}`); + console.log(` Old: ${imp.getText()}`); + } + + if (!isDryRun) { + // Apply replacements + for (const newPath in importsToReplace) { + const isTypeOnly = importsToReplace[newPath].filter((i) => i.isTypeOnly); + if (isTypeOnly.length > 0) { + sourceFile.insertImportDeclaration(imp.getChildIndex(), { + namedImports: isTypeOnly.map((i) => i.name), + moduleSpecifier: newPath, + isTypeOnly: true, + }); + } + const isValueImport = importsToReplace[newPath].filter((i) => !i.isTypeOnly); + if (isValueImport.length > 0) { + sourceFile.insertImportDeclaration(imp.getChildIndex(), { + namedImports: isValueImport.map((i) => i.name), + moduleSpecifier: newPath, + isTypeOnly: false, + }); + } + for (const { name } of importsToReplace[newPath]) { + const namedImport = imp.getNamedImports().find((ni) => ni.getName() === name); + if (namedImport) { + namedImport.remove(); + } + } + } + } else { + // In dry run, just print what it would do + for (const newPath in importsToReplace) { + const names = importsToReplace[newPath].map((i) => i.name).join(", "); + console.log(` -> Would import { ${names} } from "${newPath}"`); + } + } + + if (defaultImport) { + const name = defaultImport.getText(); + let newPath = importMap.get(name); + if (newPath) { + if (moduleSpec.endsWith(".ts") && newPath.startsWith("@lib/")) { + newPath = newPath + ".ts"; + } + if (!isDryRun) { + sourceFile.insertImportDeclaration(imp.getChildIndex(), { + defaultImport: name, + moduleSpecifier: newPath, + isTypeOnly: imp.isTypeOnly(), + }); + imp.removeDefaultImport(); + } else { + console.log(` -> Would import default ${name} from "${newPath}"`); + } + } + } + + if (!isDryRun) { + if (imp.getNamedImports().length === 0 && !imp.getDefaultImport()) { + imp.remove(); + } + } + } + } + if (fileModified) { + modifiedFilesCount++; + } +} + +console.log(`\nTotal files to modify: ${modifiedFilesCount}`); + +if (!isDryRun) { + project.saveSync(); + console.log("All changes successfully saved."); +} else { + console.log("Dry run complete. No changes were written to files."); +} diff --git a/utilsdeno/refactor-imports.ts b/utilsdeno/refactor-imports.ts index 1e61115..7a0fa14 100644 --- a/utilsdeno/refactor-imports.ts +++ b/utilsdeno/refactor-imports.ts @@ -8,23 +8,23 @@ const importMap = new Map(); // Build a map of types moved out of Models. // Under src/lib/src/common/models. for (const sourceFile of project.getSourceFiles()) { - if (sourceFile.getFilePath().includes("src/lib/src/common/models")) { - const exports = sourceFile.getExportedDeclarations(); - for (const [name, declarations] of exports) { - for (const declaration of declarations) { - if ( - // declaration.getKindName() === "TypeAliasDeclaration" || - // declaration.getKindName() === "InterfaceDeclaration" || - // declaration.getKindName() === "EnumDeclaration" || - true - ) { - console.log(`Found type export in ${sourceFile.getFilePath()}:`, name); - const relativePath = sourceFile.getFilePath().split("src/lib/src/")[1].replace(/\.ts$/, ""); - importMap.set(name, `@lib/${relativePath}`); + if (sourceFile.getFilePath().includes("src/lib/src/common/models")) { + const exports = sourceFile.getExportedDeclarations(); + for (const [name, declarations] of exports) { + for (const declaration of declarations) { + if ( + // declaration.getKindName() === "TypeAliasDeclaration" || + // declaration.getKindName() === "InterfaceDeclaration" || + // declaration.getKindName() === "EnumDeclaration" || + true + ) { + console.log(`Found type export in ${sourceFile.getFilePath()}:`, name); + const relativePath = sourceFile.getFilePath().split("src/lib/src/")[1].replace(/\.ts$/, ""); + importMap.set(name, `@lib/${relativePath}`); + } + } } - } } - } } // Extras @@ -40,91 +40,97 @@ console.log("Import map:", importMap); // Loop through all files that import from types.ts. for (const sourceFile of project.getSourceFiles()) { - const imports = sourceFile.getImportDeclarations(); + const imports = sourceFile.getImportDeclarations(); - for (const imp of imports) { - if (imp.getModuleSpecifierValue().includes("types.ts") && imp.getModuleSpecifierValue().startsWith("@lib/common/")) { - // Collect imports from types.ts. - const namedImports = imp.getNamedImports(); - const defaultImport = imp.getDefaultImport(); - console.log(`Found import in ${sourceFile.getFilePath()}:`, { - namedImports: namedImports.map((ni) => ni.getText()), - defaultImport: defaultImport ? defaultImport.getText() : null, - }); - // Group imports by their names and generate new import paths based on the importMap - const importsToReplace: Record = {}; - for (const namedImport of namedImports) { - const name = namedImport.getName(); - const newPath = importMap.get(name); - if (newPath) { - console.log( - `Will replace import of ${name} in ${sourceFile.getFilePath()} with new path:`, - newPath - ); - if (!importsToReplace[newPath]) { - importsToReplace[newPath] = []; - } - importsToReplace[newPath].push({ name, newPath, isTypeOnly: namedImport.isTypeOnly() || imp.isTypeOnly() }); - } - } + for (const imp of imports) { + if ( + imp.getModuleSpecifierValue().includes("types.ts") && + imp.getModuleSpecifierValue().startsWith("@lib/common/") + ) { + // Collect imports from types.ts. + const namedImports = imp.getNamedImports(); + const defaultImport = imp.getDefaultImport(); + console.log(`Found import in ${sourceFile.getFilePath()}:`, { + namedImports: namedImports.map((ni) => ni.getText()), + defaultImport: defaultImport ? defaultImport.getText() : null, + }); + // Group imports by their names and generate new import paths based on the importMap + const importsToReplace: Record = {}; + for (const namedImport of namedImports) { + const name = namedImport.getName(); + const newPath = importMap.get(name); + if (newPath) { + console.log( + `Will replace import of ${name} in ${sourceFile.getFilePath()} with new path:`, + newPath + ); + if (!importsToReplace[newPath]) { + importsToReplace[newPath] = []; + } + importsToReplace[newPath].push({ + name, + newPath, + isTypeOnly: namedImport.isTypeOnly() || imp.isTypeOnly(), + }); + } + } - // For each import, generate a new path from importMap and replace it. - // Split the import when it needs to become multiple imports. + // For each import, generate a new path from importMap and replace it. + // Split the import when it needs to become multiple imports. - for (const newPath in importsToReplace) { - // First, handle type-only imports. - const isTypeOnly = importsToReplace[newPath].filter((i) => i.isTypeOnly); - if (isTypeOnly.length > 0) { - sourceFile.insertImportDeclaration(imp.getChildIndex(), { - namedImports: isTypeOnly.map((i) => i.name), - moduleSpecifier: newPath, - isTypeOnly: true, - }); - } - // Then, handle non-type-only imports. - const isValueImport = importsToReplace[newPath].filter((i) => !i.isTypeOnly); - if (isValueImport.length > 0) { + for (const newPath in importsToReplace) { + // First, handle type-only imports. + const isTypeOnly = importsToReplace[newPath].filter((i) => i.isTypeOnly); + if (isTypeOnly.length > 0) { + sourceFile.insertImportDeclaration(imp.getChildIndex(), { + namedImports: isTypeOnly.map((i) => i.name), + moduleSpecifier: newPath, + isTypeOnly: true, + }); + } + // Then, handle non-type-only imports. + const isValueImport = importsToReplace[newPath].filter((i) => !i.isTypeOnly); + if (isValueImport.length > 0) { + sourceFile.insertImportDeclaration(imp.getChildIndex(), { + namedImports: isValueImport.map((i) => i.name), + moduleSpecifier: newPath, + isTypeOnly: false, + }); + } + // Remove the replaced named imports from the old import. + for (const { name } of importsToReplace[newPath]) { + const namedImport = imp.getNamedImports().find((ni) => ni.getName() === name); + if (namedImport) { + namedImport.remove(); + } + } + } + // If there is also a default import and it exists in importMap, replace it too. + if (defaultImport) { + const name = defaultImport.getText(); + const newPath = importMap.get(name); - sourceFile.insertImportDeclaration(imp.getChildIndex(), { - namedImports: isValueImport.map((i) => i.name), - moduleSpecifier: newPath, - isTypeOnly: false, - }); + if (newPath) { + console.log( + `Replacing default import of ${name} in ${sourceFile.getFilePath()} with new path:`, + newPath + ); + // Add the new import statement. + sourceFile.insertImportDeclaration(imp.getChildIndex(), { + defaultImport: name, + moduleSpecifier: newPath, + isTypeOnly: imp.isTypeOnly(), + }); + // Remove the default import from the old import. + imp.removeDefaultImport(); + } + } + if (imp.getNamedImports().length === 0 && !imp.getDefaultImport()) { + // Delete the entire import statement if nothing remains. + imp.remove(); + } } - // Remove the replaced named imports from the old import. - for (const { name } of importsToReplace[newPath]) { - const namedImport = imp.getNamedImports().find((ni) => ni.getName() === name); - if (namedImport) { - namedImport.remove(); - } - } - } - // If there is also a default import and it exists in importMap, replace it too. - if (defaultImport) { - const name = defaultImport.getText(); - const newPath = importMap.get(name); - - if (newPath) { - console.log( - `Replacing default import of ${name} in ${sourceFile.getFilePath()} with new path:`, - newPath - ); - // Add the new import statement. - sourceFile.insertImportDeclaration(imp.getChildIndex(), { - defaultImport: name, - moduleSpecifier: newPath, - isTypeOnly: imp.isTypeOnly(), - }); - // Remove the default import from the old import. - imp.removeDefaultImport(); - } - } - if (imp.getNamedImports().length === 0 && !imp.getDefaultImport()) { - // Delete the entire import statement if nothing remains. - imp.remove(); - } } - } } // Save everything at the end.