@esri/hub-common 9.13.2 → 9.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/dist/es2017/ArcGISContext.js +215 -158
  2. package/dist/es2017/ArcGISContext.js.map +1 -1
  3. package/dist/es2017/ArcGISContextManager.js +171 -0
  4. package/dist/es2017/ArcGISContextManager.js.map +1 -0
  5. package/dist/es2017/Hub.js +70 -0
  6. package/dist/es2017/Hub.js.map +1 -0
  7. package/dist/es2017/HubError.js +34 -0
  8. package/dist/es2017/HubError.js.map +1 -0
  9. package/dist/es2017/collections.js +23 -0
  10. package/dist/es2017/collections.js.map +1 -1
  11. package/dist/es2017/content/_internal.js +12 -0
  12. package/dist/es2017/content/_internal.js.map +1 -1
  13. package/dist/es2017/content/index.js +42 -18
  14. package/dist/es2017/content/index.js.map +1 -1
  15. package/dist/es2017/core/helpers/PropertyMapper.js +95 -0
  16. package/dist/es2017/core/helpers/PropertyMapper.js.map +1 -0
  17. package/dist/es2017/core/index.js +3 -0
  18. package/dist/es2017/core/index.js.map +1 -0
  19. package/dist/es2017/core/traits/WithBannerImage.js +1 -0
  20. package/dist/es2017/core/traits/WithBannerImage.js.map +1 -0
  21. package/dist/es2017/core/traits/WithLayout.js +1 -0
  22. package/dist/es2017/core/traits/WithLayout.js.map +1 -0
  23. package/dist/es2017/core/traits/WithSlug.js +1 -0
  24. package/dist/es2017/core/traits/WithSlug.js.map +1 -0
  25. package/dist/es2017/core/traits/index.js +4 -0
  26. package/dist/es2017/core/traits/index.js.map +1 -0
  27. package/dist/es2017/core/types/IContentEnrichments.js +1 -0
  28. package/dist/es2017/core/types/IContentEnrichments.js.map +1 -0
  29. package/dist/es2017/core/types/IHubContent.js +1 -0
  30. package/dist/es2017/core/types/IHubContent.js.map +1 -0
  31. package/dist/es2017/core/types/IHubEntityBase.js +1 -0
  32. package/dist/es2017/core/types/IHubEntityBase.js.map +1 -0
  33. package/dist/es2017/core/types/IHubEntityManager.js +1 -0
  34. package/dist/es2017/core/types/IHubEntityManager.js.map +1 -0
  35. package/dist/es2017/core/types/IHubEvent.js +1 -0
  36. package/dist/es2017/core/types/IHubEvent.js.map +1 -0
  37. package/dist/es2017/core/types/IHubImage.js +1 -0
  38. package/dist/es2017/core/types/IHubImage.js.map +1 -0
  39. package/dist/es2017/core/types/IHubInitiative.js +1 -0
  40. package/dist/es2017/core/types/IHubInitiative.js.map +1 -0
  41. package/dist/es2017/core/types/IHubItemEntity.js +1 -0
  42. package/dist/es2017/core/types/IHubItemEntity.js.map +1 -0
  43. package/dist/es2017/core/types/IHubLayout.js +1 -0
  44. package/dist/es2017/core/types/IHubLayout.js.map +1 -0
  45. package/dist/es2017/core/types/IHubPage.js +1 -0
  46. package/dist/es2017/core/types/IHubPage.js.map +1 -0
  47. package/dist/es2017/core/types/IHubProject.js +1 -0
  48. package/dist/es2017/core/types/IHubProject.js.map +1 -0
  49. package/dist/es2017/core/types/IHubSite.js +1 -0
  50. package/dist/es2017/core/types/IHubSite.js.map +1 -0
  51. package/dist/es2017/core/types/IHubTimeline.js +1 -0
  52. package/dist/es2017/core/types/IHubTimeline.js.map +1 -0
  53. package/dist/es2017/core/types/IItemEnrichments.js +1 -0
  54. package/dist/es2017/core/types/IItemEnrichments.js.map +1 -0
  55. package/dist/es2017/core/types/index.js +15 -0
  56. package/dist/es2017/core/types/index.js.map +1 -0
  57. package/dist/es2017/index.js +11 -5
  58. package/dist/es2017/index.js.map +1 -1
  59. package/dist/es2017/items/fail-safe-update.js +2 -2
  60. package/dist/es2017/items/fail-safe-update.js.map +1 -1
  61. package/dist/es2017/items/get-model-from-options.js +2 -2
  62. package/dist/es2017/items/get-model-from-options.js.map +1 -1
  63. package/dist/es2017/items/index.js +2 -3
  64. package/dist/es2017/items/index.js.map +1 -1
  65. package/dist/es2017/items/slugs.js +92 -0
  66. package/dist/es2017/items/slugs.js.map +1 -0
  67. package/dist/es2017/models/index.js +98 -0
  68. package/dist/es2017/models/index.js.map +1 -0
  69. package/dist/es2017/{items/serialize-model.js → models/serializeModel.js} +1 -1
  70. package/dist/es2017/models/serializeModel.js.map +1 -0
  71. package/dist/es2017/projects/HubProjectManager.js +115 -0
  72. package/dist/es2017/projects/HubProjectManager.js.map +1 -0
  73. package/dist/es2017/projects/HubProjects.js +194 -0
  74. package/dist/es2017/projects/HubProjects.js.map +1 -0
  75. package/dist/es2017/projects/index.js +3 -0
  76. package/dist/es2017/projects/index.js.map +1 -0
  77. package/dist/es2017/search/_searchContent.js +18 -7
  78. package/dist/es2017/search/_searchContent.js.map +1 -1
  79. package/dist/es2017/search/_searchGroups.js +1 -11
  80. package/dist/es2017/search/_searchGroups.js.map +1 -1
  81. package/dist/es2017/search/utils.js +1 -1
  82. package/dist/es2017/urls/getHubApiFromPortalUrl.js +21 -0
  83. package/dist/es2017/urls/getHubApiFromPortalUrl.js.map +1 -0
  84. package/dist/es2017/urls/getPortalBaseFromOrgUrl.js +25 -0
  85. package/dist/es2017/urls/getPortalBaseFromOrgUrl.js.map +1 -0
  86. package/dist/es2017/urls/index.js +2 -0
  87. package/dist/es2017/urls/index.js.map +1 -1
  88. package/dist/es2017/utils/dasherize.js +25 -0
  89. package/dist/es2017/utils/dasherize.js.map +1 -0
  90. package/dist/es2017/utils/index.js +1 -0
  91. package/dist/es2017/utils/index.js.map +1 -1
  92. package/dist/esm/ArcGISContext.js +299 -200
  93. package/dist/esm/ArcGISContext.js.map +1 -1
  94. package/dist/esm/ArcGISContextManager.js +215 -0
  95. package/dist/esm/ArcGISContextManager.js.map +1 -0
  96. package/dist/esm/Hub.js +89 -0
  97. package/dist/esm/Hub.js.map +1 -0
  98. package/dist/esm/HubError.js +40 -0
  99. package/dist/esm/HubError.js.map +1 -0
  100. package/dist/esm/collections.js +23 -0
  101. package/dist/esm/collections.js.map +1 -1
  102. package/dist/esm/content/_internal.js +14 -0
  103. package/dist/esm/content/_internal.js.map +1 -1
  104. package/dist/esm/content/index.js +42 -18
  105. package/dist/esm/content/index.js.map +1 -1
  106. package/dist/esm/core/helpers/PropertyMapper.js +97 -0
  107. package/dist/esm/core/helpers/PropertyMapper.js.map +1 -0
  108. package/dist/esm/core/index.js +3 -0
  109. package/dist/esm/core/index.js.map +1 -0
  110. package/dist/esm/core/traits/WithBannerImage.js +1 -0
  111. package/dist/esm/core/traits/WithBannerImage.js.map +1 -0
  112. package/dist/esm/core/traits/WithLayout.js +1 -0
  113. package/dist/esm/core/traits/WithLayout.js.map +1 -0
  114. package/dist/esm/core/traits/WithSlug.js +1 -0
  115. package/dist/esm/core/traits/WithSlug.js.map +1 -0
  116. package/dist/esm/core/traits/index.js +4 -0
  117. package/dist/esm/core/traits/index.js.map +1 -0
  118. package/dist/esm/core/types/IContentEnrichments.js +1 -0
  119. package/dist/esm/core/types/IContentEnrichments.js.map +1 -0
  120. package/dist/esm/core/types/IHubContent.js +1 -0
  121. package/dist/esm/core/types/IHubContent.js.map +1 -0
  122. package/dist/esm/core/types/IHubEntityBase.js +1 -0
  123. package/dist/esm/core/types/IHubEntityBase.js.map +1 -0
  124. package/dist/esm/core/types/IHubEntityManager.js +1 -0
  125. package/dist/esm/core/types/IHubEntityManager.js.map +1 -0
  126. package/dist/esm/core/types/IHubEvent.js +1 -0
  127. package/dist/esm/core/types/IHubEvent.js.map +1 -0
  128. package/dist/esm/core/types/IHubImage.js +1 -0
  129. package/dist/esm/core/types/IHubImage.js.map +1 -0
  130. package/dist/esm/core/types/IHubInitiative.js +1 -0
  131. package/dist/esm/core/types/IHubInitiative.js.map +1 -0
  132. package/dist/esm/core/types/IHubItemEntity.js +1 -0
  133. package/dist/esm/core/types/IHubItemEntity.js.map +1 -0
  134. package/dist/esm/core/types/IHubLayout.js +1 -0
  135. package/dist/esm/core/types/IHubLayout.js.map +1 -0
  136. package/dist/esm/core/types/IHubPage.js +1 -0
  137. package/dist/esm/core/types/IHubPage.js.map +1 -0
  138. package/dist/esm/core/types/IHubProject.js +1 -0
  139. package/dist/esm/core/types/IHubProject.js.map +1 -0
  140. package/dist/esm/core/types/IHubSite.js +1 -0
  141. package/dist/esm/core/types/IHubSite.js.map +1 -0
  142. package/dist/esm/core/types/IHubTimeline.js +1 -0
  143. package/dist/esm/core/types/IHubTimeline.js.map +1 -0
  144. package/dist/esm/core/types/IItemEnrichments.js +1 -0
  145. package/dist/esm/core/types/IItemEnrichments.js.map +1 -0
  146. package/dist/esm/core/types/index.js +15 -0
  147. package/dist/esm/core/types/index.js.map +1 -0
  148. package/dist/esm/index.js +11 -5
  149. package/dist/esm/index.js.map +1 -1
  150. package/dist/esm/items/fail-safe-update.js +2 -2
  151. package/dist/esm/items/fail-safe-update.js.map +1 -1
  152. package/dist/esm/items/get-model-from-options.js +2 -2
  153. package/dist/esm/items/get-model-from-options.js.map +1 -1
  154. package/dist/esm/items/index.js +2 -3
  155. package/dist/esm/items/index.js.map +1 -1
  156. package/dist/esm/items/slugs.js +93 -0
  157. package/dist/esm/items/slugs.js.map +1 -0
  158. package/dist/esm/models/index.js +99 -0
  159. package/dist/esm/models/index.js.map +1 -0
  160. package/dist/esm/{items/serialize-model.js → models/serializeModel.js} +1 -1
  161. package/dist/esm/models/serializeModel.js.map +1 -0
  162. package/dist/esm/projects/HubProjectManager.js +142 -0
  163. package/dist/esm/projects/HubProjectManager.js.map +1 -0
  164. package/dist/esm/projects/HubProjects.js +225 -0
  165. package/dist/esm/projects/HubProjects.js.map +1 -0
  166. package/dist/esm/projects/index.js +3 -0
  167. package/dist/esm/projects/index.js.map +1 -0
  168. package/dist/esm/search/_searchContent.js +18 -7
  169. package/dist/esm/search/_searchContent.js.map +1 -1
  170. package/dist/esm/search/_searchGroups.js +3 -13
  171. package/dist/esm/search/_searchGroups.js.map +1 -1
  172. package/dist/esm/search/utils.js +1 -1
  173. package/dist/esm/urls/getHubApiFromPortalUrl.js +21 -0
  174. package/dist/esm/urls/getHubApiFromPortalUrl.js.map +1 -0
  175. package/dist/esm/urls/getPortalBaseFromOrgUrl.js +25 -0
  176. package/dist/esm/urls/getPortalBaseFromOrgUrl.js.map +1 -0
  177. package/dist/esm/urls/index.js +2 -0
  178. package/dist/esm/urls/index.js.map +1 -1
  179. package/dist/esm/utils/dasherize.js +25 -0
  180. package/dist/esm/utils/dasherize.js.map +1 -0
  181. package/dist/esm/utils/index.js +1 -0
  182. package/dist/esm/utils/index.js.map +1 -1
  183. package/dist/node/ArcGISContext.js +215 -158
  184. package/dist/node/ArcGISContext.js.map +1 -1
  185. package/dist/node/ArcGISContextManager.js +175 -0
  186. package/dist/node/ArcGISContextManager.js.map +1 -0
  187. package/dist/node/Hub.js +74 -0
  188. package/dist/node/Hub.js.map +1 -0
  189. package/dist/node/HubError.js +37 -0
  190. package/dist/node/HubError.js.map +1 -0
  191. package/dist/node/collections.js +24 -1
  192. package/dist/node/collections.js.map +1 -1
  193. package/dist/node/content/_internal.js +13 -1
  194. package/dist/node/content/_internal.js.map +1 -1
  195. package/dist/node/content/index.js +42 -18
  196. package/dist/node/content/index.js.map +1 -1
  197. package/dist/node/core/helpers/PropertyMapper.js +101 -0
  198. package/dist/node/core/helpers/PropertyMapper.js.map +1 -0
  199. package/dist/node/core/index.js +6 -0
  200. package/dist/node/core/index.js.map +1 -0
  201. package/dist/node/core/traits/WithBannerImage.js +3 -0
  202. package/dist/node/core/traits/WithBannerImage.js.map +1 -0
  203. package/dist/node/core/traits/WithLayout.js +3 -0
  204. package/dist/node/core/traits/WithLayout.js.map +1 -0
  205. package/dist/node/core/traits/WithSlug.js +3 -0
  206. package/dist/node/core/traits/WithSlug.js.map +1 -0
  207. package/dist/node/core/traits/index.js +7 -0
  208. package/dist/node/core/traits/index.js.map +1 -0
  209. package/dist/node/core/types/IContentEnrichments.js +3 -0
  210. package/dist/node/core/types/IContentEnrichments.js.map +1 -0
  211. package/dist/node/core/types/IHubContent.js +3 -0
  212. package/dist/node/core/types/IHubContent.js.map +1 -0
  213. package/dist/node/core/types/IHubEntityBase.js +3 -0
  214. package/dist/node/core/types/IHubEntityBase.js.map +1 -0
  215. package/dist/node/core/types/IHubEntityManager.js +3 -0
  216. package/dist/node/core/types/IHubEntityManager.js.map +1 -0
  217. package/dist/node/core/types/IHubEvent.js +3 -0
  218. package/dist/node/core/types/IHubEvent.js.map +1 -0
  219. package/dist/node/core/types/IHubImage.js +3 -0
  220. package/dist/node/core/types/IHubImage.js.map +1 -0
  221. package/dist/node/core/types/IHubInitiative.js +3 -0
  222. package/dist/node/core/types/IHubInitiative.js.map +1 -0
  223. package/dist/node/core/types/IHubItemEntity.js +3 -0
  224. package/dist/node/core/types/IHubItemEntity.js.map +1 -0
  225. package/dist/node/core/types/IHubLayout.js +3 -0
  226. package/dist/node/core/types/IHubLayout.js.map +1 -0
  227. package/dist/node/core/types/IHubPage.js +3 -0
  228. package/dist/node/core/types/IHubPage.js.map +1 -0
  229. package/dist/node/core/types/IHubProject.js +3 -0
  230. package/dist/node/core/types/IHubProject.js.map +1 -0
  231. package/dist/node/core/types/IHubSite.js +3 -0
  232. package/dist/node/core/types/IHubSite.js.map +1 -0
  233. package/dist/node/core/types/IHubTimeline.js +3 -0
  234. package/dist/node/core/types/IHubTimeline.js.map +1 -0
  235. package/dist/node/core/types/IItemEnrichments.js +3 -0
  236. package/dist/node/core/types/IItemEnrichments.js.map +1 -0
  237. package/dist/node/core/types/index.js +18 -0
  238. package/dist/node/core/types/index.js.map +1 -0
  239. package/dist/node/index.js +12 -5
  240. package/dist/node/index.js.map +1 -1
  241. package/dist/node/items/fail-safe-update.js +3 -3
  242. package/dist/node/items/fail-safe-update.js.map +1 -1
  243. package/dist/node/items/get-model-from-options.js +3 -3
  244. package/dist/node/items/get-model-from-options.js.map +1 -1
  245. package/dist/node/items/index.js +2 -3
  246. package/dist/node/items/index.js.map +1 -1
  247. package/dist/node/items/slugs.js +99 -0
  248. package/dist/node/items/slugs.js.map +1 -0
  249. package/dist/node/models/index.js +106 -0
  250. package/dist/node/models/index.js.map +1 -0
  251. package/dist/node/{items/serialize-model.js → models/serializeModel.js} +1 -1
  252. package/dist/node/models/serializeModel.js.map +1 -0
  253. package/dist/node/projects/HubProjectManager.js +119 -0
  254. package/dist/node/projects/HubProjectManager.js.map +1 -0
  255. package/dist/node/projects/HubProjects.js +201 -0
  256. package/dist/node/projects/HubProjects.js.map +1 -0
  257. package/dist/node/projects/index.js +6 -0
  258. package/dist/node/projects/index.js.map +1 -0
  259. package/dist/node/search/_searchContent.js +17 -6
  260. package/dist/node/search/_searchContent.js.map +1 -1
  261. package/dist/node/search/_searchGroups.js +1 -11
  262. package/dist/node/search/_searchGroups.js.map +1 -1
  263. package/dist/node/search/utils.js +1 -1
  264. package/dist/node/urls/getHubApiFromPortalUrl.js +25 -0
  265. package/dist/node/urls/getHubApiFromPortalUrl.js.map +1 -0
  266. package/dist/node/urls/getPortalBaseFromOrgUrl.js +29 -0
  267. package/dist/node/urls/getPortalBaseFromOrgUrl.js.map +1 -0
  268. package/dist/node/urls/index.js +2 -0
  269. package/dist/node/urls/index.js.map +1 -1
  270. package/dist/node/utils/dasherize.js +29 -0
  271. package/dist/node/utils/dasherize.js.map +1 -0
  272. package/dist/node/utils/index.js +1 -0
  273. package/dist/node/utils/index.js.map +1 -1
  274. package/dist/types/ArcGISContext.d.ts +276 -66
  275. package/dist/types/ArcGISContextManager.d.ts +130 -0
  276. package/dist/types/Hub.d.ts +72 -0
  277. package/dist/types/HubError.d.ts +17 -0
  278. package/dist/types/collections.d.ts +12 -0
  279. package/dist/types/content/_internal.d.ts +66 -38
  280. package/dist/types/content/index.d.ts +17 -8
  281. package/dist/types/core/helpers/PropertyMapper.d.ts +69 -0
  282. package/dist/types/core/index.d.ts +2 -0
  283. package/dist/types/core/traits/WithBannerImage.d.ts +30 -0
  284. package/dist/types/core/traits/WithLayout.d.ts +54 -0
  285. package/dist/types/core/traits/WithSlug.d.ts +15 -0
  286. package/dist/types/core/traits/index.d.ts +3 -0
  287. package/dist/types/core/types/IContentEnrichments.d.ts +10 -0
  288. package/dist/types/core/types/IHubContent.d.ts +77 -0
  289. package/dist/types/core/types/IHubEntityBase.d.ts +41 -0
  290. package/dist/types/core/types/IHubEntityManager.d.ts +33 -0
  291. package/dist/types/core/types/IHubEvent.d.ts +10 -0
  292. package/dist/types/core/types/IHubImage.d.ts +25 -0
  293. package/dist/types/core/types/IHubInitiative.d.ts +8 -0
  294. package/dist/types/core/types/IHubItemEntity.d.ts +42 -0
  295. package/dist/types/core/types/IHubLayout.d.ts +20 -0
  296. package/dist/types/core/types/IHubPage.d.ts +8 -0
  297. package/dist/types/core/types/IHubProject.d.ts +15 -0
  298. package/dist/types/core/types/IHubSite.d.ts +11 -0
  299. package/dist/types/core/types/IHubTimeline.d.ts +41 -0
  300. package/dist/types/core/types/IItemEnrichments.d.ts +23 -0
  301. package/dist/types/core/types/index.d.ts +14 -0
  302. package/dist/types/index.d.ts +11 -5
  303. package/dist/types/items/index.d.ts +2 -3
  304. package/dist/types/items/slugs.d.ts +43 -0
  305. package/dist/types/models/index.d.ts +42 -0
  306. package/dist/types/{items/serialize-model.d.ts → models/serializeModel.d.ts} +0 -0
  307. package/dist/types/projects/HubProjectManager.d.ts +81 -0
  308. package/dist/types/projects/HubProjects.d.ts +31 -0
  309. package/dist/types/projects/index.d.ts +2 -0
  310. package/dist/types/search/utils.d.ts +1 -1
  311. package/dist/types/types.d.ts +2 -92
  312. package/dist/types/urls/getHubApiFromPortalUrl.d.ts +8 -0
  313. package/dist/types/urls/getPortalBaseFromOrgUrl.d.ts +9 -0
  314. package/dist/types/urls/index.d.ts +2 -0
  315. package/dist/types/utils/dasherize.d.ts +17 -0
  316. package/dist/types/utils/index.d.ts +1 -0
  317. package/dist/umd/common.umd.js +2119 -1152
  318. package/dist/umd/common.umd.js.map +1 -1
  319. package/dist/umd/common.umd.min.js +1 -1
  320. package/dist/umd/common.umd.min.js.map +1 -1
  321. package/package.json +1 -1
  322. package/dist/es2017/ArcGISContextState.js +0 -203
  323. package/dist/es2017/ArcGISContextState.js.map +0 -1
  324. package/dist/es2017/items/get-model.js +0 -19
  325. package/dist/es2017/items/get-model.js.map +0 -1
  326. package/dist/es2017/items/serialize-model.js.map +0 -1
  327. package/dist/esm/ArcGISContextState.js +0 -285
  328. package/dist/esm/ArcGISContextState.js.map +0 -1
  329. package/dist/esm/items/get-model.js +0 -19
  330. package/dist/esm/items/get-model.js.map +0 -1
  331. package/dist/esm/items/serialize-model.js.map +0 -1
  332. package/dist/node/ArcGISContextState.js +0 -207
  333. package/dist/node/ArcGISContextState.js.map +0 -1
  334. package/dist/node/items/get-model.js +0 -23
  335. package/dist/node/items/get-model.js.map +0 -1
  336. package/dist/node/items/serialize-model.js.map +0 -1
  337. package/dist/types/ArcGISContextState.d.ts +0 -129
  338. package/dist/types/items/get-model.d.ts +0 -8
@@ -1,5 +1,5 @@
1
1
  /* @preserve
2
- * @esri/hub-common - v9.13.1 - Sat Jan 22 2022 18:07:51 GMT+0000 (Coordinated Universal Time)
2
+ * @esri/hub-common - v9.15.0 - Wed Feb 16 2022 20:36:25 GMT+0000 (Coordinated Universal Time)
3
3
  * Copyright (c) 2022 Environmental Systems Research Institute, Inc.
4
4
  * Apache-2.0
5
5
  */
@@ -2988,6 +2988,31 @@
2988
2988
  }
2989
2989
  }
2990
2990
 
2991
+ /**
2992
+ * Dasherize a string
2993
+ *
2994
+ * ```javascript
2995
+ * import { dasherize } from '@esri/hub-common';
2996
+ * dasherize('innerHTML'); // 'inner-html'
2997
+ * dasherize('action_name'); // 'action-name'
2998
+ * dasherize('css-class-name'); // 'css-class-name'
2999
+ * dasherize('my favorite items'); // 'my-favorite-items'
3000
+ * dasherize('privateDocs/ownerInvoice'; // 'private-docs/owner-invoice'
3001
+ * ```
3002
+ *
3003
+ * Extracted and modified from Ember.js source code - MIT license
3004
+ * @param value
3005
+ * @returns
3006
+ */
3007
+ function dasherize(value) {
3008
+ var DECAMELIZE_REGEXP = /([a-z\d])([A-Z])/g;
3009
+ var DASHERIZE_REGEXP = /[ _]/g;
3010
+ return value
3011
+ .replace(DECAMELIZE_REGEXP, "$1_$2")
3012
+ .toLowerCase()
3013
+ .replace(DASHERIZE_REGEXP, "-");
3014
+ }
3015
+
2991
3016
  /**
2992
3017
  * Checks for fundamental privilege required by all access checks
2993
3018
  * @param {IUser} user
@@ -3255,6 +3280,76 @@
3255
3280
  });
3256
3281
  }
3257
3282
 
3283
+ /* Copyright (c) 2018 Environmental Systems Research Institute, Inc.
3284
+ * Apache-2.0 */
3285
+ /**
3286
+ * ```js
3287
+ * import { createItemInFolder } from "@esri/arcgis-rest-portal";
3288
+ * //
3289
+ * createItemInFolder({
3290
+ * item: {
3291
+ * title: "The Amazing Voyage",
3292
+ * type: "Web Map"
3293
+ * },
3294
+ * folderId: 'fe8',
3295
+ * authentication
3296
+ * })
3297
+ * ```
3298
+ * Create an item in a folder. See the [REST Documentation](https://developers.arcgis.com/rest/users-groups-and-items/add-item.htm) for more information.
3299
+ *
3300
+ * @param requestOptions = Options for the request
3301
+ */
3302
+ function createItemInFolder(requestOptions) {
3303
+ if (requestOptions.multipart && !requestOptions.filename) {
3304
+ return Promise.reject(new Error("The filename is required for a multipart request."));
3305
+ }
3306
+ return determineOwner(requestOptions).then(function (owner) {
3307
+ var baseUrl = getPortalUrl$1(requestOptions) + "/content/users/" + owner;
3308
+ var url = baseUrl + "/addItem";
3309
+ if (requestOptions.folderId) {
3310
+ url = baseUrl + "/" + requestOptions.folderId + "/addItem";
3311
+ }
3312
+ requestOptions.params = __assign(__assign({}, requestOptions.params), serializeItem(requestOptions.item));
3313
+ // serialize the item into something Portal will accept
3314
+ var options = appendCustomParams(requestOptions, [
3315
+ "owner",
3316
+ "folderId",
3317
+ "file",
3318
+ "dataUrl",
3319
+ "text",
3320
+ "async",
3321
+ "multipart",
3322
+ "filename",
3323
+ "overwrite"
3324
+ ], {
3325
+ params: __assign({}, requestOptions.params)
3326
+ });
3327
+ return request(url, options);
3328
+ });
3329
+ }
3330
+ /**
3331
+ * ```js
3332
+ * import { createItem } from "@esri/arcgis-rest-portal";
3333
+ * //
3334
+ * createItem({
3335
+ * item: {
3336
+ * title: "The Amazing Voyage",
3337
+ * type: "Web Map"
3338
+ * },
3339
+ * authentication
3340
+ * })
3341
+ * ```
3342
+ * Create an Item in the user's root folder. See the [REST Documentation](https://developers.arcgis.com/rest/users-groups-and-items/add-item.htm) for more information.
3343
+ *
3344
+ * @param requestOptions - Options for the request
3345
+ * @returns A Promise that creates an item.
3346
+ */
3347
+ function createItem(requestOptions) {
3348
+ // delegate to createItemInFolder placing in the root of the filestore
3349
+ var options = __assign({ folderId: null }, requestOptions);
3350
+ return createItemInFolder(options);
3351
+ }
3352
+
3258
3353
  /* Copyright (c) 2018 Environmental Systems Research Institute, Inc.
3259
3354
  * Apache-2.0 */
3260
3355
  /**
@@ -4976,6 +5071,52 @@
4976
5071
  return content.replace("(", "<br/>(");
4977
5072
  }
4978
5073
 
5074
+ /**
5075
+ * Cross-walk from a portalUrl to the corresponding Hub API Url
5076
+ *
5077
+ * If the passed url is not recognized, then this will return `undefined`
5078
+ * @param portalUrl
5079
+ * @returns
5080
+ */
5081
+ function getHubApiFromPortalUrl(portalUrl) {
5082
+ var result;
5083
+ if (portalUrl.match(/(qaext|\.mapsqa)\.arcgis.com/)) {
5084
+ result = "https://hubqa.arcgis.com";
5085
+ }
5086
+ else if (portalUrl.match(/(devext|\.mapsdevext)\.arcgis.com/)) {
5087
+ result = "https://hubdev.arcgis.com";
5088
+ }
5089
+ else if (portalUrl.match(/(www|\.maps)\.arcgis.com/)) {
5090
+ result = "https://hub.arcgis.com";
5091
+ }
5092
+ return result;
5093
+ }
5094
+
5095
+ /**
5096
+ * Given an org url, get the portal base url
5097
+ *
5098
+ * i.e. https://myorg.maps.arcgis.com will return https://www.arcgis.com
5099
+ *
5100
+ * @param orgUrl
5101
+ * @returns
5102
+ */
5103
+ function getPortalBaseFromOrgUrl(orgUrl) {
5104
+ var result = orgUrl;
5105
+ if (orgUrl.match(/(qaext|\.mapsqa)\.arcgis.com/)) {
5106
+ result = "https://qaext.arcgis.com";
5107
+ }
5108
+ else if (orgUrl.match(/(devext|\.mapsdevext)\.arcgis.com/)) {
5109
+ result = "https://devext.arcgis.com";
5110
+ }
5111
+ else {
5112
+ /* istanbul ignore else */
5113
+ if (orgUrl.match(/(www|\.maps)\.arcgis.com/)) {
5114
+ result = "https://www.arcgis.com";
5115
+ }
5116
+ }
5117
+ return result;
5118
+ }
5119
+
4979
5120
  var MAP_OR_FEATURE_SERVER_URL_REGEX = /\/(map|feature)server/i;
4980
5121
  /**
4981
5122
  *
@@ -5017,146 +5158,689 @@
5017
5158
  return _getHubUrlFromPortalHostname(getPortalApiUrl(urlOrObject));
5018
5159
  }
5019
5160
 
5020
- /* Copyright (c) 2018 Environmental Systems Research Institute, Inc.
5021
- * Apache-2.0 */
5022
5161
  /**
5023
- * A thin wrapper around [`UserSession.completeOAuth2()`](https://esri.github.io/arcgis-rest-js/api/auth/UserSession/#completeOAuth2) that sets search tags and other relevant metadata for newly created community users.
5162
+ * Hash of Hub API end points so updates
5163
+ * are centralized
5024
5164
  */
5025
- /* istanbul ignore next */
5026
- function completeOAuth2(options, win) {
5027
- if (win === void 0) { win = window; }
5028
- var match = win.location.href.match(/access_token=(.+)&expires_in=.+&username=([^&]+)/);
5029
- var token = match[1];
5030
- var user = decodeURIComponent(match[2]);
5031
- var baseUrl = "https://www.arcgis.com/sharing/rest/community/users/" + user;
5032
- return request(baseUrl, {
5033
- params: { token: token },
5034
- httpMethod: "GET"
5035
- }).then(function (response) {
5036
- if (Date.now() - response.created < 5000) {
5037
- return request(baseUrl + "/update", {
5038
- params: {
5039
- token: token,
5040
- tags: ["hubRole:participant", "org:" + response.orgId],
5041
- access: "public"
5042
- }
5043
- }).then(function () {
5044
- return UserSession.completeOAuth2(options);
5045
- });
5165
+ var hubApiEndpoints = {
5166
+ domains: "/api/v3/domains",
5167
+ search: "/api/v3/datasets",
5168
+ discussions: "/api/discussions/v1",
5169
+ };
5170
+ /**
5171
+ * Abstraction that holds a `UserSession`, along with
5172
+ * getters to streamline access to various platform
5173
+ * urls, and common constructs like `IRequestOptions`,
5174
+ * `IUserRequestOptions` etc.
5175
+ *
5176
+ * Instances are intended to be immutable, but this is not directly enforced.
5177
+ *
5178
+ * In most circumstances, this class should be created by
5179
+ * the ArcGISContextManager class.
5180
+ */
5181
+ var ArcGISContext = /** @class */ (function () {
5182
+ /**
5183
+ * Create a new instance of `ArcGISContext`.
5184
+ *
5185
+ * @param opts
5186
+ */
5187
+ function ArcGISContext(opts) {
5188
+ this._portalUrl = "https://www.arcgis.com";
5189
+ this.id = opts.id;
5190
+ this._portalUrl = opts.portalUrl;
5191
+ this._hubUrl = opts.hubUrl;
5192
+ if (opts.authentication) {
5193
+ this._authentication = opts.authentication;
5046
5194
  }
5047
- else {
5048
- return UserSession.completeOAuth2(options);
5195
+ if (opts.portalSelf) {
5196
+ this._portalSelf = opts.portalSelf;
5197
+ }
5198
+ if (opts.currentUser) {
5199
+ this._currentUser = opts.currentUser;
5200
+ }
5201
+ if (opts.properties) {
5202
+ this._properties = opts.properties;
5049
5203
  }
5204
+ }
5205
+ Object.defineProperty(ArcGISContext.prototype, "session", {
5206
+ /**
5207
+ * Return the UserSession if authenticated
5208
+ */
5209
+ get: function () {
5210
+ return this._authentication;
5211
+ },
5212
+ enumerable: false,
5213
+ configurable: true
5050
5214
  });
5051
- }
5052
-
5053
- var app$1 = [
5054
- "Application",
5055
- "City Engine Web Scene",
5056
- "CityEngine Web Scene",
5057
- "Dashboard",
5058
- "Insights Page",
5059
- "Insights Workbook",
5060
- "Operation View",
5061
- "Web Mapping Application",
5062
- "StoryMap",
5063
- "Web Experience",
5064
- "Urban Model",
5065
- ];
5066
- var dataset$1 = [
5067
- "CSV Collection",
5068
- "CSV",
5069
- "Feature Collection Template",
5070
- "Feature Collection",
5071
- "Feature Layer",
5072
- "Feature Service",
5073
- "File Geodatabase",
5074
- "GeoJSON",
5075
- "GeoJson",
5076
- "KML Collection",
5077
- "KML",
5078
- "Microsoft Excel",
5079
- "Raster Layer",
5080
- "Shapefile",
5081
- "Stream Service",
5082
- "Table",
5083
- ];
5084
- var document$1 = [
5085
- "CAD Drawing",
5086
- "Document Link",
5087
- "Hub Page",
5088
- "Site Page",
5089
- "Image",
5090
- "iWork Keynote",
5091
- "iWork Numbers",
5092
- "iWork Pages",
5093
- "Microsoft Powerpoint",
5094
- "Microsoft Visio",
5095
- "Microsoft Word",
5096
- "Notebook",
5097
- "PDF",
5098
- "Pro Map",
5099
- "Report Template",
5100
- ];
5101
- var event$1 = ["Hub Event"];
5102
- var feedback$1 = ["Form", "Quick Capture Project"];
5103
- var initiative$1 = ["Hub Initiative"];
5104
- var solution = ["Solution"];
5105
- var template = ["Hub Initiative Template"];
5106
- var map$1 = [
5107
- "Image Collection",
5108
- "Image Service",
5109
- "Map Service Layer",
5110
- "Map Service",
5111
- "Scene Service",
5112
- "Scene Layer",
5113
- "Vector Tile Service",
5114
- "Web Map Service",
5115
- "Web Map Tile Service",
5116
- "Web Map",
5117
- "Web Scene",
5118
- "WFS",
5119
- "WMS",
5120
- "WMTS",
5121
- ];
5122
- var other$1 = [
5123
- "360 VR Experience",
5124
- "AppBuilder Widget Package",
5125
- "Application Configuration",
5126
- "ArcPad Package",
5127
- "Code Attachment",
5128
- "Code Sample",
5129
- "Desktop Add In",
5130
- "Desktop Application Template",
5131
- "Desktop Application",
5132
- "Desktop Style",
5133
- "Explorer Add In",
5134
- "Explorer Layer",
5135
- "Geocoding Service",
5136
- "Geometry Service",
5137
- "Geoprocessing Package",
5138
- "Geoprocessing Sample",
5139
- "Geoprocessing Service",
5140
- "Layer File",
5141
- "Layer Package",
5142
- "Layer Template",
5143
- "Layer",
5144
- "Layout",
5145
- "Locator Package",
5146
- "Map Area",
5147
- "Map Document",
5148
- "Map Package",
5149
- "Map Service Definition",
5150
- "Map Template",
5151
- "Mobile Application",
5152
- "Mobile Map Package",
5153
- "Native Application",
5154
- "Network Analysis Service",
5155
- "Operations Dashboard Add In",
5156
- "Project Package",
5157
- "Project Template",
5158
- "Raster Function Template",
5159
- "Rule Package",
5215
+ Object.defineProperty(ArcGISContext.prototype, "isAuthenticated", {
5216
+ /**
5217
+ * Return boolean indicating if authenticatio is present
5218
+ */
5219
+ get: function () {
5220
+ return !!this._authentication;
5221
+ },
5222
+ enumerable: false,
5223
+ configurable: true
5224
+ });
5225
+ Object.defineProperty(ArcGISContext.prototype, "userRequestOptions", {
5226
+ /**
5227
+ * Return `IUserRequestOptions`, which is used for REST-JS
5228
+ * functions which require authentication information.
5229
+ *
5230
+ * If context is not authenticated, this function will throw
5231
+ */
5232
+ get: function () {
5233
+ if (this.isAuthenticated) {
5234
+ return {
5235
+ authentication: this._authentication,
5236
+ portal: this.sharingApiUrl,
5237
+ };
5238
+ }
5239
+ },
5240
+ enumerable: false,
5241
+ configurable: true
5242
+ });
5243
+ Object.defineProperty(ArcGISContext.prototype, "requestOptions", {
5244
+ /**
5245
+ * Return `IRequestOptions`, which is used by REST-JS functions
5246
+ * which *may* use authentication information if provided.
5247
+ *
5248
+ * If context is not authenticated, this function just returns
5249
+ * the `portal` property, which informs REST-JS what Sharing API
5250
+ * instance to use (i.e. AGO, Enterprise etc)
5251
+ */
5252
+ get: function () {
5253
+ var ro = {
5254
+ portal: this.sharingApiUrl,
5255
+ };
5256
+ if (this.isAuthenticated) {
5257
+ ro = {
5258
+ authentication: this._authentication,
5259
+ portal: this.sharingApiUrl,
5260
+ };
5261
+ }
5262
+ return ro;
5263
+ },
5264
+ enumerable: false,
5265
+ configurable: true
5266
+ });
5267
+ Object.defineProperty(ArcGISContext.prototype, "hubRequestOptions", {
5268
+ /**
5269
+ * Return a `IHubRequestOptions` object
5270
+ */
5271
+ get: function () {
5272
+ // We may add more logic around what is returned in some corner cases
5273
+ if (this.isAuthenticated) {
5274
+ return {
5275
+ authentication: this.session,
5276
+ isPortal: this.isPortal,
5277
+ portalSelf: this.portal,
5278
+ hubApiUrl: this.hubUrl,
5279
+ };
5280
+ }
5281
+ },
5282
+ enumerable: false,
5283
+ configurable: true
5284
+ });
5285
+ Object.defineProperty(ArcGISContext.prototype, "portalUrl", {
5286
+ /**
5287
+ * Return the portal url i.e. https://www.arcgis.com
5288
+ *
5289
+ * If authenticated @ ArcGIS Online, it will return
5290
+ * the https://org.env.arcgis.com
5291
+ *
5292
+ * If authenticated @ ArcGIS Enterprise, it will return
5293
+ * https://{portalHostname}/{webadaptor}
5294
+ */
5295
+ get: function () {
5296
+ if (this.isAuthenticated) {
5297
+ if (this.isPortal) {
5298
+ return "https://" + this._portalSelf.portalHostname;
5299
+ }
5300
+ else {
5301
+ return "https://" + this._portalSelf.urlKey + "." + this._portalSelf.customBaseUrl;
5302
+ }
5303
+ }
5304
+ else {
5305
+ return this._portalUrl;
5306
+ }
5307
+ },
5308
+ enumerable: false,
5309
+ configurable: true
5310
+ });
5311
+ Object.defineProperty(ArcGISContext.prototype, "sharingApiUrl", {
5312
+ /**
5313
+ * Returns the url to the sharing api composed from portalUrl
5314
+ * i.e. https://myorg.maps.arcgis.com/sharing/rest
5315
+ */
5316
+ get: function () {
5317
+ return this.portalUrl + "/sharing/rest";
5318
+ },
5319
+ enumerable: false,
5320
+ configurable: true
5321
+ });
5322
+ Object.defineProperty(ArcGISContext.prototype, "hubUrl", {
5323
+ /**
5324
+ * Returns the Hub url, based on the portalUrl
5325
+ *
5326
+ * For ArcGIS Enterprise this will return `undefined`
5327
+ */
5328
+ get: function () {
5329
+ return this._hubUrl;
5330
+ },
5331
+ enumerable: false,
5332
+ configurable: true
5333
+ });
5334
+ Object.defineProperty(ArcGISContext.prototype, "isPortal", {
5335
+ /**
5336
+ * Returns boolean indicating if the backing system
5337
+ * is ArcGIS Enterprise (formerly ArcGIS Portal) or not
5338
+ */
5339
+ get: function () {
5340
+ return this._portalSelf
5341
+ ? this._portalSelf.isPortal
5342
+ : this._portalUrl.indexOf("arcgis.com") === -1;
5343
+ },
5344
+ enumerable: false,
5345
+ configurable: true
5346
+ });
5347
+ Object.defineProperty(ArcGISContext.prototype, "discussionsServiceUrl", {
5348
+ /**
5349
+ * Returns the discussions API URL
5350
+ */
5351
+ get: function () {
5352
+ if (this._hubUrl) {
5353
+ return "" + this._hubUrl + hubApiEndpoints.discussions;
5354
+ }
5355
+ },
5356
+ enumerable: false,
5357
+ configurable: true
5358
+ });
5359
+ Object.defineProperty(ArcGISContext.prototype, "hubSearchServiceUrl", {
5360
+ /**
5361
+ * Returns the Hub Search API URL
5362
+ */
5363
+ get: function () {
5364
+ if (this._hubUrl) {
5365
+ return "" + this._hubUrl + hubApiEndpoints.search;
5366
+ }
5367
+ },
5368
+ enumerable: false,
5369
+ configurable: true
5370
+ });
5371
+ Object.defineProperty(ArcGISContext.prototype, "domainServiceUrl", {
5372
+ /**
5373
+ * Returns Hub Domain Service URL
5374
+ */
5375
+ get: function () {
5376
+ if (this._hubUrl) {
5377
+ return "" + this._hubUrl + hubApiEndpoints.domains;
5378
+ }
5379
+ },
5380
+ enumerable: false,
5381
+ configurable: true
5382
+ });
5383
+ Object.defineProperty(ArcGISContext.prototype, "eventsConfig", {
5384
+ /**
5385
+ * Returns the Events configuration object from portal/self
5386
+ *
5387
+ * `{serviceId: '3ef..', publicViewId: 'bc3...'}`
5388
+ */
5389
+ get: function () {
5390
+ if (this._portalSelf) {
5391
+ return getProp(this._portalSelf, "portalProperties.hub.settings.events");
5392
+ }
5393
+ },
5394
+ enumerable: false,
5395
+ configurable: true
5396
+ });
5397
+ Object.defineProperty(ArcGISContext.prototype, "hubEnabled", {
5398
+ /**
5399
+ * Returns boolean indicating if the current user
5400
+ * belongs to an organization that has licensed
5401
+ * ArcGIS Hub
5402
+ */
5403
+ get: function () {
5404
+ return getWithDefault$1(this._portalSelf, "portalProperties.hub.enabled", false);
5405
+ },
5406
+ enumerable: false,
5407
+ configurable: true
5408
+ });
5409
+ Object.defineProperty(ArcGISContext.prototype, "communityOrgId", {
5410
+ /**
5411
+ * Return the Hub Community Org Id, if defined
5412
+ */
5413
+ get: function () {
5414
+ if (this._portalSelf) {
5415
+ return getProp(this._portalSelf, "portalProperties.hub.settings.communityOrg.orgId");
5416
+ }
5417
+ },
5418
+ enumerable: false,
5419
+ configurable: true
5420
+ });
5421
+ Object.defineProperty(ArcGISContext.prototype, "communityOrgHostname", {
5422
+ /**
5423
+ * Returns the Hub Community Org Hostname, if defined
5424
+ *
5425
+ * i.e. c-org.maps.arcgis.com
5426
+ */
5427
+ get: function () {
5428
+ if (this._portalSelf) {
5429
+ return getProp(this._portalSelf, "portalProperties.hub.settings.communityOrg.portalHostname");
5430
+ }
5431
+ },
5432
+ enumerable: false,
5433
+ configurable: true
5434
+ });
5435
+ Object.defineProperty(ArcGISContext.prototype, "communityOrgUrl", {
5436
+ /**
5437
+ * Returns the Hub Community Org url
5438
+ *
5439
+ * i.e. https://c-org.maps.arcgis.com
5440
+ */
5441
+ get: function () {
5442
+ if (this.communityOrgHostname) {
5443
+ return "https://" + this.communityOrgHostname;
5444
+ }
5445
+ },
5446
+ enumerable: false,
5447
+ configurable: true
5448
+ });
5449
+ Object.defineProperty(ArcGISContext.prototype, "helperServices", {
5450
+ /**
5451
+ * Returns the hash of helper services from portal self
5452
+ */
5453
+ get: function () {
5454
+ if (this._portalSelf) {
5455
+ return this._portalSelf.helperServices;
5456
+ }
5457
+ },
5458
+ enumerable: false,
5459
+ configurable: true
5460
+ });
5461
+ Object.defineProperty(ArcGISContext.prototype, "currentUser", {
5462
+ /**
5463
+ * Returns the current user as IUser
5464
+ */
5465
+ get: function () {
5466
+ return this._currentUser;
5467
+ },
5468
+ enumerable: false,
5469
+ configurable: true
5470
+ });
5471
+ Object.defineProperty(ArcGISContext.prototype, "portal", {
5472
+ /**
5473
+ * Returns the portal object as IPortal
5474
+ */
5475
+ get: function () {
5476
+ return this._portalSelf;
5477
+ },
5478
+ enumerable: false,
5479
+ configurable: true
5480
+ });
5481
+ Object.defineProperty(ArcGISContext.prototype, "properties", {
5482
+ /**
5483
+ * Return the properties hash that was passed in.
5484
+ * Useful for app-specific context such as the active
5485
+ * Site for ArcGIS Hub
5486
+ */
5487
+ get: function () {
5488
+ return this._properties;
5489
+ },
5490
+ enumerable: false,
5491
+ configurable: true
5492
+ });
5493
+ return ArcGISContext;
5494
+ }());
5495
+
5496
+ /**
5497
+ * The manager exposes context (`IArcGISContext`), which combines a `UserSession` with
5498
+ * the `portal/self` and `user/self` responses to provide a central lookup for platform
5499
+ * information, api urls, and other useful properties for developers such as IRequestOptions
5500
+ * IUserRequestOptions, IHubRequestOptions etc.
5501
+ *
5502
+ * The context is exposed on gthe `.context` property, and as the authentication changes
5503
+ * the `.context` is re-created. This is done to allow web frameworks to watch for
5504
+ * changes on that single property, instead of having to leverage observers or events
5505
+ * for change detection.
5506
+ *
5507
+ * Please see the [ArcGISContext Guide](/hub.js/guides/context) for additional information.
5508
+ *
5509
+ */
5510
+ var ArcGISContextManager = /** @class */ (function () {
5511
+ /**
5512
+ * Private constructor. Use `ArcGISContextManager.create(...)` to
5513
+ * instantiate an instance
5514
+ * @param opts
5515
+ */
5516
+ function ArcGISContextManager(opts) {
5517
+ this._portalUrl = "https://www.arcgis.com";
5518
+ this._logLevel = exports.Level.error;
5519
+ // Having a unique id makes debugging easier
5520
+ this.id = new Date().getTime();
5521
+ if (opts.logLevel) {
5522
+ this._logLevel = opts.logLevel;
5523
+ }
5524
+ Logger.setLogLevel(this._logLevel);
5525
+ Logger.debug("ArcGISContextManager:ctor: Creating " + this.id);
5526
+ if (opts.properties) {
5527
+ this._properties = opts.properties;
5528
+ }
5529
+ if (opts.authentication) {
5530
+ this._authentication = opts.authentication;
5531
+ this._portalUrl = this._authentication.portal.replace("/sharing/rest", "");
5532
+ this._hubUrl = getHubApiFromPortalUrl(this._portalUrl);
5533
+ }
5534
+ else if (opts.portalUrl) {
5535
+ this._portalUrl = opts.portalUrl;
5536
+ this._hubUrl = getHubApiFromPortalUrl(this._portalUrl);
5537
+ }
5538
+ else {
5539
+ this._hubUrl = getHubApiFromPortalUrl(this._portalUrl);
5540
+ }
5541
+ if (opts.portal) {
5542
+ this._portalSelf = cloneObject$1(opts.portal);
5543
+ }
5544
+ if (opts.currentUser) {
5545
+ this._currentUser = cloneObject$1(opts.currentUser);
5546
+ }
5547
+ }
5548
+ /**
5549
+ * Used to create a new instance of the ArcGISContext class.
5550
+ *
5551
+ * ```js
5552
+ * const ctxMgr = await ArcGISContextManager.create();
5553
+ * ```
5554
+ *
5555
+ * @param opts
5556
+ * @returns
5557
+ */
5558
+ ArcGISContextManager.create = function (opts) {
5559
+ if (opts === void 0) { opts = {}; }
5560
+ return __awaiter(this, void 0, void 0, function () {
5561
+ var ctx;
5562
+ return __generator(this, function (_a) {
5563
+ switch (_a.label) {
5564
+ case 0:
5565
+ ctx = new ArcGISContextManager(opts);
5566
+ return [4 /*yield*/, ctx.initialize()];
5567
+ case 1:
5568
+ _a.sent();
5569
+ return [2 /*return*/, ctx];
5570
+ }
5571
+ });
5572
+ });
5573
+ };
5574
+ /**
5575
+ * Set the Authentication (UserSession) for the context.
5576
+ * This should be called when a user signs into a running
5577
+ * application.
5578
+ * @param auth
5579
+ */
5580
+ ArcGISContextManager.prototype.setAuthentication = function (auth) {
5581
+ return __awaiter(this, void 0, void 0, function () {
5582
+ return __generator(this, function (_a) {
5583
+ switch (_a.label) {
5584
+ case 0:
5585
+ this._authentication = auth;
5586
+ this._portalUrl = auth.portal.replace("/sharing/rest", "");
5587
+ return [4 /*yield*/, this.initialize()];
5588
+ case 1:
5589
+ _a.sent();
5590
+ return [2 /*return*/];
5591
+ }
5592
+ });
5593
+ });
5594
+ };
5595
+ /**
5596
+ * Set the properties hash and re-create the context
5597
+ * @param properties
5598
+ */
5599
+ ArcGISContextManager.prototype.setProperties = function (properties) {
5600
+ this._properties = properties;
5601
+ this._context = new ArcGISContext(this.contextOpts);
5602
+ };
5603
+ /**
5604
+ * Clear the Authentication (UserSession). This should be
5605
+ * called when a user signs out of an application, but
5606
+ * the application continues running
5607
+ */
5608
+ ArcGISContextManager.prototype.clearAuthentication = function () {
5609
+ // Reset the portalUrl from the org url to the base url
5610
+ // for ArcGIS Enterprise, we just leave the _portalUrl as-is
5611
+ if (!this._context.isPortal) {
5612
+ this._portalUrl = getPortalBaseFromOrgUrl(this._portalUrl);
5613
+ }
5614
+ // Clear the auth, portalSelf and currentUser props
5615
+ this._authentication = null;
5616
+ this._portalSelf = null;
5617
+ this._currentUser = null;
5618
+ this._context = new ArcGISContext(this.contextOpts);
5619
+ };
5620
+ Object.defineProperty(ArcGISContextManager.prototype, "context", {
5621
+ /**
5622
+ * Return a reference to the current state.
5623
+ * When `.setAuthentication()` or `.clearAuthenentication()` are
5624
+ * called, the state will be re-created. This is done so frameworks
5625
+ * like React or Ember can detect changes.
5626
+ */
5627
+ get: function () {
5628
+ return this._context;
5629
+ },
5630
+ enumerable: false,
5631
+ configurable: true
5632
+ });
5633
+ /**
5634
+ * If we have a UserSession, fetch portal/self and
5635
+ * store that along with current user
5636
+ */
5637
+ ArcGISContextManager.prototype.initialize = function () {
5638
+ return __awaiter(this, void 0, void 0, function () {
5639
+ var username, requests, _a, portal, user, ex_1, msg;
5640
+ return __generator(this, function (_b) {
5641
+ switch (_b.label) {
5642
+ case 0:
5643
+ if (!(this._authentication && (!this._portalSelf || !this._currentUser))) return [3 /*break*/, 4];
5644
+ Logger.debug("ArcGISContextManager-" + this.id + ": Initializing");
5645
+ username = this._authentication.username;
5646
+ requests = [
5647
+ getSelf({ authentication: this._authentication }),
5648
+ getUser({ username: username, authentication: this._authentication }),
5649
+ ];
5650
+ _b.label = 1;
5651
+ case 1:
5652
+ _b.trys.push([1, 3, , 4]);
5653
+ return [4 /*yield*/, Promise.all(requests)];
5654
+ case 2:
5655
+ _a = _b.sent(), portal = _a[0], user = _a[1];
5656
+ this._portalSelf = portal;
5657
+ this._currentUser = user;
5658
+ Logger.debug("ArcGISContextManager-" + this.id + ": received portalSelf and currentUser");
5659
+ return [3 /*break*/, 4];
5660
+ case 3:
5661
+ ex_1 = _b.sent();
5662
+ msg = "ArcGISContextManager could not fetch portal & user for \"" + this._authentication.username + "\" using " + this._authentication.portal + ".";
5663
+ Logger.error(msg);
5664
+ // tslint:disable-next-line:no-console
5665
+ console.error(msg);
5666
+ throw ex_1;
5667
+ case 4:
5668
+ Logger.debug("ArcGISContextManager-" + this.id + ": updating context");
5669
+ // update the context
5670
+ this._context = new ArcGISContext(this.contextOpts);
5671
+ return [2 /*return*/];
5672
+ }
5673
+ });
5674
+ });
5675
+ };
5676
+ Object.defineProperty(ArcGISContextManager.prototype, "contextOpts", {
5677
+ /**
5678
+ * Getter to streamline the creation of updated Context instances
5679
+ */
5680
+ get: function () {
5681
+ var contextOpts = {
5682
+ id: this.id,
5683
+ portalUrl: this._portalUrl,
5684
+ hubUrl: this._hubUrl,
5685
+ properties: this._properties,
5686
+ };
5687
+ if (this._authentication) {
5688
+ contextOpts.authentication = this._authentication;
5689
+ }
5690
+ if (this._portalSelf) {
5691
+ contextOpts.portalSelf = this._portalSelf;
5692
+ }
5693
+ if (this._currentUser) {
5694
+ contextOpts.currentUser = this._currentUser;
5695
+ }
5696
+ return contextOpts;
5697
+ },
5698
+ enumerable: false,
5699
+ configurable: true
5700
+ });
5701
+ return ArcGISContextManager;
5702
+ }());
5703
+
5704
+ /* Copyright (c) 2018 Environmental Systems Research Institute, Inc.
5705
+ * Apache-2.0 */
5706
+ /**
5707
+ * A thin wrapper around [`UserSession.completeOAuth2()`](https://esri.github.io/arcgis-rest-js/api/auth/UserSession/#completeOAuth2) that sets search tags and other relevant metadata for newly created community users.
5708
+ */
5709
+ /* istanbul ignore next */
5710
+ function completeOAuth2(options, win) {
5711
+ if (win === void 0) { win = window; }
5712
+ var match = win.location.href.match(/access_token=(.+)&expires_in=.+&username=([^&]+)/);
5713
+ var token = match[1];
5714
+ var user = decodeURIComponent(match[2]);
5715
+ var baseUrl = "https://www.arcgis.com/sharing/rest/community/users/" + user;
5716
+ return request(baseUrl, {
5717
+ params: { token: token },
5718
+ httpMethod: "GET"
5719
+ }).then(function (response) {
5720
+ if (Date.now() - response.created < 5000) {
5721
+ return request(baseUrl + "/update", {
5722
+ params: {
5723
+ token: token,
5724
+ tags: ["hubRole:participant", "org:" + response.orgId],
5725
+ access: "public"
5726
+ }
5727
+ }).then(function () {
5728
+ return UserSession.completeOAuth2(options);
5729
+ });
5730
+ }
5731
+ else {
5732
+ return UserSession.completeOAuth2(options);
5733
+ }
5734
+ });
5735
+ }
5736
+
5737
+ var app$1 = [
5738
+ "Application",
5739
+ "City Engine Web Scene",
5740
+ "CityEngine Web Scene",
5741
+ "Dashboard",
5742
+ "Insights Page",
5743
+ "Insights Workbook",
5744
+ "Operation View",
5745
+ "Web Mapping Application",
5746
+ "StoryMap",
5747
+ "Web Experience",
5748
+ "Urban Model",
5749
+ ];
5750
+ var dataset$1 = [
5751
+ "CSV Collection",
5752
+ "CSV",
5753
+ "Feature Collection Template",
5754
+ "Feature Collection",
5755
+ "Feature Layer",
5756
+ "Feature Service",
5757
+ "File Geodatabase",
5758
+ "GeoJSON",
5759
+ "GeoJson",
5760
+ "KML Collection",
5761
+ "KML",
5762
+ "Microsoft Excel",
5763
+ "Raster Layer",
5764
+ "Shapefile",
5765
+ "Stream Service",
5766
+ "Table",
5767
+ ];
5768
+ var document$1 = [
5769
+ "CAD Drawing",
5770
+ "Document Link",
5771
+ "Hub Page",
5772
+ "Site Page",
5773
+ "Image",
5774
+ "iWork Keynote",
5775
+ "iWork Numbers",
5776
+ "iWork Pages",
5777
+ "Microsoft Powerpoint",
5778
+ "Microsoft Visio",
5779
+ "Microsoft Word",
5780
+ "Notebook",
5781
+ "PDF",
5782
+ "Pro Map",
5783
+ "Report Template",
5784
+ ];
5785
+ var event$1 = ["Hub Event"];
5786
+ var feedback$1 = ["Form", "Quick Capture Project"];
5787
+ var initiative$1 = ["Hub Initiative"];
5788
+ var solution = ["Solution"];
5789
+ var template = ["Hub Initiative Template"];
5790
+ var map$1 = [
5791
+ "Image Collection",
5792
+ "Image Service",
5793
+ "Map Service Layer",
5794
+ "Map Service",
5795
+ "Scene Service",
5796
+ "Scene Layer",
5797
+ "Vector Tile Service",
5798
+ "Web Map Service",
5799
+ "Web Map Tile Service",
5800
+ "Web Map",
5801
+ "Web Scene",
5802
+ "WFS",
5803
+ "WMS",
5804
+ "WMTS",
5805
+ ];
5806
+ var other$1 = [
5807
+ "360 VR Experience",
5808
+ "AppBuilder Widget Package",
5809
+ "Application Configuration",
5810
+ "ArcPad Package",
5811
+ "Code Attachment",
5812
+ "Code Sample",
5813
+ "Desktop Add In",
5814
+ "Desktop Application Template",
5815
+ "Desktop Application",
5816
+ "Desktop Style",
5817
+ "Explorer Add In",
5818
+ "Explorer Layer",
5819
+ "Geocoding Service",
5820
+ "Geometry Service",
5821
+ "Geoprocessing Package",
5822
+ "Geoprocessing Sample",
5823
+ "Geoprocessing Service",
5824
+ "Layer File",
5825
+ "Layer Package",
5826
+ "Layer Template",
5827
+ "Layer",
5828
+ "Layout",
5829
+ "Locator Package",
5830
+ "Map Area",
5831
+ "Map Document",
5832
+ "Map Package",
5833
+ "Map Service Definition",
5834
+ "Map Template",
5835
+ "Mobile Application",
5836
+ "Mobile Map Package",
5837
+ "Native Application",
5838
+ "Network Analysis Service",
5839
+ "Operations Dashboard Add In",
5840
+ "Project Package",
5841
+ "Project Template",
5842
+ "Raster Function Template",
5843
+ "Rule Package",
5160
5844
  "Scene Package",
5161
5845
  "Service Definition",
5162
5846
  "SQLite Geodatabase",
@@ -5166,6 +5850,8 @@
5166
5850
  "Workflow Manager Package",
5167
5851
  ];
5168
5852
  var site$1 = ["Hub Site Application", "Site Application"];
5853
+ // TODO: remove this at the next breaking change
5854
+ // it's only here to support deprecated categories
5169
5855
  var collections = {
5170
5856
  app: app$1,
5171
5857
  dataset: dataset$1,
@@ -5742,7 +6428,22 @@
5742
6428
  geometry: geometry,
5743
6429
  };
5744
6430
  };
6431
+ var MAX_SIZE = 5000000;
6432
+ /**
6433
+ * Returns whether or not an item is a proxied csv
6434
+ *
6435
+ * @param item
6436
+ * @param requestOptions Hub Request Options (including whether we're in portal)
6437
+ * @returns
6438
+ */
6439
+ var isProxiedCSV = function (item, requestOptions) {
6440
+ return !requestOptions.isPortal &&
6441
+ item.access === "public" &&
6442
+ item.type === "CSV" &&
6443
+ item.size <= MAX_SIZE;
6444
+ };
5745
6445
 
6446
+ // private helper functions
5746
6447
  function collectionToFamily(collection) {
5747
6448
  var overrides = {
5748
6449
  other: "content",
@@ -6349,7 +7050,7 @@
6349
7050
  }
6350
7051
  /**
6351
7052
  * returns a new content that has the specified type and
6352
- * and updated related properties like normalizedType, family, etc
7053
+ * and updated related properties like, family, etc
6353
7054
  * @param content orignal content
6354
7055
  * @param type new type
6355
7056
  * @returns new content
@@ -6360,9 +7061,8 @@
6360
7061
  var family = getFamily(normalizedType);
6361
7062
  var contentTypeIcon = getContentTypeIcon(normalizedType);
6362
7063
  var contentTypeLabel = getContentTypeLabel(normalizedType, content.isProxied);
6363
- // TODO: don't we need to update content.item.type too?
6364
- var updated = __assign(__assign({}, content), { type: type,
6365
- family: family,
7064
+ var updated = __assign(__assign({}, content), { type: normalizedType, family: family,
7065
+ // TODO: remove this at next breaking change now that it has been deprecated
6366
7066
  normalizedType: normalizedType,
6367
7067
  contentTypeIcon: contentTypeIcon,
6368
7068
  contentTypeLabel: contentTypeLabel });
@@ -6373,23 +7073,26 @@
6373
7073
  });
6374
7074
  };
6375
7075
  /**
6376
- * Compute the content type icon based on the normalizedType
6377
- * @param normalizedType
7076
+ * Compute the content type icon based on the content type
7077
+ * @param content type
6378
7078
  * @returns content type icon
6379
7079
  */
6380
- var getContentTypeIcon = function (normalizedType) {
7080
+ var getContentTypeIcon = function (contentType) {
6381
7081
  var _a;
6382
- var type = camelize(normalizedType || "");
7082
+ var type = camelize(contentType || "");
6383
7083
  var iconMap = {
6384
7084
  appbuilderExtension: "file",
6385
7085
  appbuilderWidgetPackage: "widgets-source",
6386
7086
  application: "web",
7087
+ applicationConfiguration: "app-gear",
6387
7088
  arcgisProMap: "desktop",
6388
7089
  cadDrawing: "file-cad",
6389
7090
  cityEngineWebScene: "urban-model",
6390
7091
  codeAttachment: "file-code",
7092
+ codeSample: "file-code",
6391
7093
  colorSet: "palette",
6392
7094
  contentCategorySet: "label",
7095
+ csv: "file-csv",
6393
7096
  cSV: "file-csv",
6394
7097
  cSVCollection: "file-csv",
6395
7098
  dashboard: "dashboard",
@@ -6411,8 +7114,8 @@
6411
7114
  geoprocessingService: "file",
6412
7115
  globeLayer: "layers",
6413
7116
  globeService: "file",
6414
- hubInitiative: "mountain-summit-nocap",
6415
- hubInitiativeTemplate: "initiative-template-outlines-thick",
7117
+ hubInitiative: "initiative",
7118
+ hubInitiativeTemplate: "initiative-template",
6416
7119
  hubPage: "browser",
6417
7120
  hubSiteApplication: "web",
6418
7121
  image: "file-image",
@@ -6428,6 +7131,7 @@
6428
7131
  kMLCollection: "data",
6429
7132
  layer: "layers",
6430
7133
  layerPackage: "layers",
7134
+ layerTemplate: "file",
6431
7135
  locatorPackage: "file",
6432
7136
  mapArea: "file",
6433
7137
  mapDocument: "map-contents",
@@ -6450,6 +7154,7 @@
6450
7154
  orthoMappingTemplate: "file",
6451
7155
  pDF: "file-pdf",
6452
7156
  quickCaptureProject: "mobile",
7157
+ rasterFunctionTemplate: "file",
6453
7158
  rasterLayer: "map",
6454
7159
  realTimeAnalytic: "file",
6455
7160
  relationalDatabaseConnection: "file",
@@ -6458,19 +7163,23 @@
6458
7163
  sceneService: "urban-model",
6459
7164
  serviceDefinition: "file",
6460
7165
  shapefile: "data",
6461
- solution: "solutions",
7166
+ solution: "puzzle-piece",
6462
7167
  sqliteGeodatabase: "file",
6463
7168
  statisticalDataCollection: "file",
7169
+ storymap: "tour",
6464
7170
  storyMap: "tour",
7171
+ storymapTheme: "palette",
6465
7172
  symbolSet: "file",
6466
7173
  table: "table",
6467
7174
  urbanModel: "urban-model",
7175
+ vectorTilePackage: "file-shape",
6468
7176
  vectorTileService: "map",
6469
7177
  visioDocument: "conditional-rules",
6470
7178
  webExperience: "apps",
6471
7179
  webMap: "map",
6472
7180
  webMappingApplication: "apps",
6473
7181
  webScene: "urban-model",
7182
+ wfs: "map",
6474
7183
  wFS: "map",
6475
7184
  wMS: "map",
6476
7185
  wMTS: "map",
@@ -6481,12 +7190,12 @@
6481
7190
  };
6482
7191
  /**
6483
7192
  * Compute the content type label
6484
- * @param normalizedType
7193
+ * @param contentType
6485
7194
  * @param isProxied
6486
7195
  * @returns content type label
6487
7196
  */
6488
- var getContentTypeLabel = function (normalizedType, isProxied) {
6489
- return isProxied ? "CSV" : camelize(normalizedType || "");
7197
+ var getContentTypeLabel = function (contentType, isProxied) {
7198
+ return isProxied ? "CSV" : camelize(contentType || "");
6490
7199
  };
6491
7200
  /**
6492
7201
  * returns a new content that has the specified hubId and updated identifier
@@ -6579,8 +7288,8 @@
6579
7288
  var getSolutionUrl = function (content) {
6580
7289
  var _a;
6581
7290
  var hubUrl;
6582
- var normalizedType = content.normalizedType, identifier = content.identifier;
6583
- if (normalizedType === "Solution") {
7291
+ var type = content.type, identifier = content.identifier;
7292
+ if (type === "Solution") {
6584
7293
  // NOTE: as per the above spreadsheet,
6585
7294
  // solution types are now in the Template family
6586
7295
  // but we don't send them to the route for initiative templates
@@ -6597,10 +7306,25 @@
6597
7306
  // TODO: we check both "Hub Page" and "Site Page" because we don't know whether the site is a portal or not
6598
7307
  // In the future, the site object will have a site.isPortal() function that we can leverage
6599
7308
  // instead of hardcoding the types here.
6600
- // TODO: should this be based on normalizedType instead?
6601
7309
  var isPageContent = function (content) {
6602
7310
  return includes(["Hub Page", "Site Page"], content.type);
6603
7311
  };
7312
+ // proxied csv helpers
7313
+ /**
7314
+ * If an item is a proxied csv, returns the url for the proxying feature layer.
7315
+ * If the item is not a proxied csv, returns undefined.
7316
+ *
7317
+ * @param item
7318
+ * @param requestOptions Hub Request Options (including whether we're in portal)
7319
+ * @returns
7320
+ */
7321
+ var getProxyUrl = function (item, requestOptions) {
7322
+ var result;
7323
+ if (isProxiedCSV(item, requestOptions)) {
7324
+ result = requestOptions.hubApiUrl + "/datasets/" + item.id + "_0/FeatureServer/0";
7325
+ }
7326
+ return result;
7327
+ };
6604
7328
 
6605
7329
  /**
6606
7330
  * Implementation of atob() according to the HTML and Infra specs, except that
@@ -7273,6 +7997,111 @@
7273
7997
  .then(_consolidateResults);
7274
7998
  }
7275
7999
 
8000
+ /**
8001
+ * Locales supported by the hub
8002
+ */
8003
+ var HUB_LOCALES = [
8004
+ "ar",
8005
+ "bs",
8006
+ "ca",
8007
+ "cs",
8008
+ "da",
8009
+ "de",
8010
+ "en",
8011
+ "es",
8012
+ "et",
8013
+ "el",
8014
+ "fi",
8015
+ "fr",
8016
+ "hr",
8017
+ "he",
8018
+ "hu",
8019
+ "it",
8020
+ "id",
8021
+ "ja",
8022
+ "ko",
8023
+ "lt",
8024
+ "lv",
8025
+ "nb",
8026
+ "nl",
8027
+ "pl",
8028
+ "pt",
8029
+ "pt-br",
8030
+ "pt-pt",
8031
+ "ro",
8032
+ "ru",
8033
+ "sl",
8034
+ "sr",
8035
+ "sv",
8036
+ "th",
8037
+ "tr",
8038
+ "uk",
8039
+ "vi",
8040
+ "zh",
8041
+ "zh-cn",
8042
+ "zh-tw",
8043
+ "zh-hk"
8044
+ ];
8045
+
8046
+ /**
8047
+ * Convert a requested locale into a locale we support.
8048
+ * i.e. en-ca => en
8049
+ * If the requested locale is not available, en will be returned
8050
+ * @param {string} requestedLocale Locale we want
8051
+ */
8052
+ function convertToWellKnownLocale(requestedLocale) {
8053
+ if (requestedLocale === void 0) { requestedLocale = "en"; }
8054
+ var wellKnownKey = "en";
8055
+ // ensure downcase
8056
+ requestedLocale = requestedLocale.toLowerCase();
8057
+ // see if it's in the hub translations as-is
8058
+ if (HUB_LOCALES.indexOf(requestedLocale) > -1) {
8059
+ wellKnownKey = requestedLocale;
8060
+ }
8061
+ else {
8062
+ // if we split the requested locale, see if we have the root in the list
8063
+ var parts = requestedLocale.split("-");
8064
+ if (parts.length > 1 && HUB_LOCALES.indexOf(parts[0]) > -1) {
8065
+ wellKnownKey = parts[0];
8066
+ }
8067
+ }
8068
+ return wellKnownKey;
8069
+ }
8070
+
8071
+ /**
8072
+ * Fetch the Hub translation file for a given locale
8073
+ * These are all public urls and should never require auth/tokens etc
8074
+ * @param {String} locale Locale code - i.e. `es`
8075
+ * @param {Object} portal Portal Self
8076
+ */
8077
+ function fetchHubTranslation(locale, portal, mode) {
8078
+ if (mode === void 0) { mode = "cors"; }
8079
+ var assetBase = getHubLocaleAssetUrl(portal);
8080
+ var url = (assetBase + "/locales/" + locale + ".json").toLocaleLowerCase();
8081
+ // to support web-tier auth, we must always send same-origin credentials
8082
+ var options = {
8083
+ method: "GET",
8084
+ credentials: "same-origin",
8085
+ mode: mode
8086
+ };
8087
+ return fetch(url, options)
8088
+ .then(function (response) { return response.json(); })
8089
+ .catch(function (err) {
8090
+ throw Error("Attempt to fetch locale " + locale + " from " + url + " failed: " + JSON.stringify(err));
8091
+ });
8092
+ }
8093
+
8094
+ /**
8095
+ * Return the culture from the Hub Request Options
8096
+ * In priority order: user.culture, portal.culture, en-us
8097
+ * @param {IHubRequestOptions} hubRequestOptions
8098
+ */
8099
+ function getCulture(hubRequestOptions) {
8100
+ return (getProp(hubRequestOptions, "portalSelf.user.culture") ||
8101
+ getProp(hubRequestOptions, "portalSelf.culture") ||
8102
+ "en-us");
8103
+ }
8104
+
7276
8105
  /**
7277
8106
  * Unprotect and Remove an Item
7278
8107
  * Assumes caller has checked that the curernt user should be able to
@@ -7346,29 +8175,106 @@
7346
8175
  function failSafeUpdate(model, requestOptions) {
7347
8176
  var failSafedUpdate = failSafe(updateItem, {
7348
8177
  id: model.item.id,
7349
- success: true
8178
+ success: true,
7350
8179
  });
7351
8180
  var opts = Object.assign({ item: serializeModel(model) }, requestOptions);
7352
8181
  return failSafedUpdate(opts);
7353
8182
  }
7354
8183
 
7355
8184
  /**
7356
- * Gets the full item/data model for an item
7357
- * @param {string} id Id of the item to fetch
8185
+ * Gets the full item/data model for an item id
8186
+ * @param {string} id
7358
8187
  * @param {Object} requestOptions
7359
8188
  */
7360
8189
  function getModel(id, requestOptions) {
7361
8190
  return Promise.all([
7362
8191
  getItem(id, requestOptions),
7363
- getItemData(id, requestOptions)
8192
+ getItemData(id, requestOptions),
7364
8193
  ]).then(function (result) {
7365
8194
  // shape this into a model
7366
8195
  return {
7367
8196
  item: result[0],
7368
- data: result[1]
8197
+ data: result[1],
7369
8198
  };
7370
8199
  });
7371
8200
  }
8201
+ /**
8202
+ * Get a model by it's slug
8203
+ *
8204
+ * This uses the [Filter](https://developers.arcgis.com/rest/users-groups-and-items/search-reference.htm) option of the
8205
+ * to search for an item that has a typekeyword of `slug|{slug-value}`
8206
+ *
8207
+ * This is useful for applications that want to use human-readable urls instead
8208
+ * of using item ids.
8209
+ *
8210
+ * @param slug
8211
+ * @param requestOptions
8212
+ * @returns
8213
+ */
8214
+ function getModelBySlug(slug, requestOptions) {
8215
+ return getItemBySlug(slug, requestOptions)
8216
+ .then(function (item) {
8217
+ var prms = [Promise.resolve(item)];
8218
+ if (item) {
8219
+ prms.push(getItemData(item.id, requestOptions));
8220
+ }
8221
+ else {
8222
+ prms.push(Promise.resolve(null));
8223
+ }
8224
+ return Promise.all(prms);
8225
+ })
8226
+ .then(function (result) {
8227
+ if (result[0]) {
8228
+ return {
8229
+ item: result[0],
8230
+ data: result[1],
8231
+ };
8232
+ }
8233
+ else {
8234
+ return null;
8235
+ }
8236
+ });
8237
+ }
8238
+ /**
8239
+ * Create an item to back and IModel.
8240
+ *
8241
+ * @param {IModel}
8242
+ * @param {IRequestOptions} requestOptions
8243
+ * @returns {Promise<IModel>}
8244
+ */
8245
+ function createModel(model, requestOptions) {
8246
+ var clone = cloneObject$1(model);
8247
+ var item = cloneObject$1(model.item);
8248
+ item.data = cloneObject$1(model.data);
8249
+ var opts = __assign({ item: item }, requestOptions);
8250
+ return createItem(opts).then(function (response) {
8251
+ clone.item.id = response.id;
8252
+ clone.item.created = new Date().getTime();
8253
+ clone.item.modified = clone.item.created;
8254
+ return clone;
8255
+ });
8256
+ }
8257
+ /**
8258
+ * Update an IModel. Generic function that will be used across all
8259
+ * type-specific update functions
8260
+ *
8261
+ * @export
8262
+ * @param {IModel} "model" object (i.e. `{item:{...}, data:{...}}`)
8263
+ * @param {IRequestOptions} requestOptions
8264
+ * @returns {Promise<IModel>}
8265
+ */
8266
+ function updateModel(model, requestOptions) {
8267
+ var clone = cloneObject$1(model);
8268
+ var item = cloneObject$1(model.item);
8269
+ item.data = cloneObject$1(model.data);
8270
+ var opts = __assign({ item: item }, requestOptions);
8271
+ return updateItem(opts).then(function () {
8272
+ // update the modified prop
8273
+ // this won't be exact, but it will be very close
8274
+ clone.item.modified = new Date().getTime();
8275
+ return clone;
8276
+ });
8277
+ }
7372
8278
 
7373
8279
  /**
7374
8280
  * To streamline passing of either a model id or the model itself, we use this function
@@ -7389,7 +8295,7 @@
7389
8295
  if (options[idProp]) {
7390
8296
  var failSafeModel = failSafe(getModel, {
7391
8297
  item: { id: options[idProp] },
7392
- isMissing: true
8298
+ isMissing: true,
7393
8299
  });
7394
8300
  return failSafeModel(options[idProp], options);
7395
8301
  }
@@ -7938,6 +8844,262 @@
7938
8844
  return interpolate(model, settings, transforms);
7939
8845
  }
7940
8846
 
8847
+ /**
8848
+ * Replaces instances of item ids on an item model
8849
+ * @param {Object} obj Object graph to traverse
8850
+ * @param {string} itemId id to replace with `{{appid}}`
8851
+ */
8852
+ function replaceItemId(obj, itemId, replacement) {
8853
+ if (replacement === void 0) { replacement = "{{appid}}"; }
8854
+ var clone = cloneObject$1(obj);
8855
+ var re = new RegExp(itemId, "g");
8856
+ return deepStringReplace(clone, re, replacement);
8857
+ }
8858
+
8859
+ /**
8860
+ * Share an item to a set of groups
8861
+ * @param {String} itemId Iten Id to share to the groups
8862
+ * @param {Array} groups Array of group id's to which the item will be shared
8863
+ * @param {String} owner optional Owner username to determine which endpoint to hit
8864
+ * @param {*} requestOptions
8865
+ */
8866
+ function shareItemToGroups(itemId, groups, requestOptions, owner) {
8867
+ return Promise.all(groups.map(function (groupId) {
8868
+ var opt = Object.assign({}, { id: itemId, groupId: groupId }, requestOptions);
8869
+ if (owner) {
8870
+ opt.owner = owner;
8871
+ }
8872
+ return shareItemWithGroup(opt);
8873
+ }));
8874
+ }
8875
+
8876
+ /**
8877
+ * Given a model, determine if it is protected, and unprotect it if it is.
8878
+ * Otherwise, just resolve with the same result.
8879
+ * @param {Object} model Model Object
8880
+ * @param {IRequestOptions} requestOptions
8881
+ */
8882
+ function unprotectModel(model, requestOptions) {
8883
+ if (model.item.protected) {
8884
+ var opts = Object.assign({ id: model.item.id }, requestOptions);
8885
+ return unprotectItem(opts);
8886
+ }
8887
+ else {
8888
+ // act as though we did it
8889
+ return Promise.resolve({ success: true });
8890
+ }
8891
+ }
8892
+
8893
+ /**
8894
+ * Unshare an item from a set of groups
8895
+ * @param {String} itemId Item Id to unshare from groups
8896
+ * @param {Array} groups Array of group id's from which the item will be unshared
8897
+ * @param {String} owner optional Owner username to determine which endpoint to hit
8898
+ * @param {IRequestOptions} requestOptions
8899
+ */
8900
+ function unshareItemFromGroups(itemId, groups, requestOptions, owner) {
8901
+ return Promise.all(groups.map(function (groupId) {
8902
+ var opt = Object.assign({}, { id: itemId, groupId: groupId }, requestOptions);
8903
+ if (owner) {
8904
+ opt.owner = owner;
8905
+ }
8906
+ return unshareItemWithGroup(opt);
8907
+ }));
8908
+ }
8909
+
8910
+ /**
8911
+ * Check if a site/page exists with a specific name
8912
+ */
8913
+ function doesItemExistWithTitle(itemTitle, options, authMgr) {
8914
+ // if options have multiple properties, put them into one string separated with 'AND'
8915
+ var optionsQuery = Object.keys(options)
8916
+ .map(function (key) {
8917
+ return key + ":\"" + options[key] + "\"";
8918
+ })
8919
+ .join(" AND ");
8920
+ var opts = {
8921
+ q: "title:\"" + itemTitle + "\" AND " + optionsQuery,
8922
+ authentication: authMgr
8923
+ };
8924
+ return searchItems(opts)
8925
+ .then(function (searchResponse) { return searchResponse.results.length > 0; })
8926
+ .catch(function (e) {
8927
+ throw Error("Error in doesItemExistWithTitle " + e);
8928
+ });
8929
+ }
8930
+
8931
+ /**
8932
+ * Given a title, construct a site/page title that is unique
8933
+ * if that title exists, this fn will add a number on the end, and increment until
8934
+ * an available title is found
8935
+ * @param {string} title site/page title to ensure if unique
8936
+ * @param {object} options an object that can be passed in to the q, eg. typekeywords, type
8937
+ * @param {object} authMgr auth info tells the function what url to use for the "root" of the API,
8938
+ * if missing, it will search against PROD
8939
+ * @param {number} step Number to increment. Defaults to 0
8940
+ */
8941
+ function getUniqueItemTitle(title, options, authMgr, step) {
8942
+ if (step === void 0) { step = 0; }
8943
+ var combinedName = title;
8944
+ if (step) {
8945
+ combinedName = title + " " + step;
8946
+ }
8947
+ return doesItemExistWithTitle(combinedName, options, authMgr)
8948
+ .then(function (result) {
8949
+ if (result) {
8950
+ step++;
8951
+ return getUniqueItemTitle(title, options, authMgr, step);
8952
+ }
8953
+ else {
8954
+ return combinedName;
8955
+ }
8956
+ })
8957
+ .catch(function (e) {
8958
+ throw Error("Error in getUniqueItemTitle " + e);
8959
+ });
8960
+ }
8961
+
8962
+ var MAX_NUM = 100;
8963
+ /**
8964
+ * Fetches all the pages in a search request
8965
+ * @param {SearchFunction} searchFunc
8966
+ * @param {ISearchOptions} opts
8967
+ * @param {number} limit
8968
+ * @param {batchSize} number of concurrent requests at a time
8969
+ * @returns {Promise<SearchableType[]>}
8970
+ */
8971
+ function fetchAllPages(searchFunc, opts, limit, batchSize) {
8972
+ if (limit === void 0) { limit = -1; }
8973
+ var pageSize = opts.num || MAX_NUM;
8974
+ var firstStart = opts.start || 1;
8975
+ // If a limit is provided, we don't have to use the first request to get the
8976
+ // total count before sending things off to batch(). So instead we fake the first
8977
+ // response just to set things up.
8978
+ var promise = limit === -1
8979
+ ? searchFunc(__assign(__assign({}, opts), { num: pageSize, start: firstStart }))
8980
+ : Promise.resolve({
8981
+ nextStart: firstStart,
8982
+ total: limit,
8983
+ results: [],
8984
+ num: pageSize
8985
+ });
8986
+ return promise
8987
+ .then(function (firstResponse) {
8988
+ // no more requests needed, return the first response
8989
+ if (firstResponse.nextStart === -1)
8990
+ return [firstResponse];
8991
+ // generate batch requests for the remaining pages to fetch
8992
+ var starts = [];
8993
+ for (var i = firstResponse.nextStart; i <= firstResponse.total; i += pageSize) {
8994
+ starts.push(i);
8995
+ }
8996
+ var batchSearchFunc = function (start) {
8997
+ return searchFunc(__assign(__assign({}, opts), { start: start, num: pageSize }));
8998
+ };
8999
+ return batch(starts, batchSearchFunc, batchSize).then(function (responses) { return __spreadArrays([
9000
+ firstResponse
9001
+ ], responses); });
9002
+ })
9003
+ .then(function (responses) {
9004
+ // merge all the search results into a single array
9005
+ var results = responses.reduce(function (acc, response) { return __spreadArrays(acc, response.results); }, []);
9006
+ // discard results beyond the limit if applicable
9007
+ var clipLimit = limit === -1 ? results.length : limit;
9008
+ return results.slice(0, clipLimit);
9009
+ });
9010
+ }
9011
+
9012
+ // TODO: work out how to unify content slug fns
9013
+ // https: github.com/Esri/hub.js/blob/master/packages/common/src/content/index.ts#L301-L348
9014
+ /**
9015
+ * Create a slug, namespaced to an org
9016
+ * Typically used to lookup items by a human readable name in urls
9017
+ *
9018
+ * @param title
9019
+ * @param orgKey
9020
+ * @returns
9021
+ */
9022
+ function constructSlug(title, orgKey) {
9023
+ return orgKey.toLowerCase() + "-" + slugify(title);
9024
+ }
9025
+ /**
9026
+ * Adds/Updates the slug typekeyword
9027
+ * Returns a new array of keywords
9028
+ * @param typeKeywords
9029
+ * @param slug
9030
+ * @returns
9031
+ */
9032
+ function setSlugKeyword(typeKeywords, slug) {
9033
+ // remove slug entry from array
9034
+ var removed = typeKeywords.filter(function (entry) {
9035
+ return !entry.startsWith("slug|");
9036
+ });
9037
+ // now add it
9038
+ removed.push("slug|" + slug);
9039
+ return removed;
9040
+ }
9041
+ /**
9042
+ * Get an item by searching for items with a typeKeyword like `slug|{slug-value}`
9043
+ *
9044
+ * For example, if you pass a slug `"snow-map"` into this function, it will
9045
+ * search for items with `slug|snow-map` in it's typeKeywords array,
9046
+ *
9047
+ * @param slug
9048
+ * @param requestOptions
9049
+ * @returns
9050
+ */
9051
+ function getItemBySlug(slug, requestOptions) {
9052
+ var opts = {
9053
+ q: "",
9054
+ filter: "typekeywords:\"slug|" + slug + "\"",
9055
+ authentication: requestOptions.authentication,
9056
+ };
9057
+ return searchItems(opts)
9058
+ .then(function (response) {
9059
+ if (response.results.length) {
9060
+ return response.results[0];
9061
+ }
9062
+ else {
9063
+ return null;
9064
+ }
9065
+ })
9066
+ .catch(function (e) {
9067
+ throw Error("Error in getItemBySlug " + e);
9068
+ });
9069
+ }
9070
+ /**
9071
+ * Given a slug, search for items using that slug, incrementing the slug name until
9072
+ * a unique value is found
9073
+ *
9074
+ * For example, if a slug of `"snow-map"` into this function and some item exists
9075
+ * with that slug, it would return `"snow-map-1"`.
9076
+ *
9077
+ * @param slug
9078
+ * @param requestOptions
9079
+ * @param step
9080
+ * @returns
9081
+ */
9082
+ function getUniqueSlug(slug, requestOptions, step) {
9083
+ if (step === void 0) { step = 0; }
9084
+ var combined = slug;
9085
+ if (step) {
9086
+ combined = slug + "-" + step;
9087
+ }
9088
+ return getItemBySlug(combined, requestOptions)
9089
+ .then(function (result) {
9090
+ if (result) {
9091
+ step++;
9092
+ return getUniqueSlug(slug, requestOptions, step);
9093
+ }
9094
+ else {
9095
+ return combined;
9096
+ }
9097
+ })
9098
+ .catch(function (e) {
9099
+ throw Error("Error in getUniqueSlug " + e);
9100
+ });
9101
+ }
9102
+
7941
9103
  var itemPropsNotInTemplates = [
7942
9104
  "id",
7943
9105
  "isOrgItem",
@@ -7967,182 +9129,529 @@
7967
9129
  "largeThumbnail"
7968
9130
  ];
7969
9131
  /**
7970
- * Given an item, remove a standard set of properties not needed in a template
7971
- * TODO: This should land in a templating helper lib in hub.js
7972
- * @param {Object} item Item to be normalized
9132
+ * Given an item, remove a standard set of properties not needed in a template
9133
+ * TODO: This should land in a templating helper lib in hub.js
9134
+ * @param {Object} item Item to be normalized
9135
+ */
9136
+ function normalizeSolutionTemplateItem(item) {
9137
+ var template = cloneObject$1(item);
9138
+ itemPropsNotInTemplates.forEach(function (prop) {
9139
+ delete template[prop];
9140
+ });
9141
+ // set a bunch of things we do want
9142
+ template.extent = "{{organization.defaultExtentBBox}}";
9143
+ return template;
9144
+ }
9145
+
9146
+ /**
9147
+ * Manage forward and backward property mappings to
9148
+ * streamline conversion between the Hub entities, and
9149
+ * the backing IModel
9150
+ */
9151
+ var PropertyMapper = /** @class */ (function () {
9152
+ /**
9153
+ * Pass in the mappings between the Entity and
9154
+ * it's backing structure (model or otherwise)
9155
+ * @param mappings
9156
+ */
9157
+ function PropertyMapper(mappings) {
9158
+ this.mappings = mappings;
9159
+ }
9160
+ /**
9161
+ * Map properties from a model on to the entity object.
9162
+ *
9163
+ * Used when constructing an entity can from a fetched model,
9164
+ * in which case the entity should be an empty object (`{}`).
9165
+ *
9166
+ * Can also be used to apply changes to an entity from a model,
9167
+ * in which case an existing entity can be passed in.
9168
+ * @param model
9169
+ * @param object
9170
+ * @returns
9171
+ */
9172
+ PropertyMapper.prototype.modelToObject = function (model, object) {
9173
+ return mapModelToObject(model, object, this.mappings);
9174
+ };
9175
+ /**
9176
+ * Map properties from an entity object onto a model.
9177
+ *
9178
+ * Typically the model will already exist, and this
9179
+ * method is used to transfer changes to the model
9180
+ * prior to storage.
9181
+ * @param object
9182
+ * @param model
9183
+ * @returns
9184
+ */
9185
+ PropertyMapper.prototype.objectToModel = function (object, model) {
9186
+ return mapObjectToModel(object, model, this.mappings);
9187
+ };
9188
+ return PropertyMapper;
9189
+ }());
9190
+ /**
9191
+ * Generic function to apply properties from an Object
9192
+ * (i.e. IHubProject) onto a Model that can be persisted to an Item
9193
+ * @param object
9194
+ * @param model
9195
+ * @param mappings
9196
+ * @returns
9197
+ */
9198
+ function mapObjectToModel(object, model, mappings) {
9199
+ return mapProps(object, "objectKey", model, "modelKey", mappings);
9200
+ }
9201
+ /**
9202
+ * Generic function to apply properties from a Model
9203
+ * onto an Object (i.e. IHubProject etc)
9204
+ * @param model
9205
+ * @param object
9206
+ * @param mappings
9207
+ * @returns
9208
+ */
9209
+ function mapModelToObject(model, object, mappings) {
9210
+ return mapProps(model, "modelKey", object, "objectKey", mappings);
9211
+ }
9212
+ /**
9213
+ * Internal function to map between objects
9214
+ * @param source
9215
+ * @param sourceKey
9216
+ * @param target
9217
+ * @param targetKey
9218
+ * @param mappings
9219
+ * @returns
7973
9220
  */
7974
- function normalizeSolutionTemplateItem(item) {
7975
- var template = cloneObject$1(item);
7976
- itemPropsNotInTemplates.forEach(function (prop) {
7977
- delete template[prop];
9221
+ function mapProps(source, sourceKey, target, targetKey, mappings) {
9222
+ // clone the target
9223
+ var clone = cloneObject$1(target);
9224
+ // walk the property map array
9225
+ mappings.forEach(function (entry) {
9226
+ // Verbose b/c typescript hates the use of property indexing with generics
9227
+ // i.e. entry<T>[sourceKey] make typescript angry
9228
+ var sourcePath = getProp(entry, sourceKey);
9229
+ var targetPath = getProp(entry, targetKey);
9230
+ // get the value from the source
9231
+ var sourceVal = getProp(source, sourcePath);
9232
+ // if it's not null or undefined
9233
+ if (sourceVal !== null && sourceVal !== undefined) {
9234
+ // set it
9235
+ deepSet(clone, targetPath, sourceVal);
9236
+ }
7978
9237
  });
7979
- // set a bunch of things we do want
7980
- template.extent = "{{organization.defaultExtentBBox}}";
7981
- return template;
9238
+ return clone;
7982
9239
  }
7983
9240
 
9241
+ var HUB_PROJECT_ITEM_TYPE = "Web Mapping Application";
7984
9242
  /**
7985
- * Replaces instances of item ids on an item model
7986
- * @param {Object} obj Object graph to traverse
7987
- * @param {string} itemId id to replace with `{{appid}}`
9243
+ * Default values of a IHubProject
7988
9244
  */
7989
- function replaceItemId(obj, itemId, replacement) {
7990
- if (replacement === void 0) { replacement = "{{appid}}"; }
7991
- var clone = cloneObject$1(obj);
7992
- var re = new RegExp(itemId, "g");
7993
- return deepStringReplace(clone, re, replacement);
9245
+ var DEFAULT_PROJECT = {
9246
+ name: "No title provided",
9247
+ tags: [],
9248
+ typeKeywords: ["IHubProject", "HubProject"],
9249
+ };
9250
+ /**
9251
+ * Default values for a new HubProject Model
9252
+ */
9253
+ var DEFAULT_PROJECT_MODEL = {
9254
+ item: {
9255
+ type: HUB_PROJECT_ITEM_TYPE,
9256
+ title: "No Title Provided",
9257
+ description: "No Description Provided",
9258
+ snippet: "",
9259
+ tags: [],
9260
+ typeKeywords: [],
9261
+ properties: {
9262
+ slug: "",
9263
+ },
9264
+ },
9265
+ data: {
9266
+ display: "about",
9267
+ timeline: {},
9268
+ org: {},
9269
+ status: "inactive",
9270
+ contacts: [],
9271
+ schemaVersion: 1,
9272
+ },
9273
+ };
9274
+ /**
9275
+ * Returns an Array of IPropertyMap objects
9276
+ * We could define these directly, but since the
9277
+ * properties of IHubProject map directly to properties
9278
+ * on item or data, it's slightly less verbose to
9279
+ * generate the structure.
9280
+ * @returns
9281
+ */
9282
+ function getProjectPropertyMap() {
9283
+ var itemProps = [
9284
+ "created",
9285
+ "culture",
9286
+ "description",
9287
+ "extent",
9288
+ "id",
9289
+ "modified",
9290
+ "owner",
9291
+ "snippet",
9292
+ "tags",
9293
+ "typeKeywords",
9294
+ "url",
9295
+ "type",
9296
+ ];
9297
+ var dataProps = [
9298
+ "contacts",
9299
+ "display",
9300
+ "geometry",
9301
+ "headerImage",
9302
+ "layout",
9303
+ "location",
9304
+ "status",
9305
+ ];
9306
+ var map = [];
9307
+ itemProps.forEach(function (entry) {
9308
+ map.push({ objectKey: entry, modelKey: "item." + entry });
9309
+ });
9310
+ dataProps.forEach(function (entry) {
9311
+ map.push({ objectKey: entry, modelKey: "data." + entry });
9312
+ });
9313
+ // Deeper mappings
9314
+ map.push({
9315
+ objectKey: "slug",
9316
+ modelKey: "item.properties.slug",
9317
+ });
9318
+ map.push({
9319
+ objectKey: "orgUrlKey",
9320
+ modelKey: "item.properties.orgUrlKey",
9321
+ });
9322
+ map.push({
9323
+ objectKey: "name",
9324
+ modelKey: "item.title",
9325
+ });
9326
+ return map;
7994
9327
  }
7995
-
7996
9328
  /**
7997
- * Share an item to a set of groups
7998
- * @param {String} itemId Iten Id to share to the groups
7999
- * @param {Array} groups Array of group id's to which the item will be shared
8000
- * @param {String} owner optional Owner username to determine which endpoint to hit
8001
- * @param {*} requestOptions
9329
+ * Create a new Hub Project item
9330
+ *
9331
+ * Minimal properties are name and org
9332
+ *
9333
+ * @param project
9334
+ * @param requestOptions
8002
9335
  */
8003
- function shareItemToGroups(itemId, groups, requestOptions, owner) {
8004
- return Promise.all(groups.map(function (groupId) {
8005
- var opt = Object.assign({}, { id: itemId, groupId: groupId }, requestOptions);
8006
- if (owner) {
8007
- opt.owner = owner;
8008
- }
8009
- return shareItemWithGroup(opt);
8010
- }));
9336
+ function createProject(partialProject, requestOptions) {
9337
+ return __awaiter(this, void 0, void 0, function () {
9338
+ var project, _a, mapper, model, newProject;
9339
+ return __generator(this, function (_b) {
9340
+ switch (_b.label) {
9341
+ case 0:
9342
+ project = __assign(__assign({}, DEFAULT_PROJECT), partialProject);
9343
+ // Create a slug from the title if one is not passed in
9344
+ if (!project.slug) {
9345
+ project.slug = constructSlug(project.name, project.orgUrlKey);
9346
+ }
9347
+ // Ensure slug is unique
9348
+ _a = project;
9349
+ return [4 /*yield*/, getUniqueSlug(project.slug, requestOptions)];
9350
+ case 1:
9351
+ // Ensure slug is unique
9352
+ _a.slug = _b.sent();
9353
+ // add slug to keywords
9354
+ project.typeKeywords = setSlugKeyword(project.typeKeywords, project.slug);
9355
+ mapper = new PropertyMapper(getProjectPropertyMap());
9356
+ model = mapper.objectToModel(project, cloneObject$1(DEFAULT_PROJECT_MODEL));
9357
+ return [4 /*yield*/, createModel(model, requestOptions)];
9358
+ case 2:
9359
+ // create the item
9360
+ model = _b.sent();
9361
+ newProject = mapper.modelToObject(model, {});
9362
+ // and return it
9363
+ return [2 /*return*/, newProject];
9364
+ }
9365
+ });
9366
+ });
8011
9367
  }
8012
-
8013
9368
  /**
8014
- * Given a model, determine if it is protected, and unprotect it if it is.
8015
- * Otherwise, just resolve with the same result.
8016
- * @param {Object} model Model Object
8017
- * @param {IRequestOptions} requestOptions
9369
+ * Update a Hub Project
9370
+ * @param project
9371
+ * @param requestOptions
8018
9372
  */
8019
- function unprotectModel(model, requestOptions) {
8020
- if (model.item.protected) {
8021
- var opts = Object.assign({ id: model.item.id }, requestOptions);
8022
- return unprotectItem(opts);
9373
+ function updateProject(project, requestOptions) {
9374
+ return __awaiter(this, void 0, void 0, function () {
9375
+ var _a, model, mapper, modelToUpdate, updatedModel, updatedProject;
9376
+ return __generator(this, function (_b) {
9377
+ switch (_b.label) {
9378
+ case 0:
9379
+ // verify that the slug is unique
9380
+ // TODO: if the slug has not changed, we don't want to do this because
9381
+ // the existing item will cause this to increment
9382
+ _a = project;
9383
+ return [4 /*yield*/, getUniqueSlug(project.slug, requestOptions)];
9384
+ case 1:
9385
+ // verify that the slug is unique
9386
+ // TODO: if the slug has not changed, we don't want to do this because
9387
+ // the existing item will cause this to increment
9388
+ _a.slug = _b.sent();
9389
+ return [4 /*yield*/, getModel(project.id, requestOptions)];
9390
+ case 2:
9391
+ model = _b.sent();
9392
+ mapper = new PropertyMapper(getProjectPropertyMap());
9393
+ modelToUpdate = mapper.objectToModel(project, model);
9394
+ return [4 /*yield*/, updateModel(modelToUpdate, requestOptions)];
9395
+ case 3:
9396
+ updatedModel = _b.sent();
9397
+ updatedProject = mapper.modelToObject(updatedModel, project);
9398
+ // the casting is needed because modelToObject returns a `Partial<T>`
9399
+ // where as this function returns a `T`
9400
+ return [2 /*return*/, updatedProject];
9401
+ }
9402
+ });
9403
+ });
9404
+ }
9405
+ /**
9406
+ * Get a Hub Project by id or slug
9407
+ * @param identifier item id or slug
9408
+ * @param requestOptions
9409
+ */
9410
+ function getProject(identifier, requestOptions) {
9411
+ var getPrms;
9412
+ if (isGuid(identifier)) {
9413
+ // get item by id
9414
+ getPrms = getModel(identifier, requestOptions);
8023
9415
  }
8024
9416
  else {
8025
- // act as though we did it
8026
- return Promise.resolve({ success: true });
8027
- }
9417
+ // search for item using filter=typekeywords:slug|identifier
9418
+ getPrms = getModelBySlug(identifier, requestOptions);
9419
+ }
9420
+ return getPrms.then(function (model) {
9421
+ // transform the model into a HubProject
9422
+ var mapper = new PropertyMapper(getProjectPropertyMap());
9423
+ var project = mapper.modelToObject(model, {});
9424
+ return project;
9425
+ });
8028
9426
  }
8029
-
8030
9427
  /**
8031
- * Unshare an item from a set of groups
8032
- * @param {String} itemId Item Id to unshare from groups
8033
- * @param {Array} groups Array of group id's from which the item will be unshared
8034
- * @param {String} owner optional Owner username to determine which endpoint to hit
8035
- * @param {IRequestOptions} requestOptions
9428
+ * Remove a Hub Project
9429
+ * @param id
9430
+ * @param requestOptions
8036
9431
  */
8037
- function unshareItemFromGroups(itemId, groups, requestOptions, owner) {
8038
- return Promise.all(groups.map(function (groupId) {
8039
- var opt = Object.assign({}, { id: itemId, groupId: groupId }, requestOptions);
8040
- if (owner) {
8041
- opt.owner = owner;
8042
- }
8043
- return unshareItemWithGroup(opt);
8044
- }));
9432
+ function destroyProject(id, requestOptions) {
9433
+ return __awaiter(this, void 0, void 0, function () {
9434
+ var ro;
9435
+ return __generator(this, function (_a) {
9436
+ switch (_a.label) {
9437
+ case 0:
9438
+ ro = __assign(__assign({}, requestOptions), { id: id });
9439
+ return [4 /*yield*/, removeItem(ro)];
9440
+ case 1:
9441
+ _a.sent();
9442
+ return [2 /*return*/];
9443
+ }
9444
+ });
9445
+ });
8045
9446
  }
9447
+ // WIP: Need to resolve how best to execute this
9448
+ // i.e. delegate to searchContent or just do an item search
9449
+ // and convert to IHubProject objects.
9450
+ //
9451
+ // export async function searchProjects(
9452
+ // filter: Filter<"content">,
9453
+ // opts: IHubSearchOptions
9454
+ // ): Promise<ISearchResponse<IHubProject>> {
9455
+ // return _searchContent(filter, opts).then((results) => {
9456
+ // })
9457
+ // }
8046
9458
 
8047
9459
  /**
8048
- * Check if a site/page exists with a specific name
9460
+ * Centralized functions used to manage IHubProject instances
9461
+ *
9462
+ * This class is a convenience wrapper over util functions which
9463
+ * are also directly accessible for use in scenarios where
9464
+ * classes are inconvenient.
8049
9465
  */
8050
- function doesItemExistWithTitle(itemTitle, options, authMgr) {
8051
- // if options have multiple properties, put them into one string separated with 'AND'
8052
- var optionsQuery = Object.keys(options)
8053
- .map(function (key) {
8054
- return key + ":\"" + options[key] + "\"";
8055
- })
8056
- .join(" AND ");
8057
- var opts = {
8058
- q: "title:\"" + itemTitle + "\" AND " + optionsQuery,
8059
- authentication: authMgr
9466
+ var HubProjectManager = /** @class */ (function () {
9467
+ /**
9468
+ * Private so we can employ a factory function should we need
9469
+ * async work during creation
9470
+ * @param contextOrManager
9471
+ */
9472
+ function HubProjectManager(contextOrManager) {
9473
+ if (contextOrManager instanceof ArcGISContextManager) {
9474
+ this._contextManager = contextOrManager;
9475
+ }
9476
+ else {
9477
+ this._context = contextOrManager;
9478
+ }
9479
+ }
9480
+ /**
9481
+ * Factory function to construct a new HubProjectManager instance.
9482
+ *
9483
+ * Note: Used so that we could do async actions in the ctor.
9484
+ * @param contextOrManager
9485
+ * @returns
9486
+ */
9487
+ HubProjectManager.init = function (contextOrManager) {
9488
+ return new HubProjectManager(contextOrManager);
8060
9489
  };
8061
- return searchItems(opts)
8062
- .then(function (searchResponse) { return searchResponse.results.length > 0; })
8063
- .catch(function (e) {
8064
- throw Error("Error in doesItemExistWithTitle " + e);
9490
+ Object.defineProperty(HubProjectManager.prototype, "context", {
9491
+ /**
9492
+ * Getter to abstract how we store the context
9493
+ */
9494
+ get: function () {
9495
+ if (this._contextManager) {
9496
+ return this._contextManager.context;
9497
+ }
9498
+ else {
9499
+ return this._context;
9500
+ }
9501
+ },
9502
+ enumerable: false,
9503
+ configurable: true
8065
9504
  });
8066
- }
9505
+ /**
9506
+ * Create and store new project.
9507
+ *
9508
+ * Projects are stored as Items in the Sharing API
9509
+ * @param project
9510
+ * @param requestOptions
9511
+ * @returns
9512
+ */
9513
+ HubProjectManager.prototype.create = function (project, requestOptions) {
9514
+ return __awaiter(this, void 0, void 0, function () {
9515
+ return __generator(this, function (_a) {
9516
+ if (requestOptions || this.context.isAuthenticated) {
9517
+ // ammend in the orgUrlKey
9518
+ if (!project.orgUrlKey) {
9519
+ project.orgUrlKey = this.context.portal.urlKey;
9520
+ }
9521
+ return [2 /*return*/, createProject(project, requestOptions || this.context.userRequestOptions)];
9522
+ }
9523
+ else {
9524
+ throw new HubError("Create Project", "Creating Hub Projects requires authentication.");
9525
+ }
9526
+ });
9527
+ });
9528
+ };
9529
+ /**
9530
+ * Update a project
9531
+ * @param project
9532
+ * @param requestOptions
9533
+ * @returns
9534
+ */
9535
+ HubProjectManager.prototype.update = function (project, requestOptions) {
9536
+ return __awaiter(this, void 0, void 0, function () {
9537
+ return __generator(this, function (_a) {
9538
+ if (requestOptions || this.context.isAuthenticated) {
9539
+ return [2 /*return*/, updateProject(project, requestOptions || this.context.userRequestOptions)];
9540
+ }
9541
+ else {
9542
+ throw new HubError("Update Project", "Updating Hub Projects requires authentication.");
9543
+ }
9544
+ });
9545
+ });
9546
+ };
9547
+ /**
9548
+ * Destroy a project.
9549
+ * This permanently removes the backing Item
9550
+ * @param id
9551
+ * @param requestOptions
9552
+ * @returns
9553
+ */
9554
+ HubProjectManager.prototype.destroy = function (id, requestOptions) {
9555
+ return __awaiter(this, void 0, void 0, function () {
9556
+ return __generator(this, function (_a) {
9557
+ if (requestOptions || this.context.isAuthenticated) {
9558
+ return [2 /*return*/, destroyProject(id, requestOptions || this.context.userRequestOptions)];
9559
+ }
9560
+ else {
9561
+ throw new HubError("Destroy Project", "Destroying Hub Projects requires authentication.");
9562
+ }
9563
+ });
9564
+ });
9565
+ };
9566
+ /**
9567
+ * Fetch a Project via id or it's slug
9568
+ *
9569
+ * This function does not require a user to be
9570
+ * authenticated, but it does require an `IRequestOptions`
9571
+ * which contains the portal instance to communicate with
9572
+ * @param identifier
9573
+ * @param requestOptions
9574
+ * @returns
9575
+ */
9576
+ HubProjectManager.prototype.fetch = function (identifier, requestOptions) {
9577
+ return __awaiter(this, void 0, void 0, function () {
9578
+ return __generator(this, function (_a) {
9579
+ if (requestOptions || this.context.requestOptions) {
9580
+ return [2 /*return*/, getProject(identifier, requestOptions || this.context.requestOptions)];
9581
+ }
9582
+ else {
9583
+ throw new HubError("Get Project", "Can not retrieve context.requestOptions from Context Manager. HubProjectManager is configured incorrectly.");
9584
+ }
9585
+ });
9586
+ });
9587
+ };
9588
+ return HubProjectManager;
9589
+ }());
8067
9590
 
8068
9591
  /**
8069
- * Given a title, construct a site/page title that is unique
8070
- * if that title exists, this fn will add a number on the end, and increment until
8071
- * an available title is found
8072
- * @param {string} title site/page title to ensure if unique
8073
- * @param {object} options an object that can be passed in to the q, eg. typekeywords, type
8074
- * @param {object} authMgr auth info tells the function what url to use for the "root" of the API,
8075
- * if missing, it will search against PROD
8076
- * @param {number} step Number to increment. Defaults to 0
9592
+ * remote server error
8077
9593
  */
8078
- function getUniqueItemTitle(title, options, authMgr, step) {
8079
- if (step === void 0) { step = 0; }
8080
- var combinedName = title;
8081
- if (step) {
8082
- combinedName = title + " " + step;
9594
+ var RemoteServerError = /** @class */ (function (_super) {
9595
+ __extends(RemoteServerError, _super);
9596
+ function RemoteServerError(message, url, status) {
9597
+ var _this = _super.call(this, message) || this;
9598
+ _this.status = status;
9599
+ _this.url = url;
9600
+ return _this;
8083
9601
  }
8084
- return doesItemExistWithTitle(combinedName, options, authMgr)
8085
- .then(function (result) {
8086
- if (result) {
8087
- step++;
8088
- return getUniqueItemTitle(title, options, authMgr, step);
9602
+ return RemoteServerError;
9603
+ }(Error));
9604
+ /**
9605
+ * ```js
9606
+ * import { hubApiRequest } from "@esri/hub-common";
9607
+ * //
9608
+ * hubApiRequest(
9609
+ * "/datasets",
9610
+ * requestOptions
9611
+ * })
9612
+ * .then(response);
9613
+ * ```
9614
+ * make a request to the Hub API
9615
+ * @param route API route
9616
+ * @param requestOptions request options
9617
+ */
9618
+ function hubApiRequest(route, requestOptions) {
9619
+ // merge in default request options
9620
+ var options = __assign({
9621
+ // why do we default to GET w/ our API?
9622
+ httpMethod: "GET" }, requestOptions);
9623
+ // use fetch override if any
9624
+ var _fetch = options.fetch || fetch;
9625
+ // merge in default headers
9626
+ var headers = __assign({ "Content-Type": "application/json" }, options.headers);
9627
+ // build query params/body based on requestOptions.params
9628
+ var query;
9629
+ var body;
9630
+ if (options.httpMethod === "GET") {
9631
+ // pass params in query string
9632
+ query = options.params;
9633
+ }
9634
+ else {
9635
+ // pass params in request body
9636
+ body = JSON.stringify(options.params);
9637
+ }
9638
+ // build Hub API URL
9639
+ var url = buildUrl({
9640
+ host: getHubApiUrl(options),
9641
+ path: ("/api/v3/" + route).replace(/\/\//g, "/"),
9642
+ query: query,
9643
+ });
9644
+ return _fetch(url, {
9645
+ method: options.httpMethod,
9646
+ headers: headers,
9647
+ body: body,
9648
+ }).then(function (resp) {
9649
+ if (resp.ok) {
9650
+ return resp.json();
8089
9651
  }
8090
9652
  else {
8091
- return combinedName;
8092
- }
8093
- })
8094
- .catch(function (e) {
8095
- throw Error("Error in getUniqueItemTitle " + e);
8096
- });
8097
- }
8098
-
8099
- var MAX_NUM = 100;
8100
- /**
8101
- * Fetches all the pages in a search request
8102
- * @param {SearchFunction} searchFunc
8103
- * @param {ISearchOptions} opts
8104
- * @param {number} limit
8105
- * @param {batchSize} number of concurrent requests at a time
8106
- * @returns {Promise<SearchableType[]>}
8107
- */
8108
- function fetchAllPages(searchFunc, opts, limit, batchSize) {
8109
- if (limit === void 0) { limit = -1; }
8110
- var pageSize = opts.num || MAX_NUM;
8111
- var firstStart = opts.start || 1;
8112
- // If a limit is provided, we don't have to use the first request to get the
8113
- // total count before sending things off to batch(). So instead we fake the first
8114
- // response just to set things up.
8115
- var promise = limit === -1
8116
- ? searchFunc(__assign(__assign({}, opts), { num: pageSize, start: firstStart }))
8117
- : Promise.resolve({
8118
- nextStart: firstStart,
8119
- total: limit,
8120
- results: [],
8121
- num: pageSize
8122
- });
8123
- return promise
8124
- .then(function (firstResponse) {
8125
- // no more requests needed, return the first response
8126
- if (firstResponse.nextStart === -1)
8127
- return [firstResponse];
8128
- // generate batch requests for the remaining pages to fetch
8129
- var starts = [];
8130
- for (var i = firstResponse.nextStart; i <= firstResponse.total; i += pageSize) {
8131
- starts.push(i);
9653
+ throw new RemoteServerError(resp.statusText, url, resp.status);
8132
9654
  }
8133
- var batchSearchFunc = function (start) {
8134
- return searchFunc(__assign(__assign({}, opts), { start: start, num: pageSize }));
8135
- };
8136
- return batch(starts, batchSearchFunc, batchSize).then(function (responses) { return __spreadArrays([
8137
- firstResponse
8138
- ], responses); });
8139
- })
8140
- .then(function (responses) {
8141
- // merge all the search results into a single array
8142
- var results = responses.reduce(function (acc, response) { return __spreadArrays(acc, response.results); }, []);
8143
- // discard results beyond the limit if applicable
8144
- var clipLimit = limit === -1 ? results.length : limit;
8145
- return results.slice(0, clipLimit);
8146
9655
  });
8147
9656
  }
8148
9657
 
@@ -8793,7 +10302,7 @@
8793
10302
  * Construct a the full url to a group thumbnail
8794
10303
  *
8795
10304
  * - If the group has a thumbnail, construct the full url
8796
- * - If the group is not public, append on the token
10305
+ * - If the group is not public, append on the token (if passed in)
8797
10306
  * @param portalUrl
8798
10307
  * @param group
8799
10308
  * @param token
@@ -9524,12 +11033,11 @@
9524
11033
  return __generator(this, function (_b) {
9525
11034
  expanded = expandContentFilter(filter);
9526
11035
  api = expandApi(options.api || "arcgis");
9527
- // map over the apis, depending on the type we issue the queries
9528
- // const searchPromises = apis.map((api) => {
9529
11036
  // Portal Search
9530
11037
  if (api.type === "arcgis") {
9531
11038
  so = serializeContentFilterForPortal(expanded);
9532
- // pass auth forward
11039
+ // if we have auth, pass it forward
11040
+ // otherwise set the portal property
9533
11041
  if (options.authentication) {
9534
11042
  so.authentication = options.authentication;
9535
11043
  }
@@ -9542,7 +11050,6 @@
9542
11050
  so.countSize = 200;
9543
11051
  }
9544
11052
  // copy over various options
9545
- // TODO: Dry this up - typscript makes this... inconvenient
9546
11053
  if (options.num) {
9547
11054
  so.num = options.num;
9548
11055
  }
@@ -9569,8 +11076,6 @@
9569
11076
  },
9570
11077
  });
9571
11078
  }
9572
- // });
9573
- // return for results
9574
11079
  return [2 /*return*/, searchPromise];
9575
11080
  });
9576
11081
  });
@@ -9584,14 +11089,29 @@
9584
11089
  * @returns
9585
11090
  */
9586
11091
  function searchPortal(searchOptions) {
11092
+ var _a;
11093
+ var portalUrl = ((_a = searchOptions.authentication) === null || _a === void 0 ? void 0 : _a.portal) || searchOptions.portal;
11094
+ var token;
11095
+ if (searchOptions.authentication) {
11096
+ var us = searchOptions.authentication;
11097
+ token = us.token;
11098
+ }
11099
+ var thumbnailify = function (content) {
11100
+ content.thumbnailUrl = getItemThumbnailUrl(content, portalUrl, token);
11101
+ return content;
11102
+ };
9587
11103
  return searchItems(searchOptions).then(function (resp) {
9588
11104
  var hasNext = resp.nextStart > -1;
11105
+ // convert items to IHubContent's
9589
11106
  var content = resp.results.map(itemToContent);
11107
+ // if we have a site, add those urls
9590
11108
  if (searchOptions.site) {
9591
11109
  content = content.map(function (entry) {
9592
11110
  return setContentSiteUrls(entry, searchOptions.site);
9593
11111
  });
9594
11112
  }
11113
+ // add thumbnailUrl
11114
+ content = content.map(thumbnailify);
9595
11115
  // convert aggregations into facets
9596
11116
  var facets = convertPortalResponseToFacets(resp);
9597
11117
  return {
@@ -9613,10 +11133,9 @@
9613
11133
  * @returns
9614
11134
  */
9615
11135
  function _searchGroups(filter, options) {
9616
- var _a;
9617
11136
  return __awaiter(this, void 0, void 0, function () {
9618
11137
  var expanded, api, so;
9619
- return __generator(this, function (_b) {
11138
+ return __generator(this, function (_a) {
9620
11139
  expanded = expandGroupFilter(filter);
9621
11140
  api = expandApi(options.api || "arcgis");
9622
11141
  if (api.type === "arcgis") {
@@ -9629,7 +11148,6 @@
9629
11148
  else {
9630
11149
  so.portal = api.url + "/sharing/rest";
9631
11150
  }
9632
- // TODO: Dry this up - typscript makes this... inconvenient
9633
11151
  if (options.num) {
9634
11152
  so.num = options.num;
9635
11153
  }
@@ -9639,10 +11157,6 @@
9639
11157
  if (options.sortOrder) {
9640
11158
  so.sortOrder = options.sortOrder;
9641
11159
  }
9642
- api.url + "/sharing/rest";
9643
- if ((_a = so.authentication) === null || _a === void 0 ? void 0 : _a.portal) {
9644
- so.authentication.portal;
9645
- }
9646
11160
  if (options.site) {
9647
11161
  so.site = cloneObject$1(options.site);
9648
11162
  }
@@ -9665,8 +11179,7 @@
9665
11179
  group.siteTeamUrl = searchOptions.site.item.url + "/teams/" + group.id + "/about";
9666
11180
  return group;
9667
11181
  };
9668
- var portalUrl = ((_a = searchOptions.authentication) === null || _a === void 0 ? void 0 : _a.portal) ||
9669
- "https://www.arcgis.com/sharing/rest";
11182
+ var portalUrl = ((_a = searchOptions.authentication) === null || _a === void 0 ? void 0 : _a.portal) || searchOptions.portal;
9670
11183
  var token;
9671
11184
  if (searchOptions.authentication) {
9672
11185
  var us = searchOptions.authentication;
@@ -10330,262 +11843,90 @@
10330
11843
  var clone = cloneObject$1(model);
10331
11844
  var oldDcatUS11Config = clone.data.values.dcatConfig;
10332
11845
  clone.data.feeds = {};
10333
- if (oldDcatUS11Config) {
10334
- clone.data.feeds.dcatUS11 = _migrateToV3Values(oldDcatUS11Config);
10335
- }
10336
- clone.item.properties.schemaVersion = 1.5;
10337
- return clone;
10338
- }
10339
- var indexValueToV3Value = {
10340
- // Defaults
10341
- "{{default.name}}": "{{name}}",
10342
- "{{default.description}}": "{{description}}",
10343
- "{{item.tags}}": "{{tags}}",
10344
- "{{item.created:toISO}}": "{{created:toISO}}",
10345
- "{{item.modified:toISO}}": "{{modified:toISO}}",
10346
- "{{default.source.source}}": "{{source}}",
10347
- "{{item.owner}}": "{{owner}}",
10348
- "{{org.portalProperties.links.contactUs.url}}": "{{orgContactEmail}}",
10349
- // Custom Values
10350
- "{{org.name}}": "{{orgName}}",
10351
- "{{item.categories}}": "{{categories}}",
10352
- "{{item.licenseInfo}}": "{{licenseInfo}}",
10353
- "{{item.modified}}": "{{modified}}",
10354
- "{{enrichments.categories}}": "{{categories}}",
10355
- "{{default.id}}": "{{id}}",
10356
- "{{item.licenseInfo || No License}}": "{{licenseInfo || No License}}",
10357
- "{{org.portalProperties.links.contactUs.url || mailto:data@tempe.gov}}": "{{orgContactEmail || mailto:data@tempe.gov}}",
10358
- "{{default.description || No Description}}": "{{description || No Description}}",
10359
- "{{item.id}}": "{{id}}",
10360
- };
10361
- function _migrateToV3Values(originalConfig) {
10362
- var migratedConfigString = JSON.stringify(originalConfig);
10363
- var supportedIndexValues = Object.keys(indexValueToV3Value);
10364
- supportedIndexValues.forEach(function (indexValue) {
10365
- // Replace all occurrences of indexValue with the corresponding v3Value
10366
- var v3Value = indexValueToV3Value[indexValue];
10367
- migratedConfigString = migratedConfigString.split(indexValue).join(v3Value);
10368
- });
10369
- return JSON.parse(migratedConfigString);
10370
- }
10371
-
10372
- /**
10373
- * Upgrades the schema upgrades
10374
- * @param model IModel
10375
- */
10376
- function upgradeSiteSchema(model) {
10377
- if (getProp(model, "item.properties.schemaVersion") === SITE_SCHEMA_VERSION) {
10378
- return model;
10379
- }
10380
- else {
10381
- // apply upgrade functions in order...
10382
- model = _applySiteSchema(model);
10383
- model = _enforceLowercaseDomains(model);
10384
- model = _ensureCatalog(model);
10385
- model = _purgeNonGuidsFromCatalog(model);
10386
- model = _ensureTelemetry(model);
10387
- model = _migrateFeedConfig(model);
10388
- // WARNING - If you are writing a site schema migration,
10389
- // you probably need to apply it to site drafts as well!
10390
- // See https://github.com/Esri/hub.js/issues/498 for more details.
10391
- return model;
10392
- }
10393
- }
10394
-
10395
- /**
10396
- * Returns site model given various kinds of identifier
10397
- *
10398
- * @param identifier - a site item ID, site hostname, enterprise site slug, or full site URL
10399
- * @param hubRequestOptions
10400
- */
10401
- function fetchSite(identifier, hubRequestOptions) {
10402
- var prms;
10403
- if (isGuid(identifier)) {
10404
- prms = getSiteById(identifier, hubRequestOptions);
10405
- }
10406
- else {
10407
- var hostnameOrSlug = identifier;
10408
- // get down the the hostname
10409
- hostnameOrSlug = stripProtocol(hostnameOrSlug);
10410
- hostnameOrSlug = hostnameOrSlug.split("/")[0];
10411
- prms = lookupDomain(hostnameOrSlug, hubRequestOptions).then(function (_a) {
10412
- var siteId = _a.siteId;
10413
- return getSiteById(siteId, hubRequestOptions);
10414
- });
10415
- }
10416
- return prms;
10417
- }
10418
-
10419
- /**
10420
- * Locales supported by the hub
10421
- */
10422
- var HUB_LOCALES = [
10423
- "ar",
10424
- "bs",
10425
- "ca",
10426
- "cs",
10427
- "da",
10428
- "de",
10429
- "en",
10430
- "es",
10431
- "et",
10432
- "el",
10433
- "fi",
10434
- "fr",
10435
- "hr",
10436
- "he",
10437
- "hu",
10438
- "it",
10439
- "id",
10440
- "ja",
10441
- "ko",
10442
- "lt",
10443
- "lv",
10444
- "nb",
10445
- "nl",
10446
- "pl",
10447
- "pt",
10448
- "pt-br",
10449
- "pt-pt",
10450
- "ro",
10451
- "ru",
10452
- "sl",
10453
- "sr",
10454
- "sv",
10455
- "th",
10456
- "tr",
10457
- "uk",
10458
- "vi",
10459
- "zh",
10460
- "zh-cn",
10461
- "zh-tw",
10462
- "zh-hk"
10463
- ];
10464
-
10465
- /**
10466
- * Convert a requested locale into a locale we support.
10467
- * i.e. en-ca => en
10468
- * If the requested locale is not available, en will be returned
10469
- * @param {string} requestedLocale Locale we want
10470
- */
10471
- function convertToWellKnownLocale(requestedLocale) {
10472
- if (requestedLocale === void 0) { requestedLocale = "en"; }
10473
- var wellKnownKey = "en";
10474
- // ensure downcase
10475
- requestedLocale = requestedLocale.toLowerCase();
10476
- // see if it's in the hub translations as-is
10477
- if (HUB_LOCALES.indexOf(requestedLocale) > -1) {
10478
- wellKnownKey = requestedLocale;
10479
- }
10480
- else {
10481
- // if we split the requested locale, see if we have the root in the list
10482
- var parts = requestedLocale.split("-");
10483
- if (parts.length > 1 && HUB_LOCALES.indexOf(parts[0]) > -1) {
10484
- wellKnownKey = parts[0];
10485
- }
10486
- }
10487
- return wellKnownKey;
10488
- }
10489
-
10490
- /**
10491
- * Fetch the Hub translation file for a given locale
10492
- * These are all public urls and should never require auth/tokens etc
10493
- * @param {String} locale Locale code - i.e. `es`
10494
- * @param {Object} portal Portal Self
10495
- */
10496
- function fetchHubTranslation(locale, portal, mode) {
10497
- if (mode === void 0) { mode = "cors"; }
10498
- var assetBase = getHubLocaleAssetUrl(portal);
10499
- var url = (assetBase + "/locales/" + locale + ".json").toLocaleLowerCase();
10500
- // to support web-tier auth, we must always send same-origin credentials
10501
- var options = {
10502
- method: "GET",
10503
- credentials: "same-origin",
10504
- mode: mode
10505
- };
10506
- return fetch(url, options)
10507
- .then(function (response) { return response.json(); })
10508
- .catch(function (err) {
10509
- throw Error("Attempt to fetch locale " + locale + " from " + url + " failed: " + JSON.stringify(err));
11846
+ if (oldDcatUS11Config) {
11847
+ clone.data.feeds.dcatUS11 = _migrateToV3Values(oldDcatUS11Config);
11848
+ }
11849
+ clone.item.properties.schemaVersion = 1.5;
11850
+ return clone;
11851
+ }
11852
+ var indexValueToV3Value = {
11853
+ // Defaults
11854
+ "{{default.name}}": "{{name}}",
11855
+ "{{default.description}}": "{{description}}",
11856
+ "{{item.tags}}": "{{tags}}",
11857
+ "{{item.created:toISO}}": "{{created:toISO}}",
11858
+ "{{item.modified:toISO}}": "{{modified:toISO}}",
11859
+ "{{default.source.source}}": "{{source}}",
11860
+ "{{item.owner}}": "{{owner}}",
11861
+ "{{org.portalProperties.links.contactUs.url}}": "{{orgContactEmail}}",
11862
+ // Custom Values
11863
+ "{{org.name}}": "{{orgName}}",
11864
+ "{{item.categories}}": "{{categories}}",
11865
+ "{{item.licenseInfo}}": "{{licenseInfo}}",
11866
+ "{{item.modified}}": "{{modified}}",
11867
+ "{{enrichments.categories}}": "{{categories}}",
11868
+ "{{default.id}}": "{{id}}",
11869
+ "{{item.licenseInfo || No License}}": "{{licenseInfo || No License}}",
11870
+ "{{org.portalProperties.links.contactUs.url || mailto:data@tempe.gov}}": "{{orgContactEmail || mailto:data@tempe.gov}}",
11871
+ "{{default.description || No Description}}": "{{description || No Description}}",
11872
+ "{{item.id}}": "{{id}}",
11873
+ };
11874
+ function _migrateToV3Values(originalConfig) {
11875
+ var migratedConfigString = JSON.stringify(originalConfig);
11876
+ var supportedIndexValues = Object.keys(indexValueToV3Value);
11877
+ supportedIndexValues.forEach(function (indexValue) {
11878
+ // Replace all occurrences of indexValue with the corresponding v3Value
11879
+ var v3Value = indexValueToV3Value[indexValue];
11880
+ migratedConfigString = migratedConfigString.split(indexValue).join(v3Value);
10510
11881
  });
11882
+ return JSON.parse(migratedConfigString);
10511
11883
  }
10512
11884
 
10513
11885
  /**
10514
- * Return the culture from the Hub Request Options
10515
- * In priority order: user.culture, portal.culture, en-us
10516
- * @param {IHubRequestOptions} hubRequestOptions
11886
+ * Upgrades the schema upgrades
11887
+ * @param model IModel
10517
11888
  */
10518
- function getCulture(hubRequestOptions) {
10519
- return (getProp(hubRequestOptions, "portalSelf.user.culture") ||
10520
- getProp(hubRequestOptions, "portalSelf.culture") ||
10521
- "en-us");
11889
+ function upgradeSiteSchema(model) {
11890
+ if (getProp(model, "item.properties.schemaVersion") === SITE_SCHEMA_VERSION) {
11891
+ return model;
11892
+ }
11893
+ else {
11894
+ // apply upgrade functions in order...
11895
+ model = _applySiteSchema(model);
11896
+ model = _enforceLowercaseDomains(model);
11897
+ model = _ensureCatalog(model);
11898
+ model = _purgeNonGuidsFromCatalog(model);
11899
+ model = _ensureTelemetry(model);
11900
+ model = _migrateFeedConfig(model);
11901
+ // WARNING - If you are writing a site schema migration,
11902
+ // you probably need to apply it to site drafts as well!
11903
+ // See https://github.com/Esri/hub.js/issues/498 for more details.
11904
+ return model;
11905
+ }
10522
11906
  }
10523
11907
 
10524
11908
  /**
10525
- * remote server error
10526
- */
10527
- var RemoteServerError = /** @class */ (function (_super) {
10528
- __extends(RemoteServerError, _super);
10529
- function RemoteServerError(message, url, status) {
10530
- var _this = _super.call(this, message) || this;
10531
- _this.status = status;
10532
- _this.url = url;
10533
- return _this;
10534
- }
10535
- return RemoteServerError;
10536
- }(Error));
10537
- /**
10538
- * ```js
10539
- * import { hubApiRequest } from "@esri/hub-common";
10540
- * //
10541
- * hubApiRequest(
10542
- * "/datasets",
10543
- * requestOptions
10544
- * })
10545
- * .then(response);
10546
- * ```
10547
- * make a request to the Hub API
10548
- * @param route API route
10549
- * @param requestOptions request options
11909
+ * Returns site model given various kinds of identifier
11910
+ *
11911
+ * @param identifier - a site item ID, site hostname, enterprise site slug, or full site URL
11912
+ * @param hubRequestOptions
10550
11913
  */
10551
- function hubApiRequest(route, requestOptions) {
10552
- // merge in default request options
10553
- var options = __assign({
10554
- // why do we default to GET w/ our API?
10555
- httpMethod: "GET" }, requestOptions);
10556
- // use fetch override if any
10557
- var _fetch = options.fetch || fetch;
10558
- // merge in default headers
10559
- var headers = __assign({ "Content-Type": "application/json" }, options.headers);
10560
- // build query params/body based on requestOptions.params
10561
- var query;
10562
- var body;
10563
- if (options.httpMethod === "GET") {
10564
- // pass params in query string
10565
- query = options.params;
11914
+ function fetchSite(identifier, hubRequestOptions) {
11915
+ var prms;
11916
+ if (isGuid(identifier)) {
11917
+ prms = getSiteById(identifier, hubRequestOptions);
10566
11918
  }
10567
11919
  else {
10568
- // pass params in request body
10569
- body = JSON.stringify(options.params);
11920
+ var hostnameOrSlug = identifier;
11921
+ // get down the the hostname
11922
+ hostnameOrSlug = stripProtocol(hostnameOrSlug);
11923
+ hostnameOrSlug = hostnameOrSlug.split("/")[0];
11924
+ prms = lookupDomain(hostnameOrSlug, hubRequestOptions).then(function (_a) {
11925
+ var siteId = _a.siteId;
11926
+ return getSiteById(siteId, hubRequestOptions);
11927
+ });
10570
11928
  }
10571
- // build Hub API URL
10572
- var url = buildUrl({
10573
- host: getHubApiUrl(options),
10574
- path: ("/api/v3/" + route).replace(/\/\//g, "/"),
10575
- query: query,
10576
- });
10577
- return _fetch(url, {
10578
- method: options.httpMethod,
10579
- headers: headers,
10580
- body: body,
10581
- }).then(function (resp) {
10582
- if (resp.ok) {
10583
- return resp.json();
10584
- }
10585
- else {
10586
- throw new RemoteServerError(resp.statusText, url, resp.status);
10587
- }
10588
- });
11929
+ return prms;
10589
11930
  }
10590
11931
 
10591
11932
  /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
@@ -10603,641 +11944,210 @@
10603
11944
  var featureService = _a.relatedItems[0];
10604
11945
  var model;
10605
11946
  if (featureService) {
10606
- model = { item: featureService };
10607
- }
10608
- return model;
10609
- });
10610
- };
10611
-
10612
- /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
10613
- * Apache-2.0 */
10614
- /**
10615
- * Fetches a Survey's source Feature Service from a given
10616
- * Fieldworker View ID
10617
- * @param {string} fieldworkerId The Fieldworker View ID
10618
- * @param {IRequestOptions} requestOptions The request options
10619
- * @returns {Promise<IModel>}
10620
- */
10621
- var getSourceFeatureServiceModelFromFieldworker = function (fieldworkerId, requestOptions) {
10622
- return getRelatedItems(__assign({ id: fieldworkerId, relationshipType: "Service2Data", direction: "forward" }, requestOptions)).then(function (_a) {
10623
- var featureService = _a.relatedItems[0];
10624
- var model;
10625
- if (featureService) {
10626
- model = { item: featureService };
10627
- }
10628
- return model;
10629
- });
10630
- };
10631
-
10632
- /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
10633
- * Apache-2.0 */
10634
- /**
10635
- * Fetches a Survey's Stakeholder View for a given
10636
- * Form ID
10637
- * @param {string} formId A Form ID
10638
- * @param {IRequestOptions} requestOptions The request options
10639
- * @returns {Promise<IModel>}
10640
- */
10641
- var getStakeholderModel = function (formId, requestOptions) {
10642
- return getRelatedItems(__assign({ id: formId, relationshipType: "Survey2Data", direction: "forward" }, requestOptions)).then(function (_a) {
10643
- var stakeholderView = _a.relatedItems[0];
10644
- var model;
10645
- if (stakeholderView) {
10646
- model = { item: stakeholderView };
10647
- }
10648
- return model;
10649
- });
10650
- };
10651
-
10652
- /**
10653
- * Determines if the provided Feature Service item is a
10654
- * Fieldworker View
10655
- * @param {IItem} featureServiceItem
10656
- * @returns {boolean}
10657
- */
10658
- function isFieldworkerView(featureServiceItem) {
10659
- var hasTypekeyword = function (typeKeyword) {
10660
- return featureServiceItem.typeKeywords.indexOf(typeKeyword) > -1;
10661
- };
10662
- // Survey123 only recently added the "FieldworkerView" typekeyword
10663
- var isFieldworker = hasTypekeyword("FieldworkerView");
10664
- // we should support previously created fieldworkers too
10665
- if (!isFieldworker) {
10666
- var hasExpectedTypeKeywords = [
10667
- "Survey123",
10668
- "Feature Service",
10669
- "View Service",
10670
- ].every(hasTypekeyword);
10671
- isFieldworker =
10672
- hasExpectedTypeKeywords && !hasTypekeyword("StakeholderView");
10673
- }
10674
- return isFieldworker;
10675
- }
10676
-
10677
- /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
10678
- * Apache-2.0 */
10679
- /**
10680
- * Builds a dictionary of Survey items for the given Form model
10681
- * @param {string} formId The Form ID of the survey
10682
- * @param {IRequestOptions} requestOptions The request options
10683
- * @returns {Promise<IGetSurveyModelsResponse>}
10684
- */
10685
- var getSurveyModels = function (formItemOrId, requestOptions) {
10686
- var fieldworker;
10687
- var stakeholder;
10688
- var getForm = function () {
10689
- return typeof formItemOrId === "string"
10690
- ? getItem(formItemOrId, requestOptions)
10691
- : Promise.resolve(formItemOrId);
10692
- };
10693
- return getForm().then(function (form) {
10694
- var promises = [
10695
- // the primary input will be the fieldworker (if it exists), otherwise
10696
- // the source feature service.
10697
- getInputFeatureServiceModel(form.id, requestOptions),
10698
- getStakeholderModel(form.id, requestOptions),
10699
- ];
10700
- return Promise.all(promises)
10701
- .then(function (_a) {
10702
- var featureServiceOrFieldworkerModelResult = _a[0], stakeholderResult = _a[1];
10703
- stakeholder = stakeholderResult;
10704
- if (featureServiceOrFieldworkerModelResult &&
10705
- isFieldworkerView(featureServiceOrFieldworkerModelResult.item)) {
10706
- fieldworker = featureServiceOrFieldworkerModelResult;
10707
- // if the primary input is the fieldworker, fetch
10708
- // the source feature service
10709
- return getSourceFeatureServiceModelFromFieldworker(fieldworker.item.id, requestOptions);
10710
- }
10711
- else {
10712
- return featureServiceOrFieldworkerModelResult;
10713
- }
10714
- })
10715
- .then(function (featureService) {
10716
- return {
10717
- form: { item: form },
10718
- featureService: featureService,
10719
- fieldworker: fieldworker,
10720
- stakeholder: stakeholder,
10721
- };
10722
- });
11947
+ model = { item: featureService };
11948
+ }
11949
+ return model;
10723
11950
  });
10724
11951
  };
10725
11952
 
11953
+ /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
11954
+ * Apache-2.0 */
10726
11955
  /**
10727
- * Hash of Hub API end points so updates
10728
- * are centralized
11956
+ * Fetches a Survey's source Feature Service from a given
11957
+ * Fieldworker View ID
11958
+ * @param {string} fieldworkerId The Fieldworker View ID
11959
+ * @param {IRequestOptions} requestOptions The request options
11960
+ * @returns {Promise<IModel>}
10729
11961
  */
10730
- var hubApiEndpoints = {
10731
- domains: "/api/v3/domains",
10732
- search: "/api/v3/datasets",
10733
- discussions: "/api/discussions/v1",
11962
+ var getSourceFeatureServiceModelFromFieldworker = function (fieldworkerId, requestOptions) {
11963
+ return getRelatedItems(__assign({ id: fieldworkerId, relationshipType: "Service2Data", direction: "forward" }, requestOptions)).then(function (_a) {
11964
+ var featureService = _a.relatedItems[0];
11965
+ var model;
11966
+ if (featureService) {
11967
+ model = { item: featureService };
11968
+ }
11969
+ return model;
11970
+ });
10734
11971
  };
11972
+
11973
+ /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
11974
+ * Apache-2.0 */
10735
11975
  /**
10736
- * @internal
10737
- * Thin class just used to enable getters
10738
- *
10739
- * This class should not be used by anything other than
10740
- * the ArcGISContext class
11976
+ * Fetches a Survey's Stakeholder View for a given
11977
+ * Form ID
11978
+ * @param {string} formId A Form ID
11979
+ * @param {IRequestOptions} requestOptions The request options
11980
+ * @returns {Promise<IModel>}
10741
11981
  */
10742
- var ArcGISContextState = /** @class */ (function () {
10743
- function ArcGISContextState(opts) {
10744
- this._portalUrl = "https://www.arcgis.com";
10745
- this.id = opts.id;
10746
- this._portalUrl = opts.portalUrl;
10747
- this._hubUrl = opts.hubUrl;
10748
- if (opts.authentication) {
10749
- this._authentication = opts.authentication;
10750
- }
10751
- if (opts.portalSelf) {
10752
- this._portalSelf = opts.portalSelf;
10753
- }
10754
- if (opts.currentUser) {
10755
- this._currentUser = opts.currentUser;
11982
+ var getStakeholderModel = function (formId, requestOptions) {
11983
+ return getRelatedItems(__assign({ id: formId, relationshipType: "Survey2Data", direction: "forward" }, requestOptions)).then(function (_a) {
11984
+ var stakeholderView = _a.relatedItems[0];
11985
+ var model;
11986
+ if (stakeholderView) {
11987
+ model = { item: stakeholderView };
10756
11988
  }
10757
- }
10758
- Object.defineProperty(ArcGISContextState.prototype, "session", {
10759
- /**
10760
- * Return the UserSession if authenticated
10761
- */
10762
- get: function () {
10763
- return this._authentication;
10764
- },
10765
- enumerable: false,
10766
- configurable: true
10767
- });
10768
- Object.defineProperty(ArcGISContextState.prototype, "isAuthenticated", {
10769
- /**
10770
- * Return boolean indicating if authenticatio is present
10771
- */
10772
- get: function () {
10773
- return !!this._authentication;
10774
- },
10775
- enumerable: false,
10776
- configurable: true
10777
- });
10778
- Object.defineProperty(ArcGISContextState.prototype, "userRequestOptions", {
10779
- /**
10780
- * Return `IUserRequestOptions`, which is used for REST-JS
10781
- * functions which require authentication information.
10782
- *
10783
- * If context is not authenticated, this function will throw
10784
- */
10785
- get: function () {
10786
- if (this.isAuthenticated) {
10787
- return {
10788
- authentication: this._authentication,
10789
- portal: this.sharingApiUrl,
10790
- };
10791
- }
10792
- },
10793
- enumerable: false,
10794
- configurable: true
10795
- });
10796
- Object.defineProperty(ArcGISContextState.prototype, "requestOptions", {
10797
- /**
10798
- * Return `IRequestOptions`, which is used by REST-JS functions
10799
- * which *may* use authentication information if provided.
10800
- *
10801
- * If context is not authenticated, this function just returns
10802
- * the `portal` property, which informs REST-JS what Sharing API
10803
- * instance to use (i.e. AGO, Enterprise etc)
10804
- */
10805
- get: function () {
10806
- var ro = {
10807
- portal: this.sharingApiUrl,
10808
- };
10809
- if (this.isAuthenticated) {
10810
- ro = {
10811
- authentication: this._authentication,
10812
- portal: this.sharingApiUrl,
10813
- };
10814
- }
10815
- return ro;
10816
- },
10817
- enumerable: false,
10818
- configurable: true
10819
- });
10820
- Object.defineProperty(ArcGISContextState.prototype, "hubRequestOptions", {
10821
- /**
10822
- * Return a `IHubRequestOptions` object
10823
- */
10824
- get: function () {
10825
- // We may add more logic around what is returned in some corner cases
10826
- return {
10827
- authentication: this.session,
10828
- isPortal: this.isPortal,
10829
- portalSelf: this.portal,
10830
- hubApiUrl: this.hubUrl,
10831
- };
10832
- },
10833
- enumerable: false,
10834
- configurable: true
10835
- });
10836
- Object.defineProperty(ArcGISContextState.prototype, "portalUrl", {
10837
- // ==============================
10838
- // Getters / Computed Properties
10839
- // ==============================
10840
- /**
10841
- * Return the portal url.
10842
- *
10843
- * If authenticated @ ArcGIS Online, it will return
10844
- * the https://org.env.arcgis.com
10845
- *
10846
- * If authenticated @ ArcGIS Enterprise, it will return
10847
- * https://portalHostname, which includes the web adaptor
10848
- */
10849
- get: function () {
10850
- if (this.isAuthenticated) {
10851
- if (this.isPortal) {
10852
- return "https://" + this._portalSelf.portalHostname;
10853
- }
10854
- else {
10855
- return "https://" + this._portalSelf.urlKey + "." + this._portalSelf.customBaseUrl;
10856
- }
10857
- }
10858
- else {
10859
- return this._portalUrl;
10860
- }
10861
- },
10862
- enumerable: false,
10863
- configurable: true
10864
- });
10865
- Object.defineProperty(ArcGISContextState.prototype, "sharingApiUrl", {
10866
- /**
10867
- * Returns the url to the sharing api
10868
- * i.e. https://myorg.maps.arcgis.com/sharing/rest
10869
- */
10870
- get: function () {
10871
- return this.portalUrl + "/sharing/rest";
10872
- },
10873
- enumerable: false,
10874
- configurable: true
10875
- });
10876
- Object.defineProperty(ArcGISContextState.prototype, "hubUrl", {
10877
- get: function () {
10878
- return this._hubUrl;
10879
- },
10880
- enumerable: false,
10881
- configurable: true
10882
- });
10883
- Object.defineProperty(ArcGISContextState.prototype, "isPortal", {
10884
- /**
10885
- * Returns boolean indicating if the backing system
10886
- * is ArcGIS Enterprise (formerly ArcGIS Portal) or not
10887
- */
10888
- get: function () {
10889
- return this._portalSelf
10890
- ? this._portalSelf.isPortal
10891
- : this._portalUrl.indexOf("arcgis.com") === -1;
10892
- },
10893
- enumerable: false,
10894
- configurable: true
10895
- });
10896
- Object.defineProperty(ArcGISContextState.prototype, "discussionsServiceUrl", {
10897
- // Hub APIs
10898
- // ----------
10899
- // Discussions
10900
- get: function () {
10901
- if (this._hubUrl) {
10902
- return "" + this._hubUrl + hubApiEndpoints.discussions;
10903
- }
10904
- },
10905
- enumerable: false,
10906
- configurable: true
10907
- });
10908
- Object.defineProperty(ArcGISContextState.prototype, "hubSearchServiceUrl", {
10909
- // Hub Search
10910
- get: function () {
10911
- if (this._hubUrl) {
10912
- return "" + this._hubUrl + hubApiEndpoints.search;
10913
- }
10914
- },
10915
- enumerable: false,
10916
- configurable: true
10917
- });
10918
- Object.defineProperty(ArcGISContextState.prototype, "domainServiceUrl", {
10919
- // Domain
10920
- get: function () {
10921
- if (this._hubUrl) {
10922
- return "" + this._hubUrl + hubApiEndpoints.domains;
10923
- }
10924
- },
10925
- enumerable: false,
10926
- configurable: true
10927
- });
10928
- Object.defineProperty(ArcGISContextState.prototype, "eventsConfig", {
10929
- // Events
10930
- // returns `{serviceId: '3ef..', publicViewId: 'bc3...'}
10931
- get: function () {
10932
- if (this._portalSelf) {
10933
- return getProp(this._portalSelf, "portalProperties.hub.settings.events");
10934
- }
10935
- },
10936
- enumerable: false,
10937
- configurable: true
10938
- });
10939
- Object.defineProperty(ArcGISContextState.prototype, "hubEnabled", {
10940
- /**
10941
- * Returns boolean indicating if the current user
10942
- * belongs to an organization that has licensed
10943
- * ArcGIS Hub
10944
- */
10945
- get: function () {
10946
- return getWithDefault$1(this._portalSelf, "portalProperties.hub.enabled", false);
10947
- },
10948
- enumerable: false,
10949
- configurable: true
10950
- });
10951
- Object.defineProperty(ArcGISContextState.prototype, "communityOrgId", {
10952
- /**
10953
- * Return Hub Community Org Id, if defined
10954
- */
10955
- get: function () {
10956
- if (this._portalSelf) {
10957
- return getProp(this._portalSelf, "portalProperties.hub.settings.communityOrg.orgId");
10958
- }
10959
- },
10960
- enumerable: false,
10961
- configurable: true
10962
- });
10963
- Object.defineProperty(ArcGISContextState.prototype, "communityOrgHostname", {
10964
- get: function () {
10965
- if (this._portalSelf) {
10966
- return getProp(this._portalSelf, "portalProperties.hub.settings.communityOrg.portalHostname");
10967
- }
10968
- },
10969
- enumerable: false,
10970
- configurable: true
11989
+ return model;
10971
11990
  });
10972
- Object.defineProperty(ArcGISContextState.prototype, "communityOrgUrl", {
10973
- get: function () {
10974
- if (this.communityOrgHostname) {
10975
- return "https://" + this.communityOrgHostname;
11991
+ };
11992
+
11993
+ /**
11994
+ * Determines if the provided Feature Service item is a
11995
+ * Fieldworker View
11996
+ * @param {IItem} featureServiceItem
11997
+ * @returns {boolean}
11998
+ */
11999
+ function isFieldworkerView(featureServiceItem) {
12000
+ var hasTypekeyword = function (typeKeyword) {
12001
+ return featureServiceItem.typeKeywords.indexOf(typeKeyword) > -1;
12002
+ };
12003
+ // Survey123 only recently added the "FieldworkerView" typekeyword
12004
+ var isFieldworker = hasTypekeyword("FieldworkerView");
12005
+ // we should support previously created fieldworkers too
12006
+ if (!isFieldworker) {
12007
+ var hasExpectedTypeKeywords = [
12008
+ "Survey123",
12009
+ "Feature Service",
12010
+ "View Service",
12011
+ ].every(hasTypekeyword);
12012
+ isFieldworker =
12013
+ hasExpectedTypeKeywords && !hasTypekeyword("StakeholderView");
12014
+ }
12015
+ return isFieldworker;
12016
+ }
12017
+
12018
+ /* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
12019
+ * Apache-2.0 */
12020
+ /**
12021
+ * Builds a dictionary of Survey items for the given Form model
12022
+ * @param {string} formId The Form ID of the survey
12023
+ * @param {IRequestOptions} requestOptions The request options
12024
+ * @returns {Promise<IGetSurveyModelsResponse>}
12025
+ */
12026
+ var getSurveyModels = function (formItemOrId, requestOptions) {
12027
+ var fieldworker;
12028
+ var stakeholder;
12029
+ var getForm = function () {
12030
+ return typeof formItemOrId === "string"
12031
+ ? getItem(formItemOrId, requestOptions)
12032
+ : Promise.resolve(formItemOrId);
12033
+ };
12034
+ return getForm().then(function (form) {
12035
+ var promises = [
12036
+ // the primary input will be the fieldworker (if it exists), otherwise
12037
+ // the source feature service.
12038
+ getInputFeatureServiceModel(form.id, requestOptions),
12039
+ getStakeholderModel(form.id, requestOptions),
12040
+ ];
12041
+ return Promise.all(promises)
12042
+ .then(function (_a) {
12043
+ var featureServiceOrFieldworkerModelResult = _a[0], stakeholderResult = _a[1];
12044
+ stakeholder = stakeholderResult;
12045
+ if (featureServiceOrFieldworkerModelResult &&
12046
+ isFieldworkerView(featureServiceOrFieldworkerModelResult.item)) {
12047
+ fieldworker = featureServiceOrFieldworkerModelResult;
12048
+ // if the primary input is the fieldworker, fetch
12049
+ // the source feature service
12050
+ return getSourceFeatureServiceModelFromFieldworker(fieldworker.item.id, requestOptions);
10976
12051
  }
10977
- },
10978
- enumerable: false,
10979
- configurable: true
10980
- });
10981
- Object.defineProperty(ArcGISContextState.prototype, "helperServices", {
10982
- // Platform API service urls are all in helperServices
10983
- // and not consistent to expose as urls
10984
- get: function () {
10985
- if (this._portalSelf) {
10986
- return this._portalSelf.helperServices;
12052
+ else {
12053
+ return featureServiceOrFieldworkerModelResult;
10987
12054
  }
10988
- },
10989
- enumerable: false,
10990
- configurable: true
10991
- });
10992
- Object.defineProperty(ArcGISContextState.prototype, "currentUser", {
10993
- get: function () {
10994
- return this._currentUser;
10995
- },
10996
- enumerable: false,
10997
- configurable: true
10998
- });
10999
- Object.defineProperty(ArcGISContextState.prototype, "portal", {
11000
- get: function () {
11001
- return this._portalSelf;
11002
- },
11003
- enumerable: false,
11004
- configurable: true
12055
+ })
12056
+ .then(function (featureService) {
12057
+ return {
12058
+ form: { item: form },
12059
+ featureService: featureService,
12060
+ fieldworker: fieldworker,
12061
+ stakeholder: stakeholder,
12062
+ };
12063
+ });
11005
12064
  });
11006
- return ArcGISContextState;
11007
- }());
12065
+ };
11008
12066
 
11009
12067
  /**
11010
- * Application Context Object
12068
+ * Hub class can be used as an entry point to managing
12069
+ * content, teams, sites, projects etc, in an organization's Hub.
12070
+ *
12071
+ * ```js
12072
+ * import {Hub} from '@esri/hub-common';
12073
+ * // create a Hub instance, authenticating as a specific user
12074
+ * // working against arcgis online
12075
+ * const myHub = await Hub.create({authOptions: {username: "casey", password: "jones"}});
12076
+ *
12077
+ * myHub.context.currentUser //=> {username: "casey", ...} as IUser
11011
12078
  *
11012
- * Abstraction that combines a `UserSession` with
11013
- * the `portal/self` and `user/self` responses to
11014
- * provide a central lookup of platform information.
12079
+ * const projectStore = await myHub.getProjectStore();
11015
12080
  *
11016
- * This is a work-in-progress, and will likely expand over time.
12081
+ * const pavingProject = await projectStore.create({name: "12th Street Paving"});
12082
+ * pavingProject.summary = "This is the 2024 planned paving of 12th Street, between 8th and 11th Ave";
12083
+ * await projectStore.update(pavingProject);
12084
+ * ```
11017
12085
  *
11018
- * `ArcGISContext` is used in conjuction with the `arcgis-app-identity`
11019
- * component to orchestrate oAuth.
12086
+ * This is a convenience class. Hub Stores can be created
12087
+ * directly, or the underlying functions can be imported an used
12088
+ * as need for scenarios where these class structures introduce
12089
+ * unwanted complexity
11020
12090
  */
11021
- var ArcGISContext = /** @class */ (function () {
12091
+ var Hub = /** @class */ (function () {
11022
12092
  /**
11023
- * Private constructor. Use `ArcGISContext.create(...)` to
11024
- * instantiate an instance
11025
- * @param opts
12093
+ * Private so we can employ a factory function should we need
12094
+ * async work during creation
12095
+ * @param contextManager
11026
12096
  */
11027
- function ArcGISContext(opts) {
11028
- this._portalUrl = "https://www.arcgis.com";
11029
- this._debug = false;
11030
- // Having a unique id makes debugging easier
11031
- this.id = new Date().getTime();
11032
- if (opts.debug) {
11033
- this._debug = opts.debug;
11034
- }
11035
- this.log("ArcGISContext:ctor: Creating " + this.id);
11036
- if (opts.authentication) {
11037
- this._authentication = opts.authentication;
11038
- this._portalUrl = this._authentication.portal.replace("/sharing/rest", "");
11039
- this._hubUrl = getHubApiFromPortalUrl(this._portalUrl);
11040
- }
11041
- else if (opts.portalUrl) {
11042
- this._portalUrl = opts.portalUrl;
11043
- this._hubUrl = getHubApiFromPortalUrl(this._portalUrl);
11044
- }
11045
- else {
11046
- this._hubUrl = getHubApiFromPortalUrl(this._portalUrl);
11047
- }
11048
- if (opts.portal) {
11049
- this._portalSelf = cloneObject$1(opts.portal);
11050
- }
11051
- if (opts.currentUser) {
11052
- this._currentUser = cloneObject$1(opts.currentUser);
11053
- }
12097
+ function Hub(contextManager) {
12098
+ this._contextManager = contextManager;
11054
12099
  }
11055
12100
  /**
11056
- * Static async Factory
11057
- * @param opts
12101
+ * Factory function to construct a new HubProjectStore instance.
12102
+ *
12103
+ * Note: Used so that we could do async actions in the ctor.
12104
+ * @param contextManager
11058
12105
  * @returns
11059
12106
  */
11060
- ArcGISContext.create = function (opts) {
11061
- if (opts === void 0) { opts = {}; }
11062
- return __awaiter(this, void 0, void 0, function () {
11063
- var ctx;
11064
- return __generator(this, function (_a) {
11065
- switch (_a.label) {
11066
- case 0:
11067
- ctx = new ArcGISContext(opts);
11068
- return [4 /*yield*/, ctx.initialize()];
11069
- case 1:
11070
- _a.sent();
11071
- return [2 /*return*/, ctx];
11072
- }
11073
- });
11074
- });
11075
- };
11076
- /**
11077
- * Set the Authentication (UserSession) for the context.
11078
- * This should be called when a user signs into a running
11079
- * application.
11080
- * @param auth
11081
- */
11082
- ArcGISContext.prototype.setAuthentication = function (auth) {
12107
+ Hub.create = function (options) {
11083
12108
  return __awaiter(this, void 0, void 0, function () {
12109
+ var opts, mgr;
11084
12110
  return __generator(this, function (_a) {
11085
12111
  switch (_a.label) {
11086
12112
  case 0:
11087
- this._authentication = auth;
11088
- this._portalUrl = auth.portal.replace("/sharing/rest", "");
11089
- return [4 /*yield*/, this.initialize()];
12113
+ if (!options.contextManager) return [3 /*break*/, 1];
12114
+ return [2 /*return*/, new Hub(options.contextManager)];
11090
12115
  case 1:
11091
- _a.sent();
11092
- return [2 /*return*/];
12116
+ opts = options.managerOptions || {};
12117
+ return [4 /*yield*/, ArcGISContextManager.create(opts)];
12118
+ case 2:
12119
+ mgr = _a.sent();
12120
+ return [2 /*return*/, new Hub(mgr)];
11093
12121
  }
11094
12122
  });
11095
12123
  });
11096
12124
  };
11097
- /**
11098
- * Clear the Authentication (UserSession). This should be
11099
- * called when a user signs out of an application, but
11100
- * the application continues running
11101
- */
11102
- ArcGISContext.prototype.clearAuthentication = function () {
11103
- // Reset the portalUrl from the org url to the base url
11104
- // for ArcGIS Enterprise, we just leave the _portalUrl as-is
11105
- if (!this._state.isPortal) {
11106
- this._portalUrl = getPortalBaseFromOrgUrl(this._portalUrl);
11107
- }
11108
- // Clear the auth, portalSelf and currentUser props
11109
- this._authentication = null;
11110
- this._portalSelf = null;
11111
- this._currentUser = null;
11112
- this._state = new ArcGISContextState({
11113
- id: this.id,
11114
- portalUrl: this._portalUrl,
11115
- hubUrl: this._hubUrl,
11116
- });
11117
- };
11118
- Object.defineProperty(ArcGISContext.prototype, "state", {
12125
+ Object.defineProperty(Hub.prototype, "context", {
11119
12126
  /**
11120
- * Return a reference to the current state.
11121
- * When `.setAuthentication()` or `.clearAuthenentication()` are
11122
- * called, the state will be re-created. This is done so frameworks
11123
- * like React or Ember can detect changes.
12127
+ * Getter to abstract the context manager
11124
12128
  */
11125
12129
  get: function () {
11126
- return this._state;
12130
+ return this._contextManager.context;
11127
12131
  },
11128
12132
  enumerable: false,
11129
12133
  configurable: true
11130
12134
  });
11131
- /**
11132
- * @internal
11133
- * Log debugging messages to the console
11134
- * @param message
11135
- */
11136
- ArcGISContext.prototype.log = function (message) {
11137
- if (this._debug) {
11138
- // tslint:disable-next-line:no-console
11139
- console.info(message);
11140
- }
11141
- };
11142
- /**
11143
- * If we have a UserSession, fetch portal/self and
11144
- * store that along with current user
11145
- */
11146
- ArcGISContext.prototype.initialize = function () {
11147
- return __awaiter(this, void 0, void 0, function () {
11148
- var username, requests, _a, portal, user, ex_1, msg;
11149
- return __generator(this, function (_b) {
11150
- switch (_b.label) {
11151
- case 0:
11152
- if (!(this._authentication && (!this._portalSelf || !this._currentUser))) return [3 /*break*/, 4];
11153
- this.log("ArcGISContext-" + this.id + ": Initializing");
11154
- username = this._authentication.username;
11155
- requests = [
11156
- getSelf({ authentication: this._authentication }),
11157
- getUser({ username: username, authentication: this._authentication }),
11158
- ];
11159
- _b.label = 1;
11160
- case 1:
11161
- _b.trys.push([1, 3, , 4]);
11162
- return [4 /*yield*/, Promise.all(requests)];
11163
- case 2:
11164
- _a = _b.sent(), portal = _a[0], user = _a[1];
11165
- this._portalSelf = portal;
11166
- this._currentUser = user;
11167
- return [3 /*break*/, 4];
11168
- case 3:
11169
- ex_1 = _b.sent();
11170
- msg = "ArcGISContext could not fetch portal & user for \"" + this._authentication.username + "\" using " + this._authentication.portal + ".";
11171
- // tslint:disable-next-line:no-console
11172
- console.error(msg);
11173
- throw ex_1;
11174
- case 4:
11175
- // update the state
11176
- this._state = new ArcGISContextState(this.stateOpts);
11177
- return [2 /*return*/];
11178
- }
11179
- });
11180
- });
11181
- };
11182
- Object.defineProperty(ArcGISContext.prototype, "stateOpts", {
12135
+ Object.defineProperty(Hub.prototype, "projects", {
12136
+ /**
12137
+ * Create a Project Store connected to the current Hub
12138
+ * @returns
12139
+ */
11183
12140
  get: function () {
11184
- var stateOpts = {
11185
- id: this.id,
11186
- portalUrl: this._portalUrl,
11187
- hubUrl: this._hubUrl,
11188
- };
11189
- if (this._authentication) {
11190
- stateOpts.authentication = this._authentication;
11191
- }
11192
- if (this._portalSelf) {
11193
- stateOpts.portalSelf = this._portalSelf;
12141
+ if (!this._projectManager) {
12142
+ this._projectManager = HubProjectManager.init(this._contextManager);
11194
12143
  }
11195
- if (this._currentUser) {
11196
- stateOpts.currentUser = this._currentUser;
11197
- }
11198
- return stateOpts;
12144
+ return this._projectManager;
11199
12145
  },
11200
12146
  enumerable: false,
11201
12147
  configurable: true
11202
12148
  });
11203
- return ArcGISContext;
12149
+ return Hub;
11204
12150
  }());
11205
- /**
11206
- * Cross-walk from a portalUrl to the corresponding Hub.
11207
- *
11208
- * If the passed url is not recognized, then this will return `undefined`
11209
- * @param portalUrl
11210
- * @returns
11211
- */
11212
- function getHubApiFromPortalUrl(portalUrl) {
11213
- var result;
11214
- if (portalUrl.match(/(qaext|\.mapsqa)\.arcgis.com/)) {
11215
- result = "https://hubqa.arcgis.com";
11216
- }
11217
- else if (portalUrl.match(/(devext|\.mapsdevext)\.arcgis.com/)) {
11218
- result = "https://hubdev.arcgis.com";
11219
- }
11220
- else if (portalUrl.match(/(www|\.maps)\.arcgis.com/)) {
11221
- result = "https://hub.arcgis.com";
11222
- }
11223
- return result;
11224
- }
11225
- function getPortalBaseFromOrgUrl(orgUrl) {
11226
- var result;
11227
- if (orgUrl.match(/(qaext|\.mapsqa)\.arcgis.com/)) {
11228
- result = "https://qaext.arcgis.com";
11229
- }
11230
- else if (orgUrl.match(/(devext|\.mapsdevext)\.arcgis.com/)) {
11231
- result = "https://devext.arcgis.com";
11232
- }
11233
- else {
11234
- /* istanbul ignore else */
11235
- if (orgUrl.match(/(www|\.maps)\.arcgis.com/)) {
11236
- result = "https://www.arcgis.com";
11237
- }
11238
- }
11239
- return result;
11240
- }
11241
12151
 
11242
12152
  /* Copyright (c) 2018-2020 Environmental Systems Research Institute, Inc.
11243
12153
  * Apache-2.0 */
@@ -11498,10 +12408,52 @@
11498
12408
  return msg;
11499
12409
  }
11500
12410
 
12411
+ /**
12412
+ * Generic Hub Error with an Error stack as well
12413
+ * as an optional serialized OperationStack.
12414
+ *
12415
+ * Also accepts a `rootCause` Error object
12416
+ */
12417
+ var HubError = /** @class */ (function (_super) {
12418
+ __extends(HubError, _super);
12419
+ /**
12420
+ * Creates an instance of HubError.
12421
+ * @param {string} operation
12422
+ * @param {string} [message]
12423
+ * @param {Error} [rootCause]
12424
+ * @memberof HubError
12425
+ */
12426
+ function HubError(operation, message, rootCause) {
12427
+ var _this = this;
12428
+ message = message || "UNKNOWN_ERROR";
12429
+ // if the rootCause has a .rootCause, use that so we don't deeply nest
12430
+ rootCause = getWithDefault$1(rootCause, "rootCause", rootCause);
12431
+ /* Skip coverage on super(...) as per:
12432
+ https://github.com/Microsoft/TypeScript/issues/13029
12433
+ https://github.com/SitePen/remap-istanbul/issues/106
12434
+ */
12435
+ /* istanbul ignore next */
12436
+ _this = _super.call(this, operation, message, rootCause) || this;
12437
+ _this.name = "HubError";
12438
+ // if the original error has a stack use it, otherwise create a new
12439
+ // stack. Note: a new Stack will make it look like the error origninated
12440
+ // in the HubError constructor. This is only an issue in tests but
12441
+ // it can be confusing to debug
12442
+ _this.stack = getWithDefault$1(rootCause, "stack", new Error().stack);
12443
+ return _this;
12444
+ }
12445
+ return HubError;
12446
+ }(OperationError));
12447
+
11501
12448
  exports.ArcGISContext = ArcGISContext;
12449
+ exports.ArcGISContextManager = ArcGISContextManager;
11502
12450
  exports.GLOBAL_EXTENT = GLOBAL_EXTENT;
11503
12451
  exports.HUB_CDN_URLMAP = HUB_CDN_URLMAP;
11504
12452
  exports.HUB_LOCALES = HUB_LOCALES;
12453
+ exports.HUB_PROJECT_ITEM_TYPE = HUB_PROJECT_ITEM_TYPE;
12454
+ exports.Hub = Hub;
12455
+ exports.HubError = HubError;
12456
+ exports.HubProjectManager = HubProjectManager;
11505
12457
  exports.Logger = Logger;
11506
12458
  exports.OperationError = OperationError;
11507
12459
  exports.OperationStack = OperationStack;
@@ -11571,6 +12523,7 @@
11571
12523
  exports.cloneObject = cloneObject$1;
11572
12524
  exports.completeOAuth2 = completeOAuth2;
11573
12525
  exports.compose = compose;
12526
+ exports.constructSlug = constructSlug;
11574
12527
  exports.convertContentDefinitionToFilter = convertContentDefinitionToFilter;
11575
12528
  exports.convertContentFilterToSearchOptions = convertContentFilterToSearchOptions;
11576
12529
  exports.convertPortalResponseToFacets = convertPortalResponseToFacets;
@@ -11579,7 +12532,10 @@
11579
12532
  exports.convertUrlsToAnchorTags = convertUrlsToAnchorTags;
11580
12533
  exports.createExtent = createExtent;
11581
12534
  exports.createId = createId;
12535
+ exports.createModel = createModel;
11582
12536
  exports.createOperationPipeline = createOperationPipeline;
12537
+ exports.createProject = createProject;
12538
+ exports.dasherize = dasherize;
11583
12539
  exports.datasetToContent = datasetToContent;
11584
12540
  exports.datasetToItem = datasetToItem;
11585
12541
  exports.deepFind = deepFind;
@@ -11587,6 +12543,7 @@
11587
12543
  exports.deepSet = deepSet;
11588
12544
  exports.deepStringReplace = deepStringReplace;
11589
12545
  exports.deleteProp = deleteProp;
12546
+ exports.destroyProject = destroyProject;
11590
12547
  exports.doesItemExistWithTitle = doesItemExistWithTitle;
11591
12548
  exports.domainExists = domainExists;
11592
12549
  exports.domainExistsPortal = domainExistsPortal;
@@ -11627,6 +12584,7 @@
11627
12584
  exports.getFamily = getFamily;
11628
12585
  exports.getGeographicOrgExtent = getGeographicOrgExtent;
11629
12586
  exports.getGroupThumbnailUrl = getGroupThumbnailUrl;
12587
+ exports.getHubApiFromPortalUrl = getHubApiFromPortalUrl;
11630
12588
  exports.getHubApiUrl = getHubApiUrl;
11631
12589
  exports.getHubApiUrlFromPortal = getHubApiUrlFromPortal;
11632
12590
  exports.getHubLocaleAssetUrl = getHubLocaleAssetUrl;
@@ -11635,6 +12593,7 @@
11635
12593
  exports.getInputFeatureServiceModel = getInputFeatureServiceModel;
11636
12594
  exports.getItemApiUrl = getItemApiUrl;
11637
12595
  exports.getItemAssets = getItemAssets;
12596
+ exports.getItemBySlug = getItemBySlug;
11638
12597
  exports.getItemDataUrl = getItemDataUrl;
11639
12598
  exports.getItemHomeUrl = getItemHomeUrl;
11640
12599
  exports.getItemHubId = getItemHubId;
@@ -11643,13 +12602,17 @@
11643
12602
  exports.getItemThumbnailUrl = getItemThumbnailUrl;
11644
12603
  exports.getLayerIdFromUrl = getLayerIdFromUrl;
11645
12604
  exports.getModel = getModel;
12605
+ exports.getModelBySlug = getModelBySlug;
11646
12606
  exports.getModelFromOptions = getModelFromOptions;
11647
12607
  exports.getNextFunction = getNextFunction;
11648
12608
  exports.getOrgExtentAsBBox = getOrgExtentAsBBox;
11649
12609
  exports.getPortalApiUrl = getPortalApiUrl;
12610
+ exports.getPortalBaseFromOrgUrl = getPortalBaseFromOrgUrl;
11650
12611
  exports.getPortalUrl = getPortalUrl;
12612
+ exports.getProject = getProject;
11651
12613
  exports.getProp = getProp;
11652
12614
  exports.getProps = getProps;
12615
+ exports.getProxyUrl = getProxyUrl;
11653
12616
  exports.getServiceTypeFromUrl = getServiceTypeFromUrl;
11654
12617
  exports.getSession = getSession;
11655
12618
  exports.getSiteById = getSiteById;
@@ -11664,6 +12627,7 @@
11664
12627
  exports.getUniqueDomainName = getUniqueDomainName;
11665
12628
  exports.getUniqueDomainNamePortal = getUniqueDomainNamePortal;
11666
12629
  exports.getUniqueItemTitle = getUniqueItemTitle;
12630
+ exports.getUniqueSlug = getUniqueSlug;
11667
12631
  exports.getUserThumbnailUrl = getUserThumbnailUrl;
11668
12632
  exports.getWithDefault = getWithDefault$1;
11669
12633
  exports.hasBasePriv = hasBasePriv;
@@ -11729,6 +12693,7 @@
11729
12693
  exports.setContentSiteUrls = setContentSiteUrls;
11730
12694
  exports.setContentType = setContentType;
11731
12695
  exports.setProp = setProp;
12696
+ exports.setSlugKeyword = setSlugKeyword;
11732
12697
  exports.shareItemToGroups = shareItemToGroups;
11733
12698
  exports.slugify = slugify;
11734
12699
  exports.stringToBlob = stringToBlob;
@@ -11738,6 +12703,8 @@
11738
12703
  exports.unprotectModel = unprotectModel;
11739
12704
  exports.unshareItemFromGroups = unshareItemFromGroups;
11740
12705
  exports.updateDomain = updateDomain;
12706
+ exports.updateModel = updateModel;
12707
+ exports.updateProject = updateProject;
11741
12708
  exports.upgradeProtocol = upgradeProtocol;
11742
12709
  exports.upgradeSiteSchema = upgradeSiteSchema;
11743
12710
  exports.uploadResourcesFromUrl = uploadResourcesFromUrl;