@esri/solution-creator 0.24.0 → 1.1.4

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.
@@ -1,7 +1,7 @@
1
1
  /* @preserve
2
- * @esri/solution-creator - v0.24.0 - Apache-2.0
2
+ * @esri/solution-creator - v1.1.4 - Apache-2.0
3
3
  * Copyright (c) 2018-2021 Esri, Inc.
4
- * Wed Jun 09 2021 15:03:13 GMT-0700 (Pacific Daylight Time)
4
+ * Tue Oct 26 2021 15:16:53 GMT-0700 (Pacific Daylight Time)
5
5
  *
6
6
  * Licensed under the Apache License, Version 2.0 (the "License");
7
7
  * you may not use this file except in compliance with the License.
@@ -16,1281 +16,1250 @@
16
16
  * limitations under the License.
17
17
  */
18
18
  (function (global, factory) {
19
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@esri/solution-common'), require('@esri/hub-common'), require('@esri/solution-feature-layer'), require('@esri/solution-file'), require('@esri/solution-form'), require('@esri/solution-group'), require('@esri/solution-simple-types'), require('@esri/solution-storymap'), require('@esri/solution-web-experience'), require('@esri/solution-hub-types')) :
20
- typeof define === 'function' && define.amd ? define(['exports', '@esri/solution-common', '@esri/hub-common', '@esri/solution-feature-layer', '@esri/solution-file', '@esri/solution-form', '@esri/solution-group', '@esri/solution-simple-types', '@esri/solution-storymap', '@esri/solution-web-experience', '@esri/solution-hub-types'], factory) :
21
- (global = global || self, factory(global.arcgisSolution = global.arcgisSolution || {}, global.arcgisSolution, global.arcgisHub, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution));
22
- }(this, (function (exports, solutionCommon, hubCommon, featureLayer, fileProcessor, formProcessor, group, solutionSimpleTypes, solutionStorymap, solutionWebExperience, solutionHubTypes) { 'use strict';
19
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@esri/solution-common'), require('@esri/hub-common'), require('@esri/solution-feature-layer'), require('@esri/solution-file'), require('@esri/solution-form'), require('@esri/solution-group'), require('@esri/solution-simple-types'), require('@esri/solution-storymap'), require('@esri/solution-velocity'), require('@esri/solution-web-experience'), require('@esri/solution-hub-types')) :
20
+ typeof define === 'function' && define.amd ? define(['exports', '@esri/solution-common', '@esri/hub-common', '@esri/solution-feature-layer', '@esri/solution-file', '@esri/solution-form', '@esri/solution-group', '@esri/solution-simple-types', '@esri/solution-storymap', '@esri/solution-velocity', '@esri/solution-web-experience', '@esri/solution-hub-types'], factory) :
21
+ (global = global || self, factory(global.arcgisSolution = global.arcgisSolution || {}, global.arcgisSolution, global.arcgisHub, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution, global.arcgisSolution));
22
+ }(this, (function (exports, solutionCommon, hubCommon, featureLayer, fileProcessor, formProcessor, group, solutionSimpleTypes, solutionStorymap, solutionVelocity, solutionWebExperience, solutionHubTypes) { 'use strict';
23
23
 
24
- /*! *****************************************************************************
25
- Copyright (c) Microsoft Corporation. All rights reserved.
26
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
27
- this file except in compliance with the License. You may obtain a copy of the
28
- License at http://www.apache.org/licenses/LICENSE-2.0
29
-
30
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
31
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
32
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
33
- MERCHANTABLITY OR NON-INFRINGEMENT.
34
-
35
- See the Apache Version 2.0 License for specific language governing permissions
36
- and limitations under the License.
37
- ***************************************************************************** */
38
-
39
- var __assign = function() {
40
- __assign = Object.assign || function __assign(t) {
41
- for (var s, i = 1, n = arguments.length; i < n; i++) {
42
- s = arguments[i];
43
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
44
- }
45
- return t;
46
- };
47
- return __assign.apply(this, arguments);
48
- };
49
-
50
- function __read(o, n) {
51
- var m = typeof Symbol === "function" && o[Symbol.iterator];
52
- if (!m) return o;
53
- var i = m.call(o), r, ar = [], e;
54
- try {
55
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
56
- }
57
- catch (error) { e = { error: error }; }
58
- finally {
59
- try {
60
- if (r && !r.done && (m = i["return"])) m.call(i);
61
- }
62
- finally { if (e) throw e.error; }
63
- }
64
- return ar;
65
- }
66
-
67
- function __spread() {
68
- for (var ar = [], i = 0; i < arguments.length; i++)
69
- ar = ar.concat(__read(arguments[i]));
70
- return ar;
71
- }
24
+ /** @license
25
+ * Copyright 2020 Esri
26
+ *
27
+ * Licensed under the Apache License, Version 2.0 (the "License");
28
+ * you may not use this file except in compliance with the License.
29
+ * You may obtain a copy of the License at
30
+ *
31
+ * http://www.apache.org/licenses/LICENSE-2.0
32
+ *
33
+ * Unless required by applicable law or agreed to in writing, software
34
+ * distributed under the License is distributed on an "AS IS" BASIS,
35
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
+ * See the License for the specific language governing permissions and
37
+ * limitations under the License.
38
+ */
39
+ const UNSUPPORTED = null;
40
+ /**
41
+ * Mapping from item type to module with type-specific template-handling code.
42
+ * AGO types come from a blend of arcgis-portal-app\src\js\arcgisonline\pages\item\_Info.js and
43
+ * arcgis-portal-app\src\js\arcgis-components\src\_utils\metadata\item\displayName.ts
44
+ */
45
+ const moduleMap = {
46
+ ////////////////////////////////////////////////////////
47
+ // Group type
48
+ Group: group,
49
+ ////////////////////////////////////////////////////////
50
+ // Layer types
51
+ "Big Data Analytic": solutionVelocity.VelocityProcessor,
52
+ "Feature Collection": solutionSimpleTypes.simpleTypes,
53
+ "Feature Service": featureLayer,
54
+ Feed: solutionVelocity.VelocityProcessor,
55
+ "Geocoding Service": undefined,
56
+ "Geodata Service": undefined,
57
+ "Geometry Service": undefined,
58
+ "Geoprocessing Service": undefined,
59
+ "Globe Service": undefined,
60
+ "Image Service": undefined,
61
+ KML: undefined,
62
+ "Map Service": featureLayer,
63
+ "Network Analysis Service": undefined,
64
+ "Real Time Analytic": solutionVelocity.VelocityProcessor,
65
+ "Relational Database Connection": undefined,
66
+ "Scene Service": undefined,
67
+ "Stream Service": undefined,
68
+ Tool: undefined,
69
+ "Vector Tile Service": undefined,
70
+ WFS: undefined,
71
+ WMS: undefined,
72
+ WMTS: undefined,
73
+ "Workflow Manager Service": undefined,
74
+ ////////////////////////////////////////////////////////
75
+ // Map types
76
+ "3D Web Scene": undefined,
77
+ "Web Map": solutionSimpleTypes.simpleTypes,
78
+ "Web Scene": solutionSimpleTypes.simpleTypes,
79
+ ////////////////////////////////////////////////////////
80
+ // App types
81
+ Application: undefined,
82
+ Dashboard: solutionSimpleTypes.simpleTypes,
83
+ "Data Store": undefined,
84
+ "Desktop Application": undefined,
85
+ "Excalibur Imagery Project": undefined,
86
+ Form: formProcessor,
87
+ "Hub Initiative": UNSUPPORTED,
88
+ "Hub Page": solutionHubTypes.HubPageProcessor,
89
+ "Hub Site Application": solutionHubTypes.HubSiteProcessor,
90
+ "Insights Model": solutionSimpleTypes.simpleTypes,
91
+ "Insights Page": undefined,
92
+ "Insights Theme": undefined,
93
+ "Insights Workbook": undefined,
94
+ Mission: undefined,
95
+ "Mobile Application": undefined,
96
+ Notebook: solutionSimpleTypes.notebookProcessor,
97
+ "Oriented Imagery Catalog": solutionSimpleTypes.simpleTypes,
98
+ "Ortho Mapping Project": undefined,
99
+ "QuickCapture Project": solutionSimpleTypes.quickcaptureProcessor,
100
+ "Site Application": solutionHubTypes.HubSiteProcessor,
101
+ "Site Page": solutionHubTypes.HubPageProcessor,
102
+ Solution: UNSUPPORTED,
103
+ StoryMap: solutionStorymap.StoryMapProcessor,
104
+ "Urban Model": undefined,
105
+ "Web Experience Template": undefined,
106
+ "Web Experience": solutionWebExperience.WebExperienceProcessor,
107
+ "Web Mapping Application": solutionSimpleTypes.simpleTypes,
108
+ "Workforce Project": solutionSimpleTypes.simpleTypes,
109
+ ////////////////////////////////////////////////////////
110
+ // File types
111
+ "360 VR Experience": fileProcessor,
112
+ "AppBuilder Extension": fileProcessor,
113
+ "AppBuilder Widget Package": fileProcessor,
114
+ "Application Configuration": fileProcessor,
115
+ "ArcGIS Pro Add In": fileProcessor,
116
+ "ArcGIS Pro Configuration": fileProcessor,
117
+ "ArcPad Package": fileProcessor,
118
+ "Basemap Package": fileProcessor,
119
+ "CAD Drawing": fileProcessor,
120
+ "CityEngine Web Scene": fileProcessor,
121
+ "Code Attachment": UNSUPPORTED,
122
+ "Code Sample": fileProcessor,
123
+ "Color Set": fileProcessor,
124
+ "Compact Tile Package": fileProcessor,
125
+ "CSV Collection": fileProcessor,
126
+ CSV: fileProcessor,
127
+ "Deep Learning Package": fileProcessor,
128
+ "Desktop Add In": fileProcessor,
129
+ "Desktop Application Template": fileProcessor,
130
+ "Desktop Style": fileProcessor,
131
+ "Document Link": fileProcessor,
132
+ "Explorer Add In": fileProcessor,
133
+ "Explorer Layer": fileProcessor,
134
+ "Explorer Map": fileProcessor,
135
+ "Feature Collection Template": fileProcessor,
136
+ "File Geodatabase": fileProcessor,
137
+ GeoJson: fileProcessor,
138
+ GeoPackage: fileProcessor,
139
+ "Geoprocessing Package": fileProcessor,
140
+ "Geoprocessing Sample": fileProcessor,
141
+ "Globe Document": fileProcessor,
142
+ "Image Collection": fileProcessor,
143
+ Image: fileProcessor,
144
+ "iWork Keynote": fileProcessor,
145
+ "iWork Numbers": fileProcessor,
146
+ "iWork Pages": fileProcessor,
147
+ "KML Collection": fileProcessor,
148
+ "Layer Package": fileProcessor,
149
+ "Layer Template": fileProcessor,
150
+ Layer: fileProcessor,
151
+ Layout: fileProcessor,
152
+ "Locator Package": fileProcessor,
153
+ "Map Document": fileProcessor,
154
+ "Map Package": fileProcessor,
155
+ "Map Template": fileProcessor,
156
+ "Microsoft Excel": fileProcessor,
157
+ "Microsoft Powerpoint": fileProcessor,
158
+ "Microsoft Word": fileProcessor,
159
+ "Mobile Basemap Package": fileProcessor,
160
+ "Mobile Map Package": fileProcessor,
161
+ "Mobile Scene Package": fileProcessor,
162
+ "Native Application": fileProcessor,
163
+ "Native Application Installer": fileProcessor,
164
+ "Native Application Template": fileProcessor,
165
+ netCDF: fileProcessor,
166
+ "Operation View": fileProcessor,
167
+ "Operations Dashboard Add In": fileProcessor,
168
+ "Operations Dashboard Extension": fileProcessor,
169
+ PDF: fileProcessor,
170
+ "Pro Layer Package": fileProcessor,
171
+ "Pro Layer": fileProcessor,
172
+ "Pro Map Package": fileProcessor,
173
+ "Pro Map": fileProcessor,
174
+ "Pro Report": fileProcessor,
175
+ "Project Package": fileProcessor,
176
+ "Project Template": fileProcessor,
177
+ "Published Map": fileProcessor,
178
+ "Raster function template": fileProcessor,
179
+ "Report Template": fileProcessor,
180
+ "Rule Package": fileProcessor,
181
+ "Scene Document": fileProcessor,
182
+ "Scene Package": fileProcessor,
183
+ "Service Definition": fileProcessor,
184
+ Shapefile: fileProcessor,
185
+ "Statistical Data Collection": fileProcessor,
186
+ Style: fileProcessor,
187
+ "Survey123 Add In": fileProcessor,
188
+ "Symbol Set": fileProcessor,
189
+ "Task File": fileProcessor,
190
+ "Tile Package": fileProcessor,
191
+ "Toolbox Package": fileProcessor,
192
+ "Vector Tile Package": fileProcessor,
193
+ "Viewer Configuration": fileProcessor,
194
+ "Visio Document": fileProcessor,
195
+ "Window Mobile Package": fileProcessor,
196
+ "Windows Mobile Package": fileProcessor,
197
+ "Windows Viewer Add In": fileProcessor,
198
+ "Windows Viewer Configuration": fileProcessor,
199
+ "Workflow Manager Package": fileProcessor,
200
+ ////////////////////////////////////////////////////////
201
+ // Testing "types"
202
+ Undefined: undefined,
203
+ Unsupported: UNSUPPORTED
204
+ };
72
205
 
73
- /** @license
74
- * Copyright 2020 Esri
75
- *
76
- * Licensed under the Apache License, Version 2.0 (the "License");
77
- * you may not use this file except in compliance with the License.
78
- * You may obtain a copy of the License at
79
- *
80
- * http://www.apache.org/licenses/LICENSE-2.0
81
- *
82
- * Unless required by applicable law or agreed to in writing, software
83
- * distributed under the License is distributed on an "AS IS" BASIS,
84
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85
- * See the License for the specific language governing permissions and
86
- * limitations under the License.
87
- */
88
- var UNSUPPORTED = null;
89
- /**
90
- * Mapping from item type to module with type-specific template-handling code.
91
- * AGO types come from a blend of arcgis-portal-app\src\js\arcgisonline\pages\item\_Info.js and
92
- * arcgis-portal-app\src\js\arcgis-components\src\_utils\metadata\item\displayName.ts
93
- */
94
- var moduleMap = {
95
- ////////////////////////////////////////////////////////
96
- // Group type
97
- Group: group,
98
- ////////////////////////////////////////////////////////
99
- // Layer types
100
- "Big Data Analytic": undefined,
101
- "Feature Collection": solutionSimpleTypes.simpleTypes,
102
- "Feature Service": featureLayer,
103
- Feed: undefined,
104
- "Geocoding Service": undefined,
105
- "Geodata Service": undefined,
106
- "Geometry Service": undefined,
107
- "Geoprocessing Service": undefined,
108
- "Globe Service": undefined,
109
- "Image Service": undefined,
110
- KML: undefined,
111
- "Map Service": featureLayer,
112
- "Network Analysis Service": undefined,
113
- "Real Time Analytic": undefined,
114
- "Relational Database Connection": undefined,
115
- "Scene Service": undefined,
116
- "Stream Service": undefined,
117
- Tool: undefined,
118
- "Vector Tile Service": undefined,
119
- WFS: undefined,
120
- WMS: undefined,
121
- WMTS: undefined,
122
- "Workflow Manager Service": undefined,
123
- ////////////////////////////////////////////////////////
124
- // Map types
125
- "3D Web Scene": undefined,
126
- "Web Map": solutionSimpleTypes.simpleTypes,
127
- "Web Scene": undefined,
128
- ////////////////////////////////////////////////////////
129
- // App types
130
- Application: undefined,
131
- Dashboard: solutionSimpleTypes.simpleTypes,
132
- "Data Store": undefined,
133
- "Desktop Application": undefined,
134
- "Excalibur Imagery Project": undefined,
135
- Form: formProcessor,
136
- "Hub Initiative": UNSUPPORTED,
137
- "Hub Page": solutionHubTypes.HubPageProcessor,
138
- "Hub Site Application": solutionHubTypes.HubSiteProcessor,
139
- "Insights Model": solutionSimpleTypes.simpleTypes,
140
- "Insights Page": undefined,
141
- "Insights Theme": undefined,
142
- "Insights Workbook": undefined,
143
- Mission: undefined,
144
- "Mobile Application": undefined,
145
- Notebook: solutionSimpleTypes.notebookProcessor,
146
- "Oriented Imagery Catalog": solutionSimpleTypes.simpleTypes,
147
- "Ortho Mapping Project": undefined,
148
- "QuickCapture Project": solutionSimpleTypes.quickcaptureProcessor,
149
- "Site Application": solutionHubTypes.HubSiteProcessor,
150
- "Site Page": solutionHubTypes.HubPageProcessor,
151
- Solution: UNSUPPORTED,
152
- StoryMap: solutionStorymap.StoryMapProcessor,
153
- "Urban Model": undefined,
154
- "Web Experience Template": undefined,
155
- "Web Experience": solutionWebExperience.WebExperienceProcessor,
156
- "Web Mapping Application": solutionSimpleTypes.simpleTypes,
157
- "Workforce Project": solutionSimpleTypes.simpleTypes,
158
- ////////////////////////////////////////////////////////
159
- // File types
160
- "360 VR Experience": fileProcessor,
161
- "AppBuilder Extension": fileProcessor,
162
- "AppBuilder Widget Package": fileProcessor,
163
- "Application Configuration": fileProcessor,
164
- "ArcGIS Pro Add In": fileProcessor,
165
- "ArcGIS Pro Configuration": fileProcessor,
166
- "ArcPad Package": fileProcessor,
167
- "Basemap Package": fileProcessor,
168
- "CAD Drawing": fileProcessor,
169
- "CityEngine Web Scene": fileProcessor,
170
- "Code Attachment": UNSUPPORTED,
171
- "Code Sample": fileProcessor,
172
- "Color Set": fileProcessor,
173
- "Compact Tile Package": fileProcessor,
174
- "CSV Collection": fileProcessor,
175
- CSV: fileProcessor,
176
- "Deep Learning Package": fileProcessor,
177
- "Desktop Add In": fileProcessor,
178
- "Desktop Application Template": fileProcessor,
179
- "Desktop Style": fileProcessor,
180
- "Document Link": fileProcessor,
181
- "Explorer Add In": fileProcessor,
182
- "Explorer Layer": fileProcessor,
183
- "Explorer Map": fileProcessor,
184
- "Feature Collection Template": fileProcessor,
185
- "File Geodatabase": fileProcessor,
186
- GeoJson: fileProcessor,
187
- GeoPackage: fileProcessor,
188
- "Geoprocessing Package": fileProcessor,
189
- "Geoprocessing Sample": fileProcessor,
190
- "Globe Document": fileProcessor,
191
- "Image Collection": fileProcessor,
192
- Image: fileProcessor,
193
- "iWork Keynote": fileProcessor,
194
- "iWork Numbers": fileProcessor,
195
- "iWork Pages": fileProcessor,
196
- "KML Collection": fileProcessor,
197
- "Layer Package": fileProcessor,
198
- "Layer Template": fileProcessor,
199
- Layer: fileProcessor,
200
- Layout: fileProcessor,
201
- "Locator Package": fileProcessor,
202
- "Map Document": fileProcessor,
203
- "Map Package": fileProcessor,
204
- "Map Template": fileProcessor,
205
- "Microsoft Excel": fileProcessor,
206
- "Microsoft Powerpoint": fileProcessor,
207
- "Microsoft Word": fileProcessor,
208
- "Mobile Basemap Package": fileProcessor,
209
- "Mobile Map Package": fileProcessor,
210
- "Mobile Scene Package": fileProcessor,
211
- "Native Application": fileProcessor,
212
- "Native Application Installer": fileProcessor,
213
- "Native Application Template": fileProcessor,
214
- netCDF: fileProcessor,
215
- "Operation View": fileProcessor,
216
- "Operations Dashboard Add In": fileProcessor,
217
- "Operations Dashboard Extension": fileProcessor,
218
- PDF: fileProcessor,
219
- "Pro Layer Package": fileProcessor,
220
- "Pro Layer": fileProcessor,
221
- "Pro Map Package": fileProcessor,
222
- "Pro Map": fileProcessor,
223
- "Pro Report": fileProcessor,
224
- "Project Package": fileProcessor,
225
- "Project Template": fileProcessor,
226
- "Published Map": fileProcessor,
227
- "Raster function template": fileProcessor,
228
- "Report Template": fileProcessor,
229
- "Rule Package": fileProcessor,
230
- "Scene Document": fileProcessor,
231
- "Scene Package": fileProcessor,
232
- "Service Definition": fileProcessor,
233
- Shapefile: fileProcessor,
234
- "Statistical Data Collection": fileProcessor,
235
- Style: fileProcessor,
236
- "Survey123 Add In": fileProcessor,
237
- "Symbol Set": fileProcessor,
238
- "Task File": fileProcessor,
239
- "Tile Package": fileProcessor,
240
- "Toolbox Package": fileProcessor,
241
- "Vector Tile Package": fileProcessor,
242
- "Viewer Configuration": fileProcessor,
243
- "Visio Document": fileProcessor,
244
- "Window Mobile Package": fileProcessor,
245
- "Windows Mobile Package": fileProcessor,
246
- "Windows Viewer Add In": fileProcessor,
247
- "Windows Viewer Configuration": fileProcessor,
248
- "Workflow Manager Package": fileProcessor,
249
- ////////////////////////////////////////////////////////
250
- // Testing "types"
251
- Undefined: undefined,
252
- Unsupported: UNSUPPORTED
253
- };
206
+ /** @license
207
+ * Copyright 2018 Esri
208
+ *
209
+ * Licensed under the Apache License, Version 2.0 (the "License");
210
+ * you may not use this file except in compliance with the License.
211
+ * You may obtain a copy of the License at
212
+ *
213
+ * http://www.apache.org/licenses/LICENSE-2.0
214
+ *
215
+ * Unless required by applicable law or agreed to in writing, software
216
+ * distributed under the License is distributed on an "AS IS" BASIS,
217
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
218
+ * See the License for the specific language governing permissions and
219
+ * limitations under the License.
220
+ */
221
+ // ------------------------------------------------------------------------------------------------------------------ //
222
+ /**
223
+ * Creates template for an AGO item and its dependencies
224
+ *
225
+ * @param solutionItemId The solution to contain the item
226
+ * @param itemId AGO id string
227
+ * @param templateDictionary Hash of facts
228
+ * @param srcAuthentication Credentials for requests to source items
229
+ * @param destAuthentication Authentication for requesting information from AGO about items to be included in solution item
230
+ * @param existingTemplates A collection of AGO item templates that can be referenced by newly-created templates
231
+ * @return A promise which resolves with an array of resources for the item and its dependencies
232
+ * @protected
233
+ */
234
+ function createItemTemplate(solutionItemId, itemId, templateDictionary, srcAuthentication, destAuthentication, existingTemplates, itemProgressCallback) {
235
+ return new Promise(resolve => {
236
+ // Check if item and its dependents are already in list or are queued
237
+ if (solutionCommon.findTemplateInList(existingTemplates, itemId)) {
238
+ resolve([]);
239
+ }
240
+ else {
241
+ // Add the id as a placeholder to show that it is being fetched
242
+ existingTemplates.push(solutionCommon.createPlaceholderTemplate(itemId));
243
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Started, 0);
244
+ // Fetch the item
245
+ solutionCommon.getItemBase(itemId, srcAuthentication)
246
+ .catch(() => {
247
+ // If item query fails, try fetching item as a group
248
+ // Change its placeholder from an empty type to the Group type so that we can later distinguish
249
+ // between items and groups (the base info for a group doesn't include a type property)
250
+ solutionCommon.replaceTemplate(existingTemplates, itemId, solutionCommon.createPlaceholderTemplate(itemId, "Group"));
251
+ return solutionCommon.getGroupBase(itemId, srcAuthentication);
252
+ })
253
+ .then(itemInfo => {
254
+ itemInfo = solutionCommon.sanitizeJSONAndReportChanges(itemInfo);
255
+ // Save the URL as a symbol
256
+ if (itemInfo.url) {
257
+ templateDictionary[itemInfo.url] = "{{" + itemInfo.id + ".url}}";
258
+ itemInfo.origUrl = itemInfo.url;
259
+ }
260
+ const idTest = /^source-[0-9A-F]{32}/i;
261
+ // Remove any source-itemId type keywords
262
+ if (Array.isArray(itemInfo.typeKeywords)) {
263
+ itemInfo.typeKeywords = itemInfo.typeKeywords.filter(v => idTest.test(v) ? false : true);
264
+ }
265
+ // Remove any source-itemId tags
266
+ /* istanbul ignore else */
267
+ if (Array.isArray(itemInfo.tags)) {
268
+ itemInfo.tags = itemInfo.tags.filter(v => idTest.test(v) ? false : true);
269
+ }
270
+ const placeholder = solutionCommon.findTemplateInList(existingTemplates, itemId);
271
+ let itemType = placeholder.type;
272
+ if (!itemType) {
273
+ // Groups have this defined when their placeholder is created
274
+ itemType = itemInfo.type;
275
+ placeholder.type = itemType;
276
+ }
277
+ if (!itemInfo.type) {
278
+ itemInfo.type = itemType; // Groups don't have this property, so we'll patch it in
279
+ }
280
+ placeholder.item = {
281
+ ...itemInfo
282
+ };
283
+ // Interrupt process if progress callback returns `false`
284
+ if (!itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Created, 1)) {
285
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Cancelled, 1);
286
+ resolve(solutionCommon.fail("Cancelled"));
287
+ return;
288
+ }
289
+ const itemHandler = moduleMap[itemType];
290
+ if (!itemHandler || itemHandler === UNSUPPORTED) {
291
+ if (itemHandler === UNSUPPORTED) {
292
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Ignored, 1);
293
+ resolve([]);
294
+ }
295
+ else {
296
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
297
+ placeholder.properties["failed"] = true;
298
+ solutionCommon.replaceTemplate(existingTemplates, itemId, placeholder);
299
+ resolve(solutionCommon.fail("The type of AGO item " +
300
+ itemId +
301
+ " ('" +
302
+ itemType +
303
+ "') is not supported at this time"));
304
+ }
305
+ }
306
+ else {
307
+ // Handle original Story Maps with next-gen Story Maps
308
+ /* istanbul ignore else */
309
+ /* Not yet supported
310
+ if (storyMap.isAStoryMap(itemType, itemInfo.url)) {
311
+ itemHandler = storyMap;
312
+ } */
313
+ // Delegate the creation of the item to the handler
314
+ itemHandler
315
+ .convertItemToTemplate(solutionItemId, itemInfo, destAuthentication, templateDictionary)
316
+ .then(itemTemplate => {
317
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
318
+ solutionCommon.getItemResourcesPaths(itemTemplate, solutionItemId, srcAuthentication, solutionCommon.SolutionTemplateFormatVersion).then((resourceItemFilePaths) => {
319
+ itemTemplate.item.thumbnail = null; // not needed in this property; handled as a resource
320
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
321
+ solutionCommon.getItemResourcesFilesFromPaths(resourceItemFilePaths, srcAuthentication).then((resourceItemFiles) => {
322
+ // update the template's resources
323
+ itemTemplate.resources = itemTemplate.resources.concat(resourceItemFiles.map((file) => file.folder + "/" + file.filename));
324
+ // Set the value keyed by the id to the created template, replacing the placeholder template
325
+ solutionCommon.replaceTemplate(existingTemplates, itemTemplate.itemId, itemTemplate);
326
+ // Trace item dependencies
327
+ if (itemTemplate.dependencies.length === 0) {
328
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Finished, 1);
329
+ resolve(resourceItemFiles);
330
+ }
331
+ else {
332
+ // Get its dependencies, asking each to get its dependents via
333
+ // recursive calls to this function
334
+ const dependentDfds = [];
335
+ itemTemplate.dependencies.forEach(dependentId => {
336
+ if (!solutionCommon.findTemplateInList(existingTemplates, dependentId)) {
337
+ dependentDfds.push(createItemTemplate(solutionItemId, dependentId, templateDictionary, srcAuthentication, destAuthentication, existingTemplates, itemProgressCallback));
338
+ }
339
+ });
340
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
341
+ Promise.all(dependentDfds).then((dependentResourceItemFiles) => {
342
+ // Templatization of item and its dependencies done
343
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Finished, 1);
344
+ resourceItemFiles = dependentResourceItemFiles.reduce((accumulator, currentValue) => accumulator.concat(currentValue), resourceItemFiles);
345
+ resolve(resourceItemFiles);
346
+ });
347
+ }
348
+ });
349
+ });
350
+ }, error => {
351
+ placeholder.properties["error"] = JSON.stringify(error);
352
+ solutionCommon.replaceTemplate(existingTemplates, itemId, placeholder);
353
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
354
+ resolve([]);
355
+ });
356
+ }
357
+ },
358
+ // Id not found or item is not accessible
359
+ () => {
360
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
361
+ itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
362
+ resolve([]);
363
+ });
364
+ }
365
+ });
366
+ }
367
+ /**
368
+ * Templatizes field references within specific template types.
369
+ * Currently only handles web applications
370
+ *
371
+ * @param templates List of solution templates
372
+ * @return A list of templates that have templatized field references
373
+ */
374
+ function postProcessFieldReferences(templates) {
375
+ const datasourceInfos = _getDatasourceInfos(templates);
376
+ const templateTypeHash = _getTemplateTypeHash(templates);
377
+ return templates.map(template => {
378
+ /* istanbul ignore else */
379
+ if (template.type === "Web Mapping Application" ||
380
+ template.type === "Dashboard" ||
381
+ template.type === "Web Map") {
382
+ const webMapFSDependencies = _getWebMapFSDependencies(template, templateTypeHash);
383
+ const itemHandler = moduleMap[template.item.type];
384
+ /* istanbul ignore else */
385
+ if (itemHandler) {
386
+ const dependencies = webMapFSDependencies.concat(template.dependencies);
387
+ let dependantDatasources = datasourceInfos.filter(ds => {
388
+ if (dependencies.indexOf(ds.itemId) > -1) {
389
+ return ds;
390
+ }
391
+ });
392
+ dependantDatasources = _addMapLayerIds(dependantDatasources, templateTypeHash);
393
+ if (dependantDatasources.length > 0) {
394
+ template = itemHandler.postProcessFieldReferences(template, dependantDatasources, template.item.type);
395
+ }
396
+ }
397
+ }
398
+ return template;
399
+ });
400
+ }
401
+ // ------------------------------------------------------------------------------------------------------------------ //
402
+ /**
403
+ * Get common properties that will support the templatization of field references
404
+ *
405
+ * @param templates List of solution templates
406
+ * @return A list of IDataSourceInfo objects with key properties
407
+ */
408
+ function _getDatasourceInfos(templates) {
409
+ const datasourceInfos = [];
410
+ templates.forEach(t => {
411
+ if (t.type === "Feature Service") {
412
+ const layers = hubCommon.getProp(t, "properties.layers") || [];
413
+ const tables = hubCommon.getProp(t, "properties.tables") || [];
414
+ const layersAndTables = layers.concat(tables);
415
+ layersAndTables.forEach(obj => {
416
+ /* istanbul ignore else */
417
+ if (!solutionCommon.hasDatasource(datasourceInfos, t.itemId, obj.id)) {
418
+ datasourceInfos.push({
419
+ itemId: t.itemId,
420
+ layerId: obj.id,
421
+ fields: obj.fields,
422
+ basePath: t.itemId + ".layer" + obj.id + ".fields",
423
+ url: hubCommon.getProp(t, "item.url"),
424
+ ids: [],
425
+ relationships: obj.relationships || [],
426
+ adminLayerInfo: obj.adminLayerInfo || {}
427
+ });
428
+ }
429
+ });
430
+ }
431
+ });
432
+ return datasourceInfos;
433
+ }
434
+ /**
435
+ * Creates a simple lookup object to quickly understand an items type and dependencies
436
+ * and associated web map layer ids based on itemId
437
+ *
438
+ * @param templates List of solution templates
439
+ * @return The lookup object with type, dependencies, and webmap layer info
440
+ */
441
+ function _getTemplateTypeHash(templates) {
442
+ const templateTypeHash = {};
443
+ templates.forEach(template => {
444
+ templateTypeHash[template.itemId] = {
445
+ type: template.type,
446
+ dependencies: template.dependencies
447
+ };
448
+ if (template.type === "Web Map") {
449
+ _updateWebMapHashInfo(template, templateTypeHash[template.itemId]);
450
+ }
451
+ });
452
+ return templateTypeHash;
453
+ }
454
+ /**
455
+ * Updates the lookup object with webmap layer info
456
+ * so we can know the id used within a map for a given feature service
457
+ *
458
+ * @param template A webmap solution template
459
+ * @return The lookup object with webmap layer info added
460
+ */
461
+ function _updateWebMapHashInfo(template, hashItem) {
462
+ const operationalLayers = hubCommon.getProp(template, "data.operationalLayers") || [];
463
+ const tables = hubCommon.getProp(template, "data.tables") || [];
464
+ const layersAndTables = operationalLayers.concat(tables);
465
+ if (layersAndTables && layersAndTables.length > 0) {
466
+ hashItem.layersAndTables = [];
467
+ layersAndTables.forEach(layer => {
468
+ const obj = {};
469
+ let itemId;
470
+ /* istanbul ignore else */
471
+ if (layer.itemId) {
472
+ itemId = layer.itemId;
473
+ }
474
+ /* istanbul ignore else */
475
+ if (itemId) {
476
+ obj[solutionCommon.cleanLayerBasedItemId(itemId)] = {
477
+ id: layer.id,
478
+ url: layer.url
479
+ };
480
+ hashItem.layersAndTables.push(obj);
481
+ }
482
+ });
483
+ }
484
+ }
485
+ /**
486
+ * Updates a templatized datasource URL with a layer id.
487
+ *
488
+ * @param dataSourceUrl Templatized datasource URL
489
+ * @param layerId Layer id
490
+ * @return string Amended datasource URL
491
+ */
492
+ function _addLayerIdToDatasourceUrl(datasourceUrl, layerId) {
493
+ return datasourceUrl && !isNaN(layerId)
494
+ ? datasourceUrl.replace(/[.]/, ".layer" + layerId + ".")
495
+ : "";
496
+ }
497
+ /**
498
+ * Updates the datasource info objects by passing the webmap layer IDs from the lookup hash
499
+ * to the underlying feature service datasource infos
500
+ *
501
+ * @param datasourceInfos A webmap solution template
502
+ * @param templateTypeHash A simple lookup object populated with key item info
503
+ * @return The updated datasource infos
504
+ */
505
+ function _addMapLayerIds(datasourceInfos, templateTypeHash) {
506
+ const webMapIds = Object.keys(templateTypeHash).filter(k => {
507
+ if (templateTypeHash[k].type === "Web Map") {
508
+ return templateTypeHash[k];
509
+ }
510
+ });
511
+ return datasourceInfos.map(ds => {
512
+ webMapIds.forEach(webMapId => {
513
+ templateTypeHash[webMapId].layersAndTables.forEach((opLayer) => {
514
+ const opLayerInfo = opLayer[ds.itemId];
515
+ const url = _addLayerIdToDatasourceUrl(ds.url, ds.layerId);
516
+ if (opLayerInfo &&
517
+ url === opLayerInfo.url &&
518
+ ds.ids.indexOf(opLayerInfo.id) < 0) {
519
+ ds.ids.push(opLayerInfo.id);
520
+ }
521
+ });
522
+ });
523
+ return ds;
524
+ });
525
+ }
526
+ /**
527
+ * Get feature service item IDs from applications webmaps
528
+ * As they are not explict dependencies of the application but are needed for field references
529
+ *
530
+ * @param template A webmap solution template
531
+ * @param templateTypeHash A simple lookup object populated with key item info
532
+ * @return A lsit of feature service item IDs
533
+ */
534
+ function _getWebMapFSDependencies(template, templateTypeHash) {
535
+ const webMapFSDependencies = [];
536
+ template.dependencies.forEach(dep => {
537
+ const depObj = templateTypeHash[dep];
538
+ if (depObj.type === "Web Map") {
539
+ depObj.dependencies.forEach((depObjDependency) => {
540
+ /* istanbul ignore else */
541
+ if (templateTypeHash[depObjDependency].type === "Feature Service") {
542
+ webMapFSDependencies.push(depObjDependency);
543
+ }
544
+ });
545
+ }
546
+ });
547
+ return webMapFSDependencies;
548
+ }
254
549
 
255
- /** @license
256
- * Copyright 2018 Esri
257
- *
258
- * Licensed under the Apache License, Version 2.0 (the "License");
259
- * you may not use this file except in compliance with the License.
260
- * You may obtain a copy of the License at
261
- *
262
- * http://www.apache.org/licenses/LICENSE-2.0
263
- *
264
- * Unless required by applicable law or agreed to in writing, software
265
- * distributed under the License is distributed on an "AS IS" BASIS,
266
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
267
- * See the License for the specific language governing permissions and
268
- * limitations under the License.
269
- */
270
- // ------------------------------------------------------------------------------------------------------------------ //
271
- /**
272
- * Creates template for an AGO item and its dependencies
273
- *
274
- * @param solutionItemId The solution to contain the item
275
- * @param itemId AGO id string
276
- * @param templateDictionary Hash of facts
277
- * @param authentication Authentication for requesting information from AGO about items to be included in solution item
278
- * @param existingTemplates A collection of AGO item templates that can be referenced by newly-created templates
279
- * @return A promise that will resolve when creation is done
280
- * @protected
281
- */
282
- function createItemTemplate(solutionItemId, itemId, templateDictionary, authentication, existingTemplates, itemProgressCallback) {
283
- return new Promise(function (resolve) {
284
- // Check if item and its dependents are already in list or are queued
285
- if (solutionCommon.findTemplateInList(existingTemplates, itemId)) {
286
- resolve(null);
287
- }
288
- else {
289
- // Add the id as a placeholder to show that it is being fetched
290
- existingTemplates.push(solutionCommon.createPlaceholderTemplate(itemId));
291
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Started, 0);
292
- // Fetch the item
293
- solutionCommon.getItemBase(itemId, authentication)
294
- .catch(function () {
295
- // If item query fails, try fetching item as a group
296
- // Change its placeholder from an empty type to the Group type so that we can later distinguish
297
- // between items and groups (the base info for a group doesn't include a type property)
298
- solutionCommon.replaceTemplate(existingTemplates, itemId, solutionCommon.createPlaceholderTemplate(itemId, "Group"));
299
- return solutionCommon.getGroupBase(itemId, authentication);
300
- })
301
- .then(function (itemInfo) {
302
- itemInfo = solutionCommon.sanitizeJSONAndReportChanges(itemInfo);
303
- // Save the URL as a symbol
304
- if (itemInfo.url) {
305
- templateDictionary[itemInfo.url] = "{{" + itemInfo.id + ".url}}";
306
- itemInfo.origUrl = itemInfo.url;
307
- }
308
- var idTest = /^source-[0-9A-F]{32}/i;
309
- // Remove any source-itemId type keywords
310
- if (Array.isArray(itemInfo.typeKeywords)) {
311
- itemInfo.typeKeywords = itemInfo.typeKeywords.filter(function (v) {
312
- return idTest.test(v) ? false : true;
313
- });
314
- }
315
- // Remove any source-itemId tags
316
- /* istanbul ignore else */
317
- if (Array.isArray(itemInfo.tags)) {
318
- itemInfo.tags = itemInfo.tags.filter(function (v) {
319
- return idTest.test(v) ? false : true;
320
- });
321
- }
322
- var placeholder = solutionCommon.findTemplateInList(existingTemplates, itemId);
323
- var itemType = placeholder.type;
324
- if (!itemType) {
325
- // Groups have this defined when their placeholder is created
326
- itemType = itemInfo.type;
327
- placeholder.type = itemType;
328
- }
329
- if (!itemInfo.type) {
330
- itemInfo.type = itemType; // Groups don't have this property, so we'll patch it in
331
- }
332
- placeholder.item = __assign({}, itemInfo);
333
- // Interrupt process if progress callback returns `false`
334
- if (!itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Created, 1)) {
335
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Cancelled, 1);
336
- resolve(solutionCommon.fail("Cancelled"));
337
- return;
338
- }
339
- var itemHandler = moduleMap[itemType];
340
- if (!itemHandler || itemHandler === UNSUPPORTED) {
341
- if (itemHandler === UNSUPPORTED) {
342
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Ignored, 1);
343
- resolve(null);
344
- }
345
- else {
346
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
347
- placeholder.properties["failed"] = true;
348
- solutionCommon.replaceTemplate(existingTemplates, itemId, placeholder);
349
- resolve(solutionCommon.fail("The type of AGO item " +
350
- itemId +
351
- " ('" +
352
- itemType +
353
- "') is not supported at this time"));
354
- }
355
- }
356
- else {
357
- // Handle original Story Maps with next-gen Story Maps
358
- /* istanbul ignore else */
359
- /* Not yet supported
360
- if (storyMap.isAStoryMap(itemType, itemInfo.url)) {
361
- itemHandler = storyMap;
362
- } */
363
- // Delegate the creation of the item to the handler
364
- itemHandler
365
- .convertItemToTemplate(solutionItemId, itemInfo, authentication, templateDictionary)
366
- .then(function (itemTemplate) {
367
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
368
- solutionCommon.storeItemResources(itemTemplate, solutionItemId, authentication, solutionCommon.SolutionTemplateFormatVersion).then(function (resources) {
369
- // update the templates resources
370
- itemTemplate.item.thumbnail = null; // no longer needed; use resources
371
- itemTemplate.resources = itemTemplate.resources.concat(resources);
372
- // Set the value keyed by the id to the created template, replacing the placeholder template
373
- solutionCommon.replaceTemplate(existingTemplates, itemTemplate.itemId, itemTemplate);
374
- // Trace item dependencies
375
- if (itemTemplate.dependencies.length === 0) {
376
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Finished, 1);
377
- resolve(null);
378
- }
379
- else {
380
- // Get its dependencies, asking each to get its dependents via
381
- // recursive calls to this function
382
- var dependentDfds_1 = [];
383
- itemTemplate.dependencies.forEach(function (dependentId) {
384
- if (!solutionCommon.findTemplateInList(existingTemplates, dependentId)) {
385
- dependentDfds_1.push(createItemTemplate(solutionItemId, dependentId, templateDictionary, authentication, existingTemplates, itemProgressCallback));
386
- }
387
- });
388
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
389
- Promise.all(dependentDfds_1).then(function () {
390
- // Templatization of item and its dependencies done
391
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Finished, 1);
392
- resolve(null);
393
- });
394
- }
395
- });
396
- }, function (error) {
397
- placeholder.properties["error"] = JSON.stringify(error);
398
- solutionCommon.replaceTemplate(existingTemplates, itemId, placeholder);
399
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
400
- resolve(null);
401
- });
402
- }
403
- },
404
- // Id not found or item is not accessible
405
- function () {
406
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
407
- itemProgressCallback(itemId, solutionCommon.EItemProgressStatus.Failed, 1);
408
- resolve(null);
409
- });
410
- }
411
- });
412
- }
413
- /**
414
- * Templatizes field references within specific template types.
415
- * Currently only handles web applications
416
- *
417
- * @param templates List of solution templates
418
- * @return A list of templates that have templatized field references
419
- */
420
- function postProcessFieldReferences(templates) {
421
- var datasourceInfos = _getDatasourceInfos(templates);
422
- var templateTypeHash = _getTemplateTypeHash(templates);
423
- return templates.map(function (template) {
424
- /* istanbul ignore else */
425
- if (template.type === "Web Mapping Application" ||
426
- template.type === "Dashboard" ||
427
- template.type === "Web Map") {
428
- var webMapFSDependencies = _getWebMapFSDependencies(template, templateTypeHash);
429
- var itemHandler = moduleMap[template.item.type];
430
- /* istanbul ignore else */
431
- if (itemHandler) {
432
- var dependencies_1 = webMapFSDependencies.concat(template.dependencies);
433
- var dependantDatasources = datasourceInfos.filter(function (ds) {
434
- if (dependencies_1.indexOf(ds.itemId) > -1) {
435
- return ds;
436
- }
437
- });
438
- dependantDatasources = _addMapLayerIds(dependantDatasources, templateTypeHash);
439
- if (dependantDatasources.length > 0) {
440
- template = itemHandler.postProcessFieldReferences(template, dependantDatasources, template.item.type);
441
- }
442
- }
443
- }
444
- return template;
445
- });
446
- }
447
- // ------------------------------------------------------------------------------------------------------------------ //
448
- /**
449
- * Get common properties that will support the templatization of field references
450
- *
451
- * @param templates List of solution templates
452
- * @return A list of IDataSourceInfo objects with key properties
453
- */
454
- function _getDatasourceInfos(templates) {
455
- var datasourceInfos = [];
456
- templates.forEach(function (t) {
457
- if (t.type === "Feature Service") {
458
- var layers = hubCommon.getProp(t, "properties.layers") || [];
459
- var tables = hubCommon.getProp(t, "properties.tables") || [];
460
- var layersAndTables = layers.concat(tables);
461
- layersAndTables.forEach(function (obj) {
462
- /* istanbul ignore else */
463
- if (!solutionCommon.hasDatasource(datasourceInfos, t.itemId, obj.id)) {
464
- datasourceInfos.push({
465
- itemId: t.itemId,
466
- layerId: obj.id,
467
- fields: obj.fields,
468
- basePath: t.itemId + ".layer" + obj.id + ".fields",
469
- url: hubCommon.getProp(t, "item.url"),
470
- ids: [],
471
- relationships: obj.relationships || [],
472
- adminLayerInfo: obj.adminLayerInfo || {}
473
- });
474
- }
475
- });
476
- }
477
- });
478
- return datasourceInfos;
479
- }
480
- /**
481
- * Creates a simple lookup object to quickly understand an items type and dependencies
482
- * and associated web map layer ids based on itemId
483
- *
484
- * @param templates List of solution templates
485
- * @return The lookup object with type, dependencies, and webmap layer info
486
- */
487
- function _getTemplateTypeHash(templates) {
488
- var templateTypeHash = {};
489
- templates.forEach(function (template) {
490
- templateTypeHash[template.itemId] = {
491
- type: template.type,
492
- dependencies: template.dependencies
493
- };
494
- if (template.type === "Web Map") {
495
- _updateWebMapHashInfo(template, templateTypeHash[template.itemId]);
496
- }
497
- });
498
- return templateTypeHash;
499
- }
500
- /**
501
- * Updates the lookup object with webmap layer info
502
- * so we can know the id used within a map for a given feature service
503
- *
504
- * @param template A webmap solution template
505
- * @return The lookup object with webmap layer info added
506
- */
507
- function _updateWebMapHashInfo(template, hashItem) {
508
- var operationalLayers = hubCommon.getProp(template, "data.operationalLayers") || [];
509
- var tables = hubCommon.getProp(template, "data.tables") || [];
510
- var layersAndTables = operationalLayers.concat(tables);
511
- if (layersAndTables && layersAndTables.length > 0) {
512
- hashItem.layersAndTables = [];
513
- layersAndTables.forEach(function (layer) {
514
- var obj = {};
515
- var itemId;
516
- /* istanbul ignore else */
517
- if (layer.itemId) {
518
- itemId = layer.itemId;
519
- }
520
- /* istanbul ignore else */
521
- if (itemId) {
522
- obj[solutionCommon.cleanLayerBasedItemId(itemId)] = {
523
- id: layer.id,
524
- url: layer.url
525
- };
526
- hashItem.layersAndTables.push(obj);
527
- }
528
- });
529
- }
530
- }
531
- /**
532
- * Updates a templatized datasource URL with a layer id.
533
- *
534
- * @param dataSourceUrl Templatized datasource URL
535
- * @param layerId Layer id
536
- * @return string Amended datasource URL
537
- */
538
- function _addLayerIdToDatasourceUrl(datasourceUrl, layerId) {
539
- return datasourceUrl && !isNaN(layerId)
540
- ? datasourceUrl.replace(/[.]/, ".layer" + layerId + ".")
541
- : "";
542
- }
543
- /**
544
- * Updates the datasource info objects by passing the webmap layer IDs from the lookup hash
545
- * to the underlying feature service datasource infos
546
- *
547
- * @param datasourceInfos A webmap solution template
548
- * @param templateTypeHash A simple lookup object populated with key item info
549
- * @return The updated datasource infos
550
- */
551
- function _addMapLayerIds(datasourceInfos, templateTypeHash) {
552
- var webMapIds = Object.keys(templateTypeHash).filter(function (k) {
553
- if (templateTypeHash[k].type === "Web Map") {
554
- return templateTypeHash[k];
555
- }
556
- });
557
- return datasourceInfos.map(function (ds) {
558
- webMapIds.forEach(function (webMapId) {
559
- templateTypeHash[webMapId].layersAndTables.forEach(function (opLayer) {
560
- var opLayerInfo = opLayer[ds.itemId];
561
- var url = _addLayerIdToDatasourceUrl(ds.url, ds.layerId);
562
- if (opLayerInfo &&
563
- url === opLayerInfo.url &&
564
- ds.ids.indexOf(opLayerInfo.id) < 0) {
565
- ds.ids.push(opLayerInfo.id);
566
- }
567
- });
568
- });
569
- return ds;
570
- });
571
- }
572
- /**
573
- * Get feature service item IDs from applications webmaps
574
- * As they are not explict dependencies of the application but are needed for field references
575
- *
576
- * @param template A webmap solution template
577
- * @param templateTypeHash A simple lookup object populated with key item info
578
- * @return A lsit of feature service item IDs
579
- */
580
- function _getWebMapFSDependencies(template, templateTypeHash) {
581
- var webMapFSDependencies = [];
582
- template.dependencies.forEach(function (dep) {
583
- var depObj = templateTypeHash[dep];
584
- if (depObj.type === "Web Map") {
585
- depObj.dependencies.forEach(function (depObjDependency) {
586
- /* istanbul ignore else */
587
- if (templateTypeHash[depObjDependency].type === "Feature Service") {
588
- webMapFSDependencies.push(depObjDependency);
589
- }
590
- });
591
- }
592
- });
593
- return webMapFSDependencies;
594
- }
550
+ /** @license
551
+ * Copyright 2020 Esri
552
+ *
553
+ * Licensed under the Apache License, Version 2.0 (the "License");
554
+ * you may not use this file except in compliance with the License.
555
+ * You may obtain a copy of the License at
556
+ *
557
+ * http://www.apache.org/licenses/LICENSE-2.0
558
+ *
559
+ * Unless required by applicable law or agreed to in writing, software
560
+ * distributed under the License is distributed on an "AS IS" BASIS,
561
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
562
+ * See the License for the specific language governing permissions and
563
+ * limitations under the License.
564
+ */
565
+ /**
566
+ * Adds a list of AGO item ids to a solution item.
567
+ *
568
+ * @param solutionItemId AGO id of solution to receive items
569
+ * @param options Customizations for creating the solution
570
+ * @param srcAuthentication Credentials for requests to source items
571
+ * @param destAuthentication Credentials for the requests to destination solution
572
+ * @return A promise that resolves with the AGO id of the updated solution
573
+ * @internal
574
+ */
575
+ function addContentToSolution(solutionItemId, options, srcAuthentication, destAuthentication) {
576
+ return new Promise((resolve, reject) => {
577
+ if (!options.itemIds || options.itemIds.length === 0) {
578
+ resolve(solutionItemId);
579
+ return;
580
+ }
581
+ // Prepare feedback mechanism
582
+ let totalEstimatedCost = 2 * options.itemIds.length + 1; // solution items, plus avoid divide by 0
583
+ let percentDone = 16; // allow for previous creation work
584
+ let progressPercentStep = (95 - percentDone) / totalEstimatedCost; // leave some % for caller for wrapup
585
+ const failedItemIds = [];
586
+ let totalExpended = 0;
587
+ let statusOK = true;
588
+ const itemProgressCallback = (itemId, status, costUsed) => {
589
+ // ---------------------------------------------------------------------------------------------------------------
590
+ if (options.itemIds.indexOf(itemId) < 0) {
591
+ // New item--a dependency that wasn't in the supplied list of itemIds; add it to the list
592
+ // and recalculate the progress percent step based on how much progress remains to be done
593
+ options.itemIds.push(itemId);
594
+ totalEstimatedCost += 2;
595
+ progressPercentStep =
596
+ (95 - percentDone) / (totalEstimatedCost - totalExpended);
597
+ }
598
+ totalExpended += costUsed;
599
+ percentDone += progressPercentStep * costUsed;
600
+ if (options.progressCallback) {
601
+ options.progressCallback(Math.round(percentDone), options.jobId);
602
+ }
603
+ /* istanbul ignore if */
604
+ if (options.consoleProgress) {
605
+ console.log(Date.now(), itemId, options.jobId ?? "", solutionCommon.SItemProgressStatus[status], percentDone.toFixed(0) + "%", costUsed);
606
+ }
607
+ if (status === solutionCommon.EItemProgressStatus.Failed) {
608
+ let error = "";
609
+ solutionTemplates.some(t => {
610
+ /* istanbul ignore else */
611
+ if (t.itemId === itemId) {
612
+ /* istanbul ignore else */
613
+ if (hubCommon.getProp(t, "properties.error")) {
614
+ error = t.properties.error;
615
+ try {
616
+ // parse for better console logging if we can
617
+ error = JSON.parse(error);
618
+ }
619
+ catch (e) {
620
+ /* istanbul ignore next */
621
+ // do nothing and show the error as is
622
+ }
623
+ }
624
+ return true;
625
+ }
626
+ });
627
+ solutionCommon.removeTemplate(solutionTemplates, itemId);
628
+ if (failedItemIds.indexOf(itemId) < 0) {
629
+ failedItemIds.push(itemId);
630
+ }
631
+ statusOK = false;
632
+ }
633
+ else if (status === solutionCommon.EItemProgressStatus.Ignored) {
634
+ solutionCommon.removeTemplate(solutionTemplates, itemId);
635
+ }
636
+ return statusOK;
637
+ // ---------------------------------------------------------------------------------------------------------------
638
+ };
639
+ // Replacement dictionary and created templates
640
+ const templateDictionary = options.templateDictionary ?? {};
641
+ let solutionTemplates = [];
642
+ // Handle a list of one or more AGO ids by stepping through the list
643
+ // and calling this function recursively
644
+ const getItemsPromise = [];
645
+ options.itemIds.forEach(itemId => {
646
+ const createDef = createItemTemplate(solutionItemId, itemId, templateDictionary, srcAuthentication, destAuthentication, solutionTemplates, itemProgressCallback);
647
+ getItemsPromise.push(createDef);
648
+ });
649
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
650
+ Promise.all(getItemsPromise).then((multipleResourceItemFiles) => {
651
+ if (failedItemIds.length > 0) {
652
+ reject(solutionCommon.failWithIds(failedItemIds, "One or more items cannot be converted into templates"));
653
+ }
654
+ else {
655
+ if (solutionTemplates.length > 0) {
656
+ // Coalesce the resource file paths from the created templates
657
+ let resourceItemFiles = multipleResourceItemFiles.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
658
+ // test for and update group dependencies and other post-processing
659
+ solutionTemplates = _postProcessGroupDependencies(solutionTemplates);
660
+ solutionTemplates = solutionCommon.postProcessWorkforceTemplates(solutionTemplates);
661
+ // Filter out any resources from items that have been removed from the templates, such as
662
+ // Living Atlas layers
663
+ solutionTemplates = _postProcessIgnoredItems(solutionTemplates);
664
+ const templateIds = solutionTemplates.map(template => template.itemId);
665
+ // Coalesce the resource file paths from the created templates
666
+ resourceItemFiles = resourceItemFiles.filter(file => templateIds.includes(file.itemId));
667
+ // Send the accumulated resources to the solution item
668
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
669
+ solutionCommon.copyFilesToStorageItem(resourceItemFiles, solutionItemId, destAuthentication).then(() => {
670
+ _templatizeSolutionIds(solutionTemplates);
671
+ _simplifyUrlsInItemDescriptions(solutionTemplates);
672
+ _replaceDictionaryItemsInObject(templateDictionary, solutionTemplates);
673
+ _templatizeOrgUrl(solutionTemplates, destAuthentication).then(solutionTemplates2 => {
674
+ // Update solution item with its data JSON
675
+ const solutionData = {
676
+ metadata: { version: solutionCommon.SolutionTemplateFormatVersion },
677
+ templates: options.templatizeFields
678
+ ? postProcessFieldReferences(solutionTemplates2)
679
+ : solutionTemplates2
680
+ };
681
+ const itemInfo = {
682
+ id: solutionItemId,
683
+ text: solutionData
684
+ };
685
+ solutionCommon.updateItem(itemInfo, destAuthentication).then(() => {
686
+ resolve(solutionItemId);
687
+ }, reject);
688
+ }, reject);
689
+ });
690
+ }
691
+ else {
692
+ resolve(solutionItemId);
693
+ }
694
+ }
695
+ });
696
+ });
697
+ }
698
+ // ------------------------------------------------------------------------------------------------------------------ //
699
+ /**
700
+ * Gets the dependencies of an item by merging its dependencies list with item references in template variables.
701
+ *
702
+ * @param template Template to examine
703
+ * @return List of dependency ids
704
+ * @private
705
+ */
706
+ function _getDependencies(template) {
707
+ // Get all dependencies
708
+ let deps = template.dependencies.concat(_getIdsOutOfTemplateVariables(_getTemplateVariables(JSON.stringify(template.data))));
709
+ // Remove duplicates and self-references
710
+ deps.sort();
711
+ deps = deps.filter((elem, index, array) => {
712
+ if (elem === template.itemId) {
713
+ return false;
714
+ }
715
+ else if (index > 0) {
716
+ return elem !== array[index - 1];
717
+ }
718
+ else {
719
+ return true;
720
+ }
721
+ });
722
+ return deps;
723
+ }
724
+ /**
725
+ * Extracts AGO ids out of template variables.
726
+ *
727
+ * @param variables List of template variables to examine
728
+ * @return List of AGO ids referenced in `variables`
729
+ * @private
730
+ */
731
+ function _getIdsOutOfTemplateVariables(variables) {
732
+ return variables
733
+ .map(variable => {
734
+ const idList = variable.match(/[0-9A-F]{32}/i); // is it a guid?
735
+ if (idList) {
736
+ return idList[0];
737
+ }
738
+ else {
739
+ return null;
740
+ }
741
+ })
742
+ .filter(variable => !!variable);
743
+ }
744
+ /**
745
+ * Creates a list of item URLs.
746
+ *
747
+ * @param templates Templates to check for URLs
748
+ * @return List of URLs
749
+ * @private
750
+ */
751
+ function _getSolutionItemUrls(templates) {
752
+ const solutionUrls = [];
753
+ templates.forEach(template => {
754
+ /* istanbul ignore else */
755
+ if (template.item.origUrl) {
756
+ solutionUrls.push([template.itemId, template.item.origUrl]);
757
+ }
758
+ });
759
+ return solutionUrls;
760
+ }
761
+ /**
762
+ * Extracts template variables out of a string.
763
+ *
764
+ * @param text String to examine
765
+ * @return List of template variables found in string
766
+ * @private
767
+ */
768
+ function _getTemplateVariables(text) {
769
+ return (text.match(/{{[a-z0-9.]*}}/gi) || []) // find variable
770
+ .map(variable => variable.substring(2, variable.length - 2)); // remove "{{" & "}}"
771
+ }
772
+ /**
773
+ * Update the items dependencies and groups arrays
774
+ *
775
+ * @param templates The array of templates to evaluate
776
+ * @return Updated version of the templates
777
+ * @private
778
+ */
779
+ function _postProcessGroupDependencies(templates) {
780
+ return templates.map((template) => {
781
+ if (template.type === "Group") {
782
+ const id = template.itemId;
783
+ // remove group dependencies if we find a circular dependency with one of its items
784
+ let removeDependencies = false;
785
+ // before we remove update each dependants groups array
786
+ template.dependencies.forEach(dependencyId => {
787
+ const dependantTemplate = solutionCommon.getTemplateById(templates, dependencyId);
788
+ // Not all items shared to the group will exist in the templates array
789
+ // i.e. Hub Initiative items or any other unsupported types
790
+ if (dependantTemplate) {
791
+ // check if the group is in the dependantTemplate's list of dependencies
792
+ const gIndex = hubCommon.getWithDefault(dependantTemplate, "dependencies", []).indexOf(id);
793
+ /* istanbul ignore else */
794
+ if (gIndex > -1) {
795
+ removeDependencies = true;
796
+ }
797
+ // if the dependant template does not have the group id
798
+ // in it's groups array, add it
799
+ const groups = hubCommon.getWithDefault(dependantTemplate, "groups", []);
800
+ if (groups.indexOf(id) === -1) {
801
+ groups.push(id);
802
+ dependantTemplate.groups = groups;
803
+ }
804
+ }
805
+ });
806
+ if (removeDependencies) {
807
+ template.dependencies = [];
808
+ }
809
+ }
810
+ return template;
811
+ });
812
+ }
813
+ /**
814
+ * Check for feature service items that have been flagged for invalid designations.
815
+ * Remove templates that have invalid designations from the solution item and other item dependencies.
816
+ * Clean up any references to items with invalid designations in the other templates.
817
+ *
818
+ * @param templates The array of templates to evaluate
819
+ * @return Updated version of the templates
820
+ * @private
821
+ */
822
+ function _postProcessIgnoredItems(templates) {
823
+ // replace in template
824
+ const updateDictionary = templates.reduce((result, template) => {
825
+ return template.properties.hasInvalidDesignations
826
+ ? Object.assign(result, template.data)
827
+ : result;
828
+ }, {});
829
+ Object.keys(updateDictionary).forEach(k => {
830
+ solutionCommon.removeTemplate(templates, k);
831
+ templates = templates.map(t => {
832
+ t.dependencies = t.dependencies.filter(id => id !== k);
833
+ return solutionCommon.replaceInTemplate(t, updateDictionary);
834
+ });
835
+ });
836
+ return templates;
837
+ }
838
+ /**
839
+ * Recursively runs through an object to find and replace any strings found in a dictionary.
840
+ *
841
+ * @param templateDictionary Hash of things to be replaced
842
+ * @param obj Object to be examined
843
+ * @private
844
+ */
845
+ function _replaceDictionaryItemsInObject(hash, obj) {
846
+ /* istanbul ignore else */
847
+ if (obj) {
848
+ Object.keys(obj).forEach(prop => {
849
+ const propObj = obj[prop];
850
+ if (propObj) {
851
+ if (typeof propObj === "object") {
852
+ _replaceDictionaryItemsInObject(hash, propObj);
853
+ }
854
+ else if (typeof propObj === "string") {
855
+ obj[prop] = hash[propObj] || propObj;
856
+ }
857
+ }
858
+ });
859
+ }
860
+ return obj;
861
+ }
862
+ /**
863
+ * Recursively runs through an object to find and templatize any remaining references to solution's items.
864
+ *
865
+ * @param ids Ids to be replaced in strings found in object
866
+ * @param obj Object to be examined
867
+ * @private
868
+ */
869
+ function _replaceRemainingIdsInObject(ids, obj) {
870
+ /* istanbul ignore else */
871
+ if (obj) {
872
+ Object.keys(obj).forEach(prop => {
873
+ const propObj = obj[prop];
874
+ if (propObj) {
875
+ if (typeof propObj === "object") {
876
+ _replaceRemainingIdsInObject(ids, propObj);
877
+ }
878
+ else if (typeof propObj === "string") {
879
+ obj[prop] = _replaceRemainingIdsInString(ids, propObj);
880
+ }
881
+ }
882
+ });
883
+ }
884
+ return obj;
885
+ }
886
+ /**
887
+ * Templatizes ids from a list in a string if they're not already templatized.
888
+ *
889
+ * @param ids Ids to be replaced in source string
890
+ * @param str Source string to be examined
891
+ * @return A copy of the source string with any templatization changes
892
+ * @private
893
+ */
894
+ function _replaceRemainingIdsInString(ids, str) {
895
+ let updatedStr = str;
896
+ const untemplatizedIds = solutionCommon.getIDs(str);
897
+ if (untemplatizedIds.length > 0) {
898
+ untemplatizedIds.forEach(id => {
899
+ if (ids.includes(id)) {
900
+ const re = new RegExp("({*)" + id, "gi");
901
+ updatedStr = updatedStr.replace(re, match => match.indexOf("{{") < 0
902
+ ? "{{" + id.replace("{", "") + ".itemId}}"
903
+ : match);
904
+ }
905
+ });
906
+ }
907
+ return updatedStr;
908
+ }
909
+ /**
910
+ * Finds and templatizes any URLs in solution items' descriptions.
911
+ *
912
+ * @param templates The array of templates to evaluate, modified in place
913
+ * @private
914
+ */
915
+ function _simplifyUrlsInItemDescriptions(templates) {
916
+ // Get the urls in the solution along with their item ids & convert the id into the form
917
+ // "{{fcb2bf2837a6404ebb418a1f805f976a.url}}"
918
+ const solutionUrls = _getSolutionItemUrls(templates).map(idUrl => [
919
+ "{{" + idUrl[0] + ".url}}",
920
+ idUrl[1]
921
+ ]);
922
+ /* istanbul ignore else */
923
+ if (solutionUrls.length > 0) {
924
+ // Make the replacements
925
+ templates.forEach(template => {
926
+ solutionUrls.forEach(
927
+ // TypeScript for es2015 doesn't have a definition for `replaceAll`
928
+ idUrl => {
929
+ /* istanbul ignore else */
930
+ if (template.item.description) {
931
+ template.item.description = template.item
932
+ .description.replaceAll(idUrl[1], idUrl[0]);
933
+ }
934
+ });
935
+ });
936
+ }
937
+ }
938
+ /**
939
+ * Templatizes occurrences of the URL to the user's organization in the `item` and `data` template sections.
940
+ *
941
+ * @param templates The array of templates to evaluate; templates is modified in place
942
+ * @param destAuthentication Credentials for request organization info
943
+ * @return Promise resolving with `templates`
944
+ * @private
945
+ */
946
+ function _templatizeOrgUrl(templates, destAuthentication) {
947
+ return new Promise((resolve, reject) => {
948
+ // Get the org's URL
949
+ solutionCommon.getPortal(null, destAuthentication).then(org => {
950
+ const orgUrl = "https://" + org.urlKey + "." + org.customBaseUrl;
951
+ const templatizedOrgUrl = "{{portalBaseUrl}}";
952
+ // Cycle through each of the items in the template and scan the `item` and `data` sections of each for replacements
953
+ templates.forEach((template) => {
954
+ solutionCommon.globalStringReplace(template.item, new RegExp(orgUrl, "gi"), templatizedOrgUrl);
955
+ solutionCommon.globalStringReplace(template.data, new RegExp(orgUrl, "gi"), templatizedOrgUrl);
956
+ });
957
+ resolve(templates);
958
+ }, reject);
959
+ });
960
+ }
961
+ /**
962
+ * Finds and templatizes any references to solution's items.
963
+ *
964
+ * @param templates The array of templates to evaluate, modified in place
965
+ * @private
966
+ */
967
+ function _templatizeSolutionIds(templates) {
968
+ // Get the ids in the solution
969
+ const solutionIds = templates.map((template) => template.itemId);
970
+ // Cycle through each of the items in the template and
971
+ // 1. templatize untemplatized ids in our solution in the `item` and `data` sections;
972
+ // 2. update the `dependencies` section
973
+ templates.forEach((template) => {
974
+ _replaceRemainingIdsInObject(solutionIds, template.item);
975
+ _replaceRemainingIdsInObject(solutionIds, template.data);
976
+ /* istanbul ignore else */
977
+ if (template.type !== "Group" && !solutionCommon.isWorkforceProject(template)) {
978
+ template.dependencies = _getDependencies(template);
979
+ }
980
+ });
981
+ }
595
982
 
596
- /** @license
597
- * Copyright 2020 Esri
598
- *
599
- * Licensed under the Apache License, Version 2.0 (the "License");
600
- * you may not use this file except in compliance with the License.
601
- * You may obtain a copy of the License at
602
- *
603
- * http://www.apache.org/licenses/LICENSE-2.0
604
- *
605
- * Unless required by applicable law or agreed to in writing, software
606
- * distributed under the License is distributed on an "AS IS" BASIS,
607
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
608
- * See the License for the specific language governing permissions and
609
- * limitations under the License.
610
- */
611
- /**
612
- * Adds a list of AGO item ids to a solution item.
613
- *
614
- * @param solutionItemId AGO id of solution to receive items
615
- * @param options Customizations for creating the solution
616
- * @param authentication Credentials for the request
617
- * @return A promise that resolves with the AGO id of the updated solution
618
- * @internal
619
- */
620
- function addContentToSolution(solutionItemId, options, authentication) {
621
- return new Promise(function (resolve, reject) {
622
- var _a;
623
- if (!options.itemIds || options.itemIds.length === 0) {
624
- resolve(solutionItemId);
625
- return;
626
- }
627
- // Prepare feedback mechanism
628
- var totalEstimatedCost = 2 * options.itemIds.length + 1; // solution items, plus avoid divide by 0
629
- var percentDone = 16; // allow for previous creation work
630
- var progressPercentStep = (99 - percentDone) / totalEstimatedCost; // leave some % for caller for wrapup
631
- var failedItemIds = [];
632
- var totalExpended = 0;
633
- var statusOK = true;
634
- var itemProgressCallback = function (itemId, status, costUsed) {
635
- var _a;
636
- // ---------------------------------------------------------------------------------------------------------------
637
- if (options.itemIds.indexOf(itemId) < 0) {
638
- // New item--a dependency that wasn't in the supplied list of itemIds; add it to the list
639
- // and recalculate the progress percent step based on how much progress remains to be done
640
- options.itemIds.push(itemId);
641
- totalEstimatedCost += 2;
642
- progressPercentStep =
643
- (99 - percentDone) / (totalEstimatedCost - totalExpended);
644
- }
645
- totalExpended += costUsed;
646
- percentDone += progressPercentStep * costUsed;
647
- if (options.progressCallback) {
648
- options.progressCallback(Math.round(percentDone), options.jobId);
649
- }
650
- /* istanbul ignore if */
651
- if (options.consoleProgress) {
652
- console.log(Date.now(), itemId, (_a = options.jobId) !== null && _a !== void 0 ? _a : "", solutionCommon.SItemProgressStatus[status], percentDone.toFixed(0) + "%", costUsed);
653
- }
654
- if (status === solutionCommon.EItemProgressStatus.Failed) {
655
- var error_1 = "";
656
- solutionTemplates.some(function (t) {
657
- /* istanbul ignore else */
658
- if (t.itemId === itemId) {
659
- /* istanbul ignore else */
660
- if (hubCommon.getProp(t, "properties.error")) {
661
- error_1 = t.properties.error;
662
- try {
663
- // parse for better console logging if we can
664
- error_1 = JSON.parse(error_1);
665
- }
666
- catch (e) {
667
- /* istanbul ignore next */
668
- // do nothing and show the error as is
669
- }
670
- }
671
- return true;
672
- }
673
- });
674
- solutionCommon.removeTemplate(solutionTemplates, itemId);
675
- if (failedItemIds.indexOf(itemId) < 0) {
676
- failedItemIds.push(itemId);
677
- }
678
- statusOK = false;
679
- }
680
- else if (status === solutionCommon.EItemProgressStatus.Ignored) {
681
- solutionCommon.removeTemplate(solutionTemplates, itemId);
682
- }
683
- return statusOK;
684
- // ---------------------------------------------------------------------------------------------------------------
685
- };
686
- // Replacement dictionary and created templates
687
- var templateDictionary = (_a = options.templateDictionary) !== null && _a !== void 0 ? _a : {};
688
- var solutionTemplates = [];
689
- // Handle a list of one or more AGO ids by stepping through the list
690
- // and calling this function recursively
691
- var getItemsPromise = [];
692
- options.itemIds.forEach(function (itemId) {
693
- var createDef = createItemTemplate(solutionItemId, itemId, templateDictionary, authentication, solutionTemplates, itemProgressCallback);
694
- getItemsPromise.push(createDef);
695
- });
696
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
697
- Promise.all(getItemsPromise).then(function () {
698
- if (failedItemIds.length > 0) {
699
- reject(solutionCommon.failWithIds(failedItemIds, "One or more items cannot be converted into templates"));
700
- }
701
- else {
702
- if (solutionTemplates.length > 0) {
703
- // test for and update group dependencies and other post-processing
704
- solutionTemplates = _postProcessGroupDependencies(solutionTemplates);
705
- solutionTemplates = solutionCommon.postProcessWorkforceTemplates(solutionTemplates);
706
- _templatizeSolutionIds(solutionTemplates);
707
- solutionTemplates = _postProcessIgnoredItems(solutionTemplates);
708
- _simplifyUrlsInItemDescriptions(solutionTemplates);
709
- _replaceDictionaryItemsInObject(templateDictionary, solutionTemplates);
710
- _templatizeOrgUrl(solutionTemplates, authentication).then(function (solutionTemplates2) {
711
- // Update solution item with its data JSON
712
- var solutionData = {
713
- metadata: { version: solutionCommon.SolutionTemplateFormatVersion },
714
- templates: options.templatizeFields
715
- ? postProcessFieldReferences(solutionTemplates2)
716
- : solutionTemplates2
717
- };
718
- var itemInfo = {
719
- id: solutionItemId,
720
- text: solutionData
721
- };
722
- solutionCommon.updateItem(itemInfo, authentication).then(function () {
723
- resolve(solutionItemId);
724
- }, reject);
725
- }, reject);
726
- }
727
- else {
728
- resolve(solutionItemId);
729
- }
730
- }
731
- });
732
- });
733
- }
734
- // ------------------------------------------------------------------------------------------------------------------ //
735
- /**
736
- * Gets the dependencies of an item by merging its dependencies list with item references in template variables.
737
- *
738
- * @param template Template to examine
739
- * @return List of dependency ids
740
- * @private
741
- */
742
- function _getDependencies(template) {
743
- // Get all dependencies
744
- var deps = template.dependencies.concat(_getIdsOutOfTemplateVariables(_getTemplateVariables(JSON.stringify(template.item))), _getIdsOutOfTemplateVariables(_getTemplateVariables(JSON.stringify(template.data))));
745
- // Remove duplicates and self-references
746
- deps.sort();
747
- deps = deps.filter(function (elem, index, array) {
748
- if (elem === template.itemId) {
749
- return false;
750
- }
751
- else if (index > 0) {
752
- return elem !== array[index - 1];
753
- }
754
- else {
755
- return true;
756
- }
757
- });
758
- return deps;
759
- }
760
- /**
761
- * Extracts AGO ids out of template variables.
762
- *
763
- * @param variables List of template variables to examine
764
- * @return List of AGO ids referenced in `variables`
765
- * @private
766
- */
767
- function _getIdsOutOfTemplateVariables(variables) {
768
- return variables
769
- .map(function (variable) {
770
- var idList = variable.match(/[0-9A-F]{32}/i); // is it a guid?
771
- if (idList) {
772
- return idList[0];
773
- }
774
- else {
775
- return null;
776
- }
777
- })
778
- .filter(function (variable) { return !!variable; });
779
- }
780
- /**
781
- * Creates a list of item URLs.
782
- *
783
- * @param templates Templates to check for URLs
784
- * @return List of URLs
785
- * @private
786
- */
787
- function _getSolutionItemUrls(templates) {
788
- var solutionUrls = [];
789
- templates.forEach(function (template) {
790
- /* istanbul ignore else */
791
- if (template.item.origUrl) {
792
- solutionUrls.push([template.itemId, template.item.origUrl]);
793
- }
794
- });
795
- return solutionUrls;
796
- }
797
- /**
798
- * Extracts template variables out of a string.
799
- *
800
- * @param text String to examine
801
- * @return List of template variables found in string
802
- * @private
803
- */
804
- function _getTemplateVariables(text) {
805
- return (text.match(/{{[a-z0-9.]*}}/gi) || []) // find variable
806
- .map(function (variable) { return variable.substring(2, variable.length - 2); }); // remove "{{" & "}}"
807
- }
808
- /**
809
- * Update the items dependencies and groups arrays
810
- *
811
- * @param templates The array of templates to evaluate
812
- * @return Updated version of the templates
813
- * @private
814
- */
815
- function _postProcessGroupDependencies(templates) {
816
- return templates.map(function (template) {
817
- if (template.type === "Group") {
818
- var id_1 = template.itemId;
819
- // remove group dependencies if we find a circular dependency with one of its items
820
- var removeDependencies_1 = false;
821
- // before we remove update each dependants groups array
822
- template.dependencies.forEach(function (dependencyId) {
823
- var dependantTemplate = solutionCommon.getTemplateById(templates, dependencyId);
824
- // Not all items shared to the group will exist in the templates array
825
- // i.e. Hub Initiative items or any other unsupported types
826
- if (dependantTemplate) {
827
- // check if the group is in the dependantTemplate's list of dependencies
828
- var gIndex = hubCommon.getWithDefault(dependantTemplate, "dependencies", []).indexOf(id_1);
829
- /* istanbul ignore else */
830
- if (gIndex > -1) {
831
- removeDependencies_1 = true;
832
- }
833
- // if the dependant template does not have the group id
834
- // in it's groups array, add it
835
- var groups = hubCommon.getWithDefault(dependantTemplate, "groups", []);
836
- if (groups.indexOf(id_1) === -1) {
837
- groups.push(id_1);
838
- dependantTemplate.groups = groups;
839
- }
840
- }
841
- });
842
- if (removeDependencies_1) {
843
- template.dependencies = [];
844
- }
845
- }
846
- return template;
847
- });
848
- }
849
- /**
850
- * Check for feature service items that have been flagged for invalid designations.
851
- * Remove templates that have invalid designations from the solution item and other item dependencies.
852
- * Clean up any references to items with invalid designations in the other templates.
853
- *
854
- * @param templates The array of templates to evaluate
855
- * @return Updated version of the templates
856
- * @private
857
- */
858
- function _postProcessIgnoredItems(templates) {
859
- // replace in template
860
- var updateDictionary = templates.reduce(function (result, template) {
861
- return template.properties.hasInvalidDesignations
862
- ? Object.assign(result, template.data)
863
- : result;
864
- }, {});
865
- Object.keys(updateDictionary).forEach(function (k) {
866
- solutionCommon.removeTemplate(templates, k);
867
- templates = templates.map(function (t) {
868
- t.dependencies = t.dependencies.filter(function (id) { return id !== k; });
869
- return solutionCommon.replaceInTemplate(t, updateDictionary);
870
- });
871
- });
872
- return templates;
873
- }
874
- /**
875
- * Recursively runs through an object to find and replace any strings found in a dictionary.
876
- *
877
- * @param templateDictionary Hash of things to be replaced
878
- * @param obj Object to be examined
879
- * @private
880
- */
881
- function _replaceDictionaryItemsInObject(hash, obj) {
882
- /* istanbul ignore else */
883
- if (obj) {
884
- Object.keys(obj).forEach(function (prop) {
885
- var propObj = obj[prop];
886
- if (propObj) {
887
- if (typeof propObj === "object") {
888
- _replaceDictionaryItemsInObject(hash, propObj);
889
- }
890
- else if (typeof propObj === "string") {
891
- obj[prop] = hash[propObj] || propObj;
892
- }
893
- }
894
- });
895
- }
896
- return obj;
897
- }
898
- /**
899
- * Recursively runs through an object to find and templatize any remaining references to solution's items.
900
- *
901
- * @param ids Ids to be replaced in strings found in object
902
- * @param obj Object to be examined
903
- * @private
904
- */
905
- function _replaceRemainingIdsInObject(ids, obj) {
906
- /* istanbul ignore else */
907
- if (obj) {
908
- Object.keys(obj).forEach(function (prop) {
909
- var propObj = obj[prop];
910
- if (propObj) {
911
- if (typeof propObj === "object") {
912
- _replaceRemainingIdsInObject(ids, propObj);
913
- }
914
- else if (typeof propObj === "string") {
915
- obj[prop] = _replaceRemainingIdsInString(ids, propObj);
916
- }
917
- }
918
- });
919
- }
920
- return obj;
921
- }
922
- /**
923
- * Templatizes ids from a list in a string if they're not already templatized.
924
- *
925
- * @param ids Ids to be replaced in source string
926
- * @param str Source string to be examined
927
- * @return A copy of the source string with any templatization changes
928
- * @private
929
- */
930
- function _replaceRemainingIdsInString(ids, str) {
931
- var updatedStr = str;
932
- var untemplatizedIds = solutionCommon.getIDs(str);
933
- if (untemplatizedIds.length > 0) {
934
- untemplatizedIds.forEach(function (id) {
935
- if (ids.includes(id)) {
936
- var re = new RegExp("({*)" + id, "gi");
937
- updatedStr = updatedStr.replace(re, function (match) {
938
- return match.indexOf("{{") < 0
939
- ? "{{" + id.replace("{", "") + ".itemId}}"
940
- : match;
941
- });
942
- }
943
- });
944
- }
945
- return updatedStr;
946
- }
947
- /**
948
- * Finds and templatizes any URLs in solution items' descriptions.
949
- *
950
- * @param templates The array of templates to evaluate, modified in place
951
- * @private
952
- */
953
- function _simplifyUrlsInItemDescriptions(templates) {
954
- // Get the urls in the solution along with their item ids & convert the id into the form
955
- // "{{fcb2bf2837a6404ebb418a1f805f976a.url}}"
956
- var solutionUrls = _getSolutionItemUrls(templates).map(function (idUrl) { return [
957
- "{{" + idUrl[0] + ".url}}",
958
- idUrl[1]
959
- ]; });
960
- /* istanbul ignore else */
961
- if (solutionUrls.length > 0) {
962
- // Make the replacements
963
- templates.forEach(function (template) {
964
- solutionUrls.forEach(
965
- // TypeScript for es2015 doesn't have a definition for `replaceAll`
966
- function (idUrl) {
967
- /* istanbul ignore else */
968
- if (template.item.description) {
969
- template.item.description = template.item
970
- .description.replaceAll(idUrl[1], idUrl[0]);
971
- }
972
- });
973
- });
974
- }
975
- }
976
- /**
977
- * Templatizes occurrences of the URL to the user's organization in the `item` and `data` template sections.
978
- *
979
- * @param templates The array of templates to evaluate; templates is modified in place
980
- * @param authentication Credentials for request organization info
981
- * @return Promise resolving with `templates`
982
- * @private
983
- */
984
- function _templatizeOrgUrl(templates, authentication) {
985
- return new Promise(function (resolve, reject) {
986
- // Get the org's URL
987
- solutionCommon.getPortal(null, authentication).then(function (org) {
988
- var orgUrl = "https://" + org.urlKey + "." + org.customBaseUrl;
989
- var templatizedOrgUrl = "{{portalBaseUrl}}";
990
- // Cycle through each of the items in the template and scan the `item` and `data` sections of each for replacements
991
- templates.forEach(function (template) {
992
- solutionCommon.globalStringReplace(template.item, new RegExp(orgUrl, "gi"), templatizedOrgUrl);
993
- solutionCommon.globalStringReplace(template.data, new RegExp(orgUrl, "gi"), templatizedOrgUrl);
994
- });
995
- resolve(templates);
996
- }, reject);
997
- });
998
- }
999
- /**
1000
- * Finds and templatizes any references to solution's items.
1001
- *
1002
- * @param templates The array of templates to evaluate, modified in place
1003
- * @private
1004
- */
1005
- function _templatizeSolutionIds(templates) {
1006
- // Get the ids in the solution
1007
- var solutionIds = templates.map(function (template) { return template.itemId; });
1008
- // Cycle through each of the items in the template and
1009
- // 1. templatize untemplatized ids in our solution in the `item` and `data` sections;
1010
- // 2. update the `dependencies` section
1011
- templates.forEach(function (template) {
1012
- _replaceRemainingIdsInObject(solutionIds, template.item);
1013
- _replaceRemainingIdsInObject(solutionIds, template.data);
1014
- /* istanbul ignore else */
1015
- if (template.type !== "Group" && !solutionCommon.isWorkforceProject(template)) {
1016
- template.dependencies = _getDependencies(template);
1017
- }
1018
- });
1019
- }
983
+ /** @license
984
+ * Copyright 2018 Esri
985
+ *
986
+ * Licensed under the Apache License, Version 2.0 (the "License");
987
+ * you may not use this file except in compliance with the License.
988
+ * You may obtain a copy of the License at
989
+ *
990
+ * http://www.apache.org/licenses/LICENSE-2.0
991
+ *
992
+ * Unless required by applicable law or agreed to in writing, software
993
+ * distributed under the License is distributed on an "AS IS" BASIS,
994
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
995
+ * See the License for the specific language governing permissions and
996
+ * limitations under the License.
997
+ */
998
+ // Simple no-op to clean up progressCallback management
999
+ const noOp = () => { };
1000
+ /**
1001
+ * Creates a solution item.
1002
+ *
1003
+ * @param sourceId AGO id of group whose contents are to be added to solution or of an item to convert into a solution
1004
+ * @param srcAuthentication Credentials for requests to source items
1005
+ * @param destAuthentication Credentials for the requests to destination solution
1006
+ * @param options Customizations for creating the solution
1007
+ * @return A promise that resolves with the AGO id of the new solution
1008
+ */
1009
+ function createSolution(sourceId, srcAuthentication, destAuthentication, options) {
1010
+ const createOptions = options || {};
1011
+ const progressCb = createOptions.progressCallback || noOp;
1012
+ createOptions.templateDictionary = Object.assign({}, createOptions.templateDictionary);
1013
+ progressCb(1); // let the caller know that we've started
1014
+ // Assume that source is a group and try to get group's information
1015
+ return Promise.all([
1016
+ solutionCommon.getGroupBase(sourceId, srcAuthentication),
1017
+ solutionCommon.getGroupContents(sourceId, srcAuthentication),
1018
+ solutionCommon.getVelocityUrlBase(srcAuthentication, createOptions.templateDictionary)
1019
+ ])
1020
+ .then(
1021
+ // Group fetches worked; assumption was correct
1022
+ responses => {
1023
+ createOptions.itemIds = responses[1];
1024
+ progressCb(15);
1025
+ return new Promise(resolve => {
1026
+ // Update the createOptions with values from the group
1027
+ resolve(_applySourceToCreateOptions(createOptions, responses[0], srcAuthentication, true));
1028
+ });
1029
+ },
1030
+ // Assumption incorrect; try source as an item
1031
+ () => {
1032
+ return new Promise((resolve, reject) => {
1033
+ createOptions.itemIds = [sourceId];
1034
+ solutionCommon.getItemBase(sourceId, srcAuthentication).then(
1035
+ // Update the createOptions with values from the item
1036
+ itemBase => resolve(_applySourceToCreateOptions(createOptions, itemBase, srcAuthentication, false)), reject);
1037
+ });
1038
+ })
1039
+ .then(createOptions => {
1040
+ return new Promise((resolve, reject) => {
1041
+ Promise.all([
1042
+ solutionCommon.getPortal("", srcAuthentication),
1043
+ solutionCommon.getUser(srcAuthentication)
1044
+ ]).then(responses => {
1045
+ // check tracking
1046
+ const [portalResponse, userResponse] = responses;
1047
+ solutionCommon.setLocationTrackingEnabled(portalResponse, userResponse, createOptions.templateDictionary);
1048
+ resolve(createOptions);
1049
+ }, reject);
1050
+ });
1051
+ })
1052
+ .then(
1053
+ // Use a copy of the thumbnail rather than a URL to it
1054
+ createOptions => {
1055
+ return _addThumbnailFileToCreateOptions(createOptions, srcAuthentication);
1056
+ })
1057
+ .then(
1058
+ // Create a solution
1059
+ createOptions => {
1060
+ return _createSolutionFromItemIds(createOptions, srcAuthentication, destAuthentication);
1061
+ })
1062
+ .then(
1063
+ // Successfully created solution
1064
+ createdSolutionId => {
1065
+ progressCb(100); // finished
1066
+ return createdSolutionId;
1067
+ },
1068
+ // Error fetching group, group contents, or item, or error creating solution from ids
1069
+ error => {
1070
+ progressCb(1);
1071
+ console.error(error);
1072
+ throw error;
1073
+ });
1074
+ }
1075
+ /**
1076
+ * Update the createOptions with the group properties
1077
+ *
1078
+ * @param createOptions
1079
+ * @param sourceInfo
1080
+ * @param authentication
1081
+ * @param isGroup Boolean to indicate if the files are associated with a group or item
1082
+ * @internal
1083
+ */
1084
+ function _applySourceToCreateOptions(createOptions, sourceInfo, srcAuthentication, isGroup = false) {
1085
+ // Create a solution from the group's or item's contents,
1086
+ // using the group's or item's information as defaults for the solution item
1087
+ ["title", "snippet", "description", "tags"].forEach(prop => {
1088
+ createOptions[prop] = createOptions[prop] ?? sourceInfo[prop];
1089
+ });
1090
+ if (!createOptions.thumbnailurl && sourceInfo.thumbnail) {
1091
+ // Get the full path to the thumbnail
1092
+ createOptions.thumbnailurl = solutionCommon.generateSourceThumbnailUrl(srcAuthentication.portal, sourceInfo.id, sourceInfo.thumbnail, isGroup);
1093
+ delete sourceInfo.thumbnail;
1094
+ }
1095
+ return createOptions;
1096
+ }
1097
+ /**
1098
+ * Update the createOptions with the thumbnail file
1099
+ *
1100
+ * @param createOptions
1101
+ * @param srcAuthentication
1102
+ * @internal
1103
+ */
1104
+ function _addThumbnailFileToCreateOptions(createOptions, srcAuthentication) {
1105
+ return new Promise(resolve => {
1106
+ if (!createOptions.thumbnail && createOptions.thumbnailurl) {
1107
+ // Figure out the thumbnail's filename
1108
+ const filename = solutionCommon.getFilenameFromUrl(createOptions.thumbnailurl) || "thumbnail";
1109
+ const thumbnailurl = solutionCommon.appendQueryParam(createOptions.thumbnailurl, "w=400");
1110
+ delete createOptions.thumbnailurl;
1111
+ // Fetch the thumbnail
1112
+ solutionCommon.getBlobAsFile(thumbnailurl, filename, srcAuthentication).then(thumbnail => {
1113
+ createOptions.thumbnail = thumbnail;
1114
+ resolve(createOptions);
1115
+ }, () => {
1116
+ resolve(createOptions);
1117
+ });
1118
+ }
1119
+ else {
1120
+ resolve(createOptions);
1121
+ }
1122
+ });
1123
+ }
1124
+ /**
1125
+ * Creates a solution item using a list of AGO item ids.
1126
+ *
1127
+ * @param options Customizations for creating the solution
1128
+ * @param srcAuthentication Credentials for requests to source items
1129
+ * @param destAuthentication Credentials for the requests to destination solution
1130
+ * @return A promise that resolves with the AGO id of the new solution; solution item is deleted if its
1131
+ * there is a problem updating it
1132
+ * @internal
1133
+ */
1134
+ function _createSolutionFromItemIds(options, srcAuthentication, destAuthentication) {
1135
+ let solutionId = "";
1136
+ // Create a solution from the list of items
1137
+ return _createSolutionItem(destAuthentication, options)
1138
+ .then(id => {
1139
+ solutionId = id;
1140
+ // Add list of items to the new solution
1141
+ return addContentToSolution(solutionId, options, srcAuthentication, destAuthentication);
1142
+ })
1143
+ .catch(addError => {
1144
+ // If the solution item got created, delete it
1145
+ if (solutionId) {
1146
+ const failSafeRemove = hubCommon.failSafe(solutionCommon.removeItem, { success: true });
1147
+ return failSafeRemove(solutionId, destAuthentication).then(() => {
1148
+ throw addError;
1149
+ });
1150
+ }
1151
+ else {
1152
+ throw addError;
1153
+ }
1154
+ });
1155
+ }
1156
+ /**
1157
+ * Creates an empty solution item.
1158
+ *
1159
+ * @param authentication Credentials for the request
1160
+ * @param options Customizations for creating the solution
1161
+ * @return A promise that resolves with the AGO id of the new solution; solution item is deleted if its
1162
+ * there is a problem updating its thumbnail
1163
+ * @internal
1164
+ */
1165
+ function _createSolutionItem(authentication, options) {
1166
+ const model = _createSolutionItemModel(options);
1167
+ // Create new solution item
1168
+ delete model.item.thumbnailurl;
1169
+ model.item.thumbnail = options?.thumbnail;
1170
+ return solutionCommon.createItemWithData(model.item, model.data, authentication, options?.folderId).then(createResponse => {
1171
+ return Promise.resolve(createResponse.id);
1172
+ });
1173
+ }
1174
+ /**
1175
+ * Create the Solution Item model to be used to create
1176
+ * the Solution Item itself
1177
+ *
1178
+ * @param options
1179
+ * @internal
1180
+ */
1181
+ function _createSolutionItemModel(options) {
1182
+ // Solution uses all supplied tags but for deploy.* tags; that information goes into properties
1183
+ const creationTags = options?.tags ?? [];
1184
+ const solutionItem = {
1185
+ type: "Solution",
1186
+ title: options?.title ?? solutionCommon.createShortId(),
1187
+ snippet: options?.snippet ?? "",
1188
+ description: options?.description ?? "",
1189
+ properties: {
1190
+ schemaVersion: solutionCommon.CURRENT_SCHEMA_VERSION
1191
+ },
1192
+ thumbnailurl: options?.thumbnailurl ?? "",
1193
+ tags: creationTags.filter((tag) => !tag.startsWith("deploy.")),
1194
+ typeKeywords: ["Solution", "Template"].concat(_getDeploymentProperties(creationTags))
1195
+ };
1196
+ // ensure that snippet and description are not nefarious
1197
+ const sanitizedItem = solutionCommon.sanitizeJSONAndReportChanges(solutionItem);
1198
+ const addlKeywords = options?.additionalTypeKeywords || [];
1199
+ sanitizedItem.typeKeywords = [].concat(solutionItem.typeKeywords, addlKeywords);
1200
+ const solutionData = {
1201
+ metadata: {},
1202
+ templates: []
1203
+ };
1204
+ return {
1205
+ item: sanitizedItem,
1206
+ data: solutionData
1207
+ };
1208
+ }
1209
+ /**
1210
+ * Gets the deploy.id and deploy.version tag values.
1211
+ *
1212
+ * @param tags A list of item tags
1213
+ * @return A list containing the two values found in the tags, or defaulting to a new GUID and "1.0", respectively,
1214
+ * as needed
1215
+ * @internal
1216
+ */
1217
+ function _getDeploymentProperties(tags) {
1218
+ return [
1219
+ "solutionid-" +
1220
+ (_getDeploymentProperty("deploy.id.", tags) ?? solutionCommon.createLongId()),
1221
+ "solutionversion-" +
1222
+ (_getDeploymentProperty("deploy.version.", tags) ?? "1.0")
1223
+ ];
1224
+ }
1225
+ /**
1226
+ * Searches for a tag that has the specified prefix and returns the rest of the tag following that prefix.
1227
+ *
1228
+ * @param desiredTagPrefix Tag prefix to look for
1229
+ * @param tags A list of item tags
1230
+ * @return The extracted value of the first matching tag or null if a tag with the specified prefix is not found
1231
+ * @internal
1232
+ */
1233
+ function _getDeploymentProperty(desiredTagPrefix, tags) {
1234
+ const foundTagAsList = tags.filter(tag => tag.startsWith(desiredTagPrefix));
1235
+ if (foundTagAsList.length > 0) {
1236
+ return foundTagAsList[0].substr(desiredTagPrefix.length);
1237
+ }
1238
+ else {
1239
+ return null;
1240
+ }
1241
+ }
1020
1242
 
1021
- /** @license
1022
- * Copyright 2018 Esri
1023
- *
1024
- * Licensed under the Apache License, Version 2.0 (the "License");
1025
- * you may not use this file except in compliance with the License.
1026
- * You may obtain a copy of the License at
1027
- *
1028
- * http://www.apache.org/licenses/LICENSE-2.0
1029
- *
1030
- * Unless required by applicable law or agreed to in writing, software
1031
- * distributed under the License is distributed on an "AS IS" BASIS,
1032
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1033
- * See the License for the specific language governing permissions and
1034
- * limitations under the License.
1035
- */
1036
- // Simple no-op to clean up progressCallback management
1037
- var noOp = function () { };
1038
- /**
1039
- * Creates a solution item.
1040
- *
1041
- * @param sourceId AGO id of group whose contents are to be added to solution or of an item to convert into a solution
1042
- * @param authentication Credentials for the request
1043
- * @param options Customizations for creating the solution
1044
- * @return A promise that resolves with the AGO id of the new solution
1045
- */
1046
- function createSolution(sourceId, authentication, options) {
1047
- var createOptions = options || {};
1048
- var progressCb = createOptions.progressCallback || noOp;
1049
- progressCb(1); // let the caller know that we've started
1050
- // Assume that source is a group and try to get group's information
1051
- return Promise.all([
1052
- solutionCommon.getGroupBase(sourceId, authentication),
1053
- solutionCommon.getGroupContents(sourceId, authentication)
1054
- ])
1055
- .then(
1056
- // Group fetches worked; assumption was correct
1057
- function (responses) {
1058
- createOptions.itemIds = responses[1];
1059
- progressCb(15);
1060
- return new Promise(function (resolve) {
1061
- // Update the createOptions with values from the group
1062
- resolve(_applySourceToCreateOptions(createOptions, responses[0], authentication, true));
1063
- });
1064
- },
1065
- // Assumption incorrect; try source as an item
1066
- function () {
1067
- return new Promise(function (resolve, reject) {
1068
- createOptions.itemIds = [sourceId];
1069
- solutionCommon.getItemBase(sourceId, authentication).then(
1070
- // Update the createOptions with values from the item
1071
- function (itemBase) {
1072
- return resolve(_applySourceToCreateOptions(createOptions, itemBase, authentication, false));
1073
- }, reject);
1074
- });
1075
- })
1076
- .then(
1077
- // Use a copy of the thumbnail rather than a URL to it
1078
- function (createOptions) {
1079
- return _addThumbnailFileToCreateOptions(createOptions, authentication);
1080
- })
1081
- .then(
1082
- // Create a solution
1083
- function (createOptions) {
1084
- return _createSolutionFromItemIds(createOptions, authentication);
1085
- })
1086
- .then(
1087
- // Successfully created solution
1088
- function (createdSolutionId) {
1089
- progressCb(100); // finished
1090
- return createdSolutionId;
1091
- },
1092
- // Error fetching group, group contents, or item, or error creating solution from ids
1093
- function (error) {
1094
- progressCb(1);
1095
- console.error(error);
1096
- throw error;
1097
- });
1098
- }
1099
- /**
1100
- * Update the createOptions with the group properties
1101
- *
1102
- * @param createOptions
1103
- * @param sourceInfo
1104
- * @param authentication
1105
- * @param isGroup Boolean to indicate if the files are associated with a group or item
1106
- * @internal
1107
- */
1108
- function _applySourceToCreateOptions(createOptions, sourceInfo, authentication, isGroup) {
1109
- if (isGroup === void 0) { isGroup = false; }
1110
- // Create a solution from the group's or item's contents,
1111
- // using the group's or item's information as defaults for the solution item
1112
- ["title", "snippet", "description", "tags"].forEach(function (prop) {
1113
- var _a;
1114
- createOptions[prop] = (_a = createOptions[prop]) !== null && _a !== void 0 ? _a : sourceInfo[prop];
1115
- });
1116
- if (!createOptions.thumbnailurl && sourceInfo.thumbnail) {
1117
- // Get the full path to the thumbnail
1118
- createOptions.thumbnailurl = solutionCommon.generateSourceThumbnailUrl(authentication.portal, sourceInfo.id, sourceInfo.thumbnail, isGroup);
1119
- delete sourceInfo.thumbnail;
1120
- }
1121
- return createOptions;
1122
- }
1123
- /**
1124
- * Update the createOptions with the thumbnail file
1125
- *
1126
- * @param createOptions
1127
- * @param authentication
1128
- * @internal
1129
- */
1130
- function _addThumbnailFileToCreateOptions(createOptions, authentication) {
1131
- return new Promise(function (resolve) {
1132
- if (!createOptions.thumbnail && createOptions.thumbnailurl) {
1133
- // Figure out the thumbnail's filename
1134
- var filename = solutionCommon.getFilenameFromUrl(createOptions.thumbnailurl) || "thumbnail";
1135
- var thumbnailurl = solutionCommon.appendQueryParam(createOptions.thumbnailurl, "w=400");
1136
- delete createOptions.thumbnailurl;
1137
- // Fetch the thumbnail
1138
- solutionCommon.getBlobAsFile(thumbnailurl, filename, authentication).then(function (thumbnail) {
1139
- createOptions.thumbnail = thumbnail;
1140
- resolve(createOptions);
1141
- }, function () {
1142
- resolve(createOptions);
1143
- });
1144
- }
1145
- else {
1146
- resolve(createOptions);
1147
- }
1148
- });
1149
- }
1150
- /**
1151
- * Creates a solution item using a list of AGO item ids.
1152
- *
1153
- * @param options Customizations for creating the solution
1154
- * @param authentication Credentials for the request
1155
- * @return A promise that resolves with the AGO id of the new solution; solution item is deleted if its
1156
- * there is a problem updating it
1157
- * @internal
1158
- */
1159
- function _createSolutionFromItemIds(options, authentication) {
1160
- var solutionId = "";
1161
- // Create a solution from the list of items
1162
- return _createSolutionItem(authentication, options)
1163
- .then(function (id) {
1164
- solutionId = id;
1165
- // Add list of items to the new solution
1166
- return addContentToSolution(solutionId, options, authentication);
1167
- })
1168
- .catch(function (addError) {
1169
- // If the solution item got created, delete it
1170
- if (solutionId) {
1171
- var failSafeRemove = hubCommon.failSafe(solutionCommon.removeItem, { success: true });
1172
- return failSafeRemove(solutionId, authentication).then(function () {
1173
- throw addError;
1174
- });
1175
- }
1176
- else {
1177
- throw addError;
1178
- }
1179
- });
1180
- }
1181
- /**
1182
- * Creates an empty solution item.
1183
- *
1184
- * @param authentication Credentials for the request
1185
- * @param options Customizations for creating the solution
1186
- * @return A promise that resolves with the AGO id of the new solution; solution item is deleted if its
1187
- * there is a problem updating its thumbnail
1188
- * @internal
1189
- */
1190
- function _createSolutionItem(authentication, options) {
1191
- return new Promise(function (resolve, reject) {
1192
- var model = _createSolutionItemModel(options);
1193
- // Create new solution item
1194
- delete model.item.thumbnailurl;
1195
- model.item.thumbnail = options === null || options === void 0 ? void 0 : options.thumbnail;
1196
- solutionCommon.createItemWithData(model.item, model.data, authentication, options === null || options === void 0 ? void 0 : options.folderId).then(function (createResponse) {
1197
- resolve(createResponse.id);
1198
- }, function (err) {
1199
- reject(err);
1200
- });
1201
- });
1202
- }
1203
- /**
1204
- * Create the Solution Item model to be used to create
1205
- * the Solution Item itself
1206
- *
1207
- * @param options
1208
- * @internal
1209
- */
1210
- function _createSolutionItemModel(options) {
1211
- var _a, _b, _c, _d, _e;
1212
- // Solution uses all supplied tags but for deploy.* tags; that information goes into properties
1213
- var creationTags = (_a = options === null || options === void 0 ? void 0 : options.tags) !== null && _a !== void 0 ? _a : [];
1214
- var solutionItem = {
1215
- type: "Solution",
1216
- title: (_b = options === null || options === void 0 ? void 0 : options.title) !== null && _b !== void 0 ? _b : solutionCommon.createShortId(),
1217
- snippet: (_c = options === null || options === void 0 ? void 0 : options.snippet) !== null && _c !== void 0 ? _c : "",
1218
- description: (_d = options === null || options === void 0 ? void 0 : options.description) !== null && _d !== void 0 ? _d : "",
1219
- properties: {
1220
- schemaVersion: solutionCommon.CURRENT_SCHEMA_VERSION
1221
- },
1222
- thumbnailurl: (_e = options === null || options === void 0 ? void 0 : options.thumbnailurl) !== null && _e !== void 0 ? _e : "",
1223
- tags: creationTags.filter(function (tag) { return !tag.startsWith("deploy."); }),
1224
- typeKeywords: ["Solution", "Template"].concat(_getDeploymentProperties(creationTags))
1225
- };
1226
- // ensure that snippet and description are not nefarious
1227
- var sanitizedItem = solutionCommon.sanitizeJSONAndReportChanges(solutionItem);
1228
- var addlKeywords = (options === null || options === void 0 ? void 0 : options.additionalTypeKeywords) || [];
1229
- sanitizedItem.typeKeywords = __spread(solutionItem.typeKeywords, addlKeywords);
1230
- var solutionData = {
1231
- metadata: {},
1232
- templates: []
1233
- };
1234
- return {
1235
- item: sanitizedItem,
1236
- data: solutionData
1237
- };
1238
- }
1239
- /**
1240
- * Gets the deploy.id and deploy.version tag values.
1241
- *
1242
- * @param tags A list of item tags
1243
- * @return A list ocntaining the two values found in the tags, or defaulting to a new GUID and "1.0", respectively,
1244
- * as needed
1245
- * @internal
1246
- */
1247
- function _getDeploymentProperties(tags) {
1248
- var _a, _b;
1249
- return [
1250
- "solutionid-" +
1251
- ((_a = _getDeploymentProperty("deploy.id.", tags)) !== null && _a !== void 0 ? _a : solutionCommon.createLongId()),
1252
- "solutionversion-" +
1253
- ((_b = _getDeploymentProperty("deploy.version.", tags)) !== null && _b !== void 0 ? _b : "1.0")
1254
- ];
1255
- }
1256
- /**
1257
- * Searches for a tag that has the specified prefix and returns the rest of the tag following that prefix.
1258
- *
1259
- * @param desiredTagPrefix Tag prefix to look for
1260
- * @param tags A list of item tags
1261
- * @return The extracted value of the first matching tag or null if a tag with the specified prefix is not found
1262
- * @internal
1263
- */
1264
- function _getDeploymentProperty(desiredTagPrefix, tags) {
1265
- var foundTagAsList = tags.filter(function (tag) { return tag.startsWith(desiredTagPrefix); });
1266
- if (foundTagAsList.length > 0) {
1267
- return foundTagAsList[0].substr(desiredTagPrefix.length);
1268
- }
1269
- else {
1270
- return null;
1271
- }
1272
- }
1243
+ exports.UNSUPPORTED = UNSUPPORTED;
1244
+ exports._addLayerIdToDatasourceUrl = _addLayerIdToDatasourceUrl;
1245
+ exports._addMapLayerIds = _addMapLayerIds;
1246
+ exports._addThumbnailFileToCreateOptions = _addThumbnailFileToCreateOptions;
1247
+ exports._applySourceToCreateOptions = _applySourceToCreateOptions;
1248
+ exports._createSolutionFromItemIds = _createSolutionFromItemIds;
1249
+ exports._createSolutionItem = _createSolutionItem;
1250
+ exports._createSolutionItemModel = _createSolutionItemModel;
1251
+ exports._getDatasourceInfos = _getDatasourceInfos;
1252
+ exports._getDeploymentProperties = _getDeploymentProperties;
1253
+ exports._getDeploymentProperty = _getDeploymentProperty;
1254
+ exports._getTemplateTypeHash = _getTemplateTypeHash;
1255
+ exports._getWebMapFSDependencies = _getWebMapFSDependencies;
1256
+ exports._updateWebMapHashInfo = _updateWebMapHashInfo;
1257
+ exports.createItemTemplate = createItemTemplate;
1258
+ exports.createSolution = createSolution;
1259
+ exports.moduleMap = moduleMap;
1260
+ exports.postProcessFieldReferences = postProcessFieldReferences;
1273
1261
 
1274
- exports.UNSUPPORTED = UNSUPPORTED;
1275
- exports._addLayerIdToDatasourceUrl = _addLayerIdToDatasourceUrl;
1276
- exports._addMapLayerIds = _addMapLayerIds;
1277
- exports._addThumbnailFileToCreateOptions = _addThumbnailFileToCreateOptions;
1278
- exports._applySourceToCreateOptions = _applySourceToCreateOptions;
1279
- exports._createSolutionFromItemIds = _createSolutionFromItemIds;
1280
- exports._createSolutionItem = _createSolutionItem;
1281
- exports._createSolutionItemModel = _createSolutionItemModel;
1282
- exports._getDatasourceInfos = _getDatasourceInfos;
1283
- exports._getDeploymentProperties = _getDeploymentProperties;
1284
- exports._getDeploymentProperty = _getDeploymentProperty;
1285
- exports._getTemplateTypeHash = _getTemplateTypeHash;
1286
- exports._getWebMapFSDependencies = _getWebMapFSDependencies;
1287
- exports._updateWebMapHashInfo = _updateWebMapHashInfo;
1288
- exports.createItemTemplate = createItemTemplate;
1289
- exports.createSolution = createSolution;
1290
- exports.moduleMap = moduleMap;
1291
- exports.postProcessFieldReferences = postProcessFieldReferences;
1292
-
1293
- Object.defineProperty(exports, '__esModule', { value: true });
1262
+ Object.defineProperty(exports, '__esModule', { value: true });
1294
1263
 
1295
1264
  })));
1296
1265
  //# sourceMappingURL=creator.umd.js.map