apn-app-manager 1.4.1 → 1.5.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/README.md +2 -1
- package/package.json +1 -1
- package/src/actions/cloneAction.js +17 -3
- package/src/handlers/objectExtractHandler.js +16 -1
- package/src/handlers/objectMapsUpdateHandler.js +15 -11
- package/src/objectProps.js +31 -15
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ The functionality provided by this tool is not supported, nor endorsed by Appian
|
|
|
12
12
|
|
|
13
13
|
Importing an application export modified by this tool should be done at your own discretion.
|
|
14
14
|
|
|
15
|
-
Latest compatible Appian platform version tested against: **
|
|
15
|
+
Latest compatible Appian platform version tested against: **23.3**.
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
@@ -43,6 +43,7 @@ Used to duplicate all objects of an application, which replaces the namespace of
|
|
|
43
43
|
1. Enter your current namespace.
|
|
44
44
|
- For example, an application with objects such as `SMP APP Artifacts` and `SMP_APP_displayUser` would have a namespace of `SMP_APP`
|
|
45
45
|
1. Enter your new namespace.
|
|
46
|
+
1. Do advanced options if necessary.
|
|
46
47
|
1. Access your cloned application in the generated `/out/` folder.
|
|
47
48
|
|
|
48
49
|
#### Notes
|
package/package.json
CHANGED
|
@@ -14,6 +14,11 @@ const obExtract = require("../handlers/objectExtractHandler");
|
|
|
14
14
|
const obMapsUpdates = require("../handlers/objectMapsUpdateHandler");
|
|
15
15
|
const obModify = require("../handlers/objectModifyHandler");
|
|
16
16
|
|
|
17
|
+
// Options
|
|
18
|
+
const options = {
|
|
19
|
+
renameDbTables: true,
|
|
20
|
+
};
|
|
21
|
+
|
|
17
22
|
// Entry-point
|
|
18
23
|
function main(callback) {
|
|
19
24
|
util.delFile(cons.outDir);
|
|
@@ -24,7 +29,16 @@ function main(callback) {
|
|
|
24
29
|
promptNamespace("What is your new namespace?", function (newNamespace) {
|
|
25
30
|
const namespaceMap = {};
|
|
26
31
|
namespaceMap[curNamespace] = { newNamespace: newNamespace };
|
|
27
|
-
|
|
32
|
+
prompt.promptList("Advanced options?", ["No", "Yes"], function (enhancedOptions) {
|
|
33
|
+
if (enhancedOptions == "Yes") {
|
|
34
|
+
prompt.promptList("Rename database tables?", ["Yes", "No"], function (renameDbTables) {
|
|
35
|
+
options["renameDbTables"] = renameDbTables == "Yes";
|
|
36
|
+
executeClone(appZipPath, icfPath, namespaceMap, options, callback);
|
|
37
|
+
});
|
|
38
|
+
} else {
|
|
39
|
+
executeClone(appZipPath, icfPath, namespaceMap, options, callback);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
28
42
|
});
|
|
29
43
|
});
|
|
30
44
|
});
|
|
@@ -32,7 +46,7 @@ function main(callback) {
|
|
|
32
46
|
}
|
|
33
47
|
|
|
34
48
|
// Executes all the steps of the clone
|
|
35
|
-
function executeClone(appZipPath, icfPath, namespaceMap, callback) {
|
|
49
|
+
function executeClone(appZipPath, icfPath, namespaceMap, options, callback) {
|
|
36
50
|
// Initialize output variables
|
|
37
51
|
const outZipPath = path.resolve(cons.outDir, path.basename(appZipPath));
|
|
38
52
|
const outIcfPath = icfPath ? path.resolve(cons.outDir, path.basename(icfPath)) : null;
|
|
@@ -53,7 +67,7 @@ function executeClone(appZipPath, icfPath, namespaceMap, callback) {
|
|
|
53
67
|
|
|
54
68
|
// Update the object maps we are cloning based on the application prefix
|
|
55
69
|
util.print(`Cloning the objects files...`);
|
|
56
|
-
obMapsUpdates.renameObjectMaps(objectMaps, uuidCollector, namespaceMap, obProps.usageTypes.CLONE);
|
|
70
|
+
obMapsUpdates.renameObjectMaps(objectMaps, uuidCollector, namespaceMap, options, obProps.usageTypes.CLONE);
|
|
57
71
|
|
|
58
72
|
// These output files are helpful for debugging
|
|
59
73
|
util.writeJson(path.resolve(cons.outDir, `objects.json`), objectMaps);
|
|
@@ -64,7 +64,22 @@ function extractObProps(objectMaps, uuidCollector, fileCount, obPath, usageType)
|
|
|
64
64
|
const xpath = util.replaceKeys(haulField.xpath, { "{OBTYPE}": obType });
|
|
65
65
|
let result = util.xpath(xpath, fileContent, haulField.isArray, obProps.xmlNamespaces);
|
|
66
66
|
if (!util.isBlank(haulField.extractRegex) && !util.isBlank(result)) {
|
|
67
|
-
|
|
67
|
+
if (!haulField.isArray) {
|
|
68
|
+
result = util.firstMatch(result, haulField.extractRegex, "");
|
|
69
|
+
} else {
|
|
70
|
+
if (!Array.isArray(result)) {
|
|
71
|
+
result = util.regexMatches(result, haulField.extractRegex);
|
|
72
|
+
} else {
|
|
73
|
+
console.log("i did this");
|
|
74
|
+
result = result
|
|
75
|
+
.map(function (thisResult) {
|
|
76
|
+
return util.firstMatch(thisResult, haulField.extractRegex, "");
|
|
77
|
+
})
|
|
78
|
+
.filter(function (thisResult) {
|
|
79
|
+
return thisResult != "";
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
68
83
|
}
|
|
69
84
|
builder[haulField.fieldName] = result;
|
|
70
85
|
}
|
|
@@ -11,9 +11,9 @@ const { remove } = require("fs-extra");
|
|
|
11
11
|
// Exports
|
|
12
12
|
module.exports = {
|
|
13
13
|
// Goes through all of the objectMaps and creates new name, uuid, etc.
|
|
14
|
-
renameObjectMaps: function (objectMaps, uuidCollector, namespaceMap, usageType) {
|
|
14
|
+
renameObjectMaps: function (objectMaps, uuidCollector, namespaceMap, options, usageType) {
|
|
15
15
|
// Update all objectMaps with new names
|
|
16
|
-
renameObjectMaps(objectMaps, uuidCollector, namespaceMap, usageType);
|
|
16
|
+
renameObjectMaps(objectMaps, uuidCollector, namespaceMap, options, usageType);
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -22,7 +22,7 @@ module.exports = {
|
|
|
22
22
|
// ---------------------------------------------------
|
|
23
23
|
|
|
24
24
|
// Goes through all of the objectMaps and creates new name, uuid, etc.
|
|
25
|
-
function renameObjectMaps(objectMaps, uuidCollector, namespaceMap, usageType) {
|
|
25
|
+
function renameObjectMaps(objectMaps, uuidCollector, namespaceMap, options, usageType) {
|
|
26
26
|
obProps.haulTypes.forEach(haulType => {
|
|
27
27
|
objectMaps[haulType.haulName].forEach(function (objectMap, objectMapIndex) {
|
|
28
28
|
let curNamespaceForObject = findNamespaceForObject(objectMap["current"][obProps.fieldNames.NAME], namespaceMap);
|
|
@@ -44,16 +44,20 @@ function renameObjectMaps(objectMaps, uuidCollector, namespaceMap, usageType) {
|
|
|
44
44
|
let newValue;
|
|
45
45
|
let curValue = objectMap["current"][haulField.fieldName];
|
|
46
46
|
removeFoundUuids(uuidCollector, haulField, curValue);
|
|
47
|
-
if (haulField.
|
|
48
|
-
|
|
49
|
-
curValue.forEach(curValueIter => {
|
|
50
|
-
newValueArray.push(renameObjectProp(curValueIter, haulField, curNamespaceForObject, newNamespaceForObject));
|
|
51
|
-
});
|
|
52
|
-
newValue = newValueArray;
|
|
47
|
+
if (haulField.fieldName == obProps.fieldNames.DB_TABLE && !options.renameDbTables) {
|
|
48
|
+
newValue = curValue;
|
|
53
49
|
} else {
|
|
54
|
-
|
|
50
|
+
if (haulField.isArray) {
|
|
51
|
+
let newValueArray = [];
|
|
52
|
+
curValue.forEach(curValueIter => {
|
|
53
|
+
newValueArray.push(renameObjectProp(curValueIter, haulField, curNamespaceForObject, newNamespaceForObject));
|
|
54
|
+
});
|
|
55
|
+
newValue = newValueArray;
|
|
56
|
+
} else {
|
|
57
|
+
newValue = renameObjectProp(curValue, haulField, curNamespaceForObject, newNamespaceForObject);
|
|
58
|
+
}
|
|
59
|
+
objectMaps[haulType.haulName][objectMapIndex]["new"][haulField.fieldName] = newValue;
|
|
55
60
|
}
|
|
56
|
-
objectMaps[haulType.haulName][objectMapIndex]["new"][haulField.fieldName] = newValue;
|
|
57
61
|
}
|
|
58
62
|
});
|
|
59
63
|
}
|
package/src/objectProps.js
CHANGED
|
@@ -17,11 +17,13 @@ const obTypes = {
|
|
|
17
17
|
APPLICATION: "application",
|
|
18
18
|
REPORT: "tempoReport",
|
|
19
19
|
SITE: "site",
|
|
20
|
+
PORTAL: "portal",
|
|
20
21
|
WEBAPI: "webApi",
|
|
21
22
|
GROUP: "group",
|
|
22
23
|
GROUPTYPE: "groupType",
|
|
23
24
|
PROCESSMODELFOLDER: "processModelFolder",
|
|
24
25
|
CONNECTEDSYSTEM: "connectedSystem",
|
|
26
|
+
AISKILL: "aiSkill",
|
|
25
27
|
CONTENT: "content", // obTypes.CONTENT contains: [rule, document, rulesFolder, constant, folder, communityKnowledgeCenter, decision, outboundIntegration, report (process report)]
|
|
26
28
|
};
|
|
27
29
|
|
|
@@ -32,6 +34,7 @@ const fieldNames = {
|
|
|
32
34
|
INPUT_DESCRIPTION: "inputDescription",
|
|
33
35
|
VERSION: "version",
|
|
34
36
|
CACHE_VERSION: "cacheVersionKey",
|
|
37
|
+
MODEL_IDS: "modelIds",
|
|
35
38
|
HISTORY_UUIDS: "historyUuids",
|
|
36
39
|
CDT_NAMESPACE: "cdtNamespace",
|
|
37
40
|
CDT_UUID_ENCODED: "cdtUuidEncoded",
|
|
@@ -41,7 +44,7 @@ const fieldNames = {
|
|
|
41
44
|
NODE_UUIDS: "nodeUuids",
|
|
42
45
|
PM_PERSISTENT_UUIDS: "pmPersistentUuids",
|
|
43
46
|
URL_STUB: "urlStub",
|
|
44
|
-
|
|
47
|
+
PAGE_UUIDS: "pageUuids",
|
|
45
48
|
APP_PREFIX: "appPrefix",
|
|
46
49
|
RECORD_ACTION_UUIDS: "recordActionUuids",
|
|
47
50
|
RECORD_ACTION_REF_IDS: "recordActionRefIds",
|
|
@@ -396,8 +399,8 @@ const haulTypes = [
|
|
|
396
399
|
],
|
|
397
400
|
},
|
|
398
401
|
{
|
|
399
|
-
haulName: "Reports, Sites, and Web APIs",
|
|
400
|
-
obs: [obTypes.REPORT, obTypes.SITE, obTypes.WEBAPI],
|
|
402
|
+
haulName: "Reports, Sites, Portals, and Web APIs",
|
|
403
|
+
obs: [obTypes.REPORT, obTypes.SITE, obTypes.WEBAPI, obTypes.PORTAL],
|
|
401
404
|
fields: [
|
|
402
405
|
{
|
|
403
406
|
fieldName: fieldNames.UUID,
|
|
@@ -438,8 +441,8 @@ const haulTypes = [
|
|
|
438
441
|
usage: [usageTypes.CLONE, usageTypes.BUILD],
|
|
439
442
|
},
|
|
440
443
|
{
|
|
441
|
-
fieldName: fieldNames.
|
|
442
|
-
xpath: `siteHaul/site/page/@a:uuid`,
|
|
444
|
+
fieldName: fieldNames.PAGE_UUIDS,
|
|
445
|
+
xpath: `siteHaul/site/page/@a:uuid | portalHaul/portal/navigationNode/@a:uuid`,
|
|
443
446
|
type: propTypes.UUID,
|
|
444
447
|
usage: [usageTypes.CLONE, usageTypes.BUILD],
|
|
445
448
|
isArray: true,
|
|
@@ -448,31 +451,35 @@ const haulTypes = [
|
|
|
448
451
|
},
|
|
449
452
|
{
|
|
450
453
|
haulName: "Everything Else",
|
|
451
|
-
obs: [obTypes.GROUP, obTypes.GROUPTYPE, obTypes.PROCESSMODELFOLDER, obTypes.CONNECTEDSYSTEM, obTypes.CONTENT],
|
|
454
|
+
obs: [obTypes.GROUP, obTypes.GROUPTYPE, obTypes.PROCESSMODELFOLDER, obTypes.CONNECTEDSYSTEM, obTypes.AISKILL, obTypes.CONTENT],
|
|
452
455
|
// obTypes.CONTENT contains: [rule, document, rulesFolder, constant, folder, communityKnowledgeCenter, decision, outboundIntegration, report (process report)]
|
|
456
|
+
/*
|
|
457
|
+
Note, that the leading xpath for almost every object type is `{OBTYPE}Haul` (e.g. "groupHaul"), however for AI skills it's actually "aiSkillRemoteHaul"
|
|
458
|
+
Therefore, what should be `{OBTYPE}Haul/` is now replaced with ``*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/`
|
|
459
|
+
*/
|
|
453
460
|
fields: [
|
|
454
461
|
{
|
|
455
462
|
fieldName: fieldNames.UUID,
|
|
456
|
-
xpath:
|
|
463
|
+
xpath: `*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/*[contains(name(), '')]/uuid/node()`,
|
|
457
464
|
type: propTypes.UUID,
|
|
458
465
|
usage: [usageTypes.CLONE, usageTypes.BUILD, usageTypes.RENAME],
|
|
459
466
|
},
|
|
460
467
|
{
|
|
461
468
|
fieldName: fieldNames.NAME,
|
|
462
|
-
xpath:
|
|
469
|
+
xpath: `*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/*[contains(name(), '')]/name/node()`,
|
|
463
470
|
type: propTypes.NAME,
|
|
464
471
|
usage: [usageTypes.CLONE, usageTypes.BUILD, usageTypes.RENAME],
|
|
465
472
|
},
|
|
466
473
|
{
|
|
467
474
|
fieldName: fieldNames.DESCRIPTION,
|
|
468
|
-
xpath:
|
|
475
|
+
xpath: `*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/*[contains(name(), '')]/description/node()`,
|
|
469
476
|
type: propTypes.TEXT,
|
|
470
477
|
usage: [usageTypes.CLONE, usageTypes.BUILD, usageTypes.RENAME],
|
|
471
478
|
replaceFormat: "description>{VALUE}</",
|
|
472
479
|
},
|
|
473
480
|
{
|
|
474
481
|
fieldName: fieldNames.INPUT_DESCRIPTION,
|
|
475
|
-
xpath:
|
|
482
|
+
xpath: `*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/*[contains(name(), '')]/namedTypedValue/description/node()`,
|
|
476
483
|
type: propTypes.TEXT,
|
|
477
484
|
usage: [usageTypes.CLONE, usageTypes.BUILD, usageTypes.RENAME],
|
|
478
485
|
replaceFormat: "description>{VALUE}</",
|
|
@@ -480,13 +487,13 @@ const haulTypes = [
|
|
|
480
487
|
},
|
|
481
488
|
{
|
|
482
489
|
fieldName: fieldNames.VERSION,
|
|
483
|
-
xpath:
|
|
490
|
+
xpath: `*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/versionUuid/node()`,
|
|
484
491
|
type: propTypes.UUID,
|
|
485
492
|
usage: [usageTypes.CLONE, usageTypes.BUILD],
|
|
486
493
|
},
|
|
487
494
|
{
|
|
488
495
|
fieldName: fieldNames.HISTORY_UUIDS,
|
|
489
|
-
xpath:
|
|
496
|
+
xpath: `*[starts-with(name(), '{OBTYPE}') and contains(name(), 'Haul')]/history/historyInfo/@versionUuid`,
|
|
490
497
|
type: propTypes.UUID,
|
|
491
498
|
usage: [usageTypes.CLONE, usageTypes.BUILD],
|
|
492
499
|
isArray: true,
|
|
@@ -494,7 +501,7 @@ const haulTypes = [
|
|
|
494
501
|
// Only used in documents
|
|
495
502
|
{
|
|
496
503
|
fieldName: fieldNames.DOCUMENT_RAW_NAME,
|
|
497
|
-
xpath: `
|
|
504
|
+
xpath: `contentHaul/document/name/node()`,
|
|
498
505
|
extractRegex: /.*(?=_default)/g,
|
|
499
506
|
type: propTypes.TEXT,
|
|
500
507
|
usage: [usageTypes.CLONE, usageTypes.BUILD, usageTypes.RENAME],
|
|
@@ -502,7 +509,7 @@ const haulTypes = [
|
|
|
502
509
|
// Only used in documents
|
|
503
510
|
{
|
|
504
511
|
fieldName: fieldNames.DOCUMENT_EXTENSION,
|
|
505
|
-
xpath: `
|
|
512
|
+
xpath: `contentHaul/file/node()`,
|
|
506
513
|
extractRegex: /(?<=\.).*/g,
|
|
507
514
|
type: propTypes.TEXT,
|
|
508
515
|
usage: [usageTypes.BUILD],
|
|
@@ -510,11 +517,20 @@ const haulTypes = [
|
|
|
510
517
|
// Only used in decision objects
|
|
511
518
|
{
|
|
512
519
|
fieldName: fieldNames.CACHE_VERSION,
|
|
513
|
-
xpath: `
|
|
520
|
+
xpath: `contentHaul/*[contains(name(), '')]/definition/node()`,
|
|
514
521
|
extractRegex: /(?<=versionKey: ")[A-Za-z0-9-_]{10,}[0-9][A-Za-z0-9-_]{1,}-[A-Za-z0-9-_]{10,}(?=")/g,
|
|
515
522
|
type: propTypes.UUID,
|
|
516
523
|
usage: [usageTypes.CLONE, usageTypes.BUILD],
|
|
517
524
|
},
|
|
525
|
+
// Only used in aiSkills
|
|
526
|
+
{
|
|
527
|
+
fieldName: fieldNames.MODEL_IDS,
|
|
528
|
+
xpath: `aiSkillRemoteHaul/*[contains(name(), '')]/content/node()`,
|
|
529
|
+
extractRegex: /(?<="models":.*"id":")[A-Za-z0-9-_]{10,}[0-9][A-Za-z0-9-_]{1,}-[A-Za-z0-9-_]{10,}(?=")/g,
|
|
530
|
+
type: propTypes.UUID,
|
|
531
|
+
usage: [usageTypes.CLONE, usageTypes.BUILD],
|
|
532
|
+
isArray: true,
|
|
533
|
+
},
|
|
518
534
|
],
|
|
519
535
|
},
|
|
520
536
|
];
|