@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,436 @@
1
+ /**
2
+ * Private-store paths (#1383, epic #1382).
3
+ *
4
+ * On-disk join (law): resolved pages `storagedir` + `privateroot` + userid + storeid + file.
5
+ * That is `{pagesDirectory}/{privateroot}/{user}/{store}/…` — a segment under the
6
+ * existing pages directory (SLOW), not `${SLOW_STORAGE}/private` and not FAST_STORAGE.
7
+ * User catalogs (`user-index.json` and siblings) live in that same user dir.
8
+ *
9
+ * Helpers take an optional layout override so unit tests need no live engine.
10
+ *
11
+ * ## What a store holds, and where these names are set
12
+ *
13
+ * A store is self-contained: everything about its pages is inside it, so a
14
+ * takeout is "copy this directory" and nothing of it sits in a shared index.
15
+ *
16
+ * ```
17
+ * private/{user}/user-keys.json the user's wrapped keys (#1414)
18
+ * private/{user}/user-index.json legacy: read once at unlock, then removed (#1385, #1456)
19
+ * private/{user}/{store}/store.json this store: its kind, encrypt, wrapped DEK (#1414)
20
+ * private/{user}/{store}/pages-index.json its pages (#1456)
21
+ * private/{user}/{store}/files-index.json its files (#1400)
22
+ * private/{user}/{store}/search-index.json its saved search index (#1458)
23
+ * private/{user}/{store}/deleted-index.json its trash (#1459)
24
+ * private/{user}/{store}/migrations.json the one-time migrations it has had (#1457)
25
+ * private/{user}/{store}/{uuid}.md a page
26
+ * private/{user}/{store}/versions/{uuid}/ that page's history
27
+ * private/{user}/{store}/deleted/{uuid}.md a deleted page, until it is purged
28
+ * private/{user}/{store}/attachments/ its files (#1400)
29
+ * private/{user}/{store}/footnotes/{uuid}.json a page's footnotes (#1839)
30
+ * private/{user}/{store}/comments/{uuid}/ a page's comments (#1839)
31
+ * ```
32
+ *
33
+ * Every one of those names is DEFINED HERE, in
34
+ * {@link DEFAULT_PRIVATE_STORE_LAYOUT} — not in `config/app-default-config.json`.
35
+ * They are a disk convention this code owns, not a setting anyone tunes. An
36
+ * instance that must override one may still set the matching
37
+ * `ngdpbase.page.provider.filesystem.private.files.*` key (see
38
+ * {@link privateStoreLayoutFromConfig}); the default it overrides lives here.
39
+ *
40
+ * Every file but `store.json` is written through the store's `StoreFileIO`, so
41
+ * it is ciphertext at rest exactly when the store is encrypted. `store.json` is
42
+ * the one that cannot be: it holds the wrapped key needed to open the rest.
43
+ */
44
+ import path from 'path';
45
+ export const DEFAULT_PRIVATE_STORE_LAYOUT = {
46
+ privateRoot: 'vaults',
47
+ defaultStoreId: 'default',
48
+ versionsDir: 'versions',
49
+ deletedDir: 'deleted',
50
+ attachmentsDir: 'attachments',
51
+ footnotesDir: 'footnotes',
52
+ commentsDir: 'comments',
53
+ files: {
54
+ userkeys: 'user-keys.json',
55
+ userindex: 'user-index.json',
56
+ storemeta: 'store.json',
57
+ storefiles: 'files-index.json',
58
+ storepages: 'pages-index.json',
59
+ storesearch: 'search-index.json',
60
+ storemigrations: 'migrations.json',
61
+ storedeleted: 'deleted-index.json'
62
+ },
63
+ sealedVaults: []
64
+ };
65
+ export const DEFAULT_PRIVATE_STORE = DEFAULT_PRIVATE_STORE_LAYOUT.defaultStoreId;
66
+ export const STORE_META_FILENAME = DEFAULT_PRIVATE_STORE_LAYOUT.files.storemeta;
67
+ export function resolvePrivateStoreLayout(overrides) {
68
+ if (!overrides)
69
+ return DEFAULT_PRIVATE_STORE_LAYOUT;
70
+ return {
71
+ privateRoot: overrides.privateRoot ?? DEFAULT_PRIVATE_STORE_LAYOUT.privateRoot,
72
+ defaultStoreId: overrides.defaultStoreId ?? DEFAULT_PRIVATE_STORE_LAYOUT.defaultStoreId,
73
+ versionsDir: overrides.versionsDir ?? DEFAULT_PRIVATE_STORE_LAYOUT.versionsDir,
74
+ deletedDir: overrides.deletedDir ?? DEFAULT_PRIVATE_STORE_LAYOUT.deletedDir,
75
+ attachmentsDir: overrides.attachmentsDir ?? DEFAULT_PRIVATE_STORE_LAYOUT.attachmentsDir,
76
+ footnotesDir: overrides.footnotesDir ?? DEFAULT_PRIVATE_STORE_LAYOUT.footnotesDir,
77
+ commentsDir: overrides.commentsDir ?? DEFAULT_PRIVATE_STORE_LAYOUT.commentsDir,
78
+ files: {
79
+ ...DEFAULT_PRIVATE_STORE_LAYOUT.files,
80
+ ...overrides.files
81
+ },
82
+ sealedVaults: overrides.sealedVaults ?? DEFAULT_PRIVATE_STORE_LAYOUT.sealedVaults
83
+ };
84
+ }
85
+ /** The user-level catalog filenames from layout (not a second hardcoded list). */
86
+ export function privateUserCatalogFiles(layout) {
87
+ const files = resolvePrivateStoreLayout(layout).files;
88
+ return new Set([files.userkeys, files.userindex]);
89
+ }
90
+ export const PRIVATE_USER_CATALOG_FILES = privateUserCatalogFiles();
91
+ /**
92
+ * A system-category's vault, read from its `storageLocation.privatestore`
93
+ * (#1504): `pages/vaults/{user}/journal/` → `{ root: 'vaults', vaultId: 'journal' }`.
94
+ * The shape is fixed — `pages/`, the vaults' parent folder, the `{user}`
95
+ * placeholder, the vault id — and `null` for anything else, so a malformed
96
+ * entry never names a folder.
97
+ */
98
+ export function parsePrivatestore(value) {
99
+ if (typeof value !== 'string')
100
+ return null;
101
+ const parts = value.replace(/\/$/, '').split('/');
102
+ if (parts.length !== 4 || parts[0] !== 'pages' || parts[2] !== '{user}')
103
+ return null;
104
+ const [, root, , vaultId] = parts;
105
+ if (!isSafePathSegment(root) || !isValidStoreId(vaultId))
106
+ return null;
107
+ return { root, vaultId };
108
+ }
109
+ /** The entries of `ngdpbase.system-category` that declare a vault, in config order. */
110
+ export function systemCategoryVaults(categories) {
111
+ if (!categories || typeof categories !== 'object')
112
+ return [];
113
+ const vaults = [];
114
+ for (const [key, entry] of Object.entries(categories)) {
115
+ const e = entry;
116
+ const parsed = parsePrivatestore(e?.storageLocation?.privatestore);
117
+ // `encrypt` is read as the boolean it is and nothing else: a string "true" is not a switch.
118
+ if (parsed)
119
+ vaults.push({ key, ...parsed, isDefault: e?.default === true, encrypt: e?.encrypt === true });
120
+ }
121
+ return vaults;
122
+ }
123
+ /**
124
+ * The vault ids whose kind is sealed (#1834). Where two entries name the
125
+ * same vault, the first is the kind, as `storeKindFromConfig` reads it.
126
+ */
127
+ function sealedVaultIds(vaults) {
128
+ const seen = new Set();
129
+ const sealed = [];
130
+ for (const v of vaults) {
131
+ if (seen.has(v.vaultId))
132
+ continue;
133
+ seen.add(v.vaultId);
134
+ if (v.encrypt)
135
+ sealed.push(v.vaultId);
136
+ }
137
+ return sealed;
138
+ }
139
+ export function privateStoreLayoutFromConfig(getProperty) {
140
+ const str = (key, fallback) => {
141
+ const value = getProperty(key, fallback);
142
+ return typeof value === 'string' && value.length > 0 ? value : fallback;
143
+ };
144
+ const d = DEFAULT_PRIVATE_STORE_LAYOUT;
145
+ // #1504: where the vaults live, and which one is a person's ordinary vault,
146
+ // are said once — by the system-category entries' privatestore — not by
147
+ // settings of their own. Startup refuses entries that disagree on the parent
148
+ // (ValidationManager), so the first vault's parent is every vault's.
149
+ const vaults = systemCategoryVaults(getProperty('ngdpbase.system-category', ''));
150
+ return {
151
+ privateRoot: vaults[0]?.root ?? d.privateRoot,
152
+ defaultStoreId: vaults.find((v) => v.isDefault)?.vaultId ?? d.defaultStoreId,
153
+ versionsDir: str('ngdpbase.page.provider.filesystem.versionsdir', d.versionsDir),
154
+ deletedDir: str('ngdpbase.page.provider.filesystem.deleteddir', d.deletedDir),
155
+ attachmentsDir: str('ngdpbase.page.provider.filesystem.attachmentsdir', d.attachmentsDir),
156
+ footnotesDir: str('ngdpbase.page.provider.filesystem.footnotesdir', d.footnotesDir),
157
+ commentsDir: str('ngdpbase.page.provider.filesystem.commentsdir', d.commentsDir),
158
+ files: {
159
+ userkeys: str('ngdpbase.page.provider.filesystem.private.files.userkeys', d.files.userkeys),
160
+ userindex: str('ngdpbase.page.provider.filesystem.private.files.userindex', d.files.userindex),
161
+ storemeta: str('ngdpbase.page.provider.filesystem.private.files.storemeta', d.files.storemeta),
162
+ storefiles: str('ngdpbase.page.provider.filesystem.private.files.storefiles', d.files.storefiles),
163
+ storepages: str('ngdpbase.page.provider.filesystem.private.files.storepages', d.files.storepages),
164
+ storesearch: str('ngdpbase.page.provider.filesystem.private.files.storesearch', d.files.storesearch),
165
+ storemigrations: str('ngdpbase.page.provider.filesystem.private.files.storemigrations', d.files.storemigrations),
166
+ storedeleted: str('ngdpbase.page.provider.filesystem.private.files.storedeleted', d.files.storedeleted)
167
+ },
168
+ sealedVaults: sealedVaultIds(vaults)
169
+ };
170
+ }
171
+ /** A store id is a plain slug — an addon slug or `default` — never a path (#1383). */
172
+ const STORE_ID_SOURCE = '[a-z0-9]+(?:-[a-z0-9]+)*';
173
+ const STORE_ID_PATTERN = new RegExp(`^${STORE_ID_SOURCE}$`);
174
+ export function isValidStoreId(store) {
175
+ return STORE_ID_PATTERN.test(store);
176
+ }
177
+ /**
178
+ * A private page's name (#1456, operator 2026-09-22): `vaults/{owner}/{store}/{title}` —
179
+ * the same string as its URL without the leading slash. Wherever the system
180
+ * passes a page name, a private page is named this way; a plain title always
181
+ * means a public page. Titles never contain `/` (#1455), so the parts are
182
+ * unambiguous. Was `private/` until #1506.
183
+ */
184
+ export const PRIVATE_PAGE_NAME_PREFIX = 'vaults/';
185
+ /** The first path segment of a private page's URL: `/vaults/{owner}/{store}/{title}`. */
186
+ export const PRIVATE_URL_SEGMENT = PRIVATE_PAGE_NAME_PREFIX.slice(0, -1);
187
+ /**
188
+ * The vault parent folder, page-name prefix and URL segment before #1506
189
+ * (operator, 2026-09-28): `pages/private/`, `private/{owner}/{store}/{title}`,
190
+ * `/private/…`. Read only by the one-time move to `vaults` and by the things
191
+ * that must never mistake a leftover `private/` folder for public pages.
192
+ */
193
+ export const LEGACY_PRIVATE_ROOT = 'private';
194
+ /**
195
+ * The reserved start of a private page's slug: `vaults--{owner}-{vault}-{title}`.
196
+ * No public slug contains `--`, so the two can never collide. Was `private--`
197
+ * until #1507 (operator, 2026-09-29), for the same reason the page name moved
198
+ * from `private/` to `vaults/` in #1506.
199
+ */
200
+ export const PRIVATE_SLUG_PREFIX = 'vaults--';
201
+ export function formatPrivatePageName(owner, store, title) {
202
+ return `${PRIVATE_PAGE_NAME_PREFIX}${owner}/${store}/${title}`;
203
+ }
204
+ /** The parts of a private page name, or null when `name` is not one. */
205
+ export function parsePrivatePageName(name) {
206
+ if (typeof name !== 'string' || !name.startsWith(PRIVATE_PAGE_NAME_PREFIX))
207
+ return null;
208
+ const parts = name.slice(PRIVATE_PAGE_NAME_PREFIX.length).split('/');
209
+ if (parts.length !== 3)
210
+ return null;
211
+ const [owner, store, title] = parts;
212
+ if (!owner || !isSafePathSegment(owner) || !isValidStoreId(store) || !title.trim())
213
+ return null;
214
+ return { owner, store, title };
215
+ }
216
+ /**
217
+ * The name a page an identifier opened is known by: its title — the
218
+ * identifier may be a uuid or slug, and every downstream index is keyed by
219
+ * title — or, for a vault page, its vault name (#1539). A vault page's bare
220
+ * title is a PUBLIC page's name, so the door would judge, and a write would
221
+ * hit, a different page.
222
+ */
223
+ export function canonicalPageName(identifier, metadata) {
224
+ const privateName = parsePrivatePageName(identifier);
225
+ return privateName
226
+ ? formatPrivatePageName(privateName.owner, privateName.store, metadata?.title || privateName.title)
227
+ : metadata?.title || identifier;
228
+ }
229
+ /**
230
+ * A private page's LINK target, written inside brackets as `{store}/{Title}`
231
+ * (#1457). The store belongs to the owner of the page the link sits in, so the
232
+ * target names no user — {@link formatPrivatePageName} supplies the owner.
233
+ *
234
+ * `null` for anything else, including a target whose first segment is not a
235
+ * store id (`Docs/Setup`) and one with a second `/`: titles never contain one
236
+ * (#1455), so a deeper path is not a private page.
237
+ */
238
+ export function parsePrivateLinkTarget(target) {
239
+ const slash = target.indexOf('/');
240
+ if (slash <= 0)
241
+ return null;
242
+ const store = target.slice(0, slash);
243
+ const title = target.slice(slash + 1);
244
+ if (!isValidStoreId(store) || !title.trim() || title.includes('/'))
245
+ return null;
246
+ return { store, title };
247
+ }
248
+ /**
249
+ * Could this content hold a `[store/Title]` link? A cheap pre-test so only a
250
+ * page that may carry one pays for the owner lookup a render needs (#1457).
251
+ * Non-global, so it is stateless and safe to share.
252
+ */
253
+ const PRIVATE_LINK_CANDIDATE = new RegExp(`\\[(?:[^|\\]\\n]*\\|)?${STORE_ID_SOURCE}/[^\\]\\n]+\\]`);
254
+ export function mayContainPrivateLink(content) {
255
+ return PRIVATE_LINK_CANDIDATE.test(content);
256
+ }
257
+ /** Refuse a store id that is not a plain slug. Every join below runs it. */
258
+ export function assertStoreId(store) {
259
+ if (!isValidStoreId(store)) {
260
+ throw new Error(`Invalid private store id ${JSON.stringify(store)}: must be a lowercase slug`);
261
+ }
262
+ return store;
263
+ }
264
+ /**
265
+ * A user folder or file name is exactly one path segment. Usernames have no
266
+ * enforced shape, so this refuses only what could leave the folder: empty,
267
+ * `.`, `..`, a separator, or NUL.
268
+ */
269
+ export function isSafePathSegment(segment) {
270
+ return segment.length > 0 && segment !== '.' && segment !== '..' && !/[/\\\0]/.test(segment);
271
+ }
272
+ export function assertPathSegment(segment, what) {
273
+ if (!isSafePathSegment(segment)) {
274
+ throw new Error(`Invalid private store ${what} ${JSON.stringify(segment)}: must be one path segment`);
275
+ }
276
+ return segment;
277
+ }
278
+ function pageBasename(uuidOrBasename) {
279
+ return assertPathSegment(uuidOrBasename.endsWith('.md') ? uuidOrBasename : `${uuidOrBasename}.md`, 'file name');
280
+ }
281
+ export function privatePageFilePath(pagesDirectory, creator, uuidOrBasename, store, layout) {
282
+ const L = resolvePrivateStoreLayout(layout);
283
+ const storeId = store ?? L.defaultStoreId;
284
+ return path.join(pagesDirectory, L.privateRoot, assertPathSegment(creator, 'user'), assertStoreId(storeId), pageBasename(uuidOrBasename));
285
+ }
286
+ export function privateUserDir(pagesDirectory, username, layout) {
287
+ return path.join(pagesDirectory, resolvePrivateStoreLayout(layout).privateRoot, assertPathSegment(username, 'user'));
288
+ }
289
+ export function privateUserKeysPath(pagesDirectory, username, layout) {
290
+ const L = resolvePrivateStoreLayout(layout);
291
+ return path.join(privateUserDir(pagesDirectory, username, L), L.files.userkeys);
292
+ }
293
+ export function privateUserIndexPath(pagesDirectory, username, layout) {
294
+ const L = resolvePrivateStoreLayout(layout);
295
+ return path.join(privateUserDir(pagesDirectory, username, L), L.files.userindex);
296
+ }
297
+ export function privateStoreRoot(pagesDirectory, creator, store, layout) {
298
+ const L = resolvePrivateStoreLayout(layout);
299
+ return path.join(privateUserDir(pagesDirectory, creator, L), assertStoreId(store ?? L.defaultStoreId));
300
+ }
301
+ /**
302
+ * Folder for a store's non-page files: `{privateroot}/{user}/{store}/{attachmentsdir}` (#1386).
303
+ * Never the store root — an uploaded `.md` there would scan as a page.
304
+ */
305
+ export function privateStoreAttachmentsDir(pagesDirectory, creator, store, layout) {
306
+ const L = resolvePrivateStoreLayout(layout);
307
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.attachmentsDir);
308
+ }
309
+ /** Non-page file in `{privateroot}/{user}/{store}/{attachmentsdir}/{file}` (#1386). */
310
+ export function privateStoreFilePath(pagesDirectory, creator, fileName, store, layout) {
311
+ return path.join(privateStoreAttachmentsDir(pagesDirectory, creator, store, layout), assertPathSegment(fileName, 'file name'));
312
+ }
313
+ /**
314
+ * True when `relParts` (path relative to the pages directory, split) names a
315
+ * store's attachments folder: `{privateroot}/{user}/{store}/{attachmentsdir}`.
316
+ * Depth-checked so a user or store that happens to be called `attachments` is not skipped.
317
+ */
318
+ export function isPrivateStoreAttachmentsRel(relParts, layout) {
319
+ const L = resolvePrivateStoreLayout(layout);
320
+ return relParts.length === 4 && relParts[0] === L.privateRoot && relParts[3] === L.attachmentsDir;
321
+ }
322
+ export function storeMetaPath(pagesDirectory, creator, store, layout) {
323
+ const L = resolvePrivateStoreLayout(layout);
324
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.files.storemeta);
325
+ }
326
+ /** A store's own file index: `{privateroot}/{user}/{store}/{storefiles}` (#1400). */
327
+ export function storeFileIndexPath(pagesDirectory, creator, store, layout) {
328
+ const L = resolvePrivateStoreLayout(layout);
329
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.files.storefiles);
330
+ }
331
+ /** A store's own page index: `{privateroot}/{user}/{store}/{storepages}` (#1456). */
332
+ export function storePageIndexPath(pagesDirectory, creator, store, layout) {
333
+ const L = resolvePrivateStoreLayout(layout);
334
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.files.storepages);
335
+ }
336
+ /** A store's own saved search index: `{privateroot}/{user}/{store}/{storesearch}` (#1458). */
337
+ export function storeSearchIndexPath(pagesDirectory, creator, store, layout) {
338
+ const L = resolvePrivateStoreLayout(layout);
339
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.files.storesearch);
340
+ }
341
+ /**
342
+ * A store's own trash record: `{privateroot}/{user}/{store}/{storedeleted}` (#1459).
343
+ *
344
+ * Beside the store's other indexes, so it is sealed exactly when the store is
345
+ * and travels with it — a deleted private page leaves no trace outside its own
346
+ * store, not in the global trash and not in `page-index.json`.
347
+ */
348
+ export function storeDeletedIndexPath(pagesDirectory, creator, store, layout) {
349
+ const L = resolvePrivateStoreLayout(layout);
350
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.files.storedeleted);
351
+ }
352
+ /** A store's record of the one-time migrations it has had (#1457). */
353
+ export function storeMigrationsPath(pagesDirectory, creator, store, layout) {
354
+ const L = resolvePrivateStoreLayout(layout);
355
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.files.storemigrations);
356
+ }
357
+ export function privateVersionDirectory(pagesDirectory, creator, uuid, store, layout) {
358
+ const L = resolvePrivateStoreLayout(layout);
359
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.versionsDir, assertPathSegment(uuid, 'page id'));
360
+ }
361
+ /**
362
+ * Where a vault page's footnotes or comments are kept (#1839): a folder of
363
+ * the vault, `{privateroot}/{user}/{store}/{footnotesDir|commentsDir}`, so
364
+ * they are written through the vault's store I/O and sealed exactly when its
365
+ * pages are. A public page's are in the managers' own folders.
366
+ */
367
+ export function privateStoreNotesDir(pagesDirectory, creator, store, kind, layout) {
368
+ const L = resolvePrivateStoreLayout(layout);
369
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), kind === 'footnotes' ? L.footnotesDir : L.commentsDir);
370
+ }
371
+ export function privateDeletedDirectory(pagesDirectory, creator, store, layout) {
372
+ const L = resolvePrivateStoreLayout(layout);
373
+ return path.join(privateStoreRoot(pagesDirectory, creator, store, L), L.deletedDir);
374
+ }
375
+ /** Pre-#1383 live file: `{pages}/{privateroot}/{user}/{file}.md`. */
376
+ export function legacyPrivatePageFilePath(pagesDirectory, creator, uuidOrBasename, layout) {
377
+ return path.join(privateUserDir(pagesDirectory, creator, layout), pageBasename(uuidOrBasename));
378
+ }
379
+ /** Legacy `pages/versions/private` = join(versionsdir, privateroot). No extra key. */
380
+ export function legacyPrivateVersionsRoot(pagesDirectory, layout) {
381
+ const L = resolvePrivateStoreLayout(layout);
382
+ return path.join(pagesDirectory, L.versionsDir, L.privateRoot);
383
+ }
384
+ /**
385
+ * True when `filePath` is inside the private root of `pagesDirectory`. Measured
386
+ * from the pages directory, not by searching the absolute path for `/private/`
387
+ * — which matched every page on a host whose data sits under `/private/var`
388
+ * or `/private/tmp` (macOS).
389
+ */
390
+ export function pathContainsPrivateRoot(pagesDirectory, filePath, layout) {
391
+ return isUnderPrivateRoot(path.relative(pagesDirectory, filePath).split(path.sep), layout);
392
+ }
393
+ /**
394
+ * Relative path from the pages directory, split on the platform separator.
395
+ * `{privateroot}/{user}/{store}/{file}.md` → store layout.
396
+ * `{privateroot}/{user}/{file}.md` → legacy layout (pre-#1383).
397
+ *
398
+ * `null` for anything else, including a store folder whose name is not a valid
399
+ * store id. A caller that finds `null` for a path under the private root must
400
+ * skip the file, never treat it as a public page ({@link isUnderPrivateRoot}).
401
+ */
402
+ export function parsePrivatePageRel(relParts, layout) {
403
+ const L = resolvePrivateStoreLayout(layout);
404
+ if (relParts[0] !== L.privateRoot)
405
+ return null;
406
+ const last = relParts[relParts.length - 1];
407
+ if (!last || !last.toLowerCase().endsWith('.md'))
408
+ return null;
409
+ if (!isSafePathSegment(relParts[1] ?? ''))
410
+ return null;
411
+ if (relParts.length === 4) {
412
+ return isValidStoreId(relParts[2]) ? { creator: relParts[1], store: relParts[2] } : null;
413
+ }
414
+ if (relParts.length === 3) {
415
+ return { creator: relParts[1], store: L.defaultStoreId };
416
+ }
417
+ return null;
418
+ }
419
+ /**
420
+ * The store that holds a file at any depth — the live page, a version blob,
421
+ * a trash record or an attachment: `{privateroot}/{user}/{store}/…`. `null`
422
+ * for a file that is not inside a store, including the user-level catalogues
423
+ * beside the stores (#1415).
424
+ */
425
+ export function parsePrivateStoreRel(relParts, layout) {
426
+ const L = resolvePrivateStoreLayout(layout);
427
+ if (relParts.length < 4 || relParts[0] !== L.privateRoot)
428
+ return null;
429
+ if (!isSafePathSegment(relParts[1]) || !isValidStoreId(relParts[2]))
430
+ return null;
431
+ return { creator: relParts[1], store: relParts[2] };
432
+ }
433
+ /** True when a path relative to the pages directory is inside the private root. */
434
+ export function isUnderPrivateRoot(relParts, layout) {
435
+ return relParts[0] === resolvePrivateStoreLayout(layout).privateRoot;
436
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Reading a private store back out, byte for byte (#1387, epic #1382).
3
+ *
4
+ * Two features need the same thing and must not grow two answers to it:
5
+ *
6
+ * - the instance backup, which copies every store so a disk failure is
7
+ * survivable, and
8
+ * - a user's own download, which is how someone leaves with their data.
9
+ *
10
+ * What they share is this module: walk a store directory and hand back every
11
+ * file in it as bytes. Packaging and permission are the callers' business.
12
+ *
13
+ * ## Bytes, never text
14
+ *
15
+ * `FileSystemProvider.backup()` reads pages with an encoding, which is right
16
+ * for a public page and destroys a private one: a sealed store's `.md` files
17
+ * are ciphertext, and decoding them as UTF-8 substitutes U+FFFD for every byte
18
+ * that is not valid UTF-8. The file would still be in the backup, and would
19
+ * still look like a file, and would never decrypt again.
20
+ *
21
+ * So everything here is `Buffer`. A caller that wants text can decode what it
22
+ * knows to be text; nothing in this module ever does.
23
+ *
24
+ * ## The whole store, including its keys
25
+ *
26
+ * A store is self-contained by design (see `privateStorePath`), so a takeout is
27
+ * "copy this directory" — pages, their versions, the trash, the attachments and
28
+ * every index. The user's `user-keys.json` is copied too, deliberately: it is a
29
+ * WRAPPED key, useless without the password or the twelve words, and without it
30
+ * a restored sealed store could never be opened again by anyone, including its
31
+ * owner. Copying the wrapped key does not make the copier a keyholder.
32
+ */
33
+ import { type PrivateStoreLayoutOverrides } from './privateStorePath.js';
34
+ /** One file of a store, exactly as it sits on disk. */
35
+ export type StoreFile = {
36
+ /** Path relative to what was walked, with `/` separators on every platform. */
37
+ path: string;
38
+ /** The file's bytes. Ciphertext stays ciphertext. */
39
+ bytes: Buffer;
40
+ /** Last-modified time, so a restore can preserve it. */
41
+ mtime: Date;
42
+ };
43
+ /** A store found on disk, and everything in it. */
44
+ export type StoreTakeout = {
45
+ owner: string;
46
+ store: string;
47
+ /** Files of the store directory itself, relative to the store root. */
48
+ files: StoreFile[];
49
+ /** Total bytes, for a caller that wants to refuse an unreasonable download. */
50
+ totalBytes: number;
51
+ };
52
+ /**
53
+ * Every file of one store, as bytes.
54
+ *
55
+ * Returns an empty file list when the store does not exist, so a caller can ask
56
+ * about a store without first proving it is there.
57
+ */
58
+ export declare function collectStore(pagesDirectory: string, owner: string, store: string, layout?: PrivateStoreLayoutOverrides): Promise<StoreTakeout>;
59
+ /** The store ids a user has on disk, in directory order. */
60
+ export declare function listStoreIds(pagesDirectory: string, owner: string, layout?: PrivateStoreLayoutOverrides): Promise<string[]>;
61
+ /** The users who have a private directory on disk, in directory order. */
62
+ export declare function listPrivateOwners(pagesDirectory: string, layout?: PrivateStoreLayoutOverrides): Promise<string[]>;
63
+ /**
64
+ * Everything one user keeps privately: each of their stores, plus the files
65
+ * that sit at the user level beside them (`user-keys.json` and any legacy
66
+ * catalogue still there).
67
+ *
68
+ * This is the unit both callers work in — an instance backup asks for it once
69
+ * per owner, and a user's own download asks for it once, for themselves.
70
+ */
71
+ export declare function collectUser(pagesDirectory: string, owner: string, layout?: PrivateStoreLayoutOverrides): Promise<{
72
+ owner: string;
73
+ userFiles: StoreFile[];
74
+ stores: StoreTakeout[];
75
+ totalBytes: number;
76
+ }>;