ldap-rest 1.2.1 → 2.0.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 (358) hide show
  1. package/bin/sync-james.mjs +13 -2
  2. package/dist/abstract/ldapFlat.js +1 -1
  3. package/dist/abstract/plugin.js +1 -1
  4. package/dist/abstract/twakePlugin.js +1 -1
  5. package/dist/bin/index.js +1 -1
  6. package/dist/config/args.js +1 -1
  7. package/dist/config/options.js +1 -0
  8. package/dist/config/schema.js +1 -1
  9. package/dist/lib/auth/base.js +1 -1
  10. package/dist/lib/authz/base.js +1 -1
  11. package/dist/lib/entitySchema/validator.js +1 -1
  12. package/dist/lib/errors.js +1 -1
  13. package/dist/lib/expressFormatedResponses.js +1 -1
  14. package/dist/lib/health.js +1 -1
  15. package/dist/lib/hookBus.js +1 -0
  16. package/dist/lib/instanceProviders.js +1 -1
  17. package/dist/lib/ldap/callerView.js +1 -0
  18. package/dist/lib/ldap/pool.js +1 -0
  19. package/dist/lib/ldap/schema.js +1 -0
  20. package/dist/lib/ldap/searchCache.js +1 -0
  21. package/dist/lib/ldapActions.js +1 -1
  22. package/dist/lib/ldapSchema.js +1 -1
  23. package/dist/lib/parseConfig.js +1 -1
  24. package/dist/lib/route.js +1 -0
  25. package/dist/lib/schemaFile.js +1 -1
  26. package/dist/lib/services/index.js +1 -0
  27. package/dist/lib/storage/store.js +1 -1
  28. package/dist/lib/utils.js +1 -1
  29. package/dist/lib/version.js +1 -0
  30. package/dist/logger/winston.js +1 -1
  31. package/dist/plugins/auth/auth.options.js +1 -0
  32. package/dist/plugins/auth/authzDynamic.js +1 -1
  33. package/dist/plugins/auth/authzLinid1.js +1 -1
  34. package/dist/plugins/auth/authzPerBranch.js +1 -1
  35. package/dist/plugins/auth/authzPerRoute.js +1 -1
  36. package/dist/plugins/auth/authzScope.js +1 -1
  37. package/dist/plugins/auth/crowdsec.js +1 -1
  38. package/dist/plugins/auth/fake.js +1 -1
  39. package/dist/plugins/auth/hmac.js +1 -1
  40. package/dist/plugins/auth/llng.js +1 -1
  41. package/dist/plugins/auth/openidconnect.js +1 -1
  42. package/dist/plugins/auth/rateLimit.js +1 -1
  43. package/dist/plugins/auth/token.js +1 -1
  44. package/dist/plugins/auth/totp.js +1 -1
  45. package/dist/plugins/auth/trustedProxy.js +1 -1
  46. package/dist/plugins/bcl.js +1 -1
  47. package/dist/plugins/bcl.options.js +1 -0
  48. package/dist/plugins/configApi.js +1 -1
  49. package/dist/plugins/demo/helloworld.js +1 -1
  50. package/dist/plugins/ldap/accountLifecycle.js +1 -1
  51. package/dist/plugins/ldap/bulkImport.js +1 -1
  52. package/dist/plugins/ldap/departmentSync.js +1 -1
  53. package/dist/plugins/ldap/enterpriseRules.js +1 -1
  54. package/dist/plugins/ldap/externalUsersInGroups.js +1 -1
  55. package/dist/plugins/ldap/flatGeneric.js +1 -1
  56. package/dist/plugins/ldap/groups.js +1 -1
  57. package/dist/plugins/ldap/ldap.options.js +1 -0
  58. package/dist/plugins/ldap/onChange.js +1 -1
  59. package/dist/plugins/ldap/organizations.js +1 -1
  60. package/dist/plugins/ldap/passwordPolicy.js +1 -1
  61. package/dist/plugins/ldap/raw.js +1 -1
  62. package/dist/plugins/ldap/trash.js +1 -1
  63. package/dist/plugins/metrics.js +1 -1
  64. package/dist/plugins/metrics.options.js +1 -0
  65. package/dist/plugins/rabbitmq.js +1 -1
  66. package/dist/plugins/rabbitmq.options.js +1 -0
  67. package/dist/plugins/scim/baseResolver.js +1 -1
  68. package/dist/plugins/scim/bulk.js +1 -1
  69. package/dist/plugins/scim/discovery.js +1 -1
  70. package/dist/plugins/scim/errors.js +1 -1
  71. package/dist/plugins/scim/filter.js +1 -1
  72. package/dist/plugins/scim/groups.js +1 -1
  73. package/dist/plugins/scim/mapping.js +1 -1
  74. package/dist/plugins/scim/patch.js +1 -1
  75. package/dist/plugins/scim/scim.js +1 -1
  76. package/dist/plugins/scim/scim.options.js +1 -0
  77. package/dist/plugins/scim/users.js +1 -1
  78. package/dist/plugins/static.js +1 -1
  79. package/dist/plugins/static.options.js +1 -0
  80. package/dist/plugins/storage/file.js +1 -1
  81. package/dist/plugins/storage/ldap.js +1 -1
  82. package/dist/plugins/storage/postgres.js +1 -1
  83. package/dist/plugins/storage/valkey.js +1 -1
  84. package/dist/plugins/storage.js +1 -1
  85. package/dist/plugins/storage.options.js +1 -0
  86. package/dist/plugins/twake/appAccounts.options.js +1 -0
  87. package/dist/plugins/twake/appAccountsApi.js +1 -1
  88. package/dist/plugins/twake/appAccountsConsistency.js +1 -1
  89. package/dist/plugins/twake/calendar.js +1 -1
  90. package/dist/plugins/twake/calendar.options.js +1 -0
  91. package/dist/plugins/twake/calendarResources.js +1 -1
  92. package/dist/plugins/twake/cloudery.options.js +1 -0
  93. package/dist/plugins/twake/clouderyProvision.js +1 -1
  94. package/dist/plugins/twake/cozy.options.js +1 -0
  95. package/dist/plugins/twake/cozyProvision.js +1 -1
  96. package/dist/plugins/twake/drive.js +1 -1
  97. package/dist/plugins/twake/drive.options.js +1 -0
  98. package/dist/plugins/twake/groups.js +1 -1
  99. package/dist/plugins/twake/instances.js +1 -1
  100. package/dist/plugins/twake/james.js +1 -1
  101. package/dist/plugins/twake/james.options.js +1 -0
  102. package/dist/plugins/twake/lifecycleAttributes.js +1 -1
  103. package/dist/plugins/twake/lifecycleEvents.js +1 -1
  104. package/dist/plugins/twake/migrationProxy.js +1 -1
  105. package/dist/plugins/twake/migrationProxy.options.js +1 -0
  106. package/dist/plugins/twake/spaces.js +1 -1
  107. package/dist/plugins/twake/tombstone.js +1 -1
  108. package/dist/plugins/twake/twakeGroups.options.js +1 -0
  109. package/dist/plugins/twake/twakeInstances.options.js +1 -0
  110. package/dist/plugins/twake/twakeLifecycle.options.js +1 -0
  111. package/dist/plugins/twake/twakeSpaces.options.js +1 -0
  112. package/dist/plugins/twake/twakeTombstone.options.js +1 -0
  113. package/dist/plugins/weblogs.js +1 -1
  114. package/dist/src/abstract/ldapFlat.d.ts +41 -10
  115. package/dist/src/abstract/plugin.d.ts +31 -5
  116. package/dist/src/abstract/twakePlugin.d.ts +14 -4
  117. package/dist/src/bin/index.d.ts +35 -4
  118. package/dist/src/config/args.d.ts +2 -4
  119. package/dist/src/config/options.d.ts +104 -0
  120. package/dist/src/config/schema.d.ts +50 -1
  121. package/dist/src/hooks.d.ts +60 -22
  122. package/dist/src/lib/authz/base.d.ts +4 -51
  123. package/dist/src/lib/authz/composition.d.ts +2 -2
  124. package/dist/src/lib/entitySchema/validator.d.ts +63 -6
  125. package/dist/src/lib/errors.d.ts +57 -1
  126. package/dist/src/lib/expressFormatedResponses.d.ts +49 -7
  127. package/dist/src/lib/hookBus.d.ts +226 -0
  128. package/dist/src/lib/instanceProviders.d.ts +0 -8
  129. package/dist/src/lib/ldap/callerView.d.ts +45 -0
  130. package/dist/src/lib/ldap/pool.d.ts +108 -0
  131. package/dist/src/lib/ldap/schema.d.ts +157 -0
  132. package/dist/src/lib/ldap/searchCache.d.ts +112 -0
  133. package/dist/src/lib/ldapActions.d.ts +26 -256
  134. package/dist/src/lib/parseConfig.d.ts +31 -2
  135. package/dist/src/lib/route.d.ts +99 -0
  136. package/dist/src/lib/services/index.d.ts +56 -0
  137. package/dist/src/lib/utils.d.ts +100 -36
  138. package/dist/src/lib/version.d.ts +12 -0
  139. package/dist/src/plugins/auth/auth.options.d.ts +88 -0
  140. package/dist/src/plugins/auth/authzDynamic.d.ts +10 -1
  141. package/dist/src/plugins/auth/authzLinid1.d.ts +6 -0
  142. package/dist/src/plugins/auth/authzPerBranch.d.ts +9 -0
  143. package/dist/src/plugins/auth/authzPerRoute.d.ts +3 -0
  144. package/dist/src/plugins/auth/authzScope.d.ts +23 -14
  145. package/dist/src/plugins/auth/crowdsec.d.ts +5 -0
  146. package/dist/src/plugins/auth/fake.d.ts +3 -0
  147. package/dist/src/plugins/auth/hmac.d.ts +4 -0
  148. package/dist/src/plugins/auth/llng.d.ts +4 -0
  149. package/dist/src/plugins/auth/openidconnect.d.ts +7 -0
  150. package/dist/src/plugins/auth/rateLimit.d.ts +4 -0
  151. package/dist/src/plugins/auth/token.d.ts +3 -0
  152. package/dist/src/plugins/auth/totp.d.ts +5 -0
  153. package/dist/src/plugins/auth/trustedProxy.d.ts +4 -0
  154. package/dist/src/plugins/bcl.d.ts +3 -0
  155. package/dist/src/plugins/bcl.options.d.ts +8 -0
  156. package/dist/src/plugins/configApi.d.ts +24 -5
  157. package/dist/src/plugins/demo/helloworld.d.ts +8 -19
  158. package/dist/src/plugins/ldap/accountLifecycle.d.ts +17 -0
  159. package/dist/src/plugins/ldap/bulkImport.d.ts +6 -76
  160. package/dist/src/plugins/ldap/departmentSync.d.ts +1 -0
  161. package/dist/src/plugins/ldap/enterpriseRules.d.ts +8 -15
  162. package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +4 -0
  163. package/dist/src/plugins/ldap/flatGeneric.d.ts +4 -0
  164. package/dist/src/plugins/ldap/groups.d.ts +27 -11
  165. package/dist/src/plugins/ldap/ldap.options.d.ts +75 -0
  166. package/dist/src/plugins/ldap/onChange.d.ts +10 -2
  167. package/dist/src/plugins/ldap/organizations.d.ts +16 -0
  168. package/dist/src/plugins/ldap/passwordPolicy.d.ts +35 -3
  169. package/dist/src/plugins/ldap/raw.d.ts +50 -19
  170. package/dist/src/plugins/ldap/trash.d.ts +6 -0
  171. package/dist/src/plugins/metrics.d.ts +3 -0
  172. package/dist/src/plugins/metrics.options.d.ts +8 -0
  173. package/dist/src/plugins/rabbitmq.d.ts +3 -0
  174. package/dist/src/plugins/rabbitmq.options.d.ts +8 -0
  175. package/dist/src/plugins/scim/baseResolver.d.ts +2 -1
  176. package/dist/src/plugins/scim/bulk.d.ts +6 -7
  177. package/dist/src/plugins/scim/discovery.d.ts +3 -0
  178. package/dist/src/plugins/scim/errors.d.ts +2 -1
  179. package/dist/src/plugins/scim/groups.d.ts +6 -4
  180. package/dist/src/plugins/scim/mapping.d.ts +16 -3
  181. package/dist/src/plugins/scim/scim.d.ts +37 -3
  182. package/dist/src/plugins/scim/scim.options.d.ts +35 -0
  183. package/dist/src/plugins/scim/types.d.ts +2 -0
  184. package/dist/src/plugins/scim/users.d.ts +6 -7
  185. package/dist/src/plugins/static.d.ts +9 -0
  186. package/dist/src/plugins/static.options.d.ts +13 -0
  187. package/dist/src/plugins/storage.d.ts +12 -1
  188. package/dist/src/plugins/storage.options.d.ts +16 -0
  189. package/dist/src/plugins/twake/appAccounts.options.d.ts +13 -0
  190. package/dist/src/plugins/twake/appAccountsApi.d.ts +18 -0
  191. package/dist/src/plugins/twake/appAccountsConsistency.d.ts +8 -0
  192. package/dist/src/plugins/twake/calendar.d.ts +25 -2
  193. package/dist/src/plugins/twake/calendar.options.d.ts +19 -0
  194. package/dist/src/plugins/twake/cloudery.options.d.ts +26 -0
  195. package/dist/src/plugins/twake/clouderyProvision.d.ts +18 -0
  196. package/dist/src/plugins/twake/cozy.options.d.ts +23 -0
  197. package/dist/src/plugins/twake/cozyProvision.d.ts +14 -0
  198. package/dist/src/plugins/twake/drive.d.ts +7 -0
  199. package/dist/src/plugins/twake/drive.options.d.ts +15 -0
  200. package/dist/src/plugins/twake/groups.d.ts +29 -1
  201. package/dist/src/plugins/twake/instances.d.ts +74 -10
  202. package/dist/src/plugins/twake/james.d.ts +17 -0
  203. package/dist/src/plugins/twake/james.options.d.ts +21 -0
  204. package/dist/src/plugins/twake/lifecycleAttributes.d.ts +13 -2
  205. package/dist/src/plugins/twake/lifecycleEvents.d.ts +12 -0
  206. package/dist/src/plugins/twake/migrationProxy.d.ts +11 -11
  207. package/dist/src/plugins/twake/migrationProxy.options.d.ts +16 -0
  208. package/dist/src/plugins/twake/spaces.d.ts +30 -0
  209. package/dist/src/plugins/twake/tombstone.d.ts +25 -16
  210. package/dist/src/plugins/twake/twakeGroups.options.d.ts +20 -0
  211. package/dist/src/plugins/twake/twakeInstances.options.d.ts +43 -0
  212. package/dist/src/plugins/twake/twakeLifecycle.options.d.ts +21 -0
  213. package/dist/src/plugins/twake/twakeSpaces.options.d.ts +19 -0
  214. package/dist/src/plugins/twake/twakeTombstone.options.d.ts +17 -0
  215. package/docs/README.md +17 -2
  216. package/docs/client-development/api/rest-api.md +13 -3
  217. package/docs/client-development/schemas/README.md +96 -32
  218. package/docs/development/contracts.md +109 -0
  219. package/docs/plugin-development/README.md +53 -95
  220. package/docs/plugin-development/dependencies.md +24 -8
  221. package/docs/plugin-development/hooks.md +143 -23
  222. package/docs/plugin-development/openapi.md +14 -1
  223. package/docs/plugin-development/options.md +136 -0
  224. package/docs/plugin-development/routes.md +152 -0
  225. package/docs/plugin-development/services.md +95 -0
  226. package/docs/plugin-development/testing.md +3 -3
  227. package/docs/usage/configuration.md +18 -11
  228. package/docs/usage/operations.md +28 -4
  229. package/docs/usage/plugins/integrations/instances.md +11 -3
  230. package/docs/usage/plugins/integrations/lifecycle-events.md +4 -1
  231. package/docs/usage/plugins/integrations/scim.md +20 -18
  232. package/docs/usage/plugins/integrations/tombstone.md +10 -6
  233. package/docs/usage/plugins/ldap/enterprise-rules.md +10 -1
  234. package/docs/usage/plugins/ldap/flat-generic.md +11 -0
  235. package/docs/usage/plugins/ldap/groups.md +4 -1
  236. package/docs/usage/plugins/ldap/password-policy.md +7 -0
  237. package/docs/usage/plugins/ldap/raw.md +17 -1
  238. package/docs/usage/upgrading.md +253 -0
  239. package/package.json +372 -286
  240. package/static/browser/ldap-browser/LdapBrowser.js +8 -6
  241. package/static/browser/ldap-browser/LdapBrowser.js.map +1 -1
  242. package/static/browser/ldap-browser/api/RawApiClient.js +2 -0
  243. package/static/browser/ldap-browser/api/RawApiClient.js.map +1 -1
  244. package/static/browser/ldap-browser/components/EntryTree.js +9 -5
  245. package/static/browser/ldap-browser/components/EntryTree.js.map +1 -1
  246. package/static/browser/ldap-browser/components/EntryView.js +2 -0
  247. package/static/browser/ldap-browser/components/EntryView.js.map +1 -1
  248. package/static/browser/ldap-browser/schema.js +3 -2
  249. package/static/browser/ldap-browser/schema.js.map +1 -1
  250. package/static/browser/ldap-browser.esm.js +27 -18
  251. package/static/browser/ldap-browser.esm.js.map +1 -1
  252. package/static/browser/ldap-browser.js +27 -18
  253. package/static/browser/ldap-browser.js.map +1 -1
  254. package/static/browser/ldap-browser.min.js +1 -1
  255. package/static/browser/ldap-browser.min.js.map +1 -1
  256. package/static/browser/ldap-group-editor/LdapGroupEditor.js +8 -6
  257. package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -1
  258. package/static/browser/ldap-group-editor/api/GroupApiClient.js +1 -0
  259. package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -1
  260. package/static/browser/ldap-group-editor/components/CreateGroupModal.js +5 -1
  261. package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -1
  262. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +6 -3
  263. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -1
  264. package/static/browser/ldap-group-editor/components/GroupTree.js +6 -3
  265. package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -1
  266. package/static/browser/ldap-group-editor/components/MoveGroupModal.js +6 -3
  267. package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -1
  268. package/static/browser/ldap-group-editor.esm.js +32 -16
  269. package/static/browser/ldap-group-editor.esm.js.map +1 -1
  270. package/static/browser/ldap-group-editor.js +32 -16
  271. package/static/browser/ldap-group-editor.js.map +1 -1
  272. package/static/browser/ldap-group-editor.min.js +1 -1
  273. package/static/browser/ldap-group-editor.min.js.map +1 -1
  274. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +3 -0
  275. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -1
  276. package/static/browser/ldap-resource-editor/cache/CacheManager.js +3 -1
  277. package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -1
  278. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +6 -1
  279. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -1
  280. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +2 -0
  281. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -1
  282. package/static/browser/ldap-tree-viewer/components/TreeNode.js +4 -0
  283. package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -1
  284. package/static/browser/ldap-tree-viewer/components/TreeRoot.js +3 -0
  285. package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -1
  286. package/static/browser/ldap-tree-viewer/store/Store.js +3 -1
  287. package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -1
  288. package/static/browser/ldap-tree-viewer.esm.js +18 -2
  289. package/static/browser/ldap-tree-viewer.esm.js.map +1 -1
  290. package/static/browser/ldap-tree-viewer.js +18 -2
  291. package/static/browser/ldap-tree-viewer.js.map +1 -1
  292. package/static/browser/ldap-tree-viewer.min.js +1 -1
  293. package/static/browser/ldap-tree-viewer.min.js.map +1 -1
  294. package/static/browser/ldap-unit-editor/LdapUnitEditor.js +7 -5
  295. package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -1
  296. package/static/browser/ldap-unit-editor/api/UnitApiClient.js +1 -0
  297. package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -1
  298. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +7 -4
  299. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -1
  300. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +7 -4
  301. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -1
  302. package/static/browser/ldap-unit-editor/components/UnitTree.js +6 -3
  303. package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -1
  304. package/static/browser/ldap-unit-editor.esm.js +28 -16
  305. package/static/browser/ldap-unit-editor.esm.js.map +1 -1
  306. package/static/browser/ldap-unit-editor.js +28 -16
  307. package/static/browser/ldap-unit-editor.js.map +1 -1
  308. package/static/browser/ldap-unit-editor.min.js +1 -1
  309. package/static/browser/ldap-unit-editor.min.js.map +1 -1
  310. package/static/browser/ldap-user-editor/LdapUserEditor.js +9 -7
  311. package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -1
  312. package/static/browser/ldap-user-editor/api/UserApiClient.js +2 -0
  313. package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -1
  314. package/static/browser/ldap-user-editor/cache/CacheManager.js +3 -1
  315. package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -1
  316. package/static/browser/ldap-user-editor/components/MoveUserModal.js +7 -4
  317. package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -1
  318. package/static/browser/ldap-user-editor/components/PointerField.js +6 -1
  319. package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -1
  320. package/static/browser/ldap-user-editor/components/UserEditor.js +10 -5
  321. package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -1
  322. package/static/browser/ldap-user-editor/components/UserList.js +8 -4
  323. package/static/browser/ldap-user-editor/components/UserList.js.map +1 -1
  324. package/static/browser/ldap-user-editor/components/UserTree.js +7 -3
  325. package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -1
  326. package/static/browser/ldap-user-editor.esm.js +55 -30
  327. package/static/browser/ldap-user-editor.esm.js.map +1 -1
  328. package/static/browser/ldap-user-editor.js +55 -30
  329. package/static/browser/ldap-user-editor.js.map +1 -1
  330. package/static/browser/ldap-user-editor.min.js +1 -1
  331. package/static/browser/ldap-user-editor.min.js.map +1 -1
  332. package/static/browser/shared/components/DisposableComponent.js +3 -5
  333. package/static/browser/shared/components/DisposableComponent.js.map +1 -1
  334. package/static/browser/shared/components/Modal.js +2 -1
  335. package/static/browser/shared/components/Modal.js.map +1 -1
  336. package/static/browser/shared/components/StatusMessage.js +3 -2
  337. package/static/browser/shared/components/StatusMessage.js.map +1 -1
  338. package/static/browser/shared/utils/form.js.map +1 -1
  339. package/static/browser/shared/utils/hmac.js +1 -0
  340. package/static/browser/shared/utils/hmac.js.map +1 -1
  341. package/static/browser/shared/utils/totp.js +1 -0
  342. package/static/browser/shared/utils/totp.js.map +1 -1
  343. package/static/browser/shared.esm.js +9 -8
  344. package/static/browser/shared.esm.js.map +1 -1
  345. package/static/browser/shared.js +9 -8
  346. package/static/browser/shared.js.map +1 -1
  347. package/static/browser/shared.min.js +1 -1
  348. package/static/browser/shared.min.js.map +1 -1
  349. package/static/schemas/ad/groups.json +1 -1
  350. package/static/schemas/ad/users.json +3 -3
  351. package/static/schemas/example/organizations.json +2 -2
  352. package/static/schemas/example/users.json +2 -2
  353. package/static/schemas/obm/users.json +2 -2
  354. package/static/schemas/standard/groups.json +1 -1
  355. package/static/schemas/standard/users.json +2 -2
  356. package/static/schemas/twake/groups.json +4 -4
  357. package/static/schemas/twake/teamMailboxes.json +3 -3
  358. package/static/schemas/twake/users.json +7 -7
@@ -1,12 +1,16 @@
1
+ /**
2
+ * LDAP low-level library
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ */
1
5
  import type { Request } from 'express';
2
- import type { ClientOptions, SearchResult, SearchOptions } from 'ldapts';
6
+ import type { SearchResult, SearchOptions } from 'ldapts';
3
7
  import type winston from 'winston';
4
8
  import pLimit from 'p-limit';
5
9
  import { type Config } from '../config/args';
6
10
  import { type DM } from '../bin';
7
11
  import type { Hooks } from '../hooks';
8
12
  import { type ChangeContext } from './changeContext';
9
- import { SchemaIndex } from './ldapSchema';
13
+ import type { SchemaIndex } from './ldapSchema';
10
14
  export type AttributeValue = Buffer | Buffer[] | string[] | string;
11
15
  export type AttributesList = Record<string, AttributeValue>;
12
16
  export type LdapList = Record<string, AttributesList>;
@@ -68,148 +72,34 @@ export interface ModifyOptions {
68
72
  type AuthorizedHook = 'ldapaddrequest' | 'ldapmodifyrequest' | 'ldapdeleterequest' | 'ldaprenamerequest';
69
73
  declare class ldapActions {
70
74
  config: Config;
71
- options: ClientOptions;
72
- dn: string;
73
- pwd: string;
74
75
  base: string;
75
76
  parent: DM;
76
77
  logger: winston.Logger;
77
- private searchCache;
78
- private cacheEnabled;
79
- /**
80
- * How many writes this instance has made since it was built.
81
- *
82
- * A read can be overtaken by a write: the write lands and `invalidateCache`
83
- * finds nothing to drop, because the read has not stored its answer yet —
84
- * and the read then stores what it read *before* the write, an entry
85
- * nothing will drop until its TTL runs out. `search()` remembers the count
86
- * it started at and stores only if no write happened in between, so a read
87
- * a write overtook costs a cache entry, never a stale answer.
88
- *
89
- * The count is per instance and per write, not per DN: a write to another
90
- * branch keeps a concurrent read out of the cache too. That is hit rate
91
- * given up, not freshness.
92
- */
93
- private cacheGeneration;
78
+ private cache;
94
79
  queryLimit: ReturnType<typeof pLimit>;
95
- private connectionPool;
96
- private poolSize;
97
- private connectionTtl;
98
- private ldapUrls;
99
- private currentUrlIndex;
100
- private attrSignatureCache;
101
- private waitingResolvers;
102
- private availableConnections;
103
- private isCleaningUp;
104
- /** See {@link declareObjectClasses}. */
105
- private declaredClasses;
106
- private schemaCache?;
107
- private schemaLoading?;
108
- /** Whether the last schema read failed, so a failure is logged once. */
109
- private schemaUnavailable;
110
- /**
111
- * How this server spells attribute names, by name in lower case: the
112
- * configuration's, then the loaded schemas'. See {@link canonicalName}.
113
- */
114
- private spellings;
115
- /** The first name given for each attribute type, to warn of another. */
116
- private spelledTypes;
117
- /** Class problems already reported, per entry. See {@link warnOnce}. */
118
- private classWarnings;
80
+ private pool;
81
+ private schema;
82
+ private caller;
119
83
  constructor(server: DM);
120
- /**
121
- * Create a new LDAP connection with failover support
122
- */
123
- private createConnection;
124
- /**
125
- * Clean up expired connections from the pool
126
- * Uses a flag to prevent concurrent cleanup operations
127
- */
128
- private cleanupExpiredConnections;
129
- /**
130
- * Ask the directory for its root DSE on a connection of its own, bound
131
- * as the server and closed after: the readiness probe. Neither the pool
132
- * nor the search cache nor the hooks answer for a directory that does
133
- * not, and a directory that stops answering holds nothing of the pool.
134
- * The URLs are tried as `createConnection` tries them.
135
- *
136
- * @param timeoutMs how long the connection, the bind and the search may
137
- * each take; the client closes the socket when it passes
138
- * @throws when no URL answers in time
139
- */
84
+ /** See {@link LdapPool.ping}. */
140
85
  ping(timeoutMs: number): Promise<void>;
141
- /** Set by `close`: no connection is handed out any more */
142
- private closed;
143
- /**
144
- * Close every pooled connection, the ones in use included: an operation
145
- * still running on one is rejected by the client, and a waiter is refused
146
- * rather than kept.
147
- */
86
+ /** See {@link LdapPool.close}. */
148
87
  close(): Promise<void>;
149
- /**
150
- * Acquire a connection from the pool or create a new one
151
- * Optimized for O(1) lookup using separate available connections queue
152
- */
153
- private acquireConnection;
154
88
  /** The pool as it is, for the metrics */
155
89
  poolStats(): {
156
90
  busy: number;
157
91
  idle: number;
158
92
  waiting: number;
93
+ opening: number;
159
94
  max: number;
160
95
  };
161
- private takeConnection;
162
- /**
163
- * Release a connection back to the pool
164
- * If there are waiting requests, hand off the connection directly
165
- */
166
- private releaseConnection;
167
- /**
168
- * Get a sorted signature for attribute list, using cache for performance
169
- */
170
- private getAttributeSignature;
171
- /**
172
- * Generate cache key for LDAP search
173
- *
174
- * Every option that changes the answer belongs in here, or a search that
175
- * asked for more is served what a search that asked for less got: the
176
- * requested attributes above all, but also the ones that change the shape
177
- * of what comes back. `timeLimit` is deliberately absent — it bounds how
178
- * long the server may spend, not what it returns.
179
- */
180
- private getCacheKey;
181
96
  /**
182
97
  * Drop every cached read of `dn`, and of everything below it.
183
98
  *
184
99
  * Called after each write, so the next read of what just changed goes to
185
- * the directory. Two things this does that a `key.startsWith(dn)` test did
186
- * not: it compares DNs the way the directory does (see {@link foldDn}), so
187
- * a write spelling a DN differently from the read that cached it still
188
- * drops it; and it drops the subtree, because `rename()` and `move()`
189
- * re-parent a whole branch in one operation — renaming an organization
190
- * changes the DN of every entry under it — leaving the cached reads of
191
- * those children filed under DNs that no longer exist. A leaf has nothing
192
- * below it and the extra test costs nothing.
100
+ * the directory. See {@link SearchCache.invalidate}.
193
101
  */
194
102
  invalidateCache(dn: string): void;
195
- /**
196
- * Drop every cached read holding a value that names `dn`, or an entry
197
- * below it.
198
- *
199
- * The directory mirrors some writes onto other entries than the one
200
- * written: the `memberof` overlay keeps each member's `memberOf` in step
201
- * with the group's `member` / `uniqueMember`, and `refint` rewrites or
202
- * removes the references to an entry renamed or deleted. Those entries'
203
- * cached reads are what {@link invalidateCache} cannot find, and they name
204
- * the entry written: the members of a group name it in their `memberOf`.
205
- * A member a write adds names it only once the write has landed; the
206
- * caller drops those by their own DN.
207
- *
208
- * Every attribute is looked at, not `memberOf` alone: which attributes an
209
- * overlay maintains is the deployment's configuration. A read naming `dn`
210
- * for another reason is dropped too, which costs a miss.
211
- */
212
- private invalidateReferences;
213
103
  /**
214
104
  * The directory as the server itself, with no request behind it.
215
105
  *
@@ -242,20 +132,7 @@ declare class ldapActions {
242
132
  * hooks always see it. See {@link RequestBoundLdap}.
243
133
  */
244
134
  forRequest(req: Request): RequestBoundLdap;
245
- /**
246
- * Whether the caller of a request can read an entry.
247
- *
248
- * For a route that finds an entry as the server — by an attribute, across
249
- * branches — and then answers about it: an entry the caller cannot read
250
- * must get the answer an entry that is not there gets, or the route tells
251
- * them what the directory holds where they cannot read. Refused or
252
- * filtered out by an authorization plugin, the entry reads as absent.
253
- * Without a request, as for any operation, nobody judges.
254
- *
255
- * @param dn the entry
256
- * @param req the request whose caller asks
257
- * @returns whether a read of the entry, as that caller, finds it
258
- */
135
+ /** See {@link CallerView.readableBy}. */
259
136
  readableBy(dn: string, req?: Request): Promise<boolean>;
260
137
  /**
261
138
  * Have the authorization plugins judge an operation, without making it.
@@ -277,134 +154,27 @@ declare class ldapActions {
277
154
  * @throws the refusal of the first authorization plugin refusing
278
155
  */
279
156
  authorize<H extends AuthorizedHook>(hook: H, args: Parameters<NonNullable<Hooks[H]>>[0]): Promise<void>;
280
- /**
281
- * Declare the object classes an entity gives the entries of its branch.
282
- *
283
- * An entry created by another tool may lack some of them, and a class it
284
- * lacks can forbid an attribute written here: the organization link of an
285
- * account made as a bare `inetOrgPerson` is refused by the directory. A
286
- * modify writing such an attribute adds the auxiliary class that allows
287
- * it, see {@link classRepair}.
288
- *
289
- * @param base branch holding the entity's entries
290
- * @param classes object classes the entity's schema declares; a schema
291
- * file may give a single one as a string
292
- * @param includeBase whether the base is itself one of the entries, as the
293
- * top organization is
294
- */
157
+ /** See {@link DirectorySchema.declareObjectClasses}. */
295
158
  declareObjectClasses(base: string, classes: string[] | string, includeBase?: boolean): void;
296
- /**
297
- * The classes declared for the branch holding a DN. Several entities may
298
- * share a branch — the shipped `users`, `posixAccounts` and
299
- * `sshPublicKeys` schemas all live in `ou=users` — so every declaration at
300
- * the deepest matching base counts.
301
- */
302
- private declaredFor;
303
- /**
304
- * Log a class problem of an entry once, not on every write to it: nothing
305
- * an administrator can do stops a sync job from touching it again.
306
- */
307
- private warnOnce;
308
- /**
309
- * The auxiliary classes a modify needs added: for each attribute it writes
310
- * that the entry's classes do not allow, a class declared for its branch
311
- * or by the writer that allows it, provided the entry holds or receives
312
- * that class's mandatory attributes once the change is applied.
313
- *
314
- * Only what the write needs is added. Entities sharing a branch declare
315
- * classes that are not all meant for every entry: `shadowAccount` is not
316
- * something every account should be given because it sits in `ou=users`.
317
- * And a write that the directory would have accepted is never changed.
318
- *
319
- * Nothing is added when the change names `objectClass` itself, and a
320
- * schema or entry that cannot be read skips the repair.
321
- *
322
- * @param dn entry being modified
323
- * @param changes the modification, after the hooks
324
- * @param extra classes the writer declares, see {@link ModifyOptions}
325
- * @returns names of the classes to add, or `allowed` when the entry's
326
- * classes take the change as it is
327
- */
328
- private classRepair;
329
- /**
330
- * DN of the subschema entry the root DSE advertises, or the conventional
331
- * `cn=Subschema` when it advertises none.
332
- */
159
+ /** See {@link DirectorySchema.subschemaDn}. */
333
160
  subschemaDn(): Promise<string>;
334
- /**
335
- * The directory schema, kept for `--ldap-raw-schema-cache-ttl`: it is
336
- * large and changes rarely. The raw browser and the object class repair
337
- * share it, and concurrent callers share a single read.
338
- *
339
- * @returns indexed schema
340
- */
161
+ /** See {@link DirectorySchema.schemaIndex}. */
341
162
  schemaIndex(): Promise<SchemaIndex>;
342
- /**
343
- * Say how this server spells attribute names: a schema loaded by a plugin
344
- * names its attributes as the plugins compare them. The first spelling of
345
- * a name wins.
346
- *
347
- * @param names attribute names
348
- */
163
+ /** See {@link DirectorySchema.knowAttributeNames}. */
349
164
  knowAttributeNames(names: Iterable<string>): void;
350
- /**
351
- * Name each attribute of a write as this server does, in place.
352
- *
353
- * The directory takes `MAIL`, `rfc822Mailbox` and `0.9.2342.19200300.100.1.3`
354
- * for `mail`, while the authorization plugins and the hooks look for
355
- * `mail`: a write naming the organization link by its OID was judged as
356
- * if it left the link alone. Each name is resolved through the directory
357
- * schema — case, aliases, OIDs — and written as the configuration or a
358
- * loaded schema spells it, or as the directory declares it first.
359
- *
360
- * An option names a value of its own (`member;lang-en` is not `member` to
361
- * the hooks guarding `member`), and is refused, `;binary` aside. Two names
362
- * for one attribute in one part of a write are refused too: on a modify
363
- * the directory applies both, and only one would have been judged.
364
- *
365
- * Without the schema, the case is still set, and a name given as an OID,
366
- * which nothing here could resolve, is refused. So is, with or without
367
- * it, a name that is neither a descriptor nor a numeric OID.
368
- *
369
- * @param entry attributes of an add, or one part of a modify
370
- * @throws BadRequestError on an option, on a name that describes no
371
- * attribute, or on one attribute named twice
372
- */
165
+ /** See {@link DirectorySchema.canonicalAttributes}. */
373
166
  canonicalAttributes(entry: AttributesList | undefined): Promise<void>;
374
- /**
375
- * {@link canonicalAttributes} for every part of a modify, in place.
376
- *
377
- * @param changes the modify
378
- * @throws BadRequestError as {@link canonicalAttributes}
379
- */
167
+ /** See {@link DirectorySchema.canonicalChanges}. */
380
168
  canonicalChanges(changes: ModifyRequest | undefined): Promise<void>;
381
- /**
382
- * The names of one part of a write, as {@link canonicalAttributes} writes
383
- * them.
384
- */
385
- private canonicalNames;
386
- /**
387
- * One attribute description, named as this server does.
388
- *
389
- * @param key the name as written, options included
390
- * @param index the directory schema, when it could be read
391
- */
392
- private canonicalName;
393
- /**
394
- * Hand a search result to `ldapsearchfilter`, which may drop entries the
395
- * caller is not allowed to see.
396
- *
397
- * Applied on every return path of `search`, and deliberately after the
398
- * cache: `ldapsearchresult` fires before caching and knows no request, so
399
- * what it removed for one caller would be served to the next. A paginated
400
- * search is filtered chunk by chunk, as it is consumed.
401
- */
169
+ /** See {@link CallerView.filter}. */
402
170
  private filterForCaller;
403
171
  search(options: SearchOptions, base?: string, req?: Request): Promise<SearchResult | AsyncGenerator<SearchResult>>;
404
172
  /**
405
- * Wrap paginated search to ensure connection is released when done
173
+ * A paged search, opened on its first page: a generator that is never
174
+ * started holds no connection. The pool is taken here, in the generator
175
+ * body, not by `search()`.
406
176
  */
407
- private wrapPaginatedSearch;
177
+ private pagedSearch;
408
178
  add(dn: string, entry: AttributesList, req?: Request): Promise<boolean>;
409
179
  modify(dn: string, changes: ModifyRequest, req?: Request, options?: ModifyOptions): Promise<boolean>;
410
180
  private applyModify;
@@ -9,17 +9,46 @@ export type ArrayKind = 'identifiers' | 'dns' | 'phrases';
9
9
  export type ConfigEntry = [
10
10
  string,
11
11
  string,
12
- (string | string[] | boolean | number | Record<string, any>),
12
+ // env value
13
+ string | string[] | boolean | number | Record<string, any>,
13
14
  ('string' | 'number' | 'boolean' | 'array' | 'json' | null | undefined)?,
14
15
  (string | null | undefined)?,
15
16
  ArrayKind?,
16
- boolean?
17
+ boolean?,
18
+ (string[] | null | undefined)?,
19
+ (string[] | null | undefined)?
17
20
  ];
18
21
  export declare class ConfigParser {
19
22
  private config;
23
+ /** CLI arguments no entry declared, kept in `Config` by the parser */
24
+ private unknownArgs;
25
+ /** Deprecated names the configuration used, reported once each */
26
+ private readonly deprecated;
27
+ get unknownOptions(): string[];
28
+ /** Names read through a deprecated alias, for the server to warn about */
29
+ get deprecationWarnings(): string[];
30
+ private warnOnce;
31
+ /** The entry a CLI name stands for, whether canonical or a deprecated alias */
32
+ private findEntry;
33
+ /**
34
+ * The environment variable an entry reads: its own, or a deprecated alias
35
+ * when that one is set and its own is not.
36
+ */
37
+ private envNameOf;
38
+ /**
39
+ * Whether a variable value counts as set. An empty value is unset for the
40
+ * types that read it as nothing: a compose file expands an unset
41
+ * `${VAR:-}` to one. For a string or a boolean, an empty value means
42
+ * something and stays set.
43
+ */
44
+ private environmentIsSet;
20
45
  constructor(config: ConfigTemplate);
46
+ /** A deprecated name must not shadow a declared one, or be declared twice */
47
+ private checkAliases;
21
48
  parse(argv?: string[]): Config;
22
49
  private parseCliArgs;
23
50
  private getKeyFromCliArg;
24
51
  }
52
+ export declare function splitValue(value: string, kind: ArrayKind | undefined, form: 'singular' | 'plural'): string[];
53
+ export declare function parseNumber(value: string): number;
25
54
  export declare function parseConfig(config: ConfigEntry[], argv?: string[]): Config;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @module lib/route
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * One declaration per HTTP route: its input schemas, the handler that
6
+ * receives the checked values, and what the OpenAPI document says of it.
7
+ * @group Libraries
8
+ */
9
+ import type { Static, TSchema } from '@sinclair/typebox';
10
+ import type { Express, NextFunction, Request, RequestHandler, Response } from 'express';
11
+ export type RouteMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
12
+ /** What the handler receives for a part it declared no schema for. */
13
+ type Input<T> = T extends TSchema ? Static<T> : unknown;
14
+ /** What a handler receives once its request has been checked. */
15
+ export interface RouteInput<P extends TSchema | undefined, Q extends TSchema | undefined, B extends TSchema | undefined> {
16
+ req: Request;
17
+ res: Response;
18
+ /** Express's own, for a handler that answers a failure itself */
19
+ next: NextFunction;
20
+ params: Input<P>;
21
+ query: Input<Q>;
22
+ body: Input<B>;
23
+ }
24
+ /**
25
+ * An answer: its schema, and the sentence the document gives it. A bare
26
+ * schema is described by its status (`Successful response`, `Bad request`…).
27
+ */
28
+ export interface RouteResponse {
29
+ schema: TSchema;
30
+ description?: string;
31
+ }
32
+ /** A route, as declared and as recorded for the OpenAPI document. */
33
+ export interface RouteDefinition<P extends TSchema | undefined = undefined, Q extends TSchema | undefined = undefined, B extends TSchema | undefined = undefined> {
34
+ method: RouteMethod;
35
+ path: string;
36
+ /** The path parameters, checked and converted from their string form */
37
+ params?: P;
38
+ /** The query parameters, checked and converted from their string form */
39
+ query?: Q;
40
+ /** The parsed body */
41
+ body?: B;
42
+ /**
43
+ * Whether a caller that does not accept JSON is refused before the handler
44
+ * (default). A route answering another media type sets it false.
45
+ */
46
+ json?: boolean;
47
+ /** Handlers run before the declaration's, as Express mounts them */
48
+ middleware?: RequestHandler | RequestHandler[];
49
+ /** The answers, for the OpenAPI document */
50
+ responses?: Partial<Record<number, TSchema | RouteResponse>>;
51
+ summary?: string;
52
+ description?: string;
53
+ tags?: string[];
54
+ handler: (input: RouteInput<P, Q, B>) => void | Promise<void>;
55
+ }
56
+ /** A route recorded on an app, with its schemas kept for the document. */
57
+ export type RegisteredRoute = Omit<RouteDefinition<TSchema, TSchema, TSchema>, 'handler' | 'middleware'>;
58
+ /**
59
+ * The routes `defineRoute` registered on an app, in declaration order.
60
+ *
61
+ * @param app the express app the plugin was given
62
+ * @returns its routes
63
+ */
64
+ export declare const registeredRoutes: (app: Express) => readonly RegisteredRoute[];
65
+ /** A route Express carries, as the stack spells it. */
66
+ export interface StackRoute {
67
+ method: string;
68
+ path: string;
69
+ }
70
+ /**
71
+ * The routes an app carries that `defineRoute` did not declare.
72
+ *
73
+ * The stack is walked at any depth, so a mounted router's routes are seen
74
+ * too. A route is matched on its method and path, which is what the
75
+ * declaration records; a router's routes are router-relative (`/nested`,
76
+ * whatever the mount path), as Express keeps no mount path on a router, and
77
+ * `app.all` comes back as `_ALL`.
78
+ *
79
+ * @param app the express app
80
+ * @returns the undeclared routes, in stack order
81
+ */
82
+ export declare const unregisteredRoutes: (app: Express) => StackRoute[];
83
+ /**
84
+ * Declare an HTTP route.
85
+ *
86
+ * The declared schemas are checked before the handler runs; a request that
87
+ * fails them is a {@link BadRequestError} naming every failing path, so the
88
+ * middleware answers it as any other client error. The handler receives the
89
+ * checked values and answers through `res`, as with `asyncHandler`, whose
90
+ * rejections it still forwards.
91
+ *
92
+ * The declaration is recorded on the app, with its schemas, for the OpenAPI
93
+ * document and for the check that no route escapes it.
94
+ *
95
+ * @param app the express app the plugin was given
96
+ * @param route the declaration
97
+ */
98
+ export declare const defineRoute: <P extends TSchema | undefined = undefined, Q extends TSchema | undefined = undefined, B extends TSchema | undefined = undefined>(app: Express, route: RouteDefinition<P, Q, B>) => void;
99
+ export {};
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Typed services between plugins: a token names the interface a consumer
3
+ * reads and the instance a provider offers, so the compiler checks both.
4
+ *
5
+ * @see docs/plugin-development/services.md
6
+ */
7
+ declare const serviceType: unique symbol;
8
+ /**
9
+ * What identifies a service: a name for the logs, and the interface it
10
+ * answers. The type is carried by a phantom property and never exists at
11
+ * runtime; the object itself is the registry key.
12
+ */
13
+ export interface ServiceToken<T> {
14
+ /** Names the service in the logs */
15
+ readonly name: string;
16
+ /** Type only, never set: carries the interface a consumer reads */
17
+ readonly [serviceType]?: T;
18
+ /**
19
+ * Bind the instance providing this service, as a plugin's `provides`
20
+ * declares. The argument must answer the interface the token names.
21
+ *
22
+ * @param provider the plugin instance providing the service
23
+ * @returns the token and its provider
24
+ */
25
+ with(provider: T): ServiceProvider<T>;
26
+ }
27
+ /** A token with the instance providing it, as a plugin declares them. */
28
+ export interface ServiceProvider<T> {
29
+ readonly token: ServiceToken<T>;
30
+ readonly service: T;
31
+ }
32
+ /**
33
+ * Declare a service.
34
+ *
35
+ * Declare a token once, in a module both the provider and its consumers
36
+ * import: the object is the registry key, and a second declaration under the
37
+ * same name would be another service. The name only identifies it in the
38
+ * logs.
39
+ *
40
+ * @param name the service name
41
+ * @returns the token, carrying its interface
42
+ */
43
+ export declare const serviceToken: <T>(name: string) => ServiceToken<T>;
44
+ /** What `DM.services` holds: the provided instance for each token. */
45
+ export type ServiceMap = Map<ServiceToken<unknown>, unknown>;
46
+ /**
47
+ * The instance provided for a token, when a plugin provides it.
48
+ *
49
+ * A provider always answers something: `undefined` means nobody provides it.
50
+ *
51
+ * @param services the server's registry
52
+ * @param token the service wanted
53
+ * @returns the provided instance, or undefined
54
+ */
55
+ export declare const providedService: <T>(services: ReadonlyMap<ServiceToken<unknown>, unknown>, token: ServiceToken<T>) => T | undefined;
56
+ export {};