@fgv/ts-extras 5.1.0-4 → 5.1.0-40

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 (368) hide show
  1. package/dist/index.browser.js +4 -2
  2. package/dist/index.browser.js.map +1 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/packlets/ai-assist/apiClient.js +886 -158
  5. package/dist/packlets/ai-assist/apiClient.js.map +1 -0
  6. package/dist/packlets/ai-assist/chatRequestBuilders.js +282 -0
  7. package/dist/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  8. package/dist/packlets/ai-assist/converters.js +47 -3
  9. package/dist/packlets/ai-assist/converters.js.map +1 -0
  10. package/dist/packlets/ai-assist/embeddingClient.js +345 -0
  11. package/dist/packlets/ai-assist/embeddingClient.js.map +1 -0
  12. package/dist/packlets/ai-assist/endpoint.js +78 -0
  13. package/dist/packlets/ai-assist/endpoint.js.map +1 -0
  14. package/dist/packlets/ai-assist/http.js +75 -0
  15. package/dist/packlets/ai-assist/http.js.map +1 -0
  16. package/dist/packlets/ai-assist/imageOptionsResolver.js +193 -0
  17. package/dist/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
  18. package/dist/packlets/ai-assist/index.js +10 -4
  19. package/dist/packlets/ai-assist/index.js.map +1 -0
  20. package/dist/packlets/ai-assist/jsonCompletion.js +93 -0
  21. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -0
  22. package/dist/packlets/ai-assist/jsonResponse.js +149 -0
  23. package/dist/packlets/ai-assist/jsonResponse.js.map +1 -0
  24. package/dist/packlets/ai-assist/model.js +193 -9
  25. package/dist/packlets/ai-assist/model.js.map +1 -0
  26. package/dist/packlets/ai-assist/registry.js +314 -12
  27. package/dist/packlets/ai-assist/registry.js.map +1 -0
  28. package/dist/packlets/ai-assist/sseParser.js +123 -0
  29. package/dist/packlets/ai-assist/sseParser.js.map +1 -0
  30. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +368 -0
  31. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  32. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +687 -0
  33. package/dist/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
  34. package/dist/packlets/ai-assist/streamingAdapters/common.js +187 -0
  35. package/dist/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  36. package/dist/packlets/ai-assist/streamingAdapters/gemini.js +204 -0
  37. package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  38. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js +170 -0
  39. package/dist/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  40. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js +386 -0
  41. package/dist/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  42. package/dist/packlets/ai-assist/streamingAdapters/proxy.js +173 -0
  43. package/dist/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  44. package/dist/packlets/ai-assist/streamingClient.js +140 -0
  45. package/dist/packlets/ai-assist/streamingClient.js.map +1 -0
  46. package/dist/packlets/ai-assist/thinkingOptionsResolver.js +288 -0
  47. package/dist/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
  48. package/dist/packlets/ai-assist/toolFormats.js +106 -10
  49. package/dist/packlets/ai-assist/toolFormats.js.map +1 -0
  50. package/dist/packlets/conversion/converters.js +35 -1
  51. package/dist/packlets/conversion/converters.js.map +1 -0
  52. package/dist/packlets/conversion/index.js.map +1 -0
  53. package/dist/packlets/crypto-utils/constants.js.map +1 -0
  54. package/dist/packlets/crypto-utils/converters.js +42 -4
  55. package/dist/packlets/crypto-utils/converters.js.map +1 -0
  56. package/dist/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  57. package/dist/packlets/crypto-utils/encryptedFile.js.map +1 -0
  58. package/dist/packlets/crypto-utils/hpkeProvider.js +333 -0
  59. package/dist/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  60. package/dist/packlets/crypto-utils/index.browser.js +10 -2
  61. package/dist/packlets/crypto-utils/index.browser.js.map +1 -0
  62. package/dist/packlets/crypto-utils/index.js +6 -0
  63. package/dist/packlets/crypto-utils/index.js.map +1 -0
  64. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +71 -0
  65. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  66. package/dist/packlets/crypto-utils/keystore/converters.js +103 -11
  67. package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -0
  68. package/dist/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js +287 -0
  69. package/dist/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js.map +1 -0
  70. package/dist/packlets/crypto-utils/keystore/index.browser.js +36 -0
  71. package/dist/packlets/crypto-utils/keystore/index.browser.js.map +1 -0
  72. package/dist/packlets/crypto-utils/keystore/index.js +3 -0
  73. package/dist/packlets/crypto-utils/keystore/index.js.map +1 -0
  74. package/dist/packlets/crypto-utils/keystore/keyStore.js +633 -118
  75. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  76. package/dist/packlets/crypto-utils/keystore/model.js +22 -1
  77. package/dist/packlets/crypto-utils/keystore/model.js.map +1 -0
  78. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js +21 -0
  79. package/dist/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  80. package/dist/packlets/crypto-utils/model.js +32 -0
  81. package/dist/packlets/crypto-utils/model.js.map +1 -0
  82. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +270 -1
  83. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  84. package/dist/packlets/crypto-utils/spkiHelpers.js +209 -0
  85. package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  86. package/dist/packlets/csv/csvFileHelpers.js +0 -14
  87. package/dist/packlets/csv/csvFileHelpers.js.map +1 -0
  88. package/dist/packlets/csv/csvHelpers.js +14 -0
  89. package/dist/packlets/csv/csvHelpers.js.map +1 -0
  90. package/dist/packlets/csv/index.browser.js +1 -3
  91. package/dist/packlets/csv/index.browser.js.map +1 -0
  92. package/dist/packlets/csv/index.js.map +1 -0
  93. package/dist/packlets/experimental/extendedArray.js.map +1 -0
  94. package/dist/packlets/experimental/formatter.js.map +1 -0
  95. package/dist/packlets/experimental/index.js.map +1 -0
  96. package/dist/packlets/experimental/rangeOf.js.map +1 -0
  97. package/dist/packlets/hash/index.browser.js.map +1 -0
  98. package/dist/packlets/hash/index.js.map +1 -0
  99. package/dist/packlets/hash/index.node.js.map +1 -0
  100. package/dist/packlets/hash/md5Normalizer.browser.js.map +1 -0
  101. package/dist/packlets/hash/md5Normalizer.js.map +1 -0
  102. package/dist/packlets/mustache/index.js.map +1 -0
  103. package/dist/packlets/mustache/interfaces.js.map +1 -0
  104. package/dist/packlets/mustache/mustacheTemplate.js +42 -4
  105. package/dist/packlets/mustache/mustacheTemplate.js.map +1 -0
  106. package/dist/packlets/record-jar/index.browser.js +1 -3
  107. package/dist/packlets/record-jar/index.browser.js.map +1 -0
  108. package/dist/packlets/record-jar/index.js.map +1 -0
  109. package/dist/packlets/record-jar/recordJarFileHelpers.js +0 -18
  110. package/dist/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  111. package/dist/packlets/record-jar/recordJarHelpers.js +18 -0
  112. package/dist/packlets/record-jar/recordJarHelpers.js.map +1 -0
  113. package/dist/packlets/yaml/converters.js.map +1 -0
  114. package/dist/packlets/yaml/index.js +1 -0
  115. package/dist/packlets/yaml/index.js.map +1 -0
  116. package/dist/packlets/yaml/serializers.js +48 -0
  117. package/dist/packlets/yaml/serializers.js.map +1 -0
  118. package/dist/packlets/zip-file-tree/index.js.map +1 -0
  119. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  120. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  121. package/dist/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  122. package/dist/ts-extras.d.ts +3880 -105
  123. package/dist/tsdoc-metadata.json +1 -1
  124. package/lib/index.browser.d.ts +4 -2
  125. package/lib/index.browser.d.ts.map +1 -0
  126. package/lib/index.browser.js +8 -3
  127. package/lib/index.browser.js.map +1 -0
  128. package/lib/index.d.ts.map +1 -0
  129. package/lib/index.js.map +1 -0
  130. package/lib/packlets/ai-assist/apiClient.d.ts +115 -32
  131. package/lib/packlets/ai-assist/apiClient.d.ts.map +1 -0
  132. package/lib/packlets/ai-assist/apiClient.js +888 -156
  133. package/lib/packlets/ai-assist/apiClient.js.map +1 -0
  134. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts +149 -0
  135. package/lib/packlets/ai-assist/chatRequestBuilders.d.ts.map +1 -0
  136. package/lib/packlets/ai-assist/chatRequestBuilders.js +293 -0
  137. package/lib/packlets/ai-assist/chatRequestBuilders.js.map +1 -0
  138. package/lib/packlets/ai-assist/converters.d.ts +15 -1
  139. package/lib/packlets/ai-assist/converters.d.ts.map +1 -0
  140. package/lib/packlets/ai-assist/converters.js +47 -3
  141. package/lib/packlets/ai-assist/converters.js.map +1 -0
  142. package/lib/packlets/ai-assist/embeddingClient.d.ts +69 -0
  143. package/lib/packlets/ai-assist/embeddingClient.d.ts.map +1 -0
  144. package/lib/packlets/ai-assist/embeddingClient.js +349 -0
  145. package/lib/packlets/ai-assist/embeddingClient.js.map +1 -0
  146. package/lib/packlets/ai-assist/endpoint.d.ts +28 -0
  147. package/lib/packlets/ai-assist/endpoint.d.ts.map +1 -0
  148. package/lib/packlets/ai-assist/endpoint.js +82 -0
  149. package/lib/packlets/ai-assist/endpoint.js.map +1 -0
  150. package/lib/packlets/ai-assist/http.d.ts +24 -0
  151. package/lib/packlets/ai-assist/http.d.ts.map +1 -0
  152. package/lib/packlets/ai-assist/http.js +78 -0
  153. package/lib/packlets/ai-assist/http.js.map +1 -0
  154. package/lib/packlets/ai-assist/imageOptionsResolver.d.ts +66 -0
  155. package/lib/packlets/ai-assist/imageOptionsResolver.d.ts.map +1 -0
  156. package/lib/packlets/ai-assist/imageOptionsResolver.js +197 -0
  157. package/lib/packlets/ai-assist/imageOptionsResolver.js.map +1 -0
  158. package/lib/packlets/ai-assist/index.d.ts +10 -4
  159. package/lib/packlets/ai-assist/index.d.ts.map +1 -0
  160. package/lib/packlets/ai-assist/index.js +36 -1
  161. package/lib/packlets/ai-assist/index.js.map +1 -0
  162. package/lib/packlets/ai-assist/jsonCompletion.d.ts +93 -0
  163. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -0
  164. package/lib/packlets/ai-assist/jsonCompletion.js +97 -0
  165. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -0
  166. package/lib/packlets/ai-assist/jsonResponse.d.ts +91 -0
  167. package/lib/packlets/ai-assist/jsonResponse.d.ts.map +1 -0
  168. package/lib/packlets/ai-assist/jsonResponse.js +154 -0
  169. package/lib/packlets/ai-assist/jsonResponse.js.map +1 -0
  170. package/lib/packlets/ai-assist/model.d.ts +1202 -12
  171. package/lib/packlets/ai-assist/model.d.ts.map +1 -0
  172. package/lib/packlets/ai-assist/model.js +198 -10
  173. package/lib/packlets/ai-assist/model.js.map +1 -0
  174. package/lib/packlets/ai-assist/registry.d.ts +56 -1
  175. package/lib/packlets/ai-assist/registry.d.ts.map +1 -0
  176. package/lib/packlets/ai-assist/registry.js +319 -13
  177. package/lib/packlets/ai-assist/registry.js.map +1 -0
  178. package/lib/packlets/ai-assist/sseParser.d.ts +45 -0
  179. package/lib/packlets/ai-assist/sseParser.d.ts.map +1 -0
  180. package/lib/packlets/ai-assist/sseParser.js +128 -0
  181. package/lib/packlets/ai-assist/sseParser.js.map +1 -0
  182. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts +72 -0
  183. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -0
  184. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +371 -0
  185. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -0
  186. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts +260 -0
  187. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.d.ts.map +1 -0
  188. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js +694 -0
  189. package/lib/packlets/ai-assist/streamingAdapters/clientToolContinuationBuilder.js.map +1 -0
  190. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts +154 -0
  191. package/lib/packlets/ai-assist/streamingAdapters/common.d.ts.map +1 -0
  192. package/lib/packlets/ai-assist/streamingAdapters/common.js +193 -0
  193. package/lib/packlets/ai-assist/streamingAdapters/common.js.map +1 -0
  194. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts +43 -0
  195. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -0
  196. package/lib/packlets/ai-assist/streamingAdapters/gemini.js +207 -0
  197. package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -0
  198. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts +19 -0
  199. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.d.ts.map +1 -0
  200. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js +173 -0
  201. package/lib/packlets/ai-assist/streamingAdapters/openaiChat.js.map +1 -0
  202. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts +33 -0
  203. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.d.ts.map +1 -0
  204. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js +389 -0
  205. package/lib/packlets/ai-assist/streamingAdapters/openaiResponses.js.map +1 -0
  206. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts +34 -0
  207. package/lib/packlets/ai-assist/streamingAdapters/proxy.d.ts.map +1 -0
  208. package/lib/packlets/ai-assist/streamingAdapters/proxy.js +176 -0
  209. package/lib/packlets/ai-assist/streamingAdapters/proxy.js.map +1 -0
  210. package/lib/packlets/ai-assist/streamingClient.d.ts +50 -0
  211. package/lib/packlets/ai-assist/streamingClient.d.ts.map +1 -0
  212. package/lib/packlets/ai-assist/streamingClient.js +146 -0
  213. package/lib/packlets/ai-assist/streamingClient.js.map +1 -0
  214. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts +87 -0
  215. package/lib/packlets/ai-assist/thinkingOptionsResolver.d.ts.map +1 -0
  216. package/lib/packlets/ai-assist/thinkingOptionsResolver.js +294 -0
  217. package/lib/packlets/ai-assist/thinkingOptionsResolver.js.map +1 -0
  218. package/lib/packlets/ai-assist/toolFormats.d.ts +40 -9
  219. package/lib/packlets/ai-assist/toolFormats.d.ts.map +1 -0
  220. package/lib/packlets/ai-assist/toolFormats.js +107 -10
  221. package/lib/packlets/ai-assist/toolFormats.js.map +1 -0
  222. package/lib/packlets/conversion/converters.d.ts +8 -1
  223. package/lib/packlets/conversion/converters.d.ts.map +1 -0
  224. package/lib/packlets/conversion/converters.js +36 -2
  225. package/lib/packlets/conversion/converters.js.map +1 -0
  226. package/lib/packlets/conversion/index.d.ts.map +1 -0
  227. package/lib/packlets/conversion/index.js.map +1 -0
  228. package/lib/packlets/crypto-utils/constants.d.ts.map +1 -0
  229. package/lib/packlets/crypto-utils/constants.js.map +1 -0
  230. package/lib/packlets/crypto-utils/converters.d.ts +20 -1
  231. package/lib/packlets/crypto-utils/converters.d.ts.map +1 -0
  232. package/lib/packlets/crypto-utils/converters.js +43 -5
  233. package/lib/packlets/crypto-utils/converters.js.map +1 -0
  234. package/lib/packlets/crypto-utils/directEncryptionProvider.d.ts.map +1 -0
  235. package/lib/packlets/crypto-utils/directEncryptionProvider.js.map +1 -0
  236. package/lib/packlets/crypto-utils/encryptedFile.d.ts.map +1 -0
  237. package/lib/packlets/crypto-utils/encryptedFile.js.map +1 -0
  238. package/lib/packlets/crypto-utils/hpkeProvider.d.ts +142 -0
  239. package/lib/packlets/crypto-utils/hpkeProvider.d.ts.map +1 -0
  240. package/lib/packlets/crypto-utils/hpkeProvider.js +337 -0
  241. package/lib/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  242. package/lib/packlets/crypto-utils/index.browser.d.ts +4 -1
  243. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -0
  244. package/lib/packlets/crypto-utils/index.browser.js +21 -3
  245. package/lib/packlets/crypto-utils/index.browser.js.map +1 -0
  246. package/lib/packlets/crypto-utils/index.d.ts +3 -0
  247. package/lib/packlets/crypto-utils/index.d.ts.map +1 -0
  248. package/lib/packlets/crypto-utils/index.js +17 -1
  249. package/lib/packlets/crypto-utils/index.js.map +1 -0
  250. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +54 -0
  251. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts.map +1 -0
  252. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +74 -0
  253. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -0
  254. package/lib/packlets/crypto-utils/keystore/converters.d.ts +68 -6
  255. package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -0
  256. package/lib/packlets/crypto-utils/keystore/converters.js +101 -9
  257. package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -0
  258. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.d.ts +148 -0
  259. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.d.ts.map +1 -0
  260. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js +324 -0
  261. package/lib/packlets/crypto-utils/keystore/encryptedFilePrivateKeyStorage.js.map +1 -0
  262. package/lib/packlets/crypto-utils/keystore/index.browser.d.ts +10 -0
  263. package/lib/packlets/crypto-utils/keystore/index.browser.d.ts.map +1 -0
  264. package/lib/packlets/crypto-utils/keystore/index.browser.js +76 -0
  265. package/lib/packlets/crypto-utils/keystore/index.browser.js.map +1 -0
  266. package/lib/packlets/crypto-utils/keystore/index.d.ts +2 -0
  267. package/lib/packlets/crypto-utils/keystore/index.d.ts.map +1 -0
  268. package/lib/packlets/crypto-utils/keystore/index.js +5 -1
  269. package/lib/packlets/crypto-utils/keystore/index.js.map +1 -0
  270. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +205 -13
  271. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -0
  272. package/lib/packlets/crypto-utils/keystore/keyStore.js +639 -124
  273. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -0
  274. package/lib/packlets/crypto-utils/keystore/model.d.ts +275 -19
  275. package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -0
  276. package/lib/packlets/crypto-utils/keystore/model.js +24 -2
  277. package/lib/packlets/crypto-utils/keystore/model.js.map +1 -0
  278. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts +53 -0
  279. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.d.ts.map +1 -0
  280. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js +22 -0
  281. package/lib/packlets/crypto-utils/keystore/privateKeyStorage.js.map +1 -0
  282. package/lib/packlets/crypto-utils/model.d.ts +348 -10
  283. package/lib/packlets/crypto-utils/model.d.ts.map +1 -0
  284. package/lib/packlets/crypto-utils/model.js +33 -1
  285. package/lib/packlets/crypto-utils/model.js.map +1 -0
  286. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +110 -2
  287. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -0
  288. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +269 -0
  289. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -0
  290. package/lib/packlets/crypto-utils/spkiHelpers.d.ts +110 -0
  291. package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -0
  292. package/lib/packlets/crypto-utils/spkiHelpers.js +219 -0
  293. package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  294. package/lib/packlets/csv/csvFileHelpers.d.ts +0 -10
  295. package/lib/packlets/csv/csvFileHelpers.d.ts.map +1 -0
  296. package/lib/packlets/csv/csvFileHelpers.js +0 -15
  297. package/lib/packlets/csv/csvFileHelpers.js.map +1 -0
  298. package/lib/packlets/csv/csvHelpers.d.ts +10 -0
  299. package/lib/packlets/csv/csvHelpers.d.ts.map +1 -0
  300. package/lib/packlets/csv/csvHelpers.js +15 -0
  301. package/lib/packlets/csv/csvHelpers.js.map +1 -0
  302. package/lib/packlets/csv/index.browser.d.ts +0 -1
  303. package/lib/packlets/csv/index.browser.d.ts.map +1 -0
  304. package/lib/packlets/csv/index.browser.js +1 -5
  305. package/lib/packlets/csv/index.browser.js.map +1 -0
  306. package/lib/packlets/csv/index.d.ts.map +1 -0
  307. package/lib/packlets/csv/index.js.map +1 -0
  308. package/lib/packlets/experimental/extendedArray.d.ts.map +1 -0
  309. package/lib/packlets/experimental/extendedArray.js.map +1 -0
  310. package/lib/packlets/experimental/formatter.d.ts.map +1 -0
  311. package/lib/packlets/experimental/formatter.js.map +1 -0
  312. package/lib/packlets/experimental/index.d.ts.map +1 -0
  313. package/lib/packlets/experimental/index.js.map +1 -0
  314. package/lib/packlets/experimental/rangeOf.d.ts.map +1 -0
  315. package/lib/packlets/experimental/rangeOf.js.map +1 -0
  316. package/lib/packlets/hash/index.browser.d.ts.map +1 -0
  317. package/lib/packlets/hash/index.browser.js.map +1 -0
  318. package/lib/packlets/hash/index.d.ts.map +1 -0
  319. package/lib/packlets/hash/index.js.map +1 -0
  320. package/lib/packlets/hash/index.node.d.ts.map +1 -0
  321. package/lib/packlets/hash/index.node.js.map +1 -0
  322. package/lib/packlets/hash/md5Normalizer.browser.d.ts.map +1 -0
  323. package/lib/packlets/hash/md5Normalizer.browser.js.map +1 -0
  324. package/lib/packlets/hash/md5Normalizer.d.ts.map +1 -0
  325. package/lib/packlets/hash/md5Normalizer.js.map +1 -0
  326. package/lib/packlets/mustache/index.d.ts +1 -1
  327. package/lib/packlets/mustache/index.d.ts.map +1 -0
  328. package/lib/packlets/mustache/index.js.map +1 -0
  329. package/lib/packlets/mustache/interfaces.d.ts +34 -0
  330. package/lib/packlets/mustache/interfaces.d.ts.map +1 -0
  331. package/lib/packlets/mustache/interfaces.js.map +1 -0
  332. package/lib/packlets/mustache/mustacheTemplate.d.ts +2 -0
  333. package/lib/packlets/mustache/mustacheTemplate.d.ts.map +1 -0
  334. package/lib/packlets/mustache/mustacheTemplate.js +42 -4
  335. package/lib/packlets/mustache/mustacheTemplate.js.map +1 -0
  336. package/lib/packlets/record-jar/index.browser.d.ts +0 -1
  337. package/lib/packlets/record-jar/index.browser.d.ts.map +1 -0
  338. package/lib/packlets/record-jar/index.browser.js +1 -5
  339. package/lib/packlets/record-jar/index.browser.js.map +1 -0
  340. package/lib/packlets/record-jar/index.d.ts.map +1 -0
  341. package/lib/packlets/record-jar/index.js.map +1 -0
  342. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts +0 -11
  343. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts.map +1 -0
  344. package/lib/packlets/record-jar/recordJarFileHelpers.js +0 -19
  345. package/lib/packlets/record-jar/recordJarFileHelpers.js.map +1 -0
  346. package/lib/packlets/record-jar/recordJarHelpers.d.ts +11 -0
  347. package/lib/packlets/record-jar/recordJarHelpers.d.ts.map +1 -0
  348. package/lib/packlets/record-jar/recordJarHelpers.js +19 -0
  349. package/lib/packlets/record-jar/recordJarHelpers.js.map +1 -0
  350. package/lib/packlets/yaml/converters.d.ts.map +1 -0
  351. package/lib/packlets/yaml/converters.js.map +1 -0
  352. package/lib/packlets/yaml/index.d.ts +1 -0
  353. package/lib/packlets/yaml/index.d.ts.map +1 -0
  354. package/lib/packlets/yaml/index.js +1 -0
  355. package/lib/packlets/yaml/index.js.map +1 -0
  356. package/lib/packlets/yaml/serializers.d.ts +45 -0
  357. package/lib/packlets/yaml/serializers.d.ts.map +1 -0
  358. package/lib/packlets/yaml/serializers.js +84 -0
  359. package/lib/packlets/yaml/serializers.js.map +1 -0
  360. package/lib/packlets/zip-file-tree/index.d.ts.map +1 -0
  361. package/lib/packlets/zip-file-tree/index.js.map +1 -0
  362. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +2 -2
  363. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts.map +1 -0
  364. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +2 -2
  365. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -0
  366. package/lib/packlets/zip-file-tree/zipFileTreeWriter.d.ts.map +1 -0
  367. package/lib/packlets/zip-file-tree/zipFileTreeWriter.js.map +1 -0
  368. package/package.json +20 -15
@@ -1,4 +1,5 @@
1
1
  import { Conversion, Converter, Result } from '@fgv/ts-utils';
2
+ import { DateTime } from 'luxon';
2
3
  import { ExtendedArray, RangeOf, RangeOfProperties } from '../experimental';
3
4
  /**
4
5
  * Helper function to create a `StringConverter` which converts
@@ -17,13 +18,19 @@ export declare function templateString(defaultContext?: unknown): Conversion.Str
17
18
  * @public
18
19
  */
19
20
  export declare const isoDate: Converter<Date, unknown>;
21
+ /**
22
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
23
+ * a `DateTime` object.
24
+ * @public
25
+ */
26
+ export declare const isoDateTime: Converter<DateTime, unknown>;
20
27
  /**
21
28
  * A helper function to create a `Converter` which converts `unknown` to {@link Experimental.ExtendedArray | ExtendedArray<T>}.
22
29
  * @remarks
23
30
  * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
24
31
  * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
25
32
  * @param converter - `Converter` used to convert each item in the array
26
- * @param ignoreErrors - Specifies treatment of unconvertible elements
33
+ * @param onError - Specifies treatment of unconvertible elements
27
34
  * @beta
28
35
  */
29
36
  export declare function extendedArrayOf<T, TC = undefined>(label: string, converter: Converter<T, TC>, onError?: Conversion.OnError): Converter<ExtendedArray<T>, TC>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/conversion/converters.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAc,MAAM,EAAgC,MAAM,eAAe,CAAC;AACxG,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE5E;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAWpG;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,CAkB3C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,QAAQ,EAAE,OAAO,CAqBpD,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,EAAE,GAAG,SAAS,EAC/C,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAC3B,OAAO,GAAE,UAAU,CAAC,OAAuB,GAC1C,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAIjC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,SAAS,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,EAChE,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAC3B,WAAW,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC,GACtD,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAcnB;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAE/F"}
@@ -24,7 +24,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
24
  return (mod && mod.__esModule) ? mod : { "default": mod };
25
25
  };
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.isoDate = void 0;
27
+ exports.isoDateTime = exports.isoDate = void 0;
28
28
  exports.templateString = templateString;
29
29
  exports.extendedArrayOf = extendedArrayOf;
30
30
  exports.rangeTypeOf = rangeTypeOf;
@@ -70,15 +70,49 @@ exports.isoDate = new ts_utils_1.Conversion.BaseConverter((from) => {
70
70
  else if (from instanceof Date) {
71
71
  return (0, ts_utils_1.succeed)(from);
72
72
  }
73
+ else if (from instanceof luxon_1.DateTime) {
74
+ if (from.isValid) {
75
+ return (0, ts_utils_1.succeed)(from.toJSDate());
76
+ }
77
+ return (0, ts_utils_1.fail)(`Invalid date: ${from.invalidExplanation}`);
78
+ }
73
79
  return (0, ts_utils_1.fail)(`Cannot convert ${JSON.stringify(from)} to Date`);
74
80
  });
81
+ /**
82
+ * A `Converter` which converts an iso formatted string, a number or a `Date` object to
83
+ * a `DateTime` object.
84
+ * @public
85
+ */
86
+ exports.isoDateTime = new ts_utils_1.Conversion.BaseConverter((from) => {
87
+ if (typeof from === 'string') {
88
+ const dt = luxon_1.DateTime.fromISO(from);
89
+ if (dt.isValid) {
90
+ return (0, ts_utils_1.succeed)(dt);
91
+ }
92
+ return (0, ts_utils_1.fail)(`Invalid date: ${dt.invalidExplanation}`);
93
+ }
94
+ else if (typeof from === 'number') {
95
+ return (0, ts_utils_1.succeed)(luxon_1.DateTime.fromMillis(from));
96
+ /* c8 ignore next 3 - Date instance path not exercised in current test suite */
97
+ }
98
+ else if (from instanceof Date) {
99
+ return (0, ts_utils_1.succeed)(luxon_1.DateTime.fromJSDate(from));
100
+ }
101
+ else if (from instanceof luxon_1.DateTime) {
102
+ if (from.isValid) {
103
+ return (0, ts_utils_1.succeed)(from);
104
+ }
105
+ return (0, ts_utils_1.fail)(`Invalid date: ${from.invalidExplanation}`);
106
+ }
107
+ return (0, ts_utils_1.fail)(`Cannot convert ${JSON.stringify(from)} to DateTime`);
108
+ });
75
109
  /**
76
110
  * A helper function to create a `Converter` which converts `unknown` to {@link Experimental.ExtendedArray | ExtendedArray<T>}.
77
111
  * @remarks
78
112
  * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot
79
113
  * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.
80
114
  * @param converter - `Converter` used to convert each item in the array
81
- * @param ignoreErrors - Specifies treatment of unconvertible elements
115
+ * @param onError - Specifies treatment of unconvertible elements
82
116
  * @beta
83
117
  */
84
118
  function extendedArrayOf(label, converter, onError = 'failOnError') {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/conversion/converters.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2020 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Conversion, Converter, Converters, Result, captureResult, fail, succeed } from '@fgv/ts-utils';\nimport { DateTime } from 'luxon';\nimport Mustache from 'mustache';\nimport { ExtendedArray, RangeOf, RangeOfProperties } from '../experimental';\n\n/**\n * Helper function to create a `StringConverter` which converts\n * `unknown` to `string`, applying template conversions supplied at construction time or at\n * runtime as context.\n * @remarks\n * Template conversions are applied using `mustache` syntax.\n * @param defaultContext - Optional default context to use for template values.\n * @returns A new `Converter` returning `string`.\n * @public\n */\nexport function templateString(defaultContext?: unknown): Conversion.StringConverter<string, unknown> {\n return new Conversion.StringConverter<string, unknown>(\n defaultContext,\n undefined,\n (from: unknown, __self: Converter<string, unknown>, context?: unknown) => {\n if (typeof from !== 'string') {\n return fail(`Not a string: ${JSON.stringify(from)}`);\n }\n return captureResult(() => Mustache.render(from, context));\n }\n );\n}\n\n/**\n * A `Converter` which converts an iso formatted string, a number or a `Date` object to\n * a `Date` object.\n * @public\n */\nexport const isoDate: Converter<Date, unknown> = new Conversion.BaseConverter<Date>((from: unknown) => {\n if (typeof from === 'string') {\n const dt = DateTime.fromISO(from);\n if (dt.isValid) {\n return succeed(dt.toJSDate());\n }\n return fail(`Invalid date: ${dt.invalidExplanation}`);\n } else if (typeof from === 'number') {\n return succeed(new Date(from));\n } else if (from instanceof Date) {\n return succeed(from);\n } else if (from instanceof DateTime) {\n if (from.isValid) {\n return succeed(from.toJSDate());\n }\n return fail(`Invalid date: ${from.invalidExplanation}`);\n }\n return fail(`Cannot convert ${JSON.stringify(from)} to Date`);\n});\n\n/**\n * A `Converter` which converts an iso formatted string, a number or a `Date` object to\n * a `DateTime` object.\n * @public\n */\nexport const isoDateTime: Converter<DateTime, unknown> = new Conversion.BaseConverter<DateTime>(\n (from: unknown) => {\n if (typeof from === 'string') {\n const dt = DateTime.fromISO(from);\n if (dt.isValid) {\n return succeed(dt);\n }\n return fail(`Invalid date: ${dt.invalidExplanation}`);\n } else if (typeof from === 'number') {\n return succeed(DateTime.fromMillis(from));\n /* c8 ignore next 3 - Date instance path not exercised in current test suite */\n } else if (from instanceof Date) {\n return succeed(DateTime.fromJSDate(from));\n } else if (from instanceof DateTime) {\n if (from.isValid) {\n return succeed(from);\n }\n return fail(`Invalid date: ${from.invalidExplanation}`);\n }\n return fail(`Cannot convert ${JSON.stringify(from)} to DateTime`);\n }\n);\n\n/**\n * A helper function to create a `Converter` which converts `unknown` to {@link Experimental.ExtendedArray | ExtendedArray<T>}.\n * @remarks\n * If `onError` is `'failOnError'` (default), then the entire conversion fails if any element cannot\n * be converted. If `onError` is `'ignoreErrors'`, then failing elements are silently ignored.\n * @param converter - `Converter` used to convert each item in the array\n * @param onError - Specifies treatment of unconvertible elements\n * @beta\n */\nexport function extendedArrayOf<T, TC = undefined>(\n label: string,\n converter: Converter<T, TC>,\n onError: Conversion.OnError = 'failOnError'\n): Converter<ExtendedArray<T>, TC> {\n return Converters.arrayOf(converter, onError).map((items: T[]) => {\n return captureResult(() => new ExtendedArray(label, ...items));\n });\n}\n\n/**\n * A helper wrapper to construct a `Converter` which converts to an arbitrary strongly-typed\n * range of some comparable type.\n * @param converter - `Converter` used to convert `min` and `max` extent of the range.\n * @param constructor - Static constructor to instantiate the object.\n * @public\n */\nexport function rangeTypeOf<T, RT extends RangeOf<T>, TC = unknown>(\n converter: Converter<T, TC>,\n constructor: (init: RangeOfProperties<T>) => Result<RT>\n): Converter<RT, TC> {\n return new Conversion.BaseConverter((from: unknown, __self, context?: TC) => {\n const result = Converters.object(\n {\n min: converter,\n max: converter\n },\n { optionalFields: ['min', 'max'] }\n ).convert(from, context);\n if (result.isSuccess()) {\n return constructor({ min: result.value.min, max: result.value.max });\n }\n return fail(result.message);\n });\n}\n\n/**\n * A helper wrapper to construct a `Converter` which converts to {@link Experimental.RangeOf | RangeOf<T>}\n * where `<T>` is some comparable type.\n * @param converter - `Converter` used to convert `min` and `max` extent of the range.\n * @public\n */\nexport function rangeOf<T, TC = unknown>(converter: Converter<T, TC>): Converter<RangeOf<T>, TC> {\n return rangeTypeOf<T, RangeOf<T>, TC>(converter, RangeOf.createRange);\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/conversion/index.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/conversion/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yDAA2C;AAElC,gCAAU","sourcesContent":["/*\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Converters from './converters';\n\nexport { Converters };\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/constants.ts"],"names":[],"mappings":"AAwBA;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAG,yBAAkC,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAG,aAAsB,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAW,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAAW,CAAC;AAEtC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAW,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/constants.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAEZ,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;GAGG;AACU,QAAA,qBAAqB,GAAG,yBAAkC,CAAC;AAExE;;;GAGG;AACU,QAAA,iBAAiB,GAAG,aAAsB,CAAC;AAExD;;;GAGG;AACU,QAAA,gBAAgB,GAAW,EAAE,CAAC;AAE3C;;;GAGG;AACU,QAAA,WAAW,GAAW,EAAE,CAAC;AAEtC;;;GAGG;AACU,QAAA,iBAAiB,GAAW,EAAE,CAAC","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Current format version for encrypted files.\n * @public\n */\nexport const ENCRYPTED_FILE_FORMAT = 'encrypted-collection-v1' as const;\n\n/**\n * Default encryption algorithm.\n * @public\n */\nexport const DEFAULT_ALGORITHM = 'AES-256-GCM' as const;\n\n/**\n * Key size in bytes for AES-256.\n * @public\n */\nexport const AES_256_KEY_SIZE: number = 32;\n\n/**\n * IV size in bytes for GCM mode.\n * @public\n */\nexport const GCM_IV_SIZE: number = 12;\n\n/**\n * Auth tag size in bytes for GCM mode.\n * @public\n */\nexport const GCM_AUTH_TAG_SIZE: number = 16;\n"]}
@@ -1,6 +1,6 @@
1
1
  import { JsonValue } from '@fgv/ts-json-base';
2
2
  import { Converter } from '@fgv/ts-utils';
3
- import { EncryptedFileErrorMode, EncryptedFileFormat, EncryptionAlgorithm, IEncryptedFile, IKeyDerivationParams, INamedSecret, KeyDerivationFunction } from './model';
3
+ import { EncryptedFileErrorMode, EncryptedFileFormat, EncryptionAlgorithm, IArgon2idKeyDerivationParams, IEncryptedFile, IKeyDerivationParams, INamedSecret, IPbkdf2KeyDerivationParams, KeyDerivationFunction, MultibaseSpkiPublicKey } from './model';
4
4
  /**
5
5
  * Converter for {@link CryptoUtils.EncryptionAlgorithm | encryption algorithm} values.
6
6
  * @public
@@ -21,8 +21,19 @@ export declare const encryptedFileErrorMode: Converter<EncryptedFileErrorMode>;
21
21
  * @public
22
22
  */
23
23
  export declare const keyDerivationFunction: Converter<KeyDerivationFunction>;
24
+ /**
25
+ * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.
26
+ * @public
27
+ */
28
+ export declare const pbkdf2KeyDerivationParams: Converter<IPbkdf2KeyDerivationParams>;
29
+ /**
30
+ * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.
31
+ * @public
32
+ */
33
+ export declare const argon2idKeyDerivationParams: Converter<IArgon2idKeyDerivationParams>;
24
34
  /**
25
35
  * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
36
+ * Handles both PBKDF2 and Argon2id discriminated union arms.
26
37
  * @public
27
38
  */
28
39
  export declare const keyDerivationParams: Converter<IKeyDerivationParams>;
@@ -31,6 +42,14 @@ export declare const keyDerivationParams: Converter<IKeyDerivationParams>;
31
42
  * @public
32
43
  */
33
44
  export declare const base64String: Converter<string>;
45
+ /**
46
+ * Converter for {@link CryptoUtils.MultibaseSpkiPublicKey | multibase SPKI public key} strings.
47
+ * Validates that the value is a string with the `'m'` multibase prefix and a well-formed
48
+ * base64url-no-pad body, and yields the branded value. Fails with context on a non-string,
49
+ * bad-prefix, or malformed-body input.
50
+ * @public
51
+ */
52
+ export declare const multibaseSpkiPublicKey: Converter<MultibaseSpkiPublicKey>;
34
53
  /**
35
54
  * Converter which converts a base64 string to a Uint8Array.
36
55
  * @public
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/converters.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAgC,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAA6B,MAAM,eAAe,CAAC;AAErE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,EAC5B,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAOjB;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,CACiB,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,CAE7D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,CAAC,sBAAsB,CACS,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,CAAC,qBAAqB,CACQ,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,CAAC,0BAA0B,CAKxE,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,CAAC,4BAA4B,CAO5E,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,oBAAoB,CAG9D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,MAAM,CAOzC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,CAAC,sBAAsB,CAUnE,CAAC;AAMH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,UAAU,CAoBrD,CAAC;AAMH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,YAAY,CAG9C,CAAC;AAsCH;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,GAAG,SAAS,EAChE,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GACvC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAyBtC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,cAAc,CAAkC,CAAC"}
@@ -52,11 +52,12 @@ var __importStar = (this && this.__importStar) || (function () {
52
52
  };
53
53
  })();
54
54
  Object.defineProperty(exports, "__esModule", { value: true });
55
- exports.encryptedFile = exports.namedSecret = exports.uint8ArrayFromBase64 = exports.base64String = exports.keyDerivationParams = exports.keyDerivationFunction = exports.encryptedFileErrorMode = exports.encryptedFileFormat = exports.encryptionAlgorithm = void 0;
55
+ exports.encryptedFile = exports.namedSecret = exports.uint8ArrayFromBase64 = exports.multibaseSpkiPublicKey = exports.base64String = exports.keyDerivationParams = exports.argon2idKeyDerivationParams = exports.pbkdf2KeyDerivationParams = exports.keyDerivationFunction = exports.encryptedFileErrorMode = exports.encryptedFileFormat = exports.encryptionAlgorithm = void 0;
56
56
  exports.createEncryptedFileConverter = createEncryptedFileConverter;
57
57
  const ts_json_base_1 = require("@fgv/ts-json-base");
58
58
  const ts_utils_1 = require("@fgv/ts-utils");
59
59
  const Constants = __importStar(require("./constants"));
60
+ const spkiHelpers_1 = require("./spkiHelpers");
60
61
  // ============================================================================
61
62
  // Base Converters
62
63
  // ============================================================================
@@ -81,16 +82,36 @@ exports.encryptedFileErrorMode = ts_utils_1.Converters.enumeratedValue(['fail',
81
82
  * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.
82
83
  * @public
83
84
  */
84
- exports.keyDerivationFunction = ts_utils_1.Converters.enumeratedValue(['pbkdf2']);
85
+ exports.keyDerivationFunction = ts_utils_1.Converters.enumeratedValue(['pbkdf2', 'argon2id']);
85
86
  /**
86
- * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
87
+ * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.
87
88
  * @public
88
89
  */
89
- exports.keyDerivationParams = ts_utils_1.Converters.object({
90
- kdf: exports.keyDerivationFunction,
90
+ exports.pbkdf2KeyDerivationParams = ts_utils_1.Converters.object({
91
+ kdf: ts_utils_1.Converters.enumeratedValue(['pbkdf2']),
91
92
  salt: ts_utils_1.Converters.string,
92
93
  iterations: ts_utils_1.Converters.number
93
94
  });
95
+ /**
96
+ * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.
97
+ * @public
98
+ */
99
+ exports.argon2idKeyDerivationParams = ts_utils_1.Converters.object({
100
+ kdf: ts_utils_1.Converters.enumeratedValue(['argon2id']),
101
+ salt: ts_utils_1.Converters.string,
102
+ memoryKiB: ts_utils_1.Converters.number,
103
+ iterations: ts_utils_1.Converters.number,
104
+ parallelism: ts_utils_1.Converters.number
105
+ });
106
+ /**
107
+ * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
108
+ * Handles both PBKDF2 and Argon2id discriminated union arms.
109
+ * @public
110
+ */
111
+ exports.keyDerivationParams = ts_utils_1.Converters.oneOf([
112
+ exports.pbkdf2KeyDerivationParams,
113
+ exports.argon2idKeyDerivationParams
114
+ ]);
94
115
  /**
95
116
  * Converter for base64 strings (validates format).
96
117
  * @public
@@ -103,6 +124,23 @@ exports.base64String = ts_utils_1.Converters.string.withConstraint((value) => {
103
124
  }
104
125
  return (0, ts_utils_1.succeed)(value);
105
126
  });
127
+ /**
128
+ * Converter for {@link CryptoUtils.MultibaseSpkiPublicKey | multibase SPKI public key} strings.
129
+ * Validates that the value is a string with the `'m'` multibase prefix and a well-formed
130
+ * base64url-no-pad body, and yields the branded value. Fails with context on a non-string,
131
+ * bad-prefix, or malformed-body input.
132
+ * @public
133
+ */
134
+ exports.multibaseSpkiPublicKey = ts_utils_1.Converters.string.map((value) => {
135
+ var _a;
136
+ if ((0, spkiHelpers_1.isValidMultibaseSpkiPublicKey)(value)) {
137
+ return (0, ts_utils_1.succeed)(value);
138
+ }
139
+ if (!value.startsWith('m')) {
140
+ return (0, ts_utils_1.fail)(`multibaseSpkiPublicKey: invalid multibase prefix '${(_a = value[0]) !== null && _a !== void 0 ? _a : '(empty)'}' — expected 'm' (base64url)`);
141
+ }
142
+ return (0, ts_utils_1.fail)(`multibaseSpkiPublicKey: malformed base64url body`);
143
+ });
106
144
  // ============================================================================
107
145
  // Uint8Array Converter
108
146
  // ============================================================================
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/converters.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { Converters as JsonConverters, JsonValue } from '@fgv/ts-json-base';\nimport { Converter, Converters, fail, succeed } from '@fgv/ts-utils';\nimport * as Constants from './constants';\nimport {\n EncryptedFileErrorMode,\n EncryptedFileFormat,\n EncryptionAlgorithm,\n IArgon2idKeyDerivationParams,\n IEncryptedFile,\n IKeyDerivationParams,\n INamedSecret,\n IPbkdf2KeyDerivationParams,\n KeyDerivationFunction,\n MultibaseSpkiPublicKey\n} from './model';\nimport { isValidMultibaseSpkiPublicKey } from './spkiHelpers';\n\n// ============================================================================\n// Base Converters\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.EncryptionAlgorithm | encryption algorithm} values.\n * @public\n */\nexport const encryptionAlgorithm: Converter<EncryptionAlgorithm> =\n Converters.enumeratedValue<EncryptionAlgorithm>([Constants.DEFAULT_ALGORITHM]);\n\n/**\n * Converter for {@link CryptoUtils.EncryptedFileFormat | encrypted file format} version.\n * @public\n */\nexport const encryptedFileFormat: Converter<EncryptedFileFormat> = Converters.enumeratedValue([\n Constants.ENCRYPTED_FILE_FORMAT\n]);\n\n/**\n * Converter for {@link CryptoUtils.EncryptedFileErrorMode | encrypted file error mode}.\n * @public\n */\nexport const encryptedFileErrorMode: Converter<EncryptedFileErrorMode> =\n Converters.enumeratedValue<EncryptedFileErrorMode>(['fail', 'skip', 'warn']);\n\n/**\n * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.\n * @public\n */\nexport const keyDerivationFunction: Converter<KeyDerivationFunction> =\n Converters.enumeratedValue<KeyDerivationFunction>(['pbkdf2', 'argon2id']);\n\n/**\n * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.\n * @public\n */\nexport const pbkdf2KeyDerivationParams: Converter<IPbkdf2KeyDerivationParams> =\n Converters.object<IPbkdf2KeyDerivationParams>({\n kdf: Converters.enumeratedValue<'pbkdf2'>(['pbkdf2']),\n salt: Converters.string,\n iterations: Converters.number\n });\n\n/**\n * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.\n * @public\n */\nexport const argon2idKeyDerivationParams: Converter<IArgon2idKeyDerivationParams> =\n Converters.object<IArgon2idKeyDerivationParams>({\n kdf: Converters.enumeratedValue<'argon2id'>(['argon2id']),\n salt: Converters.string,\n memoryKiB: Converters.number,\n iterations: Converters.number,\n parallelism: Converters.number\n });\n\n/**\n * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.\n * Handles both PBKDF2 and Argon2id discriminated union arms.\n * @public\n */\nexport const keyDerivationParams: Converter<IKeyDerivationParams> = Converters.oneOf<IKeyDerivationParams>([\n pbkdf2KeyDerivationParams,\n argon2idKeyDerivationParams\n]);\n\n/**\n * Converter for base64 strings (validates format).\n * @public\n */\nexport const base64String: Converter<string> = Converters.string.withConstraint((value) => {\n // Basic base64 validation - check for valid characters and padding\n const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;\n if (!base64Regex.test(value)) {\n return fail('Invalid base64 encoding');\n }\n return succeed(value);\n});\n\n/**\n * Converter for {@link CryptoUtils.MultibaseSpkiPublicKey | multibase SPKI public key} strings.\n * Validates that the value is a string with the `'m'` multibase prefix and a well-formed\n * base64url-no-pad body, and yields the branded value. Fails with context on a non-string,\n * bad-prefix, or malformed-body input.\n * @public\n */\nexport const multibaseSpkiPublicKey: Converter<MultibaseSpkiPublicKey> = Converters.string.map((value) => {\n if (isValidMultibaseSpkiPublicKey(value)) {\n return succeed(value);\n }\n if (!value.startsWith('m')) {\n return fail(\n `multibaseSpkiPublicKey: invalid multibase prefix '${value[0] ?? '(empty)'}' — expected 'm' (base64url)`\n );\n }\n return fail(`multibaseSpkiPublicKey: malformed base64url body`);\n});\n\n// ============================================================================\n// Uint8Array Converter\n// ============================================================================\n\n/**\n * Converter which converts a base64 string to a Uint8Array.\n * @public\n */\nexport const uint8ArrayFromBase64: Converter<Uint8Array> = Converters.string.map((base64) => {\n try {\n // Use Buffer in Node.js environment, atob in browser\n if (typeof Buffer !== 'undefined') {\n return succeed(Uint8Array.from(Buffer.from(base64, 'base64')));\n }\n /* c8 ignore start - Browser-only fallback cannot be tested in Node.js environment */\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return succeed(bytes);\n } catch (e) {\n // This catch is for browser's atob() which throws on invalid base64\n // Node's Buffer.from() doesn't throw, it ignores invalid characters\n const message = e instanceof Error ? e.message : String(e);\n return fail(`Invalid base64: ${message}`);\n }\n /* c8 ignore stop */\n});\n\n// ============================================================================\n// Named Secret Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.INamedSecret | named secret} from JSON representation.\n * Expects key as base64 string in JSON, converts to Uint8Array.\n * @public\n */\nexport const namedSecret: Converter<INamedSecret> = Converters.object<INamedSecret>({\n name: Converters.string,\n key: uint8ArrayFromBase64\n});\n\n// ============================================================================\n// Encrypted File Converter Factory\n// ============================================================================\n\n/**\n * Base encrypted file structure without metadata typing.\n * Used internally by the converter factory.\n */\ninterface IBaseEncryptedFile {\n readonly format: EncryptedFileFormat;\n readonly secretName: string;\n readonly algorithm: EncryptionAlgorithm;\n readonly iv: string;\n readonly authTag: string;\n readonly encryptedData: string;\n readonly keyDerivation?: IKeyDerivationParams;\n readonly metadata?: JsonValue;\n}\n\n/**\n * Base converter for encrypted file structure (without typed metadata).\n */\nconst baseEncryptedFileConverter: Converter<IBaseEncryptedFile> = Converters.object<IBaseEncryptedFile>(\n {\n format: encryptedFileFormat,\n secretName: Converters.string,\n algorithm: encryptionAlgorithm,\n iv: base64String,\n authTag: base64String,\n encryptedData: base64String,\n keyDerivation: keyDerivationParams,\n metadata: JsonConverters.jsonValue\n },\n { optionalFields: ['keyDerivation', 'metadata'] }\n);\n\n/**\n * Creates a converter for {@link CryptoUtils.IEncryptedFile | encrypted files} with optional typed metadata.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @param metadataConverter - Optional converter for validating metadata field\n * @returns A converter that validates and converts encrypted file structures\n * @public\n */\nexport function createEncryptedFileConverter<TMetadata = JsonValue>(\n metadataConverter?: Converter<TMetadata>\n): Converter<IEncryptedFile<TMetadata>> {\n return Converters.generic<IEncryptedFile<TMetadata>>((from: unknown) => {\n // First validate base structure\n const baseResult = baseEncryptedFileConverter.convert(from);\n if (baseResult.isFailure()) {\n return fail(baseResult.message);\n }\n\n const base = baseResult.value;\n\n // Validate metadata with specific converter if provided and metadata exists\n if (metadataConverter !== undefined && base.metadata !== undefined) {\n const metaResult = metadataConverter.convert(base.metadata);\n if (metaResult.isFailure()) {\n return fail(`Invalid metadata: ${metaResult.message}`);\n }\n return succeed({\n ...base,\n metadata: metaResult.value\n } as IEncryptedFile<TMetadata>);\n }\n\n // Return as-is (metadata is either undefined or untyped JsonValue)\n return succeed(base as IEncryptedFile<TMetadata>);\n });\n}\n\n/**\n * Default converter for encrypted files without typed metadata.\n * @public\n */\nexport const encryptedFile: Converter<IEncryptedFile> = createEncryptedFileConverter();\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directEncryptionProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/directEncryptionProvider.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAiB,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE/E;;;GAGG;AACH,MAAM,WAAW,+BAA+B;IAC9C;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,eAAe,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAEzB;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,wBAAyB,YAAW,mBAAmB;IAClE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IAEtD,OAAO;IAMP;;;;;OAKG;WACW,MAAM,CAAC,MAAM,EAAE,+BAA+B,GAAG,MAAM,CAAC,wBAAwB,CAAC;IAO/F;;;OAGG;IACH,IAAW,eAAe,IAAI,MAAM,GAAG,SAAS,CAE/C;IAED;;OAEG;IACU,aAAa,CAAC,SAAS,GAAG,SAAS,EAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,EAClB,QAAQ,CAAC,EAAE,SAAS,GACnB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;CAe9C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directEncryptionProvider.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/directEncryptionProvider.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAGZ,4CAAsD;AACtD,mDAAsD;AA0BtD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAa,wBAAwB;IAKnC,YAAoB,MAAuC;QACzD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,eAAe,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,MAAM,CAAC,MAAuC;QAC1D,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAA,eAAI,EAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,aAAa,CACxB,UAAkB,EAClB,OAAkB,EAClB,QAAoB;QAEpB,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAChF,OAAO,IAAA,eAAI,EACT,oCAAoC,UAAU,+BAA+B,IAAI,CAAC,gBAAgB,GAAG,CACtG,CAAC;QACJ,CAAC;QAED,OAAO,IAAA,mCAAmB,EAAC;YACzB,OAAO;YACP,UAAU;YACV,GAAG,EAAE,IAAI,CAAC,IAAI;YACd,cAAc,EAAE,IAAI,CAAC,eAAe;YACpC,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;CACF;AAtDD,4DAsDC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Result, fail, succeed } from '@fgv/ts-utils';\nimport { createEncryptedFile } from './encryptedFile';\nimport { ICryptoProvider, IEncryptedFile, IEncryptionProvider } from './model';\n\n/**\n * Parameters for creating a {@link DirectEncryptionProvider}.\n * @public\n */\nexport interface IDirectEncryptionProviderParams {\n /**\n * The crypto provider to use for encryption operations.\n */\n readonly cryptoProvider: ICryptoProvider;\n\n /**\n * The encryption key (32 bytes for AES-256).\n */\n readonly key: Uint8Array;\n\n /**\n * Optional bound secret name.\n * When set, `encryptByName` will fail if called with a different name.\n * When unset, any secret name is accepted.\n */\n readonly boundSecretName?: string;\n}\n\n/**\n * An {@link IEncryptionProvider} that uses a pre-supplied key and crypto provider.\n *\n * This is useful when you have the raw encryption key from an external source\n * (e.g. a `SecretProvider` callback, password derivation, or a one-shot\n * operation) and don't want to open a full KeyStore.\n *\n * Optionally bound to a specific secret name for safety: if a `boundSecretName`\n * is provided, calls to `encryptByName` with a different name will fail.\n *\n * @example\n * ```typescript\n * const provider = DirectEncryptionProvider.create({\n * cryptoProvider: nodeCryptoProvider,\n * key: myKey,\n * boundSecretName: 'my-collection'\n * }).orThrow();\n *\n * const encrypted = await provider.encryptByName('my-collection', jsonContent);\n * ```\n *\n * @public\n */\nexport class DirectEncryptionProvider implements IEncryptionProvider {\n private readonly _cryptoProvider: ICryptoProvider;\n private readonly _key: Uint8Array;\n private readonly _boundSecretName: string | undefined;\n\n private constructor(params: IDirectEncryptionProviderParams) {\n this._cryptoProvider = params.cryptoProvider;\n this._key = params.key;\n this._boundSecretName = params.boundSecretName;\n }\n\n /**\n * Creates a new DirectEncryptionProvider.\n * @param params - Provider configuration\n * @returns Success with provider, or Failure if parameters are invalid\n * @public\n */\n public static create(params: IDirectEncryptionProviderParams): Result<DirectEncryptionProvider> {\n if (params.key.length === 0) {\n return fail('Encryption key cannot be empty');\n }\n return succeed(new DirectEncryptionProvider(params));\n }\n\n /**\n * The secret name this provider is bound to, if any.\n * @public\n */\n public get boundSecretName(): string | undefined {\n return this._boundSecretName;\n }\n\n /**\n * {@inheritDoc IEncryptionProvider.encryptByName}\n */\n public async encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>> {\n if (this._boundSecretName !== undefined && secretName !== this._boundSecretName) {\n return fail(\n `Secret name mismatch: requested '${secretName}' but provider is bound to '${this._boundSecretName}'`\n );\n }\n\n return createEncryptedFile({\n content,\n secretName,\n key: this._key,\n cryptoProvider: this._cryptoProvider,\n metadata\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryptedFile.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/encryptedFile.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAiB,SAAS,EAAQ,MAAM,EAAW,MAAM,eAAe,CAAC;AAGhF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAmB,MAAM,SAAS,CAAC;AAMjG;;;;;GAKG;AAEH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAUlD;AAGD;;;;;GAKG;AAEH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAWrD;AAOD;;;;GAIG;AACH,MAAM,WAAW,0BAA0B,CAAC,SAAS,GAAG,SAAS;IAC/D;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,eAAe,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAE9B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAElD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,CAAC;CAC/C;AAMD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,GAAG,SAAS,EAC7D,MAAM,EAAE,0BAA0B,CAAC,SAAS,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAuC5C;AAMD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,QAAQ,SAAS,SAAS,GAAG,SAAS,EACtE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,EAC7B,GAAG,EAAE,UAAU,EACf,cAAc,EAAE,eAAe,EAC/B,gBAAgB,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,GACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CA6B3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,QAAQ,SAAS,SAAS,GAAG,SAAS,EAAE,SAAS,GAAG,SAAS,EAChG,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,UAAU,EACf,cAAc,EAAE,eAAe,EAC/B,gBAAgB,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,EACtC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAc3B"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryptedFile.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/encryptedFile.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { captureResult, Converter, fail, Result, succeed } from '@fgv/ts-utils';\nimport * as Constants from './constants';\nimport { createEncryptedFileConverter } from './converters';\nimport { ICryptoProvider, IEncryptedFile, IKeyDerivationParams, isEncryptedFile } from './model';\n\n// ============================================================================\n// Base64 Utilities\n// ============================================================================\n\n/**\n * Encodes a `Uint8Array` to a base64 string.\n * @param bytes - Bytes to encode\n * @returns Base64 string\n * @public\n */\n/* c8 ignore start - Browser-only fallback cannot be tested in Node.js environment */\nexport function toBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64');\n }\n // Browser fallback\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n/* c8 ignore stop */\n\n/**\n * Decodes a base64 string to a `Uint8Array`.\n * @param base64 - Base64 string to decode\n * @returns Decoded bytes\n * @public\n */\n/* c8 ignore start - Browser-only fallback cannot be tested in Node.js environment */\nexport function fromBase64(base64: string): Uint8Array {\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(base64, 'base64'));\n }\n // Browser fallback\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n/* c8 ignore stop */\n\n// ============================================================================\n// Create Encrypted File Parameters\n// ============================================================================\n\n/**\n * Parameters for creating an {@link CryptoUtils.IEncryptedFile | encrypted file}.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @public\n */\nexport interface ICreateEncryptedFileParams<TMetadata = JsonValue> {\n /**\n * The JSON content to encrypt.\n */\n readonly content: JsonValue;\n\n /**\n * Name of the secret used for encryption.\n */\n readonly secretName: string;\n\n /**\n * The encryption key (32 bytes for AES-256).\n */\n readonly key: Uint8Array;\n\n /**\n * {@link CryptoUtils.ICryptoProvider | Crypto provider} to use for encryption.\n */\n readonly cryptoProvider: ICryptoProvider;\n\n /**\n * Optional metadata to include unencrypted.\n */\n readonly metadata?: TMetadata;\n\n /**\n * Optional converter to validate metadata before including.\n * If provided, metadata will be validated before encryption.\n */\n readonly metadataConverter?: Converter<TMetadata>;\n\n /**\n * Optional {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.\n * If provided, stores the salt and iterations used to derive the key from a password.\n * This allows decryption using only a password (the salt/iterations are read from the file).\n */\n readonly keyDerivation?: IKeyDerivationParams;\n}\n\n// ============================================================================\n// Encryption Functions\n// ============================================================================\n\n/**\n * Creates an {@link CryptoUtils.IEncryptedFile | encrypted file} from JSON content.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @param params - Encryption parameters\n * @returns `Success` with encrypted file structure, or `Failure` with an error.\n * @public\n */\nexport async function createEncryptedFile<TMetadata = JsonValue>(\n params: ICreateEncryptedFileParams<TMetadata>\n): Promise<Result<IEncryptedFile<TMetadata>>> {\n const { content, secretName, key, metadata, metadataConverter, keyDerivation, cryptoProvider } = params;\n\n // Validate metadata if converter provided\n /* c8 ignore next 6 - metadata validation path exercised via higher-level tests */\n if (metadata !== undefined && metadataConverter !== undefined) {\n const metadataResult = metadataConverter.convert(metadata);\n if (metadataResult.isFailure()) {\n return fail(`Invalid metadata: ${metadataResult.message}`);\n }\n }\n\n // Serialize content to JSON string\n const jsonResult = captureResult(() => JSON.stringify(content));\n if (jsonResult.isFailure()) {\n return fail(`Failed to serialize content: ${jsonResult.message}`);\n }\n\n // Encrypt the JSON string\n const encryptResult = await cryptoProvider.encrypt(jsonResult.value, key);\n if (encryptResult.isFailure()) {\n return fail(`Encryption failed: ${encryptResult.message}`);\n }\n\n const { iv, authTag, encryptedData } = encryptResult.value;\n\n // Build the encrypted file structure\n const encryptedFile: IEncryptedFile<TMetadata> = {\n format: Constants.ENCRYPTED_FILE_FORMAT,\n secretName,\n algorithm: Constants.DEFAULT_ALGORITHM,\n iv: toBase64(iv),\n authTag: toBase64(authTag),\n encryptedData: toBase64(encryptedData),\n ...(metadata !== undefined ? { metadata } : {}),\n ...(keyDerivation !== undefined ? { keyDerivation } : {})\n };\n\n return succeed(encryptedFile);\n}\n\n// ============================================================================\n// Decryption Functions\n// ============================================================================\n\n/**\n * Decrypts an {@link CryptoUtils.IEncryptedFile | encrypted file} and returns the JSON content.\n * @typeParam TPayload - Expected type of decrypted content\n * @param file - The encrypted file structure\n * @param key - The decryption key (32 bytes for AES-256)\n * @param cryptoProvider - {@link CryptoUtils.ICryptoProvider | Crypto provider} to use for decryption\n * @param payloadConverter - Optional converter to validate and convert decrypted content\n * @returns `Success` with decrypted content, or `Failure` with an error.\n * @public\n */\nexport async function decryptFile<TPayload extends JsonValue = JsonValue>(\n file: IEncryptedFile<unknown>,\n key: Uint8Array,\n cryptoProvider: ICryptoProvider,\n payloadConverter?: Converter<TPayload>\n): Promise<Result<TPayload>> {\n // Decode base64 values\n const iv = fromBase64(file.iv);\n const authTag = fromBase64(file.authTag);\n const encryptedData = fromBase64(file.encryptedData);\n\n // Decrypt\n const decryptResult = await cryptoProvider.decrypt(encryptedData, key, iv, authTag);\n if (decryptResult.isFailure()) {\n return fail(decryptResult.message);\n }\n\n // Parse JSON\n const parseResult = captureResult(() => JSON.parse(decryptResult.value) as TPayload).withErrorFormat(\n (e) => `Failed to parse decrypted content as JSON: ${e}`\n );\n\n /* c8 ignore next 3 - JSON parse failure only occurs with corrupted encrypted data */\n if (parseResult.isFailure()) {\n return parseResult;\n }\n\n // Validate with converter if provided\n /* c8 ignore next 3 - payload converter path exercised via higher-level tests */\n if (payloadConverter !== undefined) {\n return payloadConverter.convert(parseResult.value);\n }\n\n return parseResult;\n}\n\n/**\n * Attempts to parse and decrypt a JSON object as an {@link CryptoUtils.IEncryptedFile | encrypted file}.\n * @typeParam TPayload - Expected type of decrypted content\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @param json - JSON object that may be an encrypted file\n * @param key - The decryption key (32 bytes for AES-256)\n * @param cryptoProvider - {@link CryptoUtils.ICryptoProvider | Crypto provider} to use for decryption\n * @param payloadConverter - Optional converter to validate and convert decrypted content\n * @param metadataConverter - Optional converter to validate metadata before decryption\n * @returns `Success` with decrypted content, or `Failure` with an error (including if not encrypted)\n * @public\n */\nexport async function tryDecryptFile<TPayload extends JsonValue = JsonValue, TMetadata = JsonValue>(\n json: JsonValue,\n key: Uint8Array,\n cryptoProvider: ICryptoProvider,\n payloadConverter?: Converter<TPayload>,\n metadataConverter?: Converter<TMetadata>\n): Promise<Result<TPayload>> {\n // Check if it's an encrypted file\n if (!isEncryptedFile(json)) {\n return fail('Not an encrypted file');\n }\n\n // Validate and convert to typed encrypted file\n const fileConverter = createEncryptedFileConverter(metadataConverter);\n const fileResult = fileConverter.convert(json);\n if (fileResult.isFailure()) {\n return fail(`Invalid encrypted file format: ${fileResult.message}`);\n }\n\n return decryptFile(fileResult.value, key, cryptoProvider, payloadConverter);\n}\n"]}
@@ -0,0 +1,142 @@
1
+ import { Result } from '@fgv/ts-utils';
2
+ /**
3
+ * Output of {@link HpkeProvider.sealBase}.
4
+ *
5
+ * The `ciphertext` field includes the 16-byte AES-256-GCM authentication tag
6
+ * appended by Web Crypto's `encrypt()` operation: `length = plaintext.length + 16`.
7
+ * @public
8
+ */
9
+ export interface IHpkeSealResult {
10
+ /**
11
+ * Encapsulated key — 32-byte raw X25519 ephemeral public key (`enc` in RFC 9180).
12
+ * Must be transmitted to the recipient alongside `ciphertext`.
13
+ */
14
+ readonly enc: Uint8Array;
15
+ /**
16
+ * AES-256-GCM ciphertext with the 16-byte authentication tag appended.
17
+ * Length = `plaintext.length + 16`.
18
+ */
19
+ readonly ciphertext: Uint8Array;
20
+ }
21
+ /**
22
+ * HPKE base mode (RFC 9180) — `DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM`.
23
+ *
24
+ * Class-based provider that captures a `SubtleCrypto` instance at construction,
25
+ * matching the existing `NodeCryptoProvider` / `BrowserCryptoProvider` / `KeyStore`
26
+ * factory pattern used throughout `@fgv/ts-extras/crypto-utils`.
27
+ *
28
+ * **Node.js usage:**
29
+ * ```typescript
30
+ * import * as crypto from 'crypto';
31
+ * const hpke = HpkeProvider.create(crypto.webcrypto.subtle).orThrow();
32
+ * ```
33
+ *
34
+ * **Browser usage:**
35
+ * ```typescript
36
+ * const hpke = HpkeProvider.create(globalThis.crypto.subtle).orThrow();
37
+ * ```
38
+ *
39
+ * **Runtime requirements:** Node.js 20+ (X25519 in `crypto.webcrypto`);
40
+ * Chrome 113+, Safari 16.4+, Firefox 118+ (X25519 added to Web Crypto in 2023).
41
+ * @public
42
+ */
43
+ export declare class HpkeProvider {
44
+ private readonly _subtle;
45
+ private constructor();
46
+ /**
47
+ * Creates an `HpkeProvider` bound to the given `SubtleCrypto` instance.
48
+ *
49
+ * @param subtle - Web Crypto SubtleCrypto instance.
50
+ * Node.js: `(await import('crypto')).webcrypto.subtle`.
51
+ * Browser: `globalThis.crypto.subtle`.
52
+ * @returns `Success` with the provider, or `Failure` if construction fails.
53
+ */
54
+ static create(subtle: SubtleCrypto): Result<HpkeProvider>;
55
+ /**
56
+ * HPKE base-mode seal (sender side). RFC 9180 §6.1.
57
+ *
58
+ * Generates a fresh ephemeral X25519 keypair, runs DHKEM Encap to produce a
59
+ * shared secret and `enc` (32-byte raw ephemeral public key), derives the AEAD
60
+ * key and nonce deterministically via the RFC 9180 key schedule, then encrypts
61
+ * `plaintext` with AES-256-GCM.
62
+ *
63
+ * @param recipientPublicKey - Recipient's X25519 public `CryptoKey`
64
+ * (`algorithm.name === 'X25519'`, `type === 'public'`, **`extractable: true`**).
65
+ * Must be extractable — DHKEM Encap calls `exportKey('raw', ...)` on this key to
66
+ * build the KEM shared-secret context. Keys imported with `extractable: false` will
67
+ * cause this method to return a `Failure`.
68
+ * @param info - Context-binding bytes. **Load-bearing — no default.**
69
+ * Binds this ciphertext to a specific application context, preventing replay
70
+ * across different contexts sharing the same recipient keypair.
71
+ * Use `new TextEncoder().encode('myapp/v1/use-case\x00' + contextId)` pattern.
72
+ * Never pass an empty array in production: empty `info` provides no context binding.
73
+ * @param aad - Additional authenticated data. Integrity-protected but not encrypted.
74
+ * `new Uint8Array(0)` is valid when no AAD is needed.
75
+ * @param plaintext - Bytes to encrypt. `new Uint8Array(0)` is valid.
76
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` with error context.
77
+ */
78
+ sealBase(recipientPublicKey: CryptoKey, info: Uint8Array, aad: Uint8Array, plaintext: Uint8Array): Promise<Result<IHpkeSealResult>>;
79
+ /**
80
+ * HPKE base-mode open (recipient side). RFC 9180 §6.1.
81
+ *
82
+ * Decapsulates `enc` using the recipient's X25519 private key, derives the same
83
+ * AEAD key and nonce from the shared secret and `info`, then authenticates and
84
+ * decrypts `ciphertext` with AES-256-GCM.
85
+ *
86
+ * Returns `Failure` on any of:
87
+ * - Wrong private key (different DH output → different key derivation)
88
+ * - Wrong `info` (different key schedule context → different AEAD key)
89
+ * - Wrong `aad` (AES-GCM authentication fails)
90
+ * - Tampered `ciphertext` or `enc` (authentication fails or DH fails)
91
+ * - `enc` not exactly 32 bytes
92
+ * - `ciphertext` shorter than 16 bytes (no room for authentication tag)
93
+ *
94
+ * @param recipientPrivateKey - Recipient's X25519 private `CryptoKey`
95
+ * (`algorithm.name === 'X25519'`, `type === 'private'`, `usages` includes `'deriveBits'`).
96
+ * **Must be extractable** (`extractable: true`) — the recipient's public key bytes
97
+ * are recovered from the JWK `x` field during Decap.
98
+ * @param info - Context-binding bytes. Must exactly match `info` from `sealBase`.
99
+ * @param aad - Must exactly match `aad` from `sealBase`.
100
+ * @param enc - The encapsulated key from `sealBase` — exactly 32 bytes.
101
+ * @param ciphertext - The ciphertext from `sealBase` — `plaintext.length + 16` bytes.
102
+ * @returns `Success` with decrypted plaintext bytes, or `Failure` with error context.
103
+ */
104
+ openBase(recipientPrivateKey: CryptoKey, info: Uint8Array, aad: Uint8Array, enc: Uint8Array, ciphertext: Uint8Array): Promise<Result<Uint8Array>>;
105
+ /**
106
+ * HKDF-SHA256 key derivation (RFC 5869). Extract-then-Expand using SHA-256.
107
+ *
108
+ * This is raw RFC 5869 HKDF — it does **not** use RFC 9180's labeled variants.
109
+ * The HPKE key schedule internally uses labeled HKDF; this method is the unlabeled
110
+ * version for callers that need standalone key derivation.
111
+ *
112
+ * @param secret - Input keying material (IKM). Any length.
113
+ * @param salt - Optional salt. Use `new Uint8Array(0)` if no salt is available
114
+ * (RFC 5869: 32 zero bytes are used internally when salt is empty).
115
+ * @param info - Context / application-binding bytes. Any length.
116
+ * @param length - Number of output bytes to derive. Maximum 8160 bytes (255 × 32).
117
+ * @returns `Success` with derived bytes, or `Failure` with error context.
118
+ */
119
+ hkdf(secret: Uint8Array, salt: Uint8Array, info: Uint8Array, length: number): Promise<Result<Uint8Array>>;
120
+ /**
121
+ * Encodes an {@link IHpkeSealResult} as a single contiguous byte array for wire transport.
122
+ *
123
+ * Format: `enc` (32 bytes, fixed) || `ciphertext` (variable length).
124
+ * The 32-byte `enc` length is fixed for X25519; the split point is unambiguous.
125
+ *
126
+ * @param result - The output of {@link HpkeProvider.sealBase}.
127
+ * @returns Concatenated bytes: `enc || ciphertext`.
128
+ */
129
+ static encodeEnvelope(result: IHpkeSealResult): Uint8Array;
130
+ /**
131
+ * Decodes an envelope produced by {@link HpkeProvider.encodeEnvelope}.
132
+ *
133
+ * Validates that the buffer is at least 48 bytes (32-byte enc + 16-byte minimum
134
+ * ciphertext containing the AES-GCM auth tag; zero-length plaintext is the minimum
135
+ * meaningful case).
136
+ *
137
+ * @param envelope - Envelope bytes from `encodeEnvelope`.
138
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` if malformed.
139
+ */
140
+ static decodeEnvelope(envelope: Uint8Array): Result<IHpkeSealResult>;
141
+ }
142
+ //# sourceMappingURL=hpkeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hpkeProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/hpkeProvider.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAoD,MAAM,eAAe,CAAC;AAoOzF;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,OAAO;IAIP;;;;;;;OAOG;WACW,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAIhE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACU,QAAQ,CACnB,kBAAkB,EAAE,SAAS,EAC7B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAenC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACU,QAAQ,CACnB,mBAAmB,EAAE,SAAS,EAC9B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAuB9B;;;;;;;;;;;;;OAaG;IACU,IAAI,CACf,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAQ9B;;;;;;;;OAQG;WACW,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,UAAU;IAIjE;;;;;;;;;OASG;WACW,cAAc,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC;CAY5E"}