@pnp/cli-microsoft365 7.10.0-beta.0d80e6e → 7.10.0-beta.172f827

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.
@@ -0,0 +1,149 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _EntraPimRoleRequestListCommand_instances, _EntraPimRoleRequestListCommand_initTelemetry, _EntraPimRoleRequestListCommand_initOptions, _EntraPimRoleRequestListCommand_initValidators, _EntraPimRoleRequestListCommand_initOptionSets;
7
+ import GraphCommand from '../../../base/GraphCommand.js';
8
+ import commands from '../../commands.js';
9
+ import { validation } from '../../../../utils/validation.js';
10
+ import { entraUser } from '../../../../utils/entraUser.js';
11
+ import { entraGroup } from '../../../../utils/entraGroup.js';
12
+ import { odata } from '../../../../utils/odata.js';
13
+ class EntraPimRoleRequestListCommand extends GraphCommand {
14
+ get name() {
15
+ return commands.PIM_ROLE_REQUEST_LIST;
16
+ }
17
+ get description() {
18
+ return 'Retrieves a list of PIM requests for roles';
19
+ }
20
+ defaultProperties() {
21
+ return ['id', 'roleDefinitionName', 'principalId'];
22
+ }
23
+ constructor() {
24
+ super();
25
+ _EntraPimRoleRequestListCommand_instances.add(this);
26
+ this.allowedStatuses = ['Canceled', 'Denied', 'Failed', 'Granted', 'PendingAdminDecision', 'PendingApproval', 'PendingProvisioning', 'PendingScheduleCreation', 'Provisioned', 'Revoked', 'ScheduleCreated'];
27
+ __classPrivateFieldGet(this, _EntraPimRoleRequestListCommand_instances, "m", _EntraPimRoleRequestListCommand_initTelemetry).call(this);
28
+ __classPrivateFieldGet(this, _EntraPimRoleRequestListCommand_instances, "m", _EntraPimRoleRequestListCommand_initOptions).call(this);
29
+ __classPrivateFieldGet(this, _EntraPimRoleRequestListCommand_instances, "m", _EntraPimRoleRequestListCommand_initValidators).call(this);
30
+ __classPrivateFieldGet(this, _EntraPimRoleRequestListCommand_instances, "m", _EntraPimRoleRequestListCommand_initOptionSets).call(this);
31
+ }
32
+ async commandAction(logger, args) {
33
+ if (this.verbose) {
34
+ await logger.logToStderr(`Retrieving list of PIM roles requests for ${args.options.userId || args.options.userName || args.options.groupId || args.options.groupName || 'all users'}...`);
35
+ }
36
+ const queryParameters = [];
37
+ const filters = [];
38
+ const expands = [];
39
+ try {
40
+ const principalId = await this.getPrincipalId(logger, args.options);
41
+ if (principalId) {
42
+ filters.push(`principalId eq '${principalId}'`);
43
+ }
44
+ if (args.options.createdDateTime) {
45
+ filters.push(`createdDateTime ge ${args.options.createdDateTime}`);
46
+ }
47
+ if (args.options.status) {
48
+ filters.push(`status eq '${args.options.status}'`);
49
+ }
50
+ if (filters.length > 0) {
51
+ queryParameters.push(`$filter=${filters.join(' and ')}`);
52
+ }
53
+ expands.push('roleDefinition($select=displayName)');
54
+ if (args.options.includePrincipalDetails) {
55
+ expands.push('principal');
56
+ }
57
+ queryParameters.push(`$expand=${expands.join(',')}`);
58
+ const queryString = `?${queryParameters.join('&')}`;
59
+ const url = `${this.resource}/v1.0/roleManagement/directory/roleAssignmentScheduleRequests${queryString}`;
60
+ const results = await odata.getAllItems(url);
61
+ results.forEach(c => {
62
+ const roleDefinition = c['roleDefinition'];
63
+ if (roleDefinition) {
64
+ c.roleDefinitionName = roleDefinition.displayName;
65
+ }
66
+ delete c['roleDefinition'];
67
+ });
68
+ await logger.log(results);
69
+ }
70
+ catch (err) {
71
+ this.handleRejectedODataJsonPromise(err);
72
+ }
73
+ }
74
+ async getPrincipalId(logger, options) {
75
+ let principalId = options.userId;
76
+ if (options.userName) {
77
+ if (this.verbose) {
78
+ await logger.logToStderr(`Retrieving user by its name '${options.userName}'`);
79
+ }
80
+ principalId = await entraUser.getUserIdByUpn(options.userName);
81
+ }
82
+ else if (options.groupId) {
83
+ principalId = options.groupId;
84
+ }
85
+ else if (options.groupName) {
86
+ if (this.verbose) {
87
+ await logger.logToStderr(`Retrieving group by its name '${options.groupName}'`);
88
+ }
89
+ principalId = await entraGroup.getGroupIdByDisplayName(options.groupName);
90
+ }
91
+ return principalId;
92
+ }
93
+ }
94
+ _EntraPimRoleRequestListCommand_instances = new WeakSet(), _EntraPimRoleRequestListCommand_initTelemetry = function _EntraPimRoleRequestListCommand_initTelemetry() {
95
+ this.telemetry.push((args) => {
96
+ Object.assign(this.telemetryProperties, {
97
+ userId: typeof args.options.userId !== 'undefined',
98
+ userName: typeof args.options.userName !== 'undefined',
99
+ groupId: typeof args.options.groupId !== 'undefined',
100
+ groupName: typeof args.options.groupName !== 'undefined',
101
+ createdDateTime: typeof args.options.createdDateTime !== 'undefined',
102
+ status: typeof args.options.status !== 'undefined',
103
+ includePrincipalDetails: !!args.options.includePrincipalDetails
104
+ });
105
+ });
106
+ }, _EntraPimRoleRequestListCommand_initOptions = function _EntraPimRoleRequestListCommand_initOptions() {
107
+ this.options.unshift({
108
+ option: '--userId [userId]'
109
+ }, {
110
+ option: '--userName [userName]'
111
+ }, {
112
+ option: '--groupId [groupId]'
113
+ }, {
114
+ option: '--groupName [groupName]'
115
+ }, {
116
+ option: '-c, --createdDateTime [createdDateTime]'
117
+ }, {
118
+ option: '-s, --status [status]',
119
+ autocomplete: this.allowedStatuses
120
+ }, {
121
+ option: '--includePrincipalDetails [includePrincipalDetails]'
122
+ });
123
+ }, _EntraPimRoleRequestListCommand_initValidators = function _EntraPimRoleRequestListCommand_initValidators() {
124
+ this.validators.push(async (args) => {
125
+ if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
126
+ return `'${args.options.userId}' is not a valid GUID for option 'userId'`;
127
+ }
128
+ if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) {
129
+ return `'${args.options.userName}' is not a valid user principal name for option 'userName'.`;
130
+ }
131
+ if (args.options.groupId && !validation.isValidGuid(args.options.groupId)) {
132
+ return `'${args.options.groupId}' is not a valid GUID for option 'groupId'`;
133
+ }
134
+ if (args.options.createdDateTime && !validation.isValidISODateTime(args.options.createdDateTime)) {
135
+ return `'${args.options.createdDateTime}' is not a valid ISO 8601 date time string for option 'createdDateTime'`;
136
+ }
137
+ if (args.options.status && !this.allowedStatuses.some(status => status.toLowerCase() === args.options.status.toLowerCase())) {
138
+ return `'${args.options.status}' for option 'status' must be one of the following values: ${this.allowedStatuses.join(', ')}.`;
139
+ }
140
+ return true;
141
+ });
142
+ }, _EntraPimRoleRequestListCommand_initOptionSets = function _EntraPimRoleRequestListCommand_initOptionSets() {
143
+ this.optionSets.push({
144
+ options: ['userId', 'userName', 'groupId', 'groupName'],
145
+ runsWhen: (args) => args.options.userId || args.options.userName || args.options.groupId || args.options.groupName
146
+ });
147
+ };
148
+ export default new EntraPimRoleRequestListCommand();
149
+ //# sourceMappingURL=pim-role-request-list.js.map
@@ -16,6 +16,7 @@ export default {
16
16
  APP_SET: `${prefix} app set`,
17
17
  APP_PERMISSION_ADD: `${prefix} app permission add`,
18
18
  APP_PERMISSION_LIST: `${prefix} app permission list`,
19
+ APP_PERMISSION_REMOVE: `${prefix} app permission remove`,
19
20
  APP_ROLE_ADD: `${prefix} app role add`,
20
21
  APP_ROLE_LIST: `${prefix} app role list`,
21
22
  APP_ROLE_REMOVE: `${prefix} app role remove`,
@@ -77,6 +78,8 @@ export default {
77
78
  OAUTH2GRANT_SET: `${prefix} oauth2grant set`,
78
79
  PIM_ROLE_ASSIGNMENT_ADD: `${prefix} pim role assignment add`,
79
80
  PIM_ROLE_ASSIGNMENT_LIST: `${prefix} pim role assignment list`,
81
+ PIM_ROLE_ASSIGNMENT_ELIGIBILITY_LIST: `${prefix} pim role assignment eligibility list`,
82
+ PIM_ROLE_REQUEST_LIST: `${prefix} pim role request list`,
80
83
  POLICY_LIST: `${prefix} policy list`,
81
84
  SITECLASSIFICATION_DISABLE: `${prefix} siteclassification disable`,
82
85
  SITECLASSIFICATION_ENABLE: `${prefix} siteclassification enable`,
@@ -42,29 +42,27 @@ class SpoFileAddCommand extends SpoCommand {
42
42
  const fileName = fsUtil.getSafeFileName(path.basename(fullPath));
43
43
  let isCheckedOut = false;
44
44
  let listSettings;
45
- if (this.debug) {
46
- await logger.logToStderr(`folder path: ${folderPath}...`);
47
- }
48
- if (this.debug) {
49
- await logger.logToStderr('Check if the specified folder exists.');
50
- await logger.logToStderr('');
51
- }
52
- if (this.debug) {
45
+ if (this.verbose) {
53
46
  await logger.logToStderr(`file name: ${fileName}...`);
47
+ await logger.logToStderr(`folder path: ${folderPath}...`);
54
48
  }
55
49
  try {
56
50
  try {
51
+ if (this.verbose) {
52
+ await logger.logToStderr('Check if the specified folder exists.');
53
+ }
57
54
  const requestOptions = {
58
55
  url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')`,
59
56
  headers: {
60
- 'accept': 'application/json;odata=nometadata'
61
- }
57
+ accept: 'application/json;odata=nometadata'
58
+ },
59
+ responseType: 'json'
62
60
  };
63
61
  await request.get(requestOptions);
64
62
  }
65
63
  catch (err) {
66
64
  // folder does not exist so will attempt to create the folder tree
67
- await spo.ensureFolder(args.options.webUrl, folderPath, logger, this.debug);
65
+ await spo.ensureFolder(args.options.webUrl, folderPath, logger, this.verbose);
68
66
  }
69
67
  if (args.options.checkOut) {
70
68
  await this.fileCheckOut(fileName, args.options.webUrl, folderPath);
@@ -77,7 +75,7 @@ class SpoFileAddCommand extends SpoCommand {
77
75
  }
78
76
  const fileStats = fs.statSync(fullPath);
79
77
  const fileSize = fileStats.size;
80
- if (this.debug) {
78
+ if (this.verbose) {
81
79
  await logger.logToStderr(`File size is ${fileSize} bytes`);
82
80
  }
83
81
  // only up to 250 MB are allowed in a single request
@@ -91,8 +89,9 @@ class SpoFileAddCommand extends SpoCommand {
91
89
  const requestOptions = {
92
90
  url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files/GetByPathOrAddStub(DecodedUrl='${formatting.encodeQueryParameter(fileName)}')/StartUpload(uploadId=guid'${uploadId}')`,
93
91
  headers: {
94
- 'accept': 'application/json;odata=nometadata'
95
- }
92
+ accept: 'application/json;odata=nometadata'
93
+ },
94
+ responseType: 'json'
96
95
  };
97
96
  await request.post(requestOptions);
98
97
  // session started successfully, now upload our file chunks
@@ -119,8 +118,9 @@ class SpoFileAddCommand extends SpoCommand {
119
118
  const requestOptions = {
120
119
  url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files('${formatting.encodeQueryParameter(fileName)}')/cancelupload(uploadId=guid'${uploadId}')`,
121
120
  headers: {
122
- 'accept': 'application/json;odata=nometadata'
123
- }
121
+ accept: 'application/json;odata=nometadata'
122
+ },
123
+ responseType: 'json'
124
124
  };
125
125
  try {
126
126
  await request.post(requestOptions);
@@ -142,7 +142,7 @@ class SpoFileAddCommand extends SpoCommand {
142
142
  url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files/Add(url='${formatting.encodeQueryParameter(fileName)}', overwrite=true)`,
143
143
  data: fileBody,
144
144
  headers: {
145
- 'accept': 'application/json;odata=nometadata',
145
+ accept: 'application/json;odata=nometadata',
146
146
  'content-length': bodyLength
147
147
  },
148
148
  maxBodyLength: this.fileChunkingThreshold
@@ -165,12 +165,12 @@ class SpoFileAddCommand extends SpoCommand {
165
165
  });
166
166
  }
167
167
  if (fieldsToUpdate.length > 0) {
168
- // perform list item update and checkin
168
+ // perform list item update and check-in
169
169
  await this.validateUpdateListItem(args.options.webUrl, folderPath, fileName, fieldsToUpdate, logger, args.options.checkInComment);
170
170
  }
171
171
  else if (isCheckedOut) {
172
- // perform checkin
173
- await this.fileCheckIn(args, fileName);
172
+ // perform check-in
173
+ await this.fileCheckIn(args.options.webUrl, folderPath, fileName, args.options.checkInComment);
174
174
  }
175
175
  // approve and publish cannot be used together
176
176
  // when approve is used it will automatically publish the file
@@ -183,7 +183,7 @@ class SpoFileAddCommand extends SpoCommand {
183
183
  const requestOptions = {
184
184
  url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files('${formatting.encodeQueryParameter(fileName)}')/approve(comment='${formatting.encodeQueryParameter(args.options.approveComment || '')}')`,
185
185
  headers: {
186
- 'accept': 'application/json;odata=nometadata'
186
+ accept: 'application/json;odata=nometadata'
187
187
  },
188
188
  responseType: 'json'
189
189
  };
@@ -200,7 +200,7 @@ class SpoFileAddCommand extends SpoCommand {
200
200
  const requestOptions = {
201
201
  url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files('${formatting.encodeQueryParameter(fileName)}')/publish(comment='${formatting.encodeQueryParameter(args.options.publishComment || '')}')`,
202
202
  headers: {
203
- 'accept': 'application/json;odata=nometadata'
203
+ accept: 'application/json;odata=nometadata'
204
204
  },
205
205
  responseType: 'json'
206
206
  };
@@ -212,7 +212,11 @@ class SpoFileAddCommand extends SpoCommand {
212
212
  // in a case the command has done checkout
213
213
  // then have to rollback the checkout
214
214
  const requestOptions = {
215
- url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files('${formatting.encodeQueryParameter(fileName)}')/UndoCheckOut()`
215
+ url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files('${formatting.encodeQueryParameter(fileName)}')/UndoCheckOut()`,
216
+ headers: {
217
+ accept: 'application/json;odata=nometadata'
218
+ },
219
+ responseType: 'json'
216
220
  };
217
221
  try {
218
222
  await request.post(requestOptions);
@@ -221,7 +225,6 @@ class SpoFileAddCommand extends SpoCommand {
221
225
  if (this.verbose) {
222
226
  await logger.logToStderr('Could not rollback file checkout');
223
227
  await logger.logToStderr(err);
224
- await logger.logToStderr('');
225
228
  }
226
229
  }
227
230
  }
@@ -235,7 +238,7 @@ class SpoFileAddCommand extends SpoCommand {
235
238
  const requestOptions = {
236
239
  url: `${webUrl}/_api/web/lists('${listSettings.Id}')/contenttypes?$select=Name,Id`,
237
240
  headers: {
238
- 'accept': 'application/json;odata=nometadata'
241
+ accept: 'application/json;odata=nometadata'
239
242
  },
240
243
  responseType: 'json'
241
244
  };
@@ -253,14 +256,15 @@ class SpoFileAddCommand extends SpoCommand {
253
256
  const requestOptionsGetFile = {
254
257
  url: `${webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folder)}')/Files('${formatting.encodeQueryParameter(fileName)}')`,
255
258
  headers: {
256
- 'accept': 'application/json;odata=nometadata'
257
- }
259
+ accept: 'application/json;odata=nometadata'
260
+ },
261
+ responseType: 'json'
258
262
  };
259
263
  await request.get(requestOptionsGetFile);
260
264
  const requestOptionsCheckOut = {
261
265
  url: `${webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folder)}')/Files('${formatting.encodeQueryParameter(fileName)}')/CheckOut()`,
262
266
  headers: {
263
- 'accept': 'application/json;odata=nometadata'
267
+ accept: 'application/json;odata=nometadata'
264
268
  },
265
269
  responseType: 'json'
266
270
  };
@@ -285,7 +289,7 @@ class SpoFileAddCommand extends SpoCommand {
285
289
  url: `${info.WebUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(info.FolderPath)}')/Files('${formatting.encodeQueryParameter(info.Name)}')/${isLastChunk ? 'Finish' : 'Continue'}Upload(uploadId=guid'${info.Id}',fileOffset=${offset})`,
286
290
  data: fileBuffer,
287
291
  headers: {
288
- 'accept': 'application/json;odata=nometadata',
292
+ accept: 'application/json;odata=nometadata',
289
293
  'content-length': readCount
290
294
  },
291
295
  maxBodyLength: this.fileChunkingThreshold
@@ -341,7 +345,7 @@ class SpoFileAddCommand extends SpoCommand {
341
345
  const requestOptions = {
342
346
  url: `${webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folder)}')/Files('${formatting.encodeQueryParameter(fileName)}')/ListItemAllFields/ParentList?$Select=Id,EnableModeration,EnableVersioning,EnableMinorVersions`,
343
347
  headers: {
344
- 'accept': 'application/json;odata=nometadata'
348
+ accept: 'application/json;odata=nometadata'
345
349
  },
346
350
  responseType: 'json'
347
351
  };
@@ -353,18 +357,17 @@ class SpoFileAddCommand extends SpoCommand {
353
357
  }
354
358
  const requestBody = {
355
359
  formValues: fieldsToUpdate,
356
- bNewDocumentUpdate: true, // true = will automatically checkin the item, but we will use it to perform system update and also do a checkin
360
+ bNewDocumentUpdate: true, // true = will automatically check-in the item, but we will use it to perform system update and also do a check-in
357
361
  checkInComment: checkInComment || ''
358
362
  };
359
- if (this.debug) {
360
- await logger.logToStderr('ValidateUpdateListItem will perform the checkin ...');
361
- await logger.logToStderr('');
363
+ if (this.verbose) {
364
+ await logger.logToStderr('ValidateUpdateListItem will perform the check-in ...');
362
365
  }
363
366
  // update the existing file list item fields
364
367
  const requestOptions = {
365
368
  url: `${webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderPath)}')/Files('${formatting.encodeQueryParameter(fileName)}')/ListItemAllFields/ValidateUpdateListItem()`,
366
369
  headers: {
367
- 'accept': 'application/json;odata=nometadata'
370
+ accept: 'application/json;odata=nometadata'
368
371
  },
369
372
  data: requestBody,
370
373
  responseType: 'json'
@@ -379,11 +382,11 @@ class SpoFileAddCommand extends SpoCommand {
379
382
  }
380
383
  return;
381
384
  }
382
- async fileCheckIn(args, fileName) {
385
+ async fileCheckIn(webUrl, folderUrl, fileName, checkInComment) {
383
386
  const requestOptions = {
384
- url: `${args.options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(args.options.folder)}')/Files('${formatting.encodeQueryParameter(fileName)}')/CheckIn(comment='${formatting.encodeQueryParameter(args.options.checkInComment || '')}',checkintype=0)`,
387
+ url: `${webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderUrl)}')/Files('${formatting.encodeQueryParameter(fileName)}')/CheckIn(comment='${formatting.encodeQueryParameter(checkInComment || '')}',checkintype=0)`,
385
388
  headers: {
386
- 'accept': 'application/json;odata=nometadata'
389
+ accept: 'application/json;odata=nometadata'
387
390
  },
388
391
  responseType: 'json'
389
392
  };
@@ -28,40 +28,81 @@ class SpoFolderAddCommand extends SpoCommand {
28
28
  }
29
29
  async commandAction(logger, args) {
30
30
  try {
31
- if (this.verbose) {
32
- await logger.logToStderr(`Adding folder to site ${args.options.webUrl}...`);
33
- }
34
31
  const parentFolderServerRelativeUrl = urlUtil.getServerRelativePath(args.options.webUrl, args.options.parentFolderUrl);
35
32
  const serverRelativeUrl = `${parentFolderServerRelativeUrl}/${args.options.name}`;
36
- const requestOptions = {
37
- headers: {
38
- 'accept': 'application/json;odata=nometadata'
39
- },
40
- responseType: 'json'
41
- };
42
- if (args.options.color === undefined) {
43
- requestOptions.url = `${args.options.webUrl}/_api/web/folders/addUsingPath(decodedUrl='${formatting.encodeQueryParameter(serverRelativeUrl)}')`;
33
+ if (args.options.ensureParentFolders) {
34
+ await this.ensureParentFolderPath(args.options, parentFolderServerRelativeUrl, logger);
44
35
  }
45
- else {
46
- requestOptions.url = `${args.options.webUrl}/_api/foldercoloring/createfolder(DecodedUrl='${formatting.encodeQueryParameter(serverRelativeUrl)}', overwrite=false)`;
47
- requestOptions.data = {
48
- coloringInformation: {
49
- ColorHex: FolderColorValues[args.options.color] || args.options.color
50
- }
51
- };
52
- }
53
- const folder = await request.post(requestOptions);
36
+ const folder = await this.addFolder(serverRelativeUrl, args.options, logger);
54
37
  await logger.log(folder);
55
38
  }
56
39
  catch (err) {
57
40
  this.handleRejectedODataJsonPromise(err);
58
41
  }
59
42
  }
43
+ async ensureParentFolderPath(options, parentFolderPath, logger) {
44
+ if (this.verbose) {
45
+ await logger.logToStderr(`Ensuring parent folders exist...`);
46
+ }
47
+ const parsedUrl = new URL(options.webUrl);
48
+ const absoluteFolderUrl = `${parsedUrl.origin}${parentFolderPath}`;
49
+ const relativeFolderPath = absoluteFolderUrl.replace(options.webUrl, '');
50
+ const parentFolders = relativeFolderPath.split('/').filter(folder => folder !== '');
51
+ for (let i = 1; i < parentFolders.length; i++) {
52
+ const currentFolderPath = parentFolders.slice(0, i + 1).join('/');
53
+ if (this.verbose) {
54
+ await logger.logToStderr(`Checking if folder '${currentFolderPath}' exists...`);
55
+ }
56
+ const folderExists = await this.getFolderExists(options.webUrl, currentFolderPath);
57
+ if (!folderExists) {
58
+ await this.addFolder(currentFolderPath, options, logger);
59
+ }
60
+ }
61
+ }
62
+ async getFolderExists(webUrl, folderServerRelativeUrl) {
63
+ const requestUrl = `${webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(folderServerRelativeUrl)}')?$select=Exists`;
64
+ const requestOptions = {
65
+ url: requestUrl,
66
+ headers: {
67
+ 'accept': 'application/json;odata=nometadata'
68
+ },
69
+ responseType: 'json'
70
+ };
71
+ const response = await request.get(requestOptions);
72
+ return response.Exists;
73
+ }
74
+ async addFolder(serverRelativeUrl, options, logger) {
75
+ if (this.verbose) {
76
+ const folderName = serverRelativeUrl.split('/').pop();
77
+ const folderLocation = serverRelativeUrl.split('/').slice(0, -1).join('/');
78
+ await logger.logToStderr(`Adding folder with name '${folderName}' at location '${folderLocation}'...`);
79
+ }
80
+ const requestOptions = {
81
+ headers: {
82
+ 'accept': 'application/json;odata=nometadata'
83
+ },
84
+ responseType: 'json'
85
+ };
86
+ if (options.color === undefined) {
87
+ requestOptions.url = `${options.webUrl}/_api/web/folders/addUsingPath(decodedUrl='${formatting.encodeQueryParameter(serverRelativeUrl)}')`;
88
+ }
89
+ else {
90
+ requestOptions.url = `${options.webUrl}/_api/foldercoloring/createfolder(DecodedUrl='${formatting.encodeQueryParameter(serverRelativeUrl)}', overwrite=false)`;
91
+ requestOptions.data = {
92
+ coloringInformation: {
93
+ ColorHex: FolderColorValues[options.color] || options.color
94
+ }
95
+ };
96
+ }
97
+ const response = await request.post(requestOptions);
98
+ return response;
99
+ }
60
100
  }
61
101
  _SpoFolderAddCommand_instances = new WeakSet(), _SpoFolderAddCommand_initTelemetry = function _SpoFolderAddCommand_initTelemetry() {
62
102
  this.telemetry.push((args) => {
63
103
  Object.assign(this.telemetryProperties, {
64
- color: typeof args.options.color !== 'undefined'
104
+ color: typeof args.options.color !== 'undefined',
105
+ ensureParentFolders: !!args.options.ensureParentFolders
65
106
  });
66
107
  });
67
108
  }, _SpoFolderAddCommand_initOptions = function _SpoFolderAddCommand_initOptions() {
@@ -74,6 +115,8 @@ _SpoFolderAddCommand_instances = new WeakSet(), _SpoFolderAddCommand_initTelemet
74
115
  }, {
75
116
  option: '--color [color]',
76
117
  autocomplete: Object.keys(FolderColorValues)
118
+ }, {
119
+ option: '--ensureParentFolders [ensureParentFolders]'
77
120
  });
78
121
  }, _SpoFolderAddCommand_initValidators = function _SpoFolderAddCommand_initValidators() {
79
122
  this.validators.push(async (args) => {
@@ -88,6 +131,7 @@ _SpoFolderAddCommand_instances = new WeakSet(), _SpoFolderAddCommand_initTelemet
88
131
  });
89
132
  }, _SpoFolderAddCommand_initTypes = function _SpoFolderAddCommand_initTypes() {
90
133
  this.types.string.push('webUrl', 'parentFolderUrl', 'name', 'color');
134
+ this.types.boolean.push('ensureParentFolders');
91
135
  };
92
136
  export default new SpoFolderAddCommand();
93
137
  //# sourceMappingURL=folder-add.js.map
@@ -26,24 +26,24 @@ class TeamsUserAppAddCommand extends GraphCommand {
26
26
  __classPrivateFieldGet(this, _TeamsUserAppAddCommand_instances, "m", _TeamsUserAppAddCommand_initOptionSets).call(this);
27
27
  }
28
28
  async commandAction(logger, args) {
29
- const appId = await this.getAppId(args);
30
- const userId = (args.options.userId ?? args.options.userName);
31
- const endpoint = `${this.resource}/v1.0`;
32
- if (this.verbose) {
33
- await logger.logToStderr(`Removing app with ID ${appId} for user ${args.options.userId}`);
34
- }
35
- const requestOptions = {
36
- url: `${endpoint}/users/${formatting.encodeQueryParameter(userId)}/teamwork/installedApps`,
37
- headers: {
38
- 'content-type': 'application/json;odata=nometadata',
39
- 'accept': 'application/json;odata.metadata=none'
40
- },
41
- responseType: 'json',
42
- data: {
43
- 'teamsApp@odata.bind': `${endpoint}/appCatalogs/teamsApps/${appId}`
44
- }
45
- };
46
29
  try {
30
+ const appId = await this.getAppId(args);
31
+ const userId = (args.options.userId ?? args.options.userName);
32
+ const endpoint = `${this.resource}/v1.0`;
33
+ if (this.verbose) {
34
+ await logger.logToStderr(`Adding app with ID ${appId} for user ${args.options.userId}`);
35
+ }
36
+ const requestOptions = {
37
+ url: `${endpoint}/users/${formatting.encodeQueryParameter(userId)}/teamwork/installedApps`,
38
+ headers: {
39
+ 'content-type': 'application/json;odata=nometadata',
40
+ 'accept': 'application/json;odata.metadata=none'
41
+ },
42
+ responseType: 'json',
43
+ data: {
44
+ 'teamsApp@odata.bind': `${endpoint}/appCatalogs/teamsApps/${appId}`
45
+ }
46
+ };
47
47
  await request.post(requestOptions);
48
48
  }
49
49
  catch (err) {
@@ -0,0 +1,106 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _TeamsUserAppUpgradeCommand_instances, _TeamsUserAppUpgradeCommand_initTelemetry, _TeamsUserAppUpgradeCommand_initOptions, _TeamsUserAppUpgradeCommand_initValidators, _TeamsUserAppUpgradeCommand_initOptionSets, _TeamsUserAppUpgradeCommand_initTypes;
7
+ import { cli } from '../../../../cli/cli.js';
8
+ import request from '../../../../request.js';
9
+ import { formatting } from '../../../../utils/formatting.js';
10
+ import { odata } from '../../../../utils/odata.js';
11
+ import { validation } from '../../../../utils/validation.js';
12
+ import GraphCommand from '../../../base/GraphCommand.js';
13
+ import commands from '../../commands.js';
14
+ class TeamsUserAppUpgradeCommand extends GraphCommand {
15
+ get name() {
16
+ return commands.USER_APP_UPGRADE;
17
+ }
18
+ get description() {
19
+ return 'Upgrade an app in the personal scope of the specified user';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _TeamsUserAppUpgradeCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _TeamsUserAppUpgradeCommand_instances, "m", _TeamsUserAppUpgradeCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _TeamsUserAppUpgradeCommand_instances, "m", _TeamsUserAppUpgradeCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _TeamsUserAppUpgradeCommand_instances, "m", _TeamsUserAppUpgradeCommand_initValidators).call(this);
27
+ __classPrivateFieldGet(this, _TeamsUserAppUpgradeCommand_instances, "m", _TeamsUserAppUpgradeCommand_initOptionSets).call(this);
28
+ __classPrivateFieldGet(this, _TeamsUserAppUpgradeCommand_instances, "m", _TeamsUserAppUpgradeCommand_initTypes).call(this);
29
+ }
30
+ async commandAction(logger, args) {
31
+ try {
32
+ if (this.verbose) {
33
+ await logger.logToStderr(`Upgrading app ${args.options.id || args.options.name} for user ${args.options.userId || args.options.userName}`);
34
+ }
35
+ const installedAppId = await this.getInstalledAppId(args.options, logger);
36
+ const requestOptions = {
37
+ url: `${this.resource}/v1.0/users/${formatting.encodeQueryParameter(args.options.userId || args.options.userName)}/teamwork/installedApps/${installedAppId}/upgrade`,
38
+ headers: {
39
+ 'accept': 'application/json;odata.metadata=none'
40
+ }
41
+ };
42
+ await request.post(requestOptions);
43
+ }
44
+ catch (err) {
45
+ this.handleRejectedODataJsonPromise(err);
46
+ }
47
+ }
48
+ async getInstalledAppId(options, logger) {
49
+ if (this.verbose) {
50
+ await logger.logToStderr(`Retrieving app ID`);
51
+ }
52
+ if (options.id) {
53
+ return options.id;
54
+ }
55
+ const installedApps = await odata.getAllItems(`${this.resource}/v1.0/users/${formatting.encodeQueryParameter(options.userId || options.userName)}/teamwork/installedApps?$expand=teamsAppDefinition&$filter=teamsAppDefinition/displayName eq '${formatting.encodeQueryParameter(options.name)}'&$select=id`);
56
+ if (installedApps.length === 1) {
57
+ return installedApps[0].id;
58
+ }
59
+ if (installedApps.length === 0) {
60
+ throw `The specified Teams app ${options.name} does not exist or is not installed for the user`;
61
+ }
62
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', installedApps);
63
+ const result = (await cli.handleMultipleResultsFound(`Multiple installed Teams apps with name '${options.name}' found.`, resultAsKeyValuePair));
64
+ return result.id;
65
+ }
66
+ }
67
+ _TeamsUserAppUpgradeCommand_instances = new WeakSet(), _TeamsUserAppUpgradeCommand_initTelemetry = function _TeamsUserAppUpgradeCommand_initTelemetry() {
68
+ this.telemetry.push((args) => {
69
+ Object.assign(this.telemetryProperties, {
70
+ id: typeof args.options.id !== 'undefined',
71
+ name: typeof args.options.name !== 'undefined',
72
+ userId: typeof args.options.userId !== 'undefined',
73
+ userName: typeof args.options.userName !== 'undefined'
74
+ });
75
+ });
76
+ }, _TeamsUserAppUpgradeCommand_initOptions = function _TeamsUserAppUpgradeCommand_initOptions() {
77
+ this.options.unshift({
78
+ option: '--id [id]'
79
+ }, {
80
+ option: '--name [name]'
81
+ }, {
82
+ option: '--userId [userId]'
83
+ }, {
84
+ option: '--userName [userName]'
85
+ });
86
+ }, _TeamsUserAppUpgradeCommand_initValidators = function _TeamsUserAppUpgradeCommand_initValidators() {
87
+ this.validators.push(async (args) => {
88
+ if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
89
+ return `${args.options.userId} is not a valid GUID`;
90
+ }
91
+ if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) {
92
+ return `${args.options.userName} is not a valid userName`;
93
+ }
94
+ return true;
95
+ });
96
+ }, _TeamsUserAppUpgradeCommand_initOptionSets = function _TeamsUserAppUpgradeCommand_initOptionSets() {
97
+ this.optionSets.push({
98
+ options: ['id', 'name']
99
+ }, {
100
+ options: ['userId', 'userName']
101
+ });
102
+ }, _TeamsUserAppUpgradeCommand_initTypes = function _TeamsUserAppUpgradeCommand_initTypes() {
103
+ this.types.string.push('id', 'name', 'userId', 'userName');
104
+ };
105
+ export default new TeamsUserAppUpgradeCommand();
106
+ //# sourceMappingURL=user-app-upgrade.js.map