@rockcarver/frodo-lib 0.16.2-9 → 0.17.1

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 (355) hide show
  1. package/CHANGELOG.md +222 -1
  2. package/cjs/api/AgentApi.js +14 -61
  3. package/cjs/api/AgentApi.js.map +1 -1
  4. package/cjs/api/AgentApi.test.js.map +1 -1
  5. package/cjs/api/ApiTypes.js +0 -5
  6. package/cjs/api/ApiTypes.js.map +1 -1
  7. package/cjs/api/AuthenticateApi.js +9 -20
  8. package/cjs/api/AuthenticateApi.js.map +1 -1
  9. package/cjs/api/AuthenticateApi.test.js.map +1 -0
  10. package/cjs/api/BaseApi.js +82 -124
  11. package/cjs/api/BaseApi.js.map +1 -1
  12. package/cjs/api/CirclesOfTrustApi.js +8 -32
  13. package/cjs/api/CirclesOfTrustApi.js.map +1 -1
  14. package/cjs/api/IdmConfigApi.js +9 -34
  15. package/cjs/api/IdmConfigApi.js.map +1 -1
  16. package/cjs/api/LogApi.js +8 -31
  17. package/cjs/api/LogApi.js.map +1 -1
  18. package/cjs/api/ManagedObjectApi.js +34 -31
  19. package/cjs/api/ManagedObjectApi.js.map +1 -1
  20. package/cjs/api/NodeApi.js +10 -41
  21. package/cjs/api/NodeApi.js.map +1 -1
  22. package/cjs/api/NodeApi.test.js.map +1 -1
  23. package/cjs/api/OAuth2ClientApi.js +7 -26
  24. package/cjs/api/OAuth2ClientApi.js.map +1 -1
  25. package/cjs/api/OAuth2OIDCApi.js +28 -34
  26. package/cjs/api/OAuth2OIDCApi.js.map +1 -1
  27. package/cjs/api/OAuth2OIDCApi.test.js.map +1 -0
  28. package/cjs/api/OAuth2ProviderApi.js +5 -15
  29. package/cjs/api/OAuth2ProviderApi.js.map +1 -1
  30. package/cjs/api/RealmApi.js +8 -34
  31. package/cjs/api/RealmApi.js.map +1 -1
  32. package/cjs/api/Saml2Api.js +16 -67
  33. package/cjs/api/Saml2Api.js.map +1 -1
  34. package/cjs/api/ScriptApi.js +8 -30
  35. package/cjs/api/ScriptApi.js.map +1 -1
  36. package/cjs/api/SecretsApi.js +14 -64
  37. package/cjs/api/SecretsApi.js.map +1 -1
  38. package/cjs/api/SecretsApi.test.js.map +1 -1
  39. package/cjs/api/ServerInfoApi.js +6 -21
  40. package/cjs/api/ServerInfoApi.js.map +1 -1
  41. package/cjs/api/ServiceApi.js +49 -47
  42. package/cjs/api/ServiceApi.js.map +1 -1
  43. package/cjs/api/SocialIdentityProvidersApi.js +9 -36
  44. package/cjs/api/SocialIdentityProvidersApi.js.map +1 -1
  45. package/cjs/api/StartupApi.js +5 -24
  46. package/cjs/api/StartupApi.js.map +1 -1
  47. package/cjs/api/StartupApi.test.js.map +1 -1
  48. package/cjs/api/TreeApi.js +8 -30
  49. package/cjs/api/TreeApi.js.map +1 -1
  50. package/cjs/api/TreeApi.test.js.map +1 -1
  51. package/cjs/api/VariablesApi.js +9 -37
  52. package/cjs/api/VariablesApi.js.map +1 -1
  53. package/cjs/api/VariablesApi.test.js.map +1 -1
  54. package/cjs/api/utils/ApiUtils.js +47 -57
  55. package/cjs/api/utils/ApiUtils.js.map +1 -1
  56. package/cjs/api/utils/ApiUtils.test.js.map +1 -1
  57. package/cjs/api/utils/Base64.js +5 -15
  58. package/cjs/api/utils/Base64.js.map +1 -1
  59. package/cjs/ext/axios-curlirize/curlirize.js +2 -9
  60. package/cjs/ext/axios-curlirize/curlirize.js.map +1 -1
  61. package/cjs/ext/axios-curlirize/lib/CurlHelper.js +7 -22
  62. package/cjs/ext/axios-curlirize/lib/CurlHelper.js.map +1 -1
  63. package/cjs/index.js +30 -89
  64. package/cjs/index.js.map +1 -1
  65. package/cjs/ops/AdminOps.js +27 -165
  66. package/cjs/ops/AdminOps.js.map +1 -1
  67. package/cjs/ops/AgentOps.js +2 -159
  68. package/cjs/ops/AgentOps.js.map +1 -1
  69. package/cjs/ops/AgentOps.test.js.map +1 -1
  70. package/cjs/ops/AuthenticateOps.js +266 -226
  71. package/cjs/ops/AuthenticateOps.js.map +1 -1
  72. package/cjs/ops/AuthenticateOps.test.js.map +1 -1
  73. package/cjs/ops/CirclesOfTrustOps.js +13 -91
  74. package/cjs/ops/CirclesOfTrustOps.js.map +1 -1
  75. package/cjs/ops/ConnectionProfileOps.js +220 -136
  76. package/cjs/ops/ConnectionProfileOps.js.map +1 -1
  77. package/cjs/ops/ConnectionProfileOps.test.js.map +1 -1
  78. package/cjs/ops/EmailTemplateOps.js +35 -379
  79. package/cjs/ops/EmailTemplateOps.js.map +1 -1
  80. package/cjs/ops/EmailTemplateOps.test.js.map +1 -1
  81. package/cjs/ops/IdmOps.js +52 -426
  82. package/cjs/ops/IdmOps.js.map +1 -1
  83. package/cjs/ops/IdmOps.test.js.map +1 -1
  84. package/cjs/ops/IdpOps.js +11 -94
  85. package/cjs/ops/IdpOps.js.map +1 -1
  86. package/cjs/ops/IdpOps.test.js.map +1 -1
  87. package/cjs/ops/JoseOps.js +81 -0
  88. package/cjs/ops/JoseOps.js.map +1 -0
  89. package/cjs/ops/JoseOps.test.js.map +1 -0
  90. package/cjs/ops/JourneyOps.js +139 -370
  91. package/cjs/ops/JourneyOps.js.map +1 -1
  92. package/cjs/ops/JourneyOps.test.js.map +1 -1
  93. package/cjs/ops/LogOps.js +14 -47
  94. package/cjs/ops/LogOps.js.map +1 -1
  95. package/cjs/ops/ManagedObjectOps.js +4 -12
  96. package/cjs/ops/ManagedObjectOps.js.map +1 -1
  97. package/cjs/ops/NodeOps.js +9 -67
  98. package/cjs/ops/NodeOps.js.map +1 -1
  99. package/cjs/ops/OAuth2ClientOps.js +10 -40
  100. package/cjs/ops/OAuth2ClientOps.js.map +1 -1
  101. package/cjs/ops/OpsTypes.js +0 -5
  102. package/cjs/ops/OpsTypes.js.map +1 -1
  103. package/cjs/ops/OrganizationOps.js +6 -25
  104. package/cjs/ops/OrganizationOps.js.map +1 -1
  105. package/cjs/ops/RealmOps.js +0 -19
  106. package/cjs/ops/RealmOps.js.map +1 -1
  107. package/cjs/ops/Saml2Ops.js +11 -107
  108. package/cjs/ops/Saml2Ops.js.map +1 -1
  109. package/cjs/ops/Saml2Ops.test.js.map +1 -1
  110. package/cjs/ops/ScriptOps.js +26 -73
  111. package/cjs/ops/ScriptOps.js.map +1 -1
  112. package/cjs/ops/SecretsOps.js +2 -58
  113. package/cjs/ops/SecretsOps.js.map +1 -1
  114. package/cjs/ops/ServiceAccountOps.js +61 -0
  115. package/cjs/ops/ServiceAccountOps.js.map +1 -0
  116. package/cjs/ops/ServiceAccountOps.test.js.map +1 -0
  117. package/cjs/ops/ServiceOps.js +55 -101
  118. package/cjs/ops/ServiceOps.js.map +1 -1
  119. package/cjs/ops/StartupOps.js +2 -23
  120. package/cjs/ops/StartupOps.js.map +1 -1
  121. package/cjs/ops/ThemeOps.js +230 -436
  122. package/cjs/ops/ThemeOps.js.map +1 -1
  123. package/cjs/ops/ThemeOps.test.js.map +1 -0
  124. package/cjs/ops/VariablesOps.js +0 -38
  125. package/cjs/ops/VariablesOps.js.map +1 -1
  126. package/cjs/ops/utils/Console.js +29 -62
  127. package/cjs/ops/utils/Console.js.map +1 -1
  128. package/cjs/ops/utils/DataProtection.js +13 -47
  129. package/cjs/ops/utils/DataProtection.js.map +1 -1
  130. package/cjs/ops/utils/DataProtection.test.js.map +1 -1
  131. package/cjs/ops/utils/ExportImportUtils.js +36 -74
  132. package/cjs/ops/utils/ExportImportUtils.js.map +1 -1
  133. package/cjs/ops/utils/ExportImportUtils.test.js.map +1 -1
  134. package/cjs/ops/utils/OpsUtils.js +27 -43
  135. package/cjs/ops/utils/OpsUtils.js.map +1 -1
  136. package/cjs/ops/utils/OpsUtils.test.js.map +1 -1
  137. package/cjs/ops/utils/ValidationUtils.js +0 -13
  138. package/cjs/ops/utils/ValidationUtils.js.map +1 -1
  139. package/cjs/ops/utils/ValidationUtils.test.js.map +1 -1
  140. package/cjs/ops/utils/Version.js +2 -12
  141. package/cjs/ops/utils/Version.js.map +1 -1
  142. package/cjs/ops/utils/Version.test.js.map +1 -1
  143. package/cjs/ops/utils/Wordwrap.js +1 -2
  144. package/cjs/ops/utils/Wordwrap.js.map +1 -1
  145. package/cjs/ops/utils/Wordwrap.test.js.map +1 -0
  146. package/cjs/shared/State.js +239 -0
  147. package/cjs/shared/State.js.map +1 -0
  148. package/cjs/shared/State.test.js.map +1 -0
  149. package/cjs/storage/StaticStorage.js.map +1 -1
  150. package/cjs/test/mocks/AuthenticateApi/step/default_steps.json +88 -0
  151. package/cjs/test/mocks/ForgeRockApiMockEngine.js +161 -83
  152. package/cjs/test/mocks/ForgeRockApiMockEngine.js.map +1 -1
  153. package/cjs/test/mocks/IdmConfigApi/getConfigEntity/managed.json +4420 -0
  154. package/cjs/test/mocks/OAuth2OIDCApi/accessToken/body.json +6 -0
  155. package/cjs/test/mocks/OAuth2OIDCApi/accessToken/headers.json +19 -0
  156. package/cjs/test/mocks/OAuth2OIDCApi/authorize/headers.json +38 -0
  157. package/cjs/test/mocks/ServerInfoApi/getServerInfo/info.json +25 -0
  158. package/cjs/test/mocks/ServerInfoApi/getServerVersionInfo/version.json +8 -0
  159. package/cjs/utils/AutoSetupPolly.js +79 -0
  160. package/cjs/utils/AutoSetupPolly.js.map +1 -0
  161. package/cjs/utils/SetupJest.js +6 -0
  162. package/cjs/utils/SetupJest.js.map +1 -0
  163. package/cjs/{test/mocks → utils}/snapshotResolve.js +10 -12
  164. package/cjs/utils/snapshotResolve.js.map +1 -0
  165. package/esm/api/AgentApi.mjs +19 -21
  166. package/esm/api/AgentApi.test.mjs +6 -15
  167. package/esm/api/ApiTypes.mjs +0 -5
  168. package/esm/api/AuthenticateApi.mjs +7 -10
  169. package/esm/api/AuthenticateApi.test.mjs +39 -0
  170. package/esm/api/BaseApi.mjs +96 -81
  171. package/esm/api/CirclesOfTrustApi.mjs +9 -12
  172. package/esm/api/IdmConfigApi.mjs +11 -12
  173. package/esm/api/LogApi.mjs +6 -10
  174. package/esm/api/ManagedObjectApi.mjs +23 -8
  175. package/esm/api/NodeApi.mjs +13 -15
  176. package/esm/api/NodeApi.test.mjs +13 -17
  177. package/esm/api/OAuth2ClientApi.mjs +7 -9
  178. package/esm/api/OAuth2OIDCApi.mjs +15 -9
  179. package/esm/api/OAuth2OIDCApi.test.mjs +53 -0
  180. package/esm/api/OAuth2ProviderApi.mjs +3 -5
  181. package/esm/api/RealmApi.mjs +10 -13
  182. package/esm/api/Saml2Api.mjs +25 -29
  183. package/esm/api/ScriptApi.mjs +9 -11
  184. package/esm/api/SecretsApi.mjs +21 -24
  185. package/esm/api/SecretsApi.test.mjs +9 -31
  186. package/esm/api/ServerInfoApi.mjs +5 -9
  187. package/esm/api/ServiceApi.mjs +53 -26
  188. package/esm/api/SocialIdentityProvidersApi.mjs +11 -13
  189. package/esm/api/StartupApi.mjs +5 -10
  190. package/esm/api/StartupApi.test.mjs +4 -7
  191. package/esm/api/TreeApi.mjs +9 -11
  192. package/esm/api/TreeApi.test.mjs +24 -61
  193. package/esm/api/VariablesApi.mjs +11 -13
  194. package/esm/api/VariablesApi.test.mjs +80 -222
  195. package/esm/api/utils/ApiUtils.mjs +45 -48
  196. package/esm/api/utils/ApiUtils.test.mjs +33 -32
  197. package/esm/api/utils/Base64.mjs +5 -9
  198. package/esm/ext/axios-curlirize/curlirize.mjs +2 -7
  199. package/esm/ext/axios-curlirize/lib/CurlHelper.mjs +7 -20
  200. package/esm/index.mjs +23 -13
  201. package/esm/ops/AdminOps.mjs +33 -119
  202. package/esm/ops/AgentOps.mjs +37 -80
  203. package/esm/ops/AgentOps.test.mjs +5 -45
  204. package/esm/ops/AuthenticateOps.mjs +242 -175
  205. package/esm/ops/AuthenticateOps.test.mjs +7 -9
  206. package/esm/ops/CirclesOfTrustOps.mjs +24 -61
  207. package/esm/ops/ConnectionProfileOps.mjs +192 -82
  208. package/esm/ops/ConnectionProfileOps.test.mjs +19 -19
  209. package/esm/ops/EmailTemplateOps.mjs +18 -276
  210. package/esm/ops/EmailTemplateOps.test.mjs +19 -44
  211. package/esm/ops/IdmOps.mjs +30 -327
  212. package/esm/ops/IdmOps.test.mjs +47 -54
  213. package/esm/ops/IdpOps.mjs +21 -59
  214. package/esm/ops/IdpOps.test.mjs +5 -5
  215. package/esm/ops/JoseOps.mjs +41 -0
  216. package/esm/ops/JoseOps.test.mjs +137 -0
  217. package/esm/ops/JourneyOps.mjs +146 -289
  218. package/esm/ops/JourneyOps.test.mjs +29 -27
  219. package/esm/ops/LogOps.mjs +15 -25
  220. package/esm/ops/ManagedObjectOps.mjs +6 -6
  221. package/esm/ops/NodeOps.mjs +9 -47
  222. package/esm/ops/OAuth2ClientOps.mjs +13 -19
  223. package/esm/ops/OpsTypes.mjs +1 -3
  224. package/esm/ops/OrganizationOps.mjs +7 -14
  225. package/esm/ops/RealmOps.mjs +4 -7
  226. package/esm/ops/Saml2Ops.mjs +28 -62
  227. package/esm/ops/Saml2Ops.test.mjs +20 -23
  228. package/esm/ops/ScriptOps.mjs +29 -47
  229. package/esm/ops/SecretsOps.mjs +15 -31
  230. package/esm/ops/ServiceAccountOps.mjs +41 -0
  231. package/esm/ops/ServiceAccountOps.test.mjs +51 -0
  232. package/esm/ops/ServiceOps.mjs +66 -83
  233. package/esm/ops/StartupOps.mjs +4 -13
  234. package/esm/ops/ThemeOps.mjs +189 -298
  235. package/esm/{api/ThemeApi.test.mjs → ops/ThemeOps.test.mjs} +91 -96
  236. package/esm/ops/VariablesOps.mjs +9 -18
  237. package/esm/ops/utils/Console.mjs +28 -46
  238. package/esm/ops/utils/DataProtection.mjs +15 -28
  239. package/esm/ops/utils/DataProtection.test.mjs +8 -8
  240. package/esm/ops/utils/ExportImportUtils.mjs +34 -43
  241. package/esm/ops/utils/ExportImportUtils.test.mjs +20 -18
  242. package/esm/ops/utils/OpsUtils.mjs +27 -21
  243. package/esm/ops/utils/OpsUtils.test.mjs +155 -27
  244. package/esm/ops/utils/ValidationUtils.mjs +0 -9
  245. package/esm/ops/utils/Version.mjs +2 -3
  246. package/esm/ops/utils/Version.test.mjs +0 -2
  247. package/esm/ops/utils/Wordwrap.mjs +1 -1
  248. package/esm/ops/utils/Wordwrap.test.mjs +19 -0
  249. package/esm/shared/State.mjs +164 -0
  250. package/esm/shared/State.test.mjs +249 -0
  251. package/esm/test/mocks/AuthenticateApi/step/default_steps.json +88 -0
  252. package/esm/test/mocks/ForgeRockApiMockEngine.mjs +147 -31
  253. package/esm/test/mocks/IdmConfigApi/getConfigEntity/managed.json +4420 -0
  254. package/esm/test/mocks/OAuth2OIDCApi/accessToken/body.json +6 -0
  255. package/esm/test/mocks/OAuth2OIDCApi/accessToken/headers.json +19 -0
  256. package/esm/test/mocks/OAuth2OIDCApi/authorize/headers.json +38 -0
  257. package/esm/test/mocks/ServerInfoApi/getServerInfo/info.json +25 -0
  258. package/esm/test/mocks/ServerInfoApi/getServerVersionInfo/version.json +8 -0
  259. package/esm/utils/AutoSetupPolly.mjs +72 -0
  260. package/esm/utils/SetupJest.mjs +3 -0
  261. package/esm/{test/mocks → utils}/snapshotResolve.mjs +10 -12
  262. package/package.json +36 -26
  263. package/types/api/AgentApi.d.ts.map +1 -1
  264. package/types/api/ApiTypes.d.ts +15 -16
  265. package/types/api/ApiTypes.d.ts.map +1 -1
  266. package/types/api/AuthenticateApi.d.ts +1 -1
  267. package/types/api/AuthenticateApi.d.ts.map +1 -1
  268. package/types/api/BaseApi.d.ts +2 -0
  269. package/types/api/BaseApi.d.ts.map +1 -1
  270. package/types/api/CirclesOfTrustApi.d.ts.map +1 -1
  271. package/types/api/IdmConfigApi.d.ts.map +1 -1
  272. package/types/api/LogApi.d.ts.map +1 -1
  273. package/types/api/ManagedObjectApi.d.ts +9 -1
  274. package/types/api/ManagedObjectApi.d.ts.map +1 -1
  275. package/types/api/NodeApi.d.ts.map +1 -1
  276. package/types/api/OAuth2ClientApi.d.ts.map +1 -1
  277. package/types/api/OAuth2OIDCApi.d.ts +4 -2
  278. package/types/api/OAuth2OIDCApi.d.ts.map +1 -1
  279. package/types/api/OAuth2ProviderApi.d.ts.map +1 -1
  280. package/types/api/RealmApi.d.ts.map +1 -1
  281. package/types/api/Saml2Api.d.ts.map +1 -1
  282. package/types/api/ScriptApi.d.ts.map +1 -1
  283. package/types/api/SecretsApi.d.ts.map +1 -1
  284. package/types/api/ServerInfoApi.d.ts.map +1 -1
  285. package/types/api/ServiceApi.d.ts +14 -7
  286. package/types/api/ServiceApi.d.ts.map +1 -1
  287. package/types/api/SocialIdentityProvidersApi.d.ts.map +1 -1
  288. package/types/api/StartupApi.d.ts.map +1 -1
  289. package/types/api/TreeApi.d.ts.map +1 -1
  290. package/types/api/VariablesApi.d.ts.map +1 -1
  291. package/types/api/utils/ApiUtils.d.ts +1 -0
  292. package/types/api/utils/ApiUtils.d.ts.map +1 -1
  293. package/types/index.d.ts +11 -5
  294. package/types/index.d.ts.map +1 -1
  295. package/types/ops/AuthenticateOps.d.ts +10 -2
  296. package/types/ops/AuthenticateOps.d.ts.map +1 -1
  297. package/types/ops/ConnectionProfileOps.d.ts +49 -21
  298. package/types/ops/ConnectionProfileOps.d.ts.map +1 -1
  299. package/types/ops/EmailTemplateOps.d.ts +14 -33
  300. package/types/ops/EmailTemplateOps.d.ts.map +1 -1
  301. package/types/ops/IdmOps.d.ts +29 -37
  302. package/types/ops/IdmOps.d.ts.map +1 -1
  303. package/types/ops/JoseOps.d.ts +33 -0
  304. package/types/ops/JoseOps.d.ts.map +1 -0
  305. package/types/ops/JourneyOps.d.ts.map +1 -1
  306. package/types/ops/LogOps.d.ts.map +1 -1
  307. package/types/ops/NodeOps.d.ts.map +1 -1
  308. package/types/ops/OAuth2ClientOps.d.ts.map +1 -1
  309. package/types/ops/OpsTypes.d.ts +1 -1
  310. package/types/ops/OpsTypes.d.ts.map +1 -1
  311. package/types/ops/OrganizationOps.d.ts.map +1 -1
  312. package/types/ops/ScriptOps.d.ts.map +1 -1
  313. package/types/ops/ServiceAccountOps.d.ts +20 -0
  314. package/types/ops/ServiceAccountOps.d.ts.map +1 -0
  315. package/types/ops/ServiceOps.d.ts +18 -10
  316. package/types/ops/ServiceOps.d.ts.map +1 -1
  317. package/types/ops/ThemeOps.d.ts +35 -50
  318. package/types/ops/ThemeOps.d.ts.map +1 -1
  319. package/types/ops/utils/Console.d.ts +1 -1
  320. package/types/ops/utils/Console.d.ts.map +1 -1
  321. package/types/ops/utils/DataProtection.d.ts.map +1 -1
  322. package/types/ops/utils/ExportImportUtils.d.ts +5 -2
  323. package/types/ops/utils/ExportImportUtils.d.ts.map +1 -1
  324. package/types/ops/utils/OpsUtils.d.ts +6 -0
  325. package/types/ops/utils/OpsUtils.d.ts.map +1 -1
  326. package/types/ops/utils/Wordwrap.d.ts.map +1 -1
  327. package/types/shared/State.d.ts +223 -0
  328. package/types/shared/State.d.ts.map +1 -0
  329. package/types/test/mocks/ForgeRockApiMockEngine.d.ts +19 -1
  330. package/types/test/mocks/ForgeRockApiMockEngine.d.ts.map +1 -1
  331. package/types/utils/AutoSetupPolly.d.ts +1 -0
  332. package/types/utils/AutoSetupPolly.d.ts.map +1 -0
  333. package/types/utils/SetupJest.d.ts +1 -0
  334. package/types/utils/SetupJest.d.ts.map +1 -0
  335. package/types/utils/snapshotResolve.d.ts +1 -0
  336. package/types/utils/snapshotResolve.d.ts.map +1 -0
  337. package/cjs/api/EmailTemplateApi.js +0 -73
  338. package/cjs/api/EmailTemplateApi.js.map +0 -1
  339. package/cjs/api/ThemeApi.js +0 -367
  340. package/cjs/api/ThemeApi.js.map +0 -1
  341. package/cjs/api/ThemeApi.test.js.map +0 -1
  342. package/cjs/storage/SessionStorage.js +0 -91
  343. package/cjs/storage/SessionStorage.js.map +0 -1
  344. package/cjs/test/mocks/snapshotResolve.js.map +0 -1
  345. package/esm/api/EmailTemplateApi.mjs +0 -34
  346. package/esm/api/ThemeApi.mjs +0 -271
  347. package/esm/storage/SessionStorage.mjs +0 -79
  348. package/types/api/EmailTemplateApi.d.ts +0 -22
  349. package/types/api/EmailTemplateApi.d.ts.map +0 -1
  350. package/types/api/ThemeApi.d.ts +0 -56
  351. package/types/api/ThemeApi.d.ts.map +0 -1
  352. package/types/storage/SessionStorage.d.ts +0 -71
  353. package/types/storage/SessionStorage.d.ts.map +0 -1
  354. package/types/test/mocks/snapshotResolve.d.ts +0 -1
  355. package/types/test/mocks/snapshotResolve.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/OrganizationOps.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,2BAA2B,WAQ1C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,mBAkCrC;AAGD,wBAAsB,wBAAwB,mBA6B7C","file":"OrganizationOps.d.ts","sourcesContent":["import { queryAllManagedObjectsByType } from '../api/IdmConfigApi';\nimport storage from '../storage/SessionStorage';\nimport { printMessage } from './utils/Console';\n\n/**\n * Get organization managed object type\n * @returns {String} organization managed object type in this realm\n */\nexport function getRealmManagedOrganization() {\n let realmManagedOrg = 'organization';\n if (\n storage.session.getDeploymentType() === global.CLOUD_DEPLOYMENT_TYPE_KEY\n ) {\n realmManagedOrg = `${storage.session.getRealm()}_organization`;\n }\n return realmManagedOrg;\n}\n\n/**\n * Get organizations\n * @returns {Promise} promise resolving to an object containing an array of organization objects\n */\nexport async function getOrganizations() {\n const orgs = [];\n let result = {\n result: [],\n resultCount: 0,\n pagedResultsCookie: null,\n totalPagedResultsPolicy: 'NONE',\n totalPagedResults: -1,\n remainingPagedResults: -1,\n };\n try {\n do {\n try {\n // eslint-disable-next-line no-await-in-loop\n result = await queryAllManagedObjectsByType(\n getRealmManagedOrganization(),\n ['name', 'parent/*/name', 'children/*/name'],\n result.pagedResultsCookie\n );\n } catch (queryAllManagedObjectsByTypeError) {\n printMessage(queryAllManagedObjectsByTypeError, 'error');\n printMessage(\n `Error querying ${getRealmManagedOrganization()} objects: ${queryAllManagedObjectsByTypeError}`,\n 'error'\n );\n }\n orgs.concat(result.result);\n printMessage('.', 'text', false);\n } while (result.pagedResultsCookie);\n } catch (error) {\n printMessage(error.response.data, 'error');\n printMessage(`Error retrieving all organizations: ${error}`, 'error');\n }\n return orgs;\n}\n\n// unfinished work\nexport async function listOrganizationsTopDown() {\n const orgs = [];\n let result = {\n result: [],\n resultCount: 0,\n pagedResultsCookie: null,\n totalPagedResultsPolicy: 'NONE',\n totalPagedResults: -1,\n remainingPagedResults: -1,\n };\n do {\n try {\n // eslint-disable-next-line no-await-in-loop\n result = await queryAllManagedObjectsByType(\n getRealmManagedOrganization(),\n ['name', 'parent/*/name', 'children/*/name'],\n result.pagedResultsCookie\n );\n } catch (queryAllManagedObjectsByTypeError) {\n printMessage(queryAllManagedObjectsByTypeError, 'error');\n printMessage(\n `Error querying ${getRealmManagedOrganization()} objects: ${queryAllManagedObjectsByTypeError}`,\n 'error'\n );\n }\n orgs.concat(result.result);\n printMessage('.', 'text', false);\n } while (result.pagedResultsCookie);\n return orgs;\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/OrganizationOps.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,2BAA2B,WAM1C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,mBAkCrC;AAGD,wBAAsB,wBAAwB,mBA6B7C","file":"OrganizationOps.d.ts","sourcesContent":["import { queryAllManagedObjectsByType } from '../api/IdmConfigApi';\nimport * as state from '../shared/State';\nimport { printMessage } from './utils/Console';\n\n/**\n * Get organization managed object type\n * @returns {String} organization managed object type in this realm\n */\nexport function getRealmManagedOrganization() {\n let realmManagedOrg = 'organization';\n if (state.getDeploymentType() === global.CLOUD_DEPLOYMENT_TYPE_KEY) {\n realmManagedOrg = `${state.getRealm()}_organization`;\n }\n return realmManagedOrg;\n}\n\n/**\n * Get organizations\n * @returns {Promise} promise resolving to an object containing an array of organization objects\n */\nexport async function getOrganizations() {\n const orgs = [];\n let result = {\n result: [],\n resultCount: 0,\n pagedResultsCookie: null,\n totalPagedResultsPolicy: 'NONE',\n totalPagedResults: -1,\n remainingPagedResults: -1,\n };\n try {\n do {\n try {\n // eslint-disable-next-line no-await-in-loop\n result = await queryAllManagedObjectsByType(\n getRealmManagedOrganization(),\n ['name', 'parent/*/name', 'children/*/name'],\n result.pagedResultsCookie\n );\n } catch (queryAllManagedObjectsByTypeError) {\n printMessage(queryAllManagedObjectsByTypeError, 'error');\n printMessage(\n `Error querying ${getRealmManagedOrganization()} objects: ${queryAllManagedObjectsByTypeError}`,\n 'error'\n );\n }\n orgs.concat(result.result);\n printMessage('.', 'text', false);\n } while (result.pagedResultsCookie);\n } catch (error) {\n printMessage(error.response.data, 'error');\n printMessage(`Error retrieving all organizations: ${error}`, 'error');\n }\n return orgs;\n}\n\n// unfinished work\nexport async function listOrganizationsTopDown() {\n const orgs = [];\n let result = {\n result: [],\n resultCount: 0,\n pagedResultsCookie: null,\n totalPagedResultsPolicy: 'NONE',\n totalPagedResults: -1,\n remainingPagedResults: -1,\n };\n do {\n try {\n // eslint-disable-next-line no-await-in-loop\n result = await queryAllManagedObjectsByType(\n getRealmManagedOrganization(),\n ['name', 'parent/*/name', 'children/*/name'],\n result.pagedResultsCookie\n );\n } catch (queryAllManagedObjectsByTypeError) {\n printMessage(queryAllManagedObjectsByTypeError, 'error');\n printMessage(\n `Error querying ${getRealmManagedOrganization()} objects: ${queryAllManagedObjectsByTypeError}`,\n 'error'\n );\n }\n orgs.concat(result.result);\n printMessage('.', 'text', false);\n } while (result.pagedResultsCookie);\n return orgs;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/ScriptOps.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,UAAQ,iBA+B7C;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAelD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,KAAA,iBAwB7C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,kBAgBzC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA;;;GAwBlD;AAED,wBAAsB,qBAAqB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,MAAM,UAAQ,iBAiDrE","file":"ScriptOps.d.ts","sourcesContent":["import fs from 'fs';\nimport { v4 as uuidv4 } from 'uuid';\nimport { applyNameCollisionPolicy } from './utils/OpsUtils';\nimport {\n createProgressIndicator,\n createTable,\n printMessage,\n stopProgressIndicator,\n updateProgressIndicator,\n} from './utils/Console';\nimport { getScriptByName, getScripts, putScript } from '../api/ScriptApi';\nimport wordwrap from './utils/Wordwrap';\nimport {\n convertBase64TextToArray,\n convertTextArrayToBase64,\n getTypedFilename,\n saveToFile,\n titleCase,\n validateImport,\n} from './utils/ExportImportUtils';\nimport storage from '../storage/SessionStorage';\n\n/**\n * List scripts\n */\nexport async function listScripts(long = false) {\n try {\n const scripts = (await getScripts()).result;\n scripts.sort((a, b) => a.name.localeCompare(b.name));\n if (long) {\n const table = createTable([\n 'Name',\n 'UUID',\n 'Language',\n 'Context',\n 'Description',\n ]);\n const langMap = { JAVASCRIPT: 'JS', GROOVY: 'Groovy' };\n scripts.forEach((script) => {\n table.push([\n wordwrap(script.name, 25, ' '),\n script._id,\n langMap[script.language],\n wordwrap(titleCase(script.context.split('_').join(' ')), 25),\n wordwrap(script.description, 30),\n ]);\n });\n printMessage(table.toString(), 'data');\n } else {\n scripts.forEach((script) => {\n printMessage(`${script.name}`, 'data');\n });\n }\n } catch (error) {\n printMessage(`Error listing scripts - ${error}`, 'error');\n }\n}\n\n/**\n * Export script to file\n * @param {String} name script name\n * @param {String} file file name\n */\nexport async function exportScriptByName(name, file) {\n let fileName = getTypedFilename(name, 'script');\n if (file) {\n fileName = file;\n }\n const scriptData = (await getScriptByName(name)).result;\n if (scriptData.length > 1) {\n printMessage(`Multiple scripts with name ${name} found...`, 'error');\n }\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n });\n saveToFile('script', scriptData, '_id', fileName);\n}\n\n/**\n * Export all scripts to single file\n * @param {String} file file name\n */\nexport async function exportScriptsToFile(file) {\n let fileName = getTypedFilename(\n `all${storage.session.getRealm()}Scripts`,\n 'script'\n );\n if (file) {\n fileName = file;\n }\n const scriptList = (await getScripts()).result;\n const allScriptsData = [];\n createProgressIndicator(scriptList.length, 'Exporting script');\n for (const item of scriptList) {\n updateProgressIndicator(`Reading script ${item.name}`);\n // eslint-disable-next-line no-await-in-loop\n const scriptData = (await getScriptByName(item.name)).result;\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n allScriptsData.push(element);\n });\n }\n stopProgressIndicator('Done');\n saveToFile('script', allScriptsData, '_id', fileName);\n}\n\n/**\n * Export all scripts to individual files\n */\nexport async function exportScriptsToFiles() {\n const scriptList = (await getScripts()).result;\n createProgressIndicator(scriptList.length, 'Exporting script');\n for (const item of scriptList) {\n updateProgressIndicator(`Reading script ${item.name}`);\n // eslint-disable-next-line no-await-in-loop\n const scriptData = (await getScriptByName(item.name)).result;\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n });\n const fileName = getTypedFilename(item.name, 'script');\n saveToFile('script', scriptData, '_id', fileName);\n }\n stopProgressIndicator('Done');\n}\n\n/**\n * Import script\n * @param {String} id script uuid\n * @param {Object} data script object\n * @returns {Object} a status object\n */\nexport async function createOrUpdateScript(id, data) {\n try {\n await putScript(id, data);\n return { error: false, name: data.name };\n } catch (e) {\n if (e.response?.status === 409) {\n printMessage(\n `createOrUpdateScript WARNING: script with name ${data.name} already exists, using renaming policy... <name> => <name - imported (n)>`,\n 'warn'\n );\n const newName = applyNameCollisionPolicy(data.name);\n // console.log(newName);\n printMessage(`Trying to save script as ${newName}`, 'warn');\n // eslint-disable-next-line no-param-reassign\n data.name = newName;\n await createOrUpdateScript(id, data);\n return { error: false, name: data.name };\n }\n printMessage(\n `createOrUpdateScript ERROR: put script error, script ${id} - ${e.message}`,\n 'error'\n );\n return { error: true, name: data.name };\n }\n}\n\nexport async function importScriptsFromFile(name, file, reUuid = false) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const scriptData = JSON.parse(data);\n if (validateImport(scriptData.meta)) {\n createProgressIndicator(Object.keys(scriptData.script).length, '');\n for (const existingId in scriptData.script) {\n if ({}.hasOwnProperty.call(scriptData.script, existingId)) {\n let newId = existingId;\n // console.log(id);\n const encodedScript = convertTextArrayToBase64(\n scriptData.script[existingId].script\n );\n scriptData.script[existingId].script = encodedScript;\n if (reUuid) {\n newId = uuidv4();\n // printMessage(\n // `Re-uuid-ing script ${scriptData.script[existingId].name} ${existingId} => ${newId}...`\n // );\n scriptData.script[existingId]._id = newId;\n }\n if (name) {\n // printMessage(\n // `Renaming script ${scriptData.script[existingId].name} => ${options.script}...`\n // );\n scriptData.script[existingId].name = name;\n }\n updateProgressIndicator(\n `Importing ${scriptData.script[existingId].name}`\n );\n // console.log(scriptData.script[id]);\n createOrUpdateScript(newId, scriptData.script[existingId]).then(\n (result) => {\n if (result == null)\n printMessage(\n `Error importing ${scriptData.script[existingId].name}`,\n 'error'\n );\n }\n );\n if (name) break;\n }\n }\n stopProgressIndicator('Done');\n // printMessage('Done');\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/ScriptOps.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,UAAQ,iBA+B7C;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAelD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,KAAA,iBAqB7C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,kBAgBzC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA;;;GAwBlD;AAED,wBAAsB,qBAAqB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,MAAM,UAAQ,iBAiDrE","file":"ScriptOps.d.ts","sourcesContent":["import fs from 'fs';\nimport { v4 as uuidv4 } from 'uuid';\nimport { applyNameCollisionPolicy } from './utils/OpsUtils';\nimport {\n createProgressIndicator,\n createTable,\n printMessage,\n stopProgressIndicator,\n updateProgressIndicator,\n} from './utils/Console';\nimport { getScriptByName, getScripts, putScript } from '../api/ScriptApi';\nimport wordwrap from './utils/Wordwrap';\nimport {\n convertBase64TextToArray,\n convertTextArrayToBase64,\n getTypedFilename,\n saveToFile,\n titleCase,\n validateImport,\n} from './utils/ExportImportUtils';\nimport * as state from '../shared/State';\n\n/**\n * List scripts\n */\nexport async function listScripts(long = false) {\n try {\n const scripts = (await getScripts()).result;\n scripts.sort((a, b) => a.name.localeCompare(b.name));\n if (long) {\n const table = createTable([\n 'Name',\n 'UUID',\n 'Language',\n 'Context',\n 'Description',\n ]);\n const langMap = { JAVASCRIPT: 'JS', GROOVY: 'Groovy' };\n scripts.forEach((script) => {\n table.push([\n wordwrap(script.name, 25, ' '),\n script._id,\n langMap[script.language],\n wordwrap(titleCase(script.context.split('_').join(' ')), 25),\n wordwrap(script.description, 30),\n ]);\n });\n printMessage(table.toString(), 'data');\n } else {\n scripts.forEach((script) => {\n printMessage(`${script.name}`, 'data');\n });\n }\n } catch (error) {\n printMessage(`Error listing scripts - ${error}`, 'error');\n }\n}\n\n/**\n * Export script to file\n * @param {String} name script name\n * @param {String} file file name\n */\nexport async function exportScriptByName(name, file) {\n let fileName = getTypedFilename(name, 'script');\n if (file) {\n fileName = file;\n }\n const scriptData = (await getScriptByName(name)).result;\n if (scriptData.length > 1) {\n printMessage(`Multiple scripts with name ${name} found...`, 'error');\n }\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n });\n saveToFile('script', scriptData, '_id', fileName);\n}\n\n/**\n * Export all scripts to single file\n * @param {String} file file name\n */\nexport async function exportScriptsToFile(file) {\n let fileName = getTypedFilename(`all${state.getRealm()}Scripts`, 'script');\n if (file) {\n fileName = file;\n }\n const scriptList = (await getScripts()).result;\n const allScriptsData = [];\n createProgressIndicator(scriptList.length, 'Exporting script');\n for (const item of scriptList) {\n updateProgressIndicator(`Reading script ${item.name}`);\n // eslint-disable-next-line no-await-in-loop\n const scriptData = (await getScriptByName(item.name)).result;\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n allScriptsData.push(element);\n });\n }\n stopProgressIndicator('Done');\n saveToFile('script', allScriptsData, '_id', fileName);\n}\n\n/**\n * Export all scripts to individual files\n */\nexport async function exportScriptsToFiles() {\n const scriptList = (await getScripts()).result;\n createProgressIndicator(scriptList.length, 'Exporting script');\n for (const item of scriptList) {\n updateProgressIndicator(`Reading script ${item.name}`);\n // eslint-disable-next-line no-await-in-loop\n const scriptData = (await getScriptByName(item.name)).result;\n scriptData.forEach((element) => {\n const scriptTextArray = convertBase64TextToArray(element.script);\n // eslint-disable-next-line no-param-reassign\n element.script = scriptTextArray;\n });\n const fileName = getTypedFilename(item.name, 'script');\n saveToFile('script', scriptData, '_id', fileName);\n }\n stopProgressIndicator('Done');\n}\n\n/**\n * Import script\n * @param {String} id script uuid\n * @param {Object} data script object\n * @returns {Object} a status object\n */\nexport async function createOrUpdateScript(id, data) {\n try {\n await putScript(id, data);\n return { error: false, name: data.name };\n } catch (e) {\n if (e.response?.status === 409) {\n printMessage(\n `createOrUpdateScript WARNING: script with name ${data.name} already exists, using renaming policy... <name> => <name - imported (n)>`,\n 'warn'\n );\n const newName = applyNameCollisionPolicy(data.name);\n // console.log(newName);\n printMessage(`Trying to save script as ${newName}`, 'warn');\n // eslint-disable-next-line no-param-reassign\n data.name = newName;\n await createOrUpdateScript(id, data);\n return { error: false, name: data.name };\n }\n printMessage(\n `createOrUpdateScript ERROR: put script error, script ${id} - ${e.message}`,\n 'error'\n );\n return { error: true, name: data.name };\n }\n}\n\nexport async function importScriptsFromFile(name, file, reUuid = false) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const scriptData = JSON.parse(data);\n if (validateImport(scriptData.meta)) {\n createProgressIndicator(Object.keys(scriptData.script).length, '');\n for (const existingId in scriptData.script) {\n if ({}.hasOwnProperty.call(scriptData.script, existingId)) {\n let newId = existingId;\n // console.log(id);\n const encodedScript = convertTextArrayToBase64(\n scriptData.script[existingId].script\n );\n scriptData.script[existingId].script = encodedScript;\n if (reUuid) {\n newId = uuidv4();\n // printMessage(\n // `Re-uuid-ing script ${scriptData.script[existingId].name} ${existingId} => ${newId}...`\n // );\n scriptData.script[existingId]._id = newId;\n }\n if (name) {\n // printMessage(\n // `Renaming script ${scriptData.script[existingId].name} => ${options.script}...`\n // );\n scriptData.script[existingId].name = name;\n }\n updateProgressIndicator(\n `Importing ${scriptData.script[existingId].name}`\n );\n // console.log(scriptData.script[id]);\n createOrUpdateScript(newId, scriptData.script[existingId]).then(\n (result) => {\n if (result == null)\n printMessage(\n `Error importing ${scriptData.script[existingId].name}`,\n 'error'\n );\n }\n );\n if (name) break;\n }\n }\n stopProgressIndicator('Done');\n // printMessage('Done');\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import { JwksInterface } from './JoseOps';
2
+ import { ObjectSkeletonInterface } from '../api/ApiTypes';
3
+ export interface SvcacctInterface {
4
+ name: string;
5
+ description: string;
6
+ accountStatus: 'Active' | 'Inactive';
7
+ scopes: string[];
8
+ jwks: string;
9
+ }
10
+ export declare function isServiceAccountsFeatureAvailable(): Promise<boolean>;
11
+ /**
12
+ * Create service account
13
+ * @param {string} name Human-readable name of service account
14
+ * @param {string} description Description of service account
15
+ * @param {'Active' | 'Inactive'} accountStatus Service account status
16
+ * @param {string[]} scopes Scopes.
17
+ * @param {JwksInterface} jwks Java Web Key Set
18
+ * @returns {Promise<ObjectSkeletonInterface>} A promise resolving to a service account object
19
+ */
20
+ export declare function createServiceAccount(name: string, description: string, accountStatus: 'Active' | 'Inactive', scopes: string[], jwks: JwksInterface): Promise<ObjectSkeletonInterface>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ops/ServiceAccountOps.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAM1D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,QAAQ,GAAG,UAAU,CAAC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,OAAO,CAAC,CAe1E;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,QAAQ,GAAG,UAAU,EACpC,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,uBAAuB,CAAC,CAYlC","file":"ServiceAccountOps.d.ts","sourcesContent":["import { createManagedObject } from '../api/ManagedObjectApi';\nimport { JwksInterface } from './JoseOps';\nimport { ObjectSkeletonInterface } from '../api/ApiTypes';\nimport { debugMessage } from './utils/Console';\nimport { getConfigEntity } from './IdmOps';\n\nconst moType = 'svcacct';\n\nexport interface SvcacctInterface {\n name: string;\n description: string;\n accountStatus: 'Active' | 'Inactive';\n scopes: string[];\n jwks: string;\n}\n\nlet serviceAccountsFeatureAvailable: boolean = undefined;\nexport async function isServiceAccountsFeatureAvailable(): Promise<boolean> {\n debugMessage(`ServiceAccountOps.isServiceAccountsFeatureAvailable: start`);\n // only look up the schema once\n if (typeof serviceAccountsFeatureAvailable !== 'undefined')\n return serviceAccountsFeatureAvailable;\n\n serviceAccountsFeatureAvailable = false;\n const schema = await getConfigEntity('managed');\n for (const object of schema['objects']) {\n if (object['name'] === 'svcacct') serviceAccountsFeatureAvailable = true;\n }\n debugMessage(\n `ServiceAccountOps.isServiceAccountsFeatureAvailable: end, available=${serviceAccountsFeatureAvailable}`\n );\n return serviceAccountsFeatureAvailable;\n}\n\n/**\n * Create service account\n * @param {string} name Human-readable name of service account\n * @param {string} description Description of service account\n * @param {'Active' | 'Inactive'} accountStatus Service account status\n * @param {string[]} scopes Scopes.\n * @param {JwksInterface} jwks Java Web Key Set\n * @returns {Promise<ObjectSkeletonInterface>} A promise resolving to a service account object\n */\nexport async function createServiceAccount(\n name: string,\n description: string,\n accountStatus: 'Active' | 'Inactive',\n scopes: string[],\n jwks: JwksInterface\n): Promise<ObjectSkeletonInterface> {\n const payload: SvcacctInterface = {\n name,\n description,\n accountStatus,\n scopes,\n jwks: JSON.stringify(jwks),\n };\n debugMessage(`SvcacctOps: createSvcacct: payload:`);\n debugMessage(payload);\n const result = await createManagedObject(moType, payload);\n return result;\n}\n"]}
@@ -11,44 +11,52 @@ interface FullService extends AmServiceSkeleton {
11
11
  export declare function createServiceExportTemplate(): ServiceExportInterface;
12
12
  /**
13
13
  * Get list of services
14
+ * @param {boolean} globalConfig true if the list of global services is requested, false otherwise. Default: false.
14
15
  */
15
- export declare function getListOfServices(): Promise<import("../api/ServiceApi").ServiceListItem[]>;
16
+ export declare function getListOfServices(globalConfig?: boolean): Promise<import("../api/ServiceApi").ServiceListItem[]>;
16
17
  /**
17
18
  * Get all services including their descendents.
19
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
18
20
  * @returns Promise resolving to an array of services with their descendants
19
21
  */
20
- export declare function getFullServices(): Promise<FullService[]>;
22
+ export declare function getFullServices(globalConfig?: boolean): Promise<FullService[]>;
21
23
  /**
22
24
  * Deletes the specified service
23
25
  * @param {string} serviceId The service to delete
26
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
24
27
  */
25
- export declare function deleteFullService(serviceId: string): Promise<void>;
28
+ export declare function deleteFullService(serviceId: string, globalConfig?: boolean): Promise<void>;
26
29
  /**
27
30
  * Deletes all services
31
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
28
32
  */
29
- export declare function deleteFullServices(): Promise<void>;
33
+ export declare function deleteFullServices(globalConfig?: boolean): Promise<void>;
30
34
  /**
31
35
  * Export service. The response can be saved to file as is.
32
36
  * @param serviceId service id/name
37
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
33
38
  * @returns {Promise<ServiceExportInterface>} Promise resolving to a ServiceExportInterface object.
34
39
  */
35
- export declare function exportService(serviceId: string): Promise<ServiceExportInterface>;
40
+ export declare function exportService(serviceId: string, globalConfig?: boolean): Promise<ServiceExportInterface>;
36
41
  /**
37
42
  * Export all services
38
- * @param {string} file Options filename for the file, otherwise all{realm}Services.service.json will be the name
43
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
39
44
  */
40
- export declare function exportServices(): Promise<ServiceExportInterface>;
45
+ export declare function exportServices(globalConfig?: boolean): Promise<ServiceExportInterface>;
41
46
  /**
42
47
  * Imports a single service using a reference to the service and a file to read the data from. Optionally clean (remove) an existing service first
43
48
  * @param {string} serviceId The service id/name to add
49
+ * @param {ServiceExportInterface} importData The service configuration export data to import
44
50
  * @param {boolean} clean Indicates whether to remove a possible existing service with the same id first.
45
- * @param {string} file Reference to the filename with the data for the service
51
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
46
52
  * @returns Promise resolving when the service has been imported
47
53
  */
48
- export declare function importService(serviceId: string, importData: ServiceExportInterface, clean: boolean): Promise<AmServiceSkeleton>;
54
+ export declare function importService(serviceId: string, importData: ServiceExportInterface, clean: boolean, globalConfig?: boolean): Promise<AmServiceSkeleton>;
49
55
  /**
50
56
  * Imports multiple services from the same file. Optionally clean (remove) existing services first
57
+ * @param {ServiceExportInterface} importData The service configuration export data to import
51
58
  * @param {boolean} clean Indicates whether to remove possible existing services first
59
+ * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.
52
60
  */
53
- export declare function importServices(importData: ServiceExportInterface, clean: boolean): Promise<AmServiceSkeleton[]>;
61
+ export declare function importServices(importData: ServiceExportInterface, clean: boolean, globalConfig?: boolean): Promise<AmServiceSkeleton[]>;
54
62
  export {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/ServiceOps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAQL,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD,UAAU,WAAY,SAAQ,iBAAiB;IAC7C,eAAe,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,sBAAsB,CAKpE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,2DAKtC;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAoC9D;AA0GD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,iBAcxD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,kBA+BvC;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAajC;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,sBAAsB,CAAC,CActE;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,sBAAsB,EAClC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,CAM5B;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,sBAAsB,EAClC,KAAK,EAAE,OAAO,gCAmBf","file":"ServiceOps.d.ts","sourcesContent":["import { AmServiceSkeleton } from '../api/ApiTypes';\nimport {\n deleteService,\n deleteServiceNextDescendent,\n getService,\n getListOfServices as _getListOfServices,\n getServiceDescendents,\n putService,\n putServiceNextDescendent,\n ServiceNextDescendent,\n} from '../api/ServiceApi';\nimport { ServiceExportInterface } from './OpsTypes';\nimport { debugMessage, printMessage } from './utils/Console';\n\ninterface FullService extends AmServiceSkeleton {\n nextDescendents?: ServiceNextDescendent[];\n}\n\n/**\n * Create an empty service export template\n * @returns {SingleTreeExportInterface} an empty service export template\n */\nexport function createServiceExportTemplate(): ServiceExportInterface {\n return {\n meta: {},\n service: {},\n } as ServiceExportInterface;\n}\n\n/**\n * Get list of services\n */\nexport async function getListOfServices() {\n debugMessage(`ServiceOps.getListOfServices: start`);\n const services = (await _getListOfServices()).result;\n debugMessage(`ServiceOps.getListOfServices: end`);\n return services;\n}\n\n/**\n * Get all services including their descendents.\n * @returns Promise resolving to an array of services with their descendants\n */\nexport async function getFullServices(): Promise<FullService[]> {\n debugMessage(`ServiceOps.getFullServices: start`);\n const serviceList = (await _getListOfServices()).result;\n\n const fullServiceData = await Promise.all(\n serviceList.map(async (listItem) => {\n try {\n const [service, nextDescendents] = await Promise.all([\n getService(listItem._id),\n getServiceDescendents(listItem._id),\n ]);\n\n return {\n ...service,\n nextDescendents,\n };\n } catch (error) {\n if (\n !(\n error.response?.status === 403 &&\n error.response?.data?.message ===\n 'This operation is not available in ForgeRock Identity Cloud.'\n )\n ) {\n const message = error.response?.data?.message;\n printMessage(\n `Unable to retrieve data for ${listItem._id} with error: ${message}`,\n 'error'\n );\n }\n }\n })\n );\n\n debugMessage(`ServiceOps.getFullServices: end`);\n return fullServiceData.filter((data) => !!data); // make sure to filter out any undefined objects\n}\n\n/**\n * Saves a service using the provide id and data, including descendents\n * @param {string} serviceId the service id / name\n * @param {string} fullServiceData service object including descendants\n * @returns promise resolving to a service object\n */\nasync function putFullService(\n serviceId: string,\n fullServiceData: FullService,\n clean: boolean\n): Promise<AmServiceSkeleton> {\n debugMessage(`ServiceOps.putFullService: start, serviceId=${serviceId}`);\n const nextDescendents = fullServiceData.nextDescendents;\n\n delete fullServiceData.nextDescendents;\n delete fullServiceData._rev;\n delete fullServiceData.enabled;\n\n if (clean) {\n try {\n debugMessage(`ServiceOps.putFullService: clean`);\n await deleteFullService(serviceId);\n } catch (error) {\n if (\n !(\n error.response?.status === 404 &&\n error.response?.data?.message === 'Not Found'\n )\n ) {\n const message = error.response?.data?.message;\n printMessage(\n `Error deleting service '${serviceId}' before import: ${message}`,\n 'error'\n );\n }\n }\n }\n\n // create service first\n const result = await putService(serviceId, fullServiceData);\n\n // return fast if no next descendents supplied\n if (nextDescendents.length === 0) {\n debugMessage(`ServiceOps.putFullService: end (w/o descendents)`);\n return result;\n }\n\n // now create next descendents\n await Promise.all(\n nextDescendents.map(async (descendent) => {\n const type = descendent._type._id;\n const descendentId = descendent._id;\n debugMessage(`ServiceOps.putFullService: descendentId=${descendentId}`);\n let result = undefined;\n try {\n result = await putServiceNextDescendent(\n serviceId,\n type,\n descendentId,\n descendent\n );\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(\n `Put descendent '${descendentId}' of service '${serviceId}': ${message}`,\n 'error'\n );\n }\n return result;\n })\n );\n debugMessage(`ServiceOps.putFullService: end (w/ descendents)`);\n}\n\n/**\n * Saves multiple services using the serviceEntries which contain both id and data with descendants\n * @param {[string, FullService][]} serviceEntries The services to add\n * @param {boolean} clean Indicates whether to remove possible existing services first\n * @returns {Promise<AmService[]>} promise resolving to an array of service objects\n */\nasync function putFullServices(\n serviceEntries: [string, FullService][],\n clean: boolean\n): Promise<AmServiceSkeleton[]> {\n debugMessage(`ServiceOps.putFullServices: start`);\n const results: AmServiceSkeleton[] = [];\n for (const [id, data] of serviceEntries) {\n try {\n const result = await putFullService(id, data, clean);\n results.push(result);\n printMessage(`Imported: ${id}`, 'info');\n } catch (error) {\n const message = error.response?.data?.message;\n const detail = error.response?.data?.detail;\n printMessage(`Import service '${id}': ${message}`, 'error');\n if (detail) {\n printMessage(`Details: ${JSON.stringify(detail)}`, 'error');\n }\n }\n }\n debugMessage(`ServiceOps.putFullServices: end`);\n return results;\n}\n\n/**\n * Deletes the specified service\n * @param {string} serviceId The service to delete\n */\nexport async function deleteFullService(serviceId: string) {\n const serviceNextDescendentData = await getServiceDescendents(serviceId);\n\n await Promise.all(\n serviceNextDescendentData.map((nextDescendent) =>\n deleteServiceNextDescendent(\n serviceId,\n nextDescendent._type._id,\n nextDescendent._id\n )\n )\n );\n\n await deleteService(serviceId);\n}\n\n/**\n * Deletes all services\n */\nexport async function deleteFullServices() {\n debugMessage(`ServiceOps.deleteFullServices: start`);\n try {\n const serviceList = (await _getListOfServices()).result;\n\n await Promise.all(\n serviceList.map(async (serviceListItem) => {\n try {\n await deleteFullService(serviceListItem._id);\n } catch (error) {\n if (\n !(\n error.response?.status === 403 &&\n error.response?.data?.message ===\n 'This operation is not available in ForgeRock Identity Cloud.'\n )\n ) {\n const message = error.response?.data?.message;\n printMessage(\n `Delete service '${serviceListItem._id}': ${message}`,\n 'error'\n );\n }\n }\n })\n );\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(`Delete services: ${message}`, 'error');\n }\n debugMessage(`ServiceOps.deleteFullServices: end`);\n}\n\n/**\n * Export service. The response can be saved to file as is.\n * @param serviceId service id/name\n * @returns {Promise<ServiceExportInterface>} Promise resolving to a ServiceExportInterface object.\n */\nexport async function exportService(\n serviceId: string\n): Promise<ServiceExportInterface> {\n debugMessage(`ServiceOps.exportService: start`);\n const exportData = createServiceExportTemplate();\n try {\n const service = await getService(serviceId);\n service.nextDescendents = await getServiceDescendents(serviceId);\n exportData.service[serviceId] = service;\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(`Export service '${serviceId}': ${message}`, 'error');\n }\n debugMessage(`ServiceOps.exportService: end`);\n return exportData;\n}\n\n/**\n * Export all services\n * @param {string} file Options filename for the file, otherwise all{realm}Services.service.json will be the name\n */\nexport async function exportServices(): Promise<ServiceExportInterface> {\n debugMessage(`ServiceOps.exportServices: start`);\n const exportData = createServiceExportTemplate();\n try {\n const services = await getFullServices();\n for (const service of services) {\n exportData.service[service._type._id] = service;\n }\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(`Export servics: ${message}`, 'error');\n }\n debugMessage(`ServiceOps.exportServices: end`);\n return exportData;\n}\n\n/**\n * Imports a single service using a reference to the service and a file to read the data from. Optionally clean (remove) an existing service first\n * @param {string} serviceId The service id/name to add\n * @param {boolean} clean Indicates whether to remove a possible existing service with the same id first.\n * @param {string} file Reference to the filename with the data for the service\n * @returns Promise resolving when the service has been imported\n */\nexport async function importService(\n serviceId: string,\n importData: ServiceExportInterface,\n clean: boolean\n): Promise<AmServiceSkeleton> {\n debugMessage(`ServiceOps.importService: start`);\n const serviceData = importData.service[serviceId];\n const result = await putFullService(serviceId, serviceData, clean);\n debugMessage(`ServiceOps.importService: end`);\n return result;\n}\n\n/**\n * Imports multiple services from the same file. Optionally clean (remove) existing services first\n * @param {boolean} clean Indicates whether to remove possible existing services first\n */\nexport async function importServices(\n importData: ServiceExportInterface,\n clean: boolean\n) {\n debugMessage(`ServiceOps.importServices: start`);\n try {\n const result = await putFullServices(\n Object.entries(importData.service),\n clean\n );\n debugMessage(`ServiceOps.importServices: end`);\n return result;\n } catch (error) {\n const message = error.response?.data?.message;\n const detail = error.response?.data?.detail;\n printMessage(`Unable to import services: error: ${message}`, 'error');\n if (detail) {\n printMessage(`Details: ${JSON.stringify(detail)}`, 'error');\n }\n throw error;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/ServiceOps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAQL,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD,UAAU,WAAY,SAAQ,iBAAiB;IAC7C,eAAe,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,sBAAsB,CAKpE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,YAAY,UAAQ,0DAK3D;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,YAAY,UAAQ,GACnB,OAAO,CAAC,WAAW,EAAE,CAAC,CAsCxB;AAmHD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,UAAQ,iBAuBrB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,YAAY,UAAQ,iBAiC5D;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,YAAY,UAAQ,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAgBjC;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,YAAY,UAAQ,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAgBjC;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,sBAAsB,EAClC,KAAK,EAAE,OAAO,EACd,YAAY,UAAQ,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAW5B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,sBAAsB,EAClC,KAAK,EAAE,OAAO,EACd,YAAY,UAAQ,gCAsBrB","file":"ServiceOps.d.ts","sourcesContent":["import { AmServiceSkeleton } from '../api/ApiTypes';\nimport {\n deleteService,\n deleteServiceNextDescendent,\n getService,\n getListOfServices as _getListOfServices,\n getServiceDescendents,\n putService,\n putServiceNextDescendent,\n ServiceNextDescendent,\n} from '../api/ServiceApi';\nimport { ServiceExportInterface } from './OpsTypes';\nimport { debugMessage, printMessage } from './utils/Console';\n\ninterface FullService extends AmServiceSkeleton {\n nextDescendents?: ServiceNextDescendent[];\n}\n\n/**\n * Create an empty service export template\n * @returns {SingleTreeExportInterface} an empty service export template\n */\nexport function createServiceExportTemplate(): ServiceExportInterface {\n return {\n meta: {},\n service: {},\n } as ServiceExportInterface;\n}\n\n/**\n * Get list of services\n * @param {boolean} globalConfig true if the list of global services is requested, false otherwise. Default: false.\n */\nexport async function getListOfServices(globalConfig = false) {\n debugMessage(`ServiceOps.getListOfServices: start`);\n const services = (await _getListOfServices(globalConfig)).result;\n debugMessage(`ServiceOps.getListOfServices: end`);\n return services;\n}\n\n/**\n * Get all services including their descendents.\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n * @returns Promise resolving to an array of services with their descendants\n */\nexport async function getFullServices(\n globalConfig = false\n): Promise<FullService[]> {\n debugMessage(\n `ServiceOps.getFullServices: start, globalConfig=${globalConfig}`\n );\n const serviceList = (await _getListOfServices(globalConfig)).result;\n\n const fullServiceData = await Promise.all(\n serviceList.map(async (listItem) => {\n try {\n const [service, nextDescendents] = await Promise.all([\n getService(listItem._id, globalConfig),\n getServiceDescendents(listItem._id, globalConfig),\n ]);\n\n return {\n ...service,\n nextDescendents,\n };\n } catch (error) {\n if (\n !(\n error.response?.status === 403 &&\n error.response?.data?.message ===\n 'This operation is not available in ForgeRock Identity Cloud.'\n )\n ) {\n const message = error.response?.data?.message;\n printMessage(\n `Unable to retrieve data for ${listItem._id} with error: ${message}`,\n 'error'\n );\n }\n }\n })\n );\n\n debugMessage(`ServiceOps.getFullServices: end`);\n return fullServiceData.filter((data) => !!data); // make sure to filter out any undefined objects\n}\n\n/**\n * Saves a service using the provide id and data, including descendents\n * @param {string} serviceId the service id / name\n * @param {string} fullServiceData service object including descendants\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n * @returns promise resolving to a service object\n */\nasync function putFullService(\n serviceId: string,\n fullServiceData: FullService,\n clean: boolean,\n globalConfig = false\n): Promise<AmServiceSkeleton> {\n debugMessage(\n `ServiceOps.putFullService: start, serviceId=${serviceId}, globalConfig=${globalConfig}`\n );\n const nextDescendents = fullServiceData.nextDescendents;\n\n delete fullServiceData.nextDescendents;\n delete fullServiceData._rev;\n delete fullServiceData.enabled;\n\n if (clean) {\n try {\n debugMessage(`ServiceOps.putFullService: clean`);\n await deleteFullService(serviceId, globalConfig);\n } catch (error) {\n if (\n !(\n error.response?.status === 404 &&\n error.response?.data?.message === 'Not Found'\n )\n ) {\n const message = error.response?.data?.message;\n printMessage(\n `Error deleting service '${serviceId}' before import: ${message}`,\n 'error'\n );\n }\n }\n }\n\n // create service first\n const result = await putService(serviceId, fullServiceData, globalConfig);\n\n // return fast if no next descendents supplied\n if (nextDescendents.length === 0) {\n debugMessage(`ServiceOps.putFullService: end (w/o descendents)`);\n return result;\n }\n\n // now create next descendents\n await Promise.all(\n nextDescendents.map(async (descendent) => {\n const type = descendent._type._id;\n const descendentId = descendent._id;\n debugMessage(`ServiceOps.putFullService: descendentId=${descendentId}`);\n let result = undefined;\n try {\n result = await putServiceNextDescendent(\n serviceId,\n type,\n descendentId,\n descendent,\n globalConfig\n );\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(\n `Put descendent '${descendentId}' of service '${serviceId}': ${message}`,\n 'error'\n );\n }\n return result;\n })\n );\n debugMessage(`ServiceOps.putFullService: end (w/ descendents)`);\n}\n\n/**\n * Saves multiple services using the serviceEntries which contain both id and data with descendants\n * @param {[string, FullService][]} serviceEntries The services to add\n * @param {boolean} clean Indicates whether to remove possible existing services first\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n * @returns {Promise<AmService[]>} promise resolving to an array of service objects\n */\nasync function putFullServices(\n serviceEntries: [string, FullService][],\n clean: boolean,\n globalConfig = false\n): Promise<AmServiceSkeleton[]> {\n debugMessage(\n `ServiceOps.putFullServices: start, globalConfig=${globalConfig}`\n );\n const results: AmServiceSkeleton[] = [];\n for (const [id, data] of serviceEntries) {\n try {\n const result = await putFullService(id, data, clean, globalConfig);\n results.push(result);\n printMessage(`Imported: ${id}`, 'info');\n } catch (error) {\n const message = error.response?.data?.message;\n const detail = error.response?.data?.detail;\n printMessage(`Import service '${id}': ${message}`, 'error');\n if (detail) {\n printMessage(`Details: ${JSON.stringify(detail)}`, 'error');\n }\n }\n }\n debugMessage(`ServiceOps.putFullServices: end`);\n return results;\n}\n\n/**\n * Deletes the specified service\n * @param {string} serviceId The service to delete\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n */\nexport async function deleteFullService(\n serviceId: string,\n globalConfig = false\n) {\n debugMessage(\n `ServiceOps.deleteFullService: start, globalConfig=${globalConfig}`\n );\n const serviceNextDescendentData = await getServiceDescendents(\n serviceId,\n globalConfig\n );\n\n await Promise.all(\n serviceNextDescendentData.map((nextDescendent) =>\n deleteServiceNextDescendent(\n serviceId,\n nextDescendent._type._id,\n nextDescendent._id,\n globalConfig\n )\n )\n );\n\n await deleteService(serviceId, globalConfig);\n debugMessage(`ServiceOps.deleteFullService: end`);\n}\n\n/**\n * Deletes all services\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n */\nexport async function deleteFullServices(globalConfig = false) {\n debugMessage(\n `ServiceOps.deleteFullServices: start, globalConfig=${globalConfig}`\n );\n try {\n const serviceList = (await _getListOfServices(globalConfig)).result;\n\n await Promise.all(\n serviceList.map(async (serviceListItem) => {\n try {\n await deleteFullService(serviceListItem._id, globalConfig);\n } catch (error) {\n if (\n !(\n error.response?.status === 403 &&\n error.response?.data?.message ===\n 'This operation is not available in ForgeRock Identity Cloud.'\n )\n ) {\n const message = error.response?.data?.message;\n printMessage(\n `Delete service '${serviceListItem._id}': ${message}`,\n 'error'\n );\n }\n }\n })\n );\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(`Delete services: ${message}`, 'error');\n }\n debugMessage(`ServiceOps.deleteFullServices: end`);\n}\n\n/**\n * Export service. The response can be saved to file as is.\n * @param serviceId service id/name\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n * @returns {Promise<ServiceExportInterface>} Promise resolving to a ServiceExportInterface object.\n */\nexport async function exportService(\n serviceId: string,\n globalConfig = false\n): Promise<ServiceExportInterface> {\n debugMessage(`ServiceOps.exportService: start, globalConfig=${globalConfig}`);\n const exportData = createServiceExportTemplate();\n try {\n const service = await getService(serviceId, globalConfig);\n service.nextDescendents = await getServiceDescendents(\n serviceId,\n globalConfig\n );\n exportData.service[serviceId] = service;\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(`Export service '${serviceId}': ${message}`, 'error');\n }\n debugMessage(`ServiceOps.exportService: end`);\n return exportData;\n}\n\n/**\n * Export all services\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n */\nexport async function exportServices(\n globalConfig = false\n): Promise<ServiceExportInterface> {\n debugMessage(\n `ServiceOps.exportServices: start, globalConfig=${globalConfig}`\n );\n const exportData = createServiceExportTemplate();\n try {\n const services = await getFullServices(globalConfig);\n for (const service of services) {\n exportData.service[service._type._id] = service;\n }\n } catch (error) {\n const message = error.response?.data?.message;\n printMessage(`Export servics: ${message}`, 'error');\n }\n debugMessage(`ServiceOps.exportServices: end`);\n return exportData;\n}\n\n/**\n * Imports a single service using a reference to the service and a file to read the data from. Optionally clean (remove) an existing service first\n * @param {string} serviceId The service id/name to add\n * @param {ServiceExportInterface} importData The service configuration export data to import\n * @param {boolean} clean Indicates whether to remove a possible existing service with the same id first.\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n * @returns Promise resolving when the service has been imported\n */\nexport async function importService(\n serviceId: string,\n importData: ServiceExportInterface,\n clean: boolean,\n globalConfig = false\n): Promise<AmServiceSkeleton> {\n debugMessage(`ServiceOps.importService: start, globalConfig=${globalConfig}`);\n const serviceData = importData.service[serviceId];\n const result = await putFullService(\n serviceId,\n serviceData,\n clean,\n globalConfig\n );\n debugMessage(`ServiceOps.importService: end`);\n return result;\n}\n\n/**\n * Imports multiple services from the same file. Optionally clean (remove) existing services first\n * @param {ServiceExportInterface} importData The service configuration export data to import\n * @param {boolean} clean Indicates whether to remove possible existing services first\n * @param {boolean} globalConfig true if the global service is the target of the operation, false otherwise. Default: false.\n */\nexport async function importServices(\n importData: ServiceExportInterface,\n clean: boolean,\n globalConfig = false\n) {\n debugMessage(\n `ServiceOps.importServices: start, globalConfig=${globalConfig}`\n );\n try {\n const result = await putFullServices(\n Object.entries(importData.service),\n clean,\n globalConfig\n );\n debugMessage(`ServiceOps.importServices: end`);\n return result;\n } catch (error) {\n const message = error.response?.data?.message;\n const detail = error.response?.data?.detail;\n printMessage(`Unable to import services: error: ${message}`, 'error');\n if (detail) {\n printMessage(`Details: ${JSON.stringify(detail)}`, 'error');\n }\n throw error;\n }\n}\n"]}
@@ -1,71 +1,56 @@
1
+ import { ThemeSkeleton } from '../api/ApiTypes';
2
+ export declare const THEMEREALM_ID = "ui/themerealm";
1
3
  /**
2
- * List all the themes
3
- * @param {boolean} long Long version, more fields
4
+ * Get all themes
5
+ * @returns {Promise<ThemeSkeleton[]>} a promise that resolves to an array of themes
4
6
  */
5
- export declare function listThemes(long?: boolean): Promise<void>;
7
+ export declare function getThemes(): Promise<ThemeSkeleton[]>;
6
8
  /**
7
- * Export theme by name to file
8
- * @param {String} name theme name
9
- * @param {String} file optional export file name
9
+ * Get theme by id
10
+ * @param {string} themeId theme id
11
+ * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object
10
12
  */
11
- export declare function exportThemeByName(name: any, file: any): Promise<void>;
13
+ export declare function getTheme(themeId: string): Promise<ThemeSkeleton>;
12
14
  /**
13
- * Export theme by uuid to file
14
- * @param {String} id theme uuid
15
- * @param {String} file optional export file name
15
+ * Get theme by name
16
+ * @param {string} themeName theme name
17
+ * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object
16
18
  */
17
- export declare function exportThemeById(id: any, file: any): Promise<void>;
19
+ export declare function getThemeByName(themeName: string): Promise<ThemeSkeleton>;
18
20
  /**
19
- * Export all themes to file
20
- * @param {String} file optional export file name
21
+ * Put theme by id
22
+ * @param {string} themeId theme id
23
+ * @param {ThemeSkeleton} themeData theme object
24
+ * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object
21
25
  */
22
- export declare function exportThemesToFile(file: any): Promise<void>;
26
+ export declare function putTheme(themeId: string, themeData: ThemeSkeleton): Promise<ThemeSkeleton>;
23
27
  /**
24
- * Export all themes to separate files
28
+ * Put theme by name
29
+ * @param {String} themeName theme name
30
+ * @param {ThemeSkeleton} themeData theme object
31
+ * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object
25
32
  */
26
- export declare function exportThemesToFiles(): Promise<void>;
33
+ export declare function putThemeByName(themeName: string, themeData: ThemeSkeleton): Promise<ThemeSkeleton>;
27
34
  /**
28
- * Import theme by name from file
29
- * @param {String} name theme name
30
- * @param {String} file import file name
35
+ * Put all themes
36
+ * @param {Map<string, ThemeSkeleton>} allThemesData themes object containing all themes for all realms
37
+ * @returns {Promise<Map<string, ThemeSkeleton>>} a promise that resolves to a themes object
31
38
  */
32
- export declare function importThemeByName(name: any, file: any): Promise<void>;
33
- /**
34
- * Import theme by uuid from file
35
- * @param {String} id theme uuid
36
- * @param {String} file import file name
37
- */
38
- export declare function importThemeById(id: any, file: any): Promise<void>;
39
- /**
40
- * Import all themes from single file
41
- * @param {String} file import file name
42
- */
43
- export declare function importThemesFromFile(file: any): Promise<void>;
44
- /**
45
- * Import themes from separate files
46
- */
47
- export declare function importThemesFromFiles(): Promise<void>;
48
- /**
49
- * Import first theme from file
50
- * @param {String} file import file name
51
- */
52
- export declare function importFirstThemeFromFile(file: any): Promise<void>;
39
+ export declare function putThemes(themeMap: Map<string, ThemeSkeleton>): Promise<Map<string, ThemeSkeleton>>;
53
40
  /**
54
41
  * Delete theme by id
55
- * @param {String} id theme id
42
+ * @param {string} themeId theme id
43
+ * @returns {Promise<ThemeSkeleton>} a promise that resolves to a themes object
56
44
  */
57
- export declare function deleteThemeCmd(id: any): Promise<void>;
45
+ export declare function deleteTheme(themeId: string): Promise<ThemeSkeleton>;
58
46
  /**
59
47
  * Delete theme by name
60
- * @param {String} name theme name
61
- */
62
- export declare function deleteThemeByNameCmd(name: any): Promise<void>;
63
- /**
64
- * Delete all themes
48
+ * @param {string} themeName theme name
49
+ * @returns {Promise<ThemeSkeleton>} a promise that resolves to a themes object
65
50
  */
66
- export declare function deleteThemes(): Promise<void>;
51
+ export declare function deleteThemeByName(themeName: string): Promise<ThemeSkeleton>;
67
52
  /**
68
53
  * Delete all themes
69
- * @deprecated since version 0.14.0
54
+ * @returns {Promise<ThemeSkeleton[]>} a promise that resolves to an array of themes
70
55
  */
71
- export declare function deleteThemesCmd(): Promise<void>;
56
+ export declare function deleteThemes(): Promise<ThemeSkeleton[]>;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/ThemeOps.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,UAAQ,iBAyB5C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAejD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA,iBAe7C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,KAAA,iBAc5C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,kBASxC;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,iBAmCjD;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,KAAA,EAAE,IAAI,KAAA,iBAqC7C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,KAAA,iBAqC9C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,kBAgC1C;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,KAAA,iBA+BlD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,EAAE,KAAA,iBAQtC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,KAAA,iBAQ9C;AAED;;GAEG;AACH,wBAAsB,YAAY,kBAYjC;AAED;;;GAGG;AACH,wBAAsB,eAAe,kBAEpC","file":"ThemeOps.d.ts","sourcesContent":["import fs from 'fs';\nimport {\n deleteTheme,\n deleteThemeByName,\n deleteThemes as _deleteThemes,\n getTheme,\n getThemeByName,\n getThemes,\n putTheme,\n putThemeByName,\n putThemes,\n} from '../api/ThemeApi';\nimport {\n createProgressIndicator,\n createTable,\n printMessage,\n stopProgressIndicator,\n updateProgressIndicator,\n} from './utils/Console';\nimport {\n getRealmString,\n getTypedFilename,\n saveToFile,\n validateImport,\n} from './utils/ExportImportUtils';\n\n/**\n * List all the themes\n * @param {boolean} long Long version, more fields\n */\nexport async function listThemes(long = false) {\n const themeList = await getThemes();\n themeList.sort((a, b) => a.name.localeCompare(b.name));\n if (!long) {\n themeList.forEach((theme) => {\n printMessage(\n `${theme.isDefault ? theme.name['brightCyan'] : theme.name}`,\n 'data'\n );\n });\n } else {\n const table = createTable([\n 'Name'['brightCyan'],\n 'Id'['brightCyan'],\n 'Default'['brightCyan'],\n ]);\n themeList.forEach((theme) => {\n table.push([\n `${theme.name}`,\n `${theme._id}`,\n `${theme.isDefault ? 'Yes'['brightGreen'] : ''}`,\n ]);\n });\n printMessage(table.toString(), 'data');\n }\n}\n\n/**\n * Export theme by name to file\n * @param {String} name theme name\n * @param {String} file optional export file name\n */\nexport async function exportThemeByName(name, file) {\n let fileName = getTypedFilename(name, 'theme');\n if (file) {\n fileName = file;\n }\n createProgressIndicator(1, `Exporting ${name}`);\n try {\n const themeData = await getThemeByName(name);\n updateProgressIndicator(`Writing file ${fileName}`);\n saveToFile('theme', [themeData], '_id', fileName);\n stopProgressIndicator(`Successfully exported theme ${name}.`);\n } catch (error) {\n stopProgressIndicator(`${error.message}`);\n printMessage(`${error.message}`, 'error');\n }\n}\n\n/**\n * Export theme by uuid to file\n * @param {String} id theme uuid\n * @param {String} file optional export file name\n */\nexport async function exportThemeById(id, file) {\n let fileName = getTypedFilename(id, 'theme');\n if (file) {\n fileName = file;\n }\n createProgressIndicator(1, `Exporting ${id}`);\n try {\n const themeData = await getTheme(id);\n updateProgressIndicator(`Writing file ${fileName}`);\n saveToFile('theme', [themeData], '_id', fileName);\n stopProgressIndicator(`Successfully exported theme ${id}.`);\n } catch (error) {\n stopProgressIndicator(`${error.message}`);\n printMessage(`${error.message}`, 'error');\n }\n}\n\n/**\n * Export all themes to file\n * @param {String} file optional export file name\n */\nexport async function exportThemesToFile(file) {\n let fileName = getTypedFilename(`all${getRealmString()}Themes`, 'theme');\n if (file) {\n fileName = file;\n }\n const allThemesData = await getThemes();\n createProgressIndicator(allThemesData.length, 'Exporting themes');\n for (const themeData of allThemesData) {\n updateProgressIndicator(`Exporting theme ${themeData.name}`);\n }\n saveToFile('theme', allThemesData, '_id', fileName);\n stopProgressIndicator(\n `${allThemesData.length} themes exported to ${fileName}.`\n );\n}\n\n/**\n * Export all themes to separate files\n */\nexport async function exportThemesToFiles() {\n const allThemesData = await getThemes();\n createProgressIndicator(allThemesData.length, 'Exporting themes');\n for (const themeData of allThemesData) {\n updateProgressIndicator(`Writing theme ${themeData.name}`);\n const fileName = getTypedFilename(themeData.name, 'theme');\n saveToFile('theme', themeData, '_id', fileName);\n }\n stopProgressIndicator(`${allThemesData.length} themes exported.`);\n}\n\n/**\n * Import theme by name from file\n * @param {String} name theme name\n * @param {String} file import file name\n */\nexport async function importThemeByName(name, file) {\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n let found = false;\n for (const id in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, id)) {\n if (themeData.theme[id].name === name) {\n found = true;\n updateProgressIndicator(`Importing ${themeData.theme[id].name}`);\n try {\n await putThemeByName(name, themeData.theme[id]);\n stopProgressIndicator(`Successfully imported theme ${name}.`);\n } catch (error) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[id].name}: ${error.message}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[id].name}: ${error.message}`,\n 'error'\n );\n }\n break;\n }\n }\n }\n if (!found) {\n stopProgressIndicator(`Theme ${name} not found!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import theme by uuid from file\n * @param {String} id theme uuid\n * @param {String} file import file name\n */\nexport async function importThemeById(id, file) {\n fs.readFile(file, 'utf8', async (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n let found = false;\n for (const themeId in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, themeId)) {\n if (themeId === id) {\n found = true;\n updateProgressIndicator(\n `Importing ${themeData.theme[themeId]._id}`\n );\n try {\n await putTheme(themeId, themeData.theme[themeId]);\n stopProgressIndicator(`Successfully imported theme ${id}.`);\n } catch (error) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[themeId]._id}: ${error.message}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[themeId]._id}: ${error.message}`,\n 'error'\n );\n }\n break;\n }\n }\n }\n if (!found) {\n stopProgressIndicator(`Theme ${id} not found!`);\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import all themes from single file\n * @param {String} file import file name\n */\nexport async function importThemesFromFile(file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n createProgressIndicator(\n Object.keys(fileData.theme).length,\n 'Importing themes...'\n );\n for (const id in fileData.theme) {\n if ({}.hasOwnProperty.call(fileData.theme, id)) {\n updateProgressIndicator(`Importing ${fileData.theme[id].name}`);\n }\n }\n putThemes(fileData.theme).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing ${Object.keys(fileData.theme).length} themes!`\n );\n printMessage(\n `Error importing ${\n Object.keys(fileData.theme).length\n } themes from ${file}`,\n 'error'\n );\n } else {\n stopProgressIndicator(\n `Successfully imported ${\n Object.keys(fileData.theme).length\n } themes.`\n );\n }\n });\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Import themes from separate files\n */\nexport async function importThemesFromFiles() {\n const names = fs.readdirSync('.');\n const jsonFiles = names.filter((name) =>\n name.toLowerCase().endsWith('.theme.json')\n );\n\n createProgressIndicator(jsonFiles.length, 'Importing themes...');\n let fileData = null;\n let count = 0;\n let total = 0;\n let files = 0;\n for (const file of jsonFiles) {\n const data = fs.readFileSync(file, 'utf8');\n fileData = JSON.parse(data);\n if (validateImport(fileData.meta)) {\n count = Object.keys(fileData.theme).length;\n // eslint-disable-next-line no-await-in-loop\n const result = await putThemes(fileData.theme);\n if (result == null) {\n printMessage(`Error importing ${count} themes from ${file}`, 'error');\n } else {\n files += 1;\n total += count;\n updateProgressIndicator(`Imported ${count} theme(s) from ${file}`);\n }\n } else {\n printMessage(`Validation of ${file} failed!`, 'error');\n }\n }\n stopProgressIndicator(\n `Finished importing ${total} theme(s) from ${files} file(s).`\n );\n}\n\n/**\n * Import first theme from file\n * @param {String} file import file name\n */\nexport async function importFirstThemeFromFile(file) {\n fs.readFile(file, 'utf8', (err, data) => {\n if (err) throw err;\n const themeData = JSON.parse(data);\n if (validateImport(themeData.meta)) {\n createProgressIndicator(1, 'Importing theme...');\n for (const id in themeData.theme) {\n if ({}.hasOwnProperty.call(themeData.theme, id)) {\n updateProgressIndicator(`Importing ${themeData.theme[id].name}`);\n putTheme(id, themeData.theme[id]).then((result) => {\n if (result == null) {\n stopProgressIndicator(\n `Error importing theme ${themeData.theme[id].name}`\n );\n printMessage(\n `Error importing theme ${themeData.theme[id].name}`,\n 'error'\n );\n } else {\n stopProgressIndicator(\n `Successfully imported theme ${themeData.theme[id].name}`\n );\n }\n });\n break;\n }\n }\n } else {\n printMessage('Import validation failed...', 'error');\n }\n });\n}\n\n/**\n * Delete theme by id\n * @param {String} id theme id\n */\nexport async function deleteThemeCmd(id) {\n createProgressIndicator(undefined, `Deleting ${id}...`, 'indeterminate');\n try {\n await deleteTheme(id);\n stopProgressIndicator(`Deleted ${id}.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete theme by name\n * @param {String} name theme name\n */\nexport async function deleteThemeByNameCmd(name) {\n createProgressIndicator(undefined, `Deleting ${name}...`, 'indeterminate');\n try {\n await deleteThemeByName(name);\n stopProgressIndicator(`Deleted ${name}.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete all themes\n */\nexport async function deleteThemes() {\n createProgressIndicator(\n undefined,\n `Deleting all realm themes...`,\n 'indeterminate'\n );\n try {\n await _deleteThemes();\n stopProgressIndicator(`Deleted all realm themes.`, 'success');\n } catch (error) {\n stopProgressIndicator(`Error: ${error.message}`, 'fail');\n }\n}\n\n/**\n * Delete all themes\n * @deprecated since version 0.14.0\n */\nexport async function deleteThemesCmd() {\n return deleteThemes();\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/ThemeOps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAsB,MAAM,iBAAiB,CAAC;AAKpE,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAc7C;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAG1D;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAUtE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CAYxB;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CA8CrC;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAyBzE;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CA0BxB;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAc7D","file":"ThemeOps.d.ts","sourcesContent":["import { ThemeSkeleton, UiThemeRealmObject } from '../api/ApiTypes';\nimport { getConfigEntity, putConfigEntity } from '../api/IdmConfigApi';\nimport { getCurrentRealmName } from '../api/utils/ApiUtils';\nimport { debugMessage } from '../ops/utils/Console';\n\nexport const THEMEREALM_ID = 'ui/themerealm';\n\n/**\n * Get realm themes\n * @param {UiThemeRealmObject} themes object containing themes\n * @returns {ThemeSkeleton[]} array of theme pertaining to the current realm\n */\nfunction getRealmThemes(themes: UiThemeRealmObject): ThemeSkeleton[] {\n if (themes.realm && themes.realm[getCurrentRealmName()]) {\n return themes.realm[getCurrentRealmName()];\n }\n return [];\n}\n\n/**\n * Get all themes\n * @returns {Promise<ThemeSkeleton[]>} a promise that resolves to an array of themes\n */\nexport async function getThemes(): Promise<ThemeSkeleton[]> {\n const themes = await getConfigEntity(THEMEREALM_ID);\n return getRealmThemes(themes);\n}\n\n/**\n * Get theme by id\n * @param {string} themeId theme id\n * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object\n */\nexport async function getTheme(themeId: string): Promise<ThemeSkeleton> {\n const themes = await getConfigEntity(THEMEREALM_ID);\n const found = getRealmThemes(themes).filter((theme) => theme._id === themeId);\n if (found.length === 1) {\n return found[0];\n }\n if (found.length > 1) {\n throw new Error(`Multiple themes with id \"${themeId}\" found!`);\n }\n throw new Error(`Theme with id \"${themeId}\" not found!`);\n}\n\n/**\n * Get theme by name\n * @param {string} themeName theme name\n * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object\n */\nexport async function getThemeByName(\n themeName: string\n): Promise<ThemeSkeleton> {\n const themes = await getConfigEntity(THEMEREALM_ID);\n const found = getRealmThemes(themes).filter(\n (theme) => theme.name === themeName\n );\n if (found.length === 1) {\n return found[0];\n }\n if (found.length > 1) {\n throw new Error(`Multiple themes with the name \"${themeName}\" found!`);\n }\n throw new Error(`Theme \"${themeName}\" not found!`);\n}\n\n/**\n * Put theme by id\n * @param {string} themeId theme id\n * @param {ThemeSkeleton} themeData theme object\n * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object\n */\nexport async function putTheme(\n themeId: string,\n themeData: ThemeSkeleton\n): Promise<ThemeSkeleton> {\n const data = themeData;\n data._id = themeId;\n const themes = await getConfigEntity(THEMEREALM_ID);\n let isNew = true;\n const realmThemes = getRealmThemes(themes).map((theme) => {\n if (theme._id === themeId) {\n isNew = false;\n return data;\n }\n // eslint-disable-next-line no-param-reassign\n if (data.isDefault) theme.isDefault = false;\n return theme;\n });\n if (isNew) {\n realmThemes.push(data);\n }\n themes.realm[getCurrentRealmName()] = realmThemes;\n const found = getRealmThemes(\n await putConfigEntity(THEMEREALM_ID, themes)\n ).filter((theme) => theme._id === themeId);\n if (found.length === 1) {\n return found[0];\n }\n if (found.length > 1) {\n throw new Error(`Multiple themes with id \"${themeId}\" found!`);\n }\n throw new Error(`Theme with id \"${themeId}\" not saved!`);\n}\n\n/**\n * Put theme by name\n * @param {String} themeName theme name\n * @param {ThemeSkeleton} themeData theme object\n * @returns {Promise<ThemeSkeleton>} a promise that resolves to a theme object\n */\nexport async function putThemeByName(\n themeName: string,\n themeData: ThemeSkeleton\n): Promise<ThemeSkeleton> {\n const data = themeData;\n data.name = themeName;\n const themes = await getConfigEntity(THEMEREALM_ID);\n let isNew = true;\n const realmThemes = getRealmThemes(themes).map((theme) => {\n if (theme.name === themeName) {\n isNew = false;\n return data;\n }\n // eslint-disable-next-line no-param-reassign\n if (data.isDefault) theme.isDefault = false;\n return theme;\n });\n if (isNew) {\n realmThemes.push(data);\n }\n themes['realm'][getCurrentRealmName()] = realmThemes;\n const found = getRealmThemes(\n await putConfigEntity(THEMEREALM_ID, themes)\n ).filter((theme) => theme.name === themeName);\n if (found.length === 1) {\n return found[0];\n }\n if (found.length > 1) {\n throw new Error(`Multiple themes \"${themeName}\" found!`);\n }\n throw new Error(`Theme \"${themeName}\" not saved!`);\n}\n\n/**\n * Put all themes\n * @param {Map<string, ThemeSkeleton>} allThemesData themes object containing all themes for all realms\n * @returns {Promise<Map<string, ThemeSkeleton>>} a promise that resolves to a themes object\n */\nexport async function putThemes(\n themeMap: Map<string, ThemeSkeleton>\n): Promise<Map<string, ThemeSkeleton>> {\n debugMessage(`ThemeApi.putThemes: start`);\n const themes = await getConfigEntity(THEMEREALM_ID);\n const allThemeIDs = Object.keys(themeMap);\n const existingThemeIDs = [];\n let defaultThemeId = null;\n // update existing themes\n let realmThemes = getRealmThemes(themes).map((theme) => {\n if (themeMap[theme._id]) {\n debugMessage(`Update theme: ${theme._id} - ${theme.name}`);\n existingThemeIDs.push(theme._id);\n // remember the id of the last default theme\n if (themeMap[theme._id].isDefault) defaultThemeId = theme._id;\n return themeMap[theme._id];\n }\n return theme;\n });\n const newThemeIDs = allThemeIDs.filter(\n (id) => !existingThemeIDs.includes(id)\n );\n // add new themes\n newThemeIDs.forEach((themeId) => {\n debugMessage(\n `Add theme: ${themeMap[themeId]._id} - ${themeMap[themeId].name}`\n );\n // remember the id of the last default theme\n if (themeMap[themeId].isDefault) defaultThemeId = themeId;\n realmThemes.push(themeMap[themeId]);\n });\n // if we imported a default theme, flag all the other themes as not default\n if (defaultThemeId) {\n realmThemes = realmThemes.map((theme) => {\n // eslint-disable-next-line no-param-reassign\n theme.isDefault = theme._id === defaultThemeId;\n return theme;\n });\n }\n themes.realm[getCurrentRealmName()] = realmThemes;\n const updatedThemes = new Map(\n getRealmThemes(await putConfigEntity(THEMEREALM_ID, themes)).map(\n (theme) => [theme._id, theme]\n )\n );\n debugMessage(updatedThemes);\n debugMessage(`ThemeApi.putThemes: finished`);\n return updatedThemes;\n}\n\n/**\n * Delete theme by id\n * @param {string} themeId theme id\n * @returns {Promise<ThemeSkeleton>} a promise that resolves to a themes object\n */\nexport async function deleteTheme(themeId: string): Promise<ThemeSkeleton> {\n const themes = await getConfigEntity(THEMEREALM_ID);\n const realmThemes = getRealmThemes(themes);\n const deletedThemes: ThemeSkeleton[] = [];\n const finalThemes = realmThemes.filter((theme) => {\n if (theme._id !== themeId) {\n return true;\n }\n deletedThemes.push(theme);\n return false;\n });\n if (realmThemes.length === finalThemes.length)\n throw new Error(`${themeId} not found`);\n themes.realm[getCurrentRealmName()] = realmThemes;\n const undeletedThemes = getRealmThemes(\n await putConfigEntity(THEMEREALM_ID, themes)\n ).filter((theme) => deletedThemes.includes(theme));\n if (deletedThemes.length > 0 && undeletedThemes.length === 0) {\n return deletedThemes[0];\n }\n throw new Error(\n `Theme(s) with id(s) \"${undeletedThemes.map(\n (theme) => theme._id\n )}\" not deleted!`\n );\n}\n\n/**\n * Delete theme by name\n * @param {string} themeName theme name\n * @returns {Promise<ThemeSkeleton>} a promise that resolves to a themes object\n */\nexport async function deleteThemeByName(\n themeName: string\n): Promise<ThemeSkeleton> {\n const themes = await getConfigEntity(THEMEREALM_ID);\n const realmThemes = getRealmThemes(themes);\n const deletedThemes: ThemeSkeleton[] = [];\n const finalThemes = realmThemes.filter((theme) => {\n if (theme.name !== themeName) {\n return true;\n }\n deletedThemes.push(theme);\n return false;\n });\n if (realmThemes.length === finalThemes.length)\n throw new Error(`${themeName} not found`);\n themes.realm[getCurrentRealmName()] = finalThemes;\n // return putConfigEntity(THEMEREALM_ID, themes);\n const undeletedThemes = getRealmThemes(\n await putConfigEntity(THEMEREALM_ID, themes)\n ).filter((theme) => deletedThemes.includes(theme));\n if (deletedThemes.length > 0 && undeletedThemes.length === 0) {\n return deletedThemes[0];\n }\n throw new Error(\n `Theme(s) with id(s) \"${undeletedThemes.map(\n (theme) => theme._id\n )}\" not deleted!`\n );\n}\n\n/**\n * Delete all themes\n * @returns {Promise<ThemeSkeleton[]>} a promise that resolves to an array of themes\n */\nexport async function deleteThemes(): Promise<ThemeSkeleton[]> {\n const themes = await getConfigEntity(THEMEREALM_ID);\n const realmThemes = themes.realm[getCurrentRealmName()];\n if (!realmThemes)\n throw new Error(\n `No theme configuration found for realm \"${getCurrentRealmName()}\"`\n );\n const deletedThemes: ThemeSkeleton[] = [];\n for (const theme of realmThemes) {\n deletedThemes.push(theme);\n }\n themes.realm[getCurrentRealmName()] = [];\n await putConfigEntity(THEMEREALM_ID, themes);\n return deletedThemes;\n}\n"]}
@@ -11,7 +11,7 @@ import Table from 'cli-table3';
11
11
  * @param {boolean} [newline=true] Whether to add a newline at the end of message
12
12
  * messages returned
13
13
  */
14
- export declare function printMessage(message: string | unknown, type?: string, newline?: boolean): void;
14
+ export declare function printMessage(message: string | object, type?: string, newline?: boolean): void;
15
15
  /**
16
16
  * Handles verbose output. The caller decides and implements how
17
17
  * the messages are handled, by implementing the handler function
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/utils/Console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,GAAG,OAAO,EACzB,IAAI,SAAS,EACb,OAAO,UAAO,QAMf;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,QAKtD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,QAKpD;AAcD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,QAK/C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,KAAA,EACL,OAAO,GAAE,MAAa,EACtB,IAAI,SAAgB,QAMrB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,MAAa,QAK7D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,MAAa,EAAE,MAAM,SAAS,QAK5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,KAAA,eAqB/B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,gBAqBlC;AA+ED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,KAAA,EAAE,MAAM,KAAK,eA2BpD","file":"Console.d.ts","sourcesContent":["import Table from 'cli-table3';\nimport storage from '../../storage/SessionStorage';\n\n/**\n * Handles data / messages output. The caller decides and implements how\n * the data and messages are handled, by implementing the handler function\n * on its side. `handler` is optional, and if not included by the caller,\n * the data and messages will be lost.\n *\n * @param {string | unknown} message The string message to return\n * @param {string} [type=text] \"text\", \"info\", \"warn\", \"error\" or \"data\". All but\n * type=\"data\" will be written to stderr.\n * @param {boolean} [newline=true] Whether to add a newline at the end of message\n * messages returned\n */\nexport function printMessage(\n message: string | unknown,\n type = 'text',\n newline = true\n) {\n const handler = storage.session.getPrintHandler();\n if (handler) {\n handler(message, type, newline);\n }\n}\n\n/**\n * Handles verbose output. The caller decides and implements how\n * the messages are handled, by implementing the handler function\n * on its side. Implementing and registering a `handler` is optional.\n *\n * @param {string | unknown} message The verbose output message\n */\nexport function verboseMessage(message: string | object) {\n const handler = storage.session.getVerboseHandler();\n if (handler) {\n handler(message);\n }\n}\n\n/**\n * Handles debug output. The caller decides and implements how\n * the messages are handled, by implementing the handler function\n * on its side. Implementing and registering a `handler` is optional.\n *\n * @param {string | object} message The debug output message\n */\nexport function debugMessage(message: string | object) {\n const handler = storage.session.getDebugHandler();\n if (handler) {\n handler(message);\n }\n}\n\n/**\n * Helper function to mask password header in curl command\n * @param curlCommand curl command to mask\n * @returns masked curl command\n */\nfunction maskPasswordHeader(curlCommand: string) {\n const header = 'X-OpenAM-Password:';\n const mask = '<suppressed>';\n const regex = new RegExp('\"' + header + '.+?\"', 'g');\n return curlCommand.replace(regex, '\"' + header + mask + '\"');\n}\n\n/**\n * Handles curlirize output. The caller decides and implements how\n * the messages are handled, by implementing the handler function\n * on its side. Implementing and registering a `handler` is optional.\n *\n * @param {string} message The curlirize output message\n */\nexport function curlirizeMessage(message: string) {\n const handler = storage.session.getCurlirizeHandler();\n if (handler) {\n handler(maskPasswordHeader(message));\n }\n}\n\n/**\n * Calls a callback on client to create a progress indicator.\n * The actual implementation of the indicator is left to the client\n * Two types of indicators are supported:\n * - determinate: should be used when the process completion rate\n * can be detected (example: progress bar showing percentage or count)\n * - indeterminate: used when progress isn’t detectable, or if\n * it’s not necessary to indicate how long an activity will take.\n * (example: spinner showing progress, but not quantifying the progress)\n *\n * Example:\n * [========================================] 100% | 49/49 | Analyzing journey - transactional_auth\n *\n * @param {Number} total The total number of entries to track progress for\n * @param {String} message optional progress bar message\n * @param {String} type optional type of progress indicator. default is 'determinate'\n *\n */\nexport function createProgressIndicator(\n total,\n message: string = null,\n type = 'determinate'\n) {\n const handler = storage.session.getCreateProgressHandler();\n if (handler) {\n handler(type, total, message);\n }\n}\n\n/**\n * Updates the progress indicator with new data/updated status.\n * @param {string} message optional message to show with the indicator\n *\n */\nexport function updateProgressIndicator(message: string = null) {\n const handler = storage.session.getUpdateProgressHandler();\n if (handler) {\n handler(message);\n }\n}\n\n/**\n * Stop and hide the progress indicator\n * @param {string} message optional message to show with the indicator\n * @param {string} status one of 'none', 'success', 'warn', 'fail'\n */\nexport function stopProgressIndicator(message: string = null, status = 'none') {\n const handler = storage.session.getStopProgressHandler();\n if (handler) {\n handler(message, status);\n }\n}\n\n/**\n * Create an empty table\n * @param {[String]} head header row as an array of strings\n * @returns {CliTable3} an empty table\n */\nexport function createTable(head) {\n return new Table({\n head,\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n },\n style: { 'padding-left': 0, 'padding-right': 0, head: ['brightCyan'] },\n });\n}\n\n/**\n * Create a new key/value table\n * @returns {CliTable3} an empty key/value table\n */\nexport function createKeyValueTable() {\n return new Table({\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n },\n style: { 'padding-left': 0, 'padding-right': 0 },\n wordWrap: true,\n });\n}\n\n/**\n * Helper function to determine the total depth of an object\n * @param {Object} object input object\n * @returns {Number} total depth of the input object\n */\nfunction getObjectDepth(object) {\n return Object(object) === object\n ? 1 + Math.max(-1, ...Object.values(object).map(getObjectDepth))\n : 0;\n}\n\n/**\n * Helper function to determine if an object has values\n * @param {Object} object input object\n * @returns {boolean} true of the object or any of its sub-objects contain values, false otherwise\n */\nfunction hasValues(object) {\n let has = false;\n const keys = Object.keys(object);\n for (const key of keys) {\n if (Object(object[key]) !== object[key]) {\n return true;\n }\n has = has || hasValues(object[key]);\n }\n return has;\n}\n\n/**\n * Helper function (recursive) to add rows to an object table\n * @param {Object} object object to render\n * @param {Number} depth total depth of initial object\n * @param {Number} level current level\n * @param {CliTable3} table the object table to add the rows to\n * @returns the updated object table\n */\nfunction addRows(object, depth, level, table, keyMap) {\n const space = ' ';\n const keys = Object.keys(object);\n for (const key of keys) {\n if (Object(object[key]) !== object[key]) {\n if (level === 1) {\n table.push([\n keyMap[key] ? keyMap[key]['brightCyan'] : key['brightCyan'],\n object[key],\n ]);\n } else {\n table.push([\n {\n hAlign: 'right',\n content: keyMap[key] ? keyMap[key]['gray'] : key['gray'],\n },\n object[key],\n ]);\n }\n }\n }\n for (const key of keys) {\n if (Object(object[key]) === object[key]) {\n // only print header if there are any values below\n if (hasValues(object[key])) {\n let indention = new Array(level).fill(space).join('');\n if (level < 3) indention = `\\n${indention}`;\n table.push([\n indention.concat(\n keyMap[key] ? keyMap[key]['brightCyan'] : key['brightCyan']\n ),\n '',\n ]);\n }\n // eslint-disable-next-line no-param-reassign\n table = addRows(object[key], depth, level + 1, table, keyMap);\n }\n }\n return table;\n}\n\n/**\n * Create and populate an object table from any JSON object. Use for describe commands.\n * @param {Object} object JSON object to create\n * @returns {CliTable3} a table that can be printed to the console\n */\nexport function createObjectTable(object, keyMap = {}) {\n // eslint-disable-next-line no-param-reassign\n const depth = getObjectDepth(object);\n // eslint-disable-next-line no-param-reassign\n const level = 0;\n // eslint-disable-next-line no-param-reassign\n const table = new Table({\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n },\n style: { 'padding-left': 0, 'padding-right': 0, head: ['brightCyan'] },\n });\n addRows(object, depth, level + 1, table, keyMap);\n return table;\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/utils/Console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,IAAI,SAAS,EACb,OAAO,UAAO,QAMf;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,QAKtD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,QAKpD;AAcD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,QAK/C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,KAAA,EACL,OAAO,GAAE,MAAa,EACtB,IAAI,SAAgB,QAMrB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,MAAa,QAK7D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,MAAa,EAAE,MAAM,SAAS,QAK5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,KAAA,eAqB/B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,gBAqBlC;AA+ED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,KAAA,EAAE,MAAM,KAAK,eA2BpD","file":"Console.d.ts","sourcesContent":["import Table from 'cli-table3';\nimport * as state from '../../shared/State';\n\n/**\n * Handles data / messages output. The caller decides and implements how\n * the data and messages are handled, by implementing the handler function\n * on its side. `handler` is optional, and if not included by the caller,\n * the data and messages will be lost.\n *\n * @param {string | unknown} message The string message to return\n * @param {string} [type=text] \"text\", \"info\", \"warn\", \"error\" or \"data\". All but\n * type=\"data\" will be written to stderr.\n * @param {boolean} [newline=true] Whether to add a newline at the end of message\n * messages returned\n */\nexport function printMessage(\n message: string | object,\n type = 'text',\n newline = true\n) {\n const handler = state.getPrintHandler();\n if (handler) {\n handler(message, type, newline);\n }\n}\n\n/**\n * Handles verbose output. The caller decides and implements how\n * the messages are handled, by implementing the handler function\n * on its side. Implementing and registering a `handler` is optional.\n *\n * @param {string | unknown} message The verbose output message\n */\nexport function verboseMessage(message: string | object) {\n const handler = state.getVerboseHandler();\n if (handler) {\n handler(message);\n }\n}\n\n/**\n * Handles debug output. The caller decides and implements how\n * the messages are handled, by implementing the handler function\n * on its side. Implementing and registering a `handler` is optional.\n *\n * @param {string | object} message The debug output message\n */\nexport function debugMessage(message: string | object) {\n const handler = state.getDebugHandler();\n if (handler) {\n handler(message);\n }\n}\n\n/**\n * Helper function to mask password header in curl command\n * @param curlCommand curl command to mask\n * @returns masked curl command\n */\nfunction maskPasswordHeader(curlCommand: string) {\n const header = 'X-OpenAM-Password:';\n const mask = '<suppressed>';\n const regex = new RegExp('\"' + header + '.+?\"', 'g');\n return curlCommand.replace(regex, '\"' + header + mask + '\"');\n}\n\n/**\n * Handles curlirize output. The caller decides and implements how\n * the messages are handled, by implementing the handler function\n * on its side. Implementing and registering a `handler` is optional.\n *\n * @param {string} message The curlirize output message\n */\nexport function curlirizeMessage(message: string) {\n const handler = state.getCurlirizeHandler();\n if (handler) {\n handler(maskPasswordHeader(message));\n }\n}\n\n/**\n * Calls a callback on client to create a progress indicator.\n * The actual implementation of the indicator is left to the client\n * Two types of indicators are supported:\n * - determinate: should be used when the process completion rate\n * can be detected (example: progress bar showing percentage or count)\n * - indeterminate: used when progress isn’t detectable, or if\n * it’s not necessary to indicate how long an activity will take.\n * (example: spinner showing progress, but not quantifying the progress)\n *\n * Example:\n * [========================================] 100% | 49/49 | Analyzing journey - transactional_auth\n *\n * @param {Number} total The total number of entries to track progress for\n * @param {String} message optional progress bar message\n * @param {String} type optional type of progress indicator. default is 'determinate'\n *\n */\nexport function createProgressIndicator(\n total,\n message: string = null,\n type = 'determinate'\n) {\n const handler = state.getCreateProgressHandler();\n if (handler) {\n handler(type, total, message);\n }\n}\n\n/**\n * Updates the progress indicator with new data/updated status.\n * @param {string} message optional message to show with the indicator\n *\n */\nexport function updateProgressIndicator(message: string = null) {\n const handler = state.getUpdateProgressHandler();\n if (handler) {\n handler(message);\n }\n}\n\n/**\n * Stop and hide the progress indicator\n * @param {string} message optional message to show with the indicator\n * @param {string} status one of 'none', 'success', 'warn', 'fail'\n */\nexport function stopProgressIndicator(message: string = null, status = 'none') {\n const handler = state.getStopProgressHandler();\n if (handler) {\n handler(message, status);\n }\n}\n\n/**\n * Create an empty table\n * @param {[String]} head header row as an array of strings\n * @returns {CliTable3} an empty table\n */\nexport function createTable(head) {\n return new Table({\n head,\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n },\n style: { 'padding-left': 0, 'padding-right': 0, head: ['brightCyan'] },\n });\n}\n\n/**\n * Create a new key/value table\n * @returns {CliTable3} an empty key/value table\n */\nexport function createKeyValueTable() {\n return new Table({\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n },\n style: { 'padding-left': 0, 'padding-right': 0 },\n wordWrap: true,\n });\n}\n\n/**\n * Helper function to determine the total depth of an object\n * @param {Object} object input object\n * @returns {Number} total depth of the input object\n */\nfunction getObjectDepth(object) {\n return Object(object) === object\n ? 1 + Math.max(-1, ...Object.values(object).map(getObjectDepth))\n : 0;\n}\n\n/**\n * Helper function to determine if an object has values\n * @param {Object} object input object\n * @returns {boolean} true of the object or any of its sub-objects contain values, false otherwise\n */\nfunction hasValues(object) {\n let has = false;\n const keys = Object.keys(object);\n for (const key of keys) {\n if (Object(object[key]) !== object[key]) {\n return true;\n }\n has = has || hasValues(object[key]);\n }\n return has;\n}\n\n/**\n * Helper function (recursive) to add rows to an object table\n * @param {Object} object object to render\n * @param {Number} depth total depth of initial object\n * @param {Number} level current level\n * @param {CliTable3} table the object table to add the rows to\n * @returns the updated object table\n */\nfunction addRows(object, depth, level, table, keyMap) {\n const space = ' ';\n const keys = Object.keys(object);\n for (const key of keys) {\n if (Object(object[key]) !== object[key]) {\n if (level === 1) {\n table.push([\n keyMap[key] ? keyMap[key]['brightCyan'] : key['brightCyan'],\n object[key],\n ]);\n } else {\n table.push([\n {\n hAlign: 'right',\n content: keyMap[key] ? keyMap[key]['gray'] : key['gray'],\n },\n object[key],\n ]);\n }\n }\n }\n for (const key of keys) {\n if (Object(object[key]) === object[key]) {\n // only print header if there are any values below\n if (hasValues(object[key])) {\n let indention = new Array(level).fill(space).join('');\n if (level < 3) indention = `\\n${indention}`;\n table.push([\n indention.concat(\n keyMap[key] ? keyMap[key]['brightCyan'] : key['brightCyan']\n ),\n '',\n ]);\n }\n // eslint-disable-next-line no-param-reassign\n table = addRows(object[key], depth, level + 1, table, keyMap);\n }\n }\n return table;\n}\n\n/**\n * Create and populate an object table from any JSON object. Use for describe commands.\n * @param {Object} object JSON object to create\n * @returns {CliTable3} a table that can be printed to the console\n */\nexport function createObjectTable(object, keyMap = {}) {\n // eslint-disable-next-line no-param-reassign\n const depth = getObjectDepth(object);\n // eslint-disable-next-line no-param-reassign\n const level = 0;\n // eslint-disable-next-line no-param-reassign\n const table = new Table({\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n },\n style: { 'padding-left': 0, 'padding-right': 0, head: ['brightCyan'] },\n });\n addRows(object, depth, level + 1, table, keyMap);\n return table;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/utils/DataProtection.ts"],"names":[],"mappings":"AA8BA,cAAM,cAAc;;IAgDZ,OAAO,CAAC,IAAI,KAAA;IAQZ,OAAO,CAAC,IAAI,KAAA;CAenB;AACD,eAAe,cAAc,CAAC","file":"DataProtection.d.ts","sourcesContent":["/**\n * Data is stored in base64 format. Initially it was binary data\n * Format used in this encryption module.\n * inspired by AndiDittrich\n * +--------------------+-----------------------+----------------+----------------+\n * | SALT | Initialization Vector | Auth Tag | Payload |\n * | Used to derive key | AES GCM XOR Init | Data Integrity | Encrypted Data |\n * | 64 Bytes, random | 16 Bytes, random | 16 Bytes | (N-96) Bytes |\n * +--------------------+-----------------------+----------------+----------------+\n * This module doesn't take care of data persistence, it's assumed the consuming method/class/package will do so.\n */\nimport fs, { promises as fsp } from 'fs';\nimport crypto from 'crypto';\nimport { homedir } from 'os';\nimport { promisify } from 'util';\nimport { printMessage } from './Console';\nimport storage from '../../storage/SessionStorage';\nimport {\n FRODO_MASTER_KEY_PATH_KEY,\n FRODO_MASTER_KEY_KEY,\n} from '../../storage/StaticStorage';\n\nconst scrypt = promisify(crypto.scrypt);\n// using WeakMaps for added security since it gets garbage collected\nconst _masterKey = new WeakMap();\nconst _nonce = new WeakMap();\nconst _salt = new WeakMap();\nconst _key = new WeakMap();\nconst _encrypt = new WeakMap();\n\nclass DataProtection {\n constructor() {\n const masterKeyPath = () =>\n storage.session.getMasterKeyPath() ||\n process.env[FRODO_MASTER_KEY_PATH_KEY] ||\n `${homedir()}/.frodo/masterkey.key`;\n // Generates a master key in base64 format. This master key will be used to derive the key for encryption. this key should be protected by an HSM or KMS\n _masterKey.set(this, async () => {\n try {\n if (process.env[FRODO_MASTER_KEY_KEY])\n return process.env[FRODO_MASTER_KEY_KEY];\n if (!fs.existsSync(masterKeyPath())) {\n const masterKey = crypto.randomBytes(32).toString('base64');\n await fsp.writeFile(masterKeyPath(), masterKey);\n }\n return await fsp.readFile(masterKeyPath(), 'utf8');\n } catch (err) {\n printMessage(err.message, 'error');\n return '';\n }\n });\n\n // the nonce for AES GCM\n _nonce.set(this, () => crypto.randomBytes(16));\n\n // The salt\n _salt.set(this, () => crypto.randomBytes(64));\n\n // The function that derives the key, this supports sync and async operations\n _key.set(\n this,\n // eslint-disable-next-line no-return-await\n async (masterKey, salt) => await scrypt(masterKey, salt, 32)\n );\n\n // private method to encrypt and return encrypted data. cleaner code\n _encrypt.set(this, (key, nonce, data, salt) => {\n const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce);\n const encrypted = Buffer.concat([\n cipher.update(JSON.stringify(data), 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n const buffer = Buffer.concat([salt, nonce, tag, encrypted]);\n return buffer.toString('base64');\n });\n }\n\n async encrypt(data) {\n const nonce = _nonce.get(this)();\n const salt = _salt.get(this)();\n const masterKey = await _masterKey.get(this)();\n const key = await _key.get(this)(masterKey, salt);\n return _encrypt.get(this)(key, nonce, data, salt);\n }\n\n async decrypt(data) {\n const buffer = Buffer.from(data.toString(), 'base64');\n const salt = buffer.slice(0, 64);\n const nonce = buffer.slice(64, 80);\n const tag = buffer.slice(80, 96);\n const encrypted = buffer.slice(96);\n const masterKey = await _masterKey.get(this)();\n const key = await _key.get(this)(masterKey, salt);\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);\n decipher.setAuthTag(tag);\n return JSON.parse(\n decipher.update(encrypted.toString('binary'), 'binary', 'utf8') +\n decipher.final('utf8')\n );\n }\n}\nexport default DataProtection;\n"]}
1
+ {"version":3,"sources":["../src/ops/utils/DataProtection.ts"],"names":[],"mappings":"AA8BA,cAAM,cAAc;;IAgDZ,OAAO,CAAC,IAAI,KAAA;IAQZ,OAAO,CAAC,IAAI,KAAA;CAenB;AACD,eAAe,cAAc,CAAC","file":"DataProtection.d.ts","sourcesContent":["/**\n * Data is stored in base64 format. Initially it was binary data\n * Format used in this encryption module.\n * inspired by AndiDittrich\n * +--------------------+-----------------------+----------------+----------------+\n * | SALT | Initialization Vector | Auth Tag | Payload |\n * | Used to derive key | AES GCM XOR Init | Data Integrity | Encrypted Data |\n * | 64 Bytes, random | 16 Bytes, random | 16 Bytes | (N-96) Bytes |\n * +--------------------+-----------------------+----------------+----------------+\n * This module doesn't take care of data persistence, it's assumed the consuming method/class/package will do so.\n */\nimport fs, { promises as fsp } from 'fs';\nimport crypto from 'crypto';\nimport { homedir } from 'os';\nimport { promisify } from 'util';\nimport { printMessage } from './Console';\nimport * as state from '../../shared/State';\nimport {\n FRODO_MASTER_KEY_PATH_KEY,\n FRODO_MASTER_KEY_KEY,\n} from '../../storage/StaticStorage';\n\nconst scrypt = promisify(crypto.scrypt);\n// using WeakMaps for added security since it gets garbage collected\nconst _masterKey = new WeakMap();\nconst _nonce = new WeakMap();\nconst _salt = new WeakMap();\nconst _key = new WeakMap();\nconst _encrypt = new WeakMap();\n\nclass DataProtection {\n constructor() {\n const masterKeyPath = () =>\n state.getMasterKeyPath() ||\n process.env[FRODO_MASTER_KEY_PATH_KEY] ||\n `${homedir()}/.frodo/masterkey.key`;\n // Generates a master key in base64 format. This master key will be used to derive the key for encryption. this key should be protected by an HSM or KMS\n _masterKey.set(this, async () => {\n try {\n if (process.env[FRODO_MASTER_KEY_KEY])\n return process.env[FRODO_MASTER_KEY_KEY];\n if (!fs.existsSync(masterKeyPath())) {\n const masterKey = crypto.randomBytes(32).toString('base64');\n await fsp.writeFile(masterKeyPath(), masterKey);\n }\n return await fsp.readFile(masterKeyPath(), 'utf8');\n } catch (err) {\n printMessage(err.message, 'error');\n return '';\n }\n });\n\n // the nonce for AES GCM\n _nonce.set(this, () => crypto.randomBytes(16));\n\n // The salt\n _salt.set(this, () => crypto.randomBytes(64));\n\n // The function that derives the key, this supports sync and async operations\n _key.set(\n this,\n // eslint-disable-next-line no-return-await\n async (masterKey, salt) => await scrypt(masterKey, salt, 32)\n );\n\n // private method to encrypt and return encrypted data. cleaner code\n _encrypt.set(this, (key, nonce, data, salt) => {\n const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce);\n const encrypted = Buffer.concat([\n cipher.update(JSON.stringify(data), 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n const buffer = Buffer.concat([salt, nonce, tag, encrypted]);\n return buffer.toString('base64');\n });\n }\n\n async encrypt(data) {\n const nonce = _nonce.get(this)();\n const salt = _salt.get(this)();\n const masterKey = await _masterKey.get(this)();\n const key = await _key.get(this)(masterKey, salt);\n return _encrypt.get(this)(key, nonce, data, salt);\n }\n\n async decrypt(data) {\n const buffer = Buffer.from(data.toString(), 'base64');\n const salt = buffer.slice(0, 64);\n const nonce = buffer.slice(64, 80);\n const tag = buffer.slice(80, 96);\n const encrypted = buffer.slice(96);\n const masterKey = await _masterKey.get(this)();\n const key = await _key.get(this)(masterKey, salt);\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);\n decipher.setAuthTag(tag);\n return JSON.parse(\n decipher.update(encrypted.toString('binary'), 'binary', 'utf8') +\n decipher.final('utf8')\n );\n }\n}\nexport default DataProtection;\n"]}
@@ -1,6 +1,8 @@
1
+ import { ExportMetaData } from '../OpsTypes';
1
2
  export declare function getCurrentTimestamp(): string;
3
+ export declare function getMetadata(): ExportMetaData;
2
4
  export declare function titleCase(input: any): any;
3
- export declare function getRealmString(): any;
5
+ export declare function getRealmString(): string;
4
6
  export declare function convertBase64TextToArray(b64text: any): any[];
5
7
  export declare function convertBase64UrlTextToArray(b64UTF8Text: any): any[];
6
8
  export declare function convertTextArrayToBase64(textArray: any): string;
@@ -13,8 +15,9 @@ export declare function saveToFile(type: any, data: any, identifier: any, filena
13
15
  * Save JSON object to file
14
16
  * @param {Object} data data object
15
17
  * @param {String} filename file name
18
+ * @return {boolean} true if successful, false otherwise
16
19
  */
17
- export declare function saveJsonToFile(data: any, filename: any): void;
20
+ export declare function saveJsonToFile(data: any, filename: any, includeMeta?: boolean): boolean;
18
21
  /**
19
22
  * Save text data to file
20
23
  * @param {String} data text data
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/utils/ExportImportUtils.ts"],"names":[],"mappings":"AAeA,wBAAgB,mBAAmB,WAGlC;AAmBD,wBAAgB,SAAS,CAAC,KAAK,KAAA,OAO9B;AAED,wBAAgB,cAAc,QAK7B;AAED,wBAAgB,wBAAwB,CAAC,OAAO,KAAA,SAM/C;AAED,wBAAgB,2BAA2B,CAAC,WAAW,KAAA,SAMtD;AAED,wBAAgB,wBAAwB,CAAC,SAAS,KAAA,UAIjD;AAED,wBAAgB,2BAA2B,CAAC,SAAS,KAAA,OAIpD;AAGD,wBAAgB,cAAc,CAAC,QAAQ,KAAA,GAAG,OAAO,CAEhD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAS,UAG3E;AAED,wBAAgB,mBAAmB,WAalC;AAED,wBAAgB,UAAU,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,UAAU,KAAA,EAAE,QAAQ,KAAA,QAkB1D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA,QAS5C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA,QAQ5C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA,QAM9C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,UAAO,EACX,IAAI,SAAO,GACV,MAAM,EAAE,CAqBV;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgB7E","file":"ExportImportUtils.d.ts","sourcesContent":["import fs from 'fs';\nimport { lstat, readdir } from 'fs/promises';\nimport { join } from 'path';\nimport slugify from 'slugify';\nimport {\n decode,\n decodeBase64Url,\n encode,\n encodeBase64Url,\n} from '../../api/utils/Base64';\nimport storage from '../../storage/SessionStorage';\nimport { FRODO_METADATA_ID } from '../../storage/StaticStorage';\nimport { ExportMetaData } from '../OpsTypes';\nimport { debugMessage, printMessage } from './Console';\n\nexport function getCurrentTimestamp() {\n const ts = new Date();\n return ts.toISOString();\n}\n\nfunction getMetadata(): ExportMetaData {\n const metadata: ExportMetaData = {\n origin: storage.session.getTenant(),\n originAmVersion: storage.session.getAmVersion(),\n exportedBy: storage.session.getUsername(),\n exportDate: getCurrentTimestamp(),\n exportTool: FRODO_METADATA_ID,\n exportToolVersion: storage.session.getFrodoVersion(),\n };\n return metadata;\n}\n\n/*\n * Output str in title case\n *\n * e.g.: 'ALL UPPERCASE AND all lowercase' = 'All Uppercase And All Lowercase'\n */\nexport function titleCase(input) {\n const str = input.toString();\n const splitStr = str.toLowerCase().split(' ');\n for (let i = 0; i < splitStr.length; i += 1) {\n splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].slice(1);\n }\n return splitStr.join(' ');\n}\n\nexport function getRealmString() {\n const realm = storage.session.getRealm();\n return realm\n .split('/')\n .reduce((result, item) => `${result}${titleCase(item)}`, '');\n}\n\nexport function convertBase64TextToArray(b64text) {\n let arrayOut = [];\n let plainText = decode(b64text);\n plainText = plainText.replace(/\\t/g, ' ');\n arrayOut = plainText.split('\\n');\n return arrayOut;\n}\n\nexport function convertBase64UrlTextToArray(b64UTF8Text) {\n let arrayOut = [];\n let plainText = decodeBase64Url(b64UTF8Text);\n plainText = plainText.replace(/\\t/g, ' ');\n arrayOut = plainText.split('\\n');\n return arrayOut;\n}\n\nexport function convertTextArrayToBase64(textArray) {\n const joinedText = textArray.join('\\n');\n const b64encodedScript = encode(joinedText);\n return b64encodedScript;\n}\n\nexport function convertTextArrayToBase64Url(textArray) {\n const joinedText = textArray.join('\\n');\n const b64encodedScript = encodeBase64Url(joinedText);\n return b64encodedScript;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport function validateImport(metadata): boolean {\n return metadata || true;\n}\n\nexport function getTypedFilename(name: string, type: string, suffix = 'json') {\n const slug = slugify(name.replace(/^http(s?):\\/\\//, ''));\n return `${slug}.${type}.${suffix}`;\n}\n\nexport function getWorkingDirectory() {\n let wd = '.';\n if (storage.session.getDirectory()) {\n wd = storage.session.getDirectory().replace(/\\/$/, '');\n // create directory if it doesn't exist\n if (!fs.existsSync(wd)) {\n debugMessage(\n `ExportImportUtils.getWorkingDirectory: creating directory '${wd}'`\n );\n fs.mkdirSync(wd, { recursive: true });\n }\n }\n return wd;\n}\n\nexport function saveToFile(type, data, identifier, filename) {\n const exportData = {};\n exportData['meta'] = getMetadata();\n exportData[type] = {};\n\n if (Array.isArray(data)) {\n data.forEach((element) => {\n exportData[type][element[identifier]] = element;\n });\n } else {\n exportData[type][data[identifier]] = data;\n }\n fs.writeFile(filename, JSON.stringify(exportData, null, 2), (err) => {\n if (err) {\n return printMessage(`ERROR - can't save ${type} to file`, 'error');\n }\n return '';\n });\n}\n\n/**\n * Save JSON object to file\n * @param {Object} data data object\n * @param {String} filename file name\n */\nexport function saveJsonToFile(data, filename) {\n const exportData = data;\n exportData.meta = getMetadata();\n fs.writeFile(filename, JSON.stringify(exportData, null, 2), (err) => {\n if (err) {\n return printMessage(`ERROR - can't save ${filename}`, 'error');\n }\n return '';\n });\n}\n\n/**\n * Save text data to file\n * @param {String} data text data\n * @param {String} filename file name\n */\nexport function saveTextToFile(data, filename) {\n fs.writeFile(filename, data, (err) => {\n if (err) {\n printMessage(`ERROR - can't save ${filename}`, 'error');\n return false;\n }\n return true;\n });\n}\n\n/**\n * Append text data to file\n * @param {String} data text data\n * @param {String} filename file name\n */\nexport function appendTextToFile(data, filename) {\n try {\n fs.appendFileSync(filename, data);\n } catch (error) {\n printMessage(`${error.message}`, 'error');\n }\n}\n\n/**\n * Find files by name\n * @param {string} fileName file name to search for\n * @param {boolean} fast return first result and stop search\n * @param {string} path path to directory where to start the search\n * @returns {string[]} array of found file paths relative to starting directory\n */\nexport function findFilesByName(\n fileName: string,\n fast = true,\n path = './'\n): string[] {\n const entries = fs.readdirSync(path, {\n encoding: 'utf8',\n withFileTypes: true,\n });\n\n // Get files within the current directory and add a path key to the file objects\n const files: string[] = entries\n .filter((entry) => !entry.isDirectory())\n .filter((file) => file.name === fileName)\n // .map((file) => ({ ...file, path: path + file.name }));\n .map((file) => path + file.name);\n\n if (fast && files.length > 0) return files;\n\n // search sub-folders\n const folders = entries.filter((entry) => entry.isDirectory());\n for (const folder of folders)\n files.push(...findFilesByName(fileName, fast, `${path}${folder.name}/`));\n\n return files;\n}\n\n/**\n * find all (nested) files in a directory\n *\n * @param directory directory to search\n * @returns list of files\n */\nexport async function readFilesRecursive(directory: string): Promise<string[]> {\n const items = await readdir(directory);\n\n const filePathsNested = await Promise.all(\n items.map(async (entity) => {\n const path = join(directory, entity);\n const isDirectory = (await lstat(path)).isDirectory();\n\n if (isDirectory) {\n return readFilesRecursive(path);\n }\n return path;\n })\n );\n\n return filePathsNested.flat();\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/utils/ExportImportUtils.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,wBAAgB,mBAAmB,WAGlC;AAED,wBAAgB,WAAW,IAAI,cAAc,CAU5C;AAOD,wBAAgB,SAAS,CAAC,KAAK,KAAA,OAO9B;AAED,wBAAgB,cAAc,WAK7B;AAED,wBAAgB,wBAAwB,CAAC,OAAO,KAAA,SAM/C;AAED,wBAAgB,2BAA2B,CAAC,WAAW,KAAA,SAMtD;AAED,wBAAgB,wBAAwB,CAAC,SAAS,KAAA,UAIjD;AAED,wBAAgB,2BAA2B,CAAC,SAAS,KAAA,OAIpD;AAGD,wBAAgB,cAAc,CAAC,QAAQ,KAAA,GAAG,OAAO,CAEhD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAS,UAG3E;AAED,wBAAgB,mBAAmB,WAalC;AAED,wBAAgB,UAAU,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,UAAU,KAAA,EAAE,QAAQ,KAAA,QAkB1D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA,EAAE,WAAW,UAAO,GAAG,OAAO,CAU1E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA,QAQ5C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA,QAM9C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,UAAO,EACX,IAAI,SAAO,GACV,MAAM,EAAE,CAqBV;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgB7E","file":"ExportImportUtils.d.ts","sourcesContent":["import fs from 'fs';\nimport { lstat, readdir } from 'fs/promises';\nimport { join } from 'path';\nimport slugify from 'slugify';\nimport {\n decode,\n decodeBase64Url,\n encode,\n encodeBase64Url,\n} from '../../api/utils/Base64';\nimport * as state from '../../shared/State';\nimport { FRODO_METADATA_ID } from '../../storage/StaticStorage';\nimport { ExportMetaData } from '../OpsTypes';\nimport { debugMessage, printMessage } from './Console';\n\nexport function getCurrentTimestamp() {\n const ts = new Date();\n return ts.toISOString();\n}\n\nexport function getMetadata(): ExportMetaData {\n const metadata: ExportMetaData = {\n origin: state.getHost(),\n originAmVersion: state.getAmVersion(),\n exportedBy: state.getUsername(),\n exportDate: getCurrentTimestamp(),\n exportTool: FRODO_METADATA_ID,\n exportToolVersion: state.getFrodoVersion(),\n };\n return metadata;\n}\n\n/*\n * Output str in title case\n *\n * e.g.: 'ALL UPPERCASE AND all lowercase' = 'All Uppercase And All Lowercase'\n */\nexport function titleCase(input) {\n const str = input.toString();\n const splitStr = str.toLowerCase().split(' ');\n for (let i = 0; i < splitStr.length; i += 1) {\n splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].slice(1);\n }\n return splitStr.join(' ');\n}\n\nexport function getRealmString() {\n const realm = state.getRealm();\n return realm\n .split('/')\n .reduce((result, item) => `${result}${titleCase(item)}`, '');\n}\n\nexport function convertBase64TextToArray(b64text) {\n let arrayOut = [];\n let plainText = decode(b64text);\n plainText = plainText.replace(/\\t/g, ' ');\n arrayOut = plainText.split('\\n');\n return arrayOut;\n}\n\nexport function convertBase64UrlTextToArray(b64UTF8Text) {\n let arrayOut = [];\n let plainText = decodeBase64Url(b64UTF8Text);\n plainText = plainText.replace(/\\t/g, ' ');\n arrayOut = plainText.split('\\n');\n return arrayOut;\n}\n\nexport function convertTextArrayToBase64(textArray) {\n const joinedText = textArray.join('\\n');\n const b64encodedScript = encode(joinedText);\n return b64encodedScript;\n}\n\nexport function convertTextArrayToBase64Url(textArray) {\n const joinedText = textArray.join('\\n');\n const b64encodedScript = encodeBase64Url(joinedText);\n return b64encodedScript;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport function validateImport(metadata): boolean {\n return metadata || true;\n}\n\nexport function getTypedFilename(name: string, type: string, suffix = 'json') {\n const slug = slugify(name.replace(/^http(s?):\\/\\//, ''));\n return `${slug}.${type}.${suffix}`;\n}\n\nexport function getWorkingDirectory() {\n let wd = '.';\n if (state.getDirectory()) {\n wd = state.getDirectory().replace(/\\/$/, '');\n // create directory if it doesn't exist\n if (!fs.existsSync(wd)) {\n debugMessage(\n `ExportImportUtils.getWorkingDirectory: creating directory '${wd}'`\n );\n fs.mkdirSync(wd, { recursive: true });\n }\n }\n return wd;\n}\n\nexport function saveToFile(type, data, identifier, filename) {\n const exportData = {};\n exportData['meta'] = getMetadata();\n exportData[type] = {};\n\n if (Array.isArray(data)) {\n data.forEach((element) => {\n exportData[type][element[identifier]] = element;\n });\n } else {\n exportData[type][data[identifier]] = data;\n }\n fs.writeFile(filename, JSON.stringify(exportData, null, 2), (err) => {\n if (err) {\n return printMessage(`ERROR - can't save ${type} to file`, 'error');\n }\n return '';\n });\n}\n\n/**\n * Save JSON object to file\n * @param {Object} data data object\n * @param {String} filename file name\n * @return {boolean} true if successful, false otherwise\n */\nexport function saveJsonToFile(data, filename, includeMeta = true): boolean {\n const exportData = data;\n if (includeMeta) exportData.meta = getMetadata();\n try {\n fs.writeFileSync(filename, JSON.stringify(exportData, null, 2));\n return true;\n } catch (err) {\n printMessage(`ERROR - can't save ${filename}`, 'error');\n return false;\n }\n}\n\n/**\n * Save text data to file\n * @param {String} data text data\n * @param {String} filename file name\n */\nexport function saveTextToFile(data, filename) {\n fs.writeFile(filename, data, (err) => {\n if (err) {\n printMessage(`ERROR - can't save ${filename}`, 'error');\n return false;\n }\n return true;\n });\n}\n\n/**\n * Append text data to file\n * @param {String} data text data\n * @param {String} filename file name\n */\nexport function appendTextToFile(data, filename) {\n try {\n fs.appendFileSync(filename, data);\n } catch (error) {\n printMessage(`${error.message}`, 'error');\n }\n}\n\n/**\n * Find files by name\n * @param {string} fileName file name to search for\n * @param {boolean} fast return first result and stop search\n * @param {string} path path to directory where to start the search\n * @returns {string[]} array of found file paths relative to starting directory\n */\nexport function findFilesByName(\n fileName: string,\n fast = true,\n path = './'\n): string[] {\n const entries = fs.readdirSync(path, {\n encoding: 'utf8',\n withFileTypes: true,\n });\n\n // Get files within the current directory and add a path key to the file objects\n const files: string[] = entries\n .filter((entry) => !entry.isDirectory())\n .filter((file) => file.name === fileName)\n // .map((file) => ({ ...file, path: path + file.name }));\n .map((file) => path + file.name);\n\n if (fast && files.length > 0) return files;\n\n // search sub-folders\n const folders = entries.filter((entry) => entry.isDirectory());\n for (const folder of folders)\n files.push(...findFilesByName(fileName, fast, `${path}${folder.name}/`));\n\n return files;\n}\n\n/**\n * find all (nested) files in a directory\n *\n * @param directory directory to search\n * @returns list of files\n */\nexport async function readFilesRecursive(directory: string): Promise<string[]> {\n const items = await readdir(directory);\n\n const filePathsNested = await Promise.all(\n items.map(async (entity) => {\n const path = join(directory, entity);\n const isDirectory = (await lstat(path)).isDirectory();\n\n if (isDirectory) {\n return readFilesRecursive(path);\n }\n return path;\n })\n );\n\n return filePathsNested.flat();\n}\n"]}
@@ -39,3 +39,9 @@ export declare function readFiles(baseDirectory: string, childDirectory?: string
39
39
  }[]>;
40
40
  export declare function substituteEnvParams(input: string, reader: Reader): string;
41
41
  export declare function unSubstituteEnvParams(input: string, reader: Reader): string;
42
+ /**
43
+ * Check if a string is a valid URL
44
+ * @param {string} urlString input string to be evaluated
45
+ * @returns {boolean} true if a valid URL, false otherwise
46
+ */
47
+ export declare function isValidUrl(urlString: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/utils/OpsUtils.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,wBAAgB,YAAY,CAAC,GAAG,KAAA,OAE/B;AAGD,wBAAgB,UAAU,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,EAAE,OAAO,KAAA,OAE5C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,KAAA,UAU5C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,WAQlC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,UAAU,GAAE,MAAM,EAAO,WAwBhE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,KAAA,UAEjC;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,aAAa,EAAE,MAAM,EACrB,cAAc,SAAK,GAClB,OAAO,CACR;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,EAAE,CACJ,CAsBA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAKhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAKlE","file":"OpsUtils.d.ts","sourcesContent":["import storage from '../../storage/SessionStorage';\nimport * as global from '../../storage/StaticStorage';\nimport {\n getCurrentRealmName,\n getRealmName as _getRealmName,\n} from '../../api/utils/ApiUtils';\nimport { lstat, readdir, readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { Reader } from 'properties-reader';\nimport replaceall from 'replaceall';\n\n// TODO: do we really need this? if yes: document\nexport function escapeRegExp(str) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n// TODO: do we really need this? if yes: document\nexport function replaceAll(str, find, replace) {\n return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n\n/**\n * Get new name when names collide\n * @param {String} name to apply policy to\n * @returns {String} new name according to policy\n */\nexport function applyNameCollisionPolicy(name) {\n const capturingRegex = /(.* - imported) \\(([0-9]+)\\)/;\n const found = name.match(capturingRegex);\n if (found && found.length > 0 && found.length === 3) {\n // already renamed one or more times\n // return the next number\n return `${found[1]} (${parseInt(found[2], 10) + 1})`;\n }\n // first time\n return `${name} - imported (1)`;\n}\n\n/**\n * Get the name of the managed user object for the current realm\n * @returns {String} the name of the managed user object for the current realm\n */\nexport function getRealmManagedUser() {\n let realmManagedUser = 'user';\n if (\n storage.session.getDeploymentType() === global.CLOUD_DEPLOYMENT_TYPE_KEY\n ) {\n realmManagedUser = `${getCurrentRealmName()}_user`;\n }\n return realmManagedUser;\n}\n\n/**\n * Compare two json objects\n * @param {Object} obj1 object 1\n * @param {Object} obj2 object 2\n * @param {[String]} ignoreKeys array of keys to ignore in comparison\n * @returns {boolean} true if the two json objects have the same length and all the properties have the same value\n */\nexport function isEqualJson(obj1, obj2, ignoreKeys: string[] = []) {\n const obj1Keys = Object.keys(obj1).filter((key) => !ignoreKeys.includes(key));\n const obj2Keys = Object.keys(obj2).filter((key) => !ignoreKeys.includes(key));\n\n if (obj1Keys.length !== obj2Keys.length) {\n return false;\n }\n\n for (const objKey of obj1Keys) {\n if (obj1[objKey] !== obj2[objKey]) {\n if (\n typeof obj1[objKey] === 'object' &&\n typeof obj2[objKey] === 'object'\n ) {\n if (!isEqualJson(obj1[objKey], obj2[objKey], ignoreKeys)) {\n return false;\n }\n } else {\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Get current realm name\n * @param {String} realm realm\n * @returns {String} name of the realm. /alpha -> alpha\n */\nexport function getRealmName(realm) {\n return _getRealmName(realm);\n}\n\n/**\n * find all (nested) files in a directory\n *\n * @param baseDirectory directory to search\n * @param childDirectory subdirectory to search\n * @returns list of files\n */\nexport async function readFiles(\n baseDirectory: string,\n childDirectory = ''\n): Promise<\n {\n path: string;\n content: string;\n }[]\n> {\n const targetDirectory = join(baseDirectory, childDirectory);\n const directoryItems = await readdir(targetDirectory);\n const childPaths = directoryItems.map((item) => join(childDirectory, item));\n\n const filePathsNested = await Promise.all(\n childPaths.map(async (childPath) => {\n const path = join(baseDirectory, childPath);\n const isDirectory = (await lstat(path)).isDirectory();\n\n if (isDirectory) {\n return readFiles(baseDirectory, childPath);\n }\n\n return {\n path: childPath,\n content: await readFile(path, 'utf8'),\n };\n })\n );\n\n return filePathsNested.flat();\n}\n\nexport function substituteEnvParams(input: string, reader: Reader) {\n reader.each((key, value) => {\n input = replaceall(value, `\\${${key}}`, input);\n });\n return input;\n}\n\nexport function unSubstituteEnvParams(input: string, reader: Reader) {\n reader.each((key, value) => {\n input = replaceall(`\\${${key}}`, value, input);\n });\n return input;\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/utils/OpsUtils.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI3C,wBAAgB,YAAY,CAAC,GAAG,KAAA,OAE/B;AAGD,wBAAgB,UAAU,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,EAAE,OAAO,KAAA,OAE5C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,KAAA,UAU5C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,WAMlC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,KAAA,EAAE,IAAI,KAAA,EAAE,UAAU,GAAE,MAAM,EAAO,WAwBhE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,KAAA,UAEjC;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,aAAa,EAAE,MAAM,EACrB,cAAc,SAAK,GAClB,OAAO,CACR;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,EAAE,CACJ,CAsBA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAKhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAKlE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,WAM3C","file":"OpsUtils.d.ts","sourcesContent":["import * as state from '../../shared/State';\nimport * as globalConfig from '../../storage/StaticStorage';\nimport {\n getCurrentRealmName,\n getRealmName as _getRealmName,\n} from '../../api/utils/ApiUtils';\nimport { lstat, readdir, readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { Reader } from 'properties-reader';\nimport replaceall from 'replaceall';\n\n// TODO: do we really need this? if yes: document\nexport function escapeRegExp(str) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n// TODO: do we really need this? if yes: document\nexport function replaceAll(str, find, replace) {\n return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n\n/**\n * Get new name when names collide\n * @param {String} name to apply policy to\n * @returns {String} new name according to policy\n */\nexport function applyNameCollisionPolicy(name) {\n const capturingRegex = /(.* - imported) \\(([0-9]+)\\)/;\n const found = name.match(capturingRegex);\n if (found && found.length > 0 && found.length === 3) {\n // already renamed one or more times\n // return the next number\n return `${found[1]} (${parseInt(found[2], 10) + 1})`;\n }\n // first time\n return `${name} - imported (1)`;\n}\n\n/**\n * Get the name of the managed user object for the current realm\n * @returns {String} the name of the managed user object for the current realm\n */\nexport function getRealmManagedUser() {\n let realmManagedUser = 'user';\n if (state.getDeploymentType() === globalConfig.CLOUD_DEPLOYMENT_TYPE_KEY) {\n realmManagedUser = `${getCurrentRealmName()}_user`;\n }\n return realmManagedUser;\n}\n\n/**\n * Compare two json objects\n * @param {Object} obj1 object 1\n * @param {Object} obj2 object 2\n * @param {[String]} ignoreKeys array of keys to ignore in comparison\n * @returns {boolean} true if the two json objects have the same length and all the properties have the same value\n */\nexport function isEqualJson(obj1, obj2, ignoreKeys: string[] = []) {\n const obj1Keys = Object.keys(obj1).filter((key) => !ignoreKeys.includes(key));\n const obj2Keys = Object.keys(obj2).filter((key) => !ignoreKeys.includes(key));\n\n if (obj1Keys.length !== obj2Keys.length) {\n return false;\n }\n\n for (const objKey of obj1Keys) {\n if (obj1[objKey] !== obj2[objKey]) {\n if (\n typeof obj1[objKey] === 'object' &&\n typeof obj2[objKey] === 'object'\n ) {\n if (!isEqualJson(obj1[objKey], obj2[objKey], ignoreKeys)) {\n return false;\n }\n } else {\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Get current realm name\n * @param {String} realm realm\n * @returns {String} name of the realm. /alpha -> alpha\n */\nexport function getRealmName(realm) {\n return _getRealmName(realm);\n}\n\n/**\n * find all (nested) files in a directory\n *\n * @param baseDirectory directory to search\n * @param childDirectory subdirectory to search\n * @returns list of files\n */\nexport async function readFiles(\n baseDirectory: string,\n childDirectory = ''\n): Promise<\n {\n path: string;\n content: string;\n }[]\n> {\n const targetDirectory = join(baseDirectory, childDirectory);\n const directoryItems = await readdir(targetDirectory);\n const childPaths = directoryItems.map((item) => join(childDirectory, item));\n\n const filePathsNested = await Promise.all(\n childPaths.map(async (childPath) => {\n const path = join(baseDirectory, childPath);\n const isDirectory = (await lstat(path)).isDirectory();\n\n if (isDirectory) {\n return readFiles(baseDirectory, childPath);\n }\n\n return {\n path: childPath,\n content: await readFile(path, 'utf8'),\n };\n })\n );\n\n return filePathsNested.flat();\n}\n\nexport function substituteEnvParams(input: string, reader: Reader) {\n reader.each((key, value) => {\n input = replaceall(value, `\\${${key}}`, input);\n });\n return input;\n}\n\nexport function unSubstituteEnvParams(input: string, reader: Reader) {\n reader.each((key, value) => {\n input = replaceall(`\\${${key}}`, value, input);\n });\n return input;\n}\n\n/**\n * Check if a string is a valid URL\n * @param {string} urlString input string to be evaluated\n * @returns {boolean} true if a valid URL, false otherwise\n */\nexport function isValidUrl(urlString: string) {\n try {\n return Boolean(new URL(urlString));\n } catch (error) {\n return false;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ops/utils/Wordwrap.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,KAAA,EAAE,GAAG,KAAA,EAAE,MAAM,MAAY,OAU5D","file":"Wordwrap.d.ts","sourcesContent":["export default function wordwrap(str, len, indent = undefined) {\n if (!str) return '';\n return (\n str.match(\n new RegExp(\n `(\\\\S.{0,${len - 1 - (indent ? indent.length : 0)}})(?=\\\\s+|$)`,\n 'g'\n )\n ) || []\n ).join(indent ? `\\n${indent}` : '\\n');\n}\n"]}
1
+ {"version":3,"sources":["../src/ops/utils/Wordwrap.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,KAAA,EAAE,GAAG,KAAA,EAAE,MAAM,MAAY,OAU5D","file":"Wordwrap.d.ts","sourcesContent":["export default function wordwrap(str, len, indent = undefined) {\n if (!str) return '';\n return (\n str.match(\n new RegExp(\n `(\\\\S.{0,${len - 1 - (indent ? indent.length : 0)}})(?=\\\\S+|$)`,\n 'g'\n )\n ) || []\n ).join(indent ? `\\n${indent}` : '\\n');\n}\n"]}