@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,89 @@
1
+ import BaseManager from './BaseManager.js';
2
+ import type { WikiEngine } from '../types/WikiEngine.js';
3
+ import type { Migration } from '../providers/sqliteMigrations.js';
4
+ import { type AddonDatabaseDeclaration } from '../utils/addonDatabaseRules.js';
5
+ /** The environment variable holding the SQLCipher key. Never a config key: config is readable from the admin screens. */
6
+ export declare const DATABASE_KEY_ENV = "NGDPBASE_DATABASE_KEY";
7
+ /** What an add-on hands over to have its database opened and migrated. */
8
+ export interface AddonDatabaseOptions {
9
+ /** Dated migrations, strictly ascending by id — the same rules as core's ledger. */
10
+ migrations: Migration[];
11
+ /** Where the applied ids are recorded. Must start with the owner's slug (dashes as underscores) and `_`. */
12
+ ledgerTable: string;
13
+ }
14
+ /** A declared add-on database as Admin → Add-ons and the backup (#1723) see it. */
15
+ export interface DeclaredAddonDatabase extends AddonDatabaseDeclaration {
16
+ /** `<owner>.db` beside the application database; null when no application database is configured. */
17
+ file: string | null;
18
+ /** Whether this declaration's ledger is open in this process. */
19
+ open: boolean;
20
+ }
21
+ /**
22
+ * The request rules (addonDatabaseRules): the owner is a canonical slug, and
23
+ * the ledger table starts with its prefix. `openAddonDatabase` applies them,
24
+ * and so does the test kit's in-memory database
25
+ * (`@jwilleke/ngdpbase-types/testing`, #1865), so a test refuses what a site
26
+ * refuses.
27
+ */
28
+ export declare function checkAddonDatabaseRequest(owner: string, options: AddonDatabaseOptions): void;
29
+ /**
30
+ * The declaration of this owner's ledger among `declarations`, or a refusal
31
+ * naming what is missing (#1860). `openAddonDatabase` asks it of the site's
32
+ * declarations; the test kit asks it of the add-on's own (#1865).
33
+ */
34
+ export declare function addonDatabaseDeclarationFor(declarations: readonly AddonDatabaseDeclaration[], owner: string, ledgerTable: string): AddonDatabaseDeclaration;
35
+ declare class DatabaseManager extends BaseManager {
36
+ private provider;
37
+ private databaseFile;
38
+ private busyTimeoutMs;
39
+ private readonly addonDatabases;
40
+ constructor(engine: WikiEngine);
41
+ initialize(config?: Record<string, unknown>): Promise<void>;
42
+ /** Whether an application database is open. */
43
+ isEnabled(): boolean;
44
+ /**
45
+ * The open connection, for a row-storing provider's constructor. Throws when
46
+ * no database is configured, so a provider that needs one fails at boot with
47
+ * the key to set rather than at its first write.
48
+ */
49
+ getHandle<Handle = unknown>(): Handle;
50
+ /**
51
+ * Open (or join) an add-on's own database and run its migrations
52
+ * (ngdp-accounting-addons#13). The file is `<owner>.db` beside the application
53
+ * database, opened by the same provider under the same key, so it gets the
54
+ * same network-filesystem refusal, WAL, integrity check and newer-schema
55
+ * refusal. The first call for an owner opens the file; a later call — from an
56
+ * add-on that depends on the owner — adds its own ledger to the same file.
57
+ *
58
+ * Requires the application database: an operator who has not set
59
+ * `ngdpbase.database.provider` to `sqlite` has not chosen to keep a database.
60
+ *
61
+ * Opens only a declared database (#1860): an enabled add-on declares this
62
+ * owner and this ledger in `ngdpbase.addons.<slug>.database`. A declaration
63
+ * with `encrypt: "required"` is refused when `NGDPBASE_DATABASE_KEY` is not
64
+ * set; nothing is opened in the clear.
65
+ */
66
+ openAddonDatabase<Handle = unknown>(owner: string, options: AddonDatabaseOptions): Handle;
67
+ /**
68
+ * Every add-on database declared on this site (#1860), whether or not its
69
+ * add-on is turned on — so a turned-off add-on's file is still listed and
70
+ * backed up (#1723). One entry per declared ledger; several may share an
71
+ * owner's file.
72
+ */
73
+ getDeclaredDatabases(): DeclaredAddonDatabase[];
74
+ /**
75
+ * Why this add-on must not load, decided before it is imported (#1860): it
76
+ * declares a database `encrypt: "required"` and no key is set. Null when it
77
+ * may load. Asked by AddonsManager, as the configuration merge's refusals
78
+ * are (#1559).
79
+ */
80
+ addonRefusal(slug: string): string | null;
81
+ private declarations;
82
+ /** The one rule: a database declared `encrypt: "required"` is never opened without the key. */
83
+ private static keyRefusal;
84
+ /** Whether every open database passes SQLite's quick check; true when none is configured. */
85
+ integrityOk(): boolean;
86
+ /** Closes the add-on databases, then the application database. */
87
+ shutdown(): Promise<void>;
88
+ }
89
+ export default DatabaseManager;
@@ -0,0 +1,236 @@
1
+ /**
2
+ * DatabaseManager — the one door to the application database (#1536).
3
+ *
4
+ * Ported from yourPHR (yourphr#617), where it is in production. A manager that
5
+ * stores rows is handed this connection through `getHandle()`; nothing opens a
6
+ * database handle of its own.
7
+ *
8
+ * `ngdpbase.database.provider` chooses the provider:
9
+ * - `none` (the default) — no database is opened. Nothing in core stores rows
10
+ * yet; the first will be the database audit provider (#1537). Opening a file
11
+ * with no reader would only add a way to fail at boot — on a data volume
12
+ * that is a network filesystem, for instance.
13
+ * - `sqlite` — one file at `ngdpbase.database.file`, encrypted with SQLCipher
14
+ * when `NGDPBASE_DATABASE_KEY` is set (in the environment or the instance
15
+ * `.env`), never from config. Without a key it opens unencrypted and says so.
16
+ *
17
+ * Boot refuses, naming the cause, when the file would sit on a network
18
+ * filesystem, when the schema is from a newer build, when a migration fails,
19
+ * or when the integrity check does not pass.
20
+ *
21
+ * An add-on that keeps rows gets a database of its own the same way
22
+ * (`openAddonDatabase`, ngdp-accounting-addons#13): its own file beside the
23
+ * application database, opened by the same provider under the same key, with
24
+ * its own migration ledger. A dependent add-on adds its ledger to that file.
25
+ * Only a declared database is opened (#1860): the add-on names it in its own
26
+ * config/default-config.json (`ngdpbase.addons.<slug>.database`), and one
27
+ * declared `encrypt: "required"` is never opened without the key.
28
+ */
29
+ import path from 'node:path';
30
+ import BaseManager from './BaseManager.js';
31
+ import SqliteDatabaseProvider, { DEFAULT_BUSY_TIMEOUT_MS } from '../providers/SqliteDatabaseProvider.js';
32
+ import DATABASE_MIGRATIONS from '../providers/databaseMigrations.js';
33
+ import logger from '../utils/logger.js';
34
+ import { ADDON_SLUG, ledgerPrefix } from '../utils/addonDatabaseRules.js';
35
+ /** The environment variable holding the SQLCipher key. Never a config key: config is readable from the admin screens. */
36
+ export const DATABASE_KEY_ENV = 'NGDPBASE_DATABASE_KEY';
37
+ /**
38
+ * The request rules (addonDatabaseRules): the owner is a canonical slug, and
39
+ * the ledger table starts with its prefix. `openAddonDatabase` applies them,
40
+ * and so does the test kit's in-memory database
41
+ * (`@jwilleke/ngdpbase-types/testing`, #1865), so a test refuses what a site
42
+ * refuses.
43
+ */
44
+ export function checkAddonDatabaseRequest(owner, options) {
45
+ if (!ADDON_SLUG.test(owner)) {
46
+ throw new Error(`'${owner}' is not an add-on slug — lowercase letters and digits, single dashes (ngdp-accounting-addons#13)`);
47
+ }
48
+ const prefix = ledgerPrefix(owner);
49
+ if (!options.ledgerTable.startsWith(prefix)) {
50
+ throw new Error(`Add-on '${owner}': migration ledger table '${options.ledgerTable}' must start with '${prefix}' (ngdp-accounting-addons#13)`);
51
+ }
52
+ }
53
+ /**
54
+ * The declaration of this owner's ledger among `declarations`, or a refusal
55
+ * naming what is missing (#1860). `openAddonDatabase` asks it of the site's
56
+ * declarations; the test kit asks it of the add-on's own (#1865).
57
+ */
58
+ export function addonDatabaseDeclarationFor(declarations, owner, ledgerTable) {
59
+ const forOwner = declarations.filter((d) => d.owner === owner);
60
+ const declaration = forOwner.find((d) => d.ledgerTable === ledgerTable);
61
+ if (!declaration) {
62
+ throw new Error(forOwner.length === 0
63
+ ? `No add-on declares database '${owner}' — declare ngdpbase.addons.<slug>.database { owner, ledgerTable, encrypt } in the add-on's config/default-config.json (#1860)`
64
+ : `Database '${owner}' is declared, but not with ledger '${ledgerTable}' — the add-on that opens it declares that ledger (#1860)`);
65
+ }
66
+ if (!declaration.enabled) {
67
+ throw new Error(`Database '${owner}' ledger '${ledgerTable}' is declared by add-on '${declaration.declaredBy}', which is turned off or not loaded (#1860)`);
68
+ }
69
+ return declaration;
70
+ }
71
+ class DatabaseManager extends BaseManager {
72
+ provider = null;
73
+ databaseFile = null;
74
+ busyTimeoutMs = DEFAULT_BUSY_TIMEOUT_MS;
75
+ addonDatabases = new Map();
76
+ constructor(engine) {
77
+ super(engine);
78
+ }
79
+ async initialize(config = {}) {
80
+ await super.initialize(config);
81
+ const configManager = this.engine.getManager('ConfigurationManager');
82
+ const configured = configManager?.getProperty('ngdpbase.database.provider', 'none');
83
+ const kind = (typeof configured === 'string' ? configured : 'none').toLowerCase();
84
+ if (kind === 'none') {
85
+ logger.info('[DatabaseManager] No application database (ngdpbase.database.provider is none)');
86
+ return;
87
+ }
88
+ if (kind !== 'sqlite' || !configManager) {
89
+ throw new Error(`ngdpbase.database.provider '${kind}' is not a database provider — use 'sqlite' or 'none' (#1536)`);
90
+ }
91
+ const busy = configManager.getProperty('ngdpbase.database.busy-timeout-ms', DEFAULT_BUSY_TIMEOUT_MS);
92
+ if (typeof busy !== 'number' || !Number.isInteger(busy) || busy < 0) {
93
+ throw new Error(`ngdpbase.database.busy-timeout-ms must be a whole number of milliseconds, 0 or more — got ${JSON.stringify(busy)} (#1710)`);
94
+ }
95
+ this.busyTimeoutMs = busy;
96
+ const file = configManager.getResolvedDataPath('ngdpbase.database.file', './data/ngdpbase.db');
97
+ const key = process.env[DATABASE_KEY_ENV] ?? '';
98
+ const provider = new SqliteDatabaseProvider(file, key, DATABASE_MIGRATIONS, 'schema_migrations', { busyTimeoutMs: this.busyTimeoutMs });
99
+ if (!provider.integrityOk()) {
100
+ provider.close();
101
+ throw new Error(`The application database ${file} failed its integrity check — refusing to start (#1536)`);
102
+ }
103
+ this.provider = provider;
104
+ this.databaseFile = file;
105
+ const { applied, skipped } = provider.migrations;
106
+ logger.info(`[DatabaseManager] Opened ${file} (${key ? 'encrypted' : 'NOT encrypted'}, lock wait ${this.busyTimeoutMs} ms) — migrations applied ${applied.length}, already present ${skipped}`);
107
+ if (!key) {
108
+ logger.warn(`[DatabaseManager] ${DATABASE_KEY_ENV} is not set, so the application database is stored unencrypted (#1536)`);
109
+ }
110
+ }
111
+ /** Whether an application database is open. */
112
+ isEnabled() {
113
+ return this.provider !== null;
114
+ }
115
+ /**
116
+ * The open connection, for a row-storing provider's constructor. Throws when
117
+ * no database is configured, so a provider that needs one fails at boot with
118
+ * the key to set rather than at its first write.
119
+ */
120
+ getHandle() {
121
+ if (!this.provider) {
122
+ throw new Error("No application database is open — set ngdpbase.database.provider to 'sqlite' (#1536)");
123
+ }
124
+ return this.provider.handle;
125
+ }
126
+ /**
127
+ * Open (or join) an add-on's own database and run its migrations
128
+ * (ngdp-accounting-addons#13). The file is `<owner>.db` beside the application
129
+ * database, opened by the same provider under the same key, so it gets the
130
+ * same network-filesystem refusal, WAL, integrity check and newer-schema
131
+ * refusal. The first call for an owner opens the file; a later call — from an
132
+ * add-on that depends on the owner — adds its own ledger to the same file.
133
+ *
134
+ * Requires the application database: an operator who has not set
135
+ * `ngdpbase.database.provider` to `sqlite` has not chosen to keep a database.
136
+ *
137
+ * Opens only a declared database (#1860): an enabled add-on declares this
138
+ * owner and this ledger in `ngdpbase.addons.<slug>.database`. A declaration
139
+ * with `encrypt: "required"` is refused when `NGDPBASE_DATABASE_KEY` is not
140
+ * set; nothing is opened in the clear.
141
+ */
142
+ openAddonDatabase(owner, options) {
143
+ if (!this.provider || !this.databaseFile) {
144
+ throw new Error(`Add-on '${owner}' needs a database, but none is open — set ngdpbase.database.provider to 'sqlite' (ngdp-accounting-addons#13)`);
145
+ }
146
+ checkAddonDatabaseRequest(owner, options);
147
+ const declaration = addonDatabaseDeclarationFor(this.declarations(), owner, options.ledgerTable);
148
+ const key = process.env[DATABASE_KEY_ENV] ?? '';
149
+ const refusal = DatabaseManager.keyRefusal(declaration, key);
150
+ if (refusal)
151
+ throw new Error(refusal);
152
+ const existing = this.addonDatabases.get(owner);
153
+ if (existing) {
154
+ if (existing.ledgers.has(options.ledgerTable)) {
155
+ throw new Error(`Add-on '${owner}': migration ledger '${options.ledgerTable}' is already registered (ngdp-accounting-addons#13)`);
156
+ }
157
+ const { applied, skipped } = existing.provider.migrate(options.migrations, options.ledgerTable);
158
+ existing.ledgers.add(options.ledgerTable);
159
+ logger.info(`[DatabaseManager] ${owner}: ledger ${options.ledgerTable} — migrations applied ${applied.length}, already present ${skipped}`);
160
+ return existing.provider.handle;
161
+ }
162
+ const file = path.join(path.dirname(this.databaseFile), `${owner}.db`);
163
+ if (path.resolve(file) === path.resolve(this.databaseFile)) {
164
+ throw new Error(`Add-on '${owner}' would open the application database itself (${file}) (ngdp-accounting-addons#13)`);
165
+ }
166
+ const provider = new SqliteDatabaseProvider(file, key, options.migrations, options.ledgerTable, { busyTimeoutMs: this.busyTimeoutMs });
167
+ if (!provider.integrityOk()) {
168
+ provider.close();
169
+ throw new Error(`Add-on database ${file} failed its integrity check (ngdp-accounting-addons#13)`);
170
+ }
171
+ this.addonDatabases.set(owner, { provider, ledgers: new Set([options.ledgerTable]) });
172
+ const { applied, skipped } = provider.migrations;
173
+ logger.info(`[DatabaseManager] Opened ${file} for ${owner} (${key ? 'encrypted' : 'NOT encrypted'}) — ledger ${options.ledgerTable}, migrations applied ${applied.length}, already present ${skipped}`);
174
+ return provider.handle;
175
+ }
176
+ /**
177
+ * Every add-on database declared on this site (#1860), whether or not its
178
+ * add-on is turned on — so a turned-off add-on's file is still listed and
179
+ * backed up (#1723). One entry per declared ledger; several may share an
180
+ * owner's file.
181
+ */
182
+ getDeclaredDatabases() {
183
+ return this.declarations().map((d) => ({
184
+ ...d,
185
+ file: this.databaseFile ? path.join(path.dirname(this.databaseFile), `${d.owner}.db`) : null,
186
+ open: this.addonDatabases.get(d.owner)?.ledgers.has(d.ledgerTable) ?? false
187
+ }));
188
+ }
189
+ /**
190
+ * Why this add-on must not load, decided before it is imported (#1860): it
191
+ * declares a database `encrypt: "required"` and no key is set. Null when it
192
+ * may load. Asked by AddonsManager, as the configuration merge's refusals
193
+ * are (#1559).
194
+ */
195
+ addonRefusal(slug) {
196
+ const key = process.env[DATABASE_KEY_ENV] ?? '';
197
+ for (const declaration of this.declarations()) {
198
+ if (declaration.declaredBy !== slug || !declaration.enabled)
199
+ continue;
200
+ const refusal = DatabaseManager.keyRefusal(declaration, key);
201
+ if (refusal)
202
+ return refusal;
203
+ }
204
+ return null;
205
+ }
206
+ declarations() {
207
+ return this.engine.getManager('ConfigurationManager')?.getAddonDatabaseDeclarations?.() ?? [];
208
+ }
209
+ /** The one rule: a database declared `encrypt: "required"` is never opened without the key. */
210
+ static keyRefusal(declaration, key) {
211
+ if (declaration.encrypt !== 'required' || key)
212
+ return null;
213
+ return `Add-on '${declaration.declaredBy}' declares database '${declaration.owner}' with encrypt "required", but ${DATABASE_KEY_ENV} is not set — it is never opened unencrypted (#1860)`;
214
+ }
215
+ /** Whether every open database passes SQLite's quick check; true when none is configured. */
216
+ integrityOk() {
217
+ if (this.provider && !this.provider.integrityOk())
218
+ return false;
219
+ for (const { provider } of this.addonDatabases.values()) {
220
+ if (!provider.integrityOk())
221
+ return false;
222
+ }
223
+ return true;
224
+ }
225
+ /** Closes the add-on databases, then the application database. */
226
+ async shutdown() {
227
+ for (const { provider } of this.addonDatabases.values())
228
+ provider.close();
229
+ this.addonDatabases.clear();
230
+ this.provider?.close();
231
+ this.provider = null;
232
+ this.databaseFile = null;
233
+ await super.shutdown();
234
+ }
235
+ }
236
+ export default DatabaseManager;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * EmailManager — shared outbound email transport.
3
+ *
4
+ * A single manager used by any feature that needs to send email:
5
+ * magic-link auth, notification escalation, server-error alerts, etc.
6
+ *
7
+ * Two providers, selected by `ngdpbase.mail.provider`:
8
+ * console — prints to server log (default / development)
9
+ * smtp — sends via NodemailerMailProvider; works with any SMTP relay
10
+ * (Gmail, Resend, SendGrid, SES, self-hosted Postfix, …)
11
+ *
12
+ * Implements the MailProvider interface so it can be passed directly to
13
+ * MagicLinkAuthProvider without any changes to that class.
14
+ *
15
+ * @see docs/admin/email-setup.md for operator setup instructions
16
+ * @see {@link https://github.com/jwilleke/ngdpbase/issues/456}
17
+ */
18
+ import BaseManager from './BaseManager.js';
19
+ import type { BackupData } from './BaseManager.js';
20
+ import type { WikiEngine } from '../types/WikiEngine.js';
21
+ import type { MailMessage, MailProvider } from '../mail/MailProvider.js';
22
+ declare class EmailManager extends BaseManager implements MailProvider {
23
+ private provider;
24
+ private providerName;
25
+ private from;
26
+ private enabled;
27
+ constructor(engine: WikiEngine);
28
+ initialize(config?: Record<string, unknown>): Promise<void>;
29
+ /**
30
+ * Send an email. Injects the configured from address if the message omits it.
31
+ */
32
+ send(message: MailMessage): Promise<void>;
33
+ /**
34
+ * Convenience wrapper — build and send a message in one call.
35
+ */
36
+ sendTo(to: string, subject: string, text: string, html?: string): Promise<void>;
37
+ /** Name of the active provider: 'console' | 'smtp' */
38
+ getProviderName(): string;
39
+ /** Effective from address (smtp.from or mail.from) */
40
+ getFrom(): string;
41
+ /** Whether ngdpbase.mail.enabled is true */
42
+ isEnabled(): boolean;
43
+ shutdown(): Promise<void>;
44
+ backup(): Promise<BackupData>;
45
+ restore(_backupData: BackupData): Promise<void>;
46
+ }
47
+ export default EmailManager;
@@ -0,0 +1,129 @@
1
+ import type { ActorContext } from '../context/ActorContext.js';
2
+ import BaseManager from './BaseManager.js';
3
+ import type { WikiEngine } from '../types/WikiEngine.js';
4
+ /**
5
+ * Export file metadata interface
6
+ */
7
+ export interface ExportFileInfo {
8
+ filename: string;
9
+ path: string;
10
+ size: number;
11
+ created: Date;
12
+ modified: Date;
13
+ }
14
+ /**
15
+ * Export configuration interface
16
+ */
17
+ export interface ExportConfig extends Record<string, unknown> {
18
+ exportDirectory?: string;
19
+ }
20
+ /**
21
+ * User preferences interface (for locale support)
22
+ */
23
+ export interface UserPreferences {
24
+ locale?: string;
25
+ }
26
+ /**
27
+ * User object interface (for locale-aware formatting)
28
+ */
29
+ export interface ExportUser {
30
+ preferences?: UserPreferences;
31
+ }
32
+ /**
33
+ * Page object interface (minimal fields needed for export)
34
+ */
35
+ export interface PageForExport {
36
+ content: string;
37
+ lastModified?: string;
38
+ 'system-category'?: string;
39
+ 'user-keywords'?: string[];
40
+ name?: string;
41
+ }
42
+ declare class ExportManager extends BaseManager {
43
+ private exportDirectory;
44
+ /**
45
+ * Creates a new ExportManager instance
46
+ *
47
+ * @constructor
48
+ * @param {any} engine - The wiki engine instance
49
+ */
50
+ constructor(engine: WikiEngine);
51
+ /**
52
+ * One field of the one CSV writer for every export (RFC 4180): quoted when
53
+ * it holds a comma, quote or line break.
54
+ *
55
+ * A cell that starts with `=`, `+`, `-`, `@`, a tab or a carriage return is
56
+ * run as a formula by Excel, LibreOffice and Google Sheets ("CSV injection",
57
+ * OWASP), so a text cell starting with one gets a leading `'`. Numbers are
58
+ * written as numbers: a negative amount stays `-12550`.
59
+ *
60
+ * @param value - The cell value
61
+ * @returns The field, ready to join with commas
62
+ */
63
+ csvCell(value: unknown): string;
64
+ /**
65
+ * A header row and data rows as one CSV document, each line ending CRLF.
66
+ * Every CSV export (the audit log, add-ons) goes through here.
67
+ *
68
+ * @param headers - The header row
69
+ * @param rows - The data rows
70
+ * @returns The CSV document
71
+ */
72
+ toCsv(headers: readonly string[], rows: readonly (readonly unknown[])[]): string;
73
+ /**
74
+ * Initialize the ExportManager
75
+ *
76
+ * @async
77
+ * @param {ExportConfig} [config={}] - Configuration object
78
+ * @param {string} [config.exportDirectory] - Export directory path
79
+ * @returns {Promise<void>}
80
+ */
81
+ initialize(config?: ExportConfig): Promise<void>;
82
+ /**
83
+ * Export a single page to HTML
84
+ * @param {string} pageName - Page name to export
85
+ * @param {ExportUser|null} user - User object for locale-aware formatting
86
+ * @returns {Promise<string>} HTML content
87
+ */
88
+ exportPageToHtml(pageName: string, ctx: ActorContext, user?: ExportUser | null): Promise<string>;
89
+ /**
90
+ * Export multiple pages to a single HTML file
91
+ * @param {string[]} pageNames - Array of page names
92
+ * @param {ExportUser|null} user - User object for locale-aware formatting
93
+ * @returns {Promise<string>} Combined HTML content
94
+ */
95
+ exportPagesToHtml(pageNames: string[], ctx: ActorContext, user?: ExportUser | null): Promise<string>;
96
+ /**
97
+ * Export page(s) to markdown
98
+ * @param {string|string[]} pageNames - Single page name or array of page names
99
+ * @param {ExportUser|null} user - User object for locale-aware formatting
100
+ * @returns {Promise<string>} Markdown content
101
+ */
102
+ exportToMarkdown(pageNames: string | string[], ctx: ActorContext, user?: ExportUser | null): Promise<string>;
103
+ /**
104
+ * Save export to file
105
+ * @param {string} content - Content to save
106
+ * @param {string} filename - Filename
107
+ * @param {string} format - File format
108
+ * @returns {Promise<string>} File path
109
+ */
110
+ saveExport(content: string, filename: string, format: string): Promise<string>;
111
+ /**
112
+ * Get list of available exports
113
+ * @returns {Promise<ExportFileInfo[]>} List of export files
114
+ */
115
+ getExports(): Promise<ExportFileInfo[]>;
116
+ /**
117
+ * Delete an export file
118
+ * @param {string} filename - Export filename
119
+ * @returns {Promise<void>}
120
+ */
121
+ deleteExport(filename: string): Promise<void>;
122
+ /**
123
+ * Get formatted timestamp using user's locale
124
+ * @param {ExportUser|null} user - User object (optional)
125
+ * @returns {string} Formatted timestamp
126
+ */
127
+ getFormattedTimestamp(user?: ExportUser | null): string;
128
+ }
129
+ export default ExportManager;