mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2026-01-21 12:02:57 -08:00
Refactor routing utilities and improve files/ external in sub-wiki
Moves routing utility functions to be exported via $tw.utils and updates type usage for better plugin integration. Adds support for excluding external attachments folders (configurable via $:/config/ExternalAttachments/WikiFolderToMove) from file watching. Updates build script to include new entry points and adjusts loader to use the correct module path. Adds and renames relevant .meta and type definition files.
This commit is contained in:
parent
cf9902fa68
commit
b4538f7c04
9 changed files with 79 additions and 15 deletions
|
|
@ -44,6 +44,10 @@ const nativeNodeModulesPlugin = {
|
|||
build.onResolve({ filter: /nsfw[/\\]build[/\\]Release[/\\]nsfw\.node$/ }, () => ({
|
||||
external: true,
|
||||
}));
|
||||
// External '$:/' files
|
||||
build.onResolve({ filter: /^\$:\// }, () => ({
|
||||
external: true,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -70,6 +74,9 @@ const PLUGINS = [
|
|||
sourceFolder: '../src/services/wiki/plugin/watchFileSystemAdaptor',
|
||||
entryPoints: [
|
||||
'loader.ts',
|
||||
'in-tagtree-of.ts',
|
||||
'WatchFileSystemAdaptor.ts',
|
||||
'routingUtilities.ts',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import fs from 'fs';
|
|||
import path from 'path';
|
||||
import type { IFileInfo } from 'tiddlywiki';
|
||||
import type { Tiddler, Wiki } from 'tiddlywiki';
|
||||
import { isWikiWorkspaceWithRouting, matchTiddlerToWorkspace } from './routingUtilities';
|
||||
import type { ExtendedUtilities } from './routingUtilities.type';
|
||||
import { isFileLockError } from './utilities';
|
||||
|
||||
/**
|
||||
|
|
@ -86,7 +86,7 @@ export class FileSystemAdaptor {
|
|||
|
||||
// Filter to wiki workspaces with routing config (main or sub-wikis)
|
||||
const workspacesWithRouting = allWorkspaces
|
||||
.filter((w: IWorkspace): w is IWikiWorkspace => isWikiWorkspaceWithRouting(w, currentWorkspace.id))
|
||||
.filter((w: IWorkspace): w is IWikiWorkspace => ($tw.utils as unknown as ExtendedUtilities).isWikiWorkspaceWithRouting(w, currentWorkspace.id))
|
||||
.sort(workspaceSorter);
|
||||
|
||||
this.wikisWithRouting = workspacesWithRouting;
|
||||
|
|
@ -142,7 +142,7 @@ export class FileSystemAdaptor {
|
|||
}
|
||||
|
||||
// Find matching workspace using the routing logic
|
||||
const matchingWiki = matchTiddlerToWorkspace(title, tags, this.wikisWithRouting, $tw.wiki, $tw.rootWidget);
|
||||
const matchingWiki = ($tw.utils as unknown as ExtendedUtilities).matchTiddlerToWorkspace(title, tags, this.wikisWithRouting, $tw.wiki, $tw.rootWidget);
|
||||
|
||||
// Determine the target directory based on routing
|
||||
// Sub-wikis store tiddlers directly in their root folder (not in /tiddlers subfolder)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
title: $:/plugins/linonetwo/watch-filesystem-adaptor/WatchFileSystemAdaptor.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
|
@ -68,6 +68,11 @@ export class WatchFileSystemAdaptor extends FileSystemAdaptor {
|
|||
private baseExcludedPaths: string[] = [];
|
||||
/** Excluded path patterns that apply to all wikis (main and sub-wikis) */
|
||||
private readonly excludedPathPatterns: string[] = ['.git', 'node_modules', '.DS_Store'];
|
||||
/**
|
||||
* External attachments folder to exclude (read from config)
|
||||
* Default is 'files', but can be configured via $:/config/ExternalAttachments/WikiFolderToMove
|
||||
*/
|
||||
private externalAttachmentsFolder: string = 'files';
|
||||
/**
|
||||
* Track pending file deletions to handle git revert/checkout scenarios.
|
||||
* Maps absolute file path to deletion timer.
|
||||
|
|
@ -124,6 +129,12 @@ export class WatchFileSystemAdaptor extends FileSystemAdaptor {
|
|||
}
|
||||
|
||||
if (this.workspace) {
|
||||
// Load external attachments folder name from config
|
||||
const externalAttachmentsFolderConfig = this.wiki.getTiddlerText('$:/config/ExternalAttachments/WikiFolderToMove', 'files');
|
||||
if (externalAttachmentsFolderConfig) {
|
||||
this.externalAttachmentsFolder = externalAttachmentsFolderConfig;
|
||||
}
|
||||
|
||||
this.ignoreSymlinks = this.workspace.ignoreSymlinks;
|
||||
}
|
||||
await this.initializeFileWatching();
|
||||
|
|
@ -452,20 +463,26 @@ export class WatchFileSystemAdaptor extends FileSystemAdaptor {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if a path contains any excluded pattern (like .git, node_modules)
|
||||
* Check if a path contains any excluded pattern (like .git, node_modules, or external attachments folder)
|
||||
* This checks all parts of the path, so it will catch:
|
||||
* - Direct .git directories: wiki/.git/config
|
||||
* - Sub-wiki .git directories: wiki/tiddlers/subwiki/.git/index.lock
|
||||
* - Symlinked .git directories: wiki/tiddlers/link-to-subwiki/.git/config
|
||||
* - External attachments folders: wiki/files/image.png
|
||||
* @param filePath File or directory path to check
|
||||
* @returns true if path should be excluded
|
||||
*/
|
||||
private shouldExcludeByPattern(filePath: string): boolean {
|
||||
// Check if any part of the path contains excluded patterns
|
||||
return this.excludedPathPatterns.some(pattern => {
|
||||
const pathParts = filePath.split(path.sep);
|
||||
return pathParts.includes(pattern);
|
||||
});
|
||||
const pathParts = filePath.split(path.sep);
|
||||
|
||||
// Check standard excluded patterns
|
||||
const hasExcludedPattern = this.excludedPathPatterns.some(pattern => pathParts.includes(pattern));
|
||||
|
||||
// Check external attachments folder
|
||||
const hasExternalAttachmentsFolder = pathParts.includes(this.externalAttachmentsFolder);
|
||||
|
||||
return hasExcludedPattern || hasExternalAttachmentsFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
// Only export in Node.js environment
|
||||
if ($tw.node) {
|
||||
const WatchFileSystemAdaptor = require('./WatchFileSystemAdaptor').WatchFileSystemAdaptor;
|
||||
const WatchFileSystemAdaptor = require('$:/plugins/linonetwo/watch-filesystem-adaptor/WatchFileSystemAdaptor.js').WatchFileSystemAdaptor;
|
||||
exports.adaptorClass = WatchFileSystemAdaptor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
title: $:/plugins/linonetwo/watch-filesystem-adaptor/routingUtilities.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
|
@ -1,9 +1,15 @@
|
|||
import type { IWikiWorkspace, IWorkspace } from '@services/workspaces/interface';
|
||||
import { workspaceSorter } from '@services/workspaces/utilities';
|
||||
|
||||
/**
|
||||
* Sub-wiki routing utilities for matching tiddlers/files to workspaces.
|
||||
* These utilities are exposed as $tw.utils functions for use in plugins.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if a workspace has routing configuration (tagNames or fileSystemPathFilter).
|
||||
*/
|
||||
export function hasRoutingConfig(workspaceItem: IWorkspace): boolean {
|
||||
function hasRoutingConfig(workspaceItem: IWorkspace): boolean {
|
||||
const hasTagNames = 'tagNames' in workspaceItem && Array.isArray(workspaceItem.tagNames) && workspaceItem.tagNames.length > 0;
|
||||
const hasFilter = 'fileSystemPathFilterEnable' in workspaceItem &&
|
||||
workspaceItem.fileSystemPathFilterEnable &&
|
||||
|
|
@ -16,7 +22,7 @@ export function hasRoutingConfig(workspaceItem: IWorkspace): boolean {
|
|||
* Check if a workspace is a wiki workspace with routing configuration.
|
||||
* This filters to wiki workspaces that are either the main workspace or sub-wikis of it.
|
||||
*/
|
||||
export function isWikiWorkspaceWithRouting(
|
||||
function isWikiWorkspaceWithRouting(
|
||||
workspaceItem: IWorkspace,
|
||||
mainWorkspaceId: string,
|
||||
): workspaceItem is IWikiWorkspace {
|
||||
|
|
@ -48,7 +54,7 @@ export function isWikiWorkspaceWithRouting(
|
|||
* - Any of the tiddler's tags match any of the workspace's tagNames
|
||||
* - The tiddler's title IS one of the tagNames (it's a "tag tiddler")
|
||||
*/
|
||||
export function matchesDirectTag(
|
||||
function matchesDirectTag(
|
||||
tiddlerTitle: string,
|
||||
tiddlerTags: string[],
|
||||
workspaceTagNames: string[],
|
||||
|
|
@ -67,7 +73,7 @@ export function matchesDirectTag(
|
|||
* Check if a tiddler matches a workspace's tag tree routing.
|
||||
* Uses TiddlyWiki's in-tagtree-of filter for recursive tag hierarchy matching.
|
||||
*/
|
||||
export function matchesTagTree(
|
||||
function matchesTagTree(
|
||||
tiddlerTitle: string,
|
||||
workspaceTagNames: string[],
|
||||
wiki: typeof $tw.wiki,
|
||||
|
|
@ -90,7 +96,7 @@ export function matchesTagTree(
|
|||
* Check if a tiddler matches a workspace's custom filter routing.
|
||||
* Filters are separated by newlines; any match wins.
|
||||
*/
|
||||
export function matchesCustomFilter(
|
||||
function matchesCustomFilter(
|
||||
tiddlerTitle: string,
|
||||
filterExpression: string,
|
||||
wiki: typeof $tw.wiki,
|
||||
|
|
@ -116,7 +122,7 @@ export function matchesCustomFilter(
|
|||
* 2. If includeTagTree is enabled, use in-tagtree-of filter for recursive tag matching
|
||||
* 3. If fileSystemPathFilterEnable is enabled, use custom filter expressions
|
||||
*/
|
||||
export function matchTiddlerToWorkspace(
|
||||
function matchTiddlerToWorkspace(
|
||||
tiddlerTitle: string,
|
||||
tiddlerTags: string[],
|
||||
workspacesWithRouting: IWikiWorkspace[],
|
||||
|
|
@ -146,3 +152,12 @@ export function matchTiddlerToWorkspace(
|
|||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
declare const exports: Record<string, unknown>;
|
||||
exports.hasRoutingConfig = hasRoutingConfig;
|
||||
exports.isWikiWorkspaceWithRouting = isWikiWorkspaceWithRouting;
|
||||
exports.workspaceSorter = workspaceSorter;
|
||||
exports.matchesDirectTag = matchesDirectTag;
|
||||
exports.matchesTagTree = matchesTagTree;
|
||||
exports.matchesCustomFilter = matchesCustomFilter;
|
||||
exports.matchTiddlerToWorkspace = matchTiddlerToWorkspace;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Type definitions for extended TiddlyWiki $tw.utils with routing utilities
|
||||
*/
|
||||
|
||||
import type { IWikiWorkspace, IWorkspace } from '@services/workspaces/interface';
|
||||
|
||||
/**
|
||||
* Extended utilities interface with routing utilities
|
||||
*/
|
||||
export interface ExtendedUtilities {
|
||||
isWikiWorkspaceWithRouting(workspace: IWorkspace, mainWorkspaceId: string): workspace is IWikiWorkspace;
|
||||
matchTiddlerToWorkspace(
|
||||
tiddlerTitle: string,
|
||||
tiddlerTags: string[],
|
||||
workspacesWithRouting: IWikiWorkspace[],
|
||||
wiki: typeof $tw.wiki,
|
||||
rootWidget: typeof $tw.rootWidget,
|
||||
): IWikiWorkspace | undefined;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue