@esri/solution-deployer 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/deploySolutionFromTemplate.js +70 -66
- package/dist/esm/deploySolutionFromTemplate.js.map +1 -1
- package/dist/esm/deploySolutionItems.js +159 -166
- package/dist/esm/deploySolutionItems.js.map +1 -1
- package/dist/esm/deployer.js +13 -14
- 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 +12 -14
- 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 +2 -2
- package/dist/esm/module-map.js.map +1 -1
- package/dist/node/deploySolutionFromTemplate.js +76 -72
- package/dist/node/deploySolutionFromTemplate.js.map +1 -1
- package/dist/node/deploySolutionItems.js +161 -168
- package/dist/node/deploySolutionItems.js.map +1 -1
- package/dist/node/deployer.js +16 -17
- 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 +16 -18
- 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 +1 -1
- package/dist/node/module-map.js +9 -9
- package/dist/node/module-map.js.map +1 -1
- package/dist/umd/deployer.umd.js +1647 -1651
- 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 +33 -33
|
@@ -21,9 +21,9 @@ exports._getGroupUpdates = exports._estimateDeploymentCost = exports._createItem
|
|
|
21
21
|
*
|
|
22
22
|
* @module deployItems
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
const common = require("@esri/solution-common");
|
|
25
|
+
const module_map_1 = require("./module-map");
|
|
26
|
+
const UNSUPPORTED = null;
|
|
27
27
|
// ------------------------------------------------------------------------------------------------------------------ //
|
|
28
28
|
/**
|
|
29
29
|
* Deploys a set of items defined by templates.
|
|
@@ -39,28 +39,26 @@ var UNSUPPORTED = null;
|
|
|
39
39
|
* @return A promise that will resolve with the list of information about the created items
|
|
40
40
|
*/
|
|
41
41
|
function deploySolutionItems(portalSharingUrl, storageItemId, templates, storageAuthentication, templateDictionary, deployedSolutionId, destinationAuthentication, options) {
|
|
42
|
-
return new Promise(
|
|
43
|
-
var _a;
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
44
43
|
// Prepare feedback mechanism
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
const totalEstimatedCost = _estimateDeploymentCost(templates) + 1; // solution items, plus avoid divide by 0
|
|
45
|
+
let percentDone = 10; // allow for previous deployment work
|
|
46
|
+
const progressPercentStep = (99 - percentDone) / totalEstimatedCost; // leave some % for caller for wrapup
|
|
47
|
+
const failedTemplateItemIds = [];
|
|
48
|
+
const deployedItemIds = [];
|
|
49
|
+
let statusOK = true;
|
|
51
50
|
// TODO: move to separate fn
|
|
52
|
-
|
|
53
|
-
) {
|
|
54
|
-
var _a;
|
|
51
|
+
const itemProgressCallback = (itemId, status, costUsed, createdItemId // supplied when status is EItemProgressStatus.Created or .Finished
|
|
52
|
+
) => {
|
|
55
53
|
percentDone += progressPercentStep * costUsed;
|
|
56
54
|
/* istanbul ignore else */
|
|
57
55
|
if (options.progressCallback) {
|
|
58
56
|
if (status === common.EItemProgressStatus.Finished) {
|
|
59
|
-
|
|
57
|
+
const event = {
|
|
60
58
|
event: common.SItemProgressStatus[status],
|
|
61
59
|
data: itemId
|
|
62
60
|
};
|
|
63
|
-
options.progressCallback(Math.round(percentDone), options.jobId,
|
|
61
|
+
options.progressCallback(Math.round(percentDone), options.jobId, event);
|
|
64
62
|
}
|
|
65
63
|
else {
|
|
66
64
|
options.progressCallback(Math.round(percentDone), options.jobId);
|
|
@@ -68,7 +66,7 @@ function deploySolutionItems(portalSharingUrl, storageItemId, templates, storage
|
|
|
68
66
|
}
|
|
69
67
|
/* istanbul ignore if */
|
|
70
68
|
if (options.consoleProgress) {
|
|
71
|
-
console.log(Date.now(), itemId,
|
|
69
|
+
console.log(Date.now(), itemId, options.jobId ?? "", common.SItemProgressStatus[status], percentDone.toFixed(0) + "%", costUsed, createdItemId ? "==> " + createdItemId : "");
|
|
72
70
|
}
|
|
73
71
|
if (status === common.EItemProgressStatus.Created) {
|
|
74
72
|
deployedItemIds.push(createdItemId);
|
|
@@ -88,27 +86,27 @@ function deploySolutionItems(portalSharingUrl, storageItemId, templates, storage
|
|
|
88
86
|
// Create an ordered graph of the templates so that dependencies are created before the items that need them.
|
|
89
87
|
// Because cycles are permitted, we also keep track of items that need to be patched later because their
|
|
90
88
|
// dependencies are necessarily created after they are created.
|
|
91
|
-
|
|
89
|
+
const { buildOrder, itemsToBePatched } = common.topologicallySortItems(templates);
|
|
92
90
|
// For each item in order from no dependencies to dependent on other items,
|
|
93
91
|
// * replace template symbols using template dictionary
|
|
94
92
|
// * create item in destination group
|
|
95
93
|
// * add created item's id into the template dictionary
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
const awaitAllItems = [];
|
|
95
|
+
const reuseItemsDef = _reuseDeployedItems(templates, options.enableItemReuse ?? false, templateDictionary, destinationAuthentication);
|
|
98
96
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
99
|
-
reuseItemsDef.then(
|
|
100
|
-
|
|
97
|
+
reuseItemsDef.then(() => {
|
|
98
|
+
const useExistingItemsDef = _useExistingItems(templates, common.getProp(templateDictionary, "params.useExisting"), templateDictionary, destinationAuthentication);
|
|
101
99
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
102
|
-
useExistingItemsDef.then(
|
|
100
|
+
useExistingItemsDef.then(() => {
|
|
103
101
|
templates = common.setNamesAndTitles(templates, templateDictionary.solutionItemId);
|
|
104
|
-
buildOrder.forEach(
|
|
102
|
+
buildOrder.forEach((id) => {
|
|
105
103
|
// Get the item's template out of the list of templates
|
|
106
|
-
|
|
104
|
+
const template = common.findTemplateInList(templates, id);
|
|
107
105
|
awaitAllItems.push(_createItemFromTemplateWhenReady(template, common.generateStorageFilePaths(portalSharingUrl, storageItemId, template.resources, options.storageVersion), storageAuthentication, templateDictionary, destinationAuthentication, itemProgressCallback));
|
|
108
106
|
});
|
|
109
107
|
// Wait until all items have been created
|
|
110
108
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
111
|
-
Promise.all(awaitAllItems).then(
|
|
109
|
+
Promise.all(awaitAllItems).then((clonedSolutionItems) => {
|
|
112
110
|
if (failedTemplateItemIds.length === 0) {
|
|
113
111
|
// Do we have any items to be patched (i.e., they refer to dependencies using the template id rather
|
|
114
112
|
// than the cloned id because the item had to be created before the dependency)? Flag these items
|
|
@@ -118,19 +116,17 @@ function deploySolutionItems(portalSharingUrl, storageItemId, templates, storage
|
|
|
118
116
|
}
|
|
119
117
|
else {
|
|
120
118
|
// Delete created items
|
|
121
|
-
|
|
119
|
+
const progressOptions = {
|
|
122
120
|
consoleProgress: true
|
|
123
121
|
};
|
|
124
122
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
125
123
|
common
|
|
126
124
|
.deleteSolutionByComponents(deployedSolutionId, deployedItemIds, templates, templateDictionary, destinationAuthentication, progressOptions)
|
|
127
|
-
.then(
|
|
128
|
-
return reject(common.failWithIds(failedTemplateItemIds));
|
|
129
|
-
});
|
|
125
|
+
.then(() => reject(common.failWithIds(failedTemplateItemIds)));
|
|
130
126
|
}
|
|
131
127
|
});
|
|
132
128
|
});
|
|
133
|
-
},
|
|
129
|
+
}, e => {
|
|
134
130
|
console.error(e);
|
|
135
131
|
reject(common.fail(e));
|
|
136
132
|
});
|
|
@@ -145,13 +141,13 @@ exports.deploySolutionItems = deploySolutionItems;
|
|
|
145
141
|
* @param templates A collection of AGO item templates
|
|
146
142
|
*/
|
|
147
143
|
function _flagPatchItemsForPostProcessing(itemsToBePatched, templateDictionary, templates) {
|
|
148
|
-
|
|
144
|
+
let itemIdsToBePatched = Object.keys(itemsToBePatched);
|
|
149
145
|
/* istanbul ignore else */
|
|
150
146
|
if (itemIdsToBePatched.length > 0) {
|
|
151
147
|
// Replace the ids of the items to be patched (which are template ids) with their cloned versions
|
|
152
|
-
itemIdsToBePatched = itemIdsToBePatched.map(
|
|
148
|
+
itemIdsToBePatched = itemIdsToBePatched.map(id => templateDictionary[id].itemId);
|
|
153
149
|
// Make sure that the items to be patched are flagged for post processing
|
|
154
|
-
templates.forEach(
|
|
150
|
+
templates.forEach(item => {
|
|
155
151
|
/* istanbul ignore else */
|
|
156
152
|
if (itemIdsToBePatched.includes(item.id)) {
|
|
157
153
|
item.postProcess = true;
|
|
@@ -173,16 +169,16 @@ exports._flagPatchItemsForPostProcessing = _flagPatchItemsForPostProcessing;
|
|
|
173
169
|
function _evaluateSharedViewSources(templates) {
|
|
174
170
|
// update the templates so we can defer the deployment when more than one view shares the same source
|
|
175
171
|
// these are not classic dependencies but are in some ways similar
|
|
176
|
-
|
|
172
|
+
const views = _getViews(templates);
|
|
177
173
|
_updateViewTemplates(templates, views);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
Object.keys(viewHash).forEach(
|
|
182
|
-
|
|
183
|
-
_views.forEach(
|
|
184
|
-
|
|
185
|
-
|
|
174
|
+
const viewHash = _getViewHash(views);
|
|
175
|
+
let processed = [];
|
|
176
|
+
const visited = [];
|
|
177
|
+
Object.keys(viewHash).forEach(k => {
|
|
178
|
+
const _views = viewHash[k];
|
|
179
|
+
_views.forEach(cv => {
|
|
180
|
+
const template = common.findTemplateInList(templates, cv);
|
|
181
|
+
const syncViews = common.getProp(template, "properties.syncViews");
|
|
186
182
|
/* istanbul ignore else */
|
|
187
183
|
if (visited.indexOf(template.itemId) > -1) {
|
|
188
184
|
processed = processed.concat(syncViews);
|
|
@@ -218,9 +214,9 @@ exports._evaluateSharedViewSources = _evaluateSharedViewSources;
|
|
|
218
214
|
*
|
|
219
215
|
*/
|
|
220
216
|
function _updateViewTemplates(templates, views) {
|
|
221
|
-
views.forEach(
|
|
222
|
-
v.dependencies.forEach(
|
|
223
|
-
templates = templates.map(
|
|
217
|
+
views.forEach(v => {
|
|
218
|
+
v.dependencies.forEach((id) => {
|
|
219
|
+
templates = templates.map(t => {
|
|
224
220
|
/* istanbul ignore else */
|
|
225
221
|
if (common.getProp(t, "properties.service.isView") &&
|
|
226
222
|
t.dependencies.indexOf(id) > -1 &&
|
|
@@ -252,9 +248,9 @@ exports._updateViewTemplates = _updateViewTemplates;
|
|
|
252
248
|
* @protected
|
|
253
249
|
*/
|
|
254
250
|
function _getViewHash(views) {
|
|
255
|
-
|
|
256
|
-
views.forEach(
|
|
257
|
-
v.dependencies.forEach(
|
|
251
|
+
const viewHash = {};
|
|
252
|
+
views.forEach(v => {
|
|
253
|
+
v.dependencies.forEach((d) => {
|
|
258
254
|
/* istanbul ignore else */
|
|
259
255
|
if (Object.keys(viewHash).indexOf(d) < 0) {
|
|
260
256
|
viewHash[d] = [v.id];
|
|
@@ -277,7 +273,7 @@ exports._getViewHash = _getViewHash;
|
|
|
277
273
|
* @protected
|
|
278
274
|
*/
|
|
279
275
|
function _getViews(templates) {
|
|
280
|
-
return templates.reduce(
|
|
276
|
+
return templates.reduce((acc, v) => {
|
|
281
277
|
/* istanbul ignore else */
|
|
282
278
|
if (common.getProp(v, "properties.service.isView")) {
|
|
283
279
|
acc.push({
|
|
@@ -302,17 +298,17 @@ exports._getViews = _getViews;
|
|
|
302
298
|
* @protected
|
|
303
299
|
*/
|
|
304
300
|
function _reuseDeployedItems(templates, reuseItems, templateDictionary, authentication) {
|
|
305
|
-
return new Promise(
|
|
301
|
+
return new Promise((resolve, reject) => {
|
|
306
302
|
if (reuseItems) {
|
|
307
|
-
|
|
308
|
-
Promise.all(existingItemsByKeyword).then(
|
|
309
|
-
|
|
310
|
-
Promise.all(existingItemsByTag).then(
|
|
303
|
+
const existingItemsByKeyword = _findExistingItemByKeyword(templates, templateDictionary, authentication);
|
|
304
|
+
Promise.all(existingItemsByKeyword).then((existingItemsByKeywordResponse) => {
|
|
305
|
+
const existingItemsByTag = _handleExistingItems(existingItemsByKeywordResponse, templateDictionary, authentication, true);
|
|
306
|
+
Promise.all(existingItemsByTag).then(existingItemsByTagResponse => {
|
|
311
307
|
_handleExistingItems(existingItemsByTagResponse, templateDictionary, authentication, false);
|
|
312
308
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
313
309
|
_updateTemplateDictionary(templates, templateDictionary, authentication).then(resolve);
|
|
314
|
-
},
|
|
315
|
-
},
|
|
310
|
+
}, e => reject(common.fail(e)));
|
|
311
|
+
}, e => reject(common.fail(e)));
|
|
316
312
|
}
|
|
317
313
|
else {
|
|
318
314
|
resolve(null);
|
|
@@ -341,30 +337,30 @@ exports._reuseDeployedItems = _reuseDeployedItems;
|
|
|
341
337
|
* @protected
|
|
342
338
|
*/
|
|
343
339
|
function _useExistingItems(templates, useExisting, templateDictionary, authentication) {
|
|
344
|
-
return new Promise(
|
|
340
|
+
return new Promise(resolve => {
|
|
345
341
|
if (useExisting) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
Object.keys(templateDictionary.params).forEach(
|
|
350
|
-
|
|
342
|
+
const itemDefs = [];
|
|
343
|
+
const sourceIdHash = {};
|
|
344
|
+
const itemIds = [];
|
|
345
|
+
Object.keys(templateDictionary.params).forEach(k => {
|
|
346
|
+
const v = templateDictionary.params[k];
|
|
351
347
|
/* istanbul ignore else */
|
|
352
348
|
if (v.itemId && /[0-9A-F]{32}/i.test(k)) {
|
|
353
349
|
_updateTemplateDictionaryById(templateDictionary, k, v.itemId, v);
|
|
354
350
|
// need to check and set the typeKeyword if it doesn't exist on this service yet
|
|
355
351
|
// when the user has passed in an itemId that does not come from a previous deployment
|
|
356
|
-
|
|
357
|
-
|
|
352
|
+
itemDefs.push(common.getItemBase(v.itemId, authentication));
|
|
353
|
+
sourceIdHash[v.itemId] = k;
|
|
358
354
|
/* istanbul ignore else */
|
|
359
|
-
if (
|
|
360
|
-
|
|
355
|
+
if (itemIds.indexOf(k) < 0) {
|
|
356
|
+
itemIds.push(k);
|
|
361
357
|
}
|
|
362
358
|
}
|
|
363
359
|
});
|
|
364
360
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
365
|
-
_setTypekeywordForExisting(
|
|
361
|
+
_setTypekeywordForExisting(itemDefs, sourceIdHash, authentication).then(() => {
|
|
366
362
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
367
|
-
_updateTemplateDictionary(
|
|
363
|
+
_updateTemplateDictionary(itemIds.map(id => common.getTemplateById(templates, id)), templateDictionary, authentication).then(resolve);
|
|
368
364
|
});
|
|
369
365
|
}
|
|
370
366
|
else {
|
|
@@ -385,32 +381,32 @@ exports._useExistingItems = _useExistingItems;
|
|
|
385
381
|
* @return a promise to indicate when the requests are complete
|
|
386
382
|
*/
|
|
387
383
|
function _setTypekeywordForExisting(itemDefs, sourceIdHash, authentication) {
|
|
388
|
-
return new Promise(
|
|
384
|
+
return new Promise(resolve => {
|
|
389
385
|
if (itemDefs.length > 0) {
|
|
390
|
-
Promise.all(itemDefs).then(
|
|
391
|
-
|
|
392
|
-
results.forEach(
|
|
393
|
-
|
|
386
|
+
Promise.all(itemDefs).then(results => {
|
|
387
|
+
const itemUpdateDefs = [];
|
|
388
|
+
results.forEach(result => {
|
|
389
|
+
const sourceId = sourceIdHash[result.id];
|
|
394
390
|
/* istanbul ignore else */
|
|
395
391
|
if (result && sourceId && result.typeKeywords) {
|
|
396
|
-
|
|
397
|
-
|
|
392
|
+
const sourceKeyword = `source-${sourceId}`;
|
|
393
|
+
const typeKeywords = result.typeKeywords;
|
|
398
394
|
/* istanbul ignore else */
|
|
399
395
|
if (typeKeywords.indexOf(sourceKeyword) < 0) {
|
|
400
396
|
typeKeywords.push(sourceKeyword);
|
|
401
|
-
|
|
397
|
+
const itemUpdate = { id: result.id, typeKeywords };
|
|
402
398
|
itemUpdateDefs.push(common.updateItem(itemUpdate, authentication));
|
|
403
399
|
}
|
|
404
400
|
}
|
|
405
401
|
});
|
|
406
402
|
// wait for updates to finish before we resolve
|
|
407
403
|
if (itemUpdateDefs.length > 0) {
|
|
408
|
-
Promise.all(itemUpdateDefs).then(resolve,
|
|
404
|
+
Promise.all(itemUpdateDefs).then(resolve, () => resolve(undefined));
|
|
409
405
|
}
|
|
410
406
|
else {
|
|
411
407
|
resolve(undefined);
|
|
412
408
|
}
|
|
413
|
-
},
|
|
409
|
+
}, () => resolve(undefined));
|
|
414
410
|
}
|
|
415
411
|
else {
|
|
416
412
|
resolve(undefined);
|
|
@@ -427,18 +423,18 @@ exports._setTypekeywordForExisting = _setTypekeywordForExisting;
|
|
|
427
423
|
* @protected
|
|
428
424
|
*/
|
|
429
425
|
function _updateTemplateDictionary(templates, templateDictionary, authentication) {
|
|
430
|
-
return new Promise(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
templates.forEach(
|
|
436
|
-
|
|
426
|
+
return new Promise(resolve => {
|
|
427
|
+
const defs = [];
|
|
428
|
+
const urls = [];
|
|
429
|
+
const types = [];
|
|
430
|
+
const ids = [];
|
|
431
|
+
templates.forEach(t => {
|
|
432
|
+
const templateInfo = templateDictionary[t.itemId];
|
|
437
433
|
/* istanbul ignore else */
|
|
438
434
|
if (templateInfo && templateInfo.url && templateInfo.itemId) {
|
|
439
435
|
/* istanbul ignore else */
|
|
440
436
|
if (t.item.type === "Feature Service") {
|
|
441
|
-
|
|
437
|
+
const enterpriseIDMapping = common.getProp(templateDictionary, `params.${t.itemId}.enterpriseIDMapping`);
|
|
442
438
|
Object.assign(templateDictionary[t.itemId], common.getLayerSettings(common.getLayersAndTables(t), templateInfo.url, templateInfo.itemId, enterpriseIDMapping));
|
|
443
439
|
// if the service has veiws keep track of the fields so we can use them to
|
|
444
440
|
// compare with the view fields
|
|
@@ -454,7 +450,7 @@ function _updateTemplateDictionary(templates, templateDictionary, authentication
|
|
|
454
450
|
/* istanbul ignore else */
|
|
455
451
|
if (urls.indexOf(templateInfo.url) < 0) {
|
|
456
452
|
defs.push(t.item.type === "Feature Service"
|
|
457
|
-
? common.rest_request(templateInfo.url, { authentication
|
|
453
|
+
? common.rest_request(templateInfo.url, { authentication })
|
|
458
454
|
: common.getItemBase(templateInfo.itemId, authentication));
|
|
459
455
|
urls.push(templateInfo.url);
|
|
460
456
|
types.push(t.item.type);
|
|
@@ -464,23 +460,23 @@ function _updateTemplateDictionary(templates, templateDictionary, authentication
|
|
|
464
460
|
});
|
|
465
461
|
if (defs.length > 0) {
|
|
466
462
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
467
|
-
Promise.all(defs.map(
|
|
463
|
+
Promise.all(defs.map(p => p.catch(e => e))).then(results => {
|
|
468
464
|
/* istanbul ignore else */
|
|
469
465
|
if (Array.isArray(results) && results.length > 0) {
|
|
470
|
-
|
|
471
|
-
results.forEach(
|
|
466
|
+
const fieldDefs = [];
|
|
467
|
+
results.forEach((r, i) => {
|
|
472
468
|
// a feature service result will contain a serviceItemId if it was successfully fetched
|
|
473
469
|
if (r.serviceItemId && types[i] === "Feature Service") {
|
|
474
|
-
Object.keys(templateDictionary).forEach(
|
|
475
|
-
|
|
470
|
+
Object.keys(templateDictionary).forEach(k => {
|
|
471
|
+
const v = templateDictionary[k];
|
|
476
472
|
/* istanbul ignore else */
|
|
477
473
|
if (v.itemId && v.itemId === r.serviceItemId) {
|
|
478
474
|
common.setDefaultSpatialReference(templateDictionary, k, r.spatialReference);
|
|
479
475
|
// keep the extent values from these responses as well
|
|
480
|
-
common.setCreateProp(templateDictionary, k
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
476
|
+
common.setCreateProp(templateDictionary, `${k}.defaultExtent`, r.fullExtent || r.initialExtent);
|
|
477
|
+
const layerIds = (r.layers || []).map((l) => l.id);
|
|
478
|
+
const tablesIds = (r.tables || []).map((t) => t.id);
|
|
479
|
+
fieldDefs.push(common.getExistingLayersAndTables(urls[i], layerIds.concat(tablesIds), authentication));
|
|
484
480
|
}
|
|
485
481
|
});
|
|
486
482
|
}
|
|
@@ -493,26 +489,26 @@ function _updateTemplateDictionary(templates, templateDictionary, authentication
|
|
|
493
489
|
}
|
|
494
490
|
}
|
|
495
491
|
});
|
|
496
|
-
if (
|
|
492
|
+
if (fieldDefs.length > 0) {
|
|
497
493
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
498
|
-
Promise.all(
|
|
499
|
-
layerTableResult.forEach(
|
|
500
|
-
l.forEach(
|
|
501
|
-
Object.keys(templateDictionary).forEach(
|
|
494
|
+
Promise.all(fieldDefs).then(layerTableResult => {
|
|
495
|
+
layerTableResult.forEach(l => {
|
|
496
|
+
l.forEach((ll) => {
|
|
497
|
+
Object.keys(templateDictionary).forEach(k => {
|
|
502
498
|
/* istanbul ignore else */
|
|
503
499
|
if (templateDictionary[k].itemId === ll.serviceItemId) {
|
|
504
|
-
|
|
505
|
-
Object.keys(templateDictionary).some(
|
|
500
|
+
let sourceId = "";
|
|
501
|
+
Object.keys(templateDictionary).some(_k => {
|
|
506
502
|
/* istanbul ignore else */
|
|
507
503
|
if (templateDictionary[_k].itemId === ll.serviceItemId) {
|
|
508
|
-
|
|
504
|
+
sourceId = _k;
|
|
509
505
|
return true;
|
|
510
506
|
}
|
|
511
507
|
});
|
|
512
|
-
|
|
513
|
-
if (
|
|
514
|
-
Object.keys(
|
|
515
|
-
if (
|
|
508
|
+
const enterpriseIDMapping = common.getProp(templateDictionary, `params.${sourceId}.enterpriseIDMapping`);
|
|
509
|
+
if (enterpriseIDMapping) {
|
|
510
|
+
Object.keys(enterpriseIDMapping).forEach(id => {
|
|
511
|
+
if (enterpriseIDMapping[id].toString() ===
|
|
516
512
|
ll.id.toString()) {
|
|
517
513
|
_setFields(templateDictionary, k, id, ll.fields);
|
|
518
514
|
}
|
|
@@ -554,7 +550,7 @@ exports._updateTemplateDictionary = _updateTemplateDictionary;
|
|
|
554
550
|
* @protected
|
|
555
551
|
*/
|
|
556
552
|
function _setFields(templateDictionary, itemId, layerId, fields) {
|
|
557
|
-
|
|
553
|
+
const layerInfo = common.getProp(templateDictionary, `${itemId}.layer${layerId}`);
|
|
558
554
|
/* istanbul ignore else */
|
|
559
555
|
if (layerInfo && fields) {
|
|
560
556
|
layerInfo.fields = fields;
|
|
@@ -576,17 +572,17 @@ exports._setFields = _setFields;
|
|
|
576
572
|
function _updateTemplateDictionaryForError(templateDictionary, itemId) {
|
|
577
573
|
/* istanbul ignore else */
|
|
578
574
|
if (itemId) {
|
|
579
|
-
|
|
580
|
-
Object.keys(templateDictionary).some(
|
|
575
|
+
let removeKey = "";
|
|
576
|
+
Object.keys(templateDictionary).some(k => {
|
|
581
577
|
/* istanbul ignore else */
|
|
582
578
|
if (templateDictionary[k].itemId === itemId) {
|
|
583
|
-
|
|
579
|
+
removeKey = k;
|
|
584
580
|
return true;
|
|
585
581
|
}
|
|
586
582
|
});
|
|
587
583
|
/* istanbul ignore else */
|
|
588
|
-
if (
|
|
589
|
-
delete templateDictionary[
|
|
584
|
+
if (removeKey !== "") {
|
|
585
|
+
delete templateDictionary[removeKey];
|
|
590
586
|
}
|
|
591
587
|
}
|
|
592
588
|
return templateDictionary;
|
|
@@ -604,30 +600,28 @@ exports._updateTemplateDictionaryForError = _updateTemplateDictionaryForError;
|
|
|
604
600
|
*/
|
|
605
601
|
function _handleExistingItems(existingItemsResponse, templateDictionary, authentication, addTagQuery) {
|
|
606
602
|
// if items are not found by type keyword search by tag
|
|
607
|
-
|
|
603
|
+
const existingItemsByTag = [Promise.resolve(null)];
|
|
608
604
|
/* istanbul ignore else */
|
|
609
605
|
if (existingItemsResponse && Array.isArray(existingItemsResponse)) {
|
|
610
|
-
existingItemsResponse.forEach(
|
|
606
|
+
existingItemsResponse.forEach(existingItem => {
|
|
611
607
|
/* istanbul ignore else */
|
|
612
|
-
if (Array.isArray(existingItem
|
|
613
|
-
|
|
614
|
-
|
|
608
|
+
if (Array.isArray(existingItem?.results)) {
|
|
609
|
+
let result;
|
|
610
|
+
const results = existingItem.results;
|
|
615
611
|
if (results.length === 1) {
|
|
616
612
|
result = results[0];
|
|
617
613
|
}
|
|
618
614
|
else if (results.length > 1) {
|
|
619
|
-
result = results.reduce(
|
|
620
|
-
return a.created > b.created ? a : b;
|
|
621
|
-
});
|
|
615
|
+
result = results.reduce((a, b) => a.created > b.created ? a : b);
|
|
622
616
|
}
|
|
623
617
|
else {
|
|
624
618
|
if (addTagQuery && existingItem.query) {
|
|
625
|
-
|
|
619
|
+
const tagQuery = existingItem.query.replace("typekeywords", "tags");
|
|
626
620
|
existingItemsByTag.push(_findExistingItem(tagQuery, authentication));
|
|
627
621
|
}
|
|
628
622
|
}
|
|
629
623
|
if (result) {
|
|
630
|
-
|
|
624
|
+
const sourceId = existingItem.query
|
|
631
625
|
? existingItem.query.match(/[0-9A-F]{32}/i)[0]
|
|
632
626
|
: existingItem.sourceId;
|
|
633
627
|
/* istanbul ignore else */
|
|
@@ -644,7 +638,7 @@ exports._handleExistingItems = _handleExistingItems;
|
|
|
644
638
|
function _updateTemplateDictionaryById(templateDictionary, sourceId, itemId, v) {
|
|
645
639
|
templateDictionary[sourceId] = Object.assign(templateDictionary[sourceId] || {}, {
|
|
646
640
|
def: Promise.resolve(common.generateEmptyCreationResponse(v.type, itemId)),
|
|
647
|
-
itemId
|
|
641
|
+
itemId,
|
|
648
642
|
name: v.name,
|
|
649
643
|
title: v.title,
|
|
650
644
|
url: v.url
|
|
@@ -660,17 +654,16 @@ exports._updateTemplateDictionaryById = _updateTemplateDictionaryById;
|
|
|
660
654
|
* @protected
|
|
661
655
|
*/
|
|
662
656
|
function _findExistingItemByKeyword(templates, templateDictionary, authentication) {
|
|
663
|
-
|
|
664
|
-
templates.forEach(
|
|
665
|
-
var _a;
|
|
657
|
+
const existingItemsDefs = [];
|
|
658
|
+
templates.forEach(template => {
|
|
666
659
|
if (template.item.type === "Group") {
|
|
667
|
-
|
|
660
|
+
const userGroups = templateDictionary.user?.groups;
|
|
668
661
|
/* istanbul ignore else */
|
|
669
662
|
if (Array.isArray(userGroups)) {
|
|
670
663
|
existingItemsDefs.push(Promise.resolve({
|
|
671
664
|
results: userGroups
|
|
672
|
-
.filter(
|
|
673
|
-
.map(
|
|
665
|
+
.filter(g => g.tags.indexOf(`source-${template.itemId}`) > -1)
|
|
666
|
+
.map(g => {
|
|
674
667
|
g.type = "Group";
|
|
675
668
|
return g;
|
|
676
669
|
}),
|
|
@@ -679,7 +672,7 @@ function _findExistingItemByKeyword(templates, templateDictionary, authenticatio
|
|
|
679
672
|
}
|
|
680
673
|
}
|
|
681
674
|
else {
|
|
682
|
-
existingItemsDefs.push(_findExistingItem(
|
|
675
|
+
existingItemsDefs.push(_findExistingItem(`typekeywords:source-${template.itemId} type:${template.item.type} owner:${templateDictionary.user.username}`, authentication));
|
|
683
676
|
}
|
|
684
677
|
});
|
|
685
678
|
return existingItemsDefs;
|
|
@@ -694,7 +687,7 @@ exports._findExistingItemByKeyword = _findExistingItemByKeyword;
|
|
|
694
687
|
* @protected
|
|
695
688
|
*/
|
|
696
689
|
function _findExistingItem(query, authentication) {
|
|
697
|
-
|
|
690
|
+
const searchOptions = {
|
|
698
691
|
q: query,
|
|
699
692
|
authentication: authentication,
|
|
700
693
|
pagingParam: { start: 1, num: 100 }
|
|
@@ -721,16 +714,16 @@ function _createItemFromTemplateWhenReady(template, resourceFilePaths, storageAu
|
|
|
721
714
|
// or if we have a basic entry without the deferred request for its creation, add it
|
|
722
715
|
if (!templateDictionary.hasOwnProperty(template.itemId) ||
|
|
723
716
|
!common.getProp(templateDictionary[template.itemId], "def")) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
717
|
+
let createResponse;
|
|
718
|
+
let statusCode = common.EItemProgressStatus.Unknown;
|
|
719
|
+
let itemHandler;
|
|
727
720
|
templateDictionary[template.itemId] =
|
|
728
721
|
templateDictionary[template.itemId] || {};
|
|
729
722
|
// Save the deferred for the use of items that depend on this item being created first
|
|
730
|
-
templateDictionary[template.itemId].def = new Promise(
|
|
723
|
+
templateDictionary[template.itemId].def = new Promise(resolve => {
|
|
731
724
|
// Wait until all of the item's dependencies are deployed
|
|
732
|
-
|
|
733
|
-
|
|
725
|
+
const _awaitDependencies = template.dependencies.reduce((acc, id) => {
|
|
726
|
+
const def = common.getProp(templateDictionary, `${id}.def`);
|
|
734
727
|
// can't use maybePush as that clones the object, which does not work for Promises
|
|
735
728
|
/* istanbul ignore else */
|
|
736
729
|
if (def) {
|
|
@@ -738,10 +731,10 @@ function _createItemFromTemplateWhenReady(template, resourceFilePaths, storageAu
|
|
|
738
731
|
}
|
|
739
732
|
return acc;
|
|
740
733
|
}, []);
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
? syncViews.reduce(
|
|
744
|
-
|
|
734
|
+
const syncViews = common.getProp(template, "properties.syncViews");
|
|
735
|
+
const awaitDependencies = syncViews && syncViews.length > 0
|
|
736
|
+
? syncViews.reduce((acc, v) => {
|
|
737
|
+
const def = common.getProp(templateDictionary, `${v}.def`);
|
|
745
738
|
/* istanbul ignore else */
|
|
746
739
|
if (def) {
|
|
747
740
|
acc.push(def);
|
|
@@ -750,55 +743,55 @@ function _createItemFromTemplateWhenReady(template, resourceFilePaths, storageAu
|
|
|
750
743
|
}, _awaitDependencies)
|
|
751
744
|
: _awaitDependencies;
|
|
752
745
|
Promise.all(awaitDependencies)
|
|
753
|
-
.then(
|
|
746
|
+
.then(() => {
|
|
754
747
|
// Find the conversion handler for this item type
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
if (!
|
|
758
|
-
if (
|
|
759
|
-
|
|
748
|
+
const templateType = template.type;
|
|
749
|
+
itemHandler = module_map_1.moduleMap[templateType];
|
|
750
|
+
if (!itemHandler || itemHandler === UNSUPPORTED) {
|
|
751
|
+
if (itemHandler === UNSUPPORTED) {
|
|
752
|
+
statusCode = common.EItemProgressStatus.Ignored;
|
|
760
753
|
throw new Error();
|
|
761
754
|
}
|
|
762
755
|
else {
|
|
763
|
-
|
|
756
|
+
statusCode = common.EItemProgressStatus.Failed;
|
|
764
757
|
throw new Error();
|
|
765
758
|
}
|
|
766
759
|
}
|
|
767
760
|
// Get the item's thumbnail
|
|
768
761
|
return common.getThumbnailFromStorageItem(storageAuthentication, resourceFilePaths);
|
|
769
762
|
})
|
|
770
|
-
.then(
|
|
763
|
+
.then(thumbnail => {
|
|
771
764
|
template.item.thumbnail = thumbnail;
|
|
772
765
|
// Delegate the creation of the item to the handler
|
|
773
766
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
774
|
-
return
|
|
767
|
+
return itemHandler.createItemFromTemplate(template, templateDictionary, destinationAuthentication, itemProgressCallback);
|
|
775
768
|
})
|
|
776
|
-
.then(
|
|
769
|
+
.then((response) => {
|
|
777
770
|
if (response.id === "") {
|
|
778
|
-
|
|
771
|
+
statusCode = common.EItemProgressStatus.Failed;
|
|
779
772
|
throw new Error("handled"); // fails to create item
|
|
780
773
|
}
|
|
781
774
|
/* istanbul ignore else */
|
|
782
|
-
|
|
783
|
-
if (
|
|
784
|
-
common.setCreateProp(templateDictionary, template.itemId + ".url",
|
|
775
|
+
createResponse = response;
|
|
776
|
+
if (createResponse.item.item.url) {
|
|
777
|
+
common.setCreateProp(templateDictionary, template.itemId + ".url", createResponse.item.item.url);
|
|
785
778
|
}
|
|
786
779
|
if (resourceFilePaths.length > 0) {
|
|
787
780
|
// Copy resources, metadata, form
|
|
788
|
-
return common.copyFilesFromStorageItem(storageAuthentication, resourceFilePaths, templateDictionary.folderId,
|
|
781
|
+
return common.copyFilesFromStorageItem(storageAuthentication, resourceFilePaths, templateDictionary.folderId, createResponse.id, destinationAuthentication, createResponse.item);
|
|
789
782
|
}
|
|
790
783
|
else {
|
|
791
784
|
return Promise.resolve(null);
|
|
792
785
|
}
|
|
793
786
|
})
|
|
794
|
-
.then(
|
|
795
|
-
resolve(
|
|
787
|
+
.then(() => {
|
|
788
|
+
resolve(createResponse);
|
|
796
789
|
})
|
|
797
|
-
.catch(
|
|
790
|
+
.catch(error => {
|
|
798
791
|
if (!error || error.message !== "handled") {
|
|
799
|
-
itemProgressCallback(template.itemId,
|
|
792
|
+
itemProgressCallback(template.itemId, statusCode === common.EItemProgressStatus.Unknown
|
|
800
793
|
? common.EItemProgressStatus.Failed
|
|
801
|
-
:
|
|
794
|
+
: statusCode, 0);
|
|
802
795
|
}
|
|
803
796
|
// Item type not supported or fails to get item dependencies
|
|
804
797
|
resolve(common.generateEmptyCreationResponse(template.type));
|
|
@@ -816,16 +809,16 @@ exports._createItemFromTemplateWhenReady = _createItemFromTemplateWhenReady;
|
|
|
816
809
|
* @protected
|
|
817
810
|
*/
|
|
818
811
|
function _estimateDeploymentCost(templates) {
|
|
819
|
-
return templates.reduce(
|
|
812
|
+
return templates.reduce((accumulatedEstimatedCost, template) => {
|
|
820
813
|
return (accumulatedEstimatedCost + (template.estimatedDeploymentCostFactor || 1));
|
|
821
814
|
}, 0);
|
|
822
815
|
}
|
|
823
816
|
exports._estimateDeploymentCost = _estimateDeploymentCost;
|
|
824
817
|
// TODO: Return a Promise vs array of promises
|
|
825
818
|
function _getGroupUpdates(template, authentication, templateDictionary) {
|
|
826
|
-
|
|
827
|
-
return groups.map(
|
|
828
|
-
return common.shareItem(templateDictionary[sourceGroupId].itemId, template.itemId, authentication);
|
|
819
|
+
const groups = template.groups || [];
|
|
820
|
+
return groups.map((sourceGroupId) => {
|
|
821
|
+
return common.shareItem(templateDictionary[sourceGroupId].itemId, template.itemId, authentication, common.isTrackingViewTemplate(template) ? templateDictionary.locationTracking.owner : undefined);
|
|
829
822
|
});
|
|
830
823
|
}
|
|
831
824
|
exports._getGroupUpdates = _getGroupUpdates;
|