@esri/solutions-components 0.6.37 → 0.6.39

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. package/dist/cjs/calcite-alert_3.cjs.entry.js +1 -1
  2. package/dist/cjs/calcite-combobox_6.cjs.entry.js +1 -1
  3. package/dist/cjs/calcite-shell-panel_14.cjs.entry.js +2 -2
  4. package/dist/cjs/card-manager_3.cjs.entry.js +7 -4
  5. package/dist/cjs/crowdsource-manager.cjs.entry.js +1 -1
  6. package/dist/cjs/{downloadUtils-37d9aaf3.js → downloadUtils-d8e48fbd.js} +55 -12
  7. package/dist/cjs/{index.es-d1d9b140.js → index.es-6159eedc.js} +4 -3
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/cjs/map-select-tools_3.cjs.entry.js +4 -3
  10. package/dist/cjs/{mapViewUtils-96172223.js → mapViewUtils-f7bbc35b.js} +5 -2
  11. package/dist/cjs/public-notification.cjs.entry.js +5 -4
  12. package/dist/cjs/{clean-url-d5326abb.js → restHelpersGet-c94617cf.js} +398 -0
  13. package/dist/cjs/solution-configuration.cjs.entry.js +565 -565
  14. package/dist/cjs/solution-contents_3.cjs.entry.js +2 -2
  15. package/dist/cjs/{solution-store-714601a2.js → solution-store-b40c2f46.js} +19 -383
  16. package/dist/cjs/solutions-components.cjs.js +1 -1
  17. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +10 -4
  18. package/dist/collection/components/map-card/map-card.js +26 -1
  19. package/dist/collection/components/public-notification/public-notification.js +6 -5
  20. package/dist/collection/utils/downloadUtils.js +50 -8
  21. package/dist/collection/utils/downloadUtils.ts +62 -9
  22. package/dist/collection/utils/interfaces.ts +2 -0
  23. package/dist/collection/utils/queryUtils.js +5 -2
  24. package/dist/collection/utils/queryUtils.ts +4 -2
  25. package/dist/components/crowdsource-manager.js +1 -1
  26. package/dist/components/downloadUtils.js +51 -8
  27. package/dist/components/map-card2.js +4 -1
  28. package/dist/components/public-notification.js +2 -2
  29. package/dist/components/queryUtils.js +5 -2
  30. package/dist/components/{clean-url.js → restHelpersGet.js} +392 -1
  31. package/dist/components/solution-configuration.js +552 -552
  32. package/dist/components/solution-store.js +2 -365
  33. package/dist/esm/calcite-alert_3.entry.js +1 -1
  34. package/dist/esm/calcite-combobox_6.entry.js +1 -1
  35. package/dist/esm/calcite-shell-panel_14.entry.js +2 -2
  36. package/dist/esm/card-manager_3.entry.js +7 -4
  37. package/dist/esm/crowdsource-manager.entry.js +1 -1
  38. package/dist/esm/{downloadUtils-76379e4a.js → downloadUtils-d41ecba9.js} +53 -10
  39. package/dist/esm/{index.es-0d134a52.js → index.es-b226bf47.js} +4 -3
  40. package/dist/esm/loader.js +1 -1
  41. package/dist/esm/map-select-tools_3.entry.js +4 -3
  42. package/dist/esm/{mapViewUtils-08f6cfce.js → mapViewUtils-1e2befd7.js} +5 -2
  43. package/dist/esm/public-notification.entry.js +5 -4
  44. package/dist/esm/{clean-url-bce022e6.js → restHelpersGet-a5ec2192.js} +392 -1
  45. package/dist/esm/solution-configuration.entry.js +552 -552
  46. package/dist/esm/solution-contents_3.entry.js +2 -2
  47. package/dist/esm/{solution-store-3ee6c7a3.js → solution-store-17bb0a75.js} +2 -365
  48. package/dist/esm/solutions-components.js +1 -1
  49. package/dist/solutions-components/{p-9800e602.entry.js → p-091120c5.entry.js} +1 -1
  50. package/dist/solutions-components/p-1b14b687.entry.js +6 -0
  51. package/dist/solutions-components/{p-646e983f.entry.js → p-2d143359.entry.js} +1 -1
  52. package/dist/solutions-components/{p-ac7332b3.entry.js → p-40e95e2b.entry.js} +1 -1
  53. package/dist/solutions-components/p-420e1585.entry.js +36 -0
  54. package/dist/solutions-components/p-4807b2a1.js +36 -0
  55. package/dist/solutions-components/p-56a3b81e.entry.js +6 -0
  56. package/dist/solutions-components/p-5856dc4f.js +66 -0
  57. package/dist/solutions-components/p-89b4b401.js +145 -0
  58. package/dist/solutions-components/{p-4ecad91c.entry.js → p-973625f8.entry.js} +1 -1
  59. package/dist/solutions-components/p-99391a15.entry.js +6 -0
  60. package/dist/solutions-components/{p-03130804.js → p-9ecb5d66.js} +1 -1
  61. package/dist/solutions-components/{p-b02eb8f4.js → p-a8661f1f.js} +30 -30
  62. package/dist/solutions-components/p-ba064f24.entry.js +6 -0
  63. package/dist/solutions-components/solutions-components.esm.js +1 -1
  64. package/dist/solutions-components/utils/downloadUtils.ts +62 -9
  65. package/dist/solutions-components/utils/interfaces.ts +2 -0
  66. package/dist/solutions-components/utils/queryUtils.ts +4 -2
  67. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +3 -3
  68. package/dist/types/components/map-card/map-card.d.ts +5 -1
  69. package/dist/types/components/public-notification/public-notification.d.ts +1 -1
  70. package/dist/types/components.d.ts +16 -8
  71. package/dist/types/utils/interfaces.d.ts +1 -0
  72. package/package.json +1 -1
  73. package/dist/solutions-components/p-13b21d19.entry.js +0 -36
  74. package/dist/solutions-components/p-15070568.js +0 -36
  75. package/dist/solutions-components/p-63867402.entry.js +0 -6
  76. package/dist/solutions-components/p-81a0c88f.entry.js +0 -6
  77. package/dist/solutions-components/p-b7804687.entry.js +0 -6
  78. package/dist/solutions-components/p-d0544f24.js +0 -192
  79. package/dist/solutions-components/p-eba875d9.entry.js +0 -6
  80. package/dist/solutions-components/p-ecc95259.js +0 -20
@@ -8,10 +8,10 @@
8
8
  Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
10
  const index = require('./index-1ffa261f.js');
11
- const solutionStore = require('./solution-store-714601a2.js');
11
+ const solutionStore = require('./solution-store-b40c2f46.js');
12
12
  require('./solution-resource-f9e3b289.js');
13
+ const restHelpersGet = require('./restHelpersGet-c94617cf.js');
13
14
  const locale = require('./locale-d50f3250.js');
14
- const cleanUrl = require('./clean-url-d5326abb.js');
15
15
  require('./index-2bdbac04.js');
16
16
  require('./interfaces-000be6de.js');
17
17
  require('./_commonjsHelpers-384729db.js');
@@ -39,576 +39,234 @@ function decodeQueryString(query) {
39
39
  }, {});
40
40
  }
41
41
 
42
- /** @license
43
- * Copyright 2022 Esri
44
- *
45
- * Licensed under the Apache License, Version 2.0 (the "License");
46
- * you may not use this file except in compliance with the License.
47
- * You may obtain a copy of the License at
48
- *
49
- * http://www.apache.org/licenses/LICENSE-2.0
50
- *
51
- * Unless required by applicable law or agreed to in writing, software
52
- * distributed under the License is distributed on an "AS IS" BASIS,
53
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54
- * See the License for the specific language governing permissions and
55
- * limitations under the License.
56
- */
57
- //--------------------------------------------------------------------------
58
- //
59
- // Public Functions
60
- //
61
- //--------------------------------------------------------------------------
62
- /**
63
- * Sort the solution items
64
- *
65
- * @param templates a list of item templates from the solution
66
- *
67
- * @returns a sorted list of solution items
68
- */
69
- function getInventoryItems(templates) {
70
- const hierarchy = getItemHierarchy(templates);
71
- const ids = hierarchy.reduce((prev, cur) => {
72
- prev.push(cur.id);
73
- return prev;
74
- }, []);
75
- return templates.reduce((prev, cur) => {
76
- if (ids.indexOf(cur.itemId) > -1) {
77
- const hierarchyItems = hierarchy.filter(hi => hi.id === cur.itemId);
78
- prev.push(_getItemFromTemplate(cur, templates, hierarchyItems[0].dependencies));
79
- }
80
- return prev;
81
- }, []);
42
+ /*! *****************************************************************************
43
+ Copyright (c) Microsoft Corporation.
44
+
45
+ Permission to use, copy, modify, and/or distribute this software for any
46
+ purpose with or without fee is hereby granted.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
49
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
50
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
51
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
52
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
53
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
54
+ PERFORMANCE OF THIS SOFTWARE.
55
+ ***************************************************************************** */
56
+
57
+ var __assign = function() {
58
+ __assign = Object.assign || function __assign(t) {
59
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
60
+ s = arguments[i];
61
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
62
+ }
63
+ return t;
64
+ };
65
+ return __assign.apply(this, arguments);
66
+ };
67
+
68
+ /* Copyright (c) 2017 Environmental Systems Research Institute, Inc.
69
+ * Apache-2.0 */
70
+ function fetchToken(url, requestOptions) {
71
+ var options = requestOptions;
72
+ // we generate a response, so we can't return the raw response
73
+ options.rawResponse = false;
74
+ return restHelpersGet.request(url, options).then(function (response) {
75
+ var r = {
76
+ token: response.access_token,
77
+ username: response.username,
78
+ expires: new Date(
79
+ // convert seconds in response to milliseconds and add the value to the current time to calculate a static expiration timestamp
80
+ Date.now() + (response.expires_in * 1000 - 1000)),
81
+ ssl: response.ssl === true
82
+ };
83
+ if (response.refresh_token) {
84
+ r.refreshToken = response.refresh_token;
85
+ }
86
+ return r;
87
+ });
82
88
  }
83
- /**
84
- * Create item hierarchy that will avoid issues from cylical dependencies
85
- *
86
- * @param templates a list of item templates from the solution
87
- *
88
- * @returns a hierarchy for item and item dependency display
89
- */
90
- function getItemHierarchy(templates) {
91
- const hierarchy = [];
92
- // Get the template specified by id out of a list of templates
93
- function getTemplateInSolution(templates, id) {
94
- const iTemplate = templates.findIndex((template) => id === template.itemId);
95
- return iTemplate >= 0 ? templates[iTemplate] : null;
96
- }
97
- // Hierarchically list the dependencies of specified node
98
- function traceItemId(id, accumulatedHierarchy, alreadyVisitedIds = []) {
99
- // Get the dependencies of the node
100
- const template = getTemplateInSolution(templates, id);
89
+
90
+ /* Copyright (c) 2017-2018 Environmental Systems Research Institute, Inc.
91
+ * Apache-2.0 */
92
+ function generateToken(url, requestOptions) {
93
+ var options = requestOptions;
101
94
  /* istanbul ignore else */
102
- if (template) {
103
- const templateEntry = {
104
- id,
105
- dependencies: []
106
- };
107
- // Visit each dependency, but only if this template is not in the alreadyVisitedIds list to avoid infinite loops
108
- /* istanbul ignore else */
109
- if (alreadyVisitedIds.indexOf(id) < 0) {
110
- // Add dependency to alreadyVisitedIds list
111
- alreadyVisitedIds.push(id);
112
- template.dependencies.forEach((dependencyId) => {
113
- // Remove dependency from list of templates to visit in the top-level loop
114
- const iDependencyTemplate = templateItemIds.indexOf(dependencyId);
115
- /* istanbul ignore else */
116
- if (iDependencyTemplate >= 0) {
117
- templateItemIds.splice(iDependencyTemplate, 1);
118
- }
119
- traceItemId(dependencyId, templateEntry.dependencies, alreadyVisitedIds);
120
- });
121
- }
122
- accumulatedHierarchy.push(templateEntry);
95
+ if (typeof window !== "undefined" &&
96
+ window.location &&
97
+ window.location.host) {
98
+ options.params.referer = window.location.host;
123
99
  }
124
- }
125
- // Start with top-level nodes and add in the rest of the nodes to catch cycles without top-level nodes
126
- let templateItemIds = _getTopLevelItemIds(templates);
127
- const otherItems = templates
128
- .filter((template) => templateItemIds.indexOf(template.itemId) < 0) // only keep non-top-level nodes
129
- .sort((a, b) => b.dependencies.length - a.dependencies.length); // sort so that nodes with more dependencies come first--reduces stubs
130
- templateItemIds = templateItemIds.concat(otherItems.map((template) => template.itemId));
131
- // Step through the list of nodes; we'll also remove nodes as we visit them
132
- let itemId = templateItemIds.shift();
133
- while (typeof itemId !== "undefined") {
134
- traceItemId(itemId, hierarchy);
135
- itemId = templateItemIds.shift();
136
- }
137
- return hierarchy;
100
+ else {
101
+ options.params.referer = restHelpersGet.NODEJS_DEFAULT_REFERER_HEADER;
102
+ }
103
+ return restHelpersGet.request(url, options);
138
104
  }
105
+
139
106
  /**
140
- * Explore the solution item templates for variables we will allow users to insert at runtime
141
- *
142
- * @param templates a list of item templates from the solution
143
- * @param translations nls translation object
144
- *
145
- * @returns a list of variables from the solution item templates
107
+ * Used to test if a URL is an ArcGIS Online URL
146
108
  */
147
- function getSolutionVariables(templates, translations) {
148
- const vars = [];
149
- templates.forEach(t => {
150
- const item = {
151
- id: t.itemId,
152
- title: t.item.title || t.item.name,
153
- type: t.type,
154
- value: undefined,
155
- dependencies: [{
156
- id: t.itemId,
157
- title: translations.itemId,
158
- value: `{{${t.itemId}.itemId}}`,
159
- }]
160
- };
161
- if (t.item.url) {
162
- item.dependencies.push({
163
- id: t.itemId,
164
- title: translations.url,
165
- value: `{{${t.itemId}.url}}`,
166
- });
109
+ var arcgisOnlineUrlRegex = /^https?:\/\/(\S+)\.arcgis\.com.+/;
110
+ function isOnline(url) {
111
+ return arcgisOnlineUrlRegex.test(url);
112
+ }
113
+ function normalizeOnlinePortalUrl(portalUrl) {
114
+ if (!arcgisOnlineUrlRegex.test(portalUrl)) {
115
+ return portalUrl;
167
116
  }
168
- if (t.type === "Feature Service") {
169
- // TODO need to set source service name var...
170
- // TODO need to set soure service shape field name "{{d05b3cf1ffcb4a4fa677627dfb18609e.name}}.Shape"
171
- item.dependencies.push({
172
- id: t.itemId,
173
- title: translations.solutionExtent,
174
- value: `{{${t.itemId}.solutionExtent}}`,
175
- });
176
- _addLayersOrTables(t.properties.layers || [], item, t, translations);
177
- _addLayersOrTables(t.properties.tables || [], item, t, translations);
117
+ switch (getOnlineEnvironment(portalUrl)) {
118
+ case "dev":
119
+ return "https://devext.arcgis.com/sharing/rest";
120
+ case "qa":
121
+ return "https://qaext.arcgis.com/sharing/rest";
122
+ default:
123
+ return "https://www.arcgis.com/sharing/rest";
178
124
  }
179
- vars.push(item);
180
- });
181
- return vars;
182
125
  }
126
+ function getOnlineEnvironment(url) {
127
+ if (!arcgisOnlineUrlRegex.test(url)) {
128
+ return null;
129
+ }
130
+ var match = url.match(arcgisOnlineUrlRegex);
131
+ var subdomain = match[1].split(".").pop();
132
+ if (subdomain.includes("dev")) {
133
+ return "dev";
134
+ }
135
+ if (subdomain.includes("qa")) {
136
+ return "qa";
137
+ }
138
+ return "production";
139
+ }
140
+ function isFederated(owningSystemUrl, portalUrl) {
141
+ var normalizedPortalUrl = restHelpersGet.cleanUrl(normalizeOnlinePortalUrl(portalUrl)).replace(/https?:\/\//, "");
142
+ var normalizedOwningSystemUrl = restHelpersGet.cleanUrl(owningSystemUrl).replace(/https?:\/\//, "");
143
+ return new RegExp(normalizedOwningSystemUrl, "i").test(normalizedPortalUrl);
144
+ }
145
+ function canUseOnlineToken(portalUrl, requestUrl) {
146
+ var portalIsOnline = isOnline(portalUrl);
147
+ var requestIsOnline = isOnline(requestUrl);
148
+ var portalEnv = getOnlineEnvironment(portalUrl);
149
+ var requestEnv = getOnlineEnvironment(requestUrl);
150
+ if (portalIsOnline && requestIsOnline && portalEnv === requestEnv) {
151
+ return true;
152
+ }
153
+ return false;
154
+ }
155
+
156
+ /* Copyright (c) 2018-2020 Environmental Systems Research Institute, Inc.
157
+ * Apache-2.0 */
183
158
  /**
184
- * Set key organization variables we will allow users to insert at runtime
159
+ * Validates that the user has access to the application
160
+ * and if they user should be presented a "View Only" mode
185
161
  *
186
- * @param translations nls translation object
162
+ * This is only needed/valid for Esri applications that are "licensed"
163
+ * and shipped in ArcGIS Online or ArcGIS Enterprise. Most custom applications
164
+ * should not need or use this.
187
165
  *
188
- * @returns a list of variables for the organization
189
- */
190
- function getOrganizationVariables(translations) {
191
- const orgVars = [{
192
- id: "",
193
- title: translations.geocodeUrl,
194
- value: "{{organization.helperServices.geocode:getDefaultLocatorURL}}"
195
- }, {
196
- id: "",
197
- title: translations.geometryUrl,
198
- value: "{{organization.helperServices.geometry.url}}"
199
- }, {
200
- id: "",
201
- title: translations.portalBaseUrl,
202
- value: "{{portalBaseUrl}}"
203
- }, {
204
- id: "",
205
- title: translations.routeUrl,
206
- value: "{{organization.helperServices.route.url}}"
207
- }, {
208
- id: "",
209
- title: translations.solutionItemExtent,
210
- value: "{{solutionItemExtent}}"
211
- }];
212
- return orgVars;
213
- }
214
- //--------------------------------------------------------------------------
215
- //
216
- // Private Functions
217
- //
218
- //--------------------------------------------------------------------------
219
- /**
220
- * Explore a solution item template for variables we will allow users to insert at runtime.
221
- * This function will update the item argument that is passed in with the var details.
222
- *
223
- * @param children a list of layers or tables from a template
224
- * @param item an object that store key details for a given variable
225
- * @param template one of the templates from the current solution
226
- * @param translations nls translations object
227
- *
228
- */
229
- function _addLayersOrTables(children, item, template, translations) {
230
- children.forEach(l => {
231
- const name = l.name && l.name.indexOf("||") > -1 ? l.name.split("||")[1].replace("}}", "").trim() : l.name;
232
- item.dependencies.push({
233
- id: template.itemId,
234
- title: `${name} (${translations.id})`,
235
- value: `{{${template.itemId}.layer${l.id}.id}}`,
236
- });
237
- item.dependencies.push({
238
- id: template.itemId,
239
- title: `${name} (${translations.name})`,
240
- value: `{{${template.itemId}.layer${l.id}.name||${name}}}`,
241
- });
242
- });
243
- }
244
- /**
245
- * Capture key details from the solution item template
246
- *
247
- * @param template one of the templates from the current solution
248
- * @param templates full list of templates
249
- * @param dependencies list of hierarchical dependencies
166
+ * ```js
167
+ * import { validateAppAccess } from '@esri/arcgis-rest-auth';
250
168
  *
251
- * @returns an IInventoryItem that is used by other components to work with this template
252
- */
253
- function _getItemFromTemplate(template, templates, dependencies) {
254
- return {
255
- id: template.itemId || "",
256
- title: template.item.title || "",
257
- dependencies: _getDependencies(dependencies, templates),
258
- type: template.item.type || "",
259
- typeKeywords: template.item.typeKeywords || [] /*,
260
- solutionItem: {
261
- itemId: template.itemId,
262
- itemDetails: _getItemDetails(template.item, template.type === "Group"),
263
- isResource: _getIsResource(template),
264
- data: template.data,
265
- properties: template.properties,
266
- type: template.type,
267
- groupDetails: _getGroupDetails(template, templates)
268
- }*/
269
- };
270
- }
271
- /**
272
- * Capture key details from the solution item template
169
+ * return validateAppAccess('your-token', 'theClientId')
170
+ * .then((result) => {
171
+ * if (!result.value) {
172
+ * // redirect or show some other ui
173
+ * } else {
174
+ * if (result.viewOnlyUserTypeApp) {
175
+ * // use this to inform your app to show a "View Only" mode
176
+ * }
177
+ * }
178
+ * })
179
+ * .catch((err) => {
180
+ * // two possible errors
181
+ * // invalid clientId: {"error":{"code":400,"messageCode":"GWM_0007","message":"Invalid request","details":[]}}
182
+ * // invalid token: {"error":{"code":498,"message":"Invalid token.","details":[]}}
183
+ * })
184
+ * ```
273
185
  *
274
- * @param dependencies list of dependencies from a template
275
- * @param templates full list of templates
186
+ * Note: This is only usable by Esri applications hosted on *arcgis.com, *esri.com or within
187
+ * an ArcGIS Enterprise installation. Custom applications can not use this.
276
188
  *
277
- * @returns a list of IInventoryItem that are used by other components to work with the templates
189
+ * @param token platform token
190
+ * @param clientId application client id
191
+ * @param portal Optional
278
192
  */
279
- function _getDependencies(dependencies, templates) {
280
- const dependencyItems = [];
281
- const depIds = dependencies.reduce((prev, cur) => {
282
- prev.push(cur.id);
283
- dependencyItems.push(cur);
284
- return prev;
285
- }, []);
286
- return templates.reduce((prev, curr) => {
287
- const i = depIds.indexOf(curr.itemId);
288
- if (i > -1) {
289
- prev.push(_getItemFromTemplate(curr, templates, dependencyItems[i].dependencies));
290
- }
291
- return prev;
292
- }, []);
193
+ function validateAppAccess(token, clientId, portal) {
194
+ if (portal === void 0) { portal = "https://www.arcgis.com/sharing/rest"; }
195
+ var url = portal + "/oauth2/validateAppAccess";
196
+ var ro = {
197
+ method: "POST",
198
+ params: {
199
+ f: "json",
200
+ client_id: clientId,
201
+ token: token,
202
+ },
203
+ };
204
+ return restHelpersGet.request(url, ro);
293
205
  }
294
- /**
295
- * Capture the key item details for a given template
296
- *
297
- * @param item the templates item
298
- * @param isGroup boolean to indicate if the item is a group
299
- * @param itemId the item id of the template
300
- *
301
- * @returns a IItemDetails object for the current item
302
- */
303
- /*
304
- function _getItemDetails(
305
- item: any,
306
- isGroup: boolean
307
- ): IItemDetails {
308
- return {
309
- title: item.title || "",
310
- snippet: item.snippet || "",
311
- description: item.description || "",
312
- tags: item.tags || [],
313
- accessInformation: !isGroup ? item.accessInformation || "" : "",
314
- licenseInfo: !isGroup ? item.licenseInfo || "" : ""
315
- };
206
+
207
+ /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
208
+ * Apache-2.0 */
209
+ function defer() {
210
+ var deferred = {
211
+ promise: null,
212
+ resolve: null,
213
+ reject: null,
214
+ };
215
+ deferred.promise = new Promise(function (resolve, reject) {
216
+ deferred.resolve = resolve;
217
+ deferred.reject = reject;
218
+ });
219
+ return deferred;
316
220
  }
317
- */
318
221
  /**
319
- * Capture the key item details for a given group template
320
- *
321
- * @param template one of the templates from the current solution
322
- * @param templates full list of templates
323
- *
324
- * @returns a list of IItemShare objects
222
+ * ```js
223
+ * import { UserSession } from '@esri/arcgis-rest-auth';
224
+ * UserSession.beginOAuth2({
225
+ * // register an app of your own to create a unique clientId
226
+ * clientId: "abc123",
227
+ * redirectUri: 'https://yourapp.com/authenticate.html'
228
+ * })
229
+ * .then(session)
230
+ * // or
231
+ * new UserSession({
232
+ * username: "jsmith",
233
+ * password: "123456"
234
+ * })
235
+ * // or
236
+ * UserSession.deserialize(cache)
237
+ * ```
238
+ * Used to authenticate both ArcGIS Online and ArcGIS Enterprise users. `UserSession` includes helper methods for [OAuth 2.0](/arcgis-rest-js/guides/browser-authentication/) in both browser and server applications.
325
239
  */
326
- /*
327
- function _getGroupDetails(
328
- template: any,
329
- templates: any[]
330
- ): IItemShare[] {
331
- return template.type === "Group" ? templates.reduce((prev, cur) => {
332
- if (cur.itemId !== template.itemId && cur.type !== "Group") {
333
- prev.push({
334
- id: cur.itemId,
335
- title: cur.item.name || cur.item.title,
336
- isShared: (cur.groups || []).indexOf(template.itemId) > -1,
337
- shareItem: (cur.groups || []).indexOf(template.itemId) > -1,
338
- type: cur.type,
339
- typeKeywords: cur.item.typeKeywords
340
- });
341
- }
342
- return prev;
343
- }, []) : [];
344
- }
345
- */
346
- /**
347
- * Used to understand if we are dealing with a binary object that will support upload/download
348
- *
349
- * @param template one of the templates from the current solution
350
- *
351
- * @returns true if this item supports upload/download
352
- */
353
- /*
354
- function _getIsResource(
355
- template: any
356
- ): boolean {
357
- return template.type !== "Group" && template.resources.some(r => r.indexOf("_info_thumbnail") < 0) &&
358
- (template.data === null || JSON.stringify(template.data) === "{}");
359
- }
360
- */
361
- /**
362
- * Sort the template ids based on their dependencies
363
- *
364
- * @param templates full list of templates
365
- *
366
- * @returns a list of Itop level item ids
367
- */
368
- function _getTopLevelItemIds(templates) {
369
- // Find the top-level nodes. Start with all nodes, then remove those that other nodes depend on
370
- const topLevelItemCandidateIds = templates.map((template) => template.itemId);
371
- templates.forEach((template) => {
372
- (template.dependencies || []).forEach((dependencyId) => {
373
- const iNode = topLevelItemCandidateIds.indexOf(dependencyId);
374
- if (iNode >= 0) {
375
- // Node is somebody's dependency, so remove the node from the list of top-level nodes
376
- // If iNode == -1, then it's a shared dependency and it has already been removed
377
- topLevelItemCandidateIds.splice(iNode, 1);
378
- }
379
- });
380
- });
381
- return topLevelItemCandidateIds;
382
- }
383
-
384
- /*! *****************************************************************************
385
- Copyright (c) Microsoft Corporation.
386
-
387
- Permission to use, copy, modify, and/or distribute this software for any
388
- purpose with or without fee is hereby granted.
389
-
390
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
391
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
392
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
393
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
394
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
395
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
396
- PERFORMANCE OF THIS SOFTWARE.
397
- ***************************************************************************** */
398
-
399
- var __assign = function() {
400
- __assign = Object.assign || function __assign(t) {
401
- for (var s, i = 1, n = arguments.length; i < n; i++) {
402
- s = arguments[i];
403
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
404
- }
405
- return t;
406
- };
407
- return __assign.apply(this, arguments);
408
- };
409
-
410
- /* Copyright (c) 2017 Environmental Systems Research Institute, Inc.
411
- * Apache-2.0 */
412
- function fetchToken(url, requestOptions) {
413
- var options = requestOptions;
414
- // we generate a response, so we can't return the raw response
415
- options.rawResponse = false;
416
- return cleanUrl.request(url, options).then(function (response) {
417
- var r = {
418
- token: response.access_token,
419
- username: response.username,
420
- expires: new Date(
421
- // convert seconds in response to milliseconds and add the value to the current time to calculate a static expiration timestamp
422
- Date.now() + (response.expires_in * 1000 - 1000)),
423
- ssl: response.ssl === true
424
- };
425
- if (response.refresh_token) {
426
- r.refreshToken = response.refresh_token;
427
- }
428
- return r;
429
- });
430
- }
431
-
432
- /* Copyright (c) 2017-2018 Environmental Systems Research Institute, Inc.
433
- * Apache-2.0 */
434
- function generateToken(url, requestOptions) {
435
- var options = requestOptions;
436
- /* istanbul ignore else */
437
- if (typeof window !== "undefined" &&
438
- window.location &&
439
- window.location.host) {
440
- options.params.referer = window.location.host;
441
- }
442
- else {
443
- options.params.referer = cleanUrl.NODEJS_DEFAULT_REFERER_HEADER;
444
- }
445
- return cleanUrl.request(url, options);
446
- }
447
-
448
- /**
449
- * Used to test if a URL is an ArcGIS Online URL
450
- */
451
- var arcgisOnlineUrlRegex = /^https?:\/\/(\S+)\.arcgis\.com.+/;
452
- function isOnline(url) {
453
- return arcgisOnlineUrlRegex.test(url);
454
- }
455
- function normalizeOnlinePortalUrl(portalUrl) {
456
- if (!arcgisOnlineUrlRegex.test(portalUrl)) {
457
- return portalUrl;
458
- }
459
- switch (getOnlineEnvironment(portalUrl)) {
460
- case "dev":
461
- return "https://devext.arcgis.com/sharing/rest";
462
- case "qa":
463
- return "https://qaext.arcgis.com/sharing/rest";
464
- default:
465
- return "https://www.arcgis.com/sharing/rest";
466
- }
467
- }
468
- function getOnlineEnvironment(url) {
469
- if (!arcgisOnlineUrlRegex.test(url)) {
470
- return null;
471
- }
472
- var match = url.match(arcgisOnlineUrlRegex);
473
- var subdomain = match[1].split(".").pop();
474
- if (subdomain.includes("dev")) {
475
- return "dev";
476
- }
477
- if (subdomain.includes("qa")) {
478
- return "qa";
479
- }
480
- return "production";
481
- }
482
- function isFederated(owningSystemUrl, portalUrl) {
483
- var normalizedPortalUrl = cleanUrl.cleanUrl(normalizeOnlinePortalUrl(portalUrl)).replace(/https?:\/\//, "");
484
- var normalizedOwningSystemUrl = cleanUrl.cleanUrl(owningSystemUrl).replace(/https?:\/\//, "");
485
- return new RegExp(normalizedOwningSystemUrl, "i").test(normalizedPortalUrl);
486
- }
487
- function canUseOnlineToken(portalUrl, requestUrl) {
488
- var portalIsOnline = isOnline(portalUrl);
489
- var requestIsOnline = isOnline(requestUrl);
490
- var portalEnv = getOnlineEnvironment(portalUrl);
491
- var requestEnv = getOnlineEnvironment(requestUrl);
492
- if (portalIsOnline && requestIsOnline && portalEnv === requestEnv) {
493
- return true;
494
- }
495
- return false;
496
- }
497
-
498
- /* Copyright (c) 2018-2020 Environmental Systems Research Institute, Inc.
499
- * Apache-2.0 */
500
- /**
501
- * Validates that the user has access to the application
502
- * and if they user should be presented a "View Only" mode
503
- *
504
- * This is only needed/valid for Esri applications that are "licensed"
505
- * and shipped in ArcGIS Online or ArcGIS Enterprise. Most custom applications
506
- * should not need or use this.
507
- *
508
- * ```js
509
- * import { validateAppAccess } from '@esri/arcgis-rest-auth';
510
- *
511
- * return validateAppAccess('your-token', 'theClientId')
512
- * .then((result) => {
513
- * if (!result.value) {
514
- * // redirect or show some other ui
515
- * } else {
516
- * if (result.viewOnlyUserTypeApp) {
517
- * // use this to inform your app to show a "View Only" mode
518
- * }
519
- * }
520
- * })
521
- * .catch((err) => {
522
- * // two possible errors
523
- * // invalid clientId: {"error":{"code":400,"messageCode":"GWM_0007","message":"Invalid request","details":[]}}
524
- * // invalid token: {"error":{"code":498,"message":"Invalid token.","details":[]}}
525
- * })
526
- * ```
527
- *
528
- * Note: This is only usable by Esri applications hosted on *arcgis.com, *esri.com or within
529
- * an ArcGIS Enterprise installation. Custom applications can not use this.
530
- *
531
- * @param token platform token
532
- * @param clientId application client id
533
- * @param portal Optional
534
- */
535
- function validateAppAccess(token, clientId, portal) {
536
- if (portal === void 0) { portal = "https://www.arcgis.com/sharing/rest"; }
537
- var url = portal + "/oauth2/validateAppAccess";
538
- var ro = {
539
- method: "POST",
540
- params: {
541
- f: "json",
542
- client_id: clientId,
543
- token: token,
544
- },
545
- };
546
- return cleanUrl.request(url, ro);
547
- }
548
-
549
- /* Copyright (c) 2017-2019 Environmental Systems Research Institute, Inc.
550
- * Apache-2.0 */
551
- function defer() {
552
- var deferred = {
553
- promise: null,
554
- resolve: null,
555
- reject: null,
556
- };
557
- deferred.promise = new Promise(function (resolve, reject) {
558
- deferred.resolve = resolve;
559
- deferred.reject = reject;
560
- });
561
- return deferred;
562
- }
563
- /**
564
- * ```js
565
- * import { UserSession } from '@esri/arcgis-rest-auth';
566
- * UserSession.beginOAuth2({
567
- * // register an app of your own to create a unique clientId
568
- * clientId: "abc123",
569
- * redirectUri: 'https://yourapp.com/authenticate.html'
570
- * })
571
- * .then(session)
572
- * // or
573
- * new UserSession({
574
- * username: "jsmith",
575
- * password: "123456"
576
- * })
577
- * // or
578
- * UserSession.deserialize(cache)
579
- * ```
580
- * Used to authenticate both ArcGIS Online and ArcGIS Enterprise users. `UserSession` includes helper methods for [OAuth 2.0](/arcgis-rest-js/guides/browser-authentication/) in both browser and server applications.
581
- */
582
- var UserSession = /** @class */ (function () {
583
- function UserSession(options) {
584
- this.clientId = options.clientId;
585
- this._refreshToken = options.refreshToken;
586
- this._refreshTokenExpires = options.refreshTokenExpires;
587
- this.username = options.username;
588
- this.password = options.password;
589
- this._token = options.token;
590
- this._tokenExpires = options.tokenExpires;
591
- this.portal = options.portal
592
- ? cleanUrl.cleanUrl(options.portal)
593
- : "https://www.arcgis.com/sharing/rest";
594
- this.ssl = options.ssl;
595
- this.provider = options.provider || "arcgis";
596
- this.tokenDuration = options.tokenDuration || 20160;
597
- this.redirectUri = options.redirectUri;
598
- this.refreshTokenTTL = options.refreshTokenTTL || 20160;
599
- this.server = options.server;
600
- this.federatedServers = {};
601
- this.trustedDomains = [];
602
- // if a non-federated server was passed explicitly, it should be trusted.
603
- if (options.server) {
604
- // if the url includes more than '/arcgis/', trim the rest
605
- var root = this.getServerRootUrl(options.server);
606
- this.federatedServers[root] = {
607
- token: options.token,
608
- expires: options.tokenExpires,
609
- };
610
- }
611
- this._pendingTokenRequests = {};
240
+ var UserSession = /** @class */ (function () {
241
+ function UserSession(options) {
242
+ this.clientId = options.clientId;
243
+ this._refreshToken = options.refreshToken;
244
+ this._refreshTokenExpires = options.refreshTokenExpires;
245
+ this.username = options.username;
246
+ this.password = options.password;
247
+ this._token = options.token;
248
+ this._tokenExpires = options.tokenExpires;
249
+ this.portal = options.portal
250
+ ? restHelpersGet.cleanUrl(options.portal)
251
+ : "https://www.arcgis.com/sharing/rest";
252
+ this.ssl = options.ssl;
253
+ this.provider = options.provider || "arcgis";
254
+ this.tokenDuration = options.tokenDuration || 20160;
255
+ this.redirectUri = options.redirectUri;
256
+ this.refreshTokenTTL = options.refreshTokenTTL || 20160;
257
+ this.server = options.server;
258
+ this.federatedServers = {};
259
+ this.trustedDomains = [];
260
+ // if a non-federated server was passed explicitly, it should be trusted.
261
+ if (options.server) {
262
+ // if the url includes more than '/arcgis/', trim the rest
263
+ var root = this.getServerRootUrl(options.server);
264
+ this.federatedServers[root] = {
265
+ token: options.token,
266
+ expires: options.tokenExpires,
267
+ };
268
+ }
269
+ this._pendingTokenRequests = {};
612
270
  }
613
271
  Object.defineProperty(UserSession.prototype, "token", {
614
272
  /**
@@ -695,7 +353,7 @@ var UserSession = /** @class */ (function () {
695
353
  }
696
354
  // append additional params
697
355
  if (params) {
698
- url = url + "&" + cleanUrl.encodeQueryString(params);
356
+ url = url + "&" + restHelpersGet.encodeQueryString(params);
699
357
  }
700
358
  if (!popup) {
701
359
  win.location.href = url;
@@ -705,7 +363,7 @@ var UserSession = /** @class */ (function () {
705
363
  win["__ESRI_REST_AUTH_HANDLER_" + clientId] = function (errorString, oauthInfoString) {
706
364
  if (errorString) {
707
365
  var error = JSON.parse(errorString);
708
- session.reject(new cleanUrl.ArcGISAuthError(error.errorMessage, error.error));
366
+ session.reject(new restHelpersGet.ArcGISAuthError(error.errorMessage, error.error));
709
367
  return;
710
368
  }
711
369
  if (oauthInfoString) {
@@ -765,10 +423,10 @@ var UserSession = /** @class */ (function () {
765
423
  }
766
424
  }
767
425
  catch (e) {
768
- throw new cleanUrl.ArcGISAuthError("Unable to complete authentication. It's possible you specified popup based oAuth2 but no handler from \"beginOAuth2()\" present. This generally happens because the \"popup\" option differs between \"beginOAuth2()\" and \"completeOAuth2()\".");
426
+ throw new restHelpersGet.ArcGISAuthError("Unable to complete authentication. It's possible you specified popup based oAuth2 but no handler from \"beginOAuth2()\" present. This generally happens because the \"popup\" option differs between \"beginOAuth2()\" and \"completeOAuth2()\".");
769
427
  }
770
428
  if (error) {
771
- throw new cleanUrl.ArcGISAuthError(error.errorMessage, error.error);
429
+ throw new restHelpersGet.ArcGISAuthError(error.errorMessage, error.error);
772
430
  }
773
431
  return new UserSession({
774
432
  clientId: clientId,
@@ -999,7 +657,7 @@ var UserSession = /** @class */ (function () {
999
657
  else {
1000
658
  var url = this.portal + "/community/self";
1001
659
  var options = __assign(__assign({ httpMethod: "GET", authentication: this }, requestOptions), { rawResponse: false });
1002
- this._pendingUserRequest = cleanUrl.request(url, options).then(function (response) {
660
+ this._pendingUserRequest = restHelpersGet.request(url, options).then(function (response) {
1003
661
  _this._user = response;
1004
662
  _this._pendingUserRequest = null;
1005
663
  return response;
@@ -1031,7 +689,7 @@ var UserSession = /** @class */ (function () {
1031
689
  else {
1032
690
  var url = this.portal + "/portals/self";
1033
691
  var options = __assign(__assign({ httpMethod: "GET", authentication: this }, requestOptions), { rawResponse: false });
1034
- this._pendingPortalRequest = cleanUrl.request(url, options).then(function (response) {
692
+ this._pendingPortalRequest = restHelpersGet.request(url, options).then(function (response) {
1035
693
  _this._portalInfo = response;
1036
694
  _this._pendingPortalRequest = null;
1037
695
  return response;
@@ -1151,7 +809,7 @@ var UserSession = /** @class */ (function () {
1151
809
  if (this.clientId && this.refreshToken) {
1152
810
  return this.refreshWithRefreshToken();
1153
811
  }
1154
- return Promise.reject(new cleanUrl.ArcGISAuthError("Unable to refresh token."));
812
+ return Promise.reject(new restHelpersGet.ArcGISAuthError("Unable to refresh token."));
1155
813
  };
1156
814
  /**
1157
815
  * Determines the root of the ArcGIS Server or Portal for a given URL.
@@ -1159,7 +817,7 @@ var UserSession = /** @class */ (function () {
1159
817
  * @param url the URl to determine the root url for.
1160
818
  */
1161
819
  UserSession.prototype.getServerRootUrl = function (url) {
1162
- var root = cleanUrl.cleanUrl(url).split(/\/rest(\/admin)?\/services(?:\/|#|\?|$)/)[0];
820
+ var root = restHelpersGet.cleanUrl(url).split(/\/rest(\/admin)?\/services(?:\/|#|\?|$)/)[0];
1163
821
  var _a = root.match(/(https?:\/\/)(.+)/), protocol = _a[1], domainAndPath = _a[2];
1164
822
  var _b = domainAndPath.split("/"), domain = _b[0], path = _b.slice(1);
1165
823
  // only the domain is lowercased because in some cases an org id might be
@@ -1250,7 +908,7 @@ var UserSession = /** @class */ (function () {
1250
908
  return this._pendingTokenRequests[root];
1251
909
  }
1252
910
  this._pendingTokenRequests[root] = this.fetchAuthorizedDomains().then(function () {
1253
- return cleanUrl.request(root + "/rest/info", {
911
+ return restHelpersGet.request(root + "/rest/info", {
1254
912
  credentials: _this.getDomainCredentials(url),
1255
913
  })
1256
914
  .then(function (response) {
@@ -1261,13 +919,13 @@ var UserSession = /** @class */ (function () {
1261
919
  * be able to generate a token
1262
920
  */
1263
921
  if (!isFederated(response.owningSystemUrl, _this.portal)) {
1264
- throw new cleanUrl.ArcGISAuthError(url + " is not federated with " + _this.portal + ".", "NOT_FEDERATED");
922
+ throw new restHelpersGet.ArcGISAuthError(url + " is not federated with " + _this.portal + ".", "NOT_FEDERATED");
1265
923
  }
1266
924
  else {
1267
925
  /**
1268
926
  * if the server is federated, use the relevant token endpoint.
1269
927
  */
1270
- return cleanUrl.request(response.owningSystemUrl + "/sharing/rest/info", requestOptions);
928
+ return restHelpersGet.request(response.owningSystemUrl + "/sharing/rest/info", requestOptions);
1271
929
  }
1272
930
  }
1273
931
  else if (response.authInfo &&
@@ -1281,7 +939,7 @@ var UserSession = /** @class */ (function () {
1281
939
  });
1282
940
  }
1283
941
  else {
1284
- throw new cleanUrl.ArcGISAuthError(url + " is not federated with any portal and is not explicitly trusted.", "NOT_FEDERATED");
942
+ throw new restHelpersGet.ArcGISAuthError(url + " is not federated with any portal and is not explicitly trusted.", "NOT_FEDERATED");
1285
943
  }
1286
944
  })
1287
945
  .then(function (response) {
@@ -1442,6 +1100,348 @@ var UserSession = /** @class */ (function () {
1442
1100
  return UserSession;
1443
1101
  }());
1444
1102
 
1103
+ /** @license
1104
+ * Copyright 2022 Esri
1105
+ *
1106
+ * Licensed under the Apache License, Version 2.0 (the "License");
1107
+ * you may not use this file except in compliance with the License.
1108
+ * You may obtain a copy of the License at
1109
+ *
1110
+ * http://www.apache.org/licenses/LICENSE-2.0
1111
+ *
1112
+ * Unless required by applicable law or agreed to in writing, software
1113
+ * distributed under the License is distributed on an "AS IS" BASIS,
1114
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1115
+ * See the License for the specific language governing permissions and
1116
+ * limitations under the License.
1117
+ */
1118
+ //--------------------------------------------------------------------------
1119
+ //
1120
+ // Public Functions
1121
+ //
1122
+ //--------------------------------------------------------------------------
1123
+ /**
1124
+ * Sort the solution items
1125
+ *
1126
+ * @param templates a list of item templates from the solution
1127
+ *
1128
+ * @returns a sorted list of solution items
1129
+ */
1130
+ function getInventoryItems(templates) {
1131
+ const hierarchy = getItemHierarchy(templates);
1132
+ const ids = hierarchy.reduce((prev, cur) => {
1133
+ prev.push(cur.id);
1134
+ return prev;
1135
+ }, []);
1136
+ return templates.reduce((prev, cur) => {
1137
+ if (ids.indexOf(cur.itemId) > -1) {
1138
+ const hierarchyItems = hierarchy.filter(hi => hi.id === cur.itemId);
1139
+ prev.push(_getItemFromTemplate(cur, templates, hierarchyItems[0].dependencies));
1140
+ }
1141
+ return prev;
1142
+ }, []);
1143
+ }
1144
+ /**
1145
+ * Create item hierarchy that will avoid issues from cylical dependencies
1146
+ *
1147
+ * @param templates a list of item templates from the solution
1148
+ *
1149
+ * @returns a hierarchy for item and item dependency display
1150
+ */
1151
+ function getItemHierarchy(templates) {
1152
+ const hierarchy = [];
1153
+ // Get the template specified by id out of a list of templates
1154
+ function getTemplateInSolution(templates, id) {
1155
+ const iTemplate = templates.findIndex((template) => id === template.itemId);
1156
+ return iTemplate >= 0 ? templates[iTemplate] : null;
1157
+ }
1158
+ // Hierarchically list the dependencies of specified node
1159
+ function traceItemId(id, accumulatedHierarchy, alreadyVisitedIds = []) {
1160
+ // Get the dependencies of the node
1161
+ const template = getTemplateInSolution(templates, id);
1162
+ /* istanbul ignore else */
1163
+ if (template) {
1164
+ const templateEntry = {
1165
+ id,
1166
+ dependencies: []
1167
+ };
1168
+ // Visit each dependency, but only if this template is not in the alreadyVisitedIds list to avoid infinite loops
1169
+ /* istanbul ignore else */
1170
+ if (alreadyVisitedIds.indexOf(id) < 0) {
1171
+ // Add dependency to alreadyVisitedIds list
1172
+ alreadyVisitedIds.push(id);
1173
+ template.dependencies.forEach((dependencyId) => {
1174
+ // Remove dependency from list of templates to visit in the top-level loop
1175
+ const iDependencyTemplate = templateItemIds.indexOf(dependencyId);
1176
+ /* istanbul ignore else */
1177
+ if (iDependencyTemplate >= 0) {
1178
+ templateItemIds.splice(iDependencyTemplate, 1);
1179
+ }
1180
+ traceItemId(dependencyId, templateEntry.dependencies, alreadyVisitedIds);
1181
+ });
1182
+ }
1183
+ accumulatedHierarchy.push(templateEntry);
1184
+ }
1185
+ }
1186
+ // Start with top-level nodes and add in the rest of the nodes to catch cycles without top-level nodes
1187
+ let templateItemIds = _getTopLevelItemIds(templates);
1188
+ const otherItems = templates
1189
+ .filter((template) => templateItemIds.indexOf(template.itemId) < 0) // only keep non-top-level nodes
1190
+ .sort((a, b) => b.dependencies.length - a.dependencies.length); // sort so that nodes with more dependencies come first--reduces stubs
1191
+ templateItemIds = templateItemIds.concat(otherItems.map((template) => template.itemId));
1192
+ // Step through the list of nodes; we'll also remove nodes as we visit them
1193
+ let itemId = templateItemIds.shift();
1194
+ while (typeof itemId !== "undefined") {
1195
+ traceItemId(itemId, hierarchy);
1196
+ itemId = templateItemIds.shift();
1197
+ }
1198
+ return hierarchy;
1199
+ }
1200
+ /**
1201
+ * Explore the solution item templates for variables we will allow users to insert at runtime
1202
+ *
1203
+ * @param templates a list of item templates from the solution
1204
+ * @param translations nls translation object
1205
+ *
1206
+ * @returns a list of variables from the solution item templates
1207
+ */
1208
+ function getSolutionVariables(templates, translations) {
1209
+ const vars = [];
1210
+ templates.forEach(t => {
1211
+ const item = {
1212
+ id: t.itemId,
1213
+ title: t.item.title || t.item.name,
1214
+ type: t.type,
1215
+ value: undefined,
1216
+ dependencies: [{
1217
+ id: t.itemId,
1218
+ title: translations.itemId,
1219
+ value: `{{${t.itemId}.itemId}}`,
1220
+ }]
1221
+ };
1222
+ if (t.item.url) {
1223
+ item.dependencies.push({
1224
+ id: t.itemId,
1225
+ title: translations.url,
1226
+ value: `{{${t.itemId}.url}}`,
1227
+ });
1228
+ }
1229
+ if (t.type === "Feature Service") {
1230
+ // TODO need to set source service name var...
1231
+ // TODO need to set soure service shape field name "{{d05b3cf1ffcb4a4fa677627dfb18609e.name}}.Shape"
1232
+ item.dependencies.push({
1233
+ id: t.itemId,
1234
+ title: translations.solutionExtent,
1235
+ value: `{{${t.itemId}.solutionExtent}}`,
1236
+ });
1237
+ _addLayersOrTables(t.properties.layers || [], item, t, translations);
1238
+ _addLayersOrTables(t.properties.tables || [], item, t, translations);
1239
+ }
1240
+ vars.push(item);
1241
+ });
1242
+ return vars;
1243
+ }
1244
+ /**
1245
+ * Set key organization variables we will allow users to insert at runtime
1246
+ *
1247
+ * @param translations nls translation object
1248
+ *
1249
+ * @returns a list of variables for the organization
1250
+ */
1251
+ function getOrganizationVariables(translations) {
1252
+ const orgVars = [{
1253
+ id: "",
1254
+ title: translations.geocodeUrl,
1255
+ value: "{{organization.helperServices.geocode:getDefaultLocatorURL}}"
1256
+ }, {
1257
+ id: "",
1258
+ title: translations.geometryUrl,
1259
+ value: "{{organization.helperServices.geometry.url}}"
1260
+ }, {
1261
+ id: "",
1262
+ title: translations.portalBaseUrl,
1263
+ value: "{{portalBaseUrl}}"
1264
+ }, {
1265
+ id: "",
1266
+ title: translations.routeUrl,
1267
+ value: "{{organization.helperServices.route.url}}"
1268
+ }, {
1269
+ id: "",
1270
+ title: translations.solutionItemExtent,
1271
+ value: "{{solutionItemExtent}}"
1272
+ }];
1273
+ return orgVars;
1274
+ }
1275
+ //--------------------------------------------------------------------------
1276
+ //
1277
+ // Private Functions
1278
+ //
1279
+ //--------------------------------------------------------------------------
1280
+ /**
1281
+ * Explore a solution item template for variables we will allow users to insert at runtime.
1282
+ * This function will update the item argument that is passed in with the var details.
1283
+ *
1284
+ * @param children a list of layers or tables from a template
1285
+ * @param item an object that store key details for a given variable
1286
+ * @param template one of the templates from the current solution
1287
+ * @param translations nls translations object
1288
+ *
1289
+ */
1290
+ function _addLayersOrTables(children, item, template, translations) {
1291
+ children.forEach(l => {
1292
+ const name = l.name && l.name.indexOf("||") > -1 ? l.name.split("||")[1].replace("}}", "").trim() : l.name;
1293
+ item.dependencies.push({
1294
+ id: template.itemId,
1295
+ title: `${name} (${translations.id})`,
1296
+ value: `{{${template.itemId}.layer${l.id}.id}}`,
1297
+ });
1298
+ item.dependencies.push({
1299
+ id: template.itemId,
1300
+ title: `${name} (${translations.name})`,
1301
+ value: `{{${template.itemId}.layer${l.id}.name||${name}}}`,
1302
+ });
1303
+ });
1304
+ }
1305
+ /**
1306
+ * Capture key details from the solution item template
1307
+ *
1308
+ * @param template one of the templates from the current solution
1309
+ * @param templates full list of templates
1310
+ * @param dependencies list of hierarchical dependencies
1311
+ *
1312
+ * @returns an IInventoryItem that is used by other components to work with this template
1313
+ */
1314
+ function _getItemFromTemplate(template, templates, dependencies) {
1315
+ return {
1316
+ id: template.itemId || "",
1317
+ title: template.item.title || "",
1318
+ dependencies: _getDependencies(dependencies, templates),
1319
+ type: template.item.type || "",
1320
+ typeKeywords: template.item.typeKeywords || [] /*,
1321
+ solutionItem: {
1322
+ itemId: template.itemId,
1323
+ itemDetails: _getItemDetails(template.item, template.type === "Group"),
1324
+ isResource: _getIsResource(template),
1325
+ data: template.data,
1326
+ properties: template.properties,
1327
+ type: template.type,
1328
+ groupDetails: _getGroupDetails(template, templates)
1329
+ }*/
1330
+ };
1331
+ }
1332
+ /**
1333
+ * Capture key details from the solution item template
1334
+ *
1335
+ * @param dependencies list of dependencies from a template
1336
+ * @param templates full list of templates
1337
+ *
1338
+ * @returns a list of IInventoryItem that are used by other components to work with the templates
1339
+ */
1340
+ function _getDependencies(dependencies, templates) {
1341
+ const dependencyItems = [];
1342
+ const depIds = dependencies.reduce((prev, cur) => {
1343
+ prev.push(cur.id);
1344
+ dependencyItems.push(cur);
1345
+ return prev;
1346
+ }, []);
1347
+ return templates.reduce((prev, curr) => {
1348
+ const i = depIds.indexOf(curr.itemId);
1349
+ if (i > -1) {
1350
+ prev.push(_getItemFromTemplate(curr, templates, dependencyItems[i].dependencies));
1351
+ }
1352
+ return prev;
1353
+ }, []);
1354
+ }
1355
+ /**
1356
+ * Capture the key item details for a given template
1357
+ *
1358
+ * @param item the templates item
1359
+ * @param isGroup boolean to indicate if the item is a group
1360
+ * @param itemId the item id of the template
1361
+ *
1362
+ * @returns a IItemDetails object for the current item
1363
+ */
1364
+ /*
1365
+ function _getItemDetails(
1366
+ item: any,
1367
+ isGroup: boolean
1368
+ ): IItemDetails {
1369
+ return {
1370
+ title: item.title || "",
1371
+ snippet: item.snippet || "",
1372
+ description: item.description || "",
1373
+ tags: item.tags || [],
1374
+ accessInformation: !isGroup ? item.accessInformation || "" : "",
1375
+ licenseInfo: !isGroup ? item.licenseInfo || "" : ""
1376
+ };
1377
+ }
1378
+ */
1379
+ /**
1380
+ * Capture the key item details for a given group template
1381
+ *
1382
+ * @param template one of the templates from the current solution
1383
+ * @param templates full list of templates
1384
+ *
1385
+ * @returns a list of IItemShare objects
1386
+ */
1387
+ /*
1388
+ function _getGroupDetails(
1389
+ template: any,
1390
+ templates: any[]
1391
+ ): IItemShare[] {
1392
+ return template.type === "Group" ? templates.reduce((prev, cur) => {
1393
+ if (cur.itemId !== template.itemId && cur.type !== "Group") {
1394
+ prev.push({
1395
+ id: cur.itemId,
1396
+ title: cur.item.name || cur.item.title,
1397
+ isShared: (cur.groups || []).indexOf(template.itemId) > -1,
1398
+ shareItem: (cur.groups || []).indexOf(template.itemId) > -1,
1399
+ type: cur.type,
1400
+ typeKeywords: cur.item.typeKeywords
1401
+ });
1402
+ }
1403
+ return prev;
1404
+ }, []) : [];
1405
+ }
1406
+ */
1407
+ /**
1408
+ * Used to understand if we are dealing with a binary object that will support upload/download
1409
+ *
1410
+ * @param template one of the templates from the current solution
1411
+ *
1412
+ * @returns true if this item supports upload/download
1413
+ */
1414
+ /*
1415
+ function _getIsResource(
1416
+ template: any
1417
+ ): boolean {
1418
+ return template.type !== "Group" && template.resources.some(r => r.indexOf("_info_thumbnail") < 0) &&
1419
+ (template.data === null || JSON.stringify(template.data) === "{}");
1420
+ }
1421
+ */
1422
+ /**
1423
+ * Sort the template ids based on their dependencies
1424
+ *
1425
+ * @param templates full list of templates
1426
+ *
1427
+ * @returns a list of Itop level item ids
1428
+ */
1429
+ function _getTopLevelItemIds(templates) {
1430
+ // Find the top-level nodes. Start with all nodes, then remove those that other nodes depend on
1431
+ const topLevelItemCandidateIds = templates.map((template) => template.itemId);
1432
+ templates.forEach((template) => {
1433
+ (template.dependencies || []).forEach((dependencyId) => {
1434
+ const iNode = topLevelItemCandidateIds.indexOf(dependencyId);
1435
+ if (iNode >= 0) {
1436
+ // Node is somebody's dependency, so remove the node from the list of top-level nodes
1437
+ // If iNode == -1, then it's a shared dependency and it has already been removed
1438
+ topLevelItemCandidateIds.splice(iNode, 1);
1439
+ }
1440
+ });
1441
+ });
1442
+ return topLevelItemCandidateIds;
1443
+ }
1444
+
1445
1445
  const solutionConfigurationCss = ".configuration-container{position:relative;height:100%;width:100%}.configuration{position:absolute;top:0px;right:0px;bottom:0px;left:0px;display:flex;padding:0.5rem;border:1px #808080 solid}.config-tabs{width:100%}.config-tab{width:100%}.config-solution{position:absolute;top:3.5rem;right:-1px;bottom:-1px;left:-1px;display:flex;padding:0.5rem}.config-inventory{display:inline;max-width:-moz-min-content;max-width:min-content;flex-grow:0;overflow-y:auto}.config-inventory-hide{display:none;max-width:-moz-min-content;max-width:min-content;flex-grow:0;overflow-y:auto}.config-item{position:relative;display:inline;flex-grow:1;overflow-y:auto;margin-inline-start:0.5rem}solution-contents{position:relative;height:100%}solution-item{position:relative;height:100%}solution-spatial-ref{position:relative;height:100%;width:100%;overflow-y:auto}";
1446
1446
 
1447
1447
  const SolutionConfiguration = class {
@@ -1500,7 +1500,7 @@ const SolutionConfiguration = class {
1500
1500
  * Renders the component.
1501
1501
  */
1502
1502
  render() {
1503
- const wkid = solutionStore.getProp(solutionStore.state.getStoreInfo("spatialReferenceInfo"), "spatialReference");
1503
+ const wkid = restHelpersGet.getProp(solutionStore.state.getStoreInfo("spatialReferenceInfo"), "spatialReference");
1504
1504
  const hasServices = solutionStore.state.getStoreInfo("featureServices").length > 0;
1505
1505
  const solutionData = solutionStore.state.getStoreInfo("solutionData");
1506
1506
  this._solutionVariables = JSON.stringify(getSolutionVariables(solutionData.templates, this._translations));