@esri/solution-common 5.2.1 → 5.2.3

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 (212) hide show
  1. package/README.md +4 -7
  2. package/dist/esm/completeItem.js +3 -3
  3. package/dist/esm/completeItem.js.map +1 -1
  4. package/dist/esm/formHelpers.d.ts +41 -0
  5. package/dist/esm/formHelpers.js +71 -0
  6. package/dist/esm/formHelpers.js.map +1 -0
  7. package/dist/esm/generalHelpers.d.ts +33 -0
  8. package/dist/esm/generalHelpers.js +44 -1
  9. package/dist/esm/generalHelpers.js.map +1 -1
  10. package/dist/esm/index.d.ts +2 -0
  11. package/dist/esm/index.js +2 -0
  12. package/dist/esm/index.js.map +1 -1
  13. package/dist/esm/interfaces.d.ts +19 -1
  14. package/dist/esm/interfaces.js.map +1 -1
  15. package/dist/esm/restHelpers.d.ts +10 -1
  16. package/dist/esm/restHelpers.js +25 -1
  17. package/dist/esm/restHelpers.js.map +1 -1
  18. package/dist/esm/templatization.js +5 -3
  19. package/dist/esm/templatization.js.map +1 -1
  20. package/dist/esm/workflowHelpers.d.ts +21 -1
  21. package/dist/esm/workflowHelpers.js +48 -48
  22. package/dist/esm/workflowHelpers.js.map +1 -1
  23. package/dist/esm/zip-utils.d.ts +44 -17
  24. package/dist/esm/zip-utils.js +73 -24
  25. package/dist/esm/zip-utils.js.map +1 -1
  26. package/package.json +3 -3
  27. package/dist/cjs/completeItem.d.ts +0 -29
  28. package/dist/cjs/completeItem.js +0 -92
  29. package/dist/cjs/completeItem.js.map +0 -1
  30. package/dist/cjs/create-hub-request-options.d.ts +0 -29
  31. package/dist/cjs/create-hub-request-options.js +0 -64
  32. package/dist/cjs/create-hub-request-options.js.map +0 -1
  33. package/dist/cjs/deleteHelpers/deleteEmptyGroups.d.ts +0 -24
  34. package/dist/cjs/deleteHelpers/deleteEmptyGroups.js +0 -42
  35. package/dist/cjs/deleteHelpers/deleteEmptyGroups.js.map +0 -1
  36. package/dist/cjs/deleteHelpers/deleteGroupIfEmpty.d.ts +0 -27
  37. package/dist/cjs/deleteHelpers/deleteGroupIfEmpty.js +0 -97
  38. package/dist/cjs/deleteHelpers/deleteGroupIfEmpty.js.map +0 -1
  39. package/dist/cjs/deleteHelpers/deleteSolutionContents.d.ts +0 -38
  40. package/dist/cjs/deleteHelpers/deleteSolutionContents.js +0 -130
  41. package/dist/cjs/deleteHelpers/deleteSolutionContents.js.map +0 -1
  42. package/dist/cjs/deleteHelpers/deleteSolutionFolder.d.ts +0 -29
  43. package/dist/cjs/deleteHelpers/deleteSolutionFolder.js +0 -79
  44. package/dist/cjs/deleteHelpers/deleteSolutionFolder.js.map +0 -1
  45. package/dist/cjs/deleteHelpers/deleteSolutionItem.d.ts +0 -30
  46. package/dist/cjs/deleteHelpers/deleteSolutionItem.js +0 -54
  47. package/dist/cjs/deleteHelpers/deleteSolutionItem.js.map +0 -1
  48. package/dist/cjs/deleteHelpers/index.d.ts +0 -22
  49. package/dist/cjs/deleteHelpers/index.js +0 -26
  50. package/dist/cjs/deleteHelpers/index.js.map +0 -1
  51. package/dist/cjs/deleteHelpers/reconstructBuildOrderIds.d.ts +0 -27
  52. package/dist/cjs/deleteHelpers/reconstructBuildOrderIds.js +0 -34
  53. package/dist/cjs/deleteHelpers/reconstructBuildOrderIds.js.map +0 -1
  54. package/dist/cjs/deleteHelpers/removeItems.d.ts +0 -34
  55. package/dist/cjs/deleteHelpers/removeItems.js +0 -112
  56. package/dist/cjs/deleteHelpers/removeItems.js.map +0 -1
  57. package/dist/cjs/deleteHelpers/reportProgress.d.ts +0 -27
  58. package/dist/cjs/deleteHelpers/reportProgress.js +0 -46
  59. package/dist/cjs/deleteHelpers/reportProgress.js.map +0 -1
  60. package/dist/cjs/deleteSolution.d.ts +0 -55
  61. package/dist/cjs/deleteSolution.js +0 -107
  62. package/dist/cjs/deleteSolution.js.map +0 -1
  63. package/dist/cjs/dependencies.d.ts +0 -26
  64. package/dist/cjs/dependencies.js +0 -171
  65. package/dist/cjs/dependencies.js.map +0 -1
  66. package/dist/cjs/featureServiceHelpers.d.ts +0 -799
  67. package/dist/cjs/featureServiceHelpers.js +0 -2438
  68. package/dist/cjs/featureServiceHelpers.js.map +0 -1
  69. package/dist/cjs/generalHelpers.d.ts +0 -400
  70. package/dist/cjs/generalHelpers.js +0 -877
  71. package/dist/cjs/generalHelpers.js.map +0 -1
  72. package/dist/cjs/get-subscription-info.d.ts +0 -27
  73. package/dist/cjs/get-subscription-info.js +0 -39
  74. package/dist/cjs/get-subscription-info.js.map +0 -1
  75. package/dist/cjs/getDeletableSolutionInfo.d.ts +0 -29
  76. package/dist/cjs/getDeletableSolutionInfo.js +0 -53
  77. package/dist/cjs/getDeletableSolutionInfo.js.map +0 -1
  78. package/dist/cjs/getItemTypeAbbrev.d.ts +0 -19
  79. package/dist/cjs/getItemTypeAbbrev.js +0 -186
  80. package/dist/cjs/getItemTypeAbbrev.js.map +0 -1
  81. package/dist/cjs/getSolutionSummary.d.ts +0 -27
  82. package/dist/cjs/getSolutionSummary.js +0 -101
  83. package/dist/cjs/getSolutionSummary.js.map +0 -1
  84. package/dist/cjs/index.d.ts +0 -44
  85. package/dist/cjs/index.js +0 -48
  86. package/dist/cjs/index.js.map +0 -1
  87. package/dist/cjs/interfaces.d.ts +0 -1344
  88. package/dist/cjs/interfaces.js +0 -77
  89. package/dist/cjs/interfaces.js.map +0 -1
  90. package/dist/cjs/libConnectors.d.ts +0 -73
  91. package/dist/cjs/libConnectors.js +0 -115
  92. package/dist/cjs/libConnectors.js.map +0 -1
  93. package/dist/cjs/migrations/apply-schema.d.ts +0 -24
  94. package/dist/cjs/migrations/apply-schema.js +0 -36
  95. package/dist/cjs/migrations/apply-schema.js.map +0 -1
  96. package/dist/cjs/migrations/is-legacy-solution.d.ts +0 -24
  97. package/dist/cjs/migrations/is-legacy-solution.js +0 -40
  98. package/dist/cjs/migrations/is-legacy-solution.js.map +0 -1
  99. package/dist/cjs/migrations/upgrade-three-dot-one.d.ts +0 -27
  100. package/dist/cjs/migrations/upgrade-three-dot-one.js +0 -49
  101. package/dist/cjs/migrations/upgrade-three-dot-one.js.map +0 -1
  102. package/dist/cjs/migrations/upgrade-three-dot-zero.d.ts +0 -27
  103. package/dist/cjs/migrations/upgrade-three-dot-zero.js +0 -43
  104. package/dist/cjs/migrations/upgrade-three-dot-zero.js.map +0 -1
  105. package/dist/cjs/migrations/upgrade-two-dot-five.d.ts +0 -24
  106. package/dist/cjs/migrations/upgrade-two-dot-five.js +0 -73
  107. package/dist/cjs/migrations/upgrade-two-dot-five.js.map +0 -1
  108. package/dist/cjs/migrations/upgrade-two-dot-four.d.ts +0 -24
  109. package/dist/cjs/migrations/upgrade-two-dot-four.js +0 -72
  110. package/dist/cjs/migrations/upgrade-two-dot-four.js.map +0 -1
  111. package/dist/cjs/migrations/upgrade-two-dot-one.d.ts +0 -7
  112. package/dist/cjs/migrations/upgrade-two-dot-one.js +0 -39
  113. package/dist/cjs/migrations/upgrade-two-dot-one.js.map +0 -1
  114. package/dist/cjs/migrations/upgrade-two-dot-seven.d.ts +0 -23
  115. package/dist/cjs/migrations/upgrade-two-dot-seven.js +0 -58
  116. package/dist/cjs/migrations/upgrade-two-dot-seven.js.map +0 -1
  117. package/dist/cjs/migrations/upgrade-two-dot-six.d.ts +0 -27
  118. package/dist/cjs/migrations/upgrade-two-dot-six.js +0 -61
  119. package/dist/cjs/migrations/upgrade-two-dot-six.js.map +0 -1
  120. package/dist/cjs/migrations/upgrade-two-dot-three.d.ts +0 -23
  121. package/dist/cjs/migrations/upgrade-two-dot-three.js +0 -55
  122. package/dist/cjs/migrations/upgrade-two-dot-three.js.map +0 -1
  123. package/dist/cjs/migrations/upgrade-two-dot-two.d.ts +0 -23
  124. package/dist/cjs/migrations/upgrade-two-dot-two.js +0 -58
  125. package/dist/cjs/migrations/upgrade-two-dot-two.js.map +0 -1
  126. package/dist/cjs/migrations/upgrade-two-dot-zero.d.ts +0 -44
  127. package/dist/cjs/migrations/upgrade-two-dot-zero.js +0 -95
  128. package/dist/cjs/migrations/upgrade-two-dot-zero.js.map +0 -1
  129. package/dist/cjs/migrator.d.ts +0 -25
  130. package/dist/cjs/migrator.js +0 -77
  131. package/dist/cjs/migrator.js.map +0 -1
  132. package/dist/cjs/resourceHelpers.d.ts +0 -191
  133. package/dist/cjs/resourceHelpers.js +0 -384
  134. package/dist/cjs/resourceHelpers.js.map +0 -1
  135. package/dist/cjs/resources/add-resource-from-blob.d.ts +0 -26
  136. package/dist/cjs/resources/add-resource-from-blob.js +0 -52
  137. package/dist/cjs/resources/add-resource-from-blob.js.map +0 -1
  138. package/dist/cjs/resources/addMetadataFromBlob.d.ts +0 -25
  139. package/dist/cjs/resources/addMetadataFromBlob.js +0 -43
  140. package/dist/cjs/resources/addMetadataFromBlob.js.map +0 -1
  141. package/dist/cjs/resources/convert-item-resource-to-storage-resource.d.ts +0 -32
  142. package/dist/cjs/resources/convert-item-resource-to-storage-resource.js +0 -70
  143. package/dist/cjs/resources/convert-item-resource-to-storage-resource.js.map +0 -1
  144. package/dist/cjs/resources/convert-storage-resource-to-item-resource.d.ts +0 -29
  145. package/dist/cjs/resources/convert-storage-resource-to-item-resource.js +0 -70
  146. package/dist/cjs/resources/convert-storage-resource-to-item-resource.js.map +0 -1
  147. package/dist/cjs/resources/copyAssociatedFiles.d.ts +0 -67
  148. package/dist/cjs/resources/copyAssociatedFiles.js +0 -304
  149. package/dist/cjs/resources/copyAssociatedFiles.js.map +0 -1
  150. package/dist/cjs/resources/copyDataIntoItem.d.ts +0 -33
  151. package/dist/cjs/resources/copyDataIntoItem.js +0 -62
  152. package/dist/cjs/resources/copyDataIntoItem.js.map +0 -1
  153. package/dist/cjs/resources/copyMetadataIntoItem.d.ts +0 -26
  154. package/dist/cjs/resources/copyMetadataIntoItem.js +0 -46
  155. package/dist/cjs/resources/copyMetadataIntoItem.js.map +0 -1
  156. package/dist/cjs/resources/copyResourceIntoZip.d.ts +0 -33
  157. package/dist/cjs/resources/copyResourceIntoZip.js +0 -78
  158. package/dist/cjs/resources/copyResourceIntoZip.js.map +0 -1
  159. package/dist/cjs/resources/copyZipIntoItem.d.ts +0 -25
  160. package/dist/cjs/resources/copyZipIntoItem.js +0 -54
  161. package/dist/cjs/resources/copyZipIntoItem.js.map +0 -1
  162. package/dist/cjs/resources/createCopyResults.d.ts +0 -25
  163. package/dist/cjs/resources/createCopyResults.js +0 -36
  164. package/dist/cjs/resources/createCopyResults.js.map +0 -1
  165. package/dist/cjs/resources/get-blob.d.ts +0 -26
  166. package/dist/cjs/resources/get-blob.js +0 -27
  167. package/dist/cjs/resources/get-blob.js.map +0 -1
  168. package/dist/cjs/resources/getItemResourcesFilesFromPaths.d.ts +0 -24
  169. package/dist/cjs/resources/getItemResourcesFilesFromPaths.js +0 -49
  170. package/dist/cjs/resources/getItemResourcesFilesFromPaths.js.map +0 -1
  171. package/dist/cjs/resources/getItemResourcesPaths.d.ts +0 -26
  172. package/dist/cjs/resources/getItemResourcesPaths.js +0 -76
  173. package/dist/cjs/resources/getItemResourcesPaths.js.map +0 -1
  174. package/dist/cjs/resources/index.d.ts +0 -29
  175. package/dist/cjs/resources/index.js +0 -33
  176. package/dist/cjs/resources/index.js.map +0 -1
  177. package/dist/cjs/resources/solution-resource.d.ts +0 -35
  178. package/dist/cjs/resources/solution-resource.js +0 -31
  179. package/dist/cjs/resources/solution-resource.js.map +0 -1
  180. package/dist/cjs/resources/transform-resource-paths-to-solution-resources.d.ts +0 -56
  181. package/dist/cjs/resources/transform-resource-paths-to-solution-resources.js +0 -146
  182. package/dist/cjs/resources/transform-resource-paths-to-solution-resources.js.map +0 -1
  183. package/dist/cjs/restHelpers.d.ts +0 -598
  184. package/dist/cjs/restHelpers.js +0 -1929
  185. package/dist/cjs/restHelpers.js.map +0 -1
  186. package/dist/cjs/restHelpersGet.d.ts +0 -288
  187. package/dist/cjs/restHelpersGet.js +0 -804
  188. package/dist/cjs/restHelpersGet.js.map +0 -1
  189. package/dist/cjs/sharing/index.d.ts +0 -16
  190. package/dist/cjs/sharing/index.js +0 -20
  191. package/dist/cjs/sharing/index.js.map +0 -1
  192. package/dist/cjs/sharing/share-item-to-groups.d.ts +0 -26
  193. package/dist/cjs/sharing/share-item-to-groups.js +0 -44
  194. package/dist/cjs/sharing/share-item-to-groups.js.map +0 -1
  195. package/dist/cjs/templatization.d.ts +0 -139
  196. package/dist/cjs/templatization.js +0 -314
  197. package/dist/cjs/templatization.js.map +0 -1
  198. package/dist/cjs/trackingHelpers.d.ts +0 -116
  199. package/dist/cjs/trackingHelpers.js +0 -217
  200. package/dist/cjs/trackingHelpers.js.map +0 -1
  201. package/dist/cjs/velocityHelpers.d.ts +0 -57
  202. package/dist/cjs/velocityHelpers.js +0 -135
  203. package/dist/cjs/velocityHelpers.js.map +0 -1
  204. package/dist/cjs/workflowHelpers.d.ts +0 -17
  205. package/dist/cjs/workflowHelpers.js +0 -76
  206. package/dist/cjs/workflowHelpers.js.map +0 -1
  207. package/dist/cjs/workforceHelpers.d.ts +0 -115
  208. package/dist/cjs/workforceHelpers.js +0 -749
  209. package/dist/cjs/workforceHelpers.js.map +0 -1
  210. package/dist/cjs/zip-utils.d.ts +0 -49
  211. package/dist/cjs/zip-utils.js +0 -89
  212. package/dist/cjs/zip-utils.js.map +0 -1
@@ -1,1929 +0,0 @@
1
- "use strict";
2
- /** @license
3
- * Copyright 2018 Esri
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports._getFallbackExtent = exports._getCreateServiceOptions = exports._countRelationships = exports._addItemMetadataFile = exports._addItemDataFile = exports.updateItemURL = exports.updateItemTemplateFromDictionary = exports.updateItemExtended = exports.updateGroup = exports.updateItem = exports.shareItem = exports.removeUsers = exports.reassignGroup = exports.searchGroupContents = exports.searchGroupAllContents = exports.searchAllGroups = exports.searchGroups = exports.searchAllItems = exports.searchItems = exports.removeItemOrGroup = exports.removeItem = exports.removeGroup = exports.removeFolder = exports.hasInvalidGroupDesignations = exports._parseAdminServiceData = exports.getWorkflowConfiguration = exports.getFeatureServiceProperties = exports.getServiceLayersAndTables = exports.getRequest = exports._sortRelationships = exports.getLayerUpdates = exports.getLayers = exports.extractDependencies = exports.createUniqueGroup = exports.createUniqueFolder = exports.createItemWithData = exports.createFullItem = exports.createFeatureService = exports.convertExtent = exports.convertExtentWithFallback = exports._validateExtent = exports.convertToISearchOptions = exports.checkRequestStatus = exports.addToServiceDefinition = exports.addTokenToUrl = exports.addForwardItemRelationships = exports.addForwardItemRelationship = exports.getUserSession = exports.addItemData = exports.rest_request = void 0;
19
- exports._updateItemURL = exports._updateIndexesForRelationshipKeyFields = exports._setItemProperties = exports._reportVariablesInItem = exports._lowercaseDomain = exports._getUpdate = exports._getContingentValuesUpdates = exports._getRelationshipUpdates = void 0;
20
- /**
21
- * Provides common functions involving the arcgis-rest-js library.
22
- *
23
- * @module restHelpers
24
- */
25
- const featureServiceHelpers_1 = require("./featureServiceHelpers");
26
- const generalHelpers_1 = require("./generalHelpers");
27
- const interfaces_1 = require("./interfaces");
28
- const libConnectors_1 = require("./libConnectors");
29
- const restHelpersGet_1 = require("./restHelpersGet");
30
- const arcgis_rest_portal_1 = require("@esri/arcgis-rest-portal");
31
- const arcgis_rest_request_1 = require("@esri/arcgis-rest-request");
32
- const arcgis_rest_service_admin_1 = require("@esri/arcgis-rest-service-admin");
33
- const workforceHelpers_1 = require("./workforceHelpers");
34
- const templatization_1 = require("./templatization");
35
- const trackingHelpers_1 = require("./trackingHelpers");
36
- // ------------------------------------------------------------------------------------------------------------------ //
37
- var arcgis_rest_request_2 = require("@esri/arcgis-rest-request");
38
- Object.defineProperty(exports, "rest_request", { enumerable: true, get: function () { return arcgis_rest_request_2.request; } });
39
- // ------------------------------------------------------------------------------------------------------------------ //
40
- function addItemData(id, data, authentication) {
41
- const addDataOptions = {
42
- id,
43
- data,
44
- authentication
45
- };
46
- return (0, arcgis_rest_portal_1.addItemData)(addDataOptions);
47
- }
48
- exports.addItemData = addItemData;
49
- ;
50
- /**
51
- * Creates a UserSession via a function so that the global arcgisSolution variable can access authentication.
52
- *
53
- * @param options See https://esri.github.io/arcgis-rest-js/api/auth/IUserSessionOptions/
54
- * @returns UserSession
55
- */
56
- function getUserSession(options = {}) {
57
- return new interfaces_1.UserSession(options);
58
- }
59
- exports.getUserSession = getUserSession;
60
- /**
61
- * Adds a forward relationship between two items.
62
- *
63
- * @param originItemId Origin of relationship
64
- * @param destinationItemId Destination of relationship
65
- * @param relationshipType Type of relationship
66
- * @param authentication Credentials for the request
67
- * @returns A Promise to add item resources.
68
- */
69
- function addForwardItemRelationship(originItemId, destinationItemId, relationshipType, authentication) {
70
- return new Promise(resolve => {
71
- const requestOptions = {
72
- originItemId,
73
- destinationItemId,
74
- relationshipType,
75
- authentication
76
- };
77
- (0, arcgis_rest_portal_1.addItemRelationship)(requestOptions).then(response => {
78
- resolve({
79
- success: response.success,
80
- itemId: originItemId
81
- });
82
- }, () => {
83
- resolve({
84
- success: false,
85
- itemId: originItemId
86
- });
87
- });
88
- });
89
- }
90
- exports.addForwardItemRelationship = addForwardItemRelationship;
91
- /**
92
- * Adds forward relationships for an item.
93
- *
94
- * @param originItemId Origin of relationship
95
- * @param destinationRelationships Destinations
96
- * @param authentication Credentials for the request
97
- * @returns A Promise to add item resources.
98
- */
99
- function addForwardItemRelationships(originItemId, destinationRelationships, authentication) {
100
- return new Promise(resolve => {
101
- // Set up relationships using updated relationship information
102
- const relationshipPromises = new Array();
103
- destinationRelationships.forEach(relationship => {
104
- relationship.relatedItemIds.forEach(relatedItemId => {
105
- relationshipPromises.push(addForwardItemRelationship(originItemId, relatedItemId, relationship.relationshipType, authentication));
106
- });
107
- });
108
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
109
- Promise.all(relationshipPromises).then((responses) => resolve(responses));
110
- });
111
- }
112
- exports.addForwardItemRelationships = addForwardItemRelationships;
113
- /**
114
- * Adds a token to the query parameters of a URL.
115
- *
116
- * @param url URL to use as base
117
- * @param authentication Credentials to be used to generate token for URL
118
- * @returns A promise that will resolve with the supplied URL with `token=<token>` added to its query params
119
- * unless either the URL doesn't exist or the token can't be generated
120
- */
121
- function addTokenToUrl(url, authentication) {
122
- return new Promise(resolve => {
123
- if (!url || !authentication) {
124
- resolve(url);
125
- }
126
- else {
127
- authentication.getToken(url).then(token => {
128
- /* istanbul ignore else */
129
- if (token) {
130
- url = (0, generalHelpers_1.appendQueryParam)(url, "token=" + token);
131
- }
132
- resolve(url);
133
- }, () => resolve(url));
134
- }
135
- });
136
- }
137
- exports.addTokenToUrl = addTokenToUrl;
138
- /**
139
- * Calls addToDefinition for the service.
140
- *
141
- * Added retry due to some solutions failing to deploy in specific orgs/hives due to timeouts.
142
- * On the first pass we will use the quicker sync request to add.
143
- * If it fails we will use an async request that will avoid the timeout errors.
144
- *
145
- * @param url URL to use as base
146
- * @param options the info to add to the services definition
147
- * @param skipRetry a boolean to control if retry logic will be used. Defaults to false.
148
- * @param useAsync a boolean to control if we will use an async request
149
- * @returns A promise that will resolve when the request has completed
150
- */
151
- function addToServiceDefinition(url, options, skipRetry = false, useAsync = false) {
152
- /* istanbul ignore else */
153
- if (useAsync) {
154
- options.params = { ...options.params, async: true };
155
- }
156
- return new Promise((resolve, reject) => {
157
- (0, arcgis_rest_service_admin_1.addToServiceDefinition)(url, options).then((result) => {
158
- checkRequestStatus(result, options.authentication).then(() => resolve(null), e => reject((0, generalHelpers_1.fail)(e)));
159
- }, e => {
160
- if (!skipRetry) {
161
- addToServiceDefinition(url, options, true, true).then(() => resolve(null), e => reject(e));
162
- }
163
- else {
164
- reject((0, generalHelpers_1.fail)(e));
165
- }
166
- });
167
- });
168
- }
169
- exports.addToServiceDefinition = addToServiceDefinition;
170
- /**
171
- * When using an async request we need to poll the status url to know when the request has completed or failed.
172
- *
173
- * @param result the result returned from the addToDefinition request.
174
- * This will contain a status url or the standard sync result.
175
- * @param authentication Credentials to be used to generate token for URL
176
- * @returns A promise that will resolve when the request has completed
177
- */
178
- function checkRequestStatus(result, authentication) {
179
- return new Promise((resolve, reject) => {
180
- const url = result.statusURL || result.statusUrl;
181
- if (url) {
182
- const checkStatus = setInterval(() => {
183
- (0, arcgis_rest_request_1.request)(url, { authentication }).then(r => {
184
- /* istanbul ignore else */
185
- if (["completed", "success"].indexOf(r.status.toLowerCase()) > -1) {
186
- clearInterval(checkStatus);
187
- resolve();
188
- }
189
- else if (r.status.toLowerCase() === "failed") {
190
- clearInterval(checkStatus);
191
- reject(r);
192
- }
193
- }, e => {
194
- clearInterval(checkStatus);
195
- reject(e);
196
- });
197
- }, 2000);
198
- }
199
- else {
200
- resolve();
201
- }
202
- });
203
- }
204
- exports.checkRequestStatus = checkRequestStatus;
205
- /**
206
- * Converts a general search into an ISearchOptions structure.
207
- *
208
- * @param search Search specified in one of three ways
209
- * @returns Recast search
210
- */
211
- function convertToISearchOptions(search) {
212
- // Convert the search into an ISearchOptions
213
- let searchOptions = {
214
- q: "",
215
- start: 1,
216
- num: 100
217
- };
218
- if (typeof search === "string") {
219
- // Insert query into defaults
220
- searchOptions.q = search;
221
- }
222
- else if (search instanceof arcgis_rest_portal_1.SearchQueryBuilder) {
223
- // Insert query into defaults
224
- searchOptions.q = search.toParam();
225
- }
226
- else { // search is ISearchOptions
227
- searchOptions = {
228
- ...searchOptions,
229
- ...search // request
230
- };
231
- }
232
- // Remove the sortField if it's "relevance"; that's the default option and is not meant to be specified
233
- if (searchOptions.sortField === "relevance") {
234
- delete searchOptions.sortField;
235
- }
236
- return searchOptions;
237
- }
238
- exports.convertToISearchOptions = convertToISearchOptions;
239
- /**
240
- * Simple validate function to ensure all coordinates are numbers
241
- * In some cases orgs can have null or undefined coordinate values associated with the org extent
242
- *
243
- * @param extent the extent to validate
244
- * @returns the provided extent or a default global extent if some coordinates are not numbers
245
- * @private
246
- */
247
- function _validateExtent(extent) {
248
- // in some cases orgs can have invalid extents defined
249
- // this is a simple validate function that will ensure coordiantes are numbers
250
- // using -179,-89,179,89 because the project call is returning "NaN" when using -180,-90,180,90
251
- const hasInvalid = typeof extent.xmin !== "number" ||
252
- typeof extent.xmax !== "number" ||
253
- typeof extent.ymax !== "number" ||
254
- typeof extent.ymin !== "number";
255
- if (hasInvalid) {
256
- extent.xmin = -179;
257
- extent.xmax = 179;
258
- extent.ymax = 89;
259
- extent.ymin = -89;
260
- extent.spatialReference = { wkid: 4326 };
261
- }
262
- return extent;
263
- }
264
- exports._validateExtent = _validateExtent;
265
- /**
266
- * If the request to convert the extent fails it has commonly been due to an invalid extent.
267
- * This function will first attempt to use the provided extent. If it fails it will default to
268
- * the source items extent and if that fails it will then use a default global extent.
269
- *
270
- * @param extent the extent to convert
271
- * @param fallbackExtent the extent to convert if the main extent does not project to the outSR
272
- * @param outSR the spatial reference to project to
273
- * @param geometryServiceUrl the service url for the geometry service to use
274
- * @param authentication the credentials for the requests
275
- * @returns the extent projected to the provided spatial reference
276
- * or the world extent projected to the provided spatial reference
277
- * @private
278
- */
279
- function convertExtentWithFallback(extent, fallbackExtent, outSR, geometryServiceUrl, authentication) {
280
- return new Promise((resolve, reject) => {
281
- const defaultExtent = {
282
- xmin: -179,
283
- xmax: 179,
284
- ymin: -89,
285
- ymax: 89,
286
- spatialReference: { wkid: 4326 }
287
- };
288
- convertExtent(_validateExtent(extent), outSR, geometryServiceUrl, authentication).then(extentResponse => {
289
- // in some cases project will complete successfully but return "NaN" values
290
- // check for this and call convert again if it does
291
- const extentResponseString = JSON.stringify(extentResponse);
292
- const validatedExtent = JSON.stringify(_validateExtent(extentResponse));
293
- if (extentResponseString === validatedExtent) {
294
- resolve(extentResponse);
295
- }
296
- else {
297
- convertExtent(fallbackExtent || defaultExtent, outSR, geometryServiceUrl, authentication).then(resolve, e => reject((0, generalHelpers_1.fail)(e)));
298
- }
299
- },
300
- // if convert fails try again with default global extent
301
- () => {
302
- convertExtent(defaultExtent, outSR, geometryServiceUrl, authentication).then(resolve, e => reject((0, generalHelpers_1.fail)(e)));
303
- });
304
- });
305
- }
306
- exports.convertExtentWithFallback = convertExtentWithFallback;
307
- /**
308
- * Converts an extent to a specified spatial reference.
309
- *
310
- * @param extent Extent object to check and (possibly) to project
311
- * @param outSR Desired spatial reference
312
- * @param geometryServiceUrl Path to geometry service providing `findTransformations` and `project` services
313
- * @param authentication Credentials for the request
314
- * @returns Original extent if it's already using outSR or the extents projected into the outSR
315
- */
316
- function convertExtent(extent, outSR, geometryServiceUrl, authentication) {
317
- const _requestOptions = { authentication };
318
- return new Promise((resolve, reject) => {
319
- if (extent.spatialReference.wkid === outSR?.wkid || !outSR) {
320
- resolve(extent);
321
- }
322
- else {
323
- _requestOptions.params = {
324
- f: "json",
325
- inSR: extent.spatialReference.wkid,
326
- outSR: outSR.wkid,
327
- extentOfInterest: JSON.stringify(extent)
328
- };
329
- (0, arcgis_rest_request_1.request)((0, generalHelpers_1.checkUrlPathTermination)(geometryServiceUrl) + "findTransformations", _requestOptions).then(response => {
330
- const transformations = response && response.transformations
331
- ? response.transformations
332
- : undefined;
333
- let transformation;
334
- if (transformations && transformations.length > 0) {
335
- // if a forward single transformation is found use that...otherwise check for and use composite
336
- transformation = transformations[0].wkid
337
- ? transformations[0].wkid
338
- : transformations[0].geoTransforms
339
- ? transformations[0]
340
- : undefined;
341
- }
342
- _requestOptions.params = {
343
- f: "json",
344
- outSR: outSR.wkid,
345
- inSR: extent.spatialReference.wkid,
346
- geometries: {
347
- geometryType: "esriGeometryPoint",
348
- geometries: [
349
- { x: extent.xmin, y: extent.ymin },
350
- { x: extent.xmax, y: extent.ymax }
351
- ]
352
- },
353
- transformation: transformation
354
- };
355
- (0, arcgis_rest_request_1.request)((0, generalHelpers_1.checkUrlPathTermination)(geometryServiceUrl) + "project", _requestOptions).then(projectResponse => {
356
- const projectGeom = projectResponse.geometries.length === 2
357
- ? projectResponse.geometries
358
- : undefined;
359
- if (projectGeom) {
360
- resolve({
361
- xmin: projectGeom[0].x,
362
- ymin: projectGeom[0].y,
363
- xmax: projectGeom[1].x,
364
- ymax: projectGeom[1].y,
365
- spatialReference: outSR
366
- });
367
- }
368
- else {
369
- resolve(undefined);
370
- }
371
- }, e => reject((0, generalHelpers_1.fail)(e)));
372
- }, e => reject((0, generalHelpers_1.fail)(e)));
373
- }
374
- });
375
- }
376
- exports.convertExtent = convertExtent;
377
- /**
378
- * Publishes a feature service as an AGOL item; it does not include its layers and tables
379
- *
380
- * @param newItemTemplate Template of item to be created
381
- * @param authentication Credentials for the request
382
- * @param templateDictionary Hash of facts: org URL, adlib replacements, user; .user.folders property contains a list
383
- * @returns A promise that will resolve with an object reporting success and the Solution id
384
- */
385
- function createFeatureService(newItemTemplate, authentication, templateDictionary) {
386
- return new Promise((resolve, reject) => {
387
- // Create item
388
- _getCreateServiceOptions(newItemTemplate, authentication, templateDictionary).then(createOptions => {
389
- (0, arcgis_rest_service_admin_1.createFeatureService)(createOptions).then(createResponse => {
390
- // Federated servers may have inconsistent casing, so lowerCase it
391
- createResponse.encodedServiceURL = _lowercaseDomain(createResponse.encodedServiceURL);
392
- createResponse.serviceurl = _lowercaseDomain(createResponse.serviceurl);
393
- resolve(createResponse);
394
- }, e => reject((0, generalHelpers_1.fail)(e)));
395
- }, e => reject((0, generalHelpers_1.fail)(e)));
396
- });
397
- }
398
- exports.createFeatureService = createFeatureService;
399
- /**
400
- * Publishes an item and its data, metadata, and resources as an AGOL item.
401
- *
402
- * @param itemInfo Item's `item` section
403
- * @param folderId Id of folder to receive item; null indicates that the item goes into the root
404
- * folder; ignored for Group item type
405
- * @param destinationAuthentication Credentials for for requests to where the item is to be created
406
- * @param itemThumbnailUrl URL to image to use for item thumbnail
407
- * @param itemThumbnailAuthentication Credentials for requests to the thumbnail source
408
- * @param dataFile Item's `data` section
409
- * @param metadataFile Item's metadata file
410
- * @param resourcesFiles Item's resources
411
- * @param access Access to set for item: "public", "org", "private"
412
- * @returns A promise that will resolve with an object reporting success or failure and the Solution id
413
- */
414
- function createFullItem(itemInfo, folderId, destinationAuthentication, itemThumbnailUrl, itemThumbnailAuthentication, dataFile, metadataFile, resourcesFiles, access = "private") {
415
- return new Promise((resolve, reject) => {
416
- // Create item
417
- const createOptions = {
418
- item: {
419
- ...itemInfo
420
- },
421
- folderId,
422
- authentication: destinationAuthentication
423
- };
424
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
425
- addTokenToUrl(itemThumbnailUrl, itemThumbnailAuthentication).then(updatedThumbnailUrl => {
426
- /* istanbul ignore else */
427
- if (updatedThumbnailUrl) {
428
- createOptions.item.thumbnailUrl = (0, generalHelpers_1.appendQueryParam)(updatedThumbnailUrl, "w=400");
429
- }
430
- (0, arcgis_rest_portal_1.createItemInFolder)(createOptions).then(createResponse => {
431
- if (createResponse.success) {
432
- let accessDef;
433
- // Set access if it is not AGOL default
434
- // Set the access manually since the access value in createItem appears to be ignored
435
- // Need to run serially; will not work reliably if done in parallel with adding the data section
436
- if (access !== "private") {
437
- const accessOptions = {
438
- id: createResponse.id,
439
- access: access === "public" ? "public" : "org",
440
- authentication: destinationAuthentication
441
- };
442
- accessDef = (0, arcgis_rest_portal_1.setItemAccess)(accessOptions);
443
- }
444
- else {
445
- accessDef = Promise.resolve({
446
- itemId: createResponse.id
447
- });
448
- }
449
- // Now add attached items
450
- accessDef.then(() => {
451
- const updateDefs = [];
452
- // Add the data section
453
- if (dataFile) {
454
- updateDefs.push(_addItemDataFile(createResponse.id, dataFile, destinationAuthentication));
455
- }
456
- // Add the resources via a zip because AGO sometimes loses resources if many are added at the
457
- // same time to the same item
458
- if (Array.isArray(resourcesFiles) &&
459
- resourcesFiles.length > 0) {
460
- updateDefs.push(new Promise((rsrcResolve, rsrcReject) => {
461
- (0, libConnectors_1.createZip)("resources.zip", resourcesFiles).then((zipfile) => {
462
- const addResourceOptions = {
463
- id: createResponse.id,
464
- resource: zipfile,
465
- authentication: destinationAuthentication,
466
- params: {
467
- archive: true
468
- }
469
- };
470
- (0, arcgis_rest_portal_1.addItemResource)(addResourceOptions).then(rsrcResolve, rsrcReject);
471
- }, rsrcReject);
472
- }));
473
- }
474
- // Add the metadata section
475
- if (metadataFile) {
476
- updateDefs.push(_addItemMetadataFile(createResponse.id, metadataFile, destinationAuthentication));
477
- }
478
- // Wait until all adds are done
479
- Promise.all(updateDefs).then(() => resolve(createResponse), e => reject((0, generalHelpers_1.fail)(e)));
480
- }, e => reject((0, generalHelpers_1.fail)(e)));
481
- }
482
- else {
483
- reject((0, generalHelpers_1.fail)());
484
- }
485
- }, e => reject((0, generalHelpers_1.fail)(e)));
486
- });
487
- });
488
- }
489
- exports.createFullItem = createFullItem;
490
- /**
491
- * Publishes an item and its data as an AGOL item.
492
- *
493
- * @param itemInfo Item's `item` section
494
- * @param dataInfo Item's `data` section
495
- * @param authentication Credentials for the request
496
- * @param folderId Id of folder to receive item; null indicates that the item goes into the root
497
- * folder; ignored for Group item type
498
- * @param access Access to set for item: "public", "org", "private"
499
- * @returns A promise that will resolve with an object reporting success and the Solution id
500
- */
501
- function createItemWithData(itemInfo, dataInfo, authentication, folderId, access = "private") {
502
- return new Promise((resolve, reject) => {
503
- // Create item
504
- const createOptions = {
505
- item: {
506
- title: "_",
507
- ...itemInfo,
508
- data: dataInfo
509
- },
510
- folderId,
511
- authentication: authentication
512
- };
513
- if (itemInfo.thumbnail) {
514
- createOptions.params = {
515
- // Pass thumbnail file in via params because item property is serialized, which discards a blob
516
- thumbnail: itemInfo.thumbnail
517
- };
518
- delete createOptions.item.thumbnail;
519
- }
520
- (0, arcgis_rest_portal_1.createItemInFolder)(createOptions).then(createResponse => {
521
- if (createResponse.success) {
522
- if (access !== "private") {
523
- // Set access if it is not AGOL default
524
- // Set the access manually since the access value in createItem appears to be ignored
525
- const accessOptions = {
526
- id: createResponse.id,
527
- access: access === "public" ? "public" : "org",
528
- authentication: authentication
529
- };
530
- (0, arcgis_rest_portal_1.setItemAccess)(accessOptions).then(() => {
531
- resolve({
532
- folder: createResponse.folder,
533
- id: createResponse.id,
534
- success: true
535
- });
536
- }, e => reject((0, generalHelpers_1.fail)(e)));
537
- }
538
- else {
539
- resolve({
540
- folder: createResponse.folder,
541
- id: createResponse.id,
542
- success: true
543
- });
544
- }
545
- }
546
- else {
547
- reject((0, generalHelpers_1.fail)());
548
- }
549
- }, e => reject((0, generalHelpers_1.fail)(e)));
550
- });
551
- }
552
- exports.createItemWithData = createItemWithData;
553
- /**
554
- * Creates a folder using a numeric suffix to ensure uniqueness if necessary.
555
- *
556
- * @param title Folder title, used as-is if possible and with suffix otherwise
557
- * @param templateDictionary Hash of facts: org URL, adlib replacements, user; .user.folders property contains a list
558
- * of known folder names; function updates list with existing names not yet known, and creates .user.folders if it
559
- * doesn't exist in the dictionary
560
- * @param authentication Credentials for creating folder
561
- * @returns Id of created folder
562
- */
563
- function createUniqueFolder(title, templateDictionary, authentication) {
564
- return new Promise((resolve, reject) => {
565
- // Get a title that is not already in use
566
- const folderTitle = (0, generalHelpers_1.getUniqueTitle)(title, templateDictionary, "user.folders");
567
- const folderCreationParam = {
568
- title: folderTitle,
569
- authentication: authentication
570
- };
571
- (0, arcgis_rest_portal_1.createFolder)(folderCreationParam).then(ok => resolve(ok), err => {
572
- // If the name already exists, we'll try again
573
- const errorDetails = (0, generalHelpers_1.getProp)(err, "response.error.details");
574
- if (Array.isArray(errorDetails) && errorDetails.length > 0) {
575
- const nameNotAvailMsg = "Folder title '" + folderTitle + "' not available.";
576
- if (errorDetails.indexOf(nameNotAvailMsg) >= 0) {
577
- // Create the user.folders property if it doesn't exist
578
- /* istanbul ignore else */
579
- if (!(0, generalHelpers_1.getProp)(templateDictionary, "user.folders")) {
580
- (0, generalHelpers_1.setCreateProp)(templateDictionary, "user.folders", []);
581
- }
582
- templateDictionary.user.folders.push({
583
- title: folderTitle
584
- });
585
- createUniqueFolder(title, templateDictionary, authentication).then(resolve, reject);
586
- }
587
- else {
588
- reject(err);
589
- }
590
- }
591
- else {
592
- // Otherwise, error out
593
- reject(err);
594
- }
595
- });
596
- });
597
- }
598
- exports.createUniqueFolder = createUniqueFolder;
599
- /**
600
- * Creates a group using numeric suffix to ensure uniqueness.
601
- *
602
- * @param title Group title, used as-is if possible and with suffix otherwise
603
- * @param templateDictionary Hash of facts: org URL, adlib replacements, user
604
- * @param authentication Credentials for creating group
605
- * @param owner Optional arg for the Tracking owner
606
- * If the tracking owner is not the one deploying the solution
607
- * tracker groups will be created under the deployment user but
608
- * will be reassigned to the tracking owner.
609
- * @returns Information about created group
610
- */
611
- function createUniqueGroup(title, groupItem, templateDictionary, authentication, owner) {
612
- return new Promise((resolve, reject) => {
613
- let groupsPromise;
614
- // when working with tracker we need to consider the groups of the deploying user as well as the groups
615
- // of the tracking user...must be unique for both
616
- if (owner && owner !== authentication.username) {
617
- groupsPromise = searchAllGroups(`(owner:${owner}) orgid:${templateDictionary.organization.id}`, authentication);
618
- }
619
- else {
620
- groupsPromise = Promise.resolve([]);
621
- }
622
- // first get the tracker owner groups
623
- groupsPromise.then(groups => {
624
- templateDictionary["allGroups"] =
625
- groups.concat((0, generalHelpers_1.getProp)(templateDictionary, "user.groups"));
626
- // Get a title that is not already in use
627
- groupItem.title = (0, generalHelpers_1.getUniqueTitle)(title, templateDictionary, "allGroups");
628
- const groupCreationParam = {
629
- group: groupItem,
630
- authentication: authentication
631
- };
632
- (0, arcgis_rest_portal_1.createGroup)(groupCreationParam).then(resolve, err => {
633
- // If the name already exists, we'll try again
634
- const errorDetails = (0, generalHelpers_1.getProp)(err, "response.error.details");
635
- if (Array.isArray(errorDetails) && errorDetails.length > 0) {
636
- const nameNotAvailMsg = "You already have a group named '" +
637
- groupItem.title +
638
- "'. Try a different name.";
639
- if (errorDetails.indexOf(nameNotAvailMsg) >= 0) {
640
- templateDictionary.user.groups.push({
641
- title: groupItem.title
642
- });
643
- createUniqueGroup(title, groupItem, templateDictionary, authentication).then(resolve, reject);
644
- }
645
- else {
646
- reject(err);
647
- }
648
- }
649
- else {
650
- // Otherwise, error out
651
- reject(err);
652
- }
653
- });
654
- }, e => reject(e));
655
- });
656
- }
657
- exports.createUniqueGroup = createUniqueGroup;
658
- /**
659
- * Gets the ids of the dependencies of an AGOL feature service item.
660
- * Dependencies will only exist when the service is a view.
661
- *
662
- * @param itemTemplate Template of item to be created
663
- * @param authentication Credentials for the request
664
- * @returns A promise that will resolve a list of dependencies
665
- */
666
- function extractDependencies(itemTemplate, authentication) {
667
- const dependencies = [];
668
- return new Promise((resolve, reject) => {
669
- // Get service dependencies when the item is a view
670
- // This step is skipped for tracker views as they will already have a source service in the org
671
- if (itemTemplate.properties.service.isView && itemTemplate.item.url && !(0, trackingHelpers_1.isTrackingViewTemplate)(itemTemplate)) {
672
- (0, arcgis_rest_request_1.request)((0, generalHelpers_1.checkUrlPathTermination)(itemTemplate.item.url) + "sources?f=json", {
673
- authentication: authentication
674
- }).then(response => {
675
- /* istanbul ignore else */
676
- if (response && response.services) {
677
- response.services.forEach((layer) => {
678
- dependencies.push({
679
- id: layer.serviceItemId,
680
- name: layer.name
681
- });
682
- });
683
- }
684
- resolve(dependencies);
685
- }, e => reject((0, generalHelpers_1.fail)(e)));
686
- }
687
- else if ((0, workforceHelpers_1.isWorkforceProject)(itemTemplate)) {
688
- resolve((0, workforceHelpers_1.getWorkforceDependencies)(itemTemplate, dependencies));
689
- }
690
- else {
691
- resolve(dependencies);
692
- }
693
- });
694
- }
695
- exports.extractDependencies = extractDependencies;
696
- /**
697
- * Get json info for the services layers
698
- *
699
- * @param serviceUrl the url for the service
700
- * @param layerList list of base layer info
701
- * @param authentication Credentials for the request
702
- * @returns A promise that will resolve a list of dependencies
703
- */
704
- function getLayers(serviceUrl, layerList, authentication) {
705
- return new Promise((resolve, reject) => {
706
- if (layerList.length === 0) {
707
- resolve([]);
708
- }
709
- // get the admin URL
710
- serviceUrl = serviceUrl.replace("/rest/services", "/rest/admin/services");
711
- const requestsDfd = [];
712
- layerList.forEach(layer => {
713
- const requestOptions = {
714
- authentication: authentication
715
- };
716
- requestsDfd.push((0, arcgis_rest_request_1.request)((0, generalHelpers_1.checkUrlPathTermination)(serviceUrl) + layer["id"] + "?f=json", requestOptions));
717
- });
718
- // Wait until all layers are heard from
719
- Promise.all(requestsDfd).then(layers => resolve(layers), e => reject((0, generalHelpers_1.fail)(e)));
720
- });
721
- }
722
- exports.getLayers = getLayers;
723
- /**
724
- * Add additional options to a layers definition.
725
- *
726
- * @param args The IPostProcessArgs for the request(s)
727
- * @param isPortal boolean to indicate if we are deploying to portal
728
- *
729
- * @returns An array of update instructions
730
- * @private
731
- */
732
- function getLayerUpdates(args, isPortal) {
733
- const adminUrl = args.itemTemplate.item.url.replace("rest/services", "rest/admin/services");
734
- const updates = [];
735
- const refresh = _getUpdate(adminUrl, null, null, args, "refresh");
736
- updates.push(refresh);
737
- Object.keys(args.objects).forEach(id => {
738
- const obj = Object.assign({}, args.objects[id]);
739
- // These properties cannot be set in the update definition when working with portal
740
- if (isPortal) {
741
- (0, generalHelpers_1.deleteProps)(obj, ["type", "id", "relationships", "sourceServiceFields"]);
742
- }
743
- // handle definition deletes
744
- // removes previous editFieldsInfo fields if their names were changed
745
- if (obj.hasOwnProperty("deleteFields")) {
746
- updates.push(_getUpdate(adminUrl, id, obj, args, "delete"));
747
- (0, generalHelpers_1.deleteProp)(obj, "deleteFields");
748
- updates.push(_getUpdate(adminUrl, null, null, args, "refresh"));
749
- }
750
- });
751
- // issue: #706
752
- // Add source service relationships
753
- // views will now always add all layers in a single call and will inherit the relationships from the source service
754
- if (!args.itemTemplate.properties.service.isView) {
755
- const relUpdates = _getRelationshipUpdates({
756
- message: "updated layer relationships",
757
- objects: args.objects,
758
- itemTemplate: args.itemTemplate,
759
- authentication: args.authentication
760
- });
761
- // issue: #724
762
- // In portal the order the relationships are added needs to follow the layer order
763
- // otherwise the relationship IDs will be reset
764
- relUpdates.layers = _sortRelationships(args.itemTemplate.properties.layers, args.itemTemplate.properties.tables, relUpdates);
765
- /* istanbul ignore else */
766
- if (relUpdates.layers.length > 0) {
767
- updates.push(_getUpdate(adminUrl, null, relUpdates, args, "add"));
768
- updates.push(refresh);
769
- }
770
- // handle contingent values
771
- const contingentValuesUpdates = _getContingentValuesUpdates({
772
- message: "add layer contingent values",
773
- objects: args.objects,
774
- itemTemplate: args.itemTemplate,
775
- authentication: args.authentication
776
- });
777
- /* istanbul ignore else */
778
- if (contingentValuesUpdates.length > 0) {
779
- contingentValuesUpdates.forEach(conUpdate => {
780
- updates.push(_getUpdate(adminUrl + conUpdate.id, null, conUpdate.contingentValues, args, "add"));
781
- });
782
- }
783
- }
784
- return updates.length === 1 ? [] : updates;
785
- }
786
- exports.getLayerUpdates = getLayerUpdates;
787
- /**
788
- * Sorts relationships based on order of supporting layers and tables in the service definition
789
- *
790
- * @param layers the layers from the service
791
- * @param tables the tables from the service
792
- * @param relUpdates the relationships to add for the service
793
- *
794
- * @returns An array with relationships that have been sorted
795
- * @private
796
- */
797
- function _sortRelationships(layers, tables, relUpdates) {
798
- const ids = [].concat(layers.map((l) => l.id), tables.map((t) => t.id));
799
- // In portal the order the relationships are added needs to follow the layer order
800
- // otherwise the relationship IDs will be reset
801
- const _relUpdateLayers = [];
802
- ids.forEach(id => {
803
- relUpdates.layers.some((relUpdate) => {
804
- if (id === relUpdate.id) {
805
- _relUpdateLayers.push(relUpdate);
806
- return true;
807
- }
808
- else {
809
- return false;
810
- }
811
- });
812
- });
813
- return _relUpdateLayers;
814
- }
815
- exports._sortRelationships = _sortRelationships;
816
- /**
817
- * Add additional options to a layers definition
818
- *
819
- * Added retry due to some solutions failing to deploy in specific orgs/hives
820
- *
821
- *
822
- * @param Update will contain either add, update, or delete from service definition call
823
- * @param skipRetry defaults to false. when true the retry logic will be ignored
824
- * @returns A promise that will resolve when service definition call has completed
825
- * @private
826
- */
827
- /* istanbul ignore else */
828
- function getRequest(update, skipRetry = false, useAsync = false) {
829
- return new Promise((resolve, reject) => {
830
- const options = {
831
- params: update.params,
832
- authentication: update.args.authentication
833
- };
834
- /* istanbul ignore else */
835
- if ((useAsync && update.url.indexOf("addToDefinition") > -1) ||
836
- update.url.indexOf("updateDefinition") > -1 ||
837
- update.url.indexOf("deleteFromDefinition") > -1) {
838
- options.params = { ...options.params, async: true };
839
- }
840
- (0, arcgis_rest_request_1.request)(update.url, options).then(result => {
841
- checkRequestStatus(result, options.authentication).then(() => resolve(null), e => reject((0, generalHelpers_1.fail)(e)));
842
- }, (e) => {
843
- if (!skipRetry) {
844
- getRequest(update, true, true).then(() => resolve(), e => reject(e));
845
- }
846
- else {
847
- reject(e);
848
- }
849
- });
850
- });
851
- }
852
- exports.getRequest = getRequest;
853
- /**
854
- * Fills in missing data, including full layer and table definitions, in a feature services' definition.
855
- *
856
- * @param itemTemplate Feature service item, data, dependencies definition to be modified
857
- * @param authentication Credentials for the request to AGOL
858
- * @returns A promise that will resolve when fullItem has been updated
859
- * @private
860
- */
861
- function getServiceLayersAndTables(itemTemplate, authentication) {
862
- return new Promise((resolve, reject) => {
863
- // To have enough information for reconstructing the service, we'll supplement
864
- // the item and data sections with sections for the service, full layers, and
865
- // full tables
866
- // Extra steps must be taken for workforce version 2
867
- const isWorkforceService = (0, workforceHelpers_1.isWorkforceProject)(itemTemplate);
868
- // Get the service description
869
- if (itemTemplate.item.url) {
870
- getFeatureServiceProperties(itemTemplate.item.url, authentication, isWorkforceService).then(properties => {
871
- itemTemplate.properties = properties;
872
- resolve(itemTemplate);
873
- }, e => reject((0, generalHelpers_1.fail)(e)));
874
- }
875
- else {
876
- resolve(itemTemplate);
877
- }
878
- });
879
- }
880
- exports.getServiceLayersAndTables = getServiceLayersAndTables;
881
- /**
882
- * Get service properties for the given url and update key props
883
- *
884
- * @param serviceUrl the feature service url
885
- * @param authentication Credentials for the request to AGOL
886
- * @param workforceService boolean to indicate if extra workforce service steps should be handled
887
- * @returns A promise that will resolve with the service properties
888
- * @private
889
- */
890
- function getFeatureServiceProperties(serviceUrl, authentication, workforceService = false) {
891
- return new Promise((resolve, reject) => {
892
- const properties = {
893
- service: {},
894
- layers: [],
895
- tables: []
896
- };
897
- // get the admin URL
898
- serviceUrl = serviceUrl.replace("/rest/services", "/rest/admin/services");
899
- // Get the service description
900
- (0, arcgis_rest_request_1.request)(serviceUrl + "?f=json", {
901
- authentication: authentication
902
- }).then(serviceData => {
903
- properties.service = _parseAdminServiceData(serviceData);
904
- // Copy cacheMaxAge to top level so that AGO sees it when deploying the service
905
- // serviceData may have set it if there isn't an adminServiceInfo
906
- /* istanbul ignore else */
907
- if (serviceData.adminServiceInfo?.cacheMaxAge) {
908
- properties.service.cacheMaxAge =
909
- serviceData.adminServiceInfo.cacheMaxAge;
910
- }
911
- // Move the layers and tables out of the service's data section
912
- /* istanbul ignore else */
913
- if (serviceData.layers) {
914
- properties.layers = serviceData.layers;
915
- // Fill in properties that the service layer doesn't provide
916
- // and remove properties that should not exist in the template
917
- properties.layers.forEach(layer => {
918
- layer.serviceItemId = properties.service.serviceItemId;
919
- layer.extent = null;
920
- (0, featureServiceHelpers_1.removeLayerOptimization)(layer);
921
- });
922
- }
923
- delete serviceData.layers;
924
- /* istanbul ignore else */
925
- if (serviceData.tables) {
926
- properties.tables = serviceData.tables;
927
- // Fill in properties that the service layer doesn't provide
928
- properties.tables.forEach(table => {
929
- table.serviceItemId = properties.service.serviceItemId;
930
- table.extent = null;
931
- });
932
- }
933
- delete serviceData.tables;
934
- // Ensure solution items have unique indexes on relationship key fields
935
- _updateIndexesForRelationshipKeyFields(properties);
936
- (0, featureServiceHelpers_1.processContingentValues)(properties, serviceUrl, authentication).then(() => {
937
- if (workforceService) {
938
- (0, workforceHelpers_1.getWorkforceServiceInfo)(properties, serviceUrl, authentication).then(resolve, reject);
939
- }
940
- else {
941
- resolve(properties);
942
- }
943
- }, (e) => reject((0, generalHelpers_1.fail)(e)));
944
- }, (e) => reject((0, generalHelpers_1.fail)(e)));
945
- });
946
- }
947
- exports.getFeatureServiceProperties = getFeatureServiceProperties;
948
- /**
949
- * Fetches the configuration of a workflow.
950
- *
951
- * @param itemId Id of the workflow item
952
- * @param authentication Credentials for the request to AGOL
953
- * @returns Promise resolving with the workflow configuration in a zip file
954
- */
955
- async function getWorkflowConfiguration(itemId, authentication) {
956
- const user = await (0, restHelpersGet_1.getUser)(authentication);
957
- const exportConfigUrl = `https://workflow.arcgis.com/${user.orgId}/admin/${itemId}/export`;
958
- return (0, arcgis_rest_request_1.request)(exportConfigUrl, {
959
- authentication,
960
- headers: {
961
- Host: "workflow.arcgis.com",
962
- "Accept": "application/octet-stream",
963
- "Authorization": `Bearer ${authentication.token}`,
964
- "X-Esri-Authorization": `Bearer ${authentication.token}`
965
- },
966
- params: {
967
- f: "zip"
968
- }
969
- });
970
- }
971
- exports.getWorkflowConfiguration = getWorkflowConfiguration;
972
- /**
973
- * Parses the layers array and will filter subsets of Layers and Tables
974
- * Layers and Tables are both returned in the layers array when we access a feature service from the admin api.
975
- *
976
- * @param adminData The data of the feature service
977
- * @returns A mutated version of the provided adminData
978
- * @private
979
- */
980
- function _parseAdminServiceData(adminData) {
981
- const layers = adminData.layers || [];
982
- const tables = adminData.tables || [];
983
- (0, generalHelpers_1.setCreateProp)(adminData, "layers", layers.filter(l => l.type === "Feature Layer"));
984
- // TODO understand if the concat is necessary.
985
- // Not sure if the admin api will ever actually return a tables collection here.
986
- (0, generalHelpers_1.setCreateProp)(adminData, "tables", tables.concat(layers.filter(l => l.type === "Table")));
987
- return adminData;
988
- }
989
- exports._parseAdminServiceData = _parseAdminServiceData;
990
- /**
991
- * livingatlas designation test.
992
- * These layers should not be templatized or depolyed
993
- *
994
- * @param groupDesignations the items group designations to evaluate
995
- * @returns A boolean indicating if the invalid designation is found in the item info
996
- */
997
- function hasInvalidGroupDesignations(groupDesignations) {
998
- const invalidGroupDesignations = ["livingatlas"];
999
- return groupDesignations
1000
- ? invalidGroupDesignations.indexOf(groupDesignations) > -1
1001
- : false;
1002
- }
1003
- exports.hasInvalidGroupDesignations = hasInvalidGroupDesignations;
1004
- /**
1005
- * Removes a folder from AGO.
1006
- *
1007
- * @param folderId Id of a folder to delete
1008
- * @param authentication Credentials for the request to AGO
1009
- * @returns A promise that will resolve with the result of the request
1010
- */
1011
- function removeFolder(folderId, authentication) {
1012
- return new Promise((resolve, reject) => {
1013
- const requestOptions = {
1014
- folderId: folderId,
1015
- authentication: authentication
1016
- };
1017
- (0, arcgis_rest_portal_1.removeFolder)(requestOptions).then(result => (result.success ? resolve(result) : reject(result)), reject);
1018
- });
1019
- }
1020
- exports.removeFolder = removeFolder;
1021
- /**
1022
- * Removes a group from AGO.
1023
- *
1024
- * @param groupId Id of a group to delete
1025
- * @param authentication Credentials for the request to AGO
1026
- * @returns A promise that will resolve with the result of the request
1027
- */
1028
- function removeGroup(groupId, authentication) {
1029
- return new Promise((resolve, reject) => {
1030
- const requestOptions = {
1031
- id: groupId,
1032
- authentication: authentication
1033
- };
1034
- (0, arcgis_rest_portal_1.removeGroup)(requestOptions).then(result => (result.success ? resolve(result) : reject(result)), reject);
1035
- });
1036
- }
1037
- exports.removeGroup = removeGroup;
1038
- /**
1039
- * Removes an item from AGO.
1040
- *
1041
- * @param itemId Id of an item to delete
1042
- * @param authentication Credentials for the request to AGO
1043
- * @param permanentDelete If true (the default), the item is permanently deleted; if false and the item type
1044
- * supports the recycle bin, the item will be put into the recycle bin
1045
- * @returns A promise that will resolve with the result of the request
1046
- */
1047
- function removeItem(itemId, authentication, permanentDelete = true) {
1048
- return new Promise((resolve, reject) => {
1049
- const requestOptions = {
1050
- id: itemId,
1051
- authentication: authentication,
1052
- params: {
1053
- permanentDelete
1054
- }
1055
- };
1056
- (0, arcgis_rest_portal_1.removeItem)(requestOptions).then(result => (result.success ? resolve(result) : reject(result)), reject);
1057
- });
1058
- }
1059
- exports.removeItem = removeItem;
1060
- /**
1061
- * Removes an item or group from AGO.
1062
- *
1063
- * @param itemId Id of an item or group to delete
1064
- * @param authentication Credentials for the request to AGO
1065
- * @param permanentDelete If true (the default), the item is permanently deleted; if false and the item type
1066
- * supports the recycle bin, the item will be put into the recycle bin; note that this does not apply to groups
1067
- * @returns A promise that will resolve with the result of the request
1068
- */
1069
- function removeItemOrGroup(itemId, authentication, permanentDelete = true) {
1070
- return new Promise((resolve, reject) => {
1071
- removeItem(itemId, authentication, permanentDelete).then(resolve, error => {
1072
- removeGroup(itemId, authentication).then(resolve, () => reject(error));
1073
- });
1074
- });
1075
- }
1076
- exports.removeItemOrGroup = removeItemOrGroup;
1077
- /**
1078
- * Searches for items matching a query and that the caller has access to.
1079
- *
1080
- * @param search Search string (e.g., "q=redlands+map") or a more detailed structure that can include authentication
1081
- * @returns Promise resolving with search results
1082
- * @see https://developers.arcgis.com/rest/users-groups-and-items/search.htm
1083
- */
1084
- function searchItems(search) {
1085
- return (0, arcgis_rest_portal_1.searchItems)(search);
1086
- }
1087
- exports.searchItems = searchItems;
1088
- /**
1089
- * Searches for items matching a query and that the caller has access to, continuing recursively until done.
1090
- *
1091
- * @param search Search string (e.g., "q=redlands+map") or a more detailed structure that can include authentication
1092
- * @param accumulatedResponse Response built from previous requests
1093
- * @returns Promise resolving with search results
1094
- * @see https://developers.arcgis.com/rest/users-groups-and-items/search.htm
1095
- */
1096
- function searchAllItems(search, accumulatedResponse) {
1097
- // Convert the search into an ISearchOptions
1098
- const searchOptions = convertToISearchOptions(search);
1099
- // Provide a base into which results can be concatenated
1100
- const completeResponse = accumulatedResponse ? accumulatedResponse : {
1101
- query: searchOptions.q,
1102
- start: 1,
1103
- num: 100,
1104
- nextStart: -1,
1105
- total: 0,
1106
- results: []
1107
- };
1108
- return new Promise((resolve, reject) => {
1109
- searchItems(search).then(response => {
1110
- completeResponse.results = completeResponse.results.concat(response.results);
1111
- completeResponse.num = completeResponse.total = completeResponse.results.length;
1112
- if (response.nextStart > 0) {
1113
- // Insert nextStart into next query
1114
- searchOptions.start = response.nextStart;
1115
- resolve(searchAllItems(searchOptions, completeResponse));
1116
- }
1117
- else {
1118
- resolve(completeResponse);
1119
- }
1120
- }, e => reject(e));
1121
- });
1122
- }
1123
- exports.searchAllItems = searchAllItems;
1124
- /**
1125
- * Searches for groups matching criteria.
1126
- *
1127
- * @param searchString Text for which to search, e.g., 'redlands+map', 'type:"Web Map" -type:"Web Mapping Application"'
1128
- * @param authentication Credentials for the request to AGO
1129
- * @param additionalSearchOptions Adjustments to search, such as tranche size
1130
- * @returns A promise that will resolve with a structure with a tranche of results and
1131
- * describing how many items are available
1132
- * @see https://developers.arcgis.com/rest/users-groups-and-items/group-search.htm
1133
- * @see https://developers.arcgis.com/rest/users-groups-and-items/search-reference.htm
1134
- */
1135
- function searchGroups(searchString, authentication, additionalSearchOptions) {
1136
- const searchOptions = {
1137
- q: searchString,
1138
- params: {
1139
- ...additionalSearchOptions
1140
- },
1141
- authentication: authentication
1142
- };
1143
- return (0, arcgis_rest_portal_1.searchGroups)(searchOptions);
1144
- }
1145
- exports.searchGroups = searchGroups;
1146
- /**
1147
- * Searches for groups matching criteria recurusively.
1148
- *
1149
- * @param searchString Text for which to search, e.g., 'redlands+map', 'type:"Web Map" -type:"Web Mapping Application"'
1150
- * @param authentication Credentials for the request to AGO
1151
- * @param groups List of groups that have been found from previous requests
1152
- * @param inPagingParams The paging params for the recurisve searching
1153
- *
1154
- * @returns A promise that will resolve with all groups that meet the search criteria
1155
- */
1156
- function searchAllGroups(searchString, authentication, groups, inPagingParams) {
1157
- const pagingParams = inPagingParams ? inPagingParams : {
1158
- start: 1,
1159
- num: 24
1160
- };
1161
- const additionalSearchOptions = {
1162
- sortField: "title",
1163
- sortOrder: "asc",
1164
- ...pagingParams
1165
- };
1166
- // Provide a base onto which results can be concatenated
1167
- let finalResults = groups ? groups : [];
1168
- return new Promise((resolve, reject) => {
1169
- searchGroups(searchString, authentication, additionalSearchOptions).then(response => {
1170
- finalResults = finalResults.concat(response.results);
1171
- if (response.nextStart > 0) {
1172
- pagingParams.start = response.nextStart;
1173
- resolve(searchAllGroups(searchString, authentication, finalResults, pagingParams));
1174
- }
1175
- else {
1176
- resolve(finalResults);
1177
- }
1178
- }, e => reject(e));
1179
- });
1180
- }
1181
- exports.searchAllGroups = searchAllGroups;
1182
- /**
1183
- * Searches for group contents matching criteria recursively.
1184
- *
1185
- * @param groupId Group whose contents are to be searched
1186
- * @param searchString Text for which to search, e.g., 'redlands+map', 'type:"Web Map" -type:"Web Mapping Application"'
1187
- * @param authentication Credentials for the request to AGO
1188
- * @param additionalSearchOptions Adjustments to search, such as tranche size and categories of interest; categories
1189
- * are supplied as an array: each array element consists of one or more categories to be ORed; array elements are ANDed
1190
- * @param portalUrl Rest Url of the portal to perform the search
1191
- * @param accumulatedResponse Response built from previous requests
1192
- * @returns A promise that will resolve with a structure with a tranche of results and
1193
- * describing how many items are available
1194
- * @see https://developers.arcgis.com/rest/users-groups-and-items/group-content-search.htm
1195
- * @see https://developers.arcgis.com/rest/users-groups-and-items/search-reference.htm
1196
- */
1197
- function searchGroupAllContents(groupId, searchString, authentication, additionalSearchOptions, portalUrl, accumulatedResponse) {
1198
- additionalSearchOptions = additionalSearchOptions ? additionalSearchOptions : {};
1199
- // Provide a base into which results can be concatenated
1200
- const completeResponse = accumulatedResponse ? accumulatedResponse : {
1201
- query: searchString,
1202
- start: 1,
1203
- num: 100,
1204
- nextStart: -1,
1205
- total: 0,
1206
- results: []
1207
- };
1208
- // Remove the sortField if it's "relevance"; that's the default option and is not meant to be specified
1209
- if (additionalSearchOptions.sortField === "relevance") {
1210
- delete additionalSearchOptions.sortField;
1211
- }
1212
- return new Promise((resolve, reject) => {
1213
- searchGroupContents(groupId, searchString, authentication, additionalSearchOptions, portalUrl).then(response => {
1214
- completeResponse.results = completeResponse.results.concat(response.results);
1215
- completeResponse.num = completeResponse.total = completeResponse.results.length;
1216
- if (response.nextStart > 0) {
1217
- additionalSearchOptions.start = response.nextStart;
1218
- resolve(searchGroupAllContents(groupId, searchString, authentication, additionalSearchOptions, portalUrl, completeResponse));
1219
- }
1220
- else {
1221
- resolve(completeResponse);
1222
- }
1223
- }, e => reject(e));
1224
- });
1225
- }
1226
- exports.searchGroupAllContents = searchGroupAllContents;
1227
- /**
1228
- * Searches for group contents matching criteria.
1229
- *
1230
- * @param groupId Group whose contents are to be searched
1231
- * @param searchString Text for which to search, e.g., 'redlands+map', 'type:"Web Map" -type:"Web Mapping Application"'
1232
- * @param authentication Credentials for the request to AGO
1233
- * @param additionalSearchOptions Adjustments to search, such as tranche size and categories of interest; categories
1234
- * are supplied as an array: each array element consists of one or more categories to be ORed; array elements are ANDed
1235
- * @param portalUrl Rest Url of the portal to perform the search
1236
- * @returns A promise that will resolve with a structure with a tranche of results and
1237
- * describing how many items are available
1238
- * @see https://developers.arcgis.com/rest/users-groups-and-items/group-content-search.htm
1239
- * @see https://developers.arcgis.com/rest/users-groups-and-items/search-reference.htm
1240
- */
1241
- function searchGroupContents(groupId, searchString, authentication, additionalSearchOptions, portalUrl) {
1242
- const searchOptions = {
1243
- groupId,
1244
- q: searchString,
1245
- params: Object.assign({
1246
- num: 100
1247
- }, additionalSearchOptions),
1248
- authentication: authentication,
1249
- portal: portalUrl
1250
- };
1251
- // If search options include `categories`, switch to new arcgis-rest-js format
1252
- /* istanbul ignore else */
1253
- if (Array.isArray(searchOptions.params.categories)) {
1254
- searchOptions.params.categories = searchOptions.params.categories.map(andGroup => andGroup.split(","));
1255
- }
1256
- return (0, arcgis_rest_portal_1.searchGroupContent)(searchOptions);
1257
- }
1258
- exports.searchGroupContents = searchGroupContents;
1259
- /**
1260
- * Reassign ownership of a group
1261
- *
1262
- * @param groupId Group to remove users from
1263
- * @param userName The new owner for the group
1264
- * @param authentication Credentials for the request to
1265
- *
1266
- * @returns A promise that will resolve after the group ownership has been assigned
1267
- *
1268
- */
1269
- function reassignGroup(groupId, userName, authentication) {
1270
- const requestOptions = {
1271
- authentication: authentication,
1272
- params: {
1273
- targetUsername: userName
1274
- }
1275
- };
1276
- return (0, arcgis_rest_request_1.request)(`${authentication.portal}/community/groups/${groupId}/reassign`, requestOptions);
1277
- }
1278
- exports.reassignGroup = reassignGroup;
1279
- /**
1280
- * Remove users from a group
1281
- *
1282
- * @param groupId Group to remove users from
1283
- * @param users List of users to remove from the group
1284
- * @param authentication Credentials for the request to
1285
- *
1286
- * @returns A promise that will resolve after the users have been removed
1287
- *
1288
- */
1289
- function removeUsers(groupId, users, authentication) {
1290
- return (0, arcgis_rest_portal_1.removeGroupUsers)({
1291
- id: groupId,
1292
- users,
1293
- authentication
1294
- });
1295
- }
1296
- exports.removeUsers = removeUsers;
1297
- /**
1298
- * Shares an item to the defined group
1299
- *
1300
- * @param groupId Group to share with
1301
- * @param id the item id to share with the group
1302
- * @param destinationAuthentication Credentials for the request to AGO
1303
- * @param owner owner of the group when sharing tracking items (can be different from the deploying user)
1304
- *
1305
- * @returns A promise that will resolve after the item has been shared
1306
- *
1307
- */
1308
- function shareItem(groupId, id, destinationAuthentication, owner) {
1309
- return new Promise((resolve, reject) => {
1310
- const shareOptions = {
1311
- groupId,
1312
- id,
1313
- authentication: destinationAuthentication
1314
- };
1315
- /* istanbul ignore else */
1316
- if (owner) {
1317
- shareOptions.owner = owner;
1318
- }
1319
- (0, arcgis_rest_portal_1.shareItemWithGroup)(shareOptions).then(() => resolve(null), (e) => reject((0, generalHelpers_1.fail)(e)));
1320
- });
1321
- }
1322
- exports.shareItem = shareItem;
1323
- /**
1324
- * Updates an item.
1325
- *
1326
- * @param itemInfo The base info of an item; note that this content will be serialized, which doesn't work
1327
- * for binary content
1328
- * @param authentication Credentials for request
1329
- * @param folderId Item's folder
1330
- * @param additionalParams Updates that are put under the `params` property, which is not serialized
1331
- * @return
1332
- */
1333
- function updateItem(itemInfo, authentication, folderId, additionalParams) {
1334
- return new Promise((resolve, reject) => {
1335
- const updateOptions = {
1336
- item: itemInfo,
1337
- folderId: folderId,
1338
- authentication: authentication,
1339
- params: {
1340
- ...(additionalParams ?? {})
1341
- }
1342
- };
1343
- (0, arcgis_rest_portal_1.updateItem)(updateOptions).then(response => (response.success ? resolve(response) : reject(response)), err => reject(err));
1344
- });
1345
- }
1346
- exports.updateItem = updateItem;
1347
- /**
1348
- * Updates a group.
1349
- *
1350
- * @param groupInfo The base info of a group; note that this content will be serialized, which doesn't work
1351
- * for binary content
1352
- * @param authentication Credentials for request
1353
- * @param additionalParams Updates that are put under the `params` property, which is not serialized
1354
- * @returns A Promise that will resolve with the success/failure status of the request
1355
- */
1356
- function updateGroup(groupInfo, authentication, additionalParams) {
1357
- return new Promise((resolve, reject) => {
1358
- const updateOptions = {
1359
- group: groupInfo,
1360
- authentication,
1361
- params: {
1362
- ...(additionalParams ?? {})
1363
- }
1364
- };
1365
- (0, arcgis_rest_portal_1.updateGroup)(updateOptions).then(response => (response.success ? resolve(response) : reject(response)), err => reject(err));
1366
- });
1367
- }
1368
- exports.updateGroup = updateGroup;
1369
- /**
1370
- * Updates an item.
1371
- *
1372
- * @param itemInfo The base info of an item
1373
- * @param data The items data section
1374
- * @param authentication Credentials for requests
1375
- * @param thumbnail optional thumbnail to update
1376
- * @param access "public" or "org"
1377
- * @return
1378
- */
1379
- function updateItemExtended(itemInfo, data, authentication, thumbnail, access, templateDictionary) {
1380
- return new Promise((resolve, reject) => {
1381
- const updateOptions = {
1382
- item: itemInfo,
1383
- params: {
1384
- text: data || {} // AGO ignores update if `data` is empty
1385
- },
1386
- authentication: authentication
1387
- };
1388
- if (thumbnail) {
1389
- updateOptions.params.thumbnail = thumbnail;
1390
- }
1391
- if ((0, trackingHelpers_1.isTrackingViewTemplate)(undefined, itemInfo) && templateDictionary) {
1392
- updateOptions.owner = templateDictionary.locationTracking.owner;
1393
- }
1394
- (0, arcgis_rest_portal_1.updateItem)(updateOptions).then(result => {
1395
- if (access && access !== "private") {
1396
- // Set access if it is not AGOL default
1397
- // Set the access manually since the access value in createItem appears to be ignored
1398
- const accessOptions = {
1399
- id: itemInfo.id,
1400
- access: access === "public" ? "public" : "org",
1401
- authentication: authentication
1402
- };
1403
- (0, arcgis_rest_portal_1.setItemAccess)(accessOptions).then(() => resolve(result), e => reject((0, generalHelpers_1.fail)(e)));
1404
- }
1405
- else {
1406
- resolve(result);
1407
- }
1408
- }, e => reject((0, generalHelpers_1.fail)(e)));
1409
- });
1410
- }
1411
- exports.updateItemExtended = updateItemExtended;
1412
- /**
1413
- * Update an item's base and data using a dictionary.
1414
- *
1415
- * @param {string} itemId The item ID
1416
- * @param {any} templateDictionary The template dictionary
1417
- * @param {UserSession} authentication The destination session info
1418
- * @returns Promise resolving to successfulness of update
1419
- */
1420
- function updateItemTemplateFromDictionary(itemId, templateDictionary, authentication) {
1421
- return new Promise((resolve, reject) => {
1422
- // Fetch the items as stored in AGO
1423
- Promise.all([
1424
- (0, restHelpersGet_1.getItemBase)(itemId, authentication),
1425
- (0, restHelpersGet_1.getItemDataAsJson)(itemId, authentication)
1426
- ])
1427
- .then(([item, data]) => {
1428
- // Do they have any variables?
1429
- if ((0, templatization_1.hasUnresolvedVariables)(item) || (0, templatization_1.hasUnresolvedVariables)(data)) {
1430
- // Update if so
1431
- const { item: updatedItem, data: updatedData } = (0, templatization_1.replaceInTemplate)({ item, data }, templateDictionary);
1432
- _reportVariablesInItem(itemId, item.type, updatedItem, updatedData);
1433
- return updateItemExtended(updatedItem, updatedData, authentication);
1434
- }
1435
- else {
1436
- // Shortcut out if not
1437
- return Promise.resolve({
1438
- success: true,
1439
- id: itemId
1440
- });
1441
- }
1442
- })
1443
- .then(result => resolve(result))
1444
- .catch(error => reject(error));
1445
- });
1446
- }
1447
- exports.updateItemTemplateFromDictionary = updateItemTemplateFromDictionary;
1448
- /**
1449
- * Updates the URL of an item.
1450
- *
1451
- * @param id AGOL id of item to update
1452
- * @param url URL to assign to item's base section
1453
- * @param authentication Credentials for the request
1454
- * @returns A promise that will resolve with the item id when the item has been updated or an AGO-style JSON failure
1455
- * response
1456
- */
1457
- function updateItemURL(id, url, authentication) {
1458
- const numAttempts = 3;
1459
- return _updateItemURL(id, url, authentication, numAttempts);
1460
- }
1461
- exports.updateItemURL = updateItemURL;
1462
- // ------------------------------------------------------------------------------------------------------------------ //
1463
- /**
1464
- * Adds a data section to an item.
1465
- *
1466
- * @param itemId Id of item to receive data file
1467
- * @param dataFile Data to be added
1468
- * @param authentication Credentials for the request
1469
- * @returns Promise reporting success or failure
1470
- * @private
1471
- */
1472
- function _addItemDataFile(itemId, dataFile, authentication) {
1473
- return new Promise((resolve, reject) => {
1474
- const _addItemData = (data) => {
1475
- addItemData(itemId, data, authentication).then(resolve, reject);
1476
- };
1477
- // Item data has to be submitted as text or JSON for those file types
1478
- if (dataFile.type.startsWith("text/plain")) {
1479
- (0, generalHelpers_1.blobToText)(dataFile).then(_addItemData, reject);
1480
- }
1481
- else if (dataFile.type === "application/json") {
1482
- (0, generalHelpers_1.blobToJson)(dataFile).then(_addItemData, reject);
1483
- }
1484
- else {
1485
- _addItemData(dataFile);
1486
- }
1487
- });
1488
- }
1489
- exports._addItemDataFile = _addItemDataFile;
1490
- /**
1491
- * Adds a metadata file to an item.
1492
- *
1493
- * @param itemId Id of item to receive data file
1494
- * @param metadataFile Metadata to be added
1495
- * @param authentication Credentials for the request
1496
- * @returns Promise reporting success or failure
1497
- * @private
1498
- */
1499
- function _addItemMetadataFile(itemId, metadataFile, authentication) {
1500
- return new Promise((resolve, reject) => {
1501
- const addMetadataOptions = {
1502
- item: {
1503
- id: itemId
1504
- },
1505
- params: {
1506
- // Pass metadata in via params because item property is serialized, which discards a blob
1507
- metadata: metadataFile
1508
- },
1509
- authentication: authentication
1510
- };
1511
- (0, arcgis_rest_portal_1.updateItem)(addMetadataOptions).then(resolve, reject);
1512
- });
1513
- }
1514
- exports._addItemMetadataFile = _addItemMetadataFile;
1515
- /**
1516
- * Accumulates the number of relationships in a collection of layers.
1517
- *
1518
- * @param List of layers to examine
1519
- * @returns The number of relationships
1520
- * @private
1521
- */
1522
- function _countRelationships(layers) {
1523
- const reducer = (accumulator, currentLayer) => accumulator +
1524
- (currentLayer.relationships ? currentLayer.relationships.length : 0);
1525
- return layers.reduce(reducer, 0);
1526
- }
1527
- exports._countRelationships = _countRelationships;
1528
- /**
1529
- * Gets the full definitions of the layers affiliated with a hosted service.
1530
- *
1531
- * @param serviceUrl URL to hosted service
1532
- * @param layerList List of layers at that service...must contain id
1533
- * @param authentication Credentials for the request
1534
- * @returns A promise that will resolve with a list of the layers from the admin api
1535
- * @private
1536
- */
1537
- function _getCreateServiceOptions(newItemTemplate, authentication, templateDictionary) {
1538
- return new Promise((resolve, reject) => {
1539
- const serviceInfo = newItemTemplate.properties;
1540
- const folderId = templateDictionary.folderId;
1541
- const isPortal = templateDictionary.isPortal;
1542
- const itemId = newItemTemplate.itemId;
1543
- (0, featureServiceHelpers_1.validateSpatialReferenceAndExtent)(serviceInfo, newItemTemplate, templateDictionary);
1544
- const fallbackExtent = _getFallbackExtent(serviceInfo, templateDictionary);
1545
- const params = {};
1546
- const itemInfo = {
1547
- title: newItemTemplate.item.title,
1548
- name: newItemTemplate.item.name
1549
- };
1550
- const _item = {
1551
- ...itemInfo,
1552
- preserveLayerIds: true
1553
- };
1554
- const createOptions = {
1555
- item: _item,
1556
- folderId,
1557
- params,
1558
- authentication: authentication
1559
- };
1560
- createOptions.item = !(0, trackingHelpers_1.isTrackingViewTemplate)(newItemTemplate) ?
1561
- _setItemProperties(createOptions.item, newItemTemplate, serviceInfo, params, isPortal) :
1562
- (0, trackingHelpers_1.setTrackingOptions)(newItemTemplate, createOptions, templateDictionary);
1563
- // project the portals extent to match that of the service
1564
- convertExtentWithFallback(templateDictionary.organization.defaultExtent, fallbackExtent, serviceInfo.service.spatialReference, templateDictionary.organization.helperServices.geometry.url, authentication).then(extent => {
1565
- templateDictionary[itemId].solutionExtent = extent;
1566
- (0, featureServiceHelpers_1.setDefaultSpatialReference)(templateDictionary, itemId, extent.spatialReference);
1567
- createOptions.item = (0, templatization_1.replaceInTemplate)(createOptions.item, templateDictionary);
1568
- createOptions.params = (0, templatization_1.replaceInTemplate)(createOptions.params, templateDictionary);
1569
- if (newItemTemplate.item.thumbnail) {
1570
- // Pass thumbnail file in via params because item property is serialized, which discards a blob
1571
- createOptions.params.thumbnail = newItemTemplate.item.thumbnail;
1572
- }
1573
- resolve(createOptions);
1574
- }, e => reject((0, generalHelpers_1.fail)(e)));
1575
- });
1576
- }
1577
- exports._getCreateServiceOptions = _getCreateServiceOptions;
1578
- /**
1579
- * When the services spatial reference does not match that of it's default extent
1580
- * use the out SRs default extent if it exists in the templateDictionary
1581
- * this should be set when adding a custom out wkid to the params before calling deploy
1582
- * this will help avoid situations where the orgs default extent and default world extent
1583
- * will not project successfully to the out SR
1584
- *
1585
- * @param serviceInfo the object that contains the spatial reference to evaluate
1586
- * @param templateDictionary the template dictionary
1587
- * @returns the extent to use as the fallback
1588
- * @private
1589
- */
1590
- function _getFallbackExtent(serviceInfo, templateDictionary) {
1591
- const serviceSR = serviceInfo.service.spatialReference;
1592
- const serviceInfoWkid = (0, generalHelpers_1.getProp)(serviceInfo, "defaultExtent.spatialReference.wkid");
1593
- const customDefaultExtent = (0, generalHelpers_1.getProp)(templateDictionary, "params.defaultExtent");
1594
- return serviceInfoWkid && serviceInfoWkid === serviceSR.wkid
1595
- ? serviceInfo.defaultExtent
1596
- : customDefaultExtent
1597
- ? customDefaultExtent
1598
- : serviceInfo.defaultExtent;
1599
- }
1600
- exports._getFallbackExtent = _getFallbackExtent;
1601
- /**
1602
- * Add relationships to all layers in one call to retain fully functioning composite relationships
1603
- *
1604
- * @param args The IPostProcessArgs for the request(s)
1605
- * @returns Any relationships that should be updated for the service
1606
- * @private
1607
- */
1608
- function _getRelationshipUpdates(args) {
1609
- const rels = {
1610
- layers: []
1611
- };
1612
- Object.keys(args.objects).forEach((k) => {
1613
- const obj = args.objects[k];
1614
- /* istanbul ignore else */
1615
- if (obj.relationships && obj.relationships.length > 0) {
1616
- rels.layers.push({
1617
- id: obj.id,
1618
- relationships: obj.relationships
1619
- });
1620
- }
1621
- (0, generalHelpers_1.deleteProp)(obj, "relationships");
1622
- });
1623
- return rels;
1624
- }
1625
- exports._getRelationshipUpdates = _getRelationshipUpdates;
1626
- /**
1627
- * Get the stored contingent values and structure them to be added to the services layers.
1628
- *
1629
- * @param args The IPostProcessArgs for the request(s)
1630
- * @returns Any contingent values that should be added to the service.
1631
- * @private
1632
- */
1633
- function _getContingentValuesUpdates(args) {
1634
- const contingentValues = [];
1635
- Object.keys(args.objects).forEach((k) => {
1636
- const obj = args.objects[k];
1637
- /* istanbul ignore else */
1638
- if (obj.contingentValues) {
1639
- contingentValues.push({
1640
- id: obj.id,
1641
- contingentValues: obj.contingentValues
1642
- });
1643
- }
1644
- (0, generalHelpers_1.deleteProp)(obj, "contingentValues");
1645
- });
1646
- return contingentValues;
1647
- }
1648
- exports._getContingentValuesUpdates = _getContingentValuesUpdates;
1649
- /**
1650
- * Get refresh, add, update, or delete definition info
1651
- *
1652
- * @param url the base admin url for the service
1653
- * @param id the id of the layer
1654
- * @param obj parameters for the request
1655
- * @param args various arguments to help support the request
1656
- * @param type type of update the request will handle
1657
- * @returns IUpdate that has the request url and arguments
1658
- * @private
1659
- */
1660
- function _getUpdate(url, id, obj, args, type) {
1661
- const ops = {
1662
- delete: {
1663
- url: (0, generalHelpers_1.checkUrlPathTermination)(url) + id + "/deleteFromDefinition",
1664
- params: {
1665
- deleteFromDefinition: {
1666
- fields: obj && obj.hasOwnProperty("deleteFields") ? obj.deleteFields : []
1667
- }
1668
- }
1669
- },
1670
- update: {
1671
- url: (0, generalHelpers_1.checkUrlPathTermination)(url) +
1672
- (id ? `${id}/updateDefinition` : "updateDefinition"),
1673
- params: {
1674
- updateDefinition: obj
1675
- }
1676
- },
1677
- add: {
1678
- url: (0, generalHelpers_1.checkUrlPathTermination)(url) + "addToDefinition",
1679
- params: {
1680
- addToDefinition: obj
1681
- }
1682
- },
1683
- refresh: {
1684
- url: (0, generalHelpers_1.checkUrlPathTermination)(url) + "refresh",
1685
- params: {
1686
- f: "json"
1687
- }
1688
- }
1689
- };
1690
- return {
1691
- url: ops[type].url,
1692
- params: ops[type].params,
1693
- args: args
1694
- };
1695
- }
1696
- exports._getUpdate = _getUpdate;
1697
- /**
1698
- * Changes just the domain part of a URL to lowercase.
1699
- *
1700
- * @param url URL to modify
1701
- * @return Adjusted URL
1702
- * @see From `getServerRootUrl` in arcgis-rest-js' ArcGISIdentityManager.ts
1703
- * @private
1704
- */
1705
- function _lowercaseDomain(url) {
1706
- if (!url) {
1707
- return url;
1708
- }
1709
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1710
- const [_, protocol, domainAndPath] = url.match(/(https?:\/\/)(.+)/);
1711
- const [domain, ...path] = domainAndPath.split("/");
1712
- // Only the domain is lowercased because in some cases an org id might be
1713
- // in the path which cannot be lowercased.
1714
- return `${protocol}${domain.toLowerCase()}/${path.join("/")}`;
1715
- }
1716
- exports._lowercaseDomain = _lowercaseDomain;
1717
- /**
1718
- * Checks the two main parts of an item for unresolved variables and reports any found.
1719
- *
1720
- * @param base Item's base section
1721
- * @param data Item's data section
1722
- * @private
1723
- */
1724
- function _reportVariablesInItem(itemId, itemType, base, data) {
1725
- const getUnresolved = (v) => {
1726
- return JSON.stringify(v).match(/{{.+?}}/gim);
1727
- };
1728
- // Provide feedback about any remaining unresolved variables
1729
- /* istanbul ignore else */
1730
- if (base && (0, templatization_1.hasUnresolvedVariables)(base)) {
1731
- console.log(itemId +
1732
- " (" +
1733
- itemType +
1734
- ") contains variables in base: " +
1735
- JSON.stringify(getUnresolved(base)));
1736
- }
1737
- /* istanbul ignore else */
1738
- if (data && (0, templatization_1.hasUnresolvedVariables)(data)) {
1739
- console.log(itemId +
1740
- " (" +
1741
- itemType +
1742
- ") contains variables in data: " +
1743
- JSON.stringify(getUnresolved(data)));
1744
- }
1745
- }
1746
- exports._reportVariablesInItem = _reportVariablesInItem;
1747
- /**
1748
- * Updates a feature service item.
1749
- *
1750
- * @param item Item to update
1751
- * @param itemTemplate item template for the new item
1752
- * @param serviceInfo Service information
1753
- * @param params arcgis-rest-js params to update
1754
- * @param isPortal Is the service hosted in a portal?
1755
- * @returns Updated item
1756
- * @private
1757
- */
1758
- function _setItemProperties(item, itemTemplate, serviceInfo, params, isPortal) {
1759
- // Set the capabilities
1760
- const portalCapabilities = [
1761
- "Create",
1762
- "Query",
1763
- "Editing",
1764
- "Update",
1765
- "Delete",
1766
- "Uploads",
1767
- "Sync",
1768
- "Extract"
1769
- ];
1770
- const capabilities = (0, generalHelpers_1.getProp)(serviceInfo, "service.capabilities") || (isPortal ? "" : []);
1771
- item.capabilities = isPortal
1772
- ? capabilities
1773
- .split(",")
1774
- .filter((c) => portalCapabilities.indexOf(c) > -1)
1775
- .join(",")
1776
- : capabilities;
1777
- if (serviceInfo.service.capabilities) {
1778
- serviceInfo.service.capabilities = item.capabilities;
1779
- }
1780
- // Handle index update for any pre-published solution items that
1781
- // have non-unique indexes on relationship key fields
1782
- _updateIndexesForRelationshipKeyFields(serviceInfo);
1783
- // set create options item properties
1784
- const keyProperties = [
1785
- "isView",
1786
- "sourceSchemaChangesAllowed",
1787
- "isUpdatableView",
1788
- "capabilities",
1789
- "isMultiServicesView"
1790
- ];
1791
- const deleteKeys = ["layers", "tables"];
1792
- /* istanbul ignore else */
1793
- if (isPortal) {
1794
- // removed for issue #423 causing FS to fail to create
1795
- deleteKeys.push("adminServiceInfo");
1796
- }
1797
- const itemKeys = Object.keys(item);
1798
- const serviceKeys = Object.keys(serviceInfo.service);
1799
- serviceKeys.forEach(k => {
1800
- /* istanbul ignore else */
1801
- if (itemKeys.indexOf(k) === -1 && deleteKeys.indexOf(k) < 0) {
1802
- item[k] = serviceInfo.service[k];
1803
- // These need to be included via params otherwise...
1804
- // addToDef calls fail when adding adminLayerInfo
1805
- /* istanbul ignore else */
1806
- if (serviceInfo.service.isView && keyProperties.indexOf(k) > -1) {
1807
- params[k] = serviceInfo.service[k];
1808
- }
1809
- }
1810
- });
1811
- // Enable editor tracking on layer with related tables is not supported.
1812
- /* istanbul ignore else */
1813
- if (item.isMultiServicesView &&
1814
- (0, generalHelpers_1.getProp)(item, "editorTrackingInfo.enableEditorTracking")) {
1815
- item.editorTrackingInfo.enableEditorTracking = false;
1816
- params["editorTrackingInfo"] = item.editorTrackingInfo;
1817
- }
1818
- /* istanbul ignore else */
1819
- if (isPortal) {
1820
- // portal will fail when initialExtent is defined but null
1821
- // removed for issue #449 causing FS to fail to create on portal
1822
- /* istanbul ignore else */
1823
- if (Object.keys(item).indexOf("initialExtent") > -1 &&
1824
- !item.initialExtent) {
1825
- (0, generalHelpers_1.deleteProp)(item, "initialExtent");
1826
- }
1827
- }
1828
- return item;
1829
- }
1830
- exports._setItemProperties = _setItemProperties;
1831
- /**
1832
- * Set isUnique as true for indexes that reference origin relationship keyFields.
1833
- *
1834
- * @param serviceInfo Service information
1835
- * @private
1836
- */
1837
- function _updateIndexesForRelationshipKeyFields(serviceInfo) {
1838
- const layersAndTables = (serviceInfo.layers || []).concat(serviceInfo.tables || []);
1839
- layersAndTables.forEach(item => {
1840
- const relationships = item.relationships;
1841
- const indexes = item.indexes;
1842
- /* istanbul ignore else */
1843
- if (relationships &&
1844
- relationships.length > 0 &&
1845
- indexes &&
1846
- indexes.length > 0) {
1847
- const keyFields = relationships.reduce((acc, v) => {
1848
- /* istanbul ignore else */
1849
- if (v.role === "esriRelRoleOrigin" &&
1850
- v.keyField &&
1851
- acc.indexOf(v.keyField) < 0) {
1852
- acc.push(v.keyField);
1853
- }
1854
- return acc;
1855
- }, []);
1856
- indexes.map(i => {
1857
- /* istanbul ignore else */
1858
- if (keyFields.some(k => {
1859
- const regEx = new RegExp(`\\b${k}\\b`);
1860
- return regEx.test(i.fields);
1861
- })) {
1862
- i.isUnique = true;
1863
- }
1864
- return i;
1865
- });
1866
- }
1867
- });
1868
- }
1869
- exports._updateIndexesForRelationshipKeyFields = _updateIndexesForRelationshipKeyFields;
1870
- /**
1871
- * Updates the URL of an item.
1872
- *
1873
- * @param id AGOL id of item to update
1874
- * @param url URL to assign to item's base section
1875
- * @param authentication Credentials for the request
1876
- * @param numAttempts Number of times to try to set the URL if AGO says that it updated the URL, but really didn't
1877
- * @returns A promise that will resolve with the item id when the item has been updated or an AGO-style JSON failure
1878
- * response
1879
- * @private
1880
- */
1881
- function _updateItemURL(id, url, authentication, numAttempts = 1) {
1882
- // Introduce a lag because AGO update appears to choke with rapid subsequent calls
1883
- const msLag = 1000;
1884
- return new Promise((resolve, reject) => {
1885
- // Update the item's URL
1886
- const options = { item: { id, url }, authentication: authentication };
1887
- (0, arcgis_rest_portal_1.updateItem)(options).then(result => {
1888
- if (!result.success) {
1889
- reject((0, generalHelpers_1.fail)(result));
1890
- }
1891
- else {
1892
- // Get the item to see if the URL really changed; we'll delay a bit before testing because AGO
1893
- // has a timing problem with URL updates
1894
- setTimeout(() => {
1895
- (0, arcgis_rest_portal_1.getItem)(id, { authentication: authentication }).then(item => {
1896
- const iBrace = item.url.indexOf("{");
1897
- if (iBrace > -1) {
1898
- console.warn(id + " has template variable: " + item.url.substr(iBrace));
1899
- }
1900
- if (url === item.url) {
1901
- resolve(id);
1902
- }
1903
- else {
1904
- // If it fails, try again if we have sufficient attempts remaining
1905
- const errorMsg = "URL not updated for " +
1906
- item.type +
1907
- " " +
1908
- item.id +
1909
- ": " +
1910
- item.url +
1911
- " (" +
1912
- numAttempts +
1913
- ")";
1914
- if (--numAttempts > 0) {
1915
- _updateItemURL(id, url, authentication, numAttempts).then(resolve, reject);
1916
- }
1917
- else {
1918
- console.error(id + ": " + errorMsg + "; FAILED");
1919
- reject(errorMsg);
1920
- }
1921
- }
1922
- }, e => reject((0, generalHelpers_1.fail)(e)));
1923
- }, msLag);
1924
- }
1925
- }, e => reject((0, generalHelpers_1.fail)(e)));
1926
- });
1927
- }
1928
- exports._updateItemURL = _updateItemURL;
1929
- //# sourceMappingURL=restHelpers.js.map