@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.
Files changed (302) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +16 -2
  3. package/lib/packages/ngdpbase-types/index.d.ts +32 -0
  4. package/lib/packages/ngdpbase-types/testing.d.ts +43 -0
  5. package/lib/packages/ngdpbase-types/testing.js +53 -0
  6. package/lib/src/cache/CacheDependencies.d.ts +50 -0
  7. package/lib/src/cache/CacheDependencies.js +50 -0
  8. package/lib/src/cache/ICacheAdapter.d.ts +86 -0
  9. package/lib/src/cache/RegionCache.d.ts +171 -0
  10. package/lib/src/context/ActorContext.d.ts +48 -0
  11. package/lib/src/context/ActorContext.js +33 -0
  12. package/lib/src/context/ApiContext.d.ts +194 -0
  13. package/lib/src/context/ApiContext.js +273 -0
  14. package/lib/src/context/BaseContext.d.ts +110 -0
  15. package/lib/src/context/BaseContext.js +143 -0
  16. package/lib/src/context/JobContext.d.ts +153 -0
  17. package/lib/src/context/JobContext.js +144 -0
  18. package/lib/src/context/WikiContext.d.ts +404 -0
  19. package/lib/src/context/bootActions.d.ts +64 -0
  20. package/lib/src/context/bootActions.js +111 -0
  21. package/lib/src/converters/HtmlConverter.d.ts +70 -0
  22. package/lib/src/converters/IContentConverter.d.ts +94 -0
  23. package/lib/src/converters/JSPWikiConverter.d.ts +117 -0
  24. package/lib/src/converters/conversionWarning.d.ts +15 -0
  25. package/lib/src/converters/ncm/bridge.d.ts +22 -0
  26. package/lib/src/converters/ncm/existing.d.ts +23 -0
  27. package/lib/src/converters/ncm/fix/blocks.d.ts +89 -0
  28. package/lib/src/converters/ncm/fix/bulletMarkers.d.ts +21 -0
  29. package/lib/src/converters/ncm/fix/index.d.ts +36 -0
  30. package/lib/src/converters/ncm/fix/jspwikiBullets.d.ts +20 -0
  31. package/lib/src/converters/ncm/fix/jspwikiCodeMarkers.d.ts +38 -0
  32. package/lib/src/converters/ncm/fix/jspwikiHeadings.d.ts +25 -0
  33. package/lib/src/converters/ncm/fix/jspwikiIndent.d.ts +24 -0
  34. package/lib/src/converters/ncm/fix/jspwikiInsert.d.ts +21 -0
  35. package/lib/src/converters/ncm/fix/jspwikiItalic.d.ts +29 -0
  36. package/lib/src/converters/ncm/fix/jspwikiLinkLeftovers.d.ts +27 -0
  37. package/lib/src/converters/ncm/fix/moreInformationFooter.d.ts +25 -0
  38. package/lib/src/converters/ncm/fix/styleClosers.d.ts +25 -0
  39. package/lib/src/converters/ncm/fix/tightenLists.d.ts +30 -0
  40. package/lib/src/converters/ncm/fix/types.d.ts +33 -0
  41. package/lib/src/converters/ncm/footnotes.d.ts +39 -0
  42. package/lib/src/converters/ncm/images.d.ts +49 -0
  43. package/lib/src/converters/ncm/index.d.ts +20 -0
  44. package/lib/src/converters/ncm/links.d.ts +21 -0
  45. package/lib/src/converters/ncm/normalize.d.ts +39 -0
  46. package/lib/src/converters/ncm/placeholder.d.ts +25 -0
  47. package/lib/src/converters/ncm/tables.d.ts +36 -0
  48. package/lib/src/converters/ncm/types.d.ts +42 -0
  49. package/lib/src/http/egressPolicy.d.ts +52 -0
  50. package/lib/src/http/guardedFetch.d.ts +89 -0
  51. package/lib/src/http/guardedFetch.js +113 -0
  52. package/lib/src/http/guardedLookup.d.ts +48 -0
  53. package/lib/src/http/guardedLookup.js +73 -0
  54. package/lib/src/http/ssrf.d.ts +83 -0
  55. package/lib/src/http/ssrf.js +311 -0
  56. package/lib/src/mail/MailProvider.d.ts +36 -0
  57. package/lib/src/mail/NodemailerMailProvider.d.ts +26 -0
  58. package/lib/src/managers/AddonsManager.d.ts +691 -0
  59. package/lib/src/managers/AgentTokenManager.d.ts +269 -0
  60. package/lib/src/managers/AssetManager.d.ts +116 -0
  61. package/lib/src/managers/AttachmentManager.d.ts +1032 -0
  62. package/lib/src/managers/AuthManager.d.ts +1257 -0
  63. package/lib/src/managers/BackgroundJobManager.d.ts +434 -0
  64. package/lib/src/managers/BaseManager.d.ts +391 -0
  65. package/lib/src/managers/BaseManager.js +415 -0
  66. package/lib/src/managers/CacheManager.d.ts +159 -0
  67. package/lib/src/managers/CatalogManager.d.ts +235 -0
  68. package/lib/src/managers/CommentManager.d.ts +75 -0
  69. package/lib/src/managers/ConfigurationManager.d.ts +747 -0
  70. package/lib/src/managers/DatabaseManager.d.ts +89 -0
  71. package/lib/src/managers/DatabaseManager.js +236 -0
  72. package/lib/src/managers/EmailManager.d.ts +47 -0
  73. package/lib/src/managers/ExportManager.d.ts +129 -0
  74. package/lib/src/managers/ExportManager.js +420 -0
  75. package/lib/src/managers/FootnoteManager.d.ts +118 -0
  76. package/lib/src/managers/MediaManager.d.ts +279 -0
  77. package/lib/src/managers/MetricsManager.d.ts +89 -0
  78. package/lib/src/managers/NotificationManager.d.ts +165 -0
  79. package/lib/src/managers/OidcManager.d.ts +210 -0
  80. package/lib/src/managers/OrganizationManager.d.ts +107 -0
  81. package/lib/src/managers/PageManager.d.ts +1645 -0
  82. package/lib/src/managers/PersonManager.d.ts +48 -0
  83. package/lib/src/managers/PluginManager.d.ts +179 -0
  84. package/lib/src/managers/PluginManager.js +393 -0
  85. package/lib/src/managers/PolicyEvaluator.d.ts +213 -0
  86. package/lib/src/managers/RenderingManager.d.ts +358 -0
  87. package/lib/src/managers/RoleManager.d.ts +134 -0
  88. package/lib/src/managers/SearchManager.d.ts +402 -0
  89. package/lib/src/managers/ShareManager.d.ts +251 -0
  90. package/lib/src/managers/TemplateManager.d.ts +176 -0
  91. package/lib/src/managers/ThemeManager.d.ts +56 -0
  92. package/lib/src/managers/UserManager.d.ts +480 -0
  93. package/lib/src/managers/ValidationManager.d.ts +426 -0
  94. package/lib/src/managers/VariableManager.d.ts +145 -0
  95. package/lib/src/middleware/csrf.d.ts +3 -0
  96. package/lib/src/parsers/LinkParser.d.ts +457 -0
  97. package/lib/src/parsers/MarkupParser.d.ts +769 -0
  98. package/lib/src/parsers/context/ParseContext.d.ts +314 -0
  99. package/lib/src/parsers/data/emoji-map.d.ts +18 -0
  100. package/lib/src/parsers/dom/DOMBuilder.d.ts +210 -0
  101. package/lib/src/parsers/dom/DOMParser.d.ts +252 -0
  102. package/lib/src/parsers/dom/Tokenizer.d.ts +358 -0
  103. package/lib/src/parsers/dom/WikiDocument.d.ts +272 -0
  104. package/lib/src/parsers/dom/handlers/DOMLinkHandler.d.ts +260 -0
  105. package/lib/src/parsers/dom/handlers/DOMPluginHandler.d.ts +212 -0
  106. package/lib/src/parsers/dom/handlers/DOMVariableHandler.d.ts +171 -0
  107. package/lib/src/parsers/filters/BaseFilter.d.ts +269 -0
  108. package/lib/src/parsers/filters/FilterChain.d.ts +320 -0
  109. package/lib/src/parsers/handlers/BaseSyntaxHandler.d.ts +331 -0
  110. package/lib/src/parsers/handlers/HandlerRegistry.d.ts +225 -0
  111. package/lib/src/parsers/handlers/JSPWikiPreprocessor.d.ts +89 -0
  112. package/lib/src/parsers/handlers/LinkParserHandler.d.ts +80 -0
  113. package/lib/src/parsers/handlers/PluginSyntaxHandler.d.ts +78 -0
  114. package/lib/src/parsers/handlers/WikiFormHandler.d.ts +149 -0
  115. package/lib/src/parsers/handlers/WikiTagHandler.d.ts +125 -0
  116. package/lib/src/parsers/jspwikiTableRow.d.ts +39 -0
  117. package/lib/src/parsers/styleBlockSyntax.d.ts +14 -0
  118. package/lib/src/plugins/types.d.ts +79 -0
  119. package/lib/src/providers/AgentTokenAuthProvider.d.ts +40 -0
  120. package/lib/src/providers/AuthentikBearerAuthProvider.d.ts +75 -0
  121. package/lib/src/providers/BaseAttachmentProvider.d.ts +197 -0
  122. package/lib/src/providers/BaseAuthProvider.d.ts +220 -0
  123. package/lib/src/providers/BaseCacheProvider.d.ts +140 -0
  124. package/lib/src/providers/BaseCredentialsProvider.d.ts +84 -0
  125. package/lib/src/providers/BaseDatabaseProvider.d.ts +22 -0
  126. package/lib/src/providers/BaseDatabaseProvider.js +12 -0
  127. package/lib/src/providers/BaseLoggingProvider.d.ts +68 -0
  128. package/lib/src/providers/BaseLoggingProvider.js +37 -0
  129. package/lib/src/providers/BaseMediaProvider.d.ts +308 -0
  130. package/lib/src/providers/BasePageProvider.d.ts +337 -0
  131. package/lib/src/providers/BaseProvider.d.ts +98 -0
  132. package/lib/src/providers/BaseProvider.js +74 -0
  133. package/lib/src/providers/BaseSearchProvider.d.ts +362 -0
  134. package/lib/src/providers/BasicAttachmentProvider.d.ts +599 -0
  135. package/lib/src/providers/CloudflareAccessAuthProvider.d.ts +72 -0
  136. package/lib/src/providers/FileCredentialsProvider.d.ts +33 -0
  137. package/lib/src/providers/FileJobStateProvider.d.ts +58 -0
  138. package/lib/src/providers/FileLoggingProvider.d.ts +43 -0
  139. package/lib/src/providers/FileLoggingProvider.js +120 -0
  140. package/lib/src/providers/FileOidcAdapter.d.ts +25 -0
  141. package/lib/src/providers/FileSystemMediaProvider.d.ts +403 -0
  142. package/lib/src/providers/LunrSearchProvider.d.ts +280 -0
  143. package/lib/src/providers/MagicLinkAuthProvider.d.ts +125 -0
  144. package/lib/src/providers/NullCacheProvider.d.ts +72 -0
  145. package/lib/src/providers/OidcAuthProvider.d.ts +180 -0
  146. package/lib/src/providers/OidcBearerAuthProvider.d.ts +30 -0
  147. package/lib/src/providers/PasskeyAuthProvider.d.ts +58 -0
  148. package/lib/src/providers/PasswordAuthProvider.d.ts +20 -0
  149. package/lib/src/providers/SqliteDatabaseProvider.d.ts +55 -0
  150. package/lib/src/providers/SqliteDatabaseProvider.js +90 -0
  151. package/lib/src/providers/SqliteJobStateProvider.d.ts +41 -0
  152. package/lib/src/providers/databaseMigrations.d.ts +8 -0
  153. package/lib/src/providers/databaseMigrations.js +47 -0
  154. package/lib/src/providers/jobState.d.ts +99 -0
  155. package/lib/src/providers/lunrQueryToMiniSearch.d.ts +32 -0
  156. package/lib/src/providers/mediaFilenameDate.d.ts +22 -0
  157. package/lib/src/providers/sqliteLocation.d.ts +17 -0
  158. package/lib/src/providers/sqliteLocation.js +55 -0
  159. package/lib/src/providers/sqliteMigrations.d.ts +48 -0
  160. package/lib/src/providers/sqliteMigrations.js +72 -0
  161. package/lib/src/rendering/githubAlerts.d.ts +22 -0
  162. package/lib/src/rendering/htmlPolicy.d.ts +76 -0
  163. package/lib/src/rendering/markdownConverter.d.ts +73 -0
  164. package/lib/src/security/PolicyDecisionPoint.d.ts +245 -0
  165. package/lib/src/security/PolicyInformationPoint.d.ts +448 -0
  166. package/lib/src/security/pageActions.d.ts +40 -0
  167. package/lib/src/security/permissions.generated.d.ts +78 -0
  168. package/lib/src/types/Asset.d.ts +414 -0
  169. package/lib/src/types/Catalog.d.ts +61 -0
  170. package/lib/src/types/Comment.d.ts +11 -0
  171. package/lib/src/types/Config.d.ts +388 -0
  172. package/lib/src/types/Organization.d.ts +78 -0
  173. package/lib/src/types/OrganizationProvider.d.ts +38 -0
  174. package/lib/src/types/Page.d.ts +220 -0
  175. package/lib/src/types/Person.d.ts +56 -0
  176. package/lib/src/types/PersonProvider.d.ts +25 -0
  177. package/lib/src/types/Policy.d.ts +139 -0
  178. package/lib/src/types/Policy.js +17 -0
  179. package/lib/src/types/Provider.d.ts +810 -0
  180. package/lib/src/types/Role.d.ts +84 -0
  181. package/lib/src/types/RoleProvider.d.ts +35 -0
  182. package/lib/src/types/Schema.d.ts +425 -0
  183. package/lib/src/types/Share.d.ts +172 -0
  184. package/lib/src/types/Share.js +81 -0
  185. package/lib/src/types/User.d.ts +304 -0
  186. package/lib/src/types/Version.d.ts +189 -0
  187. package/lib/src/types/WikiEngine.d.ts +128 -0
  188. package/lib/src/types/express.d.ts +120 -0
  189. package/lib/src/types/express.js +1 -0
  190. package/lib/src/types/guards.d.ts +78 -0
  191. package/lib/src/types/heic-decode.d.ts +16 -0
  192. package/lib/src/types/index.d.ts +19 -0
  193. package/lib/src/types/linkedom.d.ts +77 -0
  194. package/lib/src/types/markdown-it-plugins.d.ts +21 -0
  195. package/lib/src/utils/DeltaStorage.d.ts +118 -0
  196. package/lib/src/utils/LocaleUtils.d.ts +105 -0
  197. package/lib/src/utils/LocaleUtils.js +294 -0
  198. package/lib/src/utils/PageNameMatcher.d.ts +98 -0
  199. package/lib/src/utils/PathPreflight.d.ts +38 -0
  200. package/lib/src/utils/PathPreflight.js +50 -0
  201. package/lib/src/utils/SectionUtils.d.ts +40 -0
  202. package/lib/src/utils/addonConfigLayer.d.ts +144 -0
  203. package/lib/src/utils/addonConfigLayer.js +382 -0
  204. package/lib/src/utils/addonDatabaseRules.d.ts +25 -0
  205. package/lib/src/utils/addonDatabaseRules.js +57 -0
  206. package/lib/src/utils/addonHost.d.ts +51 -0
  207. package/lib/src/utils/addonHost.js +72 -0
  208. package/lib/src/utils/addonInstaller.d.ts +109 -0
  209. package/lib/src/utils/addonLock.d.ts +37 -0
  210. package/lib/src/utils/addonLock.js +48 -0
  211. package/lib/src/utils/addonPageSync.d.ts +45 -0
  212. package/lib/src/utils/addonProvenance.d.ts +48 -0
  213. package/lib/src/utils/addonTarball.d.ts +41 -0
  214. package/lib/src/utils/addonsPathResolver.d.ts +76 -0
  215. package/lib/src/utils/addonsPathResolver.js +129 -0
  216. package/lib/src/utils/assetMetadataTags.d.ts +66 -0
  217. package/lib/src/utils/atomicWrite.d.ts +28 -0
  218. package/lib/src/utils/auditConfigChange.d.ts +57 -0
  219. package/lib/src/utils/auditEventNames.d.ts +50 -0
  220. package/lib/src/utils/auditEventNames.generated.d.ts +163 -0
  221. package/lib/src/utils/auditEventNames.generated.js +168 -0
  222. package/lib/src/utils/auditEventNames.js +49 -0
  223. package/lib/src/utils/auditEvents.d.ts +265 -0
  224. package/lib/src/utils/auditEvents.js +309 -0
  225. package/lib/src/utils/auditRegistry.d.ts +102 -0
  226. package/lib/src/utils/auditRegistry.js +168 -0
  227. package/lib/src/utils/bip39English.d.ts +2 -0
  228. package/lib/src/utils/configEnvKeys.d.ts +68 -0
  229. package/lib/src/utils/configFiles.d.ts +74 -0
  230. package/lib/src/utils/configFiles.js +150 -0
  231. package/lib/src/utils/delegation.d.ts +48 -0
  232. package/lib/src/utils/deriveUsername.d.ts +21 -0
  233. package/lib/src/utils/explainMediaPath.d.ts +123 -0
  234. package/lib/src/utils/formerTitles.d.ts +69 -0
  235. package/lib/src/utils/frontmatterAccess.d.ts +54 -0
  236. package/lib/src/utils/headlessAdminPassword.d.ts +55 -0
  237. package/lib/src/utils/imageTransform.d.ts +52 -0
  238. package/lib/src/utils/instanceEnvSecret.d.ts +51 -0
  239. package/lib/src/utils/jobSlots.d.ts +43 -0
  240. package/lib/src/utils/keywordNormalizer.d.ts +127 -0
  241. package/lib/src/utils/logger.d.ts +70 -0
  242. package/lib/src/utils/logger.js +106 -0
  243. package/lib/src/utils/magicLinkDeviceState.d.ts +95 -0
  244. package/lib/src/utils/managerUtils.d.ts +40 -0
  245. package/lib/src/utils/migrateLegacyPrivateAttachments.d.ts +15 -0
  246. package/lib/src/utils/orgFilename.d.ts +22 -0
  247. package/lib/src/utils/pageFeature.d.ts +27 -0
  248. package/lib/src/utils/pageFrontmatter.d.ts +21 -0
  249. package/lib/src/utils/pageNotes.d.ts +150 -0
  250. package/lib/src/utils/pageTitleRule.d.ts +37 -0
  251. package/lib/src/utils/pageToArticle.d.ts +59 -0
  252. package/lib/src/utils/pageUrl.d.ts +18 -0
  253. package/lib/src/utils/passwordChange.d.ts +12 -0
  254. package/lib/src/utils/passwordHash.d.ts +60 -0
  255. package/lib/src/utils/permissionCatalog.d.ts +52 -0
  256. package/lib/src/utils/pluginFormatters.d.ts +452 -0
  257. package/lib/src/utils/pluginFormatters.js +714 -0
  258. package/lib/src/utils/privateLinkRewrite.d.ts +42 -0
  259. package/lib/src/utils/privateStoreAccess.d.ts +57 -0
  260. package/lib/src/utils/privateStoreAccess.js +65 -0
  261. package/lib/src/utils/privateStoreCatalogs.d.ts +40 -0
  262. package/lib/src/utils/privateStoreCrypto.d.ts +127 -0
  263. package/lib/src/utils/privateStoreDoor.d.ts +181 -0
  264. package/lib/src/utils/privateStoreExport.d.ts +72 -0
  265. package/lib/src/utils/privateStoreFiles.d.ts +120 -0
  266. package/lib/src/utils/privateStoreMeta.d.ts +64 -0
  267. package/lib/src/utils/privateStoreMigrations.d.ts +37 -0
  268. package/lib/src/utils/privateStorePath.d.ts +259 -0
  269. package/lib/src/utils/privateStorePath.js +436 -0
  270. package/lib/src/utils/privateStoreTakeout.d.ts +76 -0
  271. package/lib/src/utils/privateStoreUnlock.d.ts +175 -0
  272. package/lib/src/utils/proxyClaim.d.ts +59 -0
  273. package/lib/src/utils/proxyClaim.js +30 -0
  274. package/lib/src/utils/redactPrivateNames.d.ts +21 -0
  275. package/lib/src/utils/redactPrivateNames.js +89 -0
  276. package/lib/src/utils/redactSecrets.d.ts +58 -0
  277. package/lib/src/utils/redactSecrets.js +171 -0
  278. package/lib/src/utils/renameLinkRewrite.d.ts +112 -0
  279. package/lib/src/utils/roleGrants.d.ts +35 -0
  280. package/lib/src/utils/safeRedirect.d.ts +32 -0
  281. package/lib/src/utils/schedule.d.ts +54 -0
  282. package/lib/src/utils/secretFileMode.d.ts +17 -0
  283. package/lib/src/utils/seededShippedPages.d.ts +45 -0
  284. package/lib/src/utils/sensitiveValues.d.ts +59 -0
  285. package/lib/src/utils/sensitiveValues.js +106 -0
  286. package/lib/src/utils/sessionEnd.d.ts +12 -0
  287. package/lib/src/utils/sessionGeneration.d.ts +24 -0
  288. package/lib/src/utils/sessionIdle.d.ts +41 -0
  289. package/lib/src/utils/sessionLimits.d.ts +68 -0
  290. package/lib/src/utils/shareLockbox.d.ts +64 -0
  291. package/lib/src/utils/sigstoreTrustedRoot.d.ts +33 -0
  292. package/lib/src/utils/sniffMime.d.ts +21 -0
  293. package/lib/src/utils/storeSearchIndex.d.ts +75 -0
  294. package/lib/src/utils/subjectMayDo.d.ts +21 -0
  295. package/lib/src/utils/systemCategoryRules.d.ts +30 -0
  296. package/lib/src/utils/systemCategoryRules.js +41 -0
  297. package/lib/src/utils/userCreateError.d.ts +62 -0
  298. package/lib/src/utils/username.d.ts +53 -0
  299. package/lib/src/utils/vaultUrlRewrite.d.ts +27 -0
  300. package/lib/src/utils/version.d.ts +84 -0
  301. package/lib/src/utils/videoFrame.d.ts +21 -0
  302. package/package.json +54 -3
@@ -0,0 +1,48 @@
1
+ import BaseManager, { type ManagerStats } from './BaseManager.js';
2
+ import type { WikiEngine } from '../types/WikiEngine.js';
3
+ import type { Person, PersonUpdate } from '../types/Person.js';
4
+ import type { PersonProvider } from '../types/PersonProvider.js';
5
+ /**
6
+ * PersonManager — canonical core record for persons (#617).
7
+ *
8
+ * Each User has at most one paired Person record. UserManager calls
9
+ * `create`/`update`/`delete` here on the matching user lifecycle events.
10
+ * `getByUserIdentifier(username)` remains as a lazy-migration entry point
11
+ * for legacy users that pre-date the sync wiring.
12
+ */
13
+ declare class PersonManager extends BaseManager {
14
+ readonly description = "Canonical Person records (#617)";
15
+ private provider;
16
+ private providerClass?;
17
+ private byIdentifierCache;
18
+ private byIdCache;
19
+ private metricsRef;
20
+ constructor(engine: WikiEngine);
21
+ initialize(config?: Record<string, unknown>): Promise<void>;
22
+ getProvider(): PersonProvider | null;
23
+ getById(id: string): Promise<Person | null>;
24
+ getByIdentifier(identifier: string): Promise<Person | null>;
25
+ /** #1006: how many people this instance holds. Count only, never records. */
26
+ getManagerStats(): Promise<ManagerStats>;
27
+ list(): Promise<Person[]>;
28
+ create(person: Person): Promise<Person>;
29
+ update(id: string, patch: PersonUpdate): Promise<Person | null>;
30
+ delete(id: string): Promise<boolean>;
31
+ /**
32
+ * Clear all caches. Called on every write — the simplest correct
33
+ * invalidation. Per-key invalidation can come later if needed.
34
+ */
35
+ invalidateCache(): void;
36
+ /**
37
+ * Lazy-migration entry point.
38
+ *
39
+ * Returns the Person paired to `username`. If none exists and a matching
40
+ * User does, a Person is created from the User's email/displayName and
41
+ * persisted. Subsequent calls return the persisted record.
42
+ */
43
+ getByUserIdentifier(username: string): Promise<Person | null>;
44
+ private requireProvider;
45
+ private getMetrics;
46
+ private normalizeProviderName;
47
+ }
48
+ export default PersonManager;
@@ -0,0 +1,179 @@
1
+ import BaseManager from './BaseManager.js';
2
+ import * as pluginFormatters from '../utils/pluginFormatters.js';
3
+ import type { WikiEngine } from '../types/WikiEngine.js';
4
+ /**
5
+ * Plugin function type - old-style callable function plugin
6
+ */
7
+ export type PluginFunction = (pageName: string, params: PluginParams, linkGraph: Record<string, unknown>) => Promise<string> | string;
8
+ /**
9
+ * Plugin object interface - new-style plugin with execute method
10
+ */
11
+ export interface PluginObject {
12
+ name?: string;
13
+ description?: string;
14
+ author?: string;
15
+ version?: string;
16
+ initialize?: (engine: WikiEngine) => Promise<void> | void;
17
+ fetch?: (engine: WikiEngine) => Promise<void> | void;
18
+ execute: (context: PluginContext, params: PluginParams) => Promise<string> | string;
19
+ /**
20
+ * Its output changes with nothing written (a clock): a page that runs it is
21
+ * not kept in the page cache (#1751). Data a plugin reads from a manager is
22
+ * declared with `context.dependsOn(topic)` instead, which keeps the page
23
+ * cached until that data changes.
24
+ */
25
+ volatile?: boolean;
26
+ }
27
+ /**
28
+ * Plugin type - can be either a function or an object with execute method
29
+ */
30
+ export type Plugin = PluginFunction | PluginObject;
31
+ /**
32
+ * The plugin formatter helpers PluginManager owns (#1820): the functions and
33
+ * constants `src/utils/pluginFormatters.ts` exports, as the same objects.
34
+ * Their types stay importable from that module with `import type`.
35
+ */
36
+ export type PluginFormatters = Readonly<typeof pluginFormatters>;
37
+ export declare const formatters: PluginFormatters;
38
+ /**
39
+ * Plugin context passed to plugins during execution
40
+ */
41
+ export interface PluginContext {
42
+ engine: WikiEngine;
43
+ pageName: string;
44
+ linkGraph: Record<string, unknown>;
45
+ /** #1820: PluginManager's formatter helpers, e.g. `context.formatters.escapeHtml(s)`. */
46
+ formatters: PluginFormatters;
47
+ /**
48
+ * #1751: this render reads `topic`'s data (by convention the owning
49
+ * manager's name, e.g. 'LedgerManager'). Call before reading; the cached
50
+ * page is re-rendered once the manager bumps that topic.
51
+ */
52
+ dependsOn?: (topic: string) => void;
53
+ /** #1751: this render's output changes on its own; do not cache the page. */
54
+ markVolatile?: () => void;
55
+ [key: string]: unknown;
56
+ }
57
+ /**
58
+ * Plugin parameters (parsed from plugin syntax)
59
+ */
60
+ export interface PluginParams {
61
+ [key: string]: string | number | boolean;
62
+ }
63
+ /**
64
+ * Plugin information returned by getPluginInfo
65
+ */
66
+ export interface PluginInfo {
67
+ name: string;
68
+ description: string;
69
+ author: string;
70
+ version: string;
71
+ }
72
+ /**
73
+ * PluginManager - Handles plugin discovery, registration, and execution
74
+ *
75
+ * Similar to JSPWiki's PluginManager, this manager provides a plugin system
76
+ * for extending wiki functionality. Plugins are discovered from configured
77
+ * search paths and executed during markup parsing.
78
+ *
79
+ * Key features:
80
+ * - Dynamic plugin discovery from search paths
81
+ * - Plugin registration and metadata management
82
+ * - Secure plugin execution with sandboxing
83
+ * - Configurable plugin search paths
84
+ *
85
+ * @class PluginManager
86
+ * @extends BaseManager
87
+ *
88
+ * @property {Map<string, Plugin>} plugins - Registered plugins
89
+ * @property {string[]} searchPaths - Directories to search for plugins
90
+ * @property {string[]} allowedRoots - Allowed root paths for security
91
+ *
92
+ * @see {@link BaseManager} for base functionality
93
+ *
94
+ * @example
95
+ * const pluginManager = engine.getManager('PluginManager');
96
+ * const result = await pluginManager.execute('CurrentTimePlugin', params);
97
+ */
98
+ declare class PluginManager extends BaseManager {
99
+ private plugins;
100
+ private allowedRoots;
101
+ /**
102
+ * The plugin formatter helpers this manager owns (#1820), frozen. Plugins
103
+ * receive them as `context.formatters`; other callers read them here.
104
+ */
105
+ readonly formatters: PluginFormatters;
106
+ /**
107
+ * Creates a new PluginManager instance
108
+ *
109
+ * @constructor
110
+ * @param {any} engine - The wiki engine instance
111
+ */
112
+ constructor(engine: WikiEngine);
113
+ /**
114
+ * Initialize the PluginManager and discover plugins
115
+ *
116
+ * @async
117
+ * @param {Record<string, unknown>} [config={}] - Configuration object (unused, reads from ConfigurationManager)
118
+ * @returns {Promise<void>}
119
+ */
120
+ initialize(config?: Record<string, unknown>): Promise<void>;
121
+ /**
122
+ * Register all plugins from search paths obtained ONLY from
123
+ * ConfigurationManager at key: ngdpbase.managers.plugin-manager.search-paths
124
+ */
125
+ registerPlugins(): Promise<void>;
126
+ /**
127
+ * Load a single plugin from a validated, allowed root
128
+ * @param {string} pluginPath - Path to the plugin file
129
+ */
130
+ loadPlugin(pluginPath: string): Promise<void>;
131
+ /**
132
+ * Find plugin by name (case-insensitive)
133
+ * Supports JSPWiki-style plugin naming where you can use either:
134
+ * - "Search" or "SearchPlugin"
135
+ * - "Index" or "IndexPlugin"
136
+ *
137
+ * @param {string} pluginName - Name of the plugin to find
138
+ * @returns {Plugin|null} Plugin object or null if not found
139
+ */
140
+ findPlugin(pluginName: string): Plugin | null;
141
+ /**
142
+ * Execute a plugin
143
+ * @param {string} pluginName - Name of the plugin
144
+ * @param {string} pageName - Current page name
145
+ * @param {PluginParams} params - Plugin parameters (parsed object)
146
+ * @param {Record<string, unknown>} context - Additional context
147
+ * @returns {Promise<string>} Plugin output
148
+ */
149
+ execute(pluginName: string, pageName: string, params: PluginParams, context?: Record<string, unknown>): Promise<string>;
150
+ /**
151
+ * Get list of all registered plugins
152
+ * @returns {string[]} Array of plugin names
153
+ */
154
+ getPluginNames(): string[];
155
+ /**
156
+ * Get plugin info
157
+ * @param {string} pluginName - Name of the plugin
158
+ * @returns {PluginInfo | null} Plugin information
159
+ */
160
+ getPluginInfo(pluginName: string): PluginInfo | null;
161
+ /**
162
+ * Check if plugin exists
163
+ * @param {string} pluginName - Name of the plugin
164
+ * @returns {boolean} True if plugin exists
165
+ */
166
+ hasPlugin(pluginName: string): boolean;
167
+ /**
168
+ * Programmatically register a plugin object (for use by add-ons).
169
+ *
170
+ * Skips the file-path security check used by loadPlugin() — the caller is
171
+ * responsible for providing a trusted Plugin instance. Calls
172
+ * plugin.initialize(engine) if present, consistent with loadPlugin().
173
+ *
174
+ * @param {string} name - Plugin name (used for [{name ...}] invocation)
175
+ * @param {Plugin} plugin - Plugin function or PluginObject
176
+ */
177
+ registerPlugin(name: string, plugin: Plugin): Promise<void>;
178
+ }
179
+ export default PluginManager;
@@ -0,0 +1,393 @@
1
+ import CacheDependencies from '../cache/CacheDependencies.js';
2
+ import BaseManager from './BaseManager.js';
3
+ import fs from 'fs-extra';
4
+ import path from 'path';
5
+ import logger from '../utils/logger.js';
6
+ import * as pluginFormatters from '../utils/pluginFormatters.js';
7
+ import { enabledEntries } from '../utils/configFiles.js';
8
+ /**
9
+ * Type guard to check if plugin is an object with execute method
10
+ */
11
+ function isPluginObject(obj) {
12
+ return typeof obj === 'object' && obj !== null && typeof obj.execute === 'function';
13
+ }
14
+ /**
15
+ * Type guard to check if an unknown value is a valid Plugin
16
+ */
17
+ function isPlugin(obj) {
18
+ return typeof obj === 'function' || isPluginObject(obj);
19
+ }
20
+ /**
21
+ * The render's dependency collector (#1751): on the parse context the plugin
22
+ * handlers pass as `wikiContext`, or on the context itself.
23
+ */
24
+ /**
25
+ * The engine a plugin sees while its render is being cached (#1751): each
26
+ * `getManager(name)` also records `name` as data this render read, so the page
27
+ * re-renders when that manager bumps its topic. One path for every plugin,
28
+ * core or add-on — none declares what it reads.
29
+ */
30
+ function trackedEngine(engine, deps) {
31
+ return new Proxy(engine, {
32
+ get(target, prop) {
33
+ if (prop === 'getManager') {
34
+ return (name) => {
35
+ deps.dependsOn(name);
36
+ return target.getManager(name);
37
+ };
38
+ }
39
+ const value = Reflect.get(target, prop, target);
40
+ return typeof value === 'function' ? value.bind(target) : value;
41
+ }
42
+ });
43
+ }
44
+ function cacheDependenciesOf(context) {
45
+ const own = context.cacheDependencies;
46
+ if (own instanceof CacheDependencies)
47
+ return own;
48
+ const parse = context.wikiContext?.cacheDependencies;
49
+ return parse instanceof CacheDependencies ? parse : undefined;
50
+ }
51
+ /**
52
+ * Type guard to check if a module export has a default export
53
+ */
54
+ function hasDefaultExport(obj) {
55
+ return typeof obj === 'object' && obj !== null && 'default' in obj;
56
+ }
57
+ export const formatters = Object.freeze({ ...pluginFormatters });
58
+ /**
59
+ * PluginManager - Handles plugin discovery, registration, and execution
60
+ *
61
+ * Similar to JSPWiki's PluginManager, this manager provides a plugin system
62
+ * for extending wiki functionality. Plugins are discovered from configured
63
+ * search paths and executed during markup parsing.
64
+ *
65
+ * Key features:
66
+ * - Dynamic plugin discovery from search paths
67
+ * - Plugin registration and metadata management
68
+ * - Secure plugin execution with sandboxing
69
+ * - Configurable plugin search paths
70
+ *
71
+ * @class PluginManager
72
+ * @extends BaseManager
73
+ *
74
+ * @property {Map<string, Plugin>} plugins - Registered plugins
75
+ * @property {string[]} searchPaths - Directories to search for plugins
76
+ * @property {string[]} allowedRoots - Allowed root paths for security
77
+ *
78
+ * @see {@link BaseManager} for base functionality
79
+ *
80
+ * @example
81
+ * const pluginManager = engine.getManager('PluginManager');
82
+ * const result = await pluginManager.execute('CurrentTimePlugin', params);
83
+ */
84
+ class PluginManager extends BaseManager {
85
+ plugins;
86
+ allowedRoots;
87
+ /**
88
+ * The plugin formatter helpers this manager owns (#1820), frozen. Plugins
89
+ * receive them as `context.formatters`; other callers read them here.
90
+ */
91
+ formatters = formatters;
92
+ /**
93
+ * Creates a new PluginManager instance
94
+ *
95
+ * @constructor
96
+ * @param {any} engine - The wiki engine instance
97
+ */
98
+ constructor(engine) {
99
+ super(engine);
100
+ this.plugins = new Map();
101
+ this.allowedRoots = [];
102
+ }
103
+ /**
104
+ * Initialize the PluginManager and discover plugins
105
+ *
106
+ * @async
107
+ * @param {Record<string, unknown>} [config={}] - Configuration object (unused, reads from ConfigurationManager)
108
+ * @returns {Promise<void>}
109
+ */
110
+ async initialize(config = {}) {
111
+ await super.initialize(config);
112
+ // Do NOT read search paths from config here; only ConfigurationManager controls them
113
+ await this.registerPlugins();
114
+ this.engine.logger?.info?.('PluginManager initialized');
115
+ }
116
+ /**
117
+ * Register all plugins from search paths obtained ONLY from
118
+ * ConfigurationManager at key: ngdpbase.managers.plugin-manager.search-paths
119
+ */
120
+ async registerPlugins() {
121
+ const cfgMgr = this.engine.getManager('ConfigurationManager');
122
+ if (!cfgMgr || typeof cfgMgr.getProperty !== 'function') {
123
+ this.engine.logger?.warn?.('PluginManager: ConfigurationManager not available; no plugins will be loaded.');
124
+ return;
125
+ }
126
+ // MUST come only from config; no fallbacks
127
+ const raw = cfgMgr.getProperty('ngdpbase.managers.plugin-manager.search-paths');
128
+ this.engine.logger?.debug?.(`PluginManager: raw searchPaths type=${typeof raw} value=${JSON.stringify(raw)}`);
129
+ // Accept a set map, an array, or a comma-separated string
130
+ let configured = enabledEntries(raw);
131
+ if (typeof raw === 'string')
132
+ configured = raw
133
+ .split(',')
134
+ .map((s) => s.trim())
135
+ .filter(Boolean);
136
+ if (!Array.isArray(configured) || configured.length === 0) {
137
+ this.engine.logger?.info?.('PluginManager: No plugin search paths configured; skipping plugin load.');
138
+ return;
139
+ }
140
+ // Resolve and validate configured roots
141
+ const roots = [];
142
+ for (const p of configured) {
143
+ try {
144
+ const abs = path.resolve(process.cwd(), String(p));
145
+ if (!(await fs.pathExists(abs))) {
146
+ this.engine.logger?.debug?.(`PluginManager: configured path does not exist: ${abs}`);
147
+ continue;
148
+ }
149
+ const st = await fs.lstat(abs);
150
+ if (!st.isDirectory()) {
151
+ this.engine.logger?.warn?.(`PluginManager: configured path is not a directory: ${abs}`);
152
+ continue;
153
+ }
154
+ // Use realpath to collapse symlinks for later prefix checks
155
+ const real = await fs.realpath(abs);
156
+ roots.push(real);
157
+ }
158
+ catch (e) {
159
+ this.engine.logger?.warn?.(`PluginManager: failed to validate configured path "${p}": ${e.message}`);
160
+ }
161
+ }
162
+ this.allowedRoots = roots;
163
+ if (this.allowedRoots.length === 0) {
164
+ this.engine.logger?.info?.('PluginManager: No valid plugin roots after validation; skipping plugin load.');
165
+ return;
166
+ }
167
+ // Enumerate .js and .ts files in allowed roots only
168
+ for (const root of this.allowedRoots) {
169
+ try {
170
+ const entries = await fs.readdir(root, { withFileTypes: true });
171
+ for (const entry of entries) {
172
+ if (!entry.isFile())
173
+ continue;
174
+ // Skip test files and non-plugin files
175
+ const isJsPlugin = entry.name.endsWith('.js') && !entry.name.endsWith('.test.js');
176
+ const isTsPlugin = entry.name.endsWith('.ts') && !entry.name.endsWith('.test.ts') && !entry.name.endsWith('.d.ts');
177
+ if (!isJsPlugin && !isTsPlugin)
178
+ continue;
179
+ const candidate = path.join(root, entry.name);
180
+ await this.loadPlugin(candidate); // loadPlugin re-validates path is under an allowed root
181
+ }
182
+ }
183
+ catch (err) {
184
+ this.engine.logger?.warn?.(`PluginManager: Failed to load plugins from ${root}: ${err.message}`);
185
+ }
186
+ }
187
+ }
188
+ /**
189
+ * Load a single plugin from a validated, allowed root
190
+ * @param {string} pluginPath - Path to the plugin file
191
+ */
192
+ async loadPlugin(pluginPath) {
193
+ try {
194
+ // Resolve and validate canonical path
195
+ const realFile = await fs.realpath(path.resolve(pluginPath));
196
+ const isAllowed = this.allowedRoots.some((root) => realFile === root || realFile.startsWith(root + path.sep));
197
+ if (!isAllowed) {
198
+ this.engine.logger?.warn?.(`PluginManager: blocked plugin outside allowed roots: ${realFile}`);
199
+ return;
200
+ }
201
+ const mod = await import(realFile);
202
+ // Extract the plugin from the module (handle both default and direct exports)
203
+ const rawPlugin = hasDefaultExport(mod) ? mod.default : mod;
204
+ // Validate the plugin is executable
205
+ if (!isPlugin(rawPlugin)) {
206
+ const fileName = path.parse(realFile).name;
207
+ this.engine.logger?.warn?.(`PluginManager: "${fileName}" is not an executable plugin; skipping.`);
208
+ return;
209
+ }
210
+ // Now we know rawPlugin is a valid Plugin
211
+ const plugin = rawPlugin;
212
+ // Get plugin name from metadata or filename
213
+ const pluginName = (isPluginObject(plugin) && plugin.name) || path.parse(realFile).name;
214
+ // Initialize the plugin if it has an initialize method (only object plugins have this)
215
+ if (isPluginObject(plugin) && typeof plugin.initialize === 'function') {
216
+ await plugin.initialize(this.engine);
217
+ }
218
+ this.plugins.set(pluginName, plugin);
219
+ this.engine.logger?.info?.(`PluginManager: Loaded plugin "${pluginName}" from ${realFile}`);
220
+ }
221
+ catch (err) {
222
+ this.engine.logger?.error?.(`PluginManager: Failed to load plugin ${pluginPath}: ${err.message}`);
223
+ }
224
+ }
225
+ /**
226
+ * Find plugin by name (case-insensitive)
227
+ * Supports JSPWiki-style plugin naming where you can use either:
228
+ * - "Search" or "SearchPlugin"
229
+ * - "Index" or "IndexPlugin"
230
+ *
231
+ * @param {string} pluginName - Name of the plugin to find
232
+ * @returns {Plugin|null} Plugin object or null if not found
233
+ */
234
+ findPlugin(pluginName) {
235
+ // Try exact match first (for performance)
236
+ if (this.plugins.has(pluginName)) {
237
+ return this.plugins.get(pluginName) ?? null;
238
+ }
239
+ // Try case-insensitive match
240
+ const lowerName = pluginName.toLowerCase();
241
+ for (const [key, plugin] of this.plugins) {
242
+ if (key.toLowerCase() === lowerName) {
243
+ return plugin;
244
+ }
245
+ }
246
+ // JSPWiki compatibility: Try with "Plugin" suffix if not already present
247
+ if (!pluginName.toLowerCase().endsWith('plugin')) {
248
+ const withSuffix = pluginName + 'Plugin';
249
+ if (this.plugins.has(withSuffix)) {
250
+ return this.plugins.get(withSuffix) ?? null;
251
+ }
252
+ // Try case-insensitive with suffix
253
+ const lowerWithSuffix = withSuffix.toLowerCase();
254
+ for (const [key, plugin] of this.plugins) {
255
+ if (key.toLowerCase() === lowerWithSuffix) {
256
+ return plugin;
257
+ }
258
+ }
259
+ }
260
+ // Try without "Plugin" suffix if it's present
261
+ if (pluginName.toLowerCase().endsWith('plugin')) {
262
+ const withoutSuffix = pluginName.slice(0, -6); // Remove "Plugin"
263
+ if (this.plugins.has(withoutSuffix)) {
264
+ return this.plugins.get(withoutSuffix) ?? null;
265
+ }
266
+ // Try case-insensitive without suffix
267
+ const lowerWithoutSuffix = withoutSuffix.toLowerCase();
268
+ for (const [key, plugin] of this.plugins) {
269
+ if (key.toLowerCase() === lowerWithoutSuffix) {
270
+ return plugin;
271
+ }
272
+ }
273
+ }
274
+ return null;
275
+ }
276
+ /**
277
+ * Execute a plugin
278
+ * @param {string} pluginName - Name of the plugin
279
+ * @param {string} pageName - Current page name
280
+ * @param {PluginParams} params - Plugin parameters (parsed object)
281
+ * @param {Record<string, unknown>} context - Additional context
282
+ * @returns {Promise<string>} Plugin output
283
+ */
284
+ async execute(pluginName, pageName, params, context = {}) {
285
+ const plugin = this.findPlugin(pluginName);
286
+ if (!plugin) {
287
+ return `Plugin '${pluginName}' not found`;
288
+ }
289
+ try {
290
+ // Pass the full context through to plugins
291
+ // Plugins expect the full ParseContext/WikiContext with all properties
292
+ // #1751: what this render reads, for the page cache's read-through.
293
+ const deps = cacheDependenciesOf(context);
294
+ if (isPluginObject(plugin) && plugin.volatile)
295
+ deps?.markVolatile();
296
+ const pluginContext = {
297
+ ...context, // Spread all context properties
298
+ // Always the manager's engine; while the page cache is collecting, every
299
+ // manager the plugin fetches is recorded as data this render read (#1751).
300
+ engine: deps ? trackedEngine(this.engine, deps) : this.engine,
301
+ pageName: pageName,
302
+ linkGraph: context.linkGraph || {},
303
+ formatters: this.formatters,
304
+ dependsOn: (topic) => deps?.dependsOn(topic),
305
+ markVolatile: () => deps?.markVolatile()
306
+ };
307
+ // Check if it's a new-style plugin with execute method
308
+ if (isPluginObject(plugin)) {
309
+ if (typeof plugin.fetch === 'function') {
310
+ // #1751: fetch reads data for this render, so it sees the same tracked engine.
311
+ await plugin.fetch(pluginContext.engine);
312
+ }
313
+ const result = await plugin.execute(pluginContext, params);
314
+ return result;
315
+ }
316
+ // Check if it's an old-style function plugin
317
+ if (typeof plugin === 'function') {
318
+ const result = await plugin(pageName, params, context.linkGraph || {});
319
+ return result;
320
+ }
321
+ // This should never happen due to type narrowing, but satisfies TypeScript
322
+ return `Plugin '${pluginName}' is not executable`;
323
+ }
324
+ catch (err) {
325
+ logger.error(`Plugin '${pluginName}' execution failed:`, err);
326
+ return `Plugin '${pluginName}' error: ${err.message}`;
327
+ }
328
+ }
329
+ /**
330
+ * Get list of all registered plugins
331
+ * @returns {string[]} Array of plugin names
332
+ */
333
+ getPluginNames() {
334
+ return Array.from(this.plugins.keys());
335
+ }
336
+ /**
337
+ * Get plugin info
338
+ * @param {string} pluginName - Name of the plugin
339
+ * @returns {PluginInfo | null} Plugin information
340
+ */
341
+ getPluginInfo(pluginName) {
342
+ const plugin = this.findPlugin(pluginName);
343
+ if (!plugin) {
344
+ return null;
345
+ }
346
+ // Only PluginObject has metadata properties
347
+ if (isPluginObject(plugin)) {
348
+ return {
349
+ name: pluginName,
350
+ description: plugin.description || 'No description available',
351
+ author: plugin.author || 'Unknown',
352
+ version: plugin.version || '1.0.0'
353
+ };
354
+ }
355
+ // Function plugins have no metadata
356
+ return {
357
+ name: pluginName,
358
+ description: 'No description available',
359
+ author: 'Unknown',
360
+ version: '1.0.0'
361
+ };
362
+ }
363
+ /**
364
+ * Check if plugin exists
365
+ * @param {string} pluginName - Name of the plugin
366
+ * @returns {boolean} True if plugin exists
367
+ */
368
+ hasPlugin(pluginName) {
369
+ return this.findPlugin(pluginName) !== null;
370
+ }
371
+ /**
372
+ * Programmatically register a plugin object (for use by add-ons).
373
+ *
374
+ * Skips the file-path security check used by loadPlugin() — the caller is
375
+ * responsible for providing a trusted Plugin instance. Calls
376
+ * plugin.initialize(engine) if present, consistent with loadPlugin().
377
+ *
378
+ * @param {string} name - Plugin name (used for [{name ...}] invocation)
379
+ * @param {Plugin} plugin - Plugin function or PluginObject
380
+ */
381
+ async registerPlugin(name, plugin) {
382
+ if (!isPlugin(plugin)) {
383
+ logger.warn(`[PluginManager] registerPlugin('${name}'): argument is not a valid Plugin — skipped`);
384
+ return;
385
+ }
386
+ if (isPluginObject(plugin) && typeof plugin.initialize === 'function') {
387
+ await plugin.initialize(this.engine);
388
+ }
389
+ this.plugins.set(name, plugin);
390
+ logger.info(`[PluginManager] Registered plugin: ${name}`);
391
+ }
392
+ }
393
+ export default PluginManager;