mcdev 4.1.1 → 4.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/.github/ISSUE_TEMPLATE/bug.yml +2 -0
- package/.vscode/launch.json +15 -15
- package/.vscode/settings.json +1 -1
- package/README.md +18 -19
- package/docs/dist/considerations.md +66 -66
- package/lib/metadataTypes/Asset.js +7 -2
- package/lib/metadataTypes/Query.js +5 -2
- package/lib/metadataTypes/Script.js +5 -2
- package/package.json +1 -1
- package/test/mockRoot/.mcdevrc.json +1 -1
package/.vscode/launch.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
|
3
|
-
// Hover to view descriptions of existing attributes.
|
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "node",
|
|
9
|
-
"request": "launch",
|
|
10
|
-
"name": "Launch Program",
|
|
11
|
-
"program": "${workspaceFolder}\\lib\\index.js",
|
|
12
|
-
"args": ["retrieve", "Dev"]
|
|
13
|
-
}
|
|
14
|
-
]
|
|
15
|
-
}
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Launch Program",
|
|
11
|
+
"program": "${workspaceFolder}\\lib\\index.js",
|
|
12
|
+
"args": ["retrieve", "Dev"]
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
package/.vscode/settings.json
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
32
32
|
},
|
|
33
33
|
"[markdown]": {
|
|
34
|
-
"editor.defaultFormatter": "
|
|
34
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
35
35
|
},
|
|
36
36
|
"[typescript]": {
|
|
37
37
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ If you experience issues installing Accenture SFMC DevTools, please check out th
|
|
|
123
123
|
1. Install Accenture SFMC DevTools by running `npm install -g mcdev` (prefix with `sudo` on MacOS)
|
|
124
124
|
- If you get an error, please see the below troubleshooting section.
|
|
125
125
|
|
|
126
|
-
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.
|
|
126
|
+
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.3`).
|
|
127
127
|
|
|
128
128
|
> **_Side note for proud nerds_:**
|
|
129
129
|
>
|
|
@@ -146,7 +146,7 @@ After the successful installation, you will now need to setup the connection to
|
|
|
146
146
|
5. Make sure you grant all available rights.
|
|
147
147
|
6. Go to the access tab and grant it access to all Business Units that you want to use it for, but ensure that the Parent/Global Business Unit is among these.
|
|
148
148
|
- _Why?_ Shared Data Extensions, roles, users, Business Unit info and some other metadata is internally stored solely on the parent Business Unit and hence can only be retrieved and updated via that BU.
|
|
149
|
-
7. Note down _EID_ (Parent MID),
|
|
149
|
+
7. Note down _EID_ (Parent MID), _Client Id_, _Client Secret_ and _Authentication Base URI_.
|
|
150
150
|
2. In your project folder
|
|
151
151
|
1. Open a CLI in your project folder (e.g. `C:\repos\MyProject\` on Windows or `~/repos/MyProject/` on Mac)
|
|
152
152
|
2. Run `mcdev init` to start the interactive setup wizard.
|
|
@@ -277,10 +277,10 @@ _Note: Regardless of which tag or branch you install_
|
|
|
277
277
|
**Install specific version (using a version tag on npm):**
|
|
278
278
|
|
|
279
279
|
```bash
|
|
280
|
-
npm install -g mcdev@4.1.
|
|
280
|
+
npm install -g mcdev@4.1.3
|
|
281
281
|
```
|
|
282
282
|
|
|
283
|
-
**Warning**: When you used the above method to install Accenture SFMC DevTools for a specific version or tag, trying to [update Accenture SFMC DevTools](#updating-mcdev) might not download the most recently published official version but instead stay on the version or branch you previously selected (in the above examples: develop, 4.1.
|
|
283
|
+
**Warning**: When you used the above method to install Accenture SFMC DevTools for a specific version or tag, trying to [update Accenture SFMC DevTools](#updating-mcdev) might not download the most recently published official version but instead stay on the version or branch you previously selected (in the above examples: develop, 4.1.3)!
|
|
284
284
|
|
|
285
285
|
> **Note**: The version is currently _not_ updated on the developer branch until a new release is published. Hence, you will not see a change if you run `mcdev --version`.
|
|
286
286
|
|
|
@@ -407,7 +407,7 @@ The following metadata types are currently supported:
|
|
|
407
407
|
| List | `list` | Yes | in backlog | - | Yes | Old way of storing data. Still used for central Email Subscriber DB. |
|
|
408
408
|
| Mobile Connect Code | `mobileCode` | Yes | No | No | - | Mobile Connect Shore or Long Codes used for sending. First 50 per BU are retrieved |
|
|
409
409
|
| Mobile Connect Keyword | `mobileKeyword` | Yes | Yes | Yes | - | Mobile Connect keywords configured within the Business UNit. First 50 per BU are retrieved |
|
|
410
|
-
| Role | `role` | Yes | Yes | yes (`bt`)
|
|
410
|
+
| Role | `role` | Yes | Yes | yes (`bt`) | Yes | User Roles define groups that are used to grant users access to SFMC systems. |
|
|
411
411
|
| Triggered Send | `triggeredSendDefinition` | Yes | Yes | - | Yes | **DEPRECATED**: Sends emails via API or DataExtension Event. |
|
|
412
412
|
| User | `accountUser` | Yes | in backlog | - | - | Users and Installed Packages including their assigned Roles, BUs and personal permissions |
|
|
413
413
|
|
|
@@ -478,7 +478,6 @@ Example url: `https://mcg123abcysykllg-0321cbs8bbt64.auth.marketingcloudapis.com
|
|
|
478
478
|
> ```bash
|
|
479
479
|
> mcdev init --y.credentialsName "yourCustomCredentialName" --y.client_id "yourClientIdHere" --y.client_secret "yourClientSecretHere" --y.auth_url "https://yourTenantSubdomainHere.auth.marketingcloudapis.com/" --y.gitRemoteUrl "https://my.git.server.com/myrepo.git" --y.account_id 00000000
|
|
480
480
|
> ```
|
|
481
|
-
>
|
|
482
481
|
|
|
483
482
|
#### 6.1.2. upgrade
|
|
484
483
|
|
|
@@ -753,13 +752,13 @@ Deletes the given metadata from your server. This needs to be run with care as a
|
|
|
753
752
|
|
|
754
753
|
Currently supported types:
|
|
755
754
|
|
|
756
|
-
| Name
|
|
757
|
-
|
|
|
758
|
-
| Data Extension
|
|
759
|
-
| Data Extension Field
|
|
760
|
-
| Email Send Definition | `Email Send Definition`
|
|
761
|
-
| List
|
|
762
|
-
| Triggered Send
|
|
755
|
+
| Name | CLI Argument |
|
|
756
|
+
| --------------------- | ------------------------- |
|
|
757
|
+
| Data Extension | `dataExtension` |
|
|
758
|
+
| Data Extension Field | `dataExtensionField` |
|
|
759
|
+
| Email Send Definition | `Email Send Definition` |
|
|
760
|
+
| List | `list` |
|
|
761
|
+
| Triggered Send | `triggeredSendDefinition` |
|
|
763
762
|
|
|
764
763
|
_Example:_
|
|
765
764
|
|
|
@@ -1103,13 +1102,13 @@ The central config in `.mcdevrc.json` holds multiple adjustable settings:
|
|
|
1103
1102
|
| options.deployment.sourceTargetMapping | `{"deployment-source": "deployment-target"}` | Configuration of 1 or many source-target marketList combos for `mcdev createDeltaPkg` |
|
|
1104
1103
|
| options.deployment.targetBranchBuMapping | `{"release/*": "...","master": ["..."]}` | Can be used by CI/CD pipelines to know what BUs shall be deployed to upon a merge into one of the specified branches |
|
|
1105
1104
|
| options.documentType | 'md' | Defines the format for documentation ('md', 'html', 'both') |
|
|
1106
|
-
| options.documentStandardRoles | false
|
|
1105
|
+
| options.documentStandardRoles | false | Optionally skip standard role documentation by setting to false |
|
|
1107
1106
|
| options.exclude.`type`.`field` | [] | Allows you to filter out metadata on retrieve based on their field values, e.g. CustomerKey (previously `options.filter`) |
|
|
1108
1107
|
| options.include.`type`.`field` | [] | Allows you to filter out metadata on retrieve based on their field values, e.g. CustomerKey |
|
|
1109
1108
|
| options.serverTimeOffset | -6 | Used to work around quirks in how SFMC handles timezones; For stack4: set to -7 (US Mountain time); others: -6 (US Central) |
|
|
1110
1109
|
| directories.businessUnits | 'businessUnits/' | Directory to save BU base details in |
|
|
1111
1110
|
| directories.deploy | 'deploy/' | Where `deploy` searches for files to deploy |
|
|
1112
|
-
| directories.docs
|
|
1111
|
+
| directories.docs | 'docs/' | Directory for `document` output |
|
|
1113
1112
|
| directories.retrieve | 'retrieve/' | Where `retrieve` stores downloaded files |
|
|
1114
1113
|
| directories.template | 'template/' | Where `rt` stores downloaded templates & `bd` retrieves them from |
|
|
1115
1114
|
| directories.templateBuilds | ['retrieve/','deploy/'] | Where `bd` saves final deployment versions in. This can hold multiple directories, e.g. ['retrieve/','deploy/'] |
|
|
@@ -1126,8 +1125,8 @@ The central config in `.mcdevrc.json` holds multiple adjustable settings:
|
|
|
1126
1125
|
|
|
1127
1126
|
The way retention policy is saved is a bit misleading and hence we wanted to provide a bit of guidance if you ever need to do a deep dive here.
|
|
1128
1127
|
|
|
1129
|
-
| Field
|
|
1130
|
-
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
1128
|
+
| Field | Description | Values |
|
|
1129
|
+
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------ |
|
|
1131
1130
|
| **DataRetentionPeriod** | this field should print the value of the unit of measure but it unfortunately is off by one (e.g. showing "weeks" instead of "months"). Also, it seems to have no impact on what's stored.<br> We therefore excluded it from retrieve/deploy | - |
|
|
1132
1131
|
| **DataRetentionPeriodUnitOfMeasure** | represents drop down for "period after" selection | 6: years<br>5: months<br>4: weeks<br>2: days |
|
|
1133
1132
|
| **DataRetentionPeriodLength** | represents number field for "period after" selection | min: 1<br>max: 999 |
|
|
@@ -1494,7 +1493,7 @@ Assuming you cloned Accenture SFMC DevTools into `C:\repos\sfmc-devtools\` (or `
|
|
|
1494
1493
|
|
|
1495
1494
|
This should tell npm to create a symlink to your cloned local directoty, allowing you to see updates you make in your mcdev repo instantly.
|
|
1496
1495
|
|
|
1497
|
-
To test your new **global** developer setup, run `mcdev --version` in CLI which should return the current version (e.g. `4.1.
|
|
1496
|
+
To test your new **global** developer setup, run `mcdev --version` in CLI which should return the current version (e.g. `4.1.3`). Then, go into your mcdev repo and update the version with the suffix `-dev`, e.g. to `4.1.3-dev` and then run `mcdev --version` again to verify that your change propagates instantly.
|
|
1498
1497
|
|
|
1499
1498
|
> **Not recommended:** Alternatively, you can install it locally only by opening a terminal in your project directory and executing `npm install --save-dev "C:\repos\sfmc-devtools"`
|
|
1500
1499
|
> To run the local version you need to prepend "npx" before your commands, e.g. `npx mcdev --version`
|
|
@@ -1532,7 +1531,7 @@ The following explains how you _could_ install it locally for certain edge cases
|
|
|
1532
1531
|
4. Afterwards, install Accenture SFMC DevTools by running `npm install --save-dev mcdev`
|
|
1533
1532
|
- If you get an error, please see the below troubleshooting section.
|
|
1534
1533
|
|
|
1535
|
-
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.
|
|
1534
|
+
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.3`).
|
|
1536
1535
|
|
|
1537
1536
|
### 9.3. NPM Scripts
|
|
1538
1537
|
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
# Metadata Type findings & considerations
|
|
2
|
-
|
|
3
|
-
## Automation
|
|
4
|
-
|
|
5
|
-
API: SOAP / REST
|
|
6
|
-
|
|
7
|
-
## Campaign
|
|
8
|
-
|
|
9
|
-
API: SOAP
|
|
10
|
-
|
|
11
|
-
Child Metadata:
|
|
12
|
-
|
|
13
|
-
- [CampaignAsset](#CampaignAsset)
|
|
14
|
-
|
|
15
|
-
## CampaignAsset
|
|
16
|
-
|
|
17
|
-
API: SOAP
|
|
18
|
-
|
|
19
|
-
## DataExtension
|
|
20
|
-
|
|
21
|
-
API: SOAP
|
|
22
|
-
|
|
23
|
-
Child Metadata:
|
|
24
|
-
|
|
25
|
-
- [DataExtensionField](#DataExtensionField)
|
|
26
|
-
|
|
27
|
-
Considerations:
|
|
28
|
-
|
|
29
|
-
- **"SendableSubscriberField": { "Name": "\_SubscriberKey" }** is part of a DataExtension while retrieving, but a DataExtension cannot be created/updated with this property. **\_SubscriberKey** must be replaced with **Subscriber Key** before creating/updating
|
|
30
|
-
- The referenced **CategoryID** represents the folder in which the DataExtension is located. these IDs are auto generated and therefore differ between BUs. When a DataExtension is deployed between BUs, the **CategoryID**s must be mapped between source and target
|
|
31
|
-
|
|
32
|
-
## DataExtensionField
|
|
33
|
-
|
|
34
|
-
API: SOAP
|
|
35
|
-
|
|
36
|
-
Considerations:
|
|
37
|
-
|
|
38
|
-
- DataExtensionFields can only be created or updated
|
|
39
|
-
- Instead of using the **CustomerKey** for updates like other metadata types, it uses the **ObjectID** which is auto generated and therefore different in each BU. ObjectIDs must be mapped between source and target if they are deployed between BUs
|
|
40
|
-
- Some properties cannot be updated, but are also not throwing an error when they are part of the request (e.g. **Scale**)
|
|
41
|
-
|
|
42
|
-
## Email
|
|
43
|
-
|
|
44
|
-
API: SOAP
|
|
45
|
-
|
|
46
|
-
## Folder
|
|
47
|
-
|
|
48
|
-
API: SOAP
|
|
49
|
-
|
|
50
|
-
Child Metadata:
|
|
51
|
-
|
|
52
|
-
- [DataExtension](#DataExtension)
|
|
53
|
-
- [Automation](#Automation)
|
|
54
|
-
|
|
55
|
-
Considerations:
|
|
56
|
-
|
|
57
|
-
- Folders are identified by their **ID** instead of their **CustomerKey**, this **ID** is auto generated and therefore different in each BU.
|
|
58
|
-
- **CustomerKey** field can be empty and the **Name** only needs to be unique inside a sub-folder. A unique identifier can be created by building the complete path of a folder (e.g. **/grandparent/parent/folder**). Such a unique identifier can be used to map Folder **ID**s between BUs. This kind of mapping does not support moving folders into other subfolders, because the unique identifier would then change
|
|
59
|
-
|
|
60
|
-
## List
|
|
61
|
-
|
|
62
|
-
API: SOAP
|
|
63
|
-
|
|
64
|
-
## Query
|
|
65
|
-
|
|
66
|
-
API: SOAP
|
|
1
|
+
# Metadata Type findings & considerations
|
|
2
|
+
|
|
3
|
+
## Automation
|
|
4
|
+
|
|
5
|
+
API: SOAP / REST
|
|
6
|
+
|
|
7
|
+
## Campaign
|
|
8
|
+
|
|
9
|
+
API: SOAP
|
|
10
|
+
|
|
11
|
+
Child Metadata:
|
|
12
|
+
|
|
13
|
+
- [CampaignAsset](#CampaignAsset)
|
|
14
|
+
|
|
15
|
+
## CampaignAsset
|
|
16
|
+
|
|
17
|
+
API: SOAP
|
|
18
|
+
|
|
19
|
+
## DataExtension
|
|
20
|
+
|
|
21
|
+
API: SOAP
|
|
22
|
+
|
|
23
|
+
Child Metadata:
|
|
24
|
+
|
|
25
|
+
- [DataExtensionField](#DataExtensionField)
|
|
26
|
+
|
|
27
|
+
Considerations:
|
|
28
|
+
|
|
29
|
+
- **"SendableSubscriberField": { "Name": "\_SubscriberKey" }** is part of a DataExtension while retrieving, but a DataExtension cannot be created/updated with this property. **\_SubscriberKey** must be replaced with **Subscriber Key** before creating/updating
|
|
30
|
+
- The referenced **CategoryID** represents the folder in which the DataExtension is located. these IDs are auto generated and therefore differ between BUs. When a DataExtension is deployed between BUs, the **CategoryID**s must be mapped between source and target
|
|
31
|
+
|
|
32
|
+
## DataExtensionField
|
|
33
|
+
|
|
34
|
+
API: SOAP
|
|
35
|
+
|
|
36
|
+
Considerations:
|
|
37
|
+
|
|
38
|
+
- DataExtensionFields can only be created or updated
|
|
39
|
+
- Instead of using the **CustomerKey** for updates like other metadata types, it uses the **ObjectID** which is auto generated and therefore different in each BU. ObjectIDs must be mapped between source and target if they are deployed between BUs
|
|
40
|
+
- Some properties cannot be updated, but are also not throwing an error when they are part of the request (e.g. **Scale**)
|
|
41
|
+
|
|
42
|
+
## Email
|
|
43
|
+
|
|
44
|
+
API: SOAP
|
|
45
|
+
|
|
46
|
+
## Folder
|
|
47
|
+
|
|
48
|
+
API: SOAP
|
|
49
|
+
|
|
50
|
+
Child Metadata:
|
|
51
|
+
|
|
52
|
+
- [DataExtension](#DataExtension)
|
|
53
|
+
- [Automation](#Automation)
|
|
54
|
+
|
|
55
|
+
Considerations:
|
|
56
|
+
|
|
57
|
+
- Folders are identified by their **ID** instead of their **CustomerKey**, this **ID** is auto generated and therefore different in each BU.
|
|
58
|
+
- **CustomerKey** field can be empty and the **Name** only needs to be unique inside a sub-folder. A unique identifier can be created by building the complete path of a folder (e.g. **/grandparent/parent/folder**). Such a unique identifier can be used to map Folder **ID**s between BUs. This kind of mapping does not support moving folders into other subfolders, because the unique identifier would then change
|
|
59
|
+
|
|
60
|
+
## List
|
|
61
|
+
|
|
62
|
+
API: SOAP
|
|
63
|
+
|
|
64
|
+
## Query
|
|
65
|
+
|
|
66
|
+
API: SOAP
|
|
@@ -723,13 +723,18 @@ class Asset extends MetadataType {
|
|
|
723
723
|
|
|
724
724
|
const filecontent = await File.readFilteredFilename(
|
|
725
725
|
[templateDir, this.definition.type, subType],
|
|
726
|
-
|
|
726
|
+
templateName,
|
|
727
727
|
fileExt,
|
|
728
728
|
'base64'
|
|
729
729
|
);
|
|
730
|
+
|
|
731
|
+
// keep old name if creating templates, otherwise use new name
|
|
732
|
+
const fileName =
|
|
733
|
+
mode === 'definition' ? metadata[this.definition.keyField] : templateName;
|
|
734
|
+
|
|
730
735
|
fileList.push({
|
|
731
736
|
subFolder: [this.definition.type, subType],
|
|
732
|
-
fileName:
|
|
737
|
+
fileName: fileName,
|
|
733
738
|
fileExt: fileExt,
|
|
734
739
|
content: filecontent,
|
|
735
740
|
encoding: 'base64',
|
|
@@ -260,17 +260,20 @@ class Query extends MetadataType {
|
|
|
260
260
|
const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir];
|
|
261
261
|
const nestedFilePaths = [];
|
|
262
262
|
|
|
263
|
+
// keep old name if creating templates, otherwise use new name
|
|
264
|
+
const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName;
|
|
265
|
+
|
|
263
266
|
for (const targetDir of targetDirArr) {
|
|
264
267
|
File.writeToFile(
|
|
265
268
|
[targetDir, this.definition.type],
|
|
266
|
-
|
|
269
|
+
fileName + '.' + this.definition.type + '-meta',
|
|
267
270
|
'sql',
|
|
268
271
|
code
|
|
269
272
|
);
|
|
270
273
|
nestedFilePaths.push([
|
|
271
274
|
targetDir,
|
|
272
275
|
this.definition.type,
|
|
273
|
-
|
|
276
|
+
fileName + '.' + this.definition.type + '-meta.sql',
|
|
274
277
|
]);
|
|
275
278
|
}
|
|
276
279
|
return nestedFilePaths;
|
|
@@ -234,17 +234,20 @@ class Script extends MetadataType {
|
|
|
234
234
|
const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir];
|
|
235
235
|
const nestedFilePaths = [];
|
|
236
236
|
|
|
237
|
+
// keep old name if creating templates, otherwise use new name
|
|
238
|
+
const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName;
|
|
239
|
+
|
|
237
240
|
for (const targetDir of targetDirArr) {
|
|
238
241
|
File.writeToFile(
|
|
239
242
|
[targetDir, this.definition.type],
|
|
240
|
-
|
|
243
|
+
fileName + '.' + this.definition.type + '-meta',
|
|
241
244
|
'ssjs',
|
|
242
245
|
code
|
|
243
246
|
);
|
|
244
247
|
nestedFilePaths.push([
|
|
245
248
|
targetDir,
|
|
246
249
|
this.definition.type,
|
|
247
|
-
|
|
250
|
+
fileName + '.' + this.definition.type + '-meta.ssjs',
|
|
248
251
|
]);
|
|
249
252
|
}
|
|
250
253
|
return nestedFilePaths;
|
package/package.json
CHANGED