@pnp/cli-microsoft365 7.8.0-beta.5ca5055 → 7.8.0-beta.a83837a
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/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/cli/cli.js +5 -8
- package/dist/index.js +13 -12
- package/dist/m365/commands/setup.js +3 -3
- package/dist/m365/entra/commands/app/app-permission-add.js +25 -6
- package/dist/m365/entra/commands/app/app-permission-list.js +17 -5
- package/dist/m365/entra/commands/group/group-add.js +12 -14
- package/dist/m365/entra/commands/group/group-user-add.js +6 -7
- package/dist/m365/entra/commands/m365group/m365group-add.js +4 -2
- package/dist/m365/entra/commands/user/user-registrationdetails-list.js +6 -7
- package/dist/m365/outlook/commands/message/message-list.js +87 -17
- package/dist/m365/planner/commands/bucket/bucket-add.js +4 -7
- package/dist/m365/planner/commands/bucket/bucket-get.js +7 -30
- package/dist/m365/planner/commands/bucket/bucket-list.js +3 -6
- package/dist/m365/planner/commands/bucket/bucket-remove.js +8 -25
- package/dist/m365/planner/commands/bucket/bucket-set.js +12 -34
- package/dist/m365/planner/commands/plan/plan-add.js +17 -7
- package/dist/m365/planner/commands/plan/plan-get.js +12 -22
- package/dist/m365/planner/commands/plan/plan-list.js +1 -2
- package/dist/m365/planner/commands/plan/plan-remove.js +5 -3
- package/dist/m365/planner/commands/plan/plan-set.js +18 -10
- package/dist/m365/planner/commands/roster/roster-add.js +1 -2
- package/dist/m365/planner/commands/task/task-add.js +15 -21
- package/dist/m365/planner/commands/task/task-checklistitem-add.js +1 -1
- package/dist/m365/planner/commands/task/task-checklistitem-remove.js +1 -1
- package/dist/m365/planner/commands/task/task-get.js +5 -26
- package/dist/m365/planner/commands/task/task-list.js +11 -37
- package/dist/m365/planner/commands/task/task-reference-remove.js +1 -1
- package/dist/m365/planner/commands/task/task-remove.js +12 -29
- package/dist/m365/planner/commands/task/task-set.js +15 -21
- package/dist/m365/spo/commands/listitem/listitem-batch-remove.js +222 -0
- package/dist/m365/spo/commands/navigation/navigation-node-add.js +3 -2
- package/dist/m365/spo/commands/navigation/navigation-node-set.js +3 -2
- package/dist/m365/spo/commands/site/site-recyclebinitem-move.js +5 -2
- package/dist/m365/spo/commands/site/site-recyclebinitem-remove.js +3 -2
- package/dist/m365/spo/commands/site/site-remove.js +128 -149
- package/dist/m365/spo/commands/spo-set.js +6 -2
- package/dist/m365/spo/commands.js +1 -0
- package/dist/m365/teams/commands/meeting/meeting-add.js +3 -3
- package/dist/m365/teams/commands/team/team-add.js +22 -16
- package/dist/utils/planner.js +87 -8
- package/dist/utils/urlUtil.js +8 -0
- package/dist/utils/validation.js +8 -5
- package/docs/docs/cmd/entra/app/app-permission-add.mdx +7 -4
- package/docs/docs/cmd/entra/app/app-permission-list.mdx +14 -5
- package/docs/docs/cmd/entra/m365group/m365group-add.mdx +24 -24
- package/docs/docs/cmd/outlook/message/message-list.mdx +18 -6
- package/docs/docs/cmd/spo/listitem/listitem-batch-remove.mdx +70 -0
- package/docs/docs/cmd/spo/site/site-remove.mdx +9 -19
- package/package.json +1 -1
|
@@ -4,7 +4,6 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
6
|
var _PlannerTaskListCommand_instances, _PlannerTaskListCommand_initTelemetry, _PlannerTaskListCommand_initOptions, _PlannerTaskListCommand_initValidators, _PlannerTaskListCommand_initOptionSets, _PlannerTaskListCommand_initTypes;
|
|
7
|
-
import request from '../../../../request.js';
|
|
8
7
|
import { entraGroup } from '../../../../utils/entraGroup.js';
|
|
9
8
|
import { formatting } from '../../../../utils/formatting.js';
|
|
10
9
|
import { odata } from '../../../../utils/odata.js';
|
|
@@ -37,37 +36,27 @@ class PlannerTaskListCommand extends GraphCommand {
|
|
|
37
36
|
const planTitle = args.options.planTitle;
|
|
38
37
|
let planId = args.options.planId;
|
|
39
38
|
let taskItems = [];
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
try {
|
|
40
|
+
if (bucketId || bucketName) {
|
|
42
41
|
bucketId = await this.getBucketId(args);
|
|
43
42
|
taskItems = await odata.getAllItems(`${this.resource}/v1.0/planner/buckets/${bucketId}/tasks`);
|
|
44
43
|
const betaTasks = await odata.getAllItems(`${this.resource}/beta/planner/buckets/${bucketId}/tasks`);
|
|
45
44
|
await logger.log(this.mergeTaskPriority(taskItems, betaTasks));
|
|
46
45
|
}
|
|
47
|
-
|
|
48
|
-
this.handleRejectedODataJsonPromise(err);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else if (planId || planTitle) {
|
|
52
|
-
try {
|
|
46
|
+
else if (planId || planTitle) {
|
|
53
47
|
planId = await this.getPlanId(args);
|
|
54
48
|
taskItems = await odata.getAllItems(`${this.resource}/v1.0/planner/plans/${planId}/tasks`);
|
|
55
49
|
const betaTasks = await odata.getAllItems(`${this.resource}/beta/planner/plans/${planId}/tasks`);
|
|
56
50
|
await logger.log(this.mergeTaskPriority(taskItems, betaTasks));
|
|
57
51
|
}
|
|
58
|
-
|
|
59
|
-
this.handleRejectedODataJsonPromise(err);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
try {
|
|
52
|
+
else {
|
|
64
53
|
taskItems = await odata.getAllItems(`${this.resource}/v1.0/me/planner/tasks`);
|
|
65
54
|
const betaTasks = await odata.getAllItems(`${this.resource}/beta/me/planner/tasks`);
|
|
66
55
|
await logger.log(this.mergeTaskPriority(taskItems, betaTasks));
|
|
67
56
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.handleRejectedODataJsonPromise(err);
|
|
71
60
|
}
|
|
72
61
|
}
|
|
73
62
|
async getBucketId(args) {
|
|
@@ -75,40 +64,25 @@ class PlannerTaskListCommand extends GraphCommand {
|
|
|
75
64
|
return formatting.encodeQueryParameter(args.options.bucketId);
|
|
76
65
|
}
|
|
77
66
|
const planId = await this.getPlanId(args);
|
|
78
|
-
|
|
79
|
-
url: `${this.resource}/v1.0/planner/plans/${planId}/buckets`,
|
|
80
|
-
headers: {
|
|
81
|
-
accept: 'application/json;odata.metadata=none'
|
|
82
|
-
},
|
|
83
|
-
responseType: 'json'
|
|
84
|
-
};
|
|
85
|
-
const response = await request.get(requestOptions);
|
|
86
|
-
const bucket = response.value.find(val => val.name === args.options.bucketName);
|
|
87
|
-
if (!bucket) {
|
|
88
|
-
throw `The specified bucket does not exist`;
|
|
89
|
-
}
|
|
90
|
-
return bucket.id;
|
|
67
|
+
return planner.getBucketIdByTitle(args.options.bucketName, planId);
|
|
91
68
|
}
|
|
92
69
|
async getPlanId(args) {
|
|
93
70
|
if (args.options.planId) {
|
|
94
71
|
return formatting.encodeQueryParameter(args.options.planId);
|
|
95
72
|
}
|
|
96
73
|
if (args.options.rosterId) {
|
|
97
|
-
|
|
98
|
-
return plan.id;
|
|
74
|
+
return planner.getPlanIdByRosterId(args.options.rosterId);
|
|
99
75
|
}
|
|
100
76
|
else {
|
|
101
77
|
const groupId = await this.getGroupId(args);
|
|
102
|
-
|
|
103
|
-
return plan.id;
|
|
78
|
+
return planner.getPlanIdByTitle(args.options.planTitle, groupId);
|
|
104
79
|
}
|
|
105
80
|
}
|
|
106
81
|
async getGroupId(args) {
|
|
107
82
|
if (args.options.ownerGroupId) {
|
|
108
83
|
return formatting.encodeQueryParameter(args.options.ownerGroupId);
|
|
109
84
|
}
|
|
110
|
-
|
|
111
|
-
return group.id;
|
|
85
|
+
return entraGroup.getGroupIdByDisplayName(args.options.ownerGroupName);
|
|
112
86
|
}
|
|
113
87
|
mergeTaskPriority(taskItems, betaTaskItems) {
|
|
114
88
|
const findBetaTask = (id) => betaTaskItems.find(task => task.id === id);
|
|
@@ -94,7 +94,7 @@ _PlannerTaskReferenceRemoveCommand_instances = new WeakSet(), _PlannerTaskRefere
|
|
|
94
94
|
Object.assign(this.telemetryProperties, {
|
|
95
95
|
url: typeof args.options.url !== 'undefined',
|
|
96
96
|
alias: typeof args.options.alias !== 'undefined',
|
|
97
|
-
force:
|
|
97
|
+
force: !!args.options.force
|
|
98
98
|
});
|
|
99
99
|
});
|
|
100
100
|
}, _PlannerTaskReferenceRemoveCommand_initOptions = function _PlannerTaskReferenceRemoveCommand_initOptions() {
|
|
@@ -33,6 +33,9 @@ class PlannerTaskRemoveCommand extends GraphCommand {
|
|
|
33
33
|
const removeTask = async () => {
|
|
34
34
|
try {
|
|
35
35
|
const task = await this.getTask(args.options);
|
|
36
|
+
if (this.verbose) {
|
|
37
|
+
await logger.logToStderr(`Removing task '${task.title}' ...`);
|
|
38
|
+
}
|
|
36
39
|
const requestOptions = {
|
|
37
40
|
url: `${this.resource}/v1.0/planner/tasks/${task.id}`,
|
|
38
41
|
headers: {
|
|
@@ -72,15 +75,15 @@ class PlannerTaskRemoveCommand extends GraphCommand {
|
|
|
72
75
|
const bucketId = await this.getBucketId(options);
|
|
73
76
|
// $filter is not working on the buckets/{bucketId}/tasks endpoint, hence it is not being used.
|
|
74
77
|
const tasks = await odata.getAllItems(`${this.resource}/v1.0/planner/buckets/${bucketId}/tasks?$select=title,id`, 'minimal');
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
78
|
+
const filteredTasks = tasks.filter(b => title.toLocaleLowerCase() === b.title.toLocaleLowerCase());
|
|
79
|
+
if (filteredTasks.length === 0) {
|
|
77
80
|
throw `The specified task ${title} does not exist`;
|
|
78
81
|
}
|
|
79
|
-
if (
|
|
80
|
-
const resultAsKeyValuePair = formatting.convertArrayToHashTable('id',
|
|
82
|
+
if (filteredTasks.length > 1) {
|
|
83
|
+
const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', filteredTasks);
|
|
81
84
|
return await cli.handleMultipleResultsFound(`Multiple tasks with title '${title}' found.`, resultAsKeyValuePair);
|
|
82
85
|
}
|
|
83
|
-
return
|
|
86
|
+
return filteredTasks[0];
|
|
84
87
|
}
|
|
85
88
|
async getBucketId(options) {
|
|
86
89
|
const { bucketId, bucketName } = options;
|
|
@@ -88,24 +91,7 @@ class PlannerTaskRemoveCommand extends GraphCommand {
|
|
|
88
91
|
return bucketId;
|
|
89
92
|
}
|
|
90
93
|
const planId = await this.getPlanId(options);
|
|
91
|
-
|
|
92
|
-
url: `${this.resource}/v1.0/planner/plans/${planId}/buckets?$select=id,name`,
|
|
93
|
-
headers: {
|
|
94
|
-
accept: 'application/json;odata.metadata=none'
|
|
95
|
-
},
|
|
96
|
-
responseType: 'json'
|
|
97
|
-
};
|
|
98
|
-
const buckets = await request.get(requestOptions);
|
|
99
|
-
const filteredBuckets = buckets.value.filter(b => bucketName.toLocaleLowerCase() === b.name.toLocaleLowerCase());
|
|
100
|
-
if (filteredBuckets.length === 0) {
|
|
101
|
-
throw `The specified bucket ${bucketName} does not exist`;
|
|
102
|
-
}
|
|
103
|
-
if (filteredBuckets.length > 1) {
|
|
104
|
-
const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', filteredBuckets);
|
|
105
|
-
const result = await cli.handleMultipleResultsFound(`Multiple buckets with name '${bucketName}' found.`, resultAsKeyValuePair);
|
|
106
|
-
return result.id;
|
|
107
|
-
}
|
|
108
|
-
return filteredBuckets[0].id;
|
|
94
|
+
return planner.getBucketIdByTitle(bucketName, planId);
|
|
109
95
|
}
|
|
110
96
|
async getPlanId(options) {
|
|
111
97
|
const { planId, planTitle, rosterId } = options;
|
|
@@ -113,13 +99,11 @@ class PlannerTaskRemoveCommand extends GraphCommand {
|
|
|
113
99
|
return planId;
|
|
114
100
|
}
|
|
115
101
|
if (options.rosterId) {
|
|
116
|
-
|
|
117
|
-
return plan.id;
|
|
102
|
+
return planner.getPlanIdByRosterId(rosterId);
|
|
118
103
|
}
|
|
119
104
|
else {
|
|
120
105
|
const groupId = await this.getGroupId(options);
|
|
121
|
-
|
|
122
|
-
return plan.id;
|
|
106
|
+
return planner.getPlanIdByTitle(planTitle, groupId);
|
|
123
107
|
}
|
|
124
108
|
}
|
|
125
109
|
async getGroupId(options) {
|
|
@@ -127,8 +111,7 @@ class PlannerTaskRemoveCommand extends GraphCommand {
|
|
|
127
111
|
if (ownerGroupId) {
|
|
128
112
|
return ownerGroupId;
|
|
129
113
|
}
|
|
130
|
-
|
|
131
|
-
return group.id;
|
|
114
|
+
return entraGroup.getGroupIdByDisplayName(ownerGroupName);
|
|
132
115
|
}
|
|
133
116
|
}
|
|
134
117
|
_PlannerTaskRemoveCommand_instances = new WeakSet(), _PlannerTaskRemoveCommand_initTelemetry = function _PlannerTaskRemoveCommand_initTelemetry() {
|
|
@@ -154,40 +154,25 @@ class PlannerTaskSetCommand extends GraphCommand {
|
|
|
154
154
|
return undefined;
|
|
155
155
|
}
|
|
156
156
|
const planId = await this.getPlanId(options);
|
|
157
|
-
|
|
158
|
-
url: `${this.resource}/v1.0/planner/plans/${planId}/buckets?$select=id,name`,
|
|
159
|
-
headers: {
|
|
160
|
-
accept: 'application/json;odata.metadata=none'
|
|
161
|
-
},
|
|
162
|
-
responseType: 'json'
|
|
163
|
-
};
|
|
164
|
-
const response = await request.get(requestOptions);
|
|
165
|
-
const bucket = response.value.find(val => val.name === options.bucketName);
|
|
166
|
-
if (!bucket) {
|
|
167
|
-
throw 'The specified bucket does not exist';
|
|
168
|
-
}
|
|
169
|
-
return bucket.id;
|
|
157
|
+
return planner.getBucketIdByTitle(options.bucketName, planId);
|
|
170
158
|
}
|
|
171
159
|
async getPlanId(options) {
|
|
172
160
|
if (options.planId) {
|
|
173
161
|
return options.planId;
|
|
174
162
|
}
|
|
175
163
|
if (options.rosterId) {
|
|
176
|
-
|
|
177
|
-
return plan.id;
|
|
164
|
+
return planner.getPlanIdByRosterId(options.rosterId);
|
|
178
165
|
}
|
|
179
166
|
else {
|
|
180
167
|
const groupId = await this.getGroupId(options);
|
|
181
|
-
|
|
182
|
-
return plan.id;
|
|
168
|
+
return planner.getPlanIdByTitle(options.planTitle, groupId);
|
|
183
169
|
}
|
|
184
170
|
}
|
|
185
171
|
async getGroupId(options) {
|
|
186
172
|
if (options.ownerGroupId) {
|
|
187
173
|
return options.ownerGroupId;
|
|
188
174
|
}
|
|
189
|
-
|
|
190
|
-
return group.id;
|
|
175
|
+
return entraGroup.getGroupIdByDisplayName(options.ownerGroupName);
|
|
191
176
|
}
|
|
192
177
|
mapRequestBody(options, appliedCategories) {
|
|
193
178
|
const requestBody = {};
|
|
@@ -266,8 +251,17 @@ _PlannerTaskSetCommand_instances = new WeakSet(), _PlannerTaskSetCommand_initTel
|
|
|
266
251
|
if (args.options.percentComplete && (args.options.percentComplete < 0 || args.options.percentComplete > 100)) {
|
|
267
252
|
return `percentComplete should be between 0 and 100`;
|
|
268
253
|
}
|
|
269
|
-
if (args.options.assignedToUserIds
|
|
270
|
-
|
|
254
|
+
if (args.options.assignedToUserIds) {
|
|
255
|
+
const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.assignedToUserIds);
|
|
256
|
+
if (isValidGUIDArrayResult !== true) {
|
|
257
|
+
return `The following GUIDs are invalid for the option 'assignedToUserIds': ${isValidGUIDArrayResult}.`;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (args.options.assignedToUserNames) {
|
|
261
|
+
const isValidUPNArrayResult = validation.isValidUserPrincipalNameArray(args.options.assignedToUserNames);
|
|
262
|
+
if (isValidUPNArrayResult !== true) {
|
|
263
|
+
return `The following user principal names are invalid for the option 'assignedToUserNames': ${isValidUPNArrayResult}.`;
|
|
264
|
+
}
|
|
271
265
|
}
|
|
272
266
|
if (args.options.appliedCategories && args.options.appliedCategories.split(',').filter(category => this.allowedAppliedCategories.indexOf(category.toLocaleLowerCase()) < 0).length !== 0) {
|
|
273
267
|
return 'The appliedCategories contains invalid value. Specify either category1, category2, category3, category4, category5 and/or category6 as properties';
|
|
@@ -0,0 +1,222 @@
|
|
|
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 _SpoListItemBatchRemoveCommand_instances, _SpoListItemBatchRemoveCommand_initTelemetry, _SpoListItemBatchRemoveCommand_initOptions, _SpoListItemBatchRemoveCommand_initValidators, _SpoListItemBatchRemoveCommand_initTypes, _SpoListItemBatchRemoveCommand_initOptionSets;
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import os from 'os';
|
|
9
|
+
import SpoCommand from '../../../base/SpoCommand.js';
|
|
10
|
+
import commands from '../../commands.js';
|
|
11
|
+
import { formatting } from '../../../../utils/formatting.js';
|
|
12
|
+
import { urlUtil } from '../../../../utils/urlUtil.js';
|
|
13
|
+
import { v4 } from 'uuid';
|
|
14
|
+
import request from '../../../../request.js';
|
|
15
|
+
import { validation } from '../../../../utils/validation.js';
|
|
16
|
+
import { cli } from '../../../../cli/cli.js';
|
|
17
|
+
class SpoListItemBatchRemoveCommand extends SpoCommand {
|
|
18
|
+
get name() {
|
|
19
|
+
return commands.LISTITEM_BATCH_REMOVE;
|
|
20
|
+
}
|
|
21
|
+
get description() {
|
|
22
|
+
return 'Removes items from a list in batch';
|
|
23
|
+
}
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
_SpoListItemBatchRemoveCommand_instances.add(this);
|
|
27
|
+
__classPrivateFieldGet(this, _SpoListItemBatchRemoveCommand_instances, "m", _SpoListItemBatchRemoveCommand_initTelemetry).call(this);
|
|
28
|
+
__classPrivateFieldGet(this, _SpoListItemBatchRemoveCommand_instances, "m", _SpoListItemBatchRemoveCommand_initOptions).call(this);
|
|
29
|
+
__classPrivateFieldGet(this, _SpoListItemBatchRemoveCommand_instances, "m", _SpoListItemBatchRemoveCommand_initValidators).call(this);
|
|
30
|
+
__classPrivateFieldGet(this, _SpoListItemBatchRemoveCommand_instances, "m", _SpoListItemBatchRemoveCommand_initTypes).call(this);
|
|
31
|
+
__classPrivateFieldGet(this, _SpoListItemBatchRemoveCommand_instances, "m", _SpoListItemBatchRemoveCommand_initOptionSets).call(this);
|
|
32
|
+
}
|
|
33
|
+
async commandAction(logger, args) {
|
|
34
|
+
const removeListItems = async () => {
|
|
35
|
+
try {
|
|
36
|
+
if (this.verbose) {
|
|
37
|
+
logger.logToStderr('Removing the listitems from SharePoint...');
|
|
38
|
+
}
|
|
39
|
+
let idsToRemove = [];
|
|
40
|
+
if (args.options.filePath) {
|
|
41
|
+
const csvContent = fs.readFileSync(args.options.filePath, 'utf-8');
|
|
42
|
+
const jsonContent = formatting.parseCsvToJson(csvContent);
|
|
43
|
+
idsToRemove = jsonContent.map((item) => item['ID']);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
idsToRemove = formatting.splitAndTrim(args.options.ids);
|
|
47
|
+
}
|
|
48
|
+
await this.removeItemsAsBatch(idsToRemove, args.options, logger);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
this.handleRejectedODataJsonPromise(err);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
if (args.options.force) {
|
|
55
|
+
await removeListItems();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const result = await cli.promptForConfirmation({ message: `Are you sure you want to ${args.options.recycle ? "recycle" : "remove"} the list items from list ${args.options.listId || args.options.listTitle || args.options.listUrl} located in site ${args.options.webUrl}?` });
|
|
59
|
+
if (result) {
|
|
60
|
+
await removeListItems();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async removeItemsAsBatch(items, options, logger) {
|
|
65
|
+
const itemsChunks = this.getChunkedArray(items, 10);
|
|
66
|
+
for (const [index, chunk] of itemsChunks.entries()) {
|
|
67
|
+
if (this.verbose) {
|
|
68
|
+
await logger.logToStderr(`Processing chunk ${index + 1} of ${itemsChunks.length}...`);
|
|
69
|
+
}
|
|
70
|
+
await this.postBatchData(chunk, options.webUrl, options);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async postBatchData(chunk, webUrl, options) {
|
|
74
|
+
const batchId = v4();
|
|
75
|
+
const requestBody = this.getRequestBody(chunk, batchId, options);
|
|
76
|
+
const requestOptions = {
|
|
77
|
+
url: `${webUrl}/_api/$batch`,
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': `multipart/mixed; boundary=batch_${batchId}`,
|
|
80
|
+
'Accept': 'application/json;odata=verbose'
|
|
81
|
+
},
|
|
82
|
+
data: requestBody.join('')
|
|
83
|
+
};
|
|
84
|
+
const response = await request.post(requestOptions);
|
|
85
|
+
const errors = this.parseBatchResponseBody(response, chunk);
|
|
86
|
+
if (errors.length > 0) {
|
|
87
|
+
throw `Creating some items failed with the following errors: ${os.EOL}${errors.map(error => { return `- ${error}`; }).join(os.EOL)}`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
getRequestBody(chunk, batchId, options) {
|
|
91
|
+
const changeSetId = v4();
|
|
92
|
+
const batchBody = [];
|
|
93
|
+
batchBody.push(`--batch_${batchId}\n`);
|
|
94
|
+
batchBody.push(`Content-Type: multipart/mixed; boundary="changeset_${changeSetId}"\n\n`);
|
|
95
|
+
batchBody.push('Content-Transfer-Encoding: binary\n\n');
|
|
96
|
+
for (const item of chunk) {
|
|
97
|
+
const actionUrl = this.getActionUrl(options, item);
|
|
98
|
+
batchBody.push(`--changeset_${changeSetId}\n`);
|
|
99
|
+
batchBody.push('Content-Type: application/http\n');
|
|
100
|
+
batchBody.push('Content-Transfer-Encoding: binary\n\n');
|
|
101
|
+
batchBody.push(`DELETE ${actionUrl} HTTP/1.1\n`);
|
|
102
|
+
batchBody.push(`Accept: application/json;odata=nometadata\n`);
|
|
103
|
+
batchBody.push(`If-Match: *\n\n`);
|
|
104
|
+
}
|
|
105
|
+
batchBody.push(`\n\n`);
|
|
106
|
+
batchBody.push(`--changeset_${changeSetId}--\n\n`);
|
|
107
|
+
batchBody.push(`--batch_${batchId}--\n`);
|
|
108
|
+
return batchBody;
|
|
109
|
+
}
|
|
110
|
+
parseBatchResponseBody(response, chunk) {
|
|
111
|
+
const errors = [];
|
|
112
|
+
response.split('\r\n')
|
|
113
|
+
.filter((line) => line.startsWith('{'))
|
|
114
|
+
.forEach((line, index) => {
|
|
115
|
+
const parsedResponse = JSON.parse(line);
|
|
116
|
+
if (parsedResponse.error) {
|
|
117
|
+
const error = parsedResponse.error;
|
|
118
|
+
errors.push(`Item ID ${chunk[index]}: ${error.message.value}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return errors;
|
|
122
|
+
}
|
|
123
|
+
;
|
|
124
|
+
getChunkedArray(inputArray, chunkSize) {
|
|
125
|
+
const result = [];
|
|
126
|
+
for (let i = 0; i < inputArray.length; i += chunkSize) {
|
|
127
|
+
result.push(inputArray.slice(i, i + chunkSize));
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
getActionUrl(options, item) {
|
|
132
|
+
let requestUrl = '';
|
|
133
|
+
if (options.listId) {
|
|
134
|
+
requestUrl += `lists(guid'${formatting.encodeQueryParameter(options.listId)}')`;
|
|
135
|
+
}
|
|
136
|
+
else if (options.listTitle) {
|
|
137
|
+
requestUrl += `lists/getByTitle('${formatting.encodeQueryParameter(options.listTitle)}')`;
|
|
138
|
+
}
|
|
139
|
+
else if (options.listUrl) {
|
|
140
|
+
const listServerRelativeUrl = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
|
|
141
|
+
requestUrl += `GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')`;
|
|
142
|
+
}
|
|
143
|
+
requestUrl += `/items(${item})`;
|
|
144
|
+
if (options.recycle) {
|
|
145
|
+
requestUrl += '/recycle()';
|
|
146
|
+
}
|
|
147
|
+
return requestUrl;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
_SpoListItemBatchRemoveCommand_instances = new WeakSet(), _SpoListItemBatchRemoveCommand_initTelemetry = function _SpoListItemBatchRemoveCommand_initTelemetry() {
|
|
151
|
+
this.telemetry.push((args) => {
|
|
152
|
+
Object.assign(this.telemetryProperties, {
|
|
153
|
+
filePath: typeof args.options.filePath !== 'undefined',
|
|
154
|
+
ids: typeof args.options.ids !== 'undefined',
|
|
155
|
+
listId: typeof args.options.listId !== 'undefined',
|
|
156
|
+
listTitle: typeof args.options.listTitle !== 'undefined',
|
|
157
|
+
listUrl: typeof args.options.listUrl !== 'undefined',
|
|
158
|
+
recycle: !!args.options.recycle,
|
|
159
|
+
force: !!args.options.force
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}, _SpoListItemBatchRemoveCommand_initOptions = function _SpoListItemBatchRemoveCommand_initOptions() {
|
|
163
|
+
this.options.unshift({
|
|
164
|
+
option: '-u, --webUrl <webUrl>'
|
|
165
|
+
}, {
|
|
166
|
+
option: '-l, --listId [listId]'
|
|
167
|
+
}, {
|
|
168
|
+
option: '-t, --listTitle [listTitle]'
|
|
169
|
+
}, {
|
|
170
|
+
option: '--listUrl [listUrl]'
|
|
171
|
+
}, {
|
|
172
|
+
option: '-p, --filePath [filePath]'
|
|
173
|
+
}, {
|
|
174
|
+
option: '-i, --ids [ids]'
|
|
175
|
+
}, {
|
|
176
|
+
option: '-r, --recycle'
|
|
177
|
+
}, {
|
|
178
|
+
option: '-f, --force'
|
|
179
|
+
});
|
|
180
|
+
}, _SpoListItemBatchRemoveCommand_initValidators = function _SpoListItemBatchRemoveCommand_initValidators() {
|
|
181
|
+
this.validators.push(async (args) => {
|
|
182
|
+
const isValidSharePointUrl = validation.isValidSharePointUrl(args.options.webUrl);
|
|
183
|
+
if (isValidSharePointUrl !== true) {
|
|
184
|
+
return isValidSharePointUrl;
|
|
185
|
+
}
|
|
186
|
+
if (args.options.listId &&
|
|
187
|
+
!validation.isValidGuid(args.options.listId)) {
|
|
188
|
+
return `${args.options.listId} in option listId is not a valid GUID.`;
|
|
189
|
+
}
|
|
190
|
+
if (args.options.filePath) {
|
|
191
|
+
if (!fs.existsSync(args.options.filePath)) {
|
|
192
|
+
return `File with path ${args.options.filePath} does not exist.`;
|
|
193
|
+
}
|
|
194
|
+
const fileContent = fs.readFileSync(args.options.filePath, 'utf-8');
|
|
195
|
+
const jsonContent = formatting.parseCsvToJson(fileContent);
|
|
196
|
+
if (!jsonContent[0].hasOwnProperty('ID')) {
|
|
197
|
+
return `The file does not contain the required header row with the column name 'ID'.`;
|
|
198
|
+
}
|
|
199
|
+
const nonNumbers = jsonContent.filter(element => isNaN(Number(element['ID'].toString().trim()))).map(element => element['ID']);
|
|
200
|
+
if (nonNumbers.length > 0) {
|
|
201
|
+
return `The specified ids '${nonNumbers.join(', ')}' are invalid numbers.`;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (args.options.ids) {
|
|
205
|
+
const nonNumbers = formatting.splitAndTrim(args.options.ids).filter(element => isNaN(Number(element)));
|
|
206
|
+
if (nonNumbers.length > 0) {
|
|
207
|
+
return `The specified ids '${nonNumbers.join(', ')}' are invalid numbers.`;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return true;
|
|
211
|
+
});
|
|
212
|
+
}, _SpoListItemBatchRemoveCommand_initTypes = function _SpoListItemBatchRemoveCommand_initTypes() {
|
|
213
|
+
this.types.string.push('webUrl', 'listId', 'listTitle', 'listUrl', 'ids', 'filePath');
|
|
214
|
+
}, _SpoListItemBatchRemoveCommand_initOptionSets = function _SpoListItemBatchRemoveCommand_initOptionSets() {
|
|
215
|
+
this.optionSets.push({
|
|
216
|
+
options: ['listId', 'listTitle', 'listUrl']
|
|
217
|
+
}, {
|
|
218
|
+
options: ['filePath', 'ids']
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
export default new SpoListItemBatchRemoveCommand();
|
|
222
|
+
//# sourceMappingURL=listitem-batch-remove.js.map
|
|
@@ -135,8 +135,9 @@ _SpoNavigationNodeAddCommand_instances = new WeakSet(), _SpoNavigationNodeAddCom
|
|
|
135
135
|
if (audienceIdsSplitted.length > 10) {
|
|
136
136
|
return 'The maximum amount of audienceIds per navigation node exceeded. The maximum amount of auciendeIds is 10.';
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.audienceIds);
|
|
139
|
+
if (isValidGUIDArrayResult !== true) {
|
|
140
|
+
return `The following GUIDs are invalid for the option 'audienceIds': ${isValidGUIDArrayResult}.`;
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
return true;
|
|
@@ -127,8 +127,9 @@ _SpoNavigationNodeSetCommand_instances = new WeakSet(), _SpoNavigationNodeSetCom
|
|
|
127
127
|
if (audienceIdsSplitted.length > 10) {
|
|
128
128
|
return 'The maximum amount of audienceIds per navigation node exceeded. The maximum amount of audienceIds is 10.';
|
|
129
129
|
}
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.audienceIds);
|
|
131
|
+
if (isValidGUIDArrayResult !== true) {
|
|
132
|
+
return `The following GUIDs are invalid for the option 'audienceIds': ${isValidGUIDArrayResult}.`;
|
|
132
133
|
}
|
|
133
134
|
}
|
|
134
135
|
return true;
|
|
@@ -89,8 +89,11 @@ _SpoSiteRecycleBinItemMoveCommand_instances = new WeakSet(), _SpoSiteRecycleBinI
|
|
|
89
89
|
if (isValidSharePointUrl !== true) {
|
|
90
90
|
return isValidSharePointUrl;
|
|
91
91
|
}
|
|
92
|
-
if (args.options.ids
|
|
93
|
-
|
|
92
|
+
if (args.options.ids) {
|
|
93
|
+
const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.ids);
|
|
94
|
+
if (isValidGUIDArrayResult !== true) {
|
|
95
|
+
return `The following GUIDs are invalid for the option 'ids': ${isValidGUIDArrayResult}.`;
|
|
96
|
+
}
|
|
94
97
|
}
|
|
95
98
|
return true;
|
|
96
99
|
});
|
|
@@ -76,8 +76,9 @@ _SpoSiteRecycleBinItemRemoveCommand_instances = new WeakSet(), _SpoSiteRecycleBi
|
|
|
76
76
|
if (isValidSharePointUrl !== true) {
|
|
77
77
|
return isValidSharePointUrl;
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.ids);
|
|
80
|
+
if (isValidGUIDArrayResult !== true) {
|
|
81
|
+
return `The following GUIDs are invalid for the option 'ids': ${isValidGUIDArrayResult}.`;
|
|
81
82
|
}
|
|
82
83
|
return true;
|
|
83
84
|
});
|