@jwilleke/ngdpbase-types 0.0.0 → 5.19.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 (304) 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 +427 -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 +188 -0
  71. package/lib/src/managers/DatabaseManager.js +590 -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/sqliteBackup.d.ts +128 -0
  158. package/lib/src/providers/sqliteBackup.js +365 -0
  159. package/lib/src/providers/sqliteLocation.d.ts +17 -0
  160. package/lib/src/providers/sqliteLocation.js +55 -0
  161. package/lib/src/providers/sqliteMigrations.d.ts +48 -0
  162. package/lib/src/providers/sqliteMigrations.js +72 -0
  163. package/lib/src/rendering/githubAlerts.d.ts +22 -0
  164. package/lib/src/rendering/htmlPolicy.d.ts +76 -0
  165. package/lib/src/rendering/markdownConverter.d.ts +73 -0
  166. package/lib/src/security/PolicyDecisionPoint.d.ts +245 -0
  167. package/lib/src/security/PolicyInformationPoint.d.ts +448 -0
  168. package/lib/src/security/pageActions.d.ts +40 -0
  169. package/lib/src/security/permissions.generated.d.ts +78 -0
  170. package/lib/src/types/Asset.d.ts +414 -0
  171. package/lib/src/types/Catalog.d.ts +61 -0
  172. package/lib/src/types/Comment.d.ts +11 -0
  173. package/lib/src/types/Config.d.ts +388 -0
  174. package/lib/src/types/Organization.d.ts +78 -0
  175. package/lib/src/types/OrganizationProvider.d.ts +38 -0
  176. package/lib/src/types/Page.d.ts +220 -0
  177. package/lib/src/types/Person.d.ts +56 -0
  178. package/lib/src/types/PersonProvider.d.ts +25 -0
  179. package/lib/src/types/Policy.d.ts +139 -0
  180. package/lib/src/types/Policy.js +17 -0
  181. package/lib/src/types/Provider.d.ts +810 -0
  182. package/lib/src/types/Role.d.ts +84 -0
  183. package/lib/src/types/RoleProvider.d.ts +35 -0
  184. package/lib/src/types/Schema.d.ts +425 -0
  185. package/lib/src/types/Share.d.ts +172 -0
  186. package/lib/src/types/Share.js +81 -0
  187. package/lib/src/types/User.d.ts +304 -0
  188. package/lib/src/types/Version.d.ts +189 -0
  189. package/lib/src/types/WikiEngine.d.ts +128 -0
  190. package/lib/src/types/express.d.ts +120 -0
  191. package/lib/src/types/express.js +1 -0
  192. package/lib/src/types/guards.d.ts +78 -0
  193. package/lib/src/types/heic-decode.d.ts +16 -0
  194. package/lib/src/types/index.d.ts +19 -0
  195. package/lib/src/types/linkedom.d.ts +77 -0
  196. package/lib/src/types/markdown-it-plugins.d.ts +21 -0
  197. package/lib/src/utils/DeltaStorage.d.ts +118 -0
  198. package/lib/src/utils/LocaleUtils.d.ts +105 -0
  199. package/lib/src/utils/LocaleUtils.js +294 -0
  200. package/lib/src/utils/PageNameMatcher.d.ts +98 -0
  201. package/lib/src/utils/PathPreflight.d.ts +38 -0
  202. package/lib/src/utils/PathPreflight.js +50 -0
  203. package/lib/src/utils/SectionUtils.d.ts +40 -0
  204. package/lib/src/utils/addonConfigLayer.d.ts +144 -0
  205. package/lib/src/utils/addonConfigLayer.js +382 -0
  206. package/lib/src/utils/addonDatabaseRules.d.ts +25 -0
  207. package/lib/src/utils/addonDatabaseRules.js +57 -0
  208. package/lib/src/utils/addonHost.d.ts +51 -0
  209. package/lib/src/utils/addonHost.js +72 -0
  210. package/lib/src/utils/addonInstaller.d.ts +109 -0
  211. package/lib/src/utils/addonLock.d.ts +37 -0
  212. package/lib/src/utils/addonLock.js +48 -0
  213. package/lib/src/utils/addonPageSync.d.ts +45 -0
  214. package/lib/src/utils/addonProvenance.d.ts +48 -0
  215. package/lib/src/utils/addonTarball.d.ts +41 -0
  216. package/lib/src/utils/addonsPathResolver.d.ts +76 -0
  217. package/lib/src/utils/addonsPathResolver.js +129 -0
  218. package/lib/src/utils/assetMetadataTags.d.ts +66 -0
  219. package/lib/src/utils/atomicWrite.d.ts +28 -0
  220. package/lib/src/utils/auditConfigChange.d.ts +57 -0
  221. package/lib/src/utils/auditEventNames.d.ts +50 -0
  222. package/lib/src/utils/auditEventNames.generated.d.ts +169 -0
  223. package/lib/src/utils/auditEventNames.generated.js +174 -0
  224. package/lib/src/utils/auditEventNames.js +49 -0
  225. package/lib/src/utils/auditEvents.d.ts +265 -0
  226. package/lib/src/utils/auditEvents.js +309 -0
  227. package/lib/src/utils/auditRegistry.d.ts +102 -0
  228. package/lib/src/utils/auditRegistry.js +168 -0
  229. package/lib/src/utils/bip39English.d.ts +2 -0
  230. package/lib/src/utils/configEnvKeys.d.ts +68 -0
  231. package/lib/src/utils/configFiles.d.ts +74 -0
  232. package/lib/src/utils/configFiles.js +150 -0
  233. package/lib/src/utils/delegation.d.ts +48 -0
  234. package/lib/src/utils/deriveUsername.d.ts +21 -0
  235. package/lib/src/utils/explainMediaPath.d.ts +123 -0
  236. package/lib/src/utils/formerTitles.d.ts +69 -0
  237. package/lib/src/utils/frontmatterAccess.d.ts +54 -0
  238. package/lib/src/utils/headlessAdminPassword.d.ts +55 -0
  239. package/lib/src/utils/imageTransform.d.ts +52 -0
  240. package/lib/src/utils/instanceEnvSecret.d.ts +51 -0
  241. package/lib/src/utils/jobSlots.d.ts +43 -0
  242. package/lib/src/utils/keywordNormalizer.d.ts +127 -0
  243. package/lib/src/utils/logger.d.ts +70 -0
  244. package/lib/src/utils/logger.js +106 -0
  245. package/lib/src/utils/magicLinkDeviceState.d.ts +95 -0
  246. package/lib/src/utils/managerUtils.d.ts +40 -0
  247. package/lib/src/utils/migrateLegacyPrivateAttachments.d.ts +15 -0
  248. package/lib/src/utils/orgFilename.d.ts +22 -0
  249. package/lib/src/utils/pageFeature.d.ts +27 -0
  250. package/lib/src/utils/pageFrontmatter.d.ts +21 -0
  251. package/lib/src/utils/pageNotes.d.ts +150 -0
  252. package/lib/src/utils/pageTitleRule.d.ts +37 -0
  253. package/lib/src/utils/pageToArticle.d.ts +59 -0
  254. package/lib/src/utils/pageUrl.d.ts +18 -0
  255. package/lib/src/utils/passwordChange.d.ts +12 -0
  256. package/lib/src/utils/passwordHash.d.ts +60 -0
  257. package/lib/src/utils/permissionCatalog.d.ts +52 -0
  258. package/lib/src/utils/pluginFormatters.d.ts +452 -0
  259. package/lib/src/utils/pluginFormatters.js +714 -0
  260. package/lib/src/utils/privateLinkRewrite.d.ts +42 -0
  261. package/lib/src/utils/privateStoreAccess.d.ts +57 -0
  262. package/lib/src/utils/privateStoreAccess.js +65 -0
  263. package/lib/src/utils/privateStoreCatalogs.d.ts +40 -0
  264. package/lib/src/utils/privateStoreCrypto.d.ts +127 -0
  265. package/lib/src/utils/privateStoreDoor.d.ts +181 -0
  266. package/lib/src/utils/privateStoreExport.d.ts +72 -0
  267. package/lib/src/utils/privateStoreFiles.d.ts +120 -0
  268. package/lib/src/utils/privateStoreMeta.d.ts +64 -0
  269. package/lib/src/utils/privateStoreMigrations.d.ts +37 -0
  270. package/lib/src/utils/privateStorePath.d.ts +259 -0
  271. package/lib/src/utils/privateStorePath.js +436 -0
  272. package/lib/src/utils/privateStoreTakeout.d.ts +76 -0
  273. package/lib/src/utils/privateStoreUnlock.d.ts +175 -0
  274. package/lib/src/utils/proxyClaim.d.ts +59 -0
  275. package/lib/src/utils/proxyClaim.js +30 -0
  276. package/lib/src/utils/redactPrivateNames.d.ts +21 -0
  277. package/lib/src/utils/redactPrivateNames.js +89 -0
  278. package/lib/src/utils/redactSecrets.d.ts +58 -0
  279. package/lib/src/utils/redactSecrets.js +171 -0
  280. package/lib/src/utils/renameLinkRewrite.d.ts +112 -0
  281. package/lib/src/utils/roleGrants.d.ts +35 -0
  282. package/lib/src/utils/safeRedirect.d.ts +32 -0
  283. package/lib/src/utils/schedule.d.ts +54 -0
  284. package/lib/src/utils/secretFileMode.d.ts +17 -0
  285. package/lib/src/utils/seededShippedPages.d.ts +45 -0
  286. package/lib/src/utils/sensitiveValues.d.ts +59 -0
  287. package/lib/src/utils/sensitiveValues.js +106 -0
  288. package/lib/src/utils/sessionEnd.d.ts +12 -0
  289. package/lib/src/utils/sessionGeneration.d.ts +24 -0
  290. package/lib/src/utils/sessionIdle.d.ts +41 -0
  291. package/lib/src/utils/sessionLimits.d.ts +68 -0
  292. package/lib/src/utils/shareLockbox.d.ts +64 -0
  293. package/lib/src/utils/sigstoreTrustedRoot.d.ts +33 -0
  294. package/lib/src/utils/sniffMime.d.ts +21 -0
  295. package/lib/src/utils/storeSearchIndex.d.ts +75 -0
  296. package/lib/src/utils/subjectMayDo.d.ts +21 -0
  297. package/lib/src/utils/systemCategoryRules.d.ts +30 -0
  298. package/lib/src/utils/systemCategoryRules.js +41 -0
  299. package/lib/src/utils/userCreateError.d.ts +62 -0
  300. package/lib/src/utils/username.d.ts +53 -0
  301. package/lib/src/utils/vaultUrlRewrite.d.ts +27 -0
  302. package/lib/src/utils/version.d.ts +84 -0
  303. package/lib/src/utils/videoFrame.d.ts +21 -0
  304. package/package.json +54 -3
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `[Title]` → `[store/Title]` inside a private store (#1457, epic #1454).
3
+ *
4
+ * A private page's links were written before the syntax existed: inside
5
+ * `private/{owner}/{store}/…`, `[Diary]` was the only way to name a sibling,
6
+ * and it resolves against the PUBLIC name list — so it renders red and points
7
+ * at `/edit/Diary`. `[store/Title]` is the syntax that reaches the page
8
+ * (slice A); the one-time migration below writes it.
9
+ *
10
+ * ## What it rewrites, and what it must not
11
+ *
12
+ * Only a target that names a page in the SAME store as the page the link sits
13
+ * in. Never a title that store does not have — a link to a public page is a
14
+ * link to a public page, and pointing it into a store would break it. Never a
15
+ * cross-store target: `[other/Diary]` already parses as a private link
16
+ * ({@link parsePrivateLinkTarget}) and is left exactly as it is, which is also
17
+ * what makes a second run write nothing.
18
+ *
19
+ * ## The text half only
20
+ *
21
+ * Pure, synchronous, no engine, no I/O — the split `renameLinkRewrite`
22
+ * established. Which pages to feed it, reading them and writing the results
23
+ * are `PageManager.migratePrivateLinks`'s job.
24
+ *
25
+ * The matching rules are not restated here: this hands a resolver to
26
+ * {@link rewriteLinkTargetsBy}, so the bracket forms, the checkbox case, the
27
+ * non-page targets and the `#fragment` handling are the ones the rename
28
+ * rewrite uses, and the two cannot drift. The case rule comes with them —
29
+ * `[Title]` byte-exact, `[Display|title]` case-insensitively — for the same
30
+ * reason: in the display form the target is prose somebody wrote.
31
+ */
32
+ import { type LinkRewriteResult } from './renameLinkRewrite.js';
33
+ /**
34
+ * Point this page's `[Title]` links at the store they are already in.
35
+ *
36
+ * @param content - The private page's markdown.
37
+ * @param store - The store the page lives in; the prefix its links gain.
38
+ * @param titles - Every page title in that store.
39
+ * @returns The rewritten content and a report — the input unchanged, and
40
+ * `rewritten: 0`, when nothing in it names a page of this store.
41
+ */
42
+ export declare function rewriteToPrivateLinks(content: string, store: string, titles: Iterable<string>): LinkRewriteResult;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Who may act inside a user's private container — `pages/vaults/{user}/` and
3
+ * every vault below it (docs/private-stores.md, Access).
4
+ *
5
+ * The owner, a share link the owner issued, or someone acting for the owner
6
+ * under a proxy grant that carries `vault-proxy` (#1762). No role reaches in,
7
+ * admin included.
8
+ *
9
+ * A share link gets in only for a vault it names (#1388), and only when the
10
+ * caller names that vault: a question about the owner's container as a whole
11
+ * — their list of vaults, their trash, their takeout — is the owner's alone.
12
+ * Which pages of the vault the link may read, that it has not expired, and
13
+ * that its issuer still holds the action, are the share ceiling's to decide
14
+ * (`PolicyDecisionPoint.ceiling`), as for every share; this is only the
15
+ * container rule.
16
+ *
17
+ * An encrypted vault additionally needs a key in the session
18
+ * (`assertContextCanWriteStore`); a share link carries none until #1388's
19
+ * encrypted slices, and a proxy only the key copy its grant carries (#1762
20
+ * slice 5, `dekFor`).
21
+ *
22
+ * The container rule reads the proxy claim the subject carries; whether the
23
+ * grant is still in force is re-read live by the PDP on every decision, and
24
+ * the subject itself is rebuilt from the live grant on every request (#1762
25
+ * slice 4).
26
+ */
27
+ import { type ActorContext } from '../context/ActorContext.js';
28
+ /** The PDP surface a vault decision needs. */
29
+ export interface VaultDecider {
30
+ decide(subject: unknown, request: {
31
+ action: string;
32
+ resource: {
33
+ type: string;
34
+ id: string;
35
+ };
36
+ attributes: Record<string, unknown>;
37
+ }): Promise<{
38
+ permit: boolean;
39
+ }>;
40
+ }
41
+ export declare function mayActInPrivateContainer(ctx: ActorContext, owner: string, opts?: {
42
+ vault?: string;
43
+ }): boolean;
44
+ /**
45
+ * May `ctx` do `action` inside `owner`'s vault `vault` (#1539)? The container
46
+ * rule first — the owner, or a share link of theirs for this vault; never a
47
+ * role — then the capability asked with the vault, so a policy on the `vault`
48
+ * resource type (`vault-owner`) decides. `resource` names what is acted on (a
49
+ * vault page's name, or a file in the vault); it never matches `page: *`, so a
50
+ * site-wide role does not reach in. The one rule for vault pages
51
+ * (`BaseContext.hasPermissionOn`) and vault files (`AttachmentManager`).
52
+ */
53
+ export declare function permitsInVault(pdp: VaultDecider | null | undefined, ctx: ActorContext, action: string, where: {
54
+ owner: string;
55
+ vault: string;
56
+ resource: string;
57
+ }): Promise<boolean>;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Who may act inside a user's private container — `pages/vaults/{user}/` and
3
+ * every vault below it (docs/private-stores.md, Access).
4
+ *
5
+ * The owner, a share link the owner issued, or someone acting for the owner
6
+ * under a proxy grant that carries `vault-proxy` (#1762). No role reaches in,
7
+ * admin included.
8
+ *
9
+ * A share link gets in only for a vault it names (#1388), and only when the
10
+ * caller names that vault: a question about the owner's container as a whole
11
+ * — their list of vaults, their trash, their takeout — is the owner's alone.
12
+ * Which pages of the vault the link may read, that it has not expired, and
13
+ * that its issuer still holds the action, are the share ceiling's to decide
14
+ * (`PolicyDecisionPoint.ceiling`), as for every share; this is only the
15
+ * container rule.
16
+ *
17
+ * An encrypted vault additionally needs a key in the session
18
+ * (`assertContextCanWriteStore`); a share link carries none until #1388's
19
+ * encrypted slices, and a proxy only the key copy its grant carries (#1762
20
+ * slice 5, `dekFor`).
21
+ *
22
+ * The container rule reads the proxy claim the subject carries; whether the
23
+ * grant is still in force is re-read live by the PDP on every decision, and
24
+ * the subject itself is rebuilt from the live grant on every request (#1762
25
+ * slice 4).
26
+ */
27
+ import { isJobContext } from '../context/ActorContext.js';
28
+ import { toPermissionSubject } from '../context/JobContext.js';
29
+ import { shareNamesVault } from '../types/Share.js';
30
+ import { mixesProxyWithDelegation, proxyCarries } from './proxyClaim.js';
31
+ export function mayActInPrivateContainer(ctx, owner, opts = {}) {
32
+ if (!owner)
33
+ return false;
34
+ // #1762: a proxy's subject carries the represented person's username, so
35
+ // the owner test below would admit it unasked. It gets in only when the
36
+ // grant carries `vault-proxy`, and never alongside a token or a share.
37
+ if (ctx.viaProxy && (mixesProxyWithDelegation(ctx) || !proxyCarries(ctx.viaProxy, 'vault-proxy')))
38
+ return false;
39
+ if (ctx.viaShare) {
40
+ return opts.vault !== undefined
41
+ && ctx.viaShare.issuer === owner
42
+ && shareNamesVault(ctx.viaShare.resources, owner, opts.vault);
43
+ }
44
+ // A request must be an authenticated session of the owner: an anonymous
45
+ // visitor never matches, even a page whose recorded owner is `Anonymous`.
46
+ // A job carries who asked for it.
47
+ if (!isJobContext(ctx) && ctx.isAuthenticated !== true)
48
+ return false;
49
+ return ctx.username === owner;
50
+ }
51
+ /**
52
+ * May `ctx` do `action` inside `owner`'s vault `vault` (#1539)? The container
53
+ * rule first — the owner, or a share link of theirs for this vault; never a
54
+ * role — then the capability asked with the vault, so a policy on the `vault`
55
+ * resource type (`vault-owner`) decides. `resource` names what is acted on (a
56
+ * vault page's name, or a file in the vault); it never matches `page: *`, so a
57
+ * site-wide role does not reach in. The one rule for vault pages
58
+ * (`BaseContext.hasPermissionOn`) and vault files (`AttachmentManager`).
59
+ */
60
+ export async function permitsInVault(pdp, ctx, action, where) {
61
+ if (!pdp || !mayActInPrivateContainer(ctx, where.owner, { vault: where.vault }))
62
+ return false;
63
+ const subject = isJobContext(ctx) ? toPermissionSubject(ctx) : ctx;
64
+ return (await pdp.decide(subject, { action, resource: { type: 'page', id: where.resource }, attributes: { vault: where.vault } })).permit;
65
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The encrypted user-level page catalog (#1385, epic #1382).
3
+ *
4
+ * `user-index.json` is wrapped with the user KEK; login decrypts it into the
5
+ * process session bag. Global `page-index.json` never receives sealed-store
6
+ * titles.
7
+ *
8
+ * What is left here is a MIGRATION path, not a live index: a store keeps its
9
+ * own page index (#1456), its own search index (#1458) and its own trash
10
+ * (#1459), and `adoptUserPageCatalog` moves what this file still holds into
11
+ * them and deletes it. The sibling `user-versions.json` and `user-trash.json`
12
+ * catalogs this module also wrote were never read by anything and went with
13
+ * #1459.
14
+ */
15
+ export interface UserCatalogPage {
16
+ title: string;
17
+ uuid: string;
18
+ slug?: string;
19
+ filename?: string;
20
+ currentVersion: number;
21
+ location: 'private';
22
+ creator: string;
23
+ store: string;
24
+ lastModified: string;
25
+ created?: string;
26
+ editor: string;
27
+ author?: string;
28
+ hasVersions: boolean;
29
+ audienceRoles?: string[];
30
+ isPrivate: true;
31
+ addon?: string;
32
+ }
33
+ export interface UserCatalog {
34
+ version: 1;
35
+ pages: Record<string, UserCatalogPage>;
36
+ }
37
+ export declare function emptyUserCatalog(): UserCatalog;
38
+ export declare function readUserCatalog(pagesDirectory: string, username: string, kek: Buffer): Promise<UserCatalog>;
39
+ export declare function writeUserCatalog(pagesDirectory: string, username: string, kek: Buffer, catalog: UserCatalog): Promise<void>;
40
+ export declare function upsertUserIndexPage(pagesDirectory: string, username: string, kek: Buffer, page: UserCatalogPage): Promise<UserCatalog>;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Private-store crypto (#1384, epic #1382).
3
+ *
4
+ * Random user KEK, wrapped by the login password and by a BIP39 12-word
5
+ * phrase. Each encrypted store has its own DEK wrapped by that KEK.
6
+ * Not on PageManager — see docs/private-stores.md.
7
+ */
8
+ import { type LinkPublicKey, type Lockbox } from './shareLockbox.js';
9
+ export declare const mnemonicWordCount = 12;
10
+ export interface ScryptKdf {
11
+ N: number;
12
+ r: number;
13
+ p: number;
14
+ }
15
+ /** Production wrap cost — same ballpark as login hashes. */
16
+ export declare const PRIVATE_STORE_KDF: ScryptKdf;
17
+ /** Unit tests only — still a valid scrypt N, cheap enough for the suite. */
18
+ export declare const TEST_PRIVATE_STORE_KDF: ScryptKdf;
19
+ export interface WrappedBlob {
20
+ iv: string;
21
+ tag: string;
22
+ ct: string;
23
+ }
24
+ /**
25
+ * A person's own key pair (#1762 slice 5): what lets someone else's grant hand
26
+ * them a copy of a vault key while they are offline. The pair is the share
27
+ * lockbox's (ECDH P-256, `shareLockbox.ts`); no other crypto.
28
+ */
29
+ export interface PersonKey {
30
+ /** The public half, readable: a grant seals a copy of the owner's KEK to it. */
31
+ publicKey: LinkPublicKey;
32
+ /** The private half (the lockbox key string), wrapped under the person's own KEK. */
33
+ privateWrap: WrappedBlob;
34
+ }
35
+ export interface UserKeyEnvelope {
36
+ version: 1;
37
+ kdf: ScryptKdf & {
38
+ salt: string;
39
+ };
40
+ passwordWrap: WrappedBlob;
41
+ recoveryKdf: {
42
+ alg: 'bip39-pbkdf2';
43
+ };
44
+ recoveryWrap: WrappedBlob;
45
+ /**
46
+ * The person's key pair (#1762 slice 5). Made with the KEK at enrolment, or
47
+ * the first time the store is unlocked after this field existed; absent
48
+ * until then.
49
+ */
50
+ personKey?: PersonKey;
51
+ }
52
+ export interface EncryptedStoreRecord {
53
+ encrypt: true;
54
+ dekWrap: WrappedBlob;
55
+ }
56
+ export interface PlainStoreRecord {
57
+ encrypt: false;
58
+ }
59
+ export type StoreKeyRecord = EncryptedStoreRecord | PlainStoreRecord;
60
+ export declare function createUserKeys(password: string, opts?: {
61
+ kdf?: ScryptKdf;
62
+ }): Promise<{
63
+ envelope: UserKeyEnvelope;
64
+ kek: Buffer;
65
+ mnemonic: string;
66
+ }>;
67
+ /** A fresh key pair for a person (#1762 slice 5), its private half wrapped under their KEK. */
68
+ export declare function newPersonKey(kek: Buffer): Promise<PersonKey>;
69
+ /** The public half of a person's key pair, checked strictly; null when they have none. */
70
+ export declare function personPublicKey(envelope: UserKeyEnvelope): LinkPublicKey | null;
71
+ /**
72
+ * Seal a copy of `kek` to `recipient`'s public key (#1762 slice 5): the copy a
73
+ * proxy grant carries. Only the recipient's private key opens it.
74
+ */
75
+ export declare function sealKekCopy(recipient: LinkPublicKey, kek: Buffer): Promise<Lockbox>;
76
+ /**
77
+ * Open a KEK copy sealed to this person (#1762 slice 5): `ownKek` unwraps
78
+ * their private key from `envelope`, which opens `copy`. Throws when any step
79
+ * fails; the private key never leaves this function.
80
+ */
81
+ export declare function openKekCopy(envelope: UserKeyEnvelope, ownKek: Buffer, copy: Lockbox): Promise<Buffer>;
82
+ export declare function unwrapKekWithPassword(envelope: UserKeyEnvelope, password: string): Promise<Buffer>;
83
+ export declare function unwrapKekWithMnemonic(envelope: UserKeyEnvelope, mnemonic: string): Buffer;
84
+ /**
85
+ * A fresh set of 12 recovery words for a KEK that has not been committed yet
86
+ * (#1414): the store door's words screen, where a failed confirmation discards
87
+ * the words it showed and never re-shows them. The KEK and its password wrap
88
+ * are kept; only the recovery wrap is replaced.
89
+ */
90
+ export declare function newRecoveryWords(kek: Buffer): {
91
+ mnemonic: string;
92
+ recoveryWrap: WrappedBlob;
93
+ };
94
+ /** True when two phrases are the same 12 words, compared as the recovery wrap reads them. */
95
+ export declare function sameMnemonic(entered: string, expected: string): boolean;
96
+ export declare function rewrapPassword(envelope: UserKeyEnvelope, oldPassword: string, newPassword: string, opts?: {
97
+ kdf?: ScryptKdf;
98
+ }): Promise<UserKeyEnvelope>;
99
+ /**
100
+ * Replace the password wrap, given the KEK itself (#1452): how the recovery
101
+ * words set a new password when the old one is forgotten. The KEK bytes and
102
+ * the recovery wrap are unchanged, so every store's wrapped DEK stays valid
103
+ * and the same words keep working.
104
+ */
105
+ export declare function rewrapPasswordWithKek(envelope: UserKeyEnvelope, kek: Buffer, newPassword: string, opts?: {
106
+ kdf?: ScryptKdf;
107
+ }): Promise<UserKeyEnvelope>;
108
+ export declare function createEncryptedStore(kek: Buffer): EncryptedStoreRecord;
109
+ export declare function unwrapDek(kek: Buffer, store: EncryptedStoreRecord): Buffer;
110
+ /** Encrypt a JSON value with the user KEK (user-index / versions / trash). */
111
+ export declare function encryptJson(key: Buffer, value: unknown): WrappedBlob;
112
+ /** Decrypt a JSON value wrapped by {@link encryptJson}. */
113
+ export declare function decryptJson<T>(key: Buffer, blob: WrappedBlob): T;
114
+ /** True when `bytes` start with the sealed-file magic. */
115
+ export declare function isSealedBytes(bytes: Buffer): boolean;
116
+ /** Encrypt the bytes of one store file with the store DEK. */
117
+ export declare function sealBytes(dek: Buffer, plaintext: Buffer): Buffer;
118
+ /** Decrypt a store file written by {@link sealBytes}. */
119
+ export declare function openBytes(dek: Buffer, sealed: Buffer): Buffer;
120
+ /**
121
+ * Shared encrypt-on write gate. Callers pass the DEK from the session bag.
122
+ * Not a PageManager method.
123
+ */
124
+ export declare function assertEncryptedStoreWritable(args: {
125
+ encrypt: boolean;
126
+ dek: Buffer | undefined;
127
+ }): void;
@@ -0,0 +1,181 @@
1
+ /**
2
+ * The store door (#1414, epic #1382).
3
+ *
4
+ * A user's copy of a store kind is created when they first walk through its
5
+ * door — never at login and never mid-save. Decisions in
6
+ * docs/private-stores.md: "Recovery words: at first deliberate entry
7
+ * into the store", "The words are confirmed before anything is committed",
8
+ * "Core owns the door", "The door asks for the password when the user has no
9
+ * key", "`store.json` shape".
10
+ *
11
+ * This module holds what the door does, not how it is shown: which kinds
12
+ * exist, the words that are pending confirmation, and the commit. The route
13
+ * renders; nothing here touches HTTP.
14
+ *
15
+ * What exists only while the words screen is open lives in a process Map keyed
16
+ * by the session's private-store handle — never in express-session JSON, never
17
+ * logged, never in a record. Abandon the flow and nothing was written.
18
+ */
19
+ import { type UserKeyEnvelope } from './privateStoreCrypto.js';
20
+ import { type PrivateStoreLayout, type PrivateStoreLayoutOverrides } from './privateStorePath.js';
21
+ type GetProperty = (key: string, defaultValue: unknown) => unknown;
22
+ /**
23
+ * A vault kind (#1505): a system-category entry that declares a vault
24
+ * (`storageLocation.privatestore`). Its id is the vault id, the last folder
25
+ * of `privatestore`; `encrypt` is the entry's own. `ngdpbase.stores.{kind}`
26
+ * no longer defines kinds (operator, 2026-09-29).
27
+ */
28
+ export interface StoreKind {
29
+ id: string;
30
+ /** Whether a copy of this kind is created sealed: the system-category's `encrypt`. */
31
+ encrypt: boolean;
32
+ /**
33
+ * Who decides about this vault (operator, 2026-09-29): `admin` for the
34
+ * site's own system-categories, or the slug of the add-on that declared it.
35
+ * The owner's declaration stands — an add-on that declares its vault
36
+ * `encrypt: true` (a health-record add-on, say) keeps it sealed; nobody else
37
+ * turns that off. The system-category entry's `owner`; absent means `admin`.
38
+ */
39
+ owner: string;
40
+ }
41
+ /** The site itself, as the owner of its own vault kinds; no add-on may claim it. */
42
+ export declare const ADMIN_STORE_OWNER = "admin";
43
+ /**
44
+ * The kind named `id`, or `null` when no system-category declares that vault.
45
+ * `encrypt` is read as the boolean it is and nothing else (a string "true" is
46
+ * not a switch).
47
+ */
48
+ export declare function storeKindFromConfig(getProperty: GetProperty, id: string): StoreKind | null;
49
+ /** Where the addon that owns a kind stands, as the door needs to know it. */
50
+ export type StoreOwnerState = 'loaded' | 'failed' | 'disabled' | 'absent';
51
+ /**
52
+ * Whether a kind's door is open (#1414). A kind the site owns is always open.
53
+ * An addon's kind is open only while that addon is loaded; otherwise the kind
54
+ * and every user's copy stay exactly as they are — nothing is removed — and
55
+ * the door says why it is shut.
56
+ */
57
+ export type StoreDoorState = {
58
+ open: true;
59
+ } | {
60
+ open: false;
61
+ reason: 'unavailable' | 'disabled' | 'not-installed';
62
+ message: string;
63
+ };
64
+ export declare function storeDoorState(kind: StoreKind, ownerState: StoreOwnerState | null): StoreDoorState;
65
+ /** Every vault kind, by id: the vault each system-category declares (#1505). */
66
+ export declare function storeKindIds(allProperties: Record<string, unknown>): string[];
67
+ /**
68
+ * How many users hold a copy of a kind: whose `store.json` for it exists.
69
+ * The copy is what the door creates, so this is "who has walked through".
70
+ */
71
+ export declare function countStoreCopies(pagesDirectory: string, kindId: string, layout?: PrivateStoreLayoutOverrides): Promise<number>;
72
+ /** A vault of a sealed kind whose copy is not sealed (#1834). */
73
+ export interface UnsealedVault {
74
+ owner: string;
75
+ vault: string;
76
+ /** `unopened`: files but no `store.json`; `mismatch`: a `store.json` that is not sealed. */
77
+ state: 'unopened' | 'mismatch';
78
+ }
79
+ /**
80
+ * Every vault of a sealed kind that holds files in the clear (#1834): a folder
81
+ * with something in it but no `store.json` (written before its door was
82
+ * opened), or a `store.json` that is not sealed. Read only — nothing is moved,
83
+ * sealed or deleted; what to do with the files is an administrator's call.
84
+ */
85
+ export declare function findUnsealedVaults(pagesDirectory: string, layout: PrivateStoreLayout): Promise<UnsealedVault[]>;
86
+ /** A sealed vault holding files that are not sealed (#1836). */
87
+ export interface PlaintextInSealedVault {
88
+ owner: string;
89
+ vault: string;
90
+ /** How many files in it are not sealed bytes. */
91
+ files: number;
92
+ /** Where they are: the vault's own folders (`versions`, `attachments`, …), `.` for its root. */
93
+ areas: string[];
94
+ }
95
+ /**
96
+ * Every sealed vault (its `store.json` says `encrypt: true`) that holds files
97
+ * in the clear (#1836): a page's history moved in with `fs.move`, an
98
+ * attachment adopted without its I/O, a backup restored from before the vault
99
+ * was sealed. A sealed file starts with the `sealBytes` magic, so each file's
100
+ * first bytes tell them apart without the key. `store.json` is the one file
101
+ * that is never sealed; an empty file holds nothing and is not counted.
102
+ *
103
+ * Read only — nothing is moved, sealed or deleted; what to do with the files
104
+ * is an administrator's call. Vaults that are not sealed at all are
105
+ * {@link findUnsealedVaults}'s.
106
+ */
107
+ export declare function findPlaintextInSealedVaults(pagesDirectory: string, layout: PrivateStoreLayout): Promise<PlaintextInSealedVault[]>;
108
+ /** Attempts at confirming the words: one, plus `ngdpbase.stores.recovery.confirmretries`. */
109
+ export declare function confirmAttempts(getProperty: GetProperty): number;
110
+ /**
111
+ * Hold a new user KEK and its words while the user writes them down. Replaces
112
+ * anything this session had pending: starting over is always allowed.
113
+ */
114
+ export declare function holdWordsForConfirmation(handle: string, args: {
115
+ username: string;
116
+ store: string;
117
+ kek: Buffer;
118
+ envelope: UserKeyEnvelope;
119
+ mnemonic: string;
120
+ attempts: number;
121
+ }): void;
122
+ /** Whether this session is part-way through the words screen for `store`. */
123
+ export declare function hasPendingWords(handle: string, username: string, store: string): boolean;
124
+ export type ConfirmOutcome = {
125
+ status: 'confirmed';
126
+ kek: Buffer;
127
+ envelope: UserKeyEnvelope;
128
+ } | {
129
+ status: 'retry';
130
+ mnemonic: string;
131
+ attemptsLeft: number;
132
+ } | {
133
+ status: 'exhausted';
134
+ } | {
135
+ status: 'none';
136
+ };
137
+ /**
138
+ * Check the words the user typed back. A match hands over the KEK and envelope
139
+ * to commit and forgets the words. A miss discards the words it showed — they
140
+ * are never shown again — and, while attempts remain, makes a new set for the
141
+ * same uncommitted KEK. No attempts left: everything is forgotten and nothing
142
+ * was ever written.
143
+ */
144
+ export declare function confirmWords(handle: string, username: string, store: string, entered: string): ConfirmOutcome;
145
+ /** Logout, or a new login in this session: nothing pending survives it. */
146
+ export declare function dropPendingWords(handle: string): void;
147
+ /** Test teardown only. */
148
+ export declare function clearPendingWords(): void;
149
+ /** Whether `username` already has a copy of `store` — the door is then just a way in. */
150
+ export declare function storeCopyExists(args: {
151
+ pagesDirectory: string;
152
+ username: string;
153
+ store: string;
154
+ layout?: PrivateStoreLayoutOverrides;
155
+ }): Promise<boolean>;
156
+ /** Whether `username` has a user KEK on disk. */
157
+ export declare function userKeysExist(args: {
158
+ pagesDirectory: string;
159
+ username: string;
160
+ layout?: PrivateStoreLayoutOverrides;
161
+ }): Promise<boolean>;
162
+ /**
163
+ * Write the user's copy of a store kind: `user-keys.json` first when this
164
+ * commit creates the user's KEK, then `store.json` — each written only if it
165
+ * does not exist yet. Returns the store DEK for a sealed copy, so the caller
166
+ * can put it in the session that walked through the door.
167
+ */
168
+ export declare function commitStoreCopy(args: {
169
+ pagesDirectory: string;
170
+ username: string;
171
+ kind: StoreKind;
172
+ /** The user KEK — required for a sealed copy. */
173
+ kek?: Buffer;
174
+ /** The new envelope, when this commit creates the user's KEK. */
175
+ newEnvelope?: UserKeyEnvelope;
176
+ layout?: PrivateStoreLayoutOverrides;
177
+ now?: Date;
178
+ }): Promise<{
179
+ dek?: Buffer;
180
+ }>;
181
+ export {};
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Building a person's takeout of their own private store (#1387).
3
+ *
4
+ * The decisions this implements, all recorded on #1387:
5
+ *
6
+ * - **It is decrypted.** There is one form of takeout, and it is readable.
7
+ * Someone who leaves with their data can open it in any text editor on the
8
+ * laptop or phone they downloaded it to.
9
+ * - **It is a copy you can read, not a copy you can pour back.** Pages under
10
+ * their real titles and attachments under the names they were uploaded
11
+ * with; no `versions/`, no `deleted/`, none of the store's indexes, and no
12
+ * `user-keys.json` — a wrapped key guards nothing that is not already in
13
+ * the clear beside it. Restoring a store as it was is the instance
14
+ * backup's job, which does it better by keeping the encryption.
15
+ * - **Full frontmatter is kept.** Title, uuid, author, timestamps, keywords.
16
+ * It stays perfectly readable, and the uuid is what lets a later import
17
+ * (#1472) recognise a page as the same page rather than duplicating it.
18
+ * - **The store's `files-index.json` is kept** (operator, 2026-09-25,
19
+ * revising the list above). It is the one "index" that is content: pages
20
+ * reference files as `/attachments/{id}`, and nothing else maps an id to
21
+ * its file or holds its description, author and dates. Each record's
22
+ * `fileName` is rewritten to the file's path in the archive, so an import
23
+ * (#1472) can find every entry and keep every link.
24
+ * - **Nothing decrypted is written to the server's disk.** Everything here
25
+ * returns bytes in memory for the caller to stream.
26
+ *
27
+ * Reading goes through `storeFileIO`, which hands back plain or sealed I/O and
28
+ * REFUSES an encrypted store whose key this context does not hold. A locked
29
+ * store therefore throws rather than quietly producing an archive of
30
+ * ciphertext or of nothing at all — a takeout that looks like it worked and
31
+ * cannot be read is worse than an error.
32
+ */
33
+ import { type PrivateStoreLayout } from './privateStorePath.js';
34
+ import type { ActorContext } from '../context/ActorContext.js';
35
+ /** One file of the takeout, ready for a packer. */
36
+ export type TakeoutFile = {
37
+ /** Path inside the archive, `/`-separated. */
38
+ path: string;
39
+ bytes: Buffer;
40
+ mtime: Date;
41
+ };
42
+ export type TakeoutOptions = {
43
+ pagesDirectory: string;
44
+ owner: string;
45
+ store: string;
46
+ /** Leave the attachments out — someone who wants their writing, not gigabytes of photos. */
47
+ pagesOnly?: boolean;
48
+ layout: PrivateStoreLayout;
49
+ };
50
+ /**
51
+ * Name of the file index inside a takeout, beside the pages.
52
+ *
53
+ * Fixed rather than read from the store layout: a takeout is carried to other
54
+ * instances, whose layout may name the on-disk index differently.
55
+ */
56
+ export declare const TAKEOUT_FILE_INDEX = "files-index.json";
57
+ export type Takeout = {
58
+ owner: string;
59
+ store: string;
60
+ files: TakeoutFile[];
61
+ pageCount: number;
62
+ attachmentCount: number;
63
+ totalBytes: number;
64
+ };
65
+ /**
66
+ * Build a takeout of one store.
67
+ *
68
+ * Throws when the store is encrypted and `ctx` does not hold its key — the
69
+ * caller turns that into "unlock your store first", never into an empty
70
+ * archive.
71
+ */
72
+ export declare function buildStoreTakeout(ctx: ActorContext, options: TakeoutOptions): Promise<Takeout>;