@jwilleke/ngdpbase-types 0.0.0 → 5.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +16 -2
- package/lib/packages/ngdpbase-types/index.d.ts +32 -0
- package/lib/packages/ngdpbase-types/testing.d.ts +43 -0
- package/lib/packages/ngdpbase-types/testing.js +53 -0
- package/lib/src/cache/CacheDependencies.d.ts +50 -0
- package/lib/src/cache/CacheDependencies.js +50 -0
- package/lib/src/cache/ICacheAdapter.d.ts +86 -0
- package/lib/src/cache/RegionCache.d.ts +171 -0
- package/lib/src/context/ActorContext.d.ts +48 -0
- package/lib/src/context/ActorContext.js +33 -0
- package/lib/src/context/ApiContext.d.ts +194 -0
- package/lib/src/context/ApiContext.js +273 -0
- package/lib/src/context/BaseContext.d.ts +110 -0
- package/lib/src/context/BaseContext.js +143 -0
- package/lib/src/context/JobContext.d.ts +153 -0
- package/lib/src/context/JobContext.js +144 -0
- package/lib/src/context/WikiContext.d.ts +404 -0
- package/lib/src/context/bootActions.d.ts +64 -0
- package/lib/src/context/bootActions.js +111 -0
- package/lib/src/converters/HtmlConverter.d.ts +70 -0
- package/lib/src/converters/IContentConverter.d.ts +94 -0
- package/lib/src/converters/JSPWikiConverter.d.ts +117 -0
- package/lib/src/converters/conversionWarning.d.ts +15 -0
- package/lib/src/converters/ncm/bridge.d.ts +22 -0
- package/lib/src/converters/ncm/existing.d.ts +23 -0
- package/lib/src/converters/ncm/fix/blocks.d.ts +89 -0
- package/lib/src/converters/ncm/fix/bulletMarkers.d.ts +21 -0
- package/lib/src/converters/ncm/fix/index.d.ts +36 -0
- package/lib/src/converters/ncm/fix/jspwikiBullets.d.ts +20 -0
- package/lib/src/converters/ncm/fix/jspwikiCodeMarkers.d.ts +38 -0
- package/lib/src/converters/ncm/fix/jspwikiHeadings.d.ts +25 -0
- package/lib/src/converters/ncm/fix/jspwikiIndent.d.ts +24 -0
- package/lib/src/converters/ncm/fix/jspwikiInsert.d.ts +21 -0
- package/lib/src/converters/ncm/fix/jspwikiItalic.d.ts +29 -0
- package/lib/src/converters/ncm/fix/jspwikiLinkLeftovers.d.ts +27 -0
- package/lib/src/converters/ncm/fix/moreInformationFooter.d.ts +25 -0
- package/lib/src/converters/ncm/fix/styleClosers.d.ts +25 -0
- package/lib/src/converters/ncm/fix/tightenLists.d.ts +30 -0
- package/lib/src/converters/ncm/fix/types.d.ts +33 -0
- package/lib/src/converters/ncm/footnotes.d.ts +39 -0
- package/lib/src/converters/ncm/images.d.ts +49 -0
- package/lib/src/converters/ncm/index.d.ts +20 -0
- package/lib/src/converters/ncm/links.d.ts +21 -0
- package/lib/src/converters/ncm/normalize.d.ts +39 -0
- package/lib/src/converters/ncm/placeholder.d.ts +25 -0
- package/lib/src/converters/ncm/tables.d.ts +36 -0
- package/lib/src/converters/ncm/types.d.ts +42 -0
- package/lib/src/http/egressPolicy.d.ts +52 -0
- package/lib/src/http/guardedFetch.d.ts +89 -0
- package/lib/src/http/guardedFetch.js +113 -0
- package/lib/src/http/guardedLookup.d.ts +48 -0
- package/lib/src/http/guardedLookup.js +73 -0
- package/lib/src/http/ssrf.d.ts +83 -0
- package/lib/src/http/ssrf.js +311 -0
- package/lib/src/mail/MailProvider.d.ts +36 -0
- package/lib/src/mail/NodemailerMailProvider.d.ts +26 -0
- package/lib/src/managers/AddonsManager.d.ts +691 -0
- package/lib/src/managers/AgentTokenManager.d.ts +269 -0
- package/lib/src/managers/AssetManager.d.ts +116 -0
- package/lib/src/managers/AttachmentManager.d.ts +1032 -0
- package/lib/src/managers/AuthManager.d.ts +1257 -0
- package/lib/src/managers/BackgroundJobManager.d.ts +434 -0
- package/lib/src/managers/BaseManager.d.ts +391 -0
- package/lib/src/managers/BaseManager.js +415 -0
- package/lib/src/managers/CacheManager.d.ts +159 -0
- package/lib/src/managers/CatalogManager.d.ts +235 -0
- package/lib/src/managers/CommentManager.d.ts +75 -0
- package/lib/src/managers/ConfigurationManager.d.ts +747 -0
- package/lib/src/managers/DatabaseManager.d.ts +89 -0
- package/lib/src/managers/DatabaseManager.js +236 -0
- package/lib/src/managers/EmailManager.d.ts +47 -0
- package/lib/src/managers/ExportManager.d.ts +129 -0
- package/lib/src/managers/ExportManager.js +420 -0
- package/lib/src/managers/FootnoteManager.d.ts +118 -0
- package/lib/src/managers/MediaManager.d.ts +279 -0
- package/lib/src/managers/MetricsManager.d.ts +89 -0
- package/lib/src/managers/NotificationManager.d.ts +165 -0
- package/lib/src/managers/OidcManager.d.ts +210 -0
- package/lib/src/managers/OrganizationManager.d.ts +107 -0
- package/lib/src/managers/PageManager.d.ts +1645 -0
- package/lib/src/managers/PersonManager.d.ts +48 -0
- package/lib/src/managers/PluginManager.d.ts +179 -0
- package/lib/src/managers/PluginManager.js +393 -0
- package/lib/src/managers/PolicyEvaluator.d.ts +213 -0
- package/lib/src/managers/RenderingManager.d.ts +358 -0
- package/lib/src/managers/RoleManager.d.ts +134 -0
- package/lib/src/managers/SearchManager.d.ts +402 -0
- package/lib/src/managers/ShareManager.d.ts +251 -0
- package/lib/src/managers/TemplateManager.d.ts +176 -0
- package/lib/src/managers/ThemeManager.d.ts +56 -0
- package/lib/src/managers/UserManager.d.ts +480 -0
- package/lib/src/managers/ValidationManager.d.ts +426 -0
- package/lib/src/managers/VariableManager.d.ts +145 -0
- package/lib/src/middleware/csrf.d.ts +3 -0
- package/lib/src/parsers/LinkParser.d.ts +457 -0
- package/lib/src/parsers/MarkupParser.d.ts +769 -0
- package/lib/src/parsers/context/ParseContext.d.ts +314 -0
- package/lib/src/parsers/data/emoji-map.d.ts +18 -0
- package/lib/src/parsers/dom/DOMBuilder.d.ts +210 -0
- package/lib/src/parsers/dom/DOMParser.d.ts +252 -0
- package/lib/src/parsers/dom/Tokenizer.d.ts +358 -0
- package/lib/src/parsers/dom/WikiDocument.d.ts +272 -0
- package/lib/src/parsers/dom/handlers/DOMLinkHandler.d.ts +260 -0
- package/lib/src/parsers/dom/handlers/DOMPluginHandler.d.ts +212 -0
- package/lib/src/parsers/dom/handlers/DOMVariableHandler.d.ts +171 -0
- package/lib/src/parsers/filters/BaseFilter.d.ts +269 -0
- package/lib/src/parsers/filters/FilterChain.d.ts +320 -0
- package/lib/src/parsers/handlers/BaseSyntaxHandler.d.ts +331 -0
- package/lib/src/parsers/handlers/HandlerRegistry.d.ts +225 -0
- package/lib/src/parsers/handlers/JSPWikiPreprocessor.d.ts +89 -0
- package/lib/src/parsers/handlers/LinkParserHandler.d.ts +80 -0
- package/lib/src/parsers/handlers/PluginSyntaxHandler.d.ts +78 -0
- package/lib/src/parsers/handlers/WikiFormHandler.d.ts +149 -0
- package/lib/src/parsers/handlers/WikiTagHandler.d.ts +125 -0
- package/lib/src/parsers/jspwikiTableRow.d.ts +39 -0
- package/lib/src/parsers/styleBlockSyntax.d.ts +14 -0
- package/lib/src/plugins/types.d.ts +79 -0
- package/lib/src/providers/AgentTokenAuthProvider.d.ts +40 -0
- package/lib/src/providers/AuthentikBearerAuthProvider.d.ts +75 -0
- package/lib/src/providers/BaseAttachmentProvider.d.ts +197 -0
- package/lib/src/providers/BaseAuthProvider.d.ts +220 -0
- package/lib/src/providers/BaseCacheProvider.d.ts +140 -0
- package/lib/src/providers/BaseCredentialsProvider.d.ts +84 -0
- package/lib/src/providers/BaseDatabaseProvider.d.ts +22 -0
- package/lib/src/providers/BaseDatabaseProvider.js +12 -0
- package/lib/src/providers/BaseLoggingProvider.d.ts +68 -0
- package/lib/src/providers/BaseLoggingProvider.js +37 -0
- package/lib/src/providers/BaseMediaProvider.d.ts +308 -0
- package/lib/src/providers/BasePageProvider.d.ts +337 -0
- package/lib/src/providers/BaseProvider.d.ts +98 -0
- package/lib/src/providers/BaseProvider.js +74 -0
- package/lib/src/providers/BaseSearchProvider.d.ts +362 -0
- package/lib/src/providers/BasicAttachmentProvider.d.ts +599 -0
- package/lib/src/providers/CloudflareAccessAuthProvider.d.ts +72 -0
- package/lib/src/providers/FileCredentialsProvider.d.ts +33 -0
- package/lib/src/providers/FileJobStateProvider.d.ts +58 -0
- package/lib/src/providers/FileLoggingProvider.d.ts +43 -0
- package/lib/src/providers/FileLoggingProvider.js +120 -0
- package/lib/src/providers/FileOidcAdapter.d.ts +25 -0
- package/lib/src/providers/FileSystemMediaProvider.d.ts +403 -0
- package/lib/src/providers/LunrSearchProvider.d.ts +280 -0
- package/lib/src/providers/MagicLinkAuthProvider.d.ts +125 -0
- package/lib/src/providers/NullCacheProvider.d.ts +72 -0
- package/lib/src/providers/OidcAuthProvider.d.ts +180 -0
- package/lib/src/providers/OidcBearerAuthProvider.d.ts +30 -0
- package/lib/src/providers/PasskeyAuthProvider.d.ts +58 -0
- package/lib/src/providers/PasswordAuthProvider.d.ts +20 -0
- package/lib/src/providers/SqliteDatabaseProvider.d.ts +55 -0
- package/lib/src/providers/SqliteDatabaseProvider.js +90 -0
- package/lib/src/providers/SqliteJobStateProvider.d.ts +41 -0
- package/lib/src/providers/databaseMigrations.d.ts +8 -0
- package/lib/src/providers/databaseMigrations.js +47 -0
- package/lib/src/providers/jobState.d.ts +99 -0
- package/lib/src/providers/lunrQueryToMiniSearch.d.ts +32 -0
- package/lib/src/providers/mediaFilenameDate.d.ts +22 -0
- package/lib/src/providers/sqliteLocation.d.ts +17 -0
- package/lib/src/providers/sqliteLocation.js +55 -0
- package/lib/src/providers/sqliteMigrations.d.ts +48 -0
- package/lib/src/providers/sqliteMigrations.js +72 -0
- package/lib/src/rendering/githubAlerts.d.ts +22 -0
- package/lib/src/rendering/htmlPolicy.d.ts +76 -0
- package/lib/src/rendering/markdownConverter.d.ts +73 -0
- package/lib/src/security/PolicyDecisionPoint.d.ts +245 -0
- package/lib/src/security/PolicyInformationPoint.d.ts +448 -0
- package/lib/src/security/pageActions.d.ts +40 -0
- package/lib/src/security/permissions.generated.d.ts +78 -0
- package/lib/src/types/Asset.d.ts +414 -0
- package/lib/src/types/Catalog.d.ts +61 -0
- package/lib/src/types/Comment.d.ts +11 -0
- package/lib/src/types/Config.d.ts +388 -0
- package/lib/src/types/Organization.d.ts +78 -0
- package/lib/src/types/OrganizationProvider.d.ts +38 -0
- package/lib/src/types/Page.d.ts +220 -0
- package/lib/src/types/Person.d.ts +56 -0
- package/lib/src/types/PersonProvider.d.ts +25 -0
- package/lib/src/types/Policy.d.ts +139 -0
- package/lib/src/types/Policy.js +17 -0
- package/lib/src/types/Provider.d.ts +810 -0
- package/lib/src/types/Role.d.ts +84 -0
- package/lib/src/types/RoleProvider.d.ts +35 -0
- package/lib/src/types/Schema.d.ts +425 -0
- package/lib/src/types/Share.d.ts +172 -0
- package/lib/src/types/Share.js +81 -0
- package/lib/src/types/User.d.ts +304 -0
- package/lib/src/types/Version.d.ts +189 -0
- package/lib/src/types/WikiEngine.d.ts +128 -0
- package/lib/src/types/express.d.ts +120 -0
- package/lib/src/types/express.js +1 -0
- package/lib/src/types/guards.d.ts +78 -0
- package/lib/src/types/heic-decode.d.ts +16 -0
- package/lib/src/types/index.d.ts +19 -0
- package/lib/src/types/linkedom.d.ts +77 -0
- package/lib/src/types/markdown-it-plugins.d.ts +21 -0
- package/lib/src/utils/DeltaStorage.d.ts +118 -0
- package/lib/src/utils/LocaleUtils.d.ts +105 -0
- package/lib/src/utils/LocaleUtils.js +294 -0
- package/lib/src/utils/PageNameMatcher.d.ts +98 -0
- package/lib/src/utils/PathPreflight.d.ts +38 -0
- package/lib/src/utils/PathPreflight.js +50 -0
- package/lib/src/utils/SectionUtils.d.ts +40 -0
- package/lib/src/utils/addonConfigLayer.d.ts +144 -0
- package/lib/src/utils/addonConfigLayer.js +382 -0
- package/lib/src/utils/addonDatabaseRules.d.ts +25 -0
- package/lib/src/utils/addonDatabaseRules.js +57 -0
- package/lib/src/utils/addonHost.d.ts +51 -0
- package/lib/src/utils/addonHost.js +72 -0
- package/lib/src/utils/addonInstaller.d.ts +109 -0
- package/lib/src/utils/addonLock.d.ts +37 -0
- package/lib/src/utils/addonLock.js +48 -0
- package/lib/src/utils/addonPageSync.d.ts +45 -0
- package/lib/src/utils/addonProvenance.d.ts +48 -0
- package/lib/src/utils/addonTarball.d.ts +41 -0
- package/lib/src/utils/addonsPathResolver.d.ts +76 -0
- package/lib/src/utils/addonsPathResolver.js +129 -0
- package/lib/src/utils/assetMetadataTags.d.ts +66 -0
- package/lib/src/utils/atomicWrite.d.ts +28 -0
- package/lib/src/utils/auditConfigChange.d.ts +57 -0
- package/lib/src/utils/auditEventNames.d.ts +50 -0
- package/lib/src/utils/auditEventNames.generated.d.ts +163 -0
- package/lib/src/utils/auditEventNames.generated.js +168 -0
- package/lib/src/utils/auditEventNames.js +49 -0
- package/lib/src/utils/auditEvents.d.ts +265 -0
- package/lib/src/utils/auditEvents.js +309 -0
- package/lib/src/utils/auditRegistry.d.ts +102 -0
- package/lib/src/utils/auditRegistry.js +168 -0
- package/lib/src/utils/bip39English.d.ts +2 -0
- package/lib/src/utils/configEnvKeys.d.ts +68 -0
- package/lib/src/utils/configFiles.d.ts +74 -0
- package/lib/src/utils/configFiles.js +150 -0
- package/lib/src/utils/delegation.d.ts +48 -0
- package/lib/src/utils/deriveUsername.d.ts +21 -0
- package/lib/src/utils/explainMediaPath.d.ts +123 -0
- package/lib/src/utils/formerTitles.d.ts +69 -0
- package/lib/src/utils/frontmatterAccess.d.ts +54 -0
- package/lib/src/utils/headlessAdminPassword.d.ts +55 -0
- package/lib/src/utils/imageTransform.d.ts +52 -0
- package/lib/src/utils/instanceEnvSecret.d.ts +51 -0
- package/lib/src/utils/jobSlots.d.ts +43 -0
- package/lib/src/utils/keywordNormalizer.d.ts +127 -0
- package/lib/src/utils/logger.d.ts +70 -0
- package/lib/src/utils/logger.js +106 -0
- package/lib/src/utils/magicLinkDeviceState.d.ts +95 -0
- package/lib/src/utils/managerUtils.d.ts +40 -0
- package/lib/src/utils/migrateLegacyPrivateAttachments.d.ts +15 -0
- package/lib/src/utils/orgFilename.d.ts +22 -0
- package/lib/src/utils/pageFeature.d.ts +27 -0
- package/lib/src/utils/pageFrontmatter.d.ts +21 -0
- package/lib/src/utils/pageNotes.d.ts +150 -0
- package/lib/src/utils/pageTitleRule.d.ts +37 -0
- package/lib/src/utils/pageToArticle.d.ts +59 -0
- package/lib/src/utils/pageUrl.d.ts +18 -0
- package/lib/src/utils/passwordChange.d.ts +12 -0
- package/lib/src/utils/passwordHash.d.ts +60 -0
- package/lib/src/utils/permissionCatalog.d.ts +52 -0
- package/lib/src/utils/pluginFormatters.d.ts +452 -0
- package/lib/src/utils/pluginFormatters.js +714 -0
- package/lib/src/utils/privateLinkRewrite.d.ts +42 -0
- package/lib/src/utils/privateStoreAccess.d.ts +57 -0
- package/lib/src/utils/privateStoreAccess.js +65 -0
- package/lib/src/utils/privateStoreCatalogs.d.ts +40 -0
- package/lib/src/utils/privateStoreCrypto.d.ts +127 -0
- package/lib/src/utils/privateStoreDoor.d.ts +181 -0
- package/lib/src/utils/privateStoreExport.d.ts +72 -0
- package/lib/src/utils/privateStoreFiles.d.ts +120 -0
- package/lib/src/utils/privateStoreMeta.d.ts +64 -0
- package/lib/src/utils/privateStoreMigrations.d.ts +37 -0
- package/lib/src/utils/privateStorePath.d.ts +259 -0
- package/lib/src/utils/privateStorePath.js +436 -0
- package/lib/src/utils/privateStoreTakeout.d.ts +76 -0
- package/lib/src/utils/privateStoreUnlock.d.ts +175 -0
- package/lib/src/utils/proxyClaim.d.ts +59 -0
- package/lib/src/utils/proxyClaim.js +30 -0
- package/lib/src/utils/redactPrivateNames.d.ts +21 -0
- package/lib/src/utils/redactPrivateNames.js +89 -0
- package/lib/src/utils/redactSecrets.d.ts +58 -0
- package/lib/src/utils/redactSecrets.js +171 -0
- package/lib/src/utils/renameLinkRewrite.d.ts +112 -0
- package/lib/src/utils/roleGrants.d.ts +35 -0
- package/lib/src/utils/safeRedirect.d.ts +32 -0
- package/lib/src/utils/schedule.d.ts +54 -0
- package/lib/src/utils/secretFileMode.d.ts +17 -0
- package/lib/src/utils/seededShippedPages.d.ts +45 -0
- package/lib/src/utils/sensitiveValues.d.ts +59 -0
- package/lib/src/utils/sensitiveValues.js +106 -0
- package/lib/src/utils/sessionEnd.d.ts +12 -0
- package/lib/src/utils/sessionGeneration.d.ts +24 -0
- package/lib/src/utils/sessionIdle.d.ts +41 -0
- package/lib/src/utils/sessionLimits.d.ts +68 -0
- package/lib/src/utils/shareLockbox.d.ts +64 -0
- package/lib/src/utils/sigstoreTrustedRoot.d.ts +33 -0
- package/lib/src/utils/sniffMime.d.ts +21 -0
- package/lib/src/utils/storeSearchIndex.d.ts +75 -0
- package/lib/src/utils/subjectMayDo.d.ts +21 -0
- package/lib/src/utils/systemCategoryRules.d.ts +30 -0
- package/lib/src/utils/systemCategoryRules.js +41 -0
- package/lib/src/utils/userCreateError.d.ts +62 -0
- package/lib/src/utils/username.d.ts +53 -0
- package/lib/src/utils/vaultUrlRewrite.d.ts +27 -0
- package/lib/src/utils/version.d.ts +84 -0
- package/lib/src/utils/videoFrame.d.ts +21 -0
- package/package.json +54 -3
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileSystemMediaProvider - Filesystem-based implementation of BaseMediaProvider
|
|
3
|
+
*
|
|
4
|
+
* Scans configured directories for media files, extracts EXIF/IPTC/XMP metadata
|
|
5
|
+
* via exiftool-vendored, generates thumbnails via Sharp, and maintains a
|
|
6
|
+
* persistent JSON index.
|
|
7
|
+
*
|
|
8
|
+
* Dependencies:
|
|
9
|
+
* - exiftool-vendored — EXIF/IPTC/XMP metadata extraction
|
|
10
|
+
* - sharp — thumbnail generation (already installed)
|
|
11
|
+
* - fs-extra — filesystem helpers
|
|
12
|
+
*
|
|
13
|
+
* @module FileSystemMediaProvider
|
|
14
|
+
*/
|
|
15
|
+
import { type MediaPathExplanation, type MediaSkipReport } from '../utils/explainMediaPath.js';
|
|
16
|
+
import BaseMediaProvider, { MediaItem, ScanResult } from './BaseMediaProvider.js';
|
|
17
|
+
import type { AssetMetadataPatch } from '../types/Asset.js';
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for FileSystemMediaProvider.
|
|
20
|
+
*/
|
|
21
|
+
export interface FileSystemMediaProviderConfig {
|
|
22
|
+
/** Absolute paths to the root media folders to scan */
|
|
23
|
+
folders: string[];
|
|
24
|
+
/** Directory names to skip during scan (e.g. [".dtrash", ".ts"]) */
|
|
25
|
+
ignoreDirs: string[];
|
|
26
|
+
/** Maximum directory depth to recurse into (0 = unlimited) */
|
|
27
|
+
maxDepth: number;
|
|
28
|
+
/** Absolute path to the media-index.json file */
|
|
29
|
+
indexFile: string;
|
|
30
|
+
/** Absolute path to the thumbnail cache directory */
|
|
31
|
+
thumbnailDir: string;
|
|
32
|
+
/** Comma-separated thumbnail size specs (e.g. "300x300,150x150") */
|
|
33
|
+
thumbnailSizes: string;
|
|
34
|
+
/** Metadata extraction priority order (e.g. ["EXIF", "IPTC", "XMP"]) */
|
|
35
|
+
metadataPriority: string[];
|
|
36
|
+
/** Whether the provider may write to source media folders (always false) */
|
|
37
|
+
readonly: boolean;
|
|
38
|
+
/** Set of file extensions (lowercase, no dot) to index */
|
|
39
|
+
extensions: Set<string>;
|
|
40
|
+
}
|
|
41
|
+
/** Default supported media file extensions — used when no config override is provided */
|
|
42
|
+
export declare const DEFAULT_MEDIA_EXTENSIONS: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Filesystem-based media provider.
|
|
45
|
+
*
|
|
46
|
+
* Scans configured folders, extracts metadata with ExifTool, and maintains a
|
|
47
|
+
* persistent JSON index. Thumbnails are generated on demand via Sharp and cached
|
|
48
|
+
* to thumbnailDir.
|
|
49
|
+
*/
|
|
50
|
+
declare class FileSystemMediaProvider extends BaseMediaProvider {
|
|
51
|
+
readonly id = "media-library";
|
|
52
|
+
readonly displayName = "Media Library";
|
|
53
|
+
readonly capabilities: import('../types/Asset.js').ProviderCapability[];
|
|
54
|
+
private readonly config;
|
|
55
|
+
/** In-memory index: id → MediaIndexEntry */
|
|
56
|
+
private index;
|
|
57
|
+
/** Single ExifTool worker process reused across all reads */
|
|
58
|
+
private readonly exiftoolInstance;
|
|
59
|
+
constructor(config: FileSystemMediaProviderConfig);
|
|
60
|
+
/**
|
|
61
|
+
* Load the persisted index from disk so queries work immediately
|
|
62
|
+
* (before the first background scan).
|
|
63
|
+
*/
|
|
64
|
+
initialize(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Release the ExifTool worker process.
|
|
67
|
+
*/
|
|
68
|
+
shutdown(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Verify that at least one configured media folder is accessible.
|
|
71
|
+
*
|
|
72
|
+
* Returns false when every configured folder is unreachable — e.g. a NAS or
|
|
73
|
+
* SLOW_STORAGE volume that has been unmounted or an SMB share that has dropped.
|
|
74
|
+
* A partial failure (some folders gone, others present) still returns true so
|
|
75
|
+
* the provider continues serving what it can; the warning log indicates which
|
|
76
|
+
* folders are missing.
|
|
77
|
+
*/
|
|
78
|
+
healthCheck(): Promise<boolean>;
|
|
79
|
+
/**
|
|
80
|
+
* The configured folders this process cannot read (#1167): missing, unmounted
|
|
81
|
+
* or without read permission. Read-only — it never touches the files.
|
|
82
|
+
*/
|
|
83
|
+
unreachableFolders(): Promise<string[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Rebuild the media index from scratch.
|
|
86
|
+
*
|
|
87
|
+
* Clears the in-memory index and deletes the persisted index file, then
|
|
88
|
+
* runs a forced full scan so the result reflects only files currently on disk.
|
|
89
|
+
*
|
|
90
|
+
* @param onProgress - Optional callback invoked periodically with (processed, total).
|
|
91
|
+
*/
|
|
92
|
+
rebuild(onProgress?: (processed: number, total: number) => void): Promise<ScanResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Scan all configured folders, extract metadata for new/changed files,
|
|
95
|
+
* save the updated index, and return a summary.
|
|
96
|
+
*
|
|
97
|
+
* Phase 1: recursively collect all matching file paths (fast, no ExifTool).
|
|
98
|
+
* Phase 2: process files concurrently in batches of BATCH_SIZE, calling
|
|
99
|
+
* ExifTool for each file that needs metadata extraction.
|
|
100
|
+
*
|
|
101
|
+
* @param force - Re-process every file even if mtime is unchanged.
|
|
102
|
+
* @param onProgress - Optional callback invoked after each batch with (processed, total).
|
|
103
|
+
*/
|
|
104
|
+
scan(force?: boolean, onProgress?: (processed: number, total: number) => void): Promise<ScanResult>;
|
|
105
|
+
/**
|
|
106
|
+
* Remove index entries whose file path is not among the primaries found in
|
|
107
|
+
* this scan, restricted to folders that were fully walked (#867).
|
|
108
|
+
*
|
|
109
|
+
* @param presentPaths - All primary file paths collected in this scan.
|
|
110
|
+
* @param prunableFolders - Folders that exist and were walked without read errors.
|
|
111
|
+
* @param counters - Scan counters; `removed` is incremented per pruned entry.
|
|
112
|
+
*/
|
|
113
|
+
private pruneStaleEntries;
|
|
114
|
+
/**
|
|
115
|
+
* Return the list of years that have at least one item, sorted descending.
|
|
116
|
+
*/
|
|
117
|
+
getYears(): Promise<number[]>;
|
|
118
|
+
/**
|
|
119
|
+
* Every item with a year, in one pass over the index (#1741).
|
|
120
|
+
*/
|
|
121
|
+
getItemCount(): Promise<number>;
|
|
122
|
+
/**
|
|
123
|
+
* Retrieve a single item by id.
|
|
124
|
+
*/
|
|
125
|
+
getItem(id: string): Promise<MediaItem | null>;
|
|
126
|
+
/**
|
|
127
|
+
* Return all items for a given year, sorted by filename.
|
|
128
|
+
*/
|
|
129
|
+
getItemsByYear(year: number): Promise<MediaItem[]>;
|
|
130
|
+
/**
|
|
131
|
+
* Return all items whose capture timestamp falls in [after, before],
|
|
132
|
+
* sorted ascending by capture date (#864 — Dawarich date-window queries).
|
|
133
|
+
* Bounds are ISO-ish strings compared against `metadata.dateTimeOriginal`
|
|
134
|
+
* ("YYYY-MM-DD HH:MM:SS"); either bound may be omitted. Items without a
|
|
135
|
+
* capture date are never returned.
|
|
136
|
+
*/
|
|
137
|
+
getItemsByDateRange(after?: string, before?: string): Promise<MediaItem[]>;
|
|
138
|
+
/**
|
|
139
|
+
* Retrieve all items whose EXIF/XMP keywords include the page name — the
|
|
140
|
+
* only association between a media item and a page (#1427).
|
|
141
|
+
*/
|
|
142
|
+
getItemsByPage(pageName: string): Promise<MediaItem[]>;
|
|
143
|
+
getItemsByKeyword(keyword: string): Promise<MediaItem[]>;
|
|
144
|
+
/**
|
|
145
|
+
* #895: distinct keywords across the media index with item counts. O(n)
|
|
146
|
+
* over the in-memory index; scalar keyword values count as one-element
|
|
147
|
+
* arrays (#545 shape tolerance).
|
|
148
|
+
*/
|
|
149
|
+
getAllKeywordCounts(): Promise<Record<string, number>>;
|
|
150
|
+
/**
|
|
151
|
+
* #917: library-wide leaf→path map built from every item's hierarchical
|
|
152
|
+
* `keywordPaths`. Keys and values are canonical-value forms; a leaf with no
|
|
153
|
+
* genuine hierarchy (only a root-level occurrence) is omitted. #918 uses this
|
|
154
|
+
* to place a newly-added keyword at its known hierarchical home.
|
|
155
|
+
*/
|
|
156
|
+
getKeywordLeafPaths(): Promise<Record<string, string>>;
|
|
157
|
+
/**
|
|
158
|
+
* Find the first item whose filename (basename) exactly matches.
|
|
159
|
+
*
|
|
160
|
+
* Iterates the in-memory index; O(n) but the index is small enough that
|
|
161
|
+
* this is acceptable for the ad-hoc `media://` URI resolution path.
|
|
162
|
+
*
|
|
163
|
+
* @param filename - Basename to match exactly (e.g. "IMG_1234.jpg").
|
|
164
|
+
*/
|
|
165
|
+
findByFilename(filename: string): Promise<MediaItem | null>;
|
|
166
|
+
/**
|
|
167
|
+
* Full-text keyword search across filename, year, title,
|
|
168
|
+
* description, and keywords fields.
|
|
169
|
+
*
|
|
170
|
+
* All query tokens must match (AND semantics).
|
|
171
|
+
*/
|
|
172
|
+
searchItems(query: string): Promise<MediaItem[]>;
|
|
173
|
+
/**
|
|
174
|
+
* Write a metadata patch into the source file (and its alternate-format
|
|
175
|
+
* siblings, so e.g. a HEIC+JPG pair stays in sync), then refresh the index
|
|
176
|
+
* entry by re-reading the file — the index always reflects what is actually
|
|
177
|
+
* on disk, not what we intended to write.
|
|
178
|
+
*
|
|
179
|
+
* ExifTool's default backup behaviour is kept deliberately: the first write
|
|
180
|
+
* to a file leaves a `<name>_original` sibling. Those extensions are not in
|
|
181
|
+
* the indexable set, so scans ignore them.
|
|
182
|
+
*
|
|
183
|
+
* The re-extract records the file's new mtime, so the next scheduled scan
|
|
184
|
+
* sees an unchanged file and skips it (no churn). `alternates` is
|
|
185
|
+
* re-attached afterwards because processFile builds entries without it.
|
|
186
|
+
*/
|
|
187
|
+
updateItemMetadata(id: string, patch: AssetMetadataPatch): Promise<MediaItem | null>;
|
|
188
|
+
/**
|
|
189
|
+
* Return a thumbnail buffer (webp) for the given item and size.
|
|
190
|
+
*
|
|
191
|
+
* Thumbnails are cached on disk in config.thumbnailDir. Image items run
|
|
192
|
+
* through Sharp directly. Video items (#722 Slice 1) have a poster frame
|
|
193
|
+
* extracted via ffmpeg-static at the 1-second mark, then fed through the
|
|
194
|
+
* same Sharp pipeline so the on-disk cache layout and `/media/thumb/:id`
|
|
195
|
+
* endpoint are unchanged. Other item types (audio, docs) return null and
|
|
196
|
+
* fall back to the generic icon in the asset-picker / media library.
|
|
197
|
+
*
|
|
198
|
+
* @param id - Item identifier.
|
|
199
|
+
* @param size - Size string in the form "WxH" (e.g. "300x300").
|
|
200
|
+
*/
|
|
201
|
+
getThumbnailBuffer(id: string, size: string): Promise<Buffer | null>;
|
|
202
|
+
/**
|
|
203
|
+
* Group files by directory+stem and keep only the highest-priority format per group.
|
|
204
|
+
* Alternate paths are returned separately so they can be stored on the primary entry.
|
|
205
|
+
*/
|
|
206
|
+
private deduplicateFormats;
|
|
207
|
+
/**
|
|
208
|
+
* Recursively collect all matching media file paths under dirPath.
|
|
209
|
+
*
|
|
210
|
+
* Applies ignoreDirs, maxDepth, extension filter, and .ngdpbaseignore patterns.
|
|
211
|
+
* Does NOT call ExifTool — that happens in Phase 2 (processFile).
|
|
212
|
+
*/
|
|
213
|
+
private collectFilePaths;
|
|
214
|
+
/**
|
|
215
|
+
* Read and parse `.ngdpbaseignore` from the given directory if it exists.
|
|
216
|
+
* Returns an array of pattern strings (blank lines and `#` comments stripped).
|
|
217
|
+
*/
|
|
218
|
+
private loadIgnorePatterns;
|
|
219
|
+
/**
|
|
220
|
+
* Test a filename against a list of .ngdpbaseignore patterns.
|
|
221
|
+
* Patterns ending with `/` are directory-only; all others match both files and dirs.
|
|
222
|
+
*/
|
|
223
|
+
private matchesIgnorePattern;
|
|
224
|
+
/**
|
|
225
|
+
* Process a single media file: stat, EXIF read, index update.
|
|
226
|
+
*/
|
|
227
|
+
private processFile;
|
|
228
|
+
/**
|
|
229
|
+
* Explain why one absolute path is, or is not, in the media index (#848).
|
|
230
|
+
*
|
|
231
|
+
* #814 reported media "often not discovered" and triage found zero indexing
|
|
232
|
+
* bugs — every missing file was correctly skipped by a rule that leaves no
|
|
233
|
+
* visible trace. This answers the question for a single path.
|
|
234
|
+
*
|
|
235
|
+
* The rule ORDER lives in `explainMediaPath`, deliberately: the scanner
|
|
236
|
+
* decides the same things inline as `continue` statements, which is fine for
|
|
237
|
+
* scanning and useless for explaining. Keeping the classifier pure also lets
|
|
238
|
+
* a future skipped-file report (#1056) reuse it instead of adding a third
|
|
239
|
+
* copy of rules that already exist in two places.
|
|
240
|
+
*
|
|
241
|
+
* Facts are gathered in two passes so the expensive ones are not paid for a
|
|
242
|
+
* file that is already explained: index lookups are cheap, reading
|
|
243
|
+
* `.ngdpbaseignore` files and EXIF is not. Only a path that survives every
|
|
244
|
+
* cheap rule triggers the second pass.
|
|
245
|
+
*/
|
|
246
|
+
explainPath(target: string): Promise<MediaPathExplanation>;
|
|
247
|
+
/**
|
|
248
|
+
* First `.ngdpbaseignore` pattern matching the file or any directory between
|
|
249
|
+
* it and its scan root, or undefined.
|
|
250
|
+
*
|
|
251
|
+
* Walks root-downward because that is the order the scanner encounters the
|
|
252
|
+
* ignore files, so the pattern reported is the one that actually stopped it.
|
|
253
|
+
*/
|
|
254
|
+
private findIgnorePatternMatch;
|
|
255
|
+
/** Whether the file carries the `ngdpbaseignore` EXIF/XMP keyword. */
|
|
256
|
+
private hasIgnoreKeyword;
|
|
257
|
+
/**
|
|
258
|
+
* Generate a stable 32-character hex ID from the file path.
|
|
259
|
+
*/
|
|
260
|
+
private generateId;
|
|
261
|
+
/**
|
|
262
|
+
* Ordered capture-date field names checked for both year extraction and
|
|
263
|
+
* full-timestamp extraction. Order matches ExifTool's own precedence:
|
|
264
|
+
* `DateTimeOriginal` is the photographer's intent (image EXIF), the
|
|
265
|
+
* `*CreateDate` variants are the file/container creation timestamps that
|
|
266
|
+
* video formats use (issue #750: QuickTime:CreationDate flattens to
|
|
267
|
+
* `CreationDate` in exiftool-vendored's Tags shape).
|
|
268
|
+
*/
|
|
269
|
+
private static readonly CAPTURE_DATE_FIELDS;
|
|
270
|
+
/**
|
|
271
|
+
* Extract the formatted capture-date timestamp ("YYYY-MM-DD HH:MM:SS") from
|
|
272
|
+
* EXIF/QuickTime tags, falling back through `DateTimeOriginal` →
|
|
273
|
+
* `CreateDate` → `MediaCreateDate` → `CreationDate`.
|
|
274
|
+
*
|
|
275
|
+
* The first three already covered images; `CreationDate` is the
|
|
276
|
+
* QuickTime/Apple variant that video containers populate when the camera
|
|
277
|
+
* didn't write `DateTimeOriginal` (#750). Without this fallback, videos
|
|
278
|
+
* indexed `dateTimeOriginal: null` and silently dropped out of any
|
|
279
|
+
* capture-date sort/filter — only the year facet worked (via `extractYear`).
|
|
280
|
+
*
|
|
281
|
+
* Also reports whether the source tag was a **partial** date — the year was
|
|
282
|
+
* present but the month and/or day were missing and got defaulted to `01`
|
|
283
|
+
* (#808). A partial date is still stored (defaulted to Jan 1, which preserves
|
|
284
|
+
* the year facet and gives a usable sort key), but the caller surfaces it to
|
|
285
|
+
* admins at WARN level — distinct from a file with no capture date at all
|
|
286
|
+
* (ERROR). A missing **time** component (HH:MM:SS) does NOT count as partial:
|
|
287
|
+
* defaulting to `00:00:00` is harmless for day-granularity sorting.
|
|
288
|
+
*
|
|
289
|
+
* Returns `null` when no field provides a usable `.year`.
|
|
290
|
+
*/
|
|
291
|
+
private extractCaptureDate;
|
|
292
|
+
/**
|
|
293
|
+
* Ordered duration-tag fallback chain. Walked by `extractDuration()` until
|
|
294
|
+
* one yields a strictly positive value. Order is most-reliable-first.
|
|
295
|
+
*
|
|
296
|
+
* Why each field is in the chain:
|
|
297
|
+
* - `Duration` — container-level top tag, present in QuickTime/MP4/MOV,
|
|
298
|
+
* MKV, AVI, WAV, AIFF, FLAC, MPEG. Single value per file.
|
|
299
|
+
* - `TrackDuration` — per-track fallback when the container doesn't
|
|
300
|
+
* expose its own. exiftool-vendored flattens N tracks into one tag,
|
|
301
|
+
* keeping the last non-empty value seen.
|
|
302
|
+
* - `MediaDuration` — same per-track shape as TrackDuration, but often
|
|
303
|
+
* zero on Pixel/Android `.TS.mp4` files where track-N is metadata-only
|
|
304
|
+
* (this is the bug that motivated the chain — exiftool reported
|
|
305
|
+
* `Duration: 15.87 s` but `MediaDuration: 0 s` for the same file).
|
|
306
|
+
* - `AudioDuration` — audio-only fallback (rarely useful alone, but
|
|
307
|
+
* present in some streaming formats).
|
|
308
|
+
* - `GoogleTrackDuration` — Pixel-specific QuickTime extension.
|
|
309
|
+
* - `StreamDuration` — streaming containers (HLS chunks, etc.).
|
|
310
|
+
* - `TotalDuration` — MPEG-1/MPEG-2 alternative top-level tag.
|
|
311
|
+
*
|
|
312
|
+
* Excluded as not-a-playback-duration: `PreviewDuration`, `SelectionDuration`,
|
|
313
|
+
* `BulbDuration`, `ContrastFlowDuration`, `SampleDuration`, `BlockDuration`,
|
|
314
|
+
* `ClusterDuration`, `DefaultDuration`, `SlowMotionRegions*Duration*`, and
|
|
315
|
+
* all DICOM `*Duration` variants. Those are either codec-internal sub-sample
|
|
316
|
+
* markers or non-media (medical imaging, slow-mo region metadata, edit
|
|
317
|
+
* selection state).
|
|
318
|
+
*/
|
|
319
|
+
private static readonly DURATION_FIELDS;
|
|
320
|
+
/**
|
|
321
|
+
* Extract playback duration from ExifTool's duration tags and normalise to
|
|
322
|
+
* ISO 8601 duration format (e.g. "PT1M30S").
|
|
323
|
+
*
|
|
324
|
+
* Walks `DURATION_FIELDS` and accepts the first tag that yields a strictly
|
|
325
|
+
* positive number of seconds. Zero values are skipped — Pixel `.TS.mp4`
|
|
326
|
+
* files set `MediaDuration: 0 s` while `Duration: 15.87 s` is the real
|
|
327
|
+
* length, and prior versions of this method picked up the zero via
|
|
328
|
+
* `??` short-circuit (#758 follow-up).
|
|
329
|
+
*
|
|
330
|
+
* Accepted raw shapes per candidate field:
|
|
331
|
+
* - number of seconds (most common for QuickTime / MP4)
|
|
332
|
+
* - string like "0:01:30" / "00:01:30" / "30" (HH:MM:SS / MM:SS / SS)
|
|
333
|
+
* - already-ISO string like "PT1M30S"
|
|
334
|
+
* - exiftool-vendored Duration object (`.seconds` property)
|
|
335
|
+
*
|
|
336
|
+
* Returns null when no candidate field yields a positive duration.
|
|
337
|
+
*/
|
|
338
|
+
private extractDuration;
|
|
339
|
+
/**
|
|
340
|
+
* Extract average bitrate (bits/second) from ExifTool AvgBitrate tag.
|
|
341
|
+
*
|
|
342
|
+
* exiftool-vendored returns AvgBitrate as either:
|
|
343
|
+
* - a number (raw bits/second)
|
|
344
|
+
* - a string like "5.00 Mbps" or "192 kbps" — parse the magnitude + unit
|
|
345
|
+
*
|
|
346
|
+
* Returns null when no usable bitrate is present.
|
|
347
|
+
*/
|
|
348
|
+
private extractBitrate;
|
|
349
|
+
/**
|
|
350
|
+
* Extract the four-digit year from tags, filename, path, or mtime.
|
|
351
|
+
*
|
|
352
|
+
* Priority:
|
|
353
|
+
* 1. EXIF/QuickTime date fields (DateTimeOriginal / CreateDate /
|
|
354
|
+
* MediaCreateDate / CreationDate — see CAPTURE_DATE_FIELDS)
|
|
355
|
+
* 2. Filename prefix YYYY- or YYYY_
|
|
356
|
+
* 3. Directory path component matching /^\d{4}$/
|
|
357
|
+
* 4. File mtime year
|
|
358
|
+
*/
|
|
359
|
+
private extractYear;
|
|
360
|
+
/**
|
|
361
|
+
* Load the persisted index from disk into memory.
|
|
362
|
+
*/
|
|
363
|
+
private loadIndex;
|
|
364
|
+
/**
|
|
365
|
+
* Tally every skip before the list is capped (#1056).
|
|
366
|
+
*
|
|
367
|
+
* Runs on the full list, never the truncated one — that ordering is the
|
|
368
|
+
* whole point. On the reference library the cap drops 93% of the entries,
|
|
369
|
+
* so counts derived after capping would understate `extension` by 13,714.
|
|
370
|
+
*/
|
|
371
|
+
private tallySkips;
|
|
372
|
+
/**
|
|
373
|
+
* Path of the skip report, beside the index file (#1056).
|
|
374
|
+
*
|
|
375
|
+
* Null when no `indexFile` is configured — an in-memory-only provider has
|
|
376
|
+
* nowhere to keep it, and the report must not silently outlive the index it
|
|
377
|
+
* describes.
|
|
378
|
+
*/
|
|
379
|
+
private get skipReportFile();
|
|
380
|
+
/**
|
|
381
|
+
* Persist the skip report for the scan that just finished (#1056).
|
|
382
|
+
*
|
|
383
|
+
* On disk rather than in memory because the question it answers — "where did
|
|
384
|
+
* my file go?" — is usually asked long after the scan, and often after a
|
|
385
|
+
* restart. An in-memory report reads as "no files were skipped" to anyone who
|
|
386
|
+
* did not personally trigger the last scan.
|
|
387
|
+
*
|
|
388
|
+
* Overwrites: it describes the CURRENT state of the library, so accumulating
|
|
389
|
+
* history would mean showing an operator files that a config change already
|
|
390
|
+
* un-skipped.
|
|
391
|
+
*/
|
|
392
|
+
private saveSkipReport;
|
|
393
|
+
/**
|
|
394
|
+
* The skip report from the most recent scan, or null if none has been
|
|
395
|
+
* written (fresh install, or no `indexFile` configured).
|
|
396
|
+
*/
|
|
397
|
+
getSkipReport(): Promise<MediaSkipReport | null>;
|
|
398
|
+
/**
|
|
399
|
+
* Save the in-memory index to disk.
|
|
400
|
+
*/
|
|
401
|
+
private saveIndex;
|
|
402
|
+
}
|
|
403
|
+
export default FileSystemMediaProvider;
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LunrSearchProvider - Full-text search provider using Lunr.js
|
|
3
|
+
*
|
|
4
|
+
* Provides client-side full-text search with stemming, stopwords, and field boosting.
|
|
5
|
+
* Suitable for small to medium-sized wikis (<10,000 pages).
|
|
6
|
+
*
|
|
7
|
+
* Configuration keys (all lowercase):
|
|
8
|
+
* - ngdpbase.search.provider.lunr.indexdir - Directory for persisted index
|
|
9
|
+
* - ngdpbase.search.provider.lunr.stemming - Enable/disable stemming
|
|
10
|
+
* - ngdpbase.search.provider.lunr.boost.title - Title field boost factor
|
|
11
|
+
* - ngdpbase.search.provider.lunr.boost.systemcategory - System category boost
|
|
12
|
+
* - ngdpbase.search.provider.lunr.boost.userkeywords - User keywords boost
|
|
13
|
+
* - ngdpbase.search.provider.lunr.boost.tags - Tags boost
|
|
14
|
+
* - ngdpbase.search.provider.lunr.maxresults - Maximum results to return
|
|
15
|
+
* - ngdpbase.search.provider.lunr.snippetlength - Snippet length in characters
|
|
16
|
+
* - ngdpbase.search.provider.lunr.flushinterval - Document persistence flush interval (ms)
|
|
17
|
+
*
|
|
18
|
+
* Related: GitHub Issue #102 - Configuration reorganization
|
|
19
|
+
* Related: GitHub Issue #267 - Incremental search index + document persistence
|
|
20
|
+
*/
|
|
21
|
+
import BaseSearchProvider, { SearchResult, SearchOptions, SearchCriteria, SearchStatistics, BackupData, WikiEngine } from './BaseSearchProvider.js';
|
|
22
|
+
/**
|
|
23
|
+
* Document structure for indexing
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Widen the last term of a query to a prefix match (#884).
|
|
27
|
+
*
|
|
28
|
+
* Lunr's `*` wildcard, applied only to the final term: someone mid-word wants
|
|
29
|
+
* completions, someone who submitted a finished query does not. Earlier terms
|
|
30
|
+
* are words the user has already finished typing and stay exact.
|
|
31
|
+
*
|
|
32
|
+
* Left alone when the last term already carries Lunr syntax — a wildcard, a
|
|
33
|
+
* field scope (`title:x`), or a presence operator (`+`/`-`). Appending `*` to
|
|
34
|
+
* those either duplicates an existing wildcard or corrupts the operator, and
|
|
35
|
+
* silently mangling a query the caller wrote deliberately is worse than not
|
|
36
|
+
* helping.
|
|
37
|
+
*
|
|
38
|
+
* @param query - Raw user query
|
|
39
|
+
* @returns The query with its last term widened, or unchanged
|
|
40
|
+
*/
|
|
41
|
+
export declare function applyPrefixToLastTerm(query: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Split URLs found in page content into searchable word tokens (#884).
|
|
44
|
+
*
|
|
45
|
+
* A URL indexed as one opaque string only ever matches if the reader types it
|
|
46
|
+
* in full. Splitting on the separators that carry no meaning — `[/:._\-?&=#]`
|
|
47
|
+
* — turns `https://en.wikipedia.org/wiki/Volcano` into `en wikipedia org wiki
|
|
48
|
+
* volcano`, so the domain and the path words each become findable terms.
|
|
49
|
+
*
|
|
50
|
+
* Deliberately conservative about what counts as a URL: only `http(s)://`
|
|
51
|
+
* matches. Bare domains would drag in ordinary prose containing dots, and
|
|
52
|
+
* abbreviations like "e.g." would tokenise into noise.
|
|
53
|
+
*
|
|
54
|
+
* Numeric-only and single-character fragments are dropped — port numbers, path
|
|
55
|
+
* ids and `v2`-style noise add index weight without ever being searched for.
|
|
56
|
+
*
|
|
57
|
+
* @param content - Page body
|
|
58
|
+
* @returns Space-joined tokens, or '' when the page links nowhere
|
|
59
|
+
*/
|
|
60
|
+
export declare function tokenizeUrls(content: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* LunrSearchProvider - Full-text search using Lunr.js
|
|
63
|
+
*/
|
|
64
|
+
declare class LunrSearchProvider extends BaseSearchProvider {
|
|
65
|
+
private searchIndex;
|
|
66
|
+
private persistTimer;
|
|
67
|
+
private documents;
|
|
68
|
+
private config;
|
|
69
|
+
private flushInterval;
|
|
70
|
+
private documentsPath;
|
|
71
|
+
constructor(engine: WikiEngine);
|
|
72
|
+
/**
|
|
73
|
+
* Initialize the Lunr search provider
|
|
74
|
+
* Loads configuration from ConfigurationManager
|
|
75
|
+
* @returns {Promise<void>}
|
|
76
|
+
*/
|
|
77
|
+
initialize(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Load persisted documents from disk
|
|
80
|
+
*/
|
|
81
|
+
private loadPersistedDocuments;
|
|
82
|
+
/**
|
|
83
|
+
* Is this document a private page's (#1458)? Either its name is a private
|
|
84
|
+
* path (#1456) or the document itself says so — a document written before
|
|
85
|
+
* private pages left the shared indexes has the flag and an ordinary title.
|
|
86
|
+
*/
|
|
87
|
+
private static isPrivateDocument;
|
|
88
|
+
/**
|
|
89
|
+
* The documents that may be written to a shared place — `documents.json`
|
|
90
|
+
* and the backup that carries it off this host (#1458).
|
|
91
|
+
*
|
|
92
|
+
* Private page text sat in both in plaintext before #1456. This is the one
|
|
93
|
+
* rule that keeps it out, whatever put it in the map: a private page's text
|
|
94
|
+
* lives in its own store's search index and nowhere else.
|
|
95
|
+
*/
|
|
96
|
+
private sharedDocuments;
|
|
97
|
+
/**
|
|
98
|
+
* Persist documents to disk — the shared ones only (#1458).
|
|
99
|
+
*/
|
|
100
|
+
private persistDocuments;
|
|
101
|
+
/**
|
|
102
|
+
* A term as both the index and a query read it: lower-cased, stop words
|
|
103
|
+
* dropped, and stemmed with Lunr's English stemmer when stemming is on, so a
|
|
104
|
+
* word matches what it matched under Lunr (#1736).
|
|
105
|
+
*/
|
|
106
|
+
private processTerm;
|
|
107
|
+
/**
|
|
108
|
+
* Build the index from the in-memory documents: at start-up and after a
|
|
109
|
+
* restore. A save changes one document (`updatePageInIndex`), never this.
|
|
110
|
+
*/
|
|
111
|
+
private rebuildSearchIndexFromDocuments;
|
|
112
|
+
/** The configured field boosts, for every search. Content is the 1.0 baseline. */
|
|
113
|
+
private fieldBoosts;
|
|
114
|
+
/**
|
|
115
|
+
* Write `documents.json` shortly after the last change rather than on every
|
|
116
|
+
* save (#1736). The interval flush and `close()` still write it.
|
|
117
|
+
*/
|
|
118
|
+
private schedulePersist;
|
|
119
|
+
/**
|
|
120
|
+
* Convert page data from WikiRoutes into a LunrDocument
|
|
121
|
+
*/
|
|
122
|
+
private buildDocumentFromPageData;
|
|
123
|
+
/**
|
|
124
|
+
* Get provider information
|
|
125
|
+
* @returns {Object} Provider metadata
|
|
126
|
+
*/
|
|
127
|
+
getProviderInfo(): {
|
|
128
|
+
name: string;
|
|
129
|
+
version: string;
|
|
130
|
+
description: string;
|
|
131
|
+
features: string[];
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Build search index from all pages
|
|
135
|
+
* @returns {Promise<void>}
|
|
136
|
+
*/
|
|
137
|
+
buildIndex(): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Search for pages matching the query
|
|
140
|
+
* @param {string} query - Search query
|
|
141
|
+
* @param {SearchOptions} options - Search options
|
|
142
|
+
* @returns {Promise<SearchResult[]>} Search results
|
|
143
|
+
*/
|
|
144
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Private-page visibility (#731/#716, #1382). Used by both the text path in
|
|
147
|
+
* search() and the no-text advancedSearch branch. A private page lives in its
|
|
148
|
+
* owner's private container: it is found only by its owner — no role, and no
|
|
149
|
+
* frontmatter audience, reaches in (docs/private-stores.md, Access;
|
|
150
|
+
* the same rule PolicyInformationPoint applies at Tier 0).
|
|
151
|
+
*/
|
|
152
|
+
private isDocVisible;
|
|
153
|
+
/**
|
|
154
|
+
* Advanced search with multiple criteria
|
|
155
|
+
* @param {SearchCriteria} options - Search criteria
|
|
156
|
+
* @returns {Promise<SearchResult[]>} Search results
|
|
157
|
+
*/
|
|
158
|
+
advancedSearch(options?: SearchCriteria): Promise<SearchResult[]>;
|
|
159
|
+
/**
|
|
160
|
+
* Generate a snippet with highlighted search terms
|
|
161
|
+
* @param {string} content - Full content
|
|
162
|
+
* @param {string} query - Search query
|
|
163
|
+
* @returns {string} Content snippet
|
|
164
|
+
*/
|
|
165
|
+
private generateSnippet;
|
|
166
|
+
/**
|
|
167
|
+
* Get search suggestions for autocomplete
|
|
168
|
+
* @param {string} partial - Partial search term
|
|
169
|
+
* @returns {Promise<string[]>} Suggested completions
|
|
170
|
+
*/
|
|
171
|
+
getSuggestions(partial: string): Promise<string[]>;
|
|
172
|
+
/**
|
|
173
|
+
* Suggest similar pages based on content
|
|
174
|
+
* @param {string} pageName - Source page name
|
|
175
|
+
* @param {number} limit - Maximum suggestions
|
|
176
|
+
* @returns {Promise<SearchResult[]>} Suggested pages
|
|
177
|
+
*/
|
|
178
|
+
suggestSimilarPages(pageName: string, limit?: number): Promise<SearchResult[]>;
|
|
179
|
+
/**
|
|
180
|
+
* Add or update a page in the search index incrementally
|
|
181
|
+
* @param {string} pageName - Page name
|
|
182
|
+
* @param {Record<string, unknown>} pageData - Page data
|
|
183
|
+
* @returns {Promise<void>}
|
|
184
|
+
*/
|
|
185
|
+
updatePageInIndex(pageName: string, pageData: Record<string, unknown>): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Remove a page from the search index
|
|
188
|
+
* @param {string} pageName - Page name to remove
|
|
189
|
+
* @returns {Promise<void>}
|
|
190
|
+
*/
|
|
191
|
+
removePageFromIndex(pageName: string): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* True rebuild from disk — mirrors MediaManager.rebuildIndex().
|
|
194
|
+
*
|
|
195
|
+
* #724: buildIndex() has a fast path that, when this.documents is
|
|
196
|
+
* non-empty (always, in steady state), rebuilds Lunr from the persisted
|
|
197
|
+
* map WITHOUT re-reading pages from disk. That makes a deleted page's
|
|
198
|
+
* index entry ("ghost") unkillable — a normal reindex can never drop it.
|
|
199
|
+
* rebuild() is the missing "Rebuild" half (vs the "Reindex"/rescan that
|
|
200
|
+
* buildIndex provides): it clears the in-memory map AND deletes the
|
|
201
|
+
* persisted documents.json, then forces the cold disk-scan path. Pages
|
|
202
|
+
* that no longer exist on disk are dropped by construction.
|
|
203
|
+
*
|
|
204
|
+
* documents.json is a derived cache (regenerated here from PageManager),
|
|
205
|
+
* never source data — deleting it is safe and not the data/-tree rule.
|
|
206
|
+
*/
|
|
207
|
+
rebuild(): Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* Get all unique categories from indexed documents
|
|
210
|
+
* @returns {Promise<string[]>} List of categories
|
|
211
|
+
*/
|
|
212
|
+
getAllCategories(): Promise<string[]>;
|
|
213
|
+
/**
|
|
214
|
+
* Split a document's `userKeywords` string back into keywords.
|
|
215
|
+
*
|
|
216
|
+
* #862: `buildDocumentFromPageData` joins user-keywords with commas (the
|
|
217
|
+
* only safe separator — keywords may contain spaces, e.g. "grow system").
|
|
218
|
+
* Every consumer must split on commas too; the previous whitespace splits
|
|
219
|
+
* meant a page with more than one keyword NEVER matched
|
|
220
|
+
* `searchByUserKeywords`, and multi-word keywords shattered into words.
|
|
221
|
+
*/
|
|
222
|
+
private splitUserKeywords;
|
|
223
|
+
/**
|
|
224
|
+
* Get all unique user keywords from indexed documents
|
|
225
|
+
* @returns {Promise<string[]>} List of user keywords
|
|
226
|
+
*/
|
|
227
|
+
getAllUserKeywords(): Promise<string[]>;
|
|
228
|
+
/**
|
|
229
|
+
* #893: all unique system keywords (machine bucket) from indexed documents.
|
|
230
|
+
* Mirrors getAllUserKeywords — same comma-join contract (#862). Previously
|
|
231
|
+
* ES-only; needed on Lunr so the asset-picker system-keywords facet includes
|
|
232
|
+
* index-derived terms like 'capture'.
|
|
233
|
+
*/
|
|
234
|
+
getAllSystemKeywords(): Promise<string[]>;
|
|
235
|
+
/**
|
|
236
|
+
* Search by category only
|
|
237
|
+
* @param {string} category - Category to search for
|
|
238
|
+
* @returns {Promise<SearchResult[]>} Pages in category
|
|
239
|
+
*/
|
|
240
|
+
getAllDocuments(): Promise<SearchResult[]>;
|
|
241
|
+
searchByCategory(category: string): Promise<SearchResult[]>;
|
|
242
|
+
/**
|
|
243
|
+
* Search by user keywords only
|
|
244
|
+
* @param {string} keyword - Keyword to search for
|
|
245
|
+
* @returns {Promise<SearchResult[]>} Pages with keyword
|
|
246
|
+
*/
|
|
247
|
+
searchByUserKeywords(keyword: string): Promise<SearchResult[]>;
|
|
248
|
+
/**
|
|
249
|
+
* Get search statistics
|
|
250
|
+
* @returns {Promise<SearchStatistics>} Search statistics
|
|
251
|
+
*/
|
|
252
|
+
getStatistics(): Promise<SearchStatistics>;
|
|
253
|
+
/**
|
|
254
|
+
* Get the total number of indexed documents
|
|
255
|
+
* @returns {Promise<number>} Number of documents
|
|
256
|
+
*/
|
|
257
|
+
getDocumentCount(): Promise<number>;
|
|
258
|
+
/**
|
|
259
|
+
* Check if the search provider is healthy/functional
|
|
260
|
+
* @returns {Promise<boolean>} True if healthy
|
|
261
|
+
*/
|
|
262
|
+
isHealthy(): Promise<boolean>;
|
|
263
|
+
/**
|
|
264
|
+
* Close/cleanup the search provider, flushing documents to disk
|
|
265
|
+
* @returns {Promise<void>}
|
|
266
|
+
*/
|
|
267
|
+
close(): Promise<void>;
|
|
268
|
+
/**
|
|
269
|
+
* Backup search index and configuration
|
|
270
|
+
* @returns {Promise<BackupData>} Backup data
|
|
271
|
+
*/
|
|
272
|
+
backup(): Promise<BackupData>;
|
|
273
|
+
/**
|
|
274
|
+
* Restore search index from backup
|
|
275
|
+
* @param {BackupData} backupData - Backup data
|
|
276
|
+
* @returns {Promise<void>}
|
|
277
|
+
*/
|
|
278
|
+
restore(backupData: BackupData): Promise<void>;
|
|
279
|
+
}
|
|
280
|
+
export default LunrSearchProvider;
|