@esri/solution-deployer 0.23.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/deploySolutionFromTemplate.js +77 -74
- package/dist/esm/deploySolutionFromTemplate.js.map +1 -1
- package/dist/esm/deploySolutionItems.d.ts +25 -1
- package/dist/esm/deploySolutionItems.js +239 -151
- package/dist/esm/deploySolutionItems.js.map +1 -1
- package/dist/esm/deployer.js +16 -17
- package/dist/esm/deployer.js.map +1 -1
- package/dist/esm/deployerUtils.js +17 -22
- package/dist/esm/deployerUtils.js.map +1 -1
- package/dist/esm/helpers/post-process.js +13 -18
- package/dist/esm/helpers/post-process.js.map +1 -1
- package/dist/esm/helpers/share-templates-to-groups.js +29 -6
- package/dist/esm/helpers/share-templates-to-groups.js.map +1 -1
- package/dist/esm/helpers/sortTemplates.js +2 -4
- package/dist/esm/helpers/sortTemplates.js.map +1 -1
- package/dist/esm/module-map.js +7 -6
- package/dist/esm/module-map.js.map +1 -1
- package/dist/node/deploySolutionFromTemplate.js +83 -80
- package/dist/node/deploySolutionFromTemplate.js.map +1 -1
- package/dist/node/deploySolutionItems.d.ts +25 -1
- package/dist/node/deploySolutionItems.js +244 -154
- package/dist/node/deploySolutionItems.js.map +1 -1
- package/dist/node/deployer.js +23 -24
- package/dist/node/deployer.js.map +1 -1
- package/dist/node/deployerUtils.js +18 -23
- package/dist/node/deployerUtils.js.map +1 -1
- package/dist/node/helpers/post-process.js +18 -23
- package/dist/node/helpers/post-process.js.map +1 -1
- package/dist/node/helpers/share-templates-to-groups.js +30 -7
- package/dist/node/helpers/share-templates-to-groups.js.map +1 -1
- package/dist/node/helpers/sortTemplates.js +2 -4
- package/dist/node/helpers/sortTemplates.js.map +1 -1
- package/dist/node/index.js +5 -5
- package/dist/node/index.js.map +1 -1
- package/dist/node/module-map.js +13 -12
- package/dist/node/module-map.js.map +1 -1
- package/dist/umd/deploySolutionItems.d.ts +25 -1
- package/dist/umd/deployer.umd.js +1622 -1550
- package/dist/umd/deployer.umd.js.map +1 -1
- package/dist/umd/deployer.umd.min.js +3 -3
- package/dist/umd/deployer.umd.min.js.map +1 -1
- package/package.json +31 -30
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import * as common from "@esri/solution-common";
|
|
22
22
|
import { moduleMap } from "./module-map";
|
|
23
|
-
|
|
23
|
+
const UNSUPPORTED = null;
|
|
24
24
|
// ------------------------------------------------------------------------------------------------------------------ //
|
|
25
25
|
/**
|
|
26
26
|
* Deploys a set of items defined by templates.
|
|
@@ -30,33 +30,32 @@ var UNSUPPORTED = null;
|
|
|
30
30
|
* @param templates A collection of AGO item templates
|
|
31
31
|
* @param storageAuthentication Credentials for the organization with the source items
|
|
32
32
|
* @param templateDictionary Hash of facts: org URL, adlib replacements
|
|
33
|
+
* @param deployedSolutionId Id of deployed Solution item
|
|
33
34
|
* @param destinationAuthentication Credentials for the destination organization
|
|
34
35
|
* @param options Options to tune deployment
|
|
35
36
|
* @return A promise that will resolve with the list of information about the created items
|
|
36
37
|
*/
|
|
37
|
-
export function deploySolutionItems(portalSharingUrl, storageItemId, templates, storageAuthentication, templateDictionary, destinationAuthentication, options) {
|
|
38
|
-
return new Promise(
|
|
39
|
-
var _a;
|
|
38
|
+
export function deploySolutionItems(portalSharingUrl, storageItemId, templates, storageAuthentication, templateDictionary, deployedSolutionId, destinationAuthentication, options) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
40
|
// Prepare feedback mechanism
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
const totalEstimatedCost = _estimateDeploymentCost(templates) + 1; // solution items, plus avoid divide by 0
|
|
42
|
+
let percentDone = 10; // allow for previous deployment work
|
|
43
|
+
const progressPercentStep = (99 - percentDone) / totalEstimatedCost; // leave some % for caller for wrapup
|
|
44
|
+
const failedTemplateItemIds = [];
|
|
45
|
+
const deployedItemIds = [];
|
|
46
|
+
let statusOK = true;
|
|
47
47
|
// TODO: move to separate fn
|
|
48
|
-
|
|
49
|
-
) {
|
|
50
|
-
var _a;
|
|
48
|
+
const itemProgressCallback = (itemId, status, costUsed, createdItemId // supplied when status is EItemProgressStatus.Created or .Finished
|
|
49
|
+
) => {
|
|
51
50
|
percentDone += progressPercentStep * costUsed;
|
|
52
51
|
/* istanbul ignore else */
|
|
53
52
|
if (options.progressCallback) {
|
|
54
53
|
if (status === common.EItemProgressStatus.Finished) {
|
|
55
|
-
|
|
54
|
+
const event = {
|
|
56
55
|
event: common.SItemProgressStatus[status],
|
|
57
56
|
data: itemId
|
|
58
57
|
};
|
|
59
|
-
options.progressCallback(Math.round(percentDone), options.jobId,
|
|
58
|
+
options.progressCallback(Math.round(percentDone), options.jobId, event);
|
|
60
59
|
}
|
|
61
60
|
else {
|
|
62
61
|
options.progressCallback(Math.round(percentDone), options.jobId);
|
|
@@ -64,7 +63,7 @@ export function deploySolutionItems(portalSharingUrl, storageItemId, templates,
|
|
|
64
63
|
}
|
|
65
64
|
/* istanbul ignore if */
|
|
66
65
|
if (options.consoleProgress) {
|
|
67
|
-
console.log(Date.now(), itemId,
|
|
66
|
+
console.log(Date.now(), itemId, options.jobId ?? "", common.SItemProgressStatus[status], percentDone.toFixed(0) + "%", costUsed, createdItemId ? "==> " + createdItemId : "");
|
|
68
67
|
}
|
|
69
68
|
if (status === common.EItemProgressStatus.Created) {
|
|
70
69
|
deployedItemIds.push(createdItemId);
|
|
@@ -84,27 +83,27 @@ export function deploySolutionItems(portalSharingUrl, storageItemId, templates,
|
|
|
84
83
|
// Create an ordered graph of the templates so that dependencies are created before the items that need them.
|
|
85
84
|
// Because cycles are permitted, we also keep track of items that need to be patched later because their
|
|
86
85
|
// dependencies are necessarily created after they are created.
|
|
87
|
-
|
|
86
|
+
const { buildOrder, itemsToBePatched } = common.topologicallySortItems(templates);
|
|
88
87
|
// For each item in order from no dependencies to dependent on other items,
|
|
89
88
|
// * replace template symbols using template dictionary
|
|
90
89
|
// * create item in destination group
|
|
91
90
|
// * add created item's id into the template dictionary
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
const awaitAllItems = [];
|
|
92
|
+
const reuseItemsDef = _reuseDeployedItems(templates, options.enableItemReuse ?? false, templateDictionary, destinationAuthentication);
|
|
94
93
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
95
|
-
reuseItemsDef.then(
|
|
96
|
-
|
|
94
|
+
reuseItemsDef.then(() => {
|
|
95
|
+
const useExistingItemsDef = _useExistingItems(templates, common.getProp(templateDictionary, "params.useExisting"), templateDictionary, destinationAuthentication);
|
|
97
96
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
98
|
-
useExistingItemsDef.then(
|
|
97
|
+
useExistingItemsDef.then(() => {
|
|
99
98
|
templates = common.setNamesAndTitles(templates, templateDictionary.solutionItemId);
|
|
100
|
-
buildOrder.forEach(
|
|
99
|
+
buildOrder.forEach((id) => {
|
|
101
100
|
// Get the item's template out of the list of templates
|
|
102
|
-
|
|
101
|
+
const template = common.findTemplateInList(templates, id);
|
|
103
102
|
awaitAllItems.push(_createItemFromTemplateWhenReady(template, common.generateStorageFilePaths(portalSharingUrl, storageItemId, template.resources, options.storageVersion), storageAuthentication, templateDictionary, destinationAuthentication, itemProgressCallback));
|
|
104
103
|
});
|
|
105
104
|
// Wait until all items have been created
|
|
106
105
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
107
|
-
Promise.all(awaitAllItems).then(
|
|
106
|
+
Promise.all(awaitAllItems).then((clonedSolutionItems) => {
|
|
108
107
|
if (failedTemplateItemIds.length === 0) {
|
|
109
108
|
// Do we have any items to be patched (i.e., they refer to dependencies using the template id rather
|
|
110
109
|
// than the cloned id because the item had to be created before the dependency)? Flag these items
|
|
@@ -114,16 +113,17 @@ export function deploySolutionItems(portalSharingUrl, storageItemId, templates,
|
|
|
114
113
|
}
|
|
115
114
|
else {
|
|
116
115
|
// Delete created items
|
|
116
|
+
const progressOptions = {
|
|
117
|
+
consoleProgress: true
|
|
118
|
+
};
|
|
117
119
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
118
120
|
common
|
|
119
|
-
.
|
|
120
|
-
.then(
|
|
121
|
-
return reject(common.failWithIds(failedTemplateItemIds));
|
|
122
|
-
});
|
|
121
|
+
.deleteSolutionByComponents(deployedSolutionId, deployedItemIds, templates, templateDictionary, destinationAuthentication, progressOptions)
|
|
122
|
+
.then(() => reject(common.failWithIds(failedTemplateItemIds)));
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
|
-
},
|
|
126
|
+
}, e => {
|
|
127
127
|
console.error(e);
|
|
128
128
|
reject(common.fail(e));
|
|
129
129
|
});
|
|
@@ -137,13 +137,13 @@ export function deploySolutionItems(portalSharingUrl, storageItemId, templates,
|
|
|
137
137
|
* @param templates A collection of AGO item templates
|
|
138
138
|
*/
|
|
139
139
|
export function _flagPatchItemsForPostProcessing(itemsToBePatched, templateDictionary, templates) {
|
|
140
|
-
|
|
140
|
+
let itemIdsToBePatched = Object.keys(itemsToBePatched);
|
|
141
141
|
/* istanbul ignore else */
|
|
142
142
|
if (itemIdsToBePatched.length > 0) {
|
|
143
143
|
// Replace the ids of the items to be patched (which are template ids) with their cloned versions
|
|
144
|
-
itemIdsToBePatched = itemIdsToBePatched.map(
|
|
144
|
+
itemIdsToBePatched = itemIdsToBePatched.map(id => templateDictionary[id].itemId);
|
|
145
145
|
// Make sure that the items to be patched are flagged for post processing
|
|
146
|
-
templates.forEach(
|
|
146
|
+
templates.forEach(item => {
|
|
147
147
|
/* istanbul ignore else */
|
|
148
148
|
if (itemIdsToBePatched.includes(item.id)) {
|
|
149
149
|
item.postProcess = true;
|
|
@@ -164,16 +164,16 @@ export function _flagPatchItemsForPostProcessing(itemsToBePatched, templateDicti
|
|
|
164
164
|
export function _evaluateSharedViewSources(templates) {
|
|
165
165
|
// update the templates so we can defer the deployment when more than one view shares the same source
|
|
166
166
|
// these are not classic dependencies but are in some ways similar
|
|
167
|
-
|
|
167
|
+
const views = _getViews(templates);
|
|
168
168
|
_updateViewTemplates(templates, views);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
Object.keys(viewHash).forEach(
|
|
173
|
-
|
|
174
|
-
_views.forEach(
|
|
175
|
-
|
|
176
|
-
|
|
169
|
+
const viewHash = _getViewHash(views);
|
|
170
|
+
let processed = [];
|
|
171
|
+
const visited = [];
|
|
172
|
+
Object.keys(viewHash).forEach(k => {
|
|
173
|
+
const _views = viewHash[k];
|
|
174
|
+
_views.forEach(cv => {
|
|
175
|
+
const template = common.findTemplateInList(templates, cv);
|
|
176
|
+
const syncViews = common.getProp(template, "properties.syncViews");
|
|
177
177
|
/* istanbul ignore else */
|
|
178
178
|
if (visited.indexOf(template.itemId) > -1) {
|
|
179
179
|
processed = processed.concat(syncViews);
|
|
@@ -208,9 +208,9 @@ export function _evaluateSharedViewSources(templates) {
|
|
|
208
208
|
*
|
|
209
209
|
*/
|
|
210
210
|
export function _updateViewTemplates(templates, views) {
|
|
211
|
-
views.forEach(
|
|
212
|
-
v.dependencies.forEach(
|
|
213
|
-
templates = templates.map(
|
|
211
|
+
views.forEach(v => {
|
|
212
|
+
v.dependencies.forEach((id) => {
|
|
213
|
+
templates = templates.map(t => {
|
|
214
214
|
/* istanbul ignore else */
|
|
215
215
|
if (common.getProp(t, "properties.service.isView") &&
|
|
216
216
|
t.dependencies.indexOf(id) > -1 &&
|
|
@@ -241,9 +241,9 @@ export function _updateViewTemplates(templates, views) {
|
|
|
241
241
|
* @protected
|
|
242
242
|
*/
|
|
243
243
|
export function _getViewHash(views) {
|
|
244
|
-
|
|
245
|
-
views.forEach(
|
|
246
|
-
v.dependencies.forEach(
|
|
244
|
+
const viewHash = {};
|
|
245
|
+
views.forEach(v => {
|
|
246
|
+
v.dependencies.forEach((d) => {
|
|
247
247
|
/* istanbul ignore else */
|
|
248
248
|
if (Object.keys(viewHash).indexOf(d) < 0) {
|
|
249
249
|
viewHash[d] = [v.id];
|
|
@@ -265,7 +265,7 @@ export function _getViewHash(views) {
|
|
|
265
265
|
* @protected
|
|
266
266
|
*/
|
|
267
267
|
export function _getViews(templates) {
|
|
268
|
-
return templates.reduce(
|
|
268
|
+
return templates.reduce((acc, v) => {
|
|
269
269
|
/* istanbul ignore else */
|
|
270
270
|
if (common.getProp(v, "properties.service.isView")) {
|
|
271
271
|
acc.push({
|
|
@@ -289,17 +289,17 @@ export function _getViews(templates) {
|
|
|
289
289
|
* @protected
|
|
290
290
|
*/
|
|
291
291
|
export function _reuseDeployedItems(templates, reuseItems, templateDictionary, authentication) {
|
|
292
|
-
return new Promise(
|
|
292
|
+
return new Promise((resolve, reject) => {
|
|
293
293
|
if (reuseItems) {
|
|
294
|
-
|
|
295
|
-
Promise.all(existingItemsByKeyword).then(
|
|
296
|
-
|
|
297
|
-
Promise.all(existingItemsByTag).then(
|
|
294
|
+
const existingItemsByKeyword = _findExistingItemByKeyword(templates, templateDictionary, authentication);
|
|
295
|
+
Promise.all(existingItemsByKeyword).then((existingItemsByKeywordResponse) => {
|
|
296
|
+
const existingItemsByTag = _handleExistingItems(existingItemsByKeywordResponse, templateDictionary, authentication, true);
|
|
297
|
+
Promise.all(existingItemsByTag).then(existingItemsByTagResponse => {
|
|
298
298
|
_handleExistingItems(existingItemsByTagResponse, templateDictionary, authentication, false);
|
|
299
299
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
300
300
|
_updateTemplateDictionary(templates, templateDictionary, authentication).then(resolve);
|
|
301
|
-
},
|
|
302
|
-
},
|
|
301
|
+
}, e => reject(common.fail(e)));
|
|
302
|
+
}, e => reject(common.fail(e)));
|
|
303
303
|
}
|
|
304
304
|
else {
|
|
305
305
|
resolve(null);
|
|
@@ -327,28 +327,81 @@ export function _reuseDeployedItems(templates, reuseItems, templateDictionary, a
|
|
|
327
327
|
* @protected
|
|
328
328
|
*/
|
|
329
329
|
export function _useExistingItems(templates, useExisting, templateDictionary, authentication) {
|
|
330
|
-
return new Promise(
|
|
330
|
+
return new Promise(resolve => {
|
|
331
331
|
if (useExisting) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
332
|
+
const itemDefs = [];
|
|
333
|
+
const sourceIdHash = {};
|
|
334
|
+
const itemIds = [];
|
|
335
|
+
Object.keys(templateDictionary.params).forEach(k => {
|
|
336
|
+
const v = templateDictionary.params[k];
|
|
335
337
|
/* istanbul ignore else */
|
|
336
|
-
if (v.itemId &&
|
|
337
|
-
_updateTemplateDictionaryById(templateDictionary,
|
|
338
|
+
if (v.itemId && /[0-9A-F]{32}/i.test(k)) {
|
|
339
|
+
_updateTemplateDictionaryById(templateDictionary, k, v.itemId, v);
|
|
340
|
+
// need to check and set the typeKeyword if it doesn't exist on this service yet
|
|
341
|
+
// when the user has passed in an itemId that does not come from a previous deployment
|
|
342
|
+
itemDefs.push(common.getItemBase(v.itemId, authentication));
|
|
343
|
+
sourceIdHash[v.itemId] = k;
|
|
338
344
|
/* istanbul ignore else */
|
|
339
|
-
if (
|
|
340
|
-
|
|
345
|
+
if (itemIds.indexOf(k) < 0) {
|
|
346
|
+
itemIds.push(k);
|
|
341
347
|
}
|
|
342
348
|
}
|
|
343
349
|
});
|
|
344
350
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
345
|
-
|
|
351
|
+
_setTypekeywordForExisting(itemDefs, sourceIdHash, authentication).then(() => {
|
|
352
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
353
|
+
_updateTemplateDictionary(itemIds.map(id => common.getTemplateById(templates, id)), templateDictionary, authentication).then(resolve);
|
|
354
|
+
});
|
|
346
355
|
}
|
|
347
356
|
else {
|
|
348
357
|
resolve(null);
|
|
349
358
|
}
|
|
350
359
|
});
|
|
351
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Verify if the existing item has the source-<itemId> typeKeyword and set it if not
|
|
363
|
+
* This allows items that did not come from deployment to be found for reuse after they
|
|
364
|
+
* have been used once via a custom itemId param
|
|
365
|
+
*
|
|
366
|
+
* @param itemDefs
|
|
367
|
+
* @param sourceIdHash key value pairs..actual itemId is the key and the source itemId is the value
|
|
368
|
+
* @param authentication credentials for the requests
|
|
369
|
+
*
|
|
370
|
+
* @return a promise to indicate when the requests are complete
|
|
371
|
+
*/
|
|
372
|
+
export function _setTypekeywordForExisting(itemDefs, sourceIdHash, authentication) {
|
|
373
|
+
return new Promise(resolve => {
|
|
374
|
+
if (itemDefs.length > 0) {
|
|
375
|
+
Promise.all(itemDefs).then(results => {
|
|
376
|
+
const itemUpdateDefs = [];
|
|
377
|
+
results.forEach(result => {
|
|
378
|
+
const sourceId = sourceIdHash[result.id];
|
|
379
|
+
/* istanbul ignore else */
|
|
380
|
+
if (result && sourceId && result.typeKeywords) {
|
|
381
|
+
const sourceKeyword = `source-${sourceId}`;
|
|
382
|
+
const typeKeywords = result.typeKeywords;
|
|
383
|
+
/* istanbul ignore else */
|
|
384
|
+
if (typeKeywords.indexOf(sourceKeyword) < 0) {
|
|
385
|
+
typeKeywords.push(sourceKeyword);
|
|
386
|
+
const itemUpdate = { id: result.id, typeKeywords };
|
|
387
|
+
itemUpdateDefs.push(common.updateItem(itemUpdate, authentication));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
// wait for updates to finish before we resolve
|
|
392
|
+
if (itemUpdateDefs.length > 0) {
|
|
393
|
+
Promise.all(itemUpdateDefs).then(resolve, () => resolve(undefined));
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
resolve(undefined);
|
|
397
|
+
}
|
|
398
|
+
}, () => resolve(undefined));
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
resolve(undefined);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
352
405
|
/**
|
|
353
406
|
* Update the templateDictionary with key details by item type
|
|
354
407
|
*
|
|
@@ -358,18 +411,19 @@ export function _useExistingItems(templates, useExisting, templateDictionary, au
|
|
|
358
411
|
* @protected
|
|
359
412
|
*/
|
|
360
413
|
export function _updateTemplateDictionary(templates, templateDictionary, authentication) {
|
|
361
|
-
return new Promise(
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
templates.forEach(
|
|
367
|
-
|
|
414
|
+
return new Promise(resolve => {
|
|
415
|
+
const defs = [];
|
|
416
|
+
const urls = [];
|
|
417
|
+
const types = [];
|
|
418
|
+
const ids = [];
|
|
419
|
+
templates.forEach(t => {
|
|
420
|
+
const templateInfo = templateDictionary[t.itemId];
|
|
368
421
|
/* istanbul ignore else */
|
|
369
422
|
if (templateInfo && templateInfo.url && templateInfo.itemId) {
|
|
370
423
|
/* istanbul ignore else */
|
|
371
424
|
if (t.item.type === "Feature Service") {
|
|
372
|
-
|
|
425
|
+
const enterpriseIDMapping = common.getProp(templateDictionary, `params.${t.itemId}.enterpriseIDMapping`);
|
|
426
|
+
Object.assign(templateDictionary[t.itemId], common.getLayerSettings(common.getLayersAndTables(t), templateInfo.url, templateInfo.itemId, enterpriseIDMapping));
|
|
373
427
|
// if the service has veiws keep track of the fields so we can use them to
|
|
374
428
|
// compare with the view fields
|
|
375
429
|
/* istanbul ignore else */
|
|
@@ -384,7 +438,7 @@ export function _updateTemplateDictionary(templates, templateDictionary, authent
|
|
|
384
438
|
/* istanbul ignore else */
|
|
385
439
|
if (urls.indexOf(templateInfo.url) < 0) {
|
|
386
440
|
defs.push(t.item.type === "Feature Service"
|
|
387
|
-
? common.rest_request(templateInfo.url, { authentication
|
|
441
|
+
? common.rest_request(templateInfo.url, { authentication })
|
|
388
442
|
: common.getItemBase(templateInfo.itemId, authentication));
|
|
389
443
|
urls.push(templateInfo.url);
|
|
390
444
|
types.push(t.item.type);
|
|
@@ -394,23 +448,23 @@ export function _updateTemplateDictionary(templates, templateDictionary, authent
|
|
|
394
448
|
});
|
|
395
449
|
if (defs.length > 0) {
|
|
396
450
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
397
|
-
Promise.all(defs.map(
|
|
451
|
+
Promise.all(defs.map(p => p.catch(e => e))).then(results => {
|
|
398
452
|
/* istanbul ignore else */
|
|
399
453
|
if (Array.isArray(results) && results.length > 0) {
|
|
400
|
-
|
|
401
|
-
results.forEach(
|
|
454
|
+
const fieldDefs = [];
|
|
455
|
+
results.forEach((r, i) => {
|
|
402
456
|
// a feature service result will contain a serviceItemId if it was successfully fetched
|
|
403
457
|
if (r.serviceItemId && types[i] === "Feature Service") {
|
|
404
|
-
Object.keys(templateDictionary).forEach(
|
|
405
|
-
|
|
458
|
+
Object.keys(templateDictionary).forEach(k => {
|
|
459
|
+
const v = templateDictionary[k];
|
|
406
460
|
/* istanbul ignore else */
|
|
407
461
|
if (v.itemId && v.itemId === r.serviceItemId) {
|
|
408
462
|
common.setDefaultSpatialReference(templateDictionary, k, r.spatialReference);
|
|
409
463
|
// keep the extent values from these responses as well
|
|
410
|
-
common.setCreateProp(templateDictionary, k
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
464
|
+
common.setCreateProp(templateDictionary, `${k}.defaultExtent`, r.fullExtent || r.initialExtent);
|
|
465
|
+
const layerIds = (r.layers || []).map((l) => l.id);
|
|
466
|
+
const tablesIds = (r.tables || []).map((t) => t.id);
|
|
467
|
+
fieldDefs.push(common.getExistingLayersAndTables(urls[i], layerIds.concat(tablesIds), authentication));
|
|
414
468
|
}
|
|
415
469
|
});
|
|
416
470
|
}
|
|
@@ -423,18 +477,33 @@ export function _updateTemplateDictionary(templates, templateDictionary, authent
|
|
|
423
477
|
}
|
|
424
478
|
}
|
|
425
479
|
});
|
|
426
|
-
if (
|
|
480
|
+
if (fieldDefs.length > 0) {
|
|
427
481
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
428
|
-
Promise.all(
|
|
429
|
-
layerTableResult.forEach(
|
|
430
|
-
l.forEach(
|
|
431
|
-
Object.keys(templateDictionary).forEach(
|
|
482
|
+
Promise.all(fieldDefs).then(layerTableResult => {
|
|
483
|
+
layerTableResult.forEach(l => {
|
|
484
|
+
l.forEach((ll) => {
|
|
485
|
+
Object.keys(templateDictionary).forEach(k => {
|
|
432
486
|
/* istanbul ignore else */
|
|
433
487
|
if (templateDictionary[k].itemId === ll.serviceItemId) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
488
|
+
let sourceId = "";
|
|
489
|
+
Object.keys(templateDictionary).some(_k => {
|
|
490
|
+
/* istanbul ignore else */
|
|
491
|
+
if (templateDictionary[_k].itemId === ll.serviceItemId) {
|
|
492
|
+
sourceId = _k;
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
const enterpriseIDMapping = common.getProp(templateDictionary, `params.${sourceId}.enterpriseIDMapping`);
|
|
497
|
+
if (enterpriseIDMapping) {
|
|
498
|
+
Object.keys(enterpriseIDMapping).forEach(id => {
|
|
499
|
+
if (enterpriseIDMapping[id].toString() ===
|
|
500
|
+
ll.id.toString()) {
|
|
501
|
+
_setFields(templateDictionary, k, id, ll.fields);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
_setFields(templateDictionary, k, ll.id, ll.fields);
|
|
438
507
|
}
|
|
439
508
|
}
|
|
440
509
|
});
|
|
@@ -457,6 +526,23 @@ export function _updateTemplateDictionary(templates, templateDictionary, authent
|
|
|
457
526
|
}
|
|
458
527
|
});
|
|
459
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Add the fields from the source layer to the template dictionary for any required replacements
|
|
531
|
+
*
|
|
532
|
+
* @param templateDictionary Hash of facts: org URL, adlib replacements, deferreds for dependencies
|
|
533
|
+
* @param itemId the id for the item
|
|
534
|
+
* @param layerId the id for the layer
|
|
535
|
+
* @param fields the fields to transfer
|
|
536
|
+
*
|
|
537
|
+
* @protected
|
|
538
|
+
*/
|
|
539
|
+
export function _setFields(templateDictionary, itemId, layerId, fields) {
|
|
540
|
+
const layerInfo = common.getProp(templateDictionary, `${itemId}.layer${layerId}`);
|
|
541
|
+
/* istanbul ignore else */
|
|
542
|
+
if (layerInfo && fields) {
|
|
543
|
+
layerInfo.fields = fields;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
460
546
|
/**
|
|
461
547
|
* In some cases an item id search will return a stale item reference
|
|
462
548
|
* it will subsequently fail when we try to fetch the underlying service.
|
|
@@ -472,17 +558,17 @@ export function _updateTemplateDictionary(templates, templateDictionary, authent
|
|
|
472
558
|
export function _updateTemplateDictionaryForError(templateDictionary, itemId) {
|
|
473
559
|
/* istanbul ignore else */
|
|
474
560
|
if (itemId) {
|
|
475
|
-
|
|
476
|
-
Object.keys(templateDictionary).some(
|
|
561
|
+
let removeKey = "";
|
|
562
|
+
Object.keys(templateDictionary).some(k => {
|
|
477
563
|
/* istanbul ignore else */
|
|
478
564
|
if (templateDictionary[k].itemId === itemId) {
|
|
479
|
-
|
|
565
|
+
removeKey = k;
|
|
480
566
|
return true;
|
|
481
567
|
}
|
|
482
568
|
});
|
|
483
569
|
/* istanbul ignore else */
|
|
484
|
-
if (
|
|
485
|
-
delete templateDictionary[
|
|
570
|
+
if (removeKey !== "") {
|
|
571
|
+
delete templateDictionary[removeKey];
|
|
486
572
|
}
|
|
487
573
|
}
|
|
488
574
|
return templateDictionary;
|
|
@@ -499,30 +585,28 @@ export function _updateTemplateDictionaryForError(templateDictionary, itemId) {
|
|
|
499
585
|
*/
|
|
500
586
|
export function _handleExistingItems(existingItemsResponse, templateDictionary, authentication, addTagQuery) {
|
|
501
587
|
// if items are not found by type keyword search by tag
|
|
502
|
-
|
|
588
|
+
const existingItemsByTag = [Promise.resolve(null)];
|
|
503
589
|
/* istanbul ignore else */
|
|
504
590
|
if (existingItemsResponse && Array.isArray(existingItemsResponse)) {
|
|
505
|
-
existingItemsResponse.forEach(
|
|
591
|
+
existingItemsResponse.forEach(existingItem => {
|
|
506
592
|
/* istanbul ignore else */
|
|
507
|
-
if (Array.isArray(existingItem
|
|
508
|
-
|
|
509
|
-
|
|
593
|
+
if (Array.isArray(existingItem?.results)) {
|
|
594
|
+
let result;
|
|
595
|
+
const results = existingItem.results;
|
|
510
596
|
if (results.length === 1) {
|
|
511
597
|
result = results[0];
|
|
512
598
|
}
|
|
513
599
|
else if (results.length > 1) {
|
|
514
|
-
result = results.reduce(
|
|
515
|
-
return a.created > b.created ? a : b;
|
|
516
|
-
});
|
|
600
|
+
result = results.reduce((a, b) => a.created > b.created ? a : b);
|
|
517
601
|
}
|
|
518
602
|
else {
|
|
519
603
|
if (addTagQuery && existingItem.query) {
|
|
520
|
-
|
|
604
|
+
const tagQuery = existingItem.query.replace("typekeywords", "tags");
|
|
521
605
|
existingItemsByTag.push(_findExistingItem(tagQuery, authentication));
|
|
522
606
|
}
|
|
523
607
|
}
|
|
524
608
|
if (result) {
|
|
525
|
-
|
|
609
|
+
const sourceId = existingItem.query
|
|
526
610
|
? existingItem.query.match(/[0-9A-F]{32}/i)[0]
|
|
527
611
|
: existingItem.sourceId;
|
|
528
612
|
/* istanbul ignore else */
|
|
@@ -538,7 +622,7 @@ export function _handleExistingItems(existingItemsResponse, templateDictionary,
|
|
|
538
622
|
export function _updateTemplateDictionaryById(templateDictionary, sourceId, itemId, v) {
|
|
539
623
|
templateDictionary[sourceId] = Object.assign(templateDictionary[sourceId] || {}, {
|
|
540
624
|
def: Promise.resolve(common.generateEmptyCreationResponse(v.type, itemId)),
|
|
541
|
-
itemId
|
|
625
|
+
itemId,
|
|
542
626
|
name: v.name,
|
|
543
627
|
title: v.title,
|
|
544
628
|
url: v.url
|
|
@@ -553,17 +637,16 @@ export function _updateTemplateDictionaryById(templateDictionary, sourceId, item
|
|
|
553
637
|
* @protected
|
|
554
638
|
*/
|
|
555
639
|
export function _findExistingItemByKeyword(templates, templateDictionary, authentication) {
|
|
556
|
-
|
|
557
|
-
templates.forEach(
|
|
558
|
-
var _a;
|
|
640
|
+
const existingItemsDefs = [];
|
|
641
|
+
templates.forEach(template => {
|
|
559
642
|
if (template.item.type === "Group") {
|
|
560
|
-
|
|
643
|
+
const userGroups = templateDictionary.user?.groups;
|
|
561
644
|
/* istanbul ignore else */
|
|
562
645
|
if (Array.isArray(userGroups)) {
|
|
563
646
|
existingItemsDefs.push(Promise.resolve({
|
|
564
647
|
results: userGroups
|
|
565
|
-
.filter(
|
|
566
|
-
.map(
|
|
648
|
+
.filter(g => g.tags.indexOf(`source-${template.itemId}`) > -1)
|
|
649
|
+
.map(g => {
|
|
567
650
|
g.type = "Group";
|
|
568
651
|
return g;
|
|
569
652
|
}),
|
|
@@ -572,7 +655,7 @@ export function _findExistingItemByKeyword(templates, templateDictionary, authen
|
|
|
572
655
|
}
|
|
573
656
|
}
|
|
574
657
|
else {
|
|
575
|
-
existingItemsDefs.push(_findExistingItem(
|
|
658
|
+
existingItemsDefs.push(_findExistingItem(`typekeywords:source-${template.itemId} type:${template.item.type} owner:${templateDictionary.user.username}`, authentication));
|
|
576
659
|
}
|
|
577
660
|
});
|
|
578
661
|
return existingItemsDefs;
|
|
@@ -586,7 +669,7 @@ export function _findExistingItemByKeyword(templates, templateDictionary, authen
|
|
|
586
669
|
* @protected
|
|
587
670
|
*/
|
|
588
671
|
export function _findExistingItem(query, authentication) {
|
|
589
|
-
|
|
672
|
+
const searchOptions = {
|
|
590
673
|
q: query,
|
|
591
674
|
authentication: authentication,
|
|
592
675
|
pagingParam: { start: 1, num: 100 }
|
|
@@ -612,16 +695,16 @@ export function _createItemFromTemplateWhenReady(template, resourceFilePaths, st
|
|
|
612
695
|
// or if we have a basic entry without the deferred request for its creation, add it
|
|
613
696
|
if (!templateDictionary.hasOwnProperty(template.itemId) ||
|
|
614
697
|
!common.getProp(templateDictionary[template.itemId], "def")) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
698
|
+
let createResponse;
|
|
699
|
+
let statusCode = common.EItemProgressStatus.Unknown;
|
|
700
|
+
let itemHandler;
|
|
618
701
|
templateDictionary[template.itemId] =
|
|
619
702
|
templateDictionary[template.itemId] || {};
|
|
620
703
|
// Save the deferred for the use of items that depend on this item being created first
|
|
621
|
-
templateDictionary[template.itemId].def = new Promise(
|
|
704
|
+
templateDictionary[template.itemId].def = new Promise(resolve => {
|
|
622
705
|
// Wait until all of the item's dependencies are deployed
|
|
623
|
-
|
|
624
|
-
|
|
706
|
+
const _awaitDependencies = template.dependencies.reduce((acc, id) => {
|
|
707
|
+
const def = common.getProp(templateDictionary, `${id}.def`);
|
|
625
708
|
// can't use maybePush as that clones the object, which does not work for Promises
|
|
626
709
|
/* istanbul ignore else */
|
|
627
710
|
if (def) {
|
|
@@ -629,10 +712,10 @@ export function _createItemFromTemplateWhenReady(template, resourceFilePaths, st
|
|
|
629
712
|
}
|
|
630
713
|
return acc;
|
|
631
714
|
}, []);
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
? syncViews.reduce(
|
|
635
|
-
|
|
715
|
+
const syncViews = common.getProp(template, "properties.syncViews");
|
|
716
|
+
const awaitDependencies = syncViews && syncViews.length > 0
|
|
717
|
+
? syncViews.reduce((acc, v) => {
|
|
718
|
+
const def = common.getProp(templateDictionary, `${v}.def`);
|
|
636
719
|
/* istanbul ignore else */
|
|
637
720
|
if (def) {
|
|
638
721
|
acc.push(def);
|
|
@@ -641,50 +724,55 @@ export function _createItemFromTemplateWhenReady(template, resourceFilePaths, st
|
|
|
641
724
|
}, _awaitDependencies)
|
|
642
725
|
: _awaitDependencies;
|
|
643
726
|
Promise.all(awaitDependencies)
|
|
644
|
-
.then(
|
|
727
|
+
.then(() => {
|
|
645
728
|
// Find the conversion handler for this item type
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
if (!
|
|
649
|
-
if (
|
|
650
|
-
|
|
729
|
+
const templateType = template.type;
|
|
730
|
+
itemHandler = moduleMap[templateType];
|
|
731
|
+
if (!itemHandler || itemHandler === UNSUPPORTED) {
|
|
732
|
+
if (itemHandler === UNSUPPORTED) {
|
|
733
|
+
statusCode = common.EItemProgressStatus.Ignored;
|
|
651
734
|
throw new Error();
|
|
652
735
|
}
|
|
653
736
|
else {
|
|
654
|
-
|
|
737
|
+
statusCode = common.EItemProgressStatus.Failed;
|
|
655
738
|
throw new Error();
|
|
656
739
|
}
|
|
657
740
|
}
|
|
658
741
|
// Get the item's thumbnail
|
|
659
742
|
return common.getThumbnailFromStorageItem(storageAuthentication, resourceFilePaths);
|
|
660
743
|
})
|
|
661
|
-
.then(
|
|
744
|
+
.then(thumbnail => {
|
|
662
745
|
template.item.thumbnail = thumbnail;
|
|
663
746
|
// Delegate the creation of the item to the handler
|
|
664
747
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
665
|
-
return
|
|
748
|
+
return itemHandler.createItemFromTemplate(template, templateDictionary, destinationAuthentication, itemProgressCallback);
|
|
666
749
|
})
|
|
667
|
-
.then(
|
|
750
|
+
.then((response) => {
|
|
668
751
|
if (response.id === "") {
|
|
669
|
-
|
|
752
|
+
statusCode = common.EItemProgressStatus.Failed;
|
|
670
753
|
throw new Error("handled"); // fails to create item
|
|
671
754
|
}
|
|
672
755
|
/* istanbul ignore else */
|
|
673
|
-
|
|
674
|
-
if (
|
|
675
|
-
common.setCreateProp(templateDictionary, template.itemId + ".url",
|
|
756
|
+
createResponse = response;
|
|
757
|
+
if (createResponse.item.item.url) {
|
|
758
|
+
common.setCreateProp(templateDictionary, template.itemId + ".url", createResponse.item.item.url);
|
|
759
|
+
}
|
|
760
|
+
if (resourceFilePaths.length > 0) {
|
|
761
|
+
// Copy resources, metadata, form
|
|
762
|
+
return common.copyFilesFromStorageItem(storageAuthentication, resourceFilePaths, templateDictionary.folderId, createResponse.id, destinationAuthentication, createResponse.item);
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
return Promise.resolve(null);
|
|
676
766
|
}
|
|
677
|
-
// Copy resources, metadata, form
|
|
678
|
-
return common.copyFilesFromStorageItem(storageAuthentication, resourceFilePaths, templateDictionary.folderId, createResponse_1.id, destinationAuthentication, createResponse_1.item);
|
|
679
767
|
})
|
|
680
|
-
.then(
|
|
681
|
-
resolve(
|
|
768
|
+
.then(() => {
|
|
769
|
+
resolve(createResponse);
|
|
682
770
|
})
|
|
683
|
-
.catch(
|
|
771
|
+
.catch(error => {
|
|
684
772
|
if (!error || error.message !== "handled") {
|
|
685
|
-
itemProgressCallback(template.itemId,
|
|
773
|
+
itemProgressCallback(template.itemId, statusCode === common.EItemProgressStatus.Unknown
|
|
686
774
|
? common.EItemProgressStatus.Failed
|
|
687
|
-
:
|
|
775
|
+
: statusCode, 0);
|
|
688
776
|
}
|
|
689
777
|
// Item type not supported or fails to get item dependencies
|
|
690
778
|
resolve(common.generateEmptyCreationResponse(template.type));
|
|
@@ -701,15 +789,15 @@ export function _createItemFromTemplateWhenReady(template, resourceFilePaths, st
|
|
|
701
789
|
* @protected
|
|
702
790
|
*/
|
|
703
791
|
export function _estimateDeploymentCost(templates) {
|
|
704
|
-
return templates.reduce(
|
|
792
|
+
return templates.reduce((accumulatedEstimatedCost, template) => {
|
|
705
793
|
return (accumulatedEstimatedCost + (template.estimatedDeploymentCostFactor || 1));
|
|
706
794
|
}, 0);
|
|
707
795
|
}
|
|
708
796
|
// TODO: Return a Promise vs array of promises
|
|
709
797
|
export function _getGroupUpdates(template, authentication, templateDictionary) {
|
|
710
|
-
|
|
711
|
-
return groups.map(
|
|
712
|
-
return common.shareItem(templateDictionary[sourceGroupId].itemId, template.itemId, authentication);
|
|
798
|
+
const groups = template.groups || [];
|
|
799
|
+
return groups.map((sourceGroupId) => {
|
|
800
|
+
return common.shareItem(templateDictionary[sourceGroupId].itemId, template.itemId, authentication, common.isTrackingViewTemplate(template) ? templateDictionary.locationTracking.owner : undefined);
|
|
713
801
|
});
|
|
714
802
|
}
|
|
715
803
|
//# sourceMappingURL=deploySolutionItems.js.map
|