mcdev 3.0.3 → 3.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/.eslintrc.json +1 -1
- package/.github/ISSUE_TEMPLATE/bug.yml +75 -0
- package/.github/ISSUE_TEMPLATE/task.md +1 -1
- package/.issuetracker +11 -3
- package/.vscode/settings.json +3 -3
- package/CHANGELOG.md +66 -0
- package/README.md +245 -141
- package/boilerplate/config.json +3 -2
- package/docs/dist/documentation.md +799 -338
- package/lib/Deployer.js +4 -1
- package/lib/MetadataTypeDefinitions.js +1 -0
- package/lib/MetadataTypeInfo.js +1 -0
- package/lib/Retriever.js +30 -14
- package/lib/cli.js +298 -0
- package/lib/index.js +773 -1019
- package/lib/metadataTypes/AccountUser.js +389 -0
- package/lib/metadataTypes/Asset.js +8 -7
- package/lib/metadataTypes/Automation.js +121 -56
- package/lib/metadataTypes/DataExtension.js +133 -97
- package/lib/metadataTypes/DataExtensionField.js +134 -4
- package/lib/metadataTypes/DataExtract.js +9 -5
- package/lib/metadataTypes/EventDefinition.js +9 -5
- package/lib/metadataTypes/FileTransfer.js +9 -5
- package/lib/metadataTypes/ImportFile.js +13 -12
- package/lib/metadataTypes/MetadataType.js +41 -33
- package/lib/metadataTypes/Query.js +2 -3
- package/lib/metadataTypes/Role.js +13 -8
- package/lib/metadataTypes/Script.js +2 -2
- package/lib/metadataTypes/definitions/AccountUser.definition.js +227 -0
- package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
- package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -1
- package/lib/metadataTypes/definitions/ImportFile.definition.js +2 -1
- package/lib/metadataTypes/definitions/Script.definition.js +5 -5
- package/lib/retrieveChangelog.js +96 -0
- package/lib/util/cli.js +4 -6
- package/lib/util/init.git.js +2 -1
- package/lib/util/util.js +17 -0
- package/package.json +18 -22
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
- package/img/README.md/troubleshoot-nodejs-postinstall.jpg +0 -0
- package/postinstall.js +0 -41
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const MetadataType = require('./MetadataType');
|
|
4
|
+
const Util = require('../util/util');
|
|
5
|
+
const File = require('../util/file');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* MessageSendActivity MetadataType
|
|
9
|
+
* @augments MetadataType
|
|
10
|
+
*/
|
|
11
|
+
class AccountUser extends MetadataType {
|
|
12
|
+
/**
|
|
13
|
+
* Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata
|
|
14
|
+
* @param {String} retrieveDir Directory where retrieved metadata directory will be saved
|
|
15
|
+
* @param {String[]} _ Returns specified fields even if their retrieve definition is not set to true
|
|
16
|
+
* @param {Object} buObject properties for auth
|
|
17
|
+
* @returns {Promise<Object>} Promise of metadata
|
|
18
|
+
*/
|
|
19
|
+
static async retrieve(retrieveDir, _, buObject) {
|
|
20
|
+
if (buObject.eid !== buObject.mid) {
|
|
21
|
+
Util.logger.info('Skipping User retrieval on non-parent BU');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
Util.logger.info('- Caching dependent Metadata: AccountUserAccount');
|
|
25
|
+
|
|
26
|
+
// get BUs that each users have access to
|
|
27
|
+
const optionsBUs = {};
|
|
28
|
+
let resultsBatch;
|
|
29
|
+
await Util.retryOnError(`Retrying ${this.definition.type}`, async () => {
|
|
30
|
+
resultsBatch = await new Promise((resolve, reject) => {
|
|
31
|
+
this.client.SoapClient.retrieve(
|
|
32
|
+
'AccountUserAccount',
|
|
33
|
+
[
|
|
34
|
+
'AccountUser.AccountUserID',
|
|
35
|
+
'AccountUser.UserID',
|
|
36
|
+
'Account.ID',
|
|
37
|
+
'Account.Name',
|
|
38
|
+
],
|
|
39
|
+
optionsBUs,
|
|
40
|
+
(ex, response) => (ex ? reject(ex) : resolve(response.body.Results))
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
this.userIdBuMap = {};
|
|
45
|
+
resultsBatch.forEach((item) => {
|
|
46
|
+
this.userIdBuMap[item.AccountUser.AccountUserID] =
|
|
47
|
+
this.userIdBuMap[item.AccountUser.AccountUserID] || [];
|
|
48
|
+
this.userIdBuMap[item.AccountUser.AccountUserID].push({
|
|
49
|
+
ID: item.Account.ID,
|
|
50
|
+
Name: item.Account.Name,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
// get actual user details
|
|
54
|
+
const options = {
|
|
55
|
+
queryAllAccounts: true,
|
|
56
|
+
|
|
57
|
+
filter: {
|
|
58
|
+
leftOperand: {
|
|
59
|
+
// normal users
|
|
60
|
+
leftOperand: 'Email',
|
|
61
|
+
operator: 'like',
|
|
62
|
+
rightOperand: '@',
|
|
63
|
+
},
|
|
64
|
+
operator: 'OR',
|
|
65
|
+
rightOperand: {
|
|
66
|
+
// installed packages
|
|
67
|
+
leftOperand: {
|
|
68
|
+
leftOperand: 'Name',
|
|
69
|
+
operator: 'like',
|
|
70
|
+
rightOperand: ' app user', // ! will not work if the name was too long as "app user" might be cut off
|
|
71
|
+
},
|
|
72
|
+
operator: 'AND',
|
|
73
|
+
rightOperand: {
|
|
74
|
+
// this is used to filter out system generated installed packages. in our testing, at least those installed packages created in the last few years have hat set this to false while additional (hidden) installed packages have it set to true.
|
|
75
|
+
leftOperand: 'MustChangePassword',
|
|
76
|
+
operator: 'equals',
|
|
77
|
+
rightOperand: 'false',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return super.retrieveSOAPgeneric(retrieveDir, buObject, options);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @param {string} date first date
|
|
88
|
+
* @param {string} date2 second date
|
|
89
|
+
* @returns {number} time difference
|
|
90
|
+
*/
|
|
91
|
+
static timeSinceDate(date) {
|
|
92
|
+
const interval = 'days';
|
|
93
|
+
const second = 1000,
|
|
94
|
+
minute = second * 60,
|
|
95
|
+
hour = minute * 60,
|
|
96
|
+
day = hour * 24,
|
|
97
|
+
week = day * 7;
|
|
98
|
+
date = new Date(date);
|
|
99
|
+
const now = new Date();
|
|
100
|
+
const timediff = now - date;
|
|
101
|
+
if (isNaN(timediff)) {
|
|
102
|
+
return NaN;
|
|
103
|
+
}
|
|
104
|
+
let result;
|
|
105
|
+
switch (interval) {
|
|
106
|
+
case 'years':
|
|
107
|
+
result = now.getFullYear() - date.getFullYear();
|
|
108
|
+
break;
|
|
109
|
+
case 'months':
|
|
110
|
+
result =
|
|
111
|
+
now.getFullYear() * 12 +
|
|
112
|
+
now.getMonth() -
|
|
113
|
+
(date.getFullYear() * 12 + date.getMonth());
|
|
114
|
+
break;
|
|
115
|
+
case 'weeks':
|
|
116
|
+
result = Math.floor(timediff / week);
|
|
117
|
+
break;
|
|
118
|
+
case 'days':
|
|
119
|
+
result = Math.floor(timediff / day);
|
|
120
|
+
break;
|
|
121
|
+
case 'hours':
|
|
122
|
+
result = Math.floor(timediff / hour);
|
|
123
|
+
break;
|
|
124
|
+
case 'minutes':
|
|
125
|
+
result = Math.floor(timediff / minute);
|
|
126
|
+
break;
|
|
127
|
+
case 'seconds':
|
|
128
|
+
result = Math.floor(timediff / second);
|
|
129
|
+
break;
|
|
130
|
+
default:
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
return result + ' ' + interval;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* helper to print bu names
|
|
137
|
+
* @param {Util.BuObject} buObject needed for eid
|
|
138
|
+
* @param {string} buObject.eid needed to check for parent bu
|
|
139
|
+
* @param {numeric} id bu id
|
|
140
|
+
* @returns {string} "bu name (bu id)""
|
|
141
|
+
*/
|
|
142
|
+
static getBuName(buObject, id) {
|
|
143
|
+
let name;
|
|
144
|
+
if (buObject.eid == id) {
|
|
145
|
+
name = '_ParentBU_';
|
|
146
|
+
} else {
|
|
147
|
+
name = this.buIdName[id];
|
|
148
|
+
}
|
|
149
|
+
return `<nobr>${name} (${id})</nobr>`;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Creates markdown documentation of all roles
|
|
153
|
+
* @param {Util.BuObject} buObject properties for auth
|
|
154
|
+
* @param {Object} [metadata] user list
|
|
155
|
+
* @returns {Promise<void>} -
|
|
156
|
+
*/
|
|
157
|
+
static async document(buObject, metadata) {
|
|
158
|
+
if (buObject.eid !== buObject.mid) {
|
|
159
|
+
Util.logger.error(
|
|
160
|
+
`Users can only be retrieved & documented for the ${Util.parentBuName}`
|
|
161
|
+
);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (!metadata) {
|
|
165
|
+
// load users from disk if document was called directly and not part of a retrieve
|
|
166
|
+
try {
|
|
167
|
+
metadata = this.readBUMetadataForType(
|
|
168
|
+
File.normalizePath([
|
|
169
|
+
this.properties.directories.retrieve,
|
|
170
|
+
buObject.credential,
|
|
171
|
+
Util.parentBuName,
|
|
172
|
+
]),
|
|
173
|
+
true
|
|
174
|
+
).accountUser;
|
|
175
|
+
} catch (ex) {
|
|
176
|
+
Util.logger.error(ex.message);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// init map of BU Ids > BU Name
|
|
181
|
+
this.buIdName = {};
|
|
182
|
+
|
|
183
|
+
// initialize permission object
|
|
184
|
+
this.allPermissions = {};
|
|
185
|
+
const users = [];
|
|
186
|
+
// traverse all permissions recursively and write them into allPermissions object once it has reached the end
|
|
187
|
+
for (const id in metadata) {
|
|
188
|
+
const user = metadata[id];
|
|
189
|
+
// TODO resolve user permissions to something readable
|
|
190
|
+
let userPermissions = '';
|
|
191
|
+
if (user.UserPermissions) {
|
|
192
|
+
if (!user.UserPermissions.length) {
|
|
193
|
+
// 1 single user permission found, normalize it
|
|
194
|
+
user.UserPermissions = [user.UserPermissions];
|
|
195
|
+
}
|
|
196
|
+
userPermissions = user.UserPermissions.map((item) => item.ID * 1)
|
|
197
|
+
.sort(function (a, b) {
|
|
198
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
199
|
+
})
|
|
200
|
+
.join(', ');
|
|
201
|
+
}
|
|
202
|
+
// user roles
|
|
203
|
+
// TODO think about what to do with "individual role" entries
|
|
204
|
+
let roles = '';
|
|
205
|
+
if (user.Roles) {
|
|
206
|
+
roles =
|
|
207
|
+
'<nobr>' +
|
|
208
|
+
user.Roles.map((item) => item.Name)
|
|
209
|
+
.sort(function (a, b) {
|
|
210
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
211
|
+
})
|
|
212
|
+
.join(',</nobr><br> <nobr>') +
|
|
213
|
+
'</nobr>';
|
|
214
|
+
}
|
|
215
|
+
let associatedBus = '';
|
|
216
|
+
if (user.AssociatedBusinessUnits__c) {
|
|
217
|
+
associatedBus = user.AssociatedBusinessUnits__c.map((item) => {
|
|
218
|
+
this.buIdName[item.ID] = item.Name;
|
|
219
|
+
return this.getBuName(buObject, item.ID);
|
|
220
|
+
})
|
|
221
|
+
.sort(function (a, b) {
|
|
222
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
223
|
+
})
|
|
224
|
+
.join(',<br> ');
|
|
225
|
+
}
|
|
226
|
+
const defaultBUName = this.getBuName(buObject, user.DefaultBusinessUnit);
|
|
227
|
+
users.push({
|
|
228
|
+
TYPE: user.type__c,
|
|
229
|
+
UserID: user.UserID,
|
|
230
|
+
AccountUserID: user.AccountUserID,
|
|
231
|
+
CustomerKey: user.CustomerKey,
|
|
232
|
+
Name: user.Name,
|
|
233
|
+
Email: user.Email,
|
|
234
|
+
NotificationEmailAddress: user.NotificationEmailAddress,
|
|
235
|
+
ActiveFlag: user.ActiveFlag === 'true' ? '✓' : '-',
|
|
236
|
+
IsAPIUser: user.IsAPIUser === 'true' ? '✓' : '-',
|
|
237
|
+
MustChangePassword: user.MustChangePassword === 'true' ? '✓' : '-',
|
|
238
|
+
DefaultBusinessUnit: defaultBUName,
|
|
239
|
+
AssociatedBusinessUnits__c: associatedBus,
|
|
240
|
+
Roles: roles,
|
|
241
|
+
UserPermissions: userPermissions,
|
|
242
|
+
LastSuccessfulLogin: this.timeSinceDate(user.LastSuccessfulLogin),
|
|
243
|
+
CreatedDate: user.CreatedDate.split('T').join(' '),
|
|
244
|
+
ModifiedDate: user.ModifiedDate.split('T').join(' '),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
users.sort(function (a, b) {
|
|
248
|
+
return a.Name < b.Name ? -1 : a.Name > b.Name ? 1 : 0;
|
|
249
|
+
});
|
|
250
|
+
const columnsToPrint = [
|
|
251
|
+
['Name', 'Name'],
|
|
252
|
+
['Last successful Login', 'LastSuccessfulLogin'],
|
|
253
|
+
['Active', 'ActiveFlag'],
|
|
254
|
+
['API User', 'IsAPIUser'],
|
|
255
|
+
['Must change PW', 'MustChangePassword'],
|
|
256
|
+
['Default BU', 'DefaultBusinessUnit'],
|
|
257
|
+
['BU Access', 'AssociatedBusinessUnits__c'],
|
|
258
|
+
['Roles', 'Roles'],
|
|
259
|
+
['User Permissions', 'UserPermissions'],
|
|
260
|
+
['Login', 'UserID'],
|
|
261
|
+
['ID', 'AccountUserID'],
|
|
262
|
+
['Key', 'CustomerKey'],
|
|
263
|
+
['E-Mail', 'Email'],
|
|
264
|
+
['Notification E-Mail', 'NotificationEmailAddress'],
|
|
265
|
+
['Modified Date', 'ModifiedDate'],
|
|
266
|
+
['Created Date', 'CreatedDate'],
|
|
267
|
+
];
|
|
268
|
+
let output = `# User Overview - ${buObject.credential}`;
|
|
269
|
+
output += this._generateDocMd(
|
|
270
|
+
users.filter((user) => user.TYPE === 'User' && user.ActiveFlag === '✓'),
|
|
271
|
+
'User',
|
|
272
|
+
columnsToPrint
|
|
273
|
+
);
|
|
274
|
+
output += this._generateDocMd(
|
|
275
|
+
users.filter((user) => user.TYPE === 'User' && user.ActiveFlag === '-'),
|
|
276
|
+
'Inactivated User',
|
|
277
|
+
columnsToPrint
|
|
278
|
+
);
|
|
279
|
+
output += this._generateDocMd(
|
|
280
|
+
users.filter((user) => user.TYPE === 'Installed Package'),
|
|
281
|
+
'Installed Package',
|
|
282
|
+
columnsToPrint
|
|
283
|
+
);
|
|
284
|
+
const docPath = File.normalizePath([this.properties.directories.users]);
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const filename = buObject.credential;
|
|
288
|
+
// ensure docs/roles folder is existing (depends on setup in .mcdevrc.json)
|
|
289
|
+
if (!File.existsSync(docPath)) {
|
|
290
|
+
File.mkdirpSync(docPath);
|
|
291
|
+
}
|
|
292
|
+
// write to disk
|
|
293
|
+
await File.writeToFile(docPath, filename + '.accountUser', 'md', output);
|
|
294
|
+
Util.logger.info(`Created ${docPath}${filename}.accountUser.md`);
|
|
295
|
+
if (['html', 'both'].includes(this.properties.options.documentType)) {
|
|
296
|
+
Util.logger.warn(
|
|
297
|
+
'HTML-based documentation of accountUser currently not supported.'
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
} catch (ex) {
|
|
301
|
+
Util.logger.error(`AccountUser.document():: error | `, ex.message);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Experimental: Only working for DataExtensions:
|
|
306
|
+
* Saves json content to a html table in the local file system. Will create the parent directory if it does not exist.
|
|
307
|
+
* The json's first level of keys must represent the rows and the secend level the columns
|
|
308
|
+
* @private
|
|
309
|
+
* @param {DataExtensionItem} json dataextension
|
|
310
|
+
* @param {Array} tabled prepped array for output in tabular format
|
|
311
|
+
* @returns {string} file content
|
|
312
|
+
*/
|
|
313
|
+
/**
|
|
314
|
+
*
|
|
315
|
+
* @param {Object[]} users list of users and installed package
|
|
316
|
+
* @param {'Installed Package'|'User'} type choose what sub type to print
|
|
317
|
+
* @param {Array[]} columnsToPrint helper array
|
|
318
|
+
* @param {Object} buObject properties for auth
|
|
319
|
+
* @returns {string} markdown
|
|
320
|
+
*/
|
|
321
|
+
static _generateDocMd(users, type, columnsToPrint) {
|
|
322
|
+
let output = `\n\n## ${type}s (${users.length})\n\n`;
|
|
323
|
+
let tableSeparator = '';
|
|
324
|
+
columnsToPrint.forEach((column) => {
|
|
325
|
+
output += `| ${column[0]} `;
|
|
326
|
+
tableSeparator += '| --- ';
|
|
327
|
+
});
|
|
328
|
+
output += `|\n${tableSeparator}|\n`;
|
|
329
|
+
users.forEach((user) => {
|
|
330
|
+
columnsToPrint.forEach((column) => {
|
|
331
|
+
output += `| ${user[column[1]]} `;
|
|
332
|
+
});
|
|
333
|
+
output += `|\n`;
|
|
334
|
+
});
|
|
335
|
+
return output;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* manages post retrieve steps
|
|
340
|
+
* @param {Object} metadata a single query
|
|
341
|
+
* @returns {Object[]} Array with one metadata object and one query string
|
|
342
|
+
*/
|
|
343
|
+
static postRetrieveTasks(metadata) {
|
|
344
|
+
return this.parseMetadata(metadata);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* parses retrieved Metadata before saving
|
|
348
|
+
* @param {Object} metadata a single query activity definition
|
|
349
|
+
* @returns {Array} Array with one metadata object and one sql string
|
|
350
|
+
*/
|
|
351
|
+
static parseMetadata(metadata) {
|
|
352
|
+
metadata.type__c = 'Installed Package';
|
|
353
|
+
if (metadata.Email.includes('@') && !metadata.Name.endsWith('app user')) {
|
|
354
|
+
metadata.type__c = 'User';
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (this.userIdBuMap[metadata.ID]) {
|
|
358
|
+
metadata.AssociatedBusinessUnits__c = this.userIdBuMap[metadata.ID];
|
|
359
|
+
} else {
|
|
360
|
+
metadata.AssociatedBusinessUnits__c = [];
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
let roles;
|
|
364
|
+
if (metadata.Roles.Role) {
|
|
365
|
+
// normalize to always use array
|
|
366
|
+
if (!metadata.Roles.Role.length) {
|
|
367
|
+
metadata.Roles.Role = [metadata.Roles.Role];
|
|
368
|
+
}
|
|
369
|
+
// convert complex object into basic set of info
|
|
370
|
+
roles = metadata.Roles.Role.map((item) => ({
|
|
371
|
+
Name: item.Name,
|
|
372
|
+
CustomerKey: item.CustomerKey,
|
|
373
|
+
})).sort(function (a, b) {
|
|
374
|
+
return a.Name < b.Name ? -1 : a.Name > b.Name ? 1 : 0;
|
|
375
|
+
});
|
|
376
|
+
} else {
|
|
377
|
+
// set to empty array
|
|
378
|
+
roles = [];
|
|
379
|
+
}
|
|
380
|
+
metadata.Roles = roles;
|
|
381
|
+
|
|
382
|
+
return metadata;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Assign definition to static attributes
|
|
387
|
+
AccountUser.definition = require('../MetadataTypeDefinitions').accountUser;
|
|
388
|
+
|
|
389
|
+
module.exports = AccountUser;
|
|
@@ -162,6 +162,7 @@ class Asset extends MetadataType {
|
|
|
162
162
|
} else {
|
|
163
163
|
Util.logger.info(`- Caching Subtype: ${subType}`);
|
|
164
164
|
}
|
|
165
|
+
const subtypeIds = subTypeArray?.map(subTypeItemName => Asset.definition.typeMapping[subTypeItemName]);
|
|
165
166
|
const uri = 'asset/v1/content/assets/';
|
|
166
167
|
const options = {
|
|
167
168
|
uri: uri + 'query',
|
|
@@ -178,9 +179,9 @@ class Asset extends MetadataType {
|
|
|
178
179
|
if (templateName) {
|
|
179
180
|
options.json.query = {
|
|
180
181
|
leftOperand: {
|
|
181
|
-
property: 'assetType.
|
|
182
|
+
property: 'assetType.id',
|
|
182
183
|
simpleOperator: 'in',
|
|
183
|
-
value:
|
|
184
|
+
value: subtypeIds,
|
|
184
185
|
},
|
|
185
186
|
logicalOperator: 'AND',
|
|
186
187
|
rightOperand: {
|
|
@@ -191,9 +192,9 @@ class Asset extends MetadataType {
|
|
|
191
192
|
};
|
|
192
193
|
} else {
|
|
193
194
|
options.json.query = {
|
|
194
|
-
property: 'assetType.
|
|
195
|
+
property: 'assetType.id',
|
|
195
196
|
simpleOperator: 'in',
|
|
196
|
-
value:
|
|
197
|
+
value: subtypeIds,
|
|
197
198
|
};
|
|
198
199
|
options.json.sort = [{ property: 'id', direction: 'ASC' }];
|
|
199
200
|
}
|
|
@@ -232,9 +233,9 @@ class Asset extends MetadataType {
|
|
|
232
233
|
// Since we sort by ID, we can get the last ID then run new requests from there
|
|
233
234
|
options.json.query = {
|
|
234
235
|
leftOperand: {
|
|
235
|
-
property: 'assetType.
|
|
236
|
+
property: 'assetType.id',
|
|
236
237
|
simpleOperator: 'in',
|
|
237
|
-
value:
|
|
238
|
+
value: subtypeIds,
|
|
238
239
|
},
|
|
239
240
|
logicalOperator: 'AND',
|
|
240
241
|
rightOperand: {
|
|
@@ -441,7 +442,7 @@ class Asset extends MetadataType {
|
|
|
441
442
|
await this._mergeCode(metadata, deployDir, subType);
|
|
442
443
|
|
|
443
444
|
// #2 get file from local disk and insert as base64
|
|
444
|
-
await this._readExtendedFileFromFS(metadata,
|
|
445
|
+
await this._readExtendedFileFromFS(metadata, subType, deployDir);
|
|
445
446
|
|
|
446
447
|
return metadata;
|
|
447
448
|
}
|