@selvajs/local-provider 0.11.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 (295) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/dist/auth/LocalAuthProvider.d.ts +28 -0
  4. package/dist/auth/LocalAuthProvider.d.ts.map +1 -0
  5. package/dist/auth/LocalAuthProvider.js +142 -0
  6. package/dist/auth/LocalAuthProvider.js.map +1 -0
  7. package/dist/auth/__tests__/conformance.test.d.ts +2 -0
  8. package/dist/auth/__tests__/conformance.test.d.ts.map +1 -0
  9. package/dist/auth/__tests__/conformance.test.js +36 -0
  10. package/dist/auth/__tests__/conformance.test.js.map +1 -0
  11. package/dist/auth/hmac.d.ts +18 -0
  12. package/dist/auth/hmac.d.ts.map +1 -0
  13. package/dist/auth/hmac.js +41 -0
  14. package/dist/auth/hmac.js.map +1 -0
  15. package/dist/auth/index.d.ts +6 -0
  16. package/dist/auth/index.d.ts.map +1 -0
  17. package/dist/auth/index.js +4 -0
  18. package/dist/auth/index.js.map +1 -0
  19. package/dist/auth/users.d.ts +38 -0
  20. package/dist/auth/users.d.ts.map +1 -0
  21. package/dist/auth/users.js +100 -0
  22. package/dist/auth/users.js.map +1 -0
  23. package/dist/compute/FilesystemComputeProvider.d.ts +16 -0
  24. package/dist/compute/FilesystemComputeProvider.d.ts.map +1 -0
  25. package/dist/compute/FilesystemComputeProvider.js +51 -0
  26. package/dist/compute/FilesystemComputeProvider.js.map +1 -0
  27. package/dist/compute/SingleComputeServerProvider.d.ts +15 -0
  28. package/dist/compute/SingleComputeServerProvider.d.ts.map +1 -0
  29. package/dist/compute/SingleComputeServerProvider.js +26 -0
  30. package/dist/compute/SingleComputeServerProvider.js.map +1 -0
  31. package/dist/compute/types.d.ts +30 -0
  32. package/dist/compute/types.d.ts.map +1 -0
  33. package/dist/compute/types.js +2 -0
  34. package/dist/compute/types.js.map +1 -0
  35. package/dist/computeServer/FilesystemComputeServerStore.d.ts +14 -0
  36. package/dist/computeServer/FilesystemComputeServerStore.d.ts.map +1 -0
  37. package/dist/computeServer/FilesystemComputeServerStore.js +35 -0
  38. package/dist/computeServer/FilesystemComputeServerStore.js.map +1 -0
  39. package/dist/computeServer/LocalComputeServerProvider.d.ts +18 -0
  40. package/dist/computeServer/LocalComputeServerProvider.d.ts.map +1 -0
  41. package/dist/computeServer/LocalComputeServerProvider.js +29 -0
  42. package/dist/computeServer/LocalComputeServerProvider.js.map +1 -0
  43. package/dist/computeServer/__tests__/conformance.test.d.ts +2 -0
  44. package/dist/computeServer/__tests__/conformance.test.d.ts.map +1 -0
  45. package/dist/computeServer/__tests__/conformance.test.js +20 -0
  46. package/dist/computeServer/__tests__/conformance.test.js.map +1 -0
  47. package/dist/computeServer/index.d.ts +2 -0
  48. package/dist/computeServer/index.d.ts.map +1 -0
  49. package/dist/computeServer/index.js +2 -0
  50. package/dist/computeServer/index.js.map +1 -0
  51. package/dist/data/LocalComputeServerStore.d.ts +72 -0
  52. package/dist/data/LocalComputeServerStore.d.ts.map +1 -0
  53. package/dist/data/LocalComputeServerStore.js +207 -0
  54. package/dist/data/LocalComputeServerStore.js.map +1 -0
  55. package/dist/data/LocalDataProvider.d.ts +47 -0
  56. package/dist/data/LocalDataProvider.d.ts.map +1 -0
  57. package/dist/data/LocalDataProvider.js +118 -0
  58. package/dist/data/LocalDataProvider.js.map +1 -0
  59. package/dist/data/LocalDefinitionMetaProvider.d.ts +22 -0
  60. package/dist/data/LocalDefinitionMetaProvider.d.ts.map +1 -0
  61. package/dist/data/LocalDefinitionMetaProvider.js +131 -0
  62. package/dist/data/LocalDefinitionMetaProvider.js.map +1 -0
  63. package/dist/data/LocalDefinitionStore.d.ts +33 -0
  64. package/dist/data/LocalDefinitionStore.d.ts.map +1 -0
  65. package/dist/data/LocalDefinitionStore.js +274 -0
  66. package/dist/data/LocalDefinitionStore.js.map +1 -0
  67. package/dist/data/LocalInviteStore.d.ts +23 -0
  68. package/dist/data/LocalInviteStore.d.ts.map +1 -0
  69. package/dist/data/LocalInviteStore.js +98 -0
  70. package/dist/data/LocalInviteStore.js.map +1 -0
  71. package/dist/data/LocalOrgStore.d.ts +67 -0
  72. package/dist/data/LocalOrgStore.d.ts.map +1 -0
  73. package/dist/data/LocalOrgStore.js +255 -0
  74. package/dist/data/LocalOrgStore.js.map +1 -0
  75. package/dist/data/LocalPlatformProjectGrantStore.d.ts +14 -0
  76. package/dist/data/LocalPlatformProjectGrantStore.d.ts.map +1 -0
  77. package/dist/data/LocalPlatformProjectGrantStore.js +62 -0
  78. package/dist/data/LocalPlatformProjectGrantStore.js.map +1 -0
  79. package/dist/data/LocalProjectStore.d.ts +30 -0
  80. package/dist/data/LocalProjectStore.d.ts.map +1 -0
  81. package/dist/data/LocalProjectStore.js +171 -0
  82. package/dist/data/LocalProjectStore.js.map +1 -0
  83. package/dist/data/LocalShareLinkStore.d.ts +39 -0
  84. package/dist/data/LocalShareLinkStore.d.ts.map +1 -0
  85. package/dist/data/LocalShareLinkStore.js +108 -0
  86. package/dist/data/LocalShareLinkStore.js.map +1 -0
  87. package/dist/data/__tests__/LocalDefinitionMetaProvider.test.d.ts +2 -0
  88. package/dist/data/__tests__/LocalDefinitionMetaProvider.test.d.ts.map +1 -0
  89. package/dist/data/__tests__/LocalDefinitionMetaProvider.test.js +21 -0
  90. package/dist/data/__tests__/LocalDefinitionMetaProvider.test.js.map +1 -0
  91. package/dist/data/__tests__/cascade.test.d.ts +2 -0
  92. package/dist/data/__tests__/cascade.test.d.ts.map +1 -0
  93. package/dist/data/__tests__/cascade.test.js +265 -0
  94. package/dist/data/__tests__/cascade.test.js.map +1 -0
  95. package/dist/data/__tests__/compute-server-conformance.test.d.ts +2 -0
  96. package/dist/data/__tests__/compute-server-conformance.test.d.ts.map +1 -0
  97. package/dist/data/__tests__/compute-server-conformance.test.js +21 -0
  98. package/dist/data/__tests__/compute-server-conformance.test.js.map +1 -0
  99. package/dist/data/__tests__/compute-server-encryption.test.d.ts +2 -0
  100. package/dist/data/__tests__/compute-server-encryption.test.d.ts.map +1 -0
  101. package/dist/data/__tests__/compute-server-encryption.test.js +131 -0
  102. package/dist/data/__tests__/compute-server-encryption.test.js.map +1 -0
  103. package/dist/data/__tests__/definition-conformance.test.d.ts +2 -0
  104. package/dist/data/__tests__/definition-conformance.test.d.ts.map +1 -0
  105. package/dist/data/__tests__/definition-conformance.test.js +20 -0
  106. package/dist/data/__tests__/definition-conformance.test.js.map +1 -0
  107. package/dist/data/__tests__/event-sink-conformance.test.d.ts +2 -0
  108. package/dist/data/__tests__/event-sink-conformance.test.d.ts.map +1 -0
  109. package/dist/data/__tests__/event-sink-conformance.test.js +24 -0
  110. package/dist/data/__tests__/event-sink-conformance.test.js.map +1 -0
  111. package/dist/data/__tests__/invite-conformance.test.d.ts +2 -0
  112. package/dist/data/__tests__/invite-conformance.test.d.ts.map +1 -0
  113. package/dist/data/__tests__/invite-conformance.test.js +21 -0
  114. package/dist/data/__tests__/invite-conformance.test.js.map +1 -0
  115. package/dist/data/__tests__/org-conformance.test.d.ts +2 -0
  116. package/dist/data/__tests__/org-conformance.test.d.ts.map +1 -0
  117. package/dist/data/__tests__/org-conformance.test.js +36 -0
  118. package/dist/data/__tests__/org-conformance.test.js.map +1 -0
  119. package/dist/data/__tests__/platform-project-grant-conformance.test.d.ts +2 -0
  120. package/dist/data/__tests__/platform-project-grant-conformance.test.d.ts.map +1 -0
  121. package/dist/data/__tests__/platform-project-grant-conformance.test.js +20 -0
  122. package/dist/data/__tests__/platform-project-grant-conformance.test.js.map +1 -0
  123. package/dist/data/__tests__/project-conformance.test.d.ts +2 -0
  124. package/dist/data/__tests__/project-conformance.test.d.ts.map +1 -0
  125. package/dist/data/__tests__/project-conformance.test.js +53 -0
  126. package/dist/data/__tests__/project-conformance.test.js.map +1 -0
  127. package/dist/data/__tests__/rules.test.d.ts +2 -0
  128. package/dist/data/__tests__/rules.test.d.ts.map +1 -0
  129. package/dist/data/__tests__/rules.test.js +484 -0
  130. package/dist/data/__tests__/rules.test.js.map +1 -0
  131. package/dist/data/__tests__/share-link-conformance.test.d.ts +2 -0
  132. package/dist/data/__tests__/share-link-conformance.test.d.ts.map +1 -0
  133. package/dist/data/__tests__/share-link-conformance.test.js +20 -0
  134. package/dist/data/__tests__/share-link-conformance.test.js.map +1 -0
  135. package/dist/data/fsJson.d.ts +12 -0
  136. package/dist/data/fsJson.d.ts.map +1 -0
  137. package/dist/data/fsJson.js +29 -0
  138. package/dist/data/fsJson.js.map +1 -0
  139. package/dist/data/index.d.ts +13 -0
  140. package/dist/data/index.d.ts.map +1 -0
  141. package/dist/data/index.js +9 -0
  142. package/dist/data/index.js.map +1 -0
  143. package/dist/data/pagination.d.ts +15 -0
  144. package/dist/data/pagination.d.ts.map +1 -0
  145. package/dist/data/pagination.js +36 -0
  146. package/dist/data/pagination.js.map +1 -0
  147. package/dist/data/secretCrypto.d.ts +23 -0
  148. package/dist/data/secretCrypto.d.ts.map +1 -0
  149. package/dist/data/secretCrypto.js +64 -0
  150. package/dist/data/secretCrypto.js.map +1 -0
  151. package/dist/data/userData.d.ts +40 -0
  152. package/dist/data/userData.d.ts.map +1 -0
  153. package/dist/data/userData.js +84 -0
  154. package/dist/data/userData.js.map +1 -0
  155. package/dist/definitions/LocalDefinitionMetaProvider.d.ts +27 -0
  156. package/dist/definitions/LocalDefinitionMetaProvider.d.ts.map +1 -0
  157. package/dist/definitions/LocalDefinitionMetaProvider.js +188 -0
  158. package/dist/definitions/LocalDefinitionMetaProvider.js.map +1 -0
  159. package/dist/definitions/__tests__/conformance.test.d.ts +2 -0
  160. package/dist/definitions/__tests__/conformance.test.d.ts.map +1 -0
  161. package/dist/definitions/__tests__/conformance.test.js +20 -0
  162. package/dist/definitions/__tests__/conformance.test.js.map +1 -0
  163. package/dist/definitions/index.d.ts +2 -0
  164. package/dist/definitions/index.d.ts.map +1 -0
  165. package/dist/definitions/index.js +2 -0
  166. package/dist/definitions/index.js.map +1 -0
  167. package/dist/definitions/providers/filesystem-files.d.ts +24 -0
  168. package/dist/definitions/providers/filesystem-files.d.ts.map +1 -0
  169. package/dist/definitions/providers/filesystem-files.js +170 -0
  170. package/dist/definitions/providers/filesystem-files.js.map +1 -0
  171. package/dist/definitions/providers/filesystem-meta.d.ts +17 -0
  172. package/dist/definitions/providers/filesystem-meta.d.ts.map +1 -0
  173. package/dist/definitions/providers/filesystem-meta.js +216 -0
  174. package/dist/definitions/providers/filesystem-meta.js.map +1 -0
  175. package/dist/fsJson.d.ts +12 -0
  176. package/dist/fsJson.d.ts.map +1 -0
  177. package/dist/fsJson.js +29 -0
  178. package/dist/fsJson.js.map +1 -0
  179. package/dist/index.d.ts +13 -0
  180. package/dist/index.d.ts.map +1 -0
  181. package/dist/index.js +16 -0
  182. package/dist/index.js.map +1 -0
  183. package/dist/invites/LocalInviteProvider.d.ts +24 -0
  184. package/dist/invites/LocalInviteProvider.d.ts.map +1 -0
  185. package/dist/invites/LocalInviteProvider.js +89 -0
  186. package/dist/invites/LocalInviteProvider.js.map +1 -0
  187. package/dist/invites/__tests__/conformance.test.d.ts +2 -0
  188. package/dist/invites/__tests__/conformance.test.d.ts.map +1 -0
  189. package/dist/invites/__tests__/conformance.test.js +21 -0
  190. package/dist/invites/__tests__/conformance.test.js.map +1 -0
  191. package/dist/organizations/LocalOrganizationProvider.d.ts +41 -0
  192. package/dist/organizations/LocalOrganizationProvider.d.ts.map +1 -0
  193. package/dist/organizations/LocalOrganizationProvider.js +198 -0
  194. package/dist/organizations/LocalOrganizationProvider.js.map +1 -0
  195. package/dist/organizations/__tests__/conformance.test.d.ts +2 -0
  196. package/dist/organizations/__tests__/conformance.test.d.ts.map +1 -0
  197. package/dist/organizations/__tests__/conformance.test.js +20 -0
  198. package/dist/organizations/__tests__/conformance.test.js.map +1 -0
  199. package/dist/organizations/index.d.ts +2 -0
  200. package/dist/organizations/index.d.ts.map +1 -0
  201. package/dist/organizations/index.js +2 -0
  202. package/dist/organizations/index.js.map +1 -0
  203. package/dist/pagination.d.ts +15 -0
  204. package/dist/pagination.d.ts.map +1 -0
  205. package/dist/pagination.js +36 -0
  206. package/dist/pagination.js.map +1 -0
  207. package/dist/permissions/LocalPlatformPermissionStore.d.ts +39 -0
  208. package/dist/permissions/LocalPlatformPermissionStore.d.ts.map +1 -0
  209. package/dist/permissions/LocalPlatformPermissionStore.js +117 -0
  210. package/dist/permissions/LocalPlatformPermissionStore.js.map +1 -0
  211. package/dist/permissions/__tests__/conformance.test.d.ts +2 -0
  212. package/dist/permissions/__tests__/conformance.test.d.ts.map +1 -0
  213. package/dist/permissions/__tests__/conformance.test.js +37 -0
  214. package/dist/permissions/__tests__/conformance.test.js.map +1 -0
  215. package/dist/permissions/index.d.ts +2 -0
  216. package/dist/permissions/index.d.ts.map +1 -0
  217. package/dist/permissions/index.js +2 -0
  218. package/dist/permissions/index.js.map +1 -0
  219. package/dist/projects/LocalProjectProvider.d.ts +21 -0
  220. package/dist/projects/LocalProjectProvider.d.ts.map +1 -0
  221. package/dist/projects/LocalProjectProvider.js +125 -0
  222. package/dist/projects/LocalProjectProvider.js.map +1 -0
  223. package/dist/projects/__tests__/conformance.test.d.ts +2 -0
  224. package/dist/projects/__tests__/conformance.test.d.ts.map +1 -0
  225. package/dist/projects/__tests__/conformance.test.js +44 -0
  226. package/dist/projects/__tests__/conformance.test.js.map +1 -0
  227. package/dist/projects/index.d.ts +2 -0
  228. package/dist/projects/index.d.ts.map +1 -0
  229. package/dist/projects/index.js +2 -0
  230. package/dist/projects/index.js.map +1 -0
  231. package/dist/storage/LocalStorageProvider.d.ts +27 -0
  232. package/dist/storage/LocalStorageProvider.d.ts.map +1 -0
  233. package/dist/storage/LocalStorageProvider.js +74 -0
  234. package/dist/storage/LocalStorageProvider.js.map +1 -0
  235. package/dist/storage/__tests__/conformance.test.d.ts +2 -0
  236. package/dist/storage/__tests__/conformance.test.d.ts.map +1 -0
  237. package/dist/storage/__tests__/conformance.test.js +20 -0
  238. package/dist/storage/__tests__/conformance.test.js.map +1 -0
  239. package/dist/storage/index.d.ts +2 -0
  240. package/dist/storage/index.d.ts.map +1 -0
  241. package/dist/storage/index.js +2 -0
  242. package/dist/storage/index.js.map +1 -0
  243. package/dist/userProfile/LocalUserProfileProvider.d.ts +25 -0
  244. package/dist/userProfile/LocalUserProfileProvider.d.ts.map +1 -0
  245. package/dist/userProfile/LocalUserProfileProvider.js +110 -0
  246. package/dist/userProfile/LocalUserProfileProvider.js.map +1 -0
  247. package/dist/userProfile/__tests__/conformance.test.d.ts +2 -0
  248. package/dist/userProfile/__tests__/conformance.test.d.ts.map +1 -0
  249. package/dist/userProfile/__tests__/conformance.test.js +40 -0
  250. package/dist/userProfile/__tests__/conformance.test.js.map +1 -0
  251. package/dist/userProfile/index.d.ts +2 -0
  252. package/dist/userProfile/index.d.ts.map +1 -0
  253. package/dist/userProfile/index.js +2 -0
  254. package/dist/userProfile/index.js.map +1 -0
  255. package/package.json +70 -0
  256. package/src/README.md +37 -0
  257. package/src/auth/LocalAuthProvider.ts +165 -0
  258. package/src/auth/__tests__/conformance.test.ts +40 -0
  259. package/src/auth/hmac.ts +53 -0
  260. package/src/auth/index.ts +5 -0
  261. package/src/auth/users.ts +151 -0
  262. package/src/data/LocalComputeServerStore.ts +290 -0
  263. package/src/data/LocalDataProvider.ts +148 -0
  264. package/src/data/LocalDefinitionStore.ts +369 -0
  265. package/src/data/LocalInviteStore.ts +117 -0
  266. package/src/data/LocalOrgStore.ts +356 -0
  267. package/src/data/LocalPlatformProjectGrantStore.ts +85 -0
  268. package/src/data/LocalProjectStore.ts +274 -0
  269. package/src/data/LocalShareLinkStore.ts +138 -0
  270. package/src/data/__tests__/cascade.test.ts +300 -0
  271. package/src/data/__tests__/compute-server-conformance.test.ts +26 -0
  272. package/src/data/__tests__/compute-server-encryption.test.ts +185 -0
  273. package/src/data/__tests__/definition-conformance.test.ts +23 -0
  274. package/src/data/__tests__/event-sink-conformance.test.ts +28 -0
  275. package/src/data/__tests__/invite-conformance.test.ts +24 -0
  276. package/src/data/__tests__/org-conformance.test.ts +43 -0
  277. package/src/data/__tests__/platform-project-grant-conformance.test.ts +24 -0
  278. package/src/data/__tests__/project-conformance.test.ts +64 -0
  279. package/src/data/__tests__/rules.test.ts +682 -0
  280. package/src/data/__tests__/share-link-conformance.test.ts +23 -0
  281. package/src/data/fsJson.ts +28 -0
  282. package/src/data/index.ts +16 -0
  283. package/src/data/pagination.ts +48 -0
  284. package/src/data/secretCrypto.ts +69 -0
  285. package/src/data/userData.ts +134 -0
  286. package/src/index.ts +42 -0
  287. package/src/permissions/LocalPlatformPermissionStore.ts +129 -0
  288. package/src/permissions/__tests__/conformance.test.ts +40 -0
  289. package/src/permissions/index.ts +1 -0
  290. package/src/storage/LocalStorageProvider.ts +78 -0
  291. package/src/storage/__tests__/conformance.test.ts +23 -0
  292. package/src/storage/index.ts +1 -0
  293. package/src/userProfile/LocalUserProfileProvider.ts +135 -0
  294. package/src/userProfile/__tests__/conformance.test.ts +43 -0
  295. package/src/userProfile/index.ts +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance.test.js","sourceRoot":"","sources":["../../../src/userProfile/__tests__/conformance.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACzC,IAAI,OAAe,CAAC;IAEpB,UAAU,CAAC,KAAK,IAAI,EAAE;QACrB,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,8BAA8B,CAAC;QAC9B,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,KAAK,IAAI,EAAE;YACvB,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC;gBAClC,UAAU,EAAE,aAAa;gBACzB,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC;aACpD,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAC1D,MAAM,QAAQ,GAAG,wBAAwB,CAAC,YAAY,CAAC,CAAC;YACxD,MAAM,KAAK,GAAG,IAAI,wBAAwB,CAAC,YAAY,CAAC,CAAC;YACzD,OAAO;gBACN,KAAK;gBACL,QAAQ,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;oBACjC,gEAAgE;oBAChE,8DAA8D;oBAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;oBACzE,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC/B,OAAO,IAAI,CAAC;gBACb,CAAC;aACD,CAAC;QACH,CAAC;KACD,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { LocalUserProfileProvider } from './LocalUserProfileProvider.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/userProfile/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { LocalUserProfileProvider } from './LocalUserProfileProvider.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/userProfile/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@selvajs/local-provider",
3
+ "version": "0.11.0",
4
+ "description": "Local filesystem, JSON, and HMAC implementations of @selvajs/platform interfaces",
5
+ "license": "MIT",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/VektorNode/selva.git",
12
+ "directory": "packages/providers/local"
13
+ },
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "source": "./src/index.ts",
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ },
23
+ "./auth": {
24
+ "source": "./src/auth/index.ts",
25
+ "types": "./dist/auth/index.d.ts",
26
+ "import": "./dist/auth/index.js"
27
+ },
28
+ "./data": {
29
+ "source": "./src/data/index.ts",
30
+ "types": "./dist/data/index.d.ts",
31
+ "import": "./dist/data/index.js"
32
+ },
33
+ "./storage": {
34
+ "source": "./src/storage/index.ts",
35
+ "types": "./dist/storage/index.d.ts",
36
+ "import": "./dist/storage/index.js"
37
+ },
38
+ "./permissions": {
39
+ "source": "./src/permissions/index.ts",
40
+ "types": "./dist/permissions/index.d.ts",
41
+ "import": "./dist/permissions/index.js"
42
+ },
43
+ "./userProfile": {
44
+ "source": "./src/userProfile/index.ts",
45
+ "types": "./dist/userProfile/index.d.ts",
46
+ "import": "./dist/userProfile/index.js"
47
+ }
48
+ },
49
+ "files": [
50
+ "dist",
51
+ "src"
52
+ ],
53
+ "dependencies": {
54
+ "sharp": "^0.34.5",
55
+ "zod": "^4.3.6",
56
+ "@selvajs/platform": "0.11.0"
57
+ },
58
+ "devDependencies": {
59
+ "@types/node": "^22.19.17",
60
+ "typescript": "^5.9.3",
61
+ "vitest": "^3.2.4"
62
+ },
63
+ "scripts": {
64
+ "build": "tsc",
65
+ "dev": "tsc --watch",
66
+ "type-check": "tsc --noEmit",
67
+ "test": "vitest run",
68
+ "test:watch": "vitest"
69
+ }
70
+ }
package/src/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # local-provider
2
+
3
+ Filesystem implementation of `@selvajs/platform` interfaces. Each subfolder implements one provider (auth, data, storage, organizations, projects, definitions, computeServer).
4
+
5
+ ## fsJson.ts
6
+
7
+ Shared helpers used by every JSON-backed store in this package.
8
+
9
+ ### `readJsonFile<T>(filePath, fallback)`
10
+
11
+ Reads and parses a JSON file. Returns `fallback` if the file doesn't exist (`ENOENT`); any other error propagates. Lets stores boot against an empty data directory without pre-seeding files.
12
+
13
+ ```ts
14
+ const { users } = await readJsonFile<UsersFile>(path, { users: [] });
15
+ ```
16
+
17
+ ### `writeJsonFile<T>(filePath, data)`
18
+
19
+ Atomic write: ensures the parent directory exists, writes to `<path>.tmp`, then renames into place. The rename is atomic on POSIX, so a crash mid-write leaves either the old file or the new one — never a half-written JSON blob.
20
+
21
+ ```ts
22
+ await writeJsonFile(path, { users: [...] });
23
+ ```
24
+
25
+ ### Why this exists
26
+
27
+ All stores follow a read-modify-write pattern on small JSON files. Centralizing it means:
28
+
29
+ - One place to get atomicity right (no partial writes on crash)
30
+ - One place to handle "file doesn't exist yet" (fallback instead of try/catch everywhere)
31
+ - Tab-indented JSON output for readable diffs when data dirs are checked into git
32
+
33
+ ### Caveats
34
+
35
+ - Not safe across **processes** — no file locking. Fine for a single dev server; don't point two processes at the same data dir.
36
+ - In-process concurrent writes on the same file can still race. Stores that need serialization wrap calls in their own mutex.
37
+ - Each write rewrites the whole file. Fine for config-scale data (users, orgs, projects); not for high-churn or large datasets.
@@ -0,0 +1,165 @@
1
+ import * as path from 'node:path';
2
+ import type {
3
+ IAuthProvider,
4
+ IPasswordAuth,
5
+ AuthUser,
6
+ LoginResult,
7
+ UserManagementResult,
8
+ ListOptions,
9
+ Page
10
+ } from '@selvajs/platform';
11
+ import { ProviderError } from '@selvajs/platform';
12
+ import { signHmacToken, verifyHmacToken } from './hmac.js';
13
+ import { verifyPasswordHash, createLocalAuthUserStore } from './users.js';
14
+ import type { LocalAuthUserStore, StoredAuthUser } from './users.js';
15
+ import { paginate } from '../data/pagination.js';
16
+
17
+ const SESSION_MAX_AGE_MS = 8 * 60 * 60 * 1000; // 8 hours
18
+
19
+ function toAuthUser(
20
+ u: Pick<StoredAuthUser, 'id' | 'email' | 'createdAt' | 'lastLoginAt' | 'disabled'>
21
+ ): AuthUser {
22
+ return {
23
+ id: u.id,
24
+ email: u.email,
25
+ createdAt: u.createdAt,
26
+ lastLoginAt: u.lastLoginAt,
27
+ disabled: u.disabled
28
+ };
29
+ }
30
+
31
+ export interface LocalAuthProviderConfig {
32
+ /** HMAC signing secret. Pass from env (SELVA_HMAC_KEY). */
33
+ hmacSecret: string;
34
+ /**
35
+ * Absolute path to auth-users.json — identity-only storage. Per-user app
36
+ * state (permissions, profile, starred defs, recent runs) lives in
37
+ * `user-data.json`, owned by `LocalDataProvider`. The two files key on
38
+ * the same user ID and are written independently.
39
+ */
40
+ usersFilePath?: string;
41
+ }
42
+
43
+ class LocalPasswordAuth implements IPasswordAuth {
44
+ constructor(
45
+ private readonly users: LocalAuthUserStore | undefined,
46
+ private readonly mintToken: (user: AuthUser) => string
47
+ ) {}
48
+
49
+ async verifyLogin(email: string, password: string): Promise<LoginResult> {
50
+ if (!this.users) return { kind: 'failed', reason: 'invalid_credentials' };
51
+ const user = await this.users.findByEmail(email);
52
+ if (!user) return { kind: 'failed', reason: 'invalid_credentials' };
53
+ if (user.disabled) return { kind: 'failed', reason: 'disabled' };
54
+ if (!user.passwordHash || !(await verifyPasswordHash(password, user.passwordHash))) {
55
+ return { kind: 'failed', reason: 'invalid_credentials' };
56
+ }
57
+ await this.users.touchLastLogin(user.id).catch(() => {});
58
+ const auth = toAuthUser(user);
59
+ return { kind: 'success', user: auth, sessionToken: this.mintToken(auth) };
60
+ }
61
+
62
+ async createUserWithPassword(email: string, password: string): Promise<AuthUser> {
63
+ if (!this.users) {
64
+ throw new ProviderError(
65
+ 'createUserWithPassword requires a users.json backend (DATA_PATH)',
66
+ 500
67
+ );
68
+ }
69
+ // Identity-only — platform permissions and the user-data row are seeded
70
+ // separately via `IDataProvider.ensureUser` + `IPlatformPermissionStore.set`.
71
+ return toAuthUser(await this.users.createUser(email, password));
72
+ }
73
+
74
+ async registerUser(email: string, password: string): Promise<AuthUser | null> {
75
+ if (!this.users) return null;
76
+ return toAuthUser(await this.users.createUser(email, password));
77
+ }
78
+ }
79
+
80
+ export class LocalAuthProvider implements IAuthProvider {
81
+ private readonly hmacSecret: string;
82
+ private readonly users?: LocalAuthUserStore;
83
+
84
+ readonly name = 'Local';
85
+ readonly passwordAuth: IPasswordAuth;
86
+
87
+ constructor(config: LocalAuthProviderConfig) {
88
+ this.hmacSecret = config.hmacSecret;
89
+ if (config.usersFilePath) {
90
+ this.users = createLocalAuthUserStore(config.usersFilePath);
91
+ }
92
+ this.passwordAuth = new LocalPasswordAuth(this.users, (user) =>
93
+ signHmacToken(this.hmacSecret, user.id, SESSION_MAX_AGE_MS)
94
+ );
95
+ }
96
+
97
+ static fromEnv(env: Record<string, string | undefined>): LocalAuthProvider {
98
+ const hmacSecret = env.SELVA_HMAC_KEY;
99
+ if (!hmacSecret) throw new Error('Missing required env var: SELVA_HMAC_KEY');
100
+ return new LocalAuthProvider({
101
+ hmacSecret,
102
+ usersFilePath: env.DATA_PATH ? path.join(env.DATA_PATH, 'auth-users.json') : undefined
103
+ });
104
+ }
105
+
106
+ /** Verify an HMAC session token and return the live user record. */
107
+ async verifyToken(token: string): Promise<AuthUser | null> {
108
+ const { valid, userId } = verifyHmacToken(token, this.hmacSecret);
109
+ if (!valid) return null;
110
+ if (!this.users) return null;
111
+ const u = await this.users.findById(userId);
112
+ if (!u || u.disabled) return null;
113
+ await this.users.touchLastLogin(u.id).catch(() => {});
114
+ return toAuthUser(u);
115
+ }
116
+
117
+ async touchLastLogin(id: string): Promise<void> {
118
+ if (!this.users) return;
119
+ await this.users.touchLastLogin(id);
120
+ }
121
+
122
+ async getUser(id: string): Promise<AuthUser | null> {
123
+ if (!this.users) return null;
124
+ const u = await this.users.findById(id);
125
+ return u ? toAuthUser(u) : null;
126
+ }
127
+
128
+ async listUsers(opts?: ListOptions): Promise<Page<AuthUser> | null> {
129
+ if (!this.users) return null;
130
+ const users = await this.users.listUsers();
131
+ return paginate(users.map(toAuthUser), opts);
132
+ }
133
+
134
+ async deleteUser(id: string): Promise<UserManagementResult> {
135
+ // Identity-only delete. The §2 sole-`instance_admin` invariant is
136
+ // enforced by the caller via `IPlatformPermissionStore.countInstanceAdminsExcluding`
137
+ // before this method is called. The caller is also responsible for
138
+ // removing the user-data row via `LocalDataProvider`'s cascade hook.
139
+ if (!this.users) return 'not_supported';
140
+ const target = await this.users.findById(id);
141
+ if (!target) return 'not_found';
142
+ try {
143
+ await this.users.deleteUser(id);
144
+ return 'ok';
145
+ } catch (err) {
146
+ if (err instanceof ProviderError && err.statusCode === 404) return 'not_found';
147
+ throw err;
148
+ }
149
+ }
150
+
151
+ async disableUser(id: string): Promise<UserManagementResult> {
152
+ // Identity-only disable. The §2 sole-`instance_admin` invariant is
153
+ // enforced by the caller, same as `deleteUser`.
154
+ if (!this.users) return 'not_supported';
155
+ const target = await this.users.findById(id);
156
+ if (!target) return 'not_found';
157
+ try {
158
+ await this.users.setDisabled(id, true);
159
+ return 'ok';
160
+ } catch (err) {
161
+ if (err instanceof ProviderError && err.statusCode === 404) return 'not_found';
162
+ throw err;
163
+ }
164
+ }
165
+ }
@@ -0,0 +1,40 @@
1
+ import { describe, beforeEach, afterEach } from 'vitest';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import * as os from 'node:os';
5
+ import { runAuthProviderConformance } from '@selvajs/platform/testing';
6
+ import { LocalAuthProvider } from '../LocalAuthProvider.js';
7
+
8
+ const TEST_SECRET = 'test-hmac-secret-for-conformance';
9
+ const ADMIN_EMAIL = 'conformance-admin@example.com';
10
+ const ADMIN_PASSWORD = 'test-admin-password';
11
+
12
+ describe('LocalAuthProvider — auth-users.json mode', () => {
13
+ let tempDir: string;
14
+
15
+ beforeEach(async () => {
16
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'selva-auth-test-'));
17
+ });
18
+
19
+ afterEach(async () => {
20
+ await fs.rm(tempDir, { recursive: true, force: true });
21
+ });
22
+
23
+ runAuthProviderConformance({
24
+ name: 'LocalAuthProvider/auth-users-json',
25
+ createProvider: async () => {
26
+ const provider = new LocalAuthProvider({
27
+ hmacSecret: TEST_SECRET,
28
+ usersFilePath: path.join(tempDir, 'auth-users.json')
29
+ });
30
+ // Idempotent seed — the conformance suite calls createProvider per test,
31
+ // but a single test may invoke it more than once.
32
+ const existing = await provider.passwordAuth.verifyLogin(ADMIN_EMAIL, ADMIN_PASSWORD);
33
+ if (existing.kind !== 'success') {
34
+ await provider.passwordAuth.createUserWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
35
+ }
36
+ return { provider, adminEmail: ADMIN_EMAIL, adminPassword: ADMIN_PASSWORD };
37
+ },
38
+ userManagement: true
39
+ });
40
+ });
@@ -0,0 +1,53 @@
1
+ import { timingSafeEqual, createHmac } from 'node:crypto';
2
+
3
+ const DEFAULT_MAX_AGE_MS = 8 * 60 * 60 * 1000; // 8 hours
4
+
5
+ /**
6
+ * Token format: base64url(userId + ':' + expiry) + '.' + hmac(payload)
7
+ *
8
+ * The userId is embedded so verifyToken can look up the live user record
9
+ * (and therefore always reflect the current permissions, not stale ones
10
+ * baked into the token at login time).
11
+ */
12
+ export function signHmacToken(
13
+ secret: string,
14
+ userId: string,
15
+ maxAgeMs = DEFAULT_MAX_AGE_MS
16
+ ): string {
17
+ const expiry = Date.now() + maxAgeMs;
18
+ const payload = Buffer.from(`${userId}:${expiry}`).toString('base64url');
19
+ const sig = createHmac('sha256', secret).update(payload).digest('base64url');
20
+ return `${payload}.${sig}`;
21
+ }
22
+
23
+ export interface HmacTokenPayload {
24
+ userId: string;
25
+ valid: boolean;
26
+ }
27
+
28
+ /**
29
+ * Verify an HMAC token. Returns the userId if valid and unexpired, or
30
+ * { valid: false } if the signature is wrong or the token has expired.
31
+ */
32
+ export function verifyHmacToken(token: string, secret: string): HmacTokenPayload {
33
+ const dot = token.lastIndexOf('.');
34
+ if (dot === -1) return { userId: '', valid: false };
35
+
36
+ const payload = token.slice(0, dot);
37
+ const sig = token.slice(dot + 1);
38
+ const expectedSig = createHmac('sha256', secret).update(payload).digest('base64url');
39
+
40
+ const a = Buffer.from(sig);
41
+ const b = Buffer.from(expectedSig);
42
+ if (a.length !== b.length || !timingSafeEqual(a, b)) return { userId: '', valid: false };
43
+
44
+ const decoded = Buffer.from(payload, 'base64url').toString();
45
+ const colon = decoded.lastIndexOf(':');
46
+ if (colon === -1) return { userId: '', valid: false };
47
+
48
+ const userId = decoded.slice(0, colon);
49
+ const expiry = parseInt(decoded.slice(colon + 1), 10);
50
+ if (!Number.isFinite(expiry) || Date.now() >= expiry) return { userId: '', valid: false };
51
+
52
+ return { userId, valid: true };
53
+ }
@@ -0,0 +1,5 @@
1
+ export { LocalAuthProvider } from './LocalAuthProvider.js';
2
+ export type { LocalAuthProviderConfig } from './LocalAuthProvider.js';
3
+ export { signHmacToken, verifyHmacToken } from './hmac.js';
4
+ export { hashPassword, verifyPasswordHash, createLocalAuthUserStore } from './users.js';
5
+ export type { StoredAuthUser, AuthUsersFile, LocalAuthUserStore } from './users.js';
@@ -0,0 +1,151 @@
1
+ import * as crypto from 'node:crypto';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { ProviderError } from '@selvajs/platform';
4
+ import { readJsonFile, writeJsonFile } from '../data/fsJson.js';
5
+
6
+ /**
7
+ * Identity-only on-disk shape. Per-user app state (permissions, profile,
8
+ * starred definitions, recent runs) lives in `user-data.json`, owned by
9
+ * `LocalDataProvider`. This split lets `LocalAuthProvider` be paired with any
10
+ * data provider, and any auth provider be paired with `LocalDataProvider`,
11
+ * without one stepping on the other.
12
+ */
13
+ export interface StoredAuthUser {
14
+ id: string;
15
+ email: string;
16
+ /**
17
+ * "pbkdf2:sha256:<iterations>:<salt>:<hash>" — all binary values base64url encoded.
18
+ * Null for OAuth-only users (allowlisted email, no password stored).
19
+ */
20
+ passwordHash: string | null;
21
+ createdAt: string; // ISO 8601
22
+ /** ISO 8601 — most recent successful credential login or token verification. */
23
+ lastLoginAt?: string;
24
+ /** When true, the provider MUST refuse to authenticate this user. */
25
+ disabled?: boolean;
26
+ }
27
+
28
+ /** Debounce window for lastLoginAt writes — skip if prior stamp is newer than this. */
29
+ const LAST_LOGIN_DEBOUNCE_MS = 60_000;
30
+
31
+ export interface AuthUsersFile {
32
+ users: StoredAuthUser[];
33
+ }
34
+
35
+ // ============================================================================
36
+ // PBKDF2 password hashing
37
+ // ============================================================================
38
+ const PBKDF2_ITERATIONS = 100_000;
39
+ const PBKDF2_KEYLEN = 32;
40
+ const PBKDF2_DIGEST = 'sha256';
41
+
42
+ export async function hashPassword(password: string): Promise<string> {
43
+ const salt = crypto.randomBytes(16).toString('base64url');
44
+ const hash = await new Promise<Buffer>((resolve, reject) =>
45
+ crypto.pbkdf2(password, salt, PBKDF2_ITERATIONS, PBKDF2_KEYLEN, PBKDF2_DIGEST, (err, key) =>
46
+ err ? reject(err) : resolve(key)
47
+ )
48
+ );
49
+ return `pbkdf2:${PBKDF2_DIGEST}:${PBKDF2_ITERATIONS}:${salt}:${hash.toString('base64url')}`;
50
+ }
51
+
52
+ export async function verifyPasswordHash(password: string, storedHash: string): Promise<boolean> {
53
+ const parts = storedHash.split(':');
54
+ if (parts.length !== 5 || parts[0] !== 'pbkdf2') return false;
55
+ const [, digest, iterStr, salt, expectedHashB64] = parts;
56
+ const iterations = parseInt(iterStr, 10);
57
+ if (!Number.isFinite(iterations) || iterations <= 0) return false;
58
+
59
+ const expected = Buffer.from(expectedHashB64, 'base64url');
60
+ const actual = await new Promise<Buffer>((resolve, reject) =>
61
+ crypto.pbkdf2(password, salt, iterations, PBKDF2_KEYLEN, digest, (err, key) =>
62
+ err ? reject(err) : resolve(key)
63
+ )
64
+ );
65
+
66
+ if (actual.length !== expected.length) return false;
67
+ return crypto.timingSafeEqual(actual, expected);
68
+ }
69
+
70
+ // ============================================================================
71
+ // CRUD
72
+ // ============================================================================
73
+ // Fresh object per call — `readJsonFile` returns its fallback by reference
74
+ // when the file is missing, so a shared singleton would let one test (or
75
+ // one process write) mutate state visible to the next read.
76
+ const empty = (): AuthUsersFile => ({ users: [] });
77
+
78
+ export interface LocalAuthUserStore {
79
+ findByEmail(email: string): Promise<StoredAuthUser | null>;
80
+ findById(id: string): Promise<StoredAuthUser | null>;
81
+ listUsers(): Promise<Omit<StoredAuthUser, 'passwordHash'>[]>;
82
+ /** password null = OAuth allowlist entry (no password stored) */
83
+ createUser(email: string, password: string | null): Promise<StoredAuthUser>;
84
+ setDisabled(id: string, disabled: boolean): Promise<void>;
85
+ touchLastLogin(id: string): Promise<void>;
86
+ deleteUser(id: string): Promise<void>;
87
+ }
88
+
89
+ export function createLocalAuthUserStore(usersFilePath: string): LocalAuthUserStore {
90
+ return {
91
+ async findByEmail(email) {
92
+ const { users } = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
93
+ return users.find((u) => u.email.toLowerCase() === email.toLowerCase()) ?? null;
94
+ },
95
+
96
+ async findById(id) {
97
+ const { users } = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
98
+ return users.find((u) => u.id === id) ?? null;
99
+ },
100
+
101
+ async listUsers() {
102
+ const { users } = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
103
+ return users.map(({ passwordHash: _ph, ...rest }) => rest);
104
+ },
105
+
106
+ async createUser(email, password) {
107
+ const file = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
108
+ if (file.users.some((u) => u.email.toLowerCase() === email.toLowerCase())) {
109
+ throw new ProviderError(`User with email "${email}" already exists`, 409);
110
+ }
111
+ const user: StoredAuthUser = {
112
+ id: randomUUID(),
113
+ email,
114
+ passwordHash: password !== null ? await hashPassword(password) : null,
115
+ createdAt: new Date().toISOString()
116
+ };
117
+ file.users.push(user);
118
+ await writeJsonFile(usersFilePath, file);
119
+ return user;
120
+ },
121
+
122
+ async setDisabled(id, disabled) {
123
+ const file = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
124
+ const user = file.users.find((u) => u.id === id);
125
+ if (!user) throw new ProviderError(`User "${id}" not found`, 404);
126
+ user.disabled = disabled;
127
+ await writeJsonFile(usersFilePath, file);
128
+ },
129
+
130
+ async touchLastLogin(id) {
131
+ const file = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
132
+ const user = file.users.find((u) => u.id === id);
133
+ if (!user) return;
134
+ const now = Date.now();
135
+ if (user.lastLoginAt) {
136
+ const prev = Date.parse(user.lastLoginAt);
137
+ if (Number.isFinite(prev) && now - prev < LAST_LOGIN_DEBOUNCE_MS) return;
138
+ }
139
+ user.lastLoginAt = new Date(now).toISOString();
140
+ await writeJsonFile(usersFilePath, file);
141
+ },
142
+
143
+ async deleteUser(id) {
144
+ const file = await readJsonFile<AuthUsersFile>(usersFilePath, empty());
145
+ const before = file.users.length;
146
+ file.users = file.users.filter((u) => u.id !== id);
147
+ if (file.users.length === before) throw new ProviderError(`User "${id}" not found`, 404);
148
+ await writeJsonFile(usersFilePath, file);
149
+ }
150
+ };
151
+ }