@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,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff operation tuple: [operation, text]
|
|
3
|
+
* operation: -1 (delete), 0 (equal), 1 (insert)
|
|
4
|
+
*/
|
|
5
|
+
export type DiffTuple = [number, string];
|
|
6
|
+
/**
|
|
7
|
+
* Diff statistics
|
|
8
|
+
*/
|
|
9
|
+
export interface DiffStats {
|
|
10
|
+
additions: number;
|
|
11
|
+
deletions: number;
|
|
12
|
+
unchanged: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* DeltaStorage - Utility for creating and applying content diffs
|
|
16
|
+
*
|
|
17
|
+
* Uses the fast-diff library (Myers diff algorithm) to efficiently store
|
|
18
|
+
* page versions as deltas. Version 1 stores full content, subsequent versions
|
|
19
|
+
* store only the differences from the previous version.
|
|
20
|
+
*
|
|
21
|
+
* fast-diff returns an array of tuples: [operation, text]
|
|
22
|
+
* - operation: -1 (delete), 0 (equal), 1 (insert)
|
|
23
|
+
* - text: the text content
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const diff = DeltaStorage.createDiff("Hello world", "Hello ngdpbase");
|
|
27
|
+
* // Returns: [[0, "Hello "], [-1, "world"], [1, "ngdpbase"]]
|
|
28
|
+
*
|
|
29
|
+
* const reconstructed = DeltaStorage.applyDiff("Hello world", diff);
|
|
30
|
+
* // Returns: "Hello ngdpbase"
|
|
31
|
+
*/
|
|
32
|
+
export default class DeltaStorage {
|
|
33
|
+
/**
|
|
34
|
+
* Generate diff between old and new content
|
|
35
|
+
*
|
|
36
|
+
* Creates a diff using the Myers algorithm (similar to git).
|
|
37
|
+
* Returns an array of operations that transform oldContent into newContent.
|
|
38
|
+
*
|
|
39
|
+
* @param oldContent - Original content
|
|
40
|
+
* @param newContent - New content
|
|
41
|
+
* @returns Diff array from fast-diff
|
|
42
|
+
* @example
|
|
43
|
+
* const diff = DeltaStorage.createDiff("foo", "bar");
|
|
44
|
+
* // Returns: [[-1, "foo"], [1, "bar"]]
|
|
45
|
+
*/
|
|
46
|
+
static createDiff(oldContent: string, newContent: string): DiffTuple[];
|
|
47
|
+
/**
|
|
48
|
+
* Apply a diff to base content to reconstruct a version
|
|
49
|
+
*
|
|
50
|
+
* Takes the base content and applies a diff array to reconstruct the target content.
|
|
51
|
+
* Used to reconstruct versions from delta storage.
|
|
52
|
+
*
|
|
53
|
+
* @param baseContent - Base content to apply diff to
|
|
54
|
+
* @param diff - Diff array from fast-diff
|
|
55
|
+
* @returns Reconstructed content
|
|
56
|
+
* @throws {TypeError} If inputs are invalid
|
|
57
|
+
* @example
|
|
58
|
+
* const base = "Hello world";
|
|
59
|
+
* const diff: DiffTuple[] = [[0, "Hello "], [-1, "world"], [1, "ngdpbase"]];
|
|
60
|
+
* const result = DeltaStorage.applyDiff(base, diff);
|
|
61
|
+
* // Returns: "Hello ngdpbase"
|
|
62
|
+
*/
|
|
63
|
+
static applyDiff(baseContent: string, diff: DiffTuple[]): string;
|
|
64
|
+
/**
|
|
65
|
+
* Apply multiple diffs sequentially
|
|
66
|
+
*
|
|
67
|
+
* Applies a chain of diffs to reconstruct a version from v1.
|
|
68
|
+
* Used when retrieving versions > 2 in delta storage.
|
|
69
|
+
*
|
|
70
|
+
* @param v1Content - Version 1 (base) content
|
|
71
|
+
* @param diffArray - Array of diffs to apply sequentially
|
|
72
|
+
* @returns Final reconstructed content
|
|
73
|
+
* @throws {Error} If any diff application fails
|
|
74
|
+
* @example
|
|
75
|
+
* const v1 = "Version 1";
|
|
76
|
+
* const diffs: DiffTuple[][] = [
|
|
77
|
+
* [[0, "Version "], [-1, "1"], [1, "2"]], // v1 → v2
|
|
78
|
+
* [[0, "Version "], [-1, "2"], [1, "3"]] // v2 → v3
|
|
79
|
+
* ];
|
|
80
|
+
* const v3 = DeltaStorage.applyDiffChain(v1, diffs);
|
|
81
|
+
* // Returns: "Version 3"
|
|
82
|
+
*/
|
|
83
|
+
static applyDiffChain(v1Content: string, diffArray: DiffTuple[][]): string;
|
|
84
|
+
/**
|
|
85
|
+
* Calculate SHA-256 hash of content
|
|
86
|
+
*
|
|
87
|
+
* Used for content integrity verification and deduplication.
|
|
88
|
+
* Stored in version metadata for verification.
|
|
89
|
+
*
|
|
90
|
+
* @param content - Content to hash
|
|
91
|
+
* @returns SHA-256 hash in hexadecimal format
|
|
92
|
+
*/
|
|
93
|
+
static calculateHash(content: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Verify content integrity using hash
|
|
96
|
+
*
|
|
97
|
+
* Checks if the content hash matches the expected hash.
|
|
98
|
+
* Used to detect corruption in version storage.
|
|
99
|
+
*
|
|
100
|
+
* @param content - Content to verify
|
|
101
|
+
* @param expectedHash - Expected SHA-256 hash
|
|
102
|
+
* @returns True if hash matches, false otherwise
|
|
103
|
+
*/
|
|
104
|
+
static verifyHash(content: string, expectedHash: string): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Calculate diff statistics
|
|
107
|
+
*
|
|
108
|
+
* Analyzes a diff to provide statistics about the changes.
|
|
109
|
+
* Useful for UI display and analytics.
|
|
110
|
+
*
|
|
111
|
+
* @param diff - Diff array from fast-diff
|
|
112
|
+
* @returns Statistics object
|
|
113
|
+
* @example
|
|
114
|
+
* const stats = DeltaStorage.getDiffStats(diff);
|
|
115
|
+
* // Returns: { additions: 10, deletions: 5, unchanged: 100 }
|
|
116
|
+
*/
|
|
117
|
+
static getDiffStats(diff: DiffTuple[]): DiffStats;
|
|
118
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LocaleUtils - Utility functions for handling browser locale and internationalization
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Date format option for user preferences
|
|
6
|
+
*/
|
|
7
|
+
interface DateFormatOption {
|
|
8
|
+
value: string;
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Supported locale information
|
|
14
|
+
*/
|
|
15
|
+
interface SupportedLocale {
|
|
16
|
+
code: string;
|
|
17
|
+
name: string;
|
|
18
|
+
dateFormat: string;
|
|
19
|
+
timeFormat: '12h' | '24h';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Locale utilities for handling browser locale and internationalization
|
|
23
|
+
*/
|
|
24
|
+
declare class LocaleUtils {
|
|
25
|
+
/**
|
|
26
|
+
* Parse Accept-Language header to get preferred locale
|
|
27
|
+
* @param acceptLanguage - Accept-Language header value
|
|
28
|
+
* @returns Best matching locale (e.g., 'en-US', 'fr-FR', 'de-DE')
|
|
29
|
+
*/
|
|
30
|
+
static parseAcceptLanguage(acceptLanguage: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Normalize locale string to standard format
|
|
33
|
+
* @param locale - Raw locale string
|
|
34
|
+
* @returns Normalized locale (e.g., 'en-US', 'fr-FR')
|
|
35
|
+
*/
|
|
36
|
+
static normalizeLocale(locale: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Get date format pattern based on locale
|
|
39
|
+
* @param locale - Locale string (e.g., 'en-US')
|
|
40
|
+
* @returns Date format pattern for user preferences
|
|
41
|
+
*/
|
|
42
|
+
static getDateFormatFromLocale(locale: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Get time format preference based on locale
|
|
45
|
+
* @param locale - Locale string (e.g., 'en-US')
|
|
46
|
+
* @returns Time format preference ('12h' or '24h')
|
|
47
|
+
*/
|
|
48
|
+
static getTimeFormatFromLocale(locale: string): '12h' | '24h';
|
|
49
|
+
/**
|
|
50
|
+
* Format date using specified locale
|
|
51
|
+
* @param date - Date to format
|
|
52
|
+
* @param locale - Locale string
|
|
53
|
+
* @returns Formatted date string
|
|
54
|
+
*/
|
|
55
|
+
static formatDate(date: Date, locale?: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Format date using an explicit pattern string (e.g. 'yyyy-MM-dd').
|
|
58
|
+
* Supports the subset of patterns offered in the profile date-format picker.
|
|
59
|
+
* @param date - Date to format
|
|
60
|
+
* @param pattern - Format pattern ('yyyy-MM-dd', 'MM/dd/yyyy', 'dd/MM/yyyy', 'dd.MM.yyyy', 'yyyy/MM/dd')
|
|
61
|
+
* @param timezone - Optional IANA timezone (e.g. 'America/New_York', 'UTC')
|
|
62
|
+
* @returns Formatted date string
|
|
63
|
+
*/
|
|
64
|
+
static formatDateWithPattern(date: Date, pattern: string, timezone?: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Format time honoring an explicit 12h/24h preference and optional timezone.
|
|
67
|
+
* @param date - Date to format
|
|
68
|
+
* @param timeFormat - '12h' or '24h'
|
|
69
|
+
* @param locale - Locale string (used for AM/PM labels in 12h mode)
|
|
70
|
+
* @param timezone - Optional IANA timezone
|
|
71
|
+
* @returns Formatted time string
|
|
72
|
+
*/
|
|
73
|
+
static formatTimeWithPrefs(date: Date, timeFormat: string, locale?: string, timezone?: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Format time using specified locale
|
|
76
|
+
* @param date - Date to format
|
|
77
|
+
* @param locale - Locale string
|
|
78
|
+
* @returns Formatted time string
|
|
79
|
+
*/
|
|
80
|
+
static formatTime(date: Date, locale?: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Get available date format options
|
|
83
|
+
* @returns Array of date format options
|
|
84
|
+
*/
|
|
85
|
+
static getDateFormatOptions(): DateFormatOption[];
|
|
86
|
+
/**
|
|
87
|
+
* Get supported locales list
|
|
88
|
+
* @returns Array of supported locale objects
|
|
89
|
+
*/
|
|
90
|
+
static getSupportedLocales(): SupportedLocale[];
|
|
91
|
+
/**
|
|
92
|
+
* Validate timezone string
|
|
93
|
+
* @param timezone - Timezone to validate
|
|
94
|
+
* @returns True if timezone is valid
|
|
95
|
+
*/
|
|
96
|
+
static isValidTimezone(timezone: string): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Get timezone display name
|
|
99
|
+
* @param timezone - Timezone identifier (e.g., 'America/New_York')
|
|
100
|
+
* @param locale - Locale for display name (default: 'en-US')
|
|
101
|
+
* @returns Human-readable timezone name
|
|
102
|
+
*/
|
|
103
|
+
static getTimezoneDisplayName(timezone: string, locale?: string): string;
|
|
104
|
+
}
|
|
105
|
+
export default LocaleUtils;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LocaleUtils - Utility functions for handling browser locale and internationalization
|
|
3
|
+
*/
|
|
4
|
+
import logger from './logger.js';
|
|
5
|
+
/**
|
|
6
|
+
* Locale utilities for handling browser locale and internationalization
|
|
7
|
+
*/
|
|
8
|
+
class LocaleUtils {
|
|
9
|
+
/**
|
|
10
|
+
* Parse Accept-Language header to get preferred locale
|
|
11
|
+
* @param acceptLanguage - Accept-Language header value
|
|
12
|
+
* @returns Best matching locale (e.g., 'en-US', 'fr-FR', 'de-DE')
|
|
13
|
+
*/
|
|
14
|
+
static parseAcceptLanguage(acceptLanguage) {
|
|
15
|
+
if (!acceptLanguage || typeof acceptLanguage !== 'string') {
|
|
16
|
+
return 'en-US'; // Default fallback
|
|
17
|
+
}
|
|
18
|
+
// Parse Accept-Language header format: "en-US,en;q=0.9,fr;q=0.8"
|
|
19
|
+
const languages = acceptLanguage
|
|
20
|
+
.split(',')
|
|
21
|
+
.map(lang => {
|
|
22
|
+
const parts = lang.trim().split(';');
|
|
23
|
+
const locale = parts[0].trim();
|
|
24
|
+
const quality = parts[1] ? parseFloat(parts[1].split('=')[1]) : 1.0;
|
|
25
|
+
return { locale, quality };
|
|
26
|
+
})
|
|
27
|
+
.sort((a, b) => b.quality - a.quality); // Sort by quality score (highest first)
|
|
28
|
+
// Return the highest quality locale
|
|
29
|
+
const preferred = languages[0]?.locale || 'en-US';
|
|
30
|
+
// Normalize common locale formats
|
|
31
|
+
return this.normalizeLocale(preferred);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Normalize locale string to standard format
|
|
35
|
+
* @param locale - Raw locale string
|
|
36
|
+
* @returns Normalized locale (e.g., 'en-US', 'fr-FR')
|
|
37
|
+
*/
|
|
38
|
+
static normalizeLocale(locale) {
|
|
39
|
+
if (!locale)
|
|
40
|
+
return 'en-US';
|
|
41
|
+
// Handle common formats
|
|
42
|
+
const normalized = locale.toLowerCase().replace('_', '-');
|
|
43
|
+
// Map common language codes to full locales
|
|
44
|
+
const localeMap = {
|
|
45
|
+
'en': 'en-US',
|
|
46
|
+
'fr': 'fr-FR',
|
|
47
|
+
'de': 'de-DE',
|
|
48
|
+
'es': 'es-ES',
|
|
49
|
+
'it': 'it-IT',
|
|
50
|
+
'pt': 'pt-BR',
|
|
51
|
+
'ja': 'ja-JP',
|
|
52
|
+
'ko': 'ko-KR',
|
|
53
|
+
'zh': 'zh-CN',
|
|
54
|
+
'ru': 'ru-RU',
|
|
55
|
+
'ar': 'ar-SA',
|
|
56
|
+
'hi': 'hi-IN'
|
|
57
|
+
};
|
|
58
|
+
// If it's just a language code, expand it
|
|
59
|
+
if (localeMap[normalized]) {
|
|
60
|
+
return localeMap[normalized];
|
|
61
|
+
}
|
|
62
|
+
// If it's already in lang-country format, capitalize country
|
|
63
|
+
const parts = normalized.split('-');
|
|
64
|
+
if (parts.length === 2) {
|
|
65
|
+
return `${parts[0]}-${parts[1].toUpperCase()}`;
|
|
66
|
+
}
|
|
67
|
+
return normalized || 'en-US';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get date format pattern based on locale
|
|
71
|
+
* @param locale - Locale string (e.g., 'en-US')
|
|
72
|
+
* @returns Date format pattern for user preferences
|
|
73
|
+
*/
|
|
74
|
+
static getDateFormatFromLocale(locale) {
|
|
75
|
+
const normalizedLocale = this.normalizeLocale(locale);
|
|
76
|
+
// Map locales to common date format preferences
|
|
77
|
+
const dateFormatMap = {
|
|
78
|
+
'en-US': 'MM/dd/yyyy', // American: 12/25/2023
|
|
79
|
+
'en-GB': 'dd/MM/yyyy', // British: 25/12/2023
|
|
80
|
+
'en-CA': 'dd/MM/yyyy', // Canadian: 25/12/2023
|
|
81
|
+
'fr-FR': 'dd/MM/yyyy', // French: 25/12/2023
|
|
82
|
+
'de-DE': 'dd.MM.yyyy', // German: 25.12.2023
|
|
83
|
+
'es-ES': 'dd/MM/yyyy', // Spanish: 25/12/2023
|
|
84
|
+
'it-IT': 'dd/MM/yyyy', // Italian: 25/12/2023
|
|
85
|
+
'pt-BR': 'dd/MM/yyyy', // Brazilian Portuguese: 25/12/2023
|
|
86
|
+
'ja-JP': 'yyyy/MM/dd', // Japanese: 2023/12/25
|
|
87
|
+
'ko-KR': 'yyyy. MM. dd.', // Korean: 2023. 12. 25.
|
|
88
|
+
'zh-CN': 'yyyy/MM/dd', // Chinese: 2023/12/25
|
|
89
|
+
'ru-RU': 'dd.MM.yyyy', // Russian: 25.12.2023
|
|
90
|
+
'ar-SA': 'dd/MM/yyyy', // Arabic: 25/12/2023
|
|
91
|
+
'hi-IN': 'dd/MM/yyyy' // Hindi: 25/12/2023
|
|
92
|
+
};
|
|
93
|
+
return dateFormatMap[normalizedLocale] || dateFormatMap['en-US'];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get time format preference based on locale
|
|
97
|
+
* @param locale - Locale string (e.g., 'en-US')
|
|
98
|
+
* @returns Time format preference ('12h' or '24h')
|
|
99
|
+
*/
|
|
100
|
+
static getTimeFormatFromLocale(locale) {
|
|
101
|
+
const normalizedLocale = this.normalizeLocale(locale);
|
|
102
|
+
// Most of the world uses 24-hour format, but some countries prefer 12-hour
|
|
103
|
+
const twelveHourLocales = [
|
|
104
|
+
'en-US', // United States
|
|
105
|
+
'en-CA', // Canada (mixed, but 12h common)
|
|
106
|
+
'en-AU', // Australia (mixed)
|
|
107
|
+
'en-NZ', // New Zealand (mixed)
|
|
108
|
+
'en-PH' // Philippines
|
|
109
|
+
];
|
|
110
|
+
return twelveHourLocales.includes(normalizedLocale) ? '12h' : '24h';
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format date using specified locale
|
|
114
|
+
* @param date - Date to format
|
|
115
|
+
* @param locale - Locale string
|
|
116
|
+
* @returns Formatted date string
|
|
117
|
+
*/
|
|
118
|
+
static formatDate(date, locale = 'en-US') {
|
|
119
|
+
if (!date || !(date instanceof Date)) {
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
122
|
+
const normalizedLocale = this.normalizeLocale(locale);
|
|
123
|
+
try {
|
|
124
|
+
return date.toLocaleDateString(normalizedLocale);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
logger.warn(`Invalid locale '${normalizedLocale}', falling back to en-US`);
|
|
128
|
+
return date.toLocaleDateString('en-US');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Format date using an explicit pattern string (e.g. 'yyyy-MM-dd').
|
|
133
|
+
* Supports the subset of patterns offered in the profile date-format picker.
|
|
134
|
+
* @param date - Date to format
|
|
135
|
+
* @param pattern - Format pattern ('yyyy-MM-dd', 'MM/dd/yyyy', 'dd/MM/yyyy', 'dd.MM.yyyy', 'yyyy/MM/dd')
|
|
136
|
+
* @param timezone - Optional IANA timezone (e.g. 'America/New_York', 'UTC')
|
|
137
|
+
* @returns Formatted date string
|
|
138
|
+
*/
|
|
139
|
+
static formatDateWithPattern(date, pattern, timezone) {
|
|
140
|
+
if (!date || !(date instanceof Date))
|
|
141
|
+
return '';
|
|
142
|
+
// Include time parts when the pattern contains time tokens (HH, mm, ss)
|
|
143
|
+
const needsTime = /HH|mm|ss/.test(pattern);
|
|
144
|
+
const opts = { year: 'numeric', month: '2-digit', day: '2-digit' };
|
|
145
|
+
if (needsTime) {
|
|
146
|
+
opts.hour = '2-digit';
|
|
147
|
+
opts.minute = '2-digit';
|
|
148
|
+
opts.second = '2-digit';
|
|
149
|
+
opts.hour12 = false;
|
|
150
|
+
}
|
|
151
|
+
if (timezone && this.isValidTimezone(timezone))
|
|
152
|
+
opts.timeZone = timezone;
|
|
153
|
+
try {
|
|
154
|
+
const parts = {};
|
|
155
|
+
for (const part of new Intl.DateTimeFormat('en-US', opts).formatToParts(date)) {
|
|
156
|
+
parts[part.type] = part.value;
|
|
157
|
+
}
|
|
158
|
+
// Intl returns hour as '00'-'23' but may use '24' for midnight in some locales;
|
|
159
|
+
// normalise to two-digit zero-padded.
|
|
160
|
+
const hour = (parts.hour ?? '00').padStart(2, '0');
|
|
161
|
+
const minute = (parts.minute ?? '00').padStart(2, '0');
|
|
162
|
+
const second = (parts.second ?? '00').padStart(2, '0');
|
|
163
|
+
return pattern
|
|
164
|
+
.replace('yyyy', parts.year ?? '')
|
|
165
|
+
.replace('MM', parts.month ?? '')
|
|
166
|
+
.replace('dd', parts.day ?? '')
|
|
167
|
+
.replace('HH', hour)
|
|
168
|
+
.replace('mm', minute)
|
|
169
|
+
.replace('ss', second);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return date.toLocaleDateString('en-US');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Format time honoring an explicit 12h/24h preference and optional timezone.
|
|
177
|
+
* @param date - Date to format
|
|
178
|
+
* @param timeFormat - '12h' or '24h'
|
|
179
|
+
* @param locale - Locale string (used for AM/PM labels in 12h mode)
|
|
180
|
+
* @param timezone - Optional IANA timezone
|
|
181
|
+
* @returns Formatted time string
|
|
182
|
+
*/
|
|
183
|
+
static formatTimeWithPrefs(date, timeFormat, locale = 'en-US', timezone) {
|
|
184
|
+
if (!date || !(date instanceof Date))
|
|
185
|
+
return '';
|
|
186
|
+
const hour12 = timeFormat === '12h';
|
|
187
|
+
const opts = {
|
|
188
|
+
hour: hour12 ? 'numeric' : '2-digit',
|
|
189
|
+
minute: '2-digit',
|
|
190
|
+
second: '2-digit',
|
|
191
|
+
hour12
|
|
192
|
+
};
|
|
193
|
+
if (timezone && this.isValidTimezone(timezone))
|
|
194
|
+
opts.timeZone = timezone;
|
|
195
|
+
const normalizedLocale = this.normalizeLocale(locale);
|
|
196
|
+
try {
|
|
197
|
+
return date.toLocaleTimeString(normalizedLocale, opts);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return date.toLocaleTimeString('en-US', opts);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Format time using specified locale
|
|
205
|
+
* @param date - Date to format
|
|
206
|
+
* @param locale - Locale string
|
|
207
|
+
* @returns Formatted time string
|
|
208
|
+
*/
|
|
209
|
+
static formatTime(date, locale = 'en-US') {
|
|
210
|
+
if (!date || !(date instanceof Date)) {
|
|
211
|
+
return '';
|
|
212
|
+
}
|
|
213
|
+
const normalizedLocale = this.normalizeLocale(locale);
|
|
214
|
+
try {
|
|
215
|
+
return date.toLocaleTimeString(normalizedLocale);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
logger.warn(`Invalid locale '${normalizedLocale}', falling back to en-US`);
|
|
219
|
+
return date.toLocaleTimeString('en-US');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get available date format options
|
|
224
|
+
* @returns Array of date format options
|
|
225
|
+
*/
|
|
226
|
+
static getDateFormatOptions() {
|
|
227
|
+
return [
|
|
228
|
+
{ value: 'auto', label: 'Auto (from locale)', description: 'Use locale-specific format' },
|
|
229
|
+
{ value: 'MM/dd/yyyy', label: 'MM/dd/yyyy', description: '12/25/2023 (US format)' },
|
|
230
|
+
{ value: 'dd/MM/yyyy', label: 'dd/MM/yyyy', description: '25/12/2023 (European format)' },
|
|
231
|
+
{ value: 'dd.MM.yyyy', label: 'dd.MM.yyyy', description: '25.12.2023 (German format)' },
|
|
232
|
+
{ value: 'yyyy/MM/dd', label: 'yyyy/MM/dd', description: '2023/12/25 (ISO-style)' },
|
|
233
|
+
{ value: 'yyyy-MM-dd', label: 'yyyy-MM-dd', description: '2023-12-25 (ISO date)' },
|
|
234
|
+
{ value: 'yyyy-MM-dd HH:mm', label: 'yyyy-MM-dd HH:mm', description: '2023-12-25 14:30 (ISO datetime)' }
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get supported locales list
|
|
239
|
+
* @returns Array of supported locale objects
|
|
240
|
+
*/
|
|
241
|
+
static getSupportedLocales() {
|
|
242
|
+
return [
|
|
243
|
+
{ code: 'en-US', name: 'English (United States)', dateFormat: 'MM/dd/yyyy', timeFormat: '12h' },
|
|
244
|
+
{ code: 'en-GB', name: 'English (United Kingdom)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' },
|
|
245
|
+
{ code: 'fr-FR', name: 'Français (France)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' },
|
|
246
|
+
{ code: 'de-DE', name: 'Deutsch (Deutschland)', dateFormat: 'dd.MM.yyyy', timeFormat: '24h' },
|
|
247
|
+
{ code: 'es-ES', name: 'Español (España)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' },
|
|
248
|
+
{ code: 'it-IT', name: 'Italiano (Italia)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' },
|
|
249
|
+
{ code: 'pt-BR', name: 'Português (Brasil)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' },
|
|
250
|
+
{ code: 'ja-JP', name: '日本語 (日本)', dateFormat: 'yyyy/MM/dd', timeFormat: '24h' },
|
|
251
|
+
{ code: 'ko-KR', name: '한국어 (대한민국)', dateFormat: 'yyyy. MM. dd.', timeFormat: '24h' },
|
|
252
|
+
{ code: 'zh-CN', name: '中文 (中国)', dateFormat: 'yyyy/MM/dd', timeFormat: '24h' },
|
|
253
|
+
{ code: 'ru-RU', name: 'Русский (Россия)', dateFormat: 'dd.MM.yyyy', timeFormat: '24h' },
|
|
254
|
+
{ code: 'ar-SA', name: 'العربية (السعودية)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' },
|
|
255
|
+
{ code: 'hi-IN', name: 'हिन्दी (भारत)', dateFormat: 'dd/MM/yyyy', timeFormat: '24h' }
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Validate timezone string
|
|
260
|
+
* @param timezone - Timezone to validate
|
|
261
|
+
* @returns True if timezone is valid
|
|
262
|
+
*/
|
|
263
|
+
static isValidTimezone(timezone) {
|
|
264
|
+
try {
|
|
265
|
+
// Test if timezone is supported by Intl.DateTimeFormat
|
|
266
|
+
new Intl.DateTimeFormat('en-US', { timeZone: timezone });
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get timezone display name
|
|
275
|
+
* @param timezone - Timezone identifier (e.g., 'America/New_York')
|
|
276
|
+
* @param locale - Locale for display name (default: 'en-US')
|
|
277
|
+
* @returns Human-readable timezone name
|
|
278
|
+
*/
|
|
279
|
+
static getTimezoneDisplayName(timezone, locale = 'en-US') {
|
|
280
|
+
try {
|
|
281
|
+
const formatter = new Intl.DateTimeFormat(locale, {
|
|
282
|
+
timeZone: timezone,
|
|
283
|
+
timeZoneName: 'long'
|
|
284
|
+
});
|
|
285
|
+
const parts = formatter.formatToParts(new Date());
|
|
286
|
+
const timeZonePart = parts.find(part => part.type === 'timeZoneName');
|
|
287
|
+
return timeZonePart ? timeZonePart.value : timezone;
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
return timezone;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
export default LocaleUtils;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageNameMatcher - Utility for matching page names with plural and case variations
|
|
3
|
+
*
|
|
4
|
+
* Implements JSPWiki-style plural matching to allow flexible page name resolution.
|
|
5
|
+
* For example, linking to "Page" will match both "Page" and "Pages".
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const matcher = new PageNameMatcher(true);
|
|
9
|
+
* matcher.findMatch('Page', ['Pages', 'Main']); // Returns 'Pages'
|
|
10
|
+
* matcher.findMatch('Categories', ['Category']); // Returns 'Category'
|
|
11
|
+
*/
|
|
12
|
+
export default class PageNameMatcher {
|
|
13
|
+
private matchEnglishPlurals;
|
|
14
|
+
private matchCamelCase;
|
|
15
|
+
/** Index mapping variation -> original page name for O(1) lookups */
|
|
16
|
+
private variationIndex;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new PageNameMatcher instance
|
|
19
|
+
*
|
|
20
|
+
* @param matchEnglishPlurals - Enable plural matching (default: true)
|
|
21
|
+
* @param matchCamelCase - Enable CamelCase splitting/joining matching (default: false)
|
|
22
|
+
*/
|
|
23
|
+
constructor(matchEnglishPlurals?: boolean, matchCamelCase?: boolean);
|
|
24
|
+
/**
|
|
25
|
+
* Build an index from page names for fast O(1) lookups
|
|
26
|
+
* Call this once with all page names before doing many findMatch calls
|
|
27
|
+
*
|
|
28
|
+
* Uses two passes so that exact page names always take priority over
|
|
29
|
+
* plural/singular variants. Without this, "Plugin" would register "plugins"
|
|
30
|
+
* as a variation and steal the index entry from the real "Plugins" page.
|
|
31
|
+
*
|
|
32
|
+
* @param pageNames - Array of all existing page names
|
|
33
|
+
*/
|
|
34
|
+
buildIndex(pageNames: string[]): void;
|
|
35
|
+
/**
|
|
36
|
+
* Clear the index (call when page list changes)
|
|
37
|
+
*/
|
|
38
|
+
clearIndex(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Normalize a page name for comparison (lowercase)
|
|
41
|
+
*
|
|
42
|
+
* @param pageName - The page name to normalize
|
|
43
|
+
* @returns Normalized page name
|
|
44
|
+
*/
|
|
45
|
+
normalize(pageName: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Split a CamelCase name into separate words
|
|
48
|
+
* e.g., "HealthCare" → ["Health", "Care"], "XMLParser" → ["XML", "Parser"]
|
|
49
|
+
*
|
|
50
|
+
* Acronyms/abbreviations are kept as single units:
|
|
51
|
+
* e.g., "BCE", "USA", "HTML" → ["BCE"], ["USA"], ["HTML"]
|
|
52
|
+
* This prevents false matches where "550 BCE" and "330 BCE" would both
|
|
53
|
+
* generate the variation "b c e" and incorrectly match each other.
|
|
54
|
+
*
|
|
55
|
+
* Ordinal/numeric prefixes are also kept as single units:
|
|
56
|
+
* e.g., "5th Century" → ["5th", "Century"], "10th Century" → ["10th", "Century"]
|
|
57
|
+
* Without this, "5th" and "10th" both reduce to "th", causing all "Nth Century"
|
|
58
|
+
* pages to collide on the same CamelCase variation.
|
|
59
|
+
*/
|
|
60
|
+
private splitCamelCase;
|
|
61
|
+
/**
|
|
62
|
+
* Join space-separated words into CamelCase
|
|
63
|
+
* e.g., "Health Care" → "HealthCare"
|
|
64
|
+
*/
|
|
65
|
+
private joinCamelCase;
|
|
66
|
+
/**
|
|
67
|
+
* Get all possible plural/singular variations of a page name
|
|
68
|
+
*
|
|
69
|
+
* @param pageName - The base page name
|
|
70
|
+
* @returns Array of possible variations (all lowercase)
|
|
71
|
+
*/
|
|
72
|
+
getVariations(pageName: string): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Check if two page names match (considering plurals and case)
|
|
75
|
+
*
|
|
76
|
+
* @param name1 - First page name
|
|
77
|
+
* @param name2 - Second page name
|
|
78
|
+
* @returns True if the names match
|
|
79
|
+
*/
|
|
80
|
+
matches(name1: string, name2: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Find a matching page name from a list of existing page names
|
|
83
|
+
*
|
|
84
|
+
* @param searchName - The page name to search for
|
|
85
|
+
* @param existingNames - Array of existing page names (ignored if index is built)
|
|
86
|
+
* @returns The matching page name, or null if not found
|
|
87
|
+
*/
|
|
88
|
+
findMatch(searchName: string, existingNames: string[]): string | null;
|
|
89
|
+
/**
|
|
90
|
+
* Check if a page name conflicts with any existing pages (considering plurals)
|
|
91
|
+
* Used when creating new pages to prevent creating "Click" when "Clicks" exists
|
|
92
|
+
*
|
|
93
|
+
* @param newPageName - The new page name to check
|
|
94
|
+
* @param existingNames - Array of existing page names
|
|
95
|
+
* @returns The conflicting page name, or null if no conflict
|
|
96
|
+
*/
|
|
97
|
+
findConflict(newPageName: string, existingNames: string[]): string | null;
|
|
98
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preflight a configured filesystem path before anything tries to write to it.
|
|
3
|
+
*
|
|
4
|
+
* Detects ONE thing: a macOS `/Volumes/<X>/...` path whose mount is absent,
|
|
5
|
+
* where `fs.ensureDir` would otherwise crash the engine with an opaque
|
|
6
|
+
* `EACCES`. A mistyped path elsewhere is not caught at all — #645 tracks
|
|
7
|
+
* widening it.
|
|
8
|
+
*
|
|
9
|
+
* __The platform is injectable, and that is not a convenience.__ The check
|
|
10
|
+
* runs only on darwin, so on Linux CI the branch was unreachable: every
|
|
11
|
+
* assertion covering it was guarded by `if (process.platform === 'darwin')`
|
|
12
|
+
* and silently skipped, while `managerStatus.test.ts` asserted the degraded
|
|
13
|
+
* state unguarded and failed on every CI run. A test that can only pass on one
|
|
14
|
+
* developer's operating system is not a test of anything CI can protect, and a
|
|
15
|
+
* continuously-red check is one nobody reads.
|
|
16
|
+
*
|
|
17
|
+
* With the seam, the darwin logic is exercised on every platform, and the
|
|
18
|
+
* production default is still `process.platform`.
|
|
19
|
+
*/
|
|
20
|
+
export interface PathPreflightResult {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
reason?: 'missing-mount';
|
|
23
|
+
missingMount?: string;
|
|
24
|
+
message?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Test seams. Production passes none of these. */
|
|
27
|
+
export interface PathPreflightOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Which platform to check as. Defaults to the real one.
|
|
30
|
+
*
|
|
31
|
+
* Injected rather than stubbed on `process`, because mutating a global for
|
|
32
|
+
* the duration of a test leaks into anything running in parallel.
|
|
33
|
+
*/
|
|
34
|
+
platform?: NodeJS.Platform;
|
|
35
|
+
/** How to test for a mounted directory. Defaults to `fs.statSync`. */
|
|
36
|
+
isDirectory?: (path: string) => boolean;
|
|
37
|
+
}
|
|
38
|
+
export declare function checkConfiguredPath(p: string | undefined | null, options?: PathPreflightOptions): PathPreflightResult;
|