@pnp/cli-microsoft365 7.0.0-beta.8726fe8 → 7.0.0-beta.88c4694

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.
@@ -8,6 +8,7 @@ import { odata } from '../../../../utils/odata.js';
8
8
  import { validation } from '../../../../utils/validation.js';
9
9
  import GraphCommand from '../../../base/GraphCommand.js';
10
10
  import commands from '../../commands.js';
11
+ import { aadGroup } from '../../../../utils/aadGroup.js';
11
12
  class AadM365GroupConversationListCommand extends GraphCommand {
12
13
  get name() {
13
14
  return commands.M365GROUP_CONVERSATION_LIST;
@@ -26,6 +27,10 @@ class AadM365GroupConversationListCommand extends GraphCommand {
26
27
  }
27
28
  async commandAction(logger, args) {
28
29
  try {
30
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(args.options.groupId);
31
+ if (!isUnifiedGroup) {
32
+ throw Error(`Specified group with id '${args.options.groupId}' is not a Microsoft 365 group.`);
33
+ }
29
34
  const conversations = await odata.getAllItems(`${this.resource}/v1.0/groups/${args.options.groupId}/conversations`);
30
35
  await logger.log(conversations);
31
36
  }
@@ -31,6 +31,10 @@ class AadM365GroupConversationPostListCommand extends GraphCommand {
31
31
  async commandAction(logger, args) {
32
32
  try {
33
33
  const retrievedgroupId = await this.getGroupId(args);
34
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(retrievedgroupId);
35
+ if (!isUnifiedGroup) {
36
+ throw Error(`Specified group with id '${retrievedgroupId}' is not a Microsoft 365 group.`);
37
+ }
34
38
  const posts = await odata.getAllItems(`${this.resource}/v1.0/groups/${retrievedgroupId}/threads/${args.options.threadId}/posts`);
35
39
  await logger.log(posts);
36
40
  }
@@ -25,10 +25,11 @@ class AadM365GroupGetCommand extends GraphCommand {
25
25
  async commandAction(logger, args) {
26
26
  let group;
27
27
  try {
28
- group = await aadGroup.getGroupById(args.options.id);
29
- if (!group.groupTypes.some(type => type === 'Unified')) {
30
- throw `Specified group with id '${args.options.id}' is not a Microsoft 365 group.`;
28
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(args.options.id);
29
+ if (!isUnifiedGroup) {
30
+ throw Error(`Specified group with id '${args.options.id}' is not a Microsoft 365 group.`);
31
31
  }
32
+ group = await aadGroup.getGroupById(args.options.id);
32
33
  if (args.options.includeSiteUrl) {
33
34
  const requestOptions = {
34
35
  url: `${this.resource}/v1.0/groups/${group.id}/drive?$select=webUrl`,
@@ -6,6 +6,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
6
6
  var _AadM365GroupRemoveCommand_instances, _AadM365GroupRemoveCommand_initTelemetry, _AadM365GroupRemoveCommand_initOptions, _AadM365GroupRemoveCommand_initValidators;
7
7
  import { Cli } from '../../../../cli/Cli.js';
8
8
  import request from '../../../../request.js';
9
+ import { aadGroup } from '../../../../utils/aadGroup.js';
9
10
  import { validation } from '../../../../utils/validation.js';
10
11
  import GraphCommand from '../../../base/GraphCommand.js';
11
12
  import commands from '../../commands.js';
@@ -29,6 +30,10 @@ class AadM365GroupRemoveCommand extends GraphCommand {
29
30
  await logger.logToStderr(`Removing Microsoft 365 Group: ${args.options.id}...`);
30
31
  }
31
32
  try {
33
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(args.options.id);
34
+ if (!isUnifiedGroup) {
35
+ throw Error(`Specified group with id '${args.options.id}' is not a Microsoft 365 group.`);
36
+ }
32
37
  const requestOptions = {
33
38
  url: `${this.resource}/v1.0/groups/${args.options.id}`,
34
39
  headers: {
@@ -5,6 +5,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
5
5
  };
6
6
  var _AadM365GroupRenewCommand_instances, _AadM365GroupRenewCommand_initOptions, _AadM365GroupRenewCommand_initValidators;
7
7
  import request from '../../../../request.js';
8
+ import { aadGroup } from '../../../../utils/aadGroup.js';
8
9
  import { validation } from '../../../../utils/validation.js';
9
10
  import GraphCommand from '../../../base/GraphCommand.js';
10
11
  import commands from '../../commands.js';
@@ -26,6 +27,10 @@ class AadM365GroupRenewCommand extends GraphCommand {
26
27
  await logger.logToStderr(`Renewing Microsoft 365 group's expiration: ${args.options.id}...`);
27
28
  }
28
29
  try {
30
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(args.options.id);
31
+ if (!isUnifiedGroup) {
32
+ throw Error(`Specified group with id '${args.options.id}' is not a Microsoft 365 group.`);
33
+ }
29
34
  const requestOptions = {
30
35
  url: `${this.resource}/v1.0/groups/${args.options.id}/renew/`,
31
36
  headers: {
@@ -11,6 +11,7 @@ import request from '../../../../request.js';
11
11
  import { validation } from '../../../../utils/validation.js';
12
12
  import GraphCommand from '../../../base/GraphCommand.js';
13
13
  import commands from '../../commands.js';
14
+ import { aadGroup } from '../../../../utils/aadGroup.js';
14
15
  class AadM365GroupSetCommand extends GraphCommand {
15
16
  get name() {
16
17
  return commands.M365GROUP_SET;
@@ -29,6 +30,10 @@ class AadM365GroupSetCommand extends GraphCommand {
29
30
  }
30
31
  async commandAction(logger, args) {
31
32
  try {
33
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(args.options.id);
34
+ if (!isUnifiedGroup) {
35
+ throw Error(`Specified group with id '${args.options.id}' is not a Microsoft 365 group.`);
36
+ }
32
37
  if (args.options.displayName || args.options.description || typeof args.options.isPrivate !== 'undefined') {
33
38
  if (this.verbose) {
34
39
  await logger.logToStderr(`Updating Microsoft 365 Group ${args.options.id}...`);
@@ -6,6 +6,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
6
6
  var _AadM365GroupTeamifyCommand_instances, _AadM365GroupTeamifyCommand_initTelemetry, _AadM365GroupTeamifyCommand_initOptions, _AadM365GroupTeamifyCommand_initValidators, _AadM365GroupTeamifyCommand_initOptionSets;
7
7
  import { Cli } from '../../../../cli/Cli.js';
8
8
  import request from '../../../../request.js';
9
+ import { aadGroup } from '../../../../utils/aadGroup.js';
9
10
  import { formatting } from '../../../../utils/formatting.js';
10
11
  import { validation } from '../../../../utils/validation.js';
11
12
  import GraphCommand from '../../../base/GraphCommand.js';
@@ -25,12 +26,12 @@ class AadM365GroupTeamifyCommand extends GraphCommand {
25
26
  __classPrivateFieldGet(this, _AadM365GroupTeamifyCommand_instances, "m", _AadM365GroupTeamifyCommand_initValidators).call(this);
26
27
  __classPrivateFieldGet(this, _AadM365GroupTeamifyCommand_instances, "m", _AadM365GroupTeamifyCommand_initOptionSets).call(this);
27
28
  }
28
- async getGroupId(args) {
29
- if (args.options.id) {
30
- return args.options.id;
29
+ async getGroupId(options) {
30
+ if (options.id) {
31
+ return options.id;
31
32
  }
32
33
  const requestOptions = {
33
- url: `${this.resource}/v1.0/groups?$filter=mailNickname eq '${formatting.encodeQueryParameter(args.options.mailNickname)}'`,
34
+ url: `${this.resource}/v1.0/groups?$filter=mailNickname eq '${formatting.encodeQueryParameter(options.mailNickname)}'`,
34
35
  headers: {
35
36
  accept: 'application/json;odata.metadata=none'
36
37
  },
@@ -43,13 +44,18 @@ class AadM365GroupTeamifyCommand extends GraphCommand {
43
44
  }
44
45
  if (response.value.length > 1) {
45
46
  const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', response.value);
46
- const result = await Cli.handleMultipleResultsFound(`Multiple Microsoft 365 Groups with name '${args.options.mailNickname}' found.`, resultAsKeyValuePair);
47
+ const result = await Cli.handleMultipleResultsFound(`Multiple Microsoft 365 Groups with name '${options.mailNickname}' found.`, resultAsKeyValuePair);
47
48
  return result.id;
48
49
  }
49
50
  return groupItem.id;
50
51
  }
51
52
  async commandAction(logger, args) {
52
53
  try {
54
+ const groupId = await this.getGroupId(args.options);
55
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(groupId);
56
+ if (!isUnifiedGroup) {
57
+ throw Error(`Specified group with id '${groupId}' is not a Microsoft 365 group.`);
58
+ }
53
59
  const data = {
54
60
  "memberSettings": {
55
61
  "allowCreatePrivateChannels": true,
@@ -64,7 +70,6 @@ class AadM365GroupTeamifyCommand extends GraphCommand {
64
70
  "giphyContentRating": "strict"
65
71
  }
66
72
  };
67
- const groupId = await this.getGroupId(args);
68
73
  const requestOptions = {
69
74
  url: `${this.resource}/v1.0/groups/${formatting.encodeQueryParameter(groupId)}/team`,
70
75
  headers: {
@@ -5,6 +5,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
5
5
  };
6
6
  var _AadM365GroupUserAddCommand_instances, _AadM365GroupUserAddCommand_initTelemetry, _AadM365GroupUserAddCommand_initOptions, _AadM365GroupUserAddCommand_initValidators, _AadM365GroupUserAddCommand_initOptionSets;
7
7
  import request from '../../../../request.js';
8
+ import { aadGroup } from '../../../../utils/aadGroup.js';
8
9
  import { formatting } from '../../../../utils/formatting.js';
9
10
  import { validation } from '../../../../utils/validation.js';
10
11
  import GraphCommand from '../../../base/GraphCommand.js';
@@ -31,6 +32,10 @@ class AadM365GroupUserAddCommand extends GraphCommand {
31
32
  async commandAction(logger, args) {
32
33
  try {
33
34
  const providedGroupId = (typeof args.options.groupId !== 'undefined') ? args.options.groupId : args.options.teamId;
35
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(providedGroupId);
36
+ if (!isUnifiedGroup) {
37
+ throw Error(`Specified group with id '${providedGroupId}' is not a Microsoft 365 group.`);
38
+ }
34
39
  let requestOptions = {
35
40
  url: `${this.resource}/v1.0/users/${formatting.encodeQueryParameter(args.options.userName)}/id`,
36
41
  headers: {
@@ -8,6 +8,7 @@ import { odata } from '../../../../utils/odata.js';
8
8
  import { validation } from '../../../../utils/validation.js';
9
9
  import GraphCommand from '../../../base/GraphCommand.js';
10
10
  import commands from '../../commands.js';
11
+ import { aadGroup } from '../../../../utils/aadGroup.js';
11
12
  class AadM365GroupUserListCommand extends GraphCommand {
12
13
  get name() {
13
14
  return commands.M365GROUP_USER_LIST;
@@ -24,6 +25,10 @@ class AadM365GroupUserListCommand extends GraphCommand {
24
25
  }
25
26
  async commandAction(logger, args) {
26
27
  try {
28
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(args.options.groupId);
29
+ if (!isUnifiedGroup) {
30
+ throw Error(`Specified group with id '${args.options.groupId}' is not a Microsoft 365 group.`);
31
+ }
27
32
  let users = await this.getOwners(args.options.groupId, logger);
28
33
  if (args.options.role !== 'Owner') {
29
34
  const membersAndGuests = await this.getMembersAndGuests(args.options.groupId, logger);
@@ -6,6 +6,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
6
6
  var _AadM365GroupUserRemoveCommand_instances, _AadM365GroupUserRemoveCommand_initTelemetry, _AadM365GroupUserRemoveCommand_initOptions, _AadM365GroupUserRemoveCommand_initValidators, _AadM365GroupUserRemoveCommand_initOptionSets;
7
7
  import { Cli } from '../../../../cli/Cli.js';
8
8
  import request from '../../../../request.js';
9
+ import { aadGroup } from '../../../../utils/aadGroup.js';
9
10
  import { formatting } from '../../../../utils/formatting.js';
10
11
  import { validation } from '../../../../utils/validation.js';
11
12
  import GraphCommand from '../../../base/GraphCommand.js';
@@ -33,6 +34,10 @@ class AadM365GroupUserRemoveCommand extends GraphCommand {
33
34
  const groupId = (typeof args.options.groupId !== 'undefined') ? args.options.groupId : args.options.teamId;
34
35
  const removeUser = async () => {
35
36
  try {
37
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(groupId);
38
+ if (!isUnifiedGroup) {
39
+ throw Error(`Specified group with id '${groupId}' is not a Microsoft 365 group.`);
40
+ }
36
41
  // retrieve user
37
42
  const user = await request.get({
38
43
  url: `${this.resource}/v1.0/users/${formatting.encodeQueryParameter(args.options.userName)}/id`,
@@ -10,6 +10,7 @@ import { validation } from '../../../../utils/validation.js';
10
10
  import GraphCommand from '../../../base/GraphCommand.js';
11
11
  import teamsCommands from '../../../teams/commands.js';
12
12
  import commands from '../../commands.js';
13
+ import { aadGroup } from '../../../../utils/aadGroup.js';
13
14
  class AadM365GroupUserSetCommand extends GraphCommand {
14
15
  get name() {
15
16
  return commands.M365GROUP_USER_SET;
@@ -31,6 +32,10 @@ class AadM365GroupUserSetCommand extends GraphCommand {
31
32
  async commandAction(logger, args) {
32
33
  try {
33
34
  const groupId = (typeof args.options.groupId !== 'undefined') ? args.options.groupId : args.options.teamId;
35
+ const isUnifiedGroup = await aadGroup.isUnifiedGroup(groupId);
36
+ if (!isUnifiedGroup) {
37
+ throw Error(`Specified group with id '${groupId}' is not a Microsoft 365 group.`);
38
+ }
34
39
  let users = await this.getOwners(groupId, logger);
35
40
  const membersAndGuests = await this.getMembersAndGuests(groupId, logger);
36
41
  users = users.concat(membersAndGuests);
@@ -0,0 +1,127 @@
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 _SpoListItemAttachmentAddCommand_instances, _SpoListItemAttachmentAddCommand_initTelemetry, _SpoListItemAttachmentAddCommand_initOptions, _SpoListItemAttachmentAddCommand_initValidators, _SpoListItemAttachmentAddCommand_initOptionSets;
7
+ import request from '../../../../request.js';
8
+ import { formatting } from '../../../../utils/formatting.js';
9
+ import { urlUtil } from '../../../../utils/urlUtil.js';
10
+ import { validation } from '../../../../utils/validation.js';
11
+ import SpoCommand from '../../../base/SpoCommand.js';
12
+ import commands from '../../commands.js';
13
+ import fs from 'fs';
14
+ class SpoListItemAttachmentAddCommand extends SpoCommand {
15
+ get name() {
16
+ return commands.LISTITEM_ATTACHMENT_ADD;
17
+ }
18
+ get description() {
19
+ return 'Adds an attachment to a list item';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _SpoListItemAttachmentAddCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _SpoListItemAttachmentAddCommand_instances, "m", _SpoListItemAttachmentAddCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _SpoListItemAttachmentAddCommand_instances, "m", _SpoListItemAttachmentAddCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _SpoListItemAttachmentAddCommand_instances, "m", _SpoListItemAttachmentAddCommand_initValidators).call(this);
27
+ __classPrivateFieldGet(this, _SpoListItemAttachmentAddCommand_instances, "m", _SpoListItemAttachmentAddCommand_initOptionSets).call(this);
28
+ }
29
+ async commandAction(logger, args) {
30
+ if (this.verbose) {
31
+ await logger.logToStderr(`Adding an attachment to list item with id ${args.options.listItemId} on list ${args.options.listId || args.options.listTitle || args.options.listUrl} on web ${args.options.webUrl}.`);
32
+ }
33
+ try {
34
+ const fileName = this.getFileName(args.options.filePath, args.options.fileName);
35
+ const fileBody = fs.readFileSync(args.options.filePath);
36
+ const requestOptions = {
37
+ url: `${args.options.webUrl}/_api/web/${this.getListUrl(args.options.webUrl, args.options.listId, args.options.listTitle, args.options.listUrl)}/items(${args.options.listItemId})/AttachmentFiles/add(FileName='${fileName}')`,
38
+ headers: {
39
+ 'accept': 'application/json;odata=nometadata'
40
+ },
41
+ data: fileBody,
42
+ responseType: 'json'
43
+ };
44
+ const response = await request.post(requestOptions);
45
+ await logger.log(response);
46
+ }
47
+ catch (err) {
48
+ if (err.error &&
49
+ err.error['odata.error'] &&
50
+ err.error['odata.error'].message && err.error['odata.error'].message.value.indexOf('The document or folder name was not changed.') > -1) {
51
+ this.handleError(err.error['odata.error'].message.value.split('\n')[0]);
52
+ }
53
+ else {
54
+ this.handleRejectedODataJsonPromise(err);
55
+ }
56
+ }
57
+ }
58
+ getFileName(filePath, fileName) {
59
+ if (!fileName) {
60
+ return filePath.replace(/^.*[\\\/]/, '');
61
+ }
62
+ const extension = filePath.split('.').pop();
63
+ if (!fileName.endsWith(`.${extension}`)) {
64
+ fileName += `.${extension}`;
65
+ }
66
+ return fileName;
67
+ }
68
+ getListUrl(webUrl, listId, listTitle, listUrl) {
69
+ if (listId) {
70
+ return `lists(guid'${formatting.encodeQueryParameter(listId)}')`;
71
+ }
72
+ else if (listTitle) {
73
+ return `lists/getByTitle('${formatting.encodeQueryParameter(listTitle)}')`;
74
+ }
75
+ else {
76
+ const listServerRelativeUrl = urlUtil.getServerRelativePath(webUrl, listUrl);
77
+ return `GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')`;
78
+ }
79
+ }
80
+ }
81
+ _SpoListItemAttachmentAddCommand_instances = new WeakSet(), _SpoListItemAttachmentAddCommand_initTelemetry = function _SpoListItemAttachmentAddCommand_initTelemetry() {
82
+ this.telemetry.push((args) => {
83
+ Object.assign(this.telemetryProperties, {
84
+ listId: typeof args.options.listId !== 'undefined',
85
+ listTitle: typeof args.options.listTitle !== 'undefined',
86
+ listUrl: typeof args.options.listUrl !== 'undefined',
87
+ fileName: typeof args.options.fileName !== 'undefined'
88
+ });
89
+ });
90
+ }, _SpoListItemAttachmentAddCommand_initOptions = function _SpoListItemAttachmentAddCommand_initOptions() {
91
+ this.options.unshift({
92
+ option: '-u, --webUrl <webUrl>'
93
+ }, {
94
+ option: '--listId [listId]'
95
+ }, {
96
+ option: '--listTitle [listTitle]'
97
+ }, {
98
+ option: '--listUrl [listUrl]'
99
+ }, {
100
+ option: '--listItemId <listItemId>'
101
+ }, {
102
+ option: '-p, --filePath <filePath>'
103
+ }, {
104
+ option: '-n, --fileName [fileName]'
105
+ });
106
+ }, _SpoListItemAttachmentAddCommand_initValidators = function _SpoListItemAttachmentAddCommand_initValidators() {
107
+ this.validators.push(async (args) => {
108
+ const isValidSharePointUrl = validation.isValidSharePointUrl(args.options.webUrl);
109
+ if (isValidSharePointUrl !== true) {
110
+ return isValidSharePointUrl;
111
+ }
112
+ if (isNaN(args.options.listItemId)) {
113
+ return `${args.options.listItemId} in option listItemId is not a valid number.`;
114
+ }
115
+ if (args.options.listId && !validation.isValidGuid(args.options.listId)) {
116
+ return `${args.options.listId} in option listId is not a valid GUID.`;
117
+ }
118
+ if (!fs.existsSync(args.options.filePath)) {
119
+ return `File with path '${args.options.filePath}' was not found.`;
120
+ }
121
+ return true;
122
+ });
123
+ }, _SpoListItemAttachmentAddCommand_initOptionSets = function _SpoListItemAttachmentAddCommand_initOptionSets() {
124
+ this.optionSets.push({ options: ['listId', 'listTitle', 'listUrl'] });
125
+ };
126
+ export default new SpoListItemAttachmentAddCommand();
127
+ //# sourceMappingURL=listitem-attachment-add.js.map
@@ -0,0 +1,97 @@
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 _SpoListItemAttachmentGetCommand_instances, _SpoListItemAttachmentGetCommand_initTelemetry, _SpoListItemAttachmentGetCommand_initOptions, _SpoListItemAttachmentGetCommand_initValidators, _SpoListItemAttachmentGetCommand_initOptionSets;
7
+ import request from '../../../../request.js';
8
+ import { formatting } from '../../../../utils/formatting.js';
9
+ import { urlUtil } from '../../../../utils/urlUtil.js';
10
+ import { validation } from '../../../../utils/validation.js';
11
+ import SpoCommand from '../../../base/SpoCommand.js';
12
+ import commands from '../../commands.js';
13
+ class SpoListItemAttachmentGetCommand extends SpoCommand {
14
+ get name() {
15
+ return commands.LISTITEM_ATTACHMENT_GET;
16
+ }
17
+ get description() {
18
+ return 'Gets an attachment from a list item';
19
+ }
20
+ constructor() {
21
+ super();
22
+ _SpoListItemAttachmentGetCommand_instances.add(this);
23
+ __classPrivateFieldGet(this, _SpoListItemAttachmentGetCommand_instances, "m", _SpoListItemAttachmentGetCommand_initTelemetry).call(this);
24
+ __classPrivateFieldGet(this, _SpoListItemAttachmentGetCommand_instances, "m", _SpoListItemAttachmentGetCommand_initOptions).call(this);
25
+ __classPrivateFieldGet(this, _SpoListItemAttachmentGetCommand_instances, "m", _SpoListItemAttachmentGetCommand_initValidators).call(this);
26
+ __classPrivateFieldGet(this, _SpoListItemAttachmentGetCommand_instances, "m", _SpoListItemAttachmentGetCommand_initOptionSets).call(this);
27
+ }
28
+ async commandAction(logger, args) {
29
+ let requestUrl = `${args.options.webUrl}/_api/web`;
30
+ if (args.options.listId) {
31
+ requestUrl += `/lists(guid'${formatting.encodeQueryParameter(args.options.listId)}')`;
32
+ }
33
+ else if (args.options.listTitle) {
34
+ requestUrl += `/lists/getByTitle('${formatting.encodeQueryParameter(args.options.listTitle)}')`;
35
+ }
36
+ else if (args.options.listUrl) {
37
+ const listServerRelativeUrl = urlUtil.getServerRelativePath(args.options.webUrl, args.options.listUrl);
38
+ requestUrl += `/GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')`;
39
+ }
40
+ const requestOptions = {
41
+ url: `${requestUrl}/items(${args.options.listItemId})/AttachmentFiles('${args.options.fileName}')`,
42
+ method: 'GET',
43
+ headers: {
44
+ 'accept': 'application/json;odata=nometadata'
45
+ },
46
+ responseType: 'json'
47
+ };
48
+ try {
49
+ const attachmentFile = await request.get(requestOptions);
50
+ await logger.log(attachmentFile);
51
+ }
52
+ catch (err) {
53
+ this.handleRejectedODataJsonPromise(err);
54
+ }
55
+ }
56
+ }
57
+ _SpoListItemAttachmentGetCommand_instances = new WeakSet(), _SpoListItemAttachmentGetCommand_initTelemetry = function _SpoListItemAttachmentGetCommand_initTelemetry() {
58
+ this.telemetry.push((args) => {
59
+ Object.assign(this.telemetryProperties, {
60
+ listId: typeof args.options.listId !== 'undefined',
61
+ listTitle: typeof args.options.listTitle !== 'undefined',
62
+ listUrl: typeof args.options.listUrl !== 'undefined'
63
+ });
64
+ });
65
+ }, _SpoListItemAttachmentGetCommand_initOptions = function _SpoListItemAttachmentGetCommand_initOptions() {
66
+ this.options.unshift({
67
+ option: '-u, --webUrl <webUrl>'
68
+ }, {
69
+ option: '--listId [listId]'
70
+ }, {
71
+ option: '--listTitle [listTitle]'
72
+ }, {
73
+ option: '--listUrl [listUrl]'
74
+ }, {
75
+ option: '--listItemId <listItemId>'
76
+ }, {
77
+ option: '-n, --fileName <fileName>'
78
+ });
79
+ }, _SpoListItemAttachmentGetCommand_initValidators = function _SpoListItemAttachmentGetCommand_initValidators() {
80
+ this.validators.push(async (args) => {
81
+ const isValidSharePointUrl = validation.isValidSharePointUrl(args.options.webUrl);
82
+ if (isValidSharePointUrl !== true) {
83
+ return isValidSharePointUrl;
84
+ }
85
+ if (args.options.listId && !validation.isValidGuid(args.options.listId)) {
86
+ return `${args.options.listId} in option listId is not a valid GUID.`;
87
+ }
88
+ if (isNaN(args.options.listItemId)) {
89
+ return `${args.options.listItemId} is not a number.`;
90
+ }
91
+ return true;
92
+ });
93
+ }, _SpoListItemAttachmentGetCommand_initOptionSets = function _SpoListItemAttachmentGetCommand_initOptionSets() {
94
+ this.optionSets.push({ options: ['listId', 'listTitle', 'listUrl'] });
95
+ };
96
+ export default new SpoListItemAttachmentGetCommand();
97
+ //# sourceMappingURL=listitem-attachment-get.js.map
@@ -0,0 +1,121 @@
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 _SpoListItemAttachmentRemoveCommand_instances, _SpoListItemAttachmentRemoveCommand_initTelemetry, _SpoListItemAttachmentRemoveCommand_initOptions, _SpoListItemAttachmentRemoveCommand_initValidators, _SpoListItemAttachmentRemoveCommand_initOptionSets;
7
+ import { Cli } from '../../../../cli/Cli.js';
8
+ import request from '../../../../request.js';
9
+ import { formatting } from '../../../../utils/formatting.js';
10
+ import { urlUtil } from '../../../../utils/urlUtil.js';
11
+ import { validation } from '../../../../utils/validation.js';
12
+ import SpoCommand from '../../../base/SpoCommand.js';
13
+ import commands from '../../commands.js';
14
+ class SpoListItemAttachmentRemoveCommand extends SpoCommand {
15
+ get name() {
16
+ return commands.LISTITEM_ATTACHMENT_REMOVE;
17
+ }
18
+ get description() {
19
+ return 'Removes an attachment from a list item';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _SpoListItemAttachmentRemoveCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _SpoListItemAttachmentRemoveCommand_instances, "m", _SpoListItemAttachmentRemoveCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _SpoListItemAttachmentRemoveCommand_instances, "m", _SpoListItemAttachmentRemoveCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _SpoListItemAttachmentRemoveCommand_instances, "m", _SpoListItemAttachmentRemoveCommand_initValidators).call(this);
27
+ __classPrivateFieldGet(this, _SpoListItemAttachmentRemoveCommand_instances, "m", _SpoListItemAttachmentRemoveCommand_initOptionSets).call(this);
28
+ }
29
+ async commandAction(logger, args) {
30
+ const removeListItemAttachment = async () => {
31
+ if (this.verbose) {
32
+ const list = (args.options.listId ? args.options.listId : args.options.listTitle ? args.options.listTitle : args.options.listUrl);
33
+ await logger.logToStderr(`Removing attachment ${args.options.fileName} of item with id ${args.options.listItemId} from list ${list} in site at ${args.options.webUrl}...`);
34
+ }
35
+ let requestUrl = `${args.options.webUrl}/_api/web`;
36
+ if (args.options.listId) {
37
+ requestUrl += `/lists(guid'${formatting.encodeQueryParameter(args.options.listId)}')`;
38
+ }
39
+ else if (args.options.listTitle) {
40
+ requestUrl += `/lists/getByTitle('${formatting.encodeQueryParameter(args.options.listTitle)}')`;
41
+ }
42
+ else if (args.options.listUrl) {
43
+ const listServerRelativeUrl = urlUtil.getServerRelativePath(args.options.webUrl, args.options.listUrl);
44
+ requestUrl += `/GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')`;
45
+ }
46
+ const requestOptions = {
47
+ url: `${requestUrl}/items(${args.options.listItemId})/AttachmentFiles('${args.options.fileName}')`,
48
+ headers: {
49
+ 'X-HTTP-Method': 'DELETE',
50
+ 'If-Match': '*',
51
+ 'accept': 'application/json;odata=nometadata'
52
+ },
53
+ responseType: 'json'
54
+ };
55
+ try {
56
+ await request.post(requestOptions);
57
+ }
58
+ catch (err) {
59
+ this.handleRejectedODataJsonPromise(err);
60
+ }
61
+ };
62
+ if (args.options.force) {
63
+ await removeListItemAttachment();
64
+ }
65
+ else {
66
+ const result = await Cli.prompt({
67
+ type: 'confirm',
68
+ name: 'continue',
69
+ default: false,
70
+ message: `Are you sure you want to remove the attachment ${args.options.fileName} of item with id ${args.options.listItemId} from the list ${args.options.listId ? args.options.listId : args.options.listTitle ? args.options.listTitle : args.options.listUrl} in site ${args.options.webUrl}?`
71
+ });
72
+ if (result.continue) {
73
+ await removeListItemAttachment();
74
+ }
75
+ }
76
+ }
77
+ }
78
+ _SpoListItemAttachmentRemoveCommand_instances = new WeakSet(), _SpoListItemAttachmentRemoveCommand_initTelemetry = function _SpoListItemAttachmentRemoveCommand_initTelemetry() {
79
+ this.telemetry.push((args) => {
80
+ Object.assign(this.telemetryProperties, {
81
+ listId: typeof args.options.listId !== 'undefined',
82
+ listTitle: typeof args.options.listTitle !== 'undefined',
83
+ listUrl: typeof args.options.listUrl !== 'undefined',
84
+ force: (!(!args.options.force)).toString()
85
+ });
86
+ });
87
+ }, _SpoListItemAttachmentRemoveCommand_initOptions = function _SpoListItemAttachmentRemoveCommand_initOptions() {
88
+ this.options.unshift({
89
+ option: '-u, --webUrl <webUrl>'
90
+ }, {
91
+ option: '--listId [listId]'
92
+ }, {
93
+ option: '--listTitle [listTitle]'
94
+ }, {
95
+ option: '--listUrl [listUrl]'
96
+ }, {
97
+ option: '--listItemId <listItemId>'
98
+ }, {
99
+ option: '-n, --fileName <fileName>'
100
+ }, {
101
+ option: '-f, --force'
102
+ });
103
+ }, _SpoListItemAttachmentRemoveCommand_initValidators = function _SpoListItemAttachmentRemoveCommand_initValidators() {
104
+ this.validators.push(async (args) => {
105
+ const isValidSharePointUrl = validation.isValidSharePointUrl(args.options.webUrl);
106
+ if (isValidSharePointUrl !== true) {
107
+ return isValidSharePointUrl;
108
+ }
109
+ if (args.options.listId && !validation.isValidGuid(args.options.listId)) {
110
+ return `${args.options.listId} in option listId is not a valid GUID`;
111
+ }
112
+ if (isNaN(args.options.listItemId)) {
113
+ return `${args.options.listItemId} is not a number`;
114
+ }
115
+ return true;
116
+ });
117
+ }, _SpoListItemAttachmentRemoveCommand_initOptionSets = function _SpoListItemAttachmentRemoveCommand_initOptionSets() {
118
+ this.optionSets.push({ options: ['listId', 'listTitle', 'listUrl'] });
119
+ };
120
+ export default new SpoListItemAttachmentRemoveCommand();
121
+ //# sourceMappingURL=listitem-attachment-remove.js.map
@@ -0,0 +1,115 @@
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 _SpoListItemAttachmentSetCommand_instances, _SpoListItemAttachmentSetCommand_initTelemetry, _SpoListItemAttachmentSetCommand_initOptions, _SpoListItemAttachmentSetCommand_initValidators, _SpoListItemAttachmentSetCommand_initOptionSets;
7
+ import request from '../../../../request.js';
8
+ import { formatting } from '../../../../utils/formatting.js';
9
+ import { urlUtil } from '../../../../utils/urlUtil.js';
10
+ import { validation } from '../../../../utils/validation.js';
11
+ import SpoCommand from '../../../base/SpoCommand.js';
12
+ import commands from '../../commands.js';
13
+ import fs from 'fs';
14
+ class SpoListItemAttachmentSetCommand extends SpoCommand {
15
+ get name() {
16
+ return commands.LISTITEM_ATTACHMENT_SET;
17
+ }
18
+ get description() {
19
+ return 'Updates an attachment from a list item';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _SpoListItemAttachmentSetCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _SpoListItemAttachmentSetCommand_instances, "m", _SpoListItemAttachmentSetCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _SpoListItemAttachmentSetCommand_instances, "m", _SpoListItemAttachmentSetCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _SpoListItemAttachmentSetCommand_instances, "m", _SpoListItemAttachmentSetCommand_initValidators).call(this);
27
+ __classPrivateFieldGet(this, _SpoListItemAttachmentSetCommand_instances, "m", _SpoListItemAttachmentSetCommand_initOptionSets).call(this);
28
+ }
29
+ async commandAction(logger, args) {
30
+ if (this.verbose) {
31
+ await logger.logToStderr(`Updating attachment ${args.options.fileName} at path ${args.options.filePath} for list item with id ${args.options.listItemId} on list ${args.options.listId || args.options.listTitle || args.options.listUrl} on web ${args.options.webUrl}.`);
32
+ }
33
+ try {
34
+ const fileName = this.getFileName(args.options.filePath, args.options.fileName);
35
+ const fileBody = fs.readFileSync(args.options.filePath);
36
+ const requestOptions = {
37
+ url: `${args.options.webUrl}/_api/web/${this.getListUrl(args.options.webUrl, args.options.listId, args.options.listTitle, args.options.listUrl)}/items(${args.options.listItemId})/AttachmentFiles('${fileName}')/$value`,
38
+ headers: {
39
+ 'accept': 'application/json;odata=nometadata'
40
+ },
41
+ data: fileBody,
42
+ responseType: 'json'
43
+ };
44
+ await request.put(requestOptions);
45
+ }
46
+ catch (err) {
47
+ this.handleRejectedODataJsonPromise(err);
48
+ }
49
+ }
50
+ getFileName(filePath, fileName) {
51
+ const extension = filePath.split('.').pop();
52
+ if (!fileName.endsWith(`.${extension}`)) {
53
+ fileName += `.${extension}`;
54
+ }
55
+ return fileName;
56
+ }
57
+ getListUrl(webUrl, listId, listTitle, listUrl) {
58
+ if (listId) {
59
+ return `lists(guid'${formatting.encodeQueryParameter(listId)}')`;
60
+ }
61
+ else if (listTitle) {
62
+ return `lists/getByTitle('${formatting.encodeQueryParameter(listTitle)}')`;
63
+ }
64
+ else {
65
+ const listServerRelativeUrl = urlUtil.getServerRelativePath(webUrl, listUrl);
66
+ return `GetList('${formatting.encodeQueryParameter(listServerRelativeUrl)}')`;
67
+ }
68
+ }
69
+ }
70
+ _SpoListItemAttachmentSetCommand_instances = new WeakSet(), _SpoListItemAttachmentSetCommand_initTelemetry = function _SpoListItemAttachmentSetCommand_initTelemetry() {
71
+ this.telemetry.push((args) => {
72
+ Object.assign(this.telemetryProperties, {
73
+ listId: typeof args.options.listId !== 'undefined',
74
+ listTitle: typeof args.options.listTitle !== 'undefined',
75
+ listUrl: typeof args.options.listUrl !== 'undefined'
76
+ });
77
+ });
78
+ }, _SpoListItemAttachmentSetCommand_initOptions = function _SpoListItemAttachmentSetCommand_initOptions() {
79
+ this.options.unshift({
80
+ option: '-u, --webUrl <webUrl>'
81
+ }, {
82
+ option: '--listId [listId]'
83
+ }, {
84
+ option: '--listTitle [listTitle]'
85
+ }, {
86
+ option: '--listUrl [listUrl]'
87
+ }, {
88
+ option: '--listItemId <listItemId>'
89
+ }, {
90
+ option: '-p, --filePath <filePath>'
91
+ }, {
92
+ option: '-n, --fileName <fileName>'
93
+ });
94
+ }, _SpoListItemAttachmentSetCommand_initValidators = function _SpoListItemAttachmentSetCommand_initValidators() {
95
+ this.validators.push(async (args) => {
96
+ const isValidSharePointUrl = validation.isValidSharePointUrl(args.options.webUrl);
97
+ if (isValidSharePointUrl !== true) {
98
+ return isValidSharePointUrl;
99
+ }
100
+ if (isNaN(args.options.listItemId)) {
101
+ return `${args.options.listItemId} in option listItemId is not a valid number.`;
102
+ }
103
+ if (args.options.listId && !validation.isValidGuid(args.options.listId)) {
104
+ return `${args.options.listId} in option listId is not a valid GUID.`;
105
+ }
106
+ if (!fs.existsSync(args.options.filePath)) {
107
+ return `File with path '${args.options.filePath}' was not found.`;
108
+ }
109
+ return true;
110
+ });
111
+ }, _SpoListItemAttachmentSetCommand_initOptionSets = function _SpoListItemAttachmentSetCommand_initOptionSets() {
112
+ this.optionSets.push({ options: ['listId', 'listTitle', 'listUrl'] });
113
+ };
114
+ export default new SpoListItemAttachmentSetCommand();
115
+ //# sourceMappingURL=listitem-attachment-set.js.map
@@ -156,7 +156,11 @@ export default {
156
156
  LIST_WEBHOOK_REMOVE: `${prefix} list webhook remove`,
157
157
  LIST_WEBHOOK_SET: `${prefix} list webhook set`,
158
158
  LISTITEM_ADD: `${prefix} listitem add`,
159
+ LISTITEM_ATTACHMENT_ADD: `${prefix} listitem attachment add`,
160
+ LISTITEM_ATTACHMENT_GET: `${prefix} listitem attachment get`,
159
161
  LISTITEM_ATTACHMENT_LIST: `${prefix} listitem attachment list`,
162
+ LISTITEM_ATTACHMENT_REMOVE: `${prefix} listitem attachment remove`,
163
+ LISTITEM_ATTACHMENT_SET: `${prefix} listitem attachment set`,
160
164
  LISTITEM_BATCH_ADD: `${prefix} listitem batch add`,
161
165
  LISTITEM_BATCH_SET: `${prefix} listitem batch set`,
162
166
  LISTITEM_GET: `${prefix} listitem get`,
@@ -75,6 +75,22 @@ export const aadGroup = {
75
75
  data: update
76
76
  };
77
77
  await request.patch(requestOptions);
78
+ },
79
+ /**
80
+ * Checks if group is a m365 group.
81
+ * @param groupId Group id.
82
+ * @returns whether the group is a m365 group or not
83
+ */
84
+ async isUnifiedGroup(groupId) {
85
+ const requestOptions = {
86
+ url: `${graphResource}/v1.0/groups/${groupId}?$select=groupTypes`,
87
+ headers: {
88
+ accept: 'application/json;odata.metadata=none'
89
+ },
90
+ responseType: 'json'
91
+ };
92
+ const group = await request.get(requestOptions);
93
+ return group.groupTypes.some(type => type === 'Unified');
78
94
  }
79
95
  };
80
96
  //# sourceMappingURL=aadGroup.js.map
@@ -0,0 +1,110 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # spo listitem attachment add
6
+
7
+ Adds an attachment to a list item
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 spo listitem attachment add [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-u, --webUrl <webUrl>`
19
+ : URL of the site where the list item is located.
20
+
21
+ `--listId [listId]`
22
+ : ID of the list. Specify either `listTitle`, `listId` or `listUrl`.
23
+
24
+ `--listTitle [listTitle]`
25
+ : Title of the list. Specify either `listTitle`, `listId` or `listUrl`.
26
+
27
+ `--listUrl [listUrl]`
28
+ : Server- or site-relative URL of the list. Specify either `listTitle`, `listId` or `listUrl`.
29
+
30
+ `--listItemId <listItemId>`
31
+ : The ID of the list item.
32
+
33
+ `-p, --filePath <filePath>`
34
+ : Local path to the file that will be added as an attachment to the list item.
35
+
36
+ `-n, --fileName [fileName]`
37
+ : Name for the file. If no name is provided, the name from `filePath` will be utilized.
38
+ ```
39
+
40
+ <Global />
41
+
42
+ ## Examples
43
+
44
+ Add a new attachment to a list item from a local file by using list title
45
+
46
+ ```sh
47
+ m365 spo listitem attachment add --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle "DemoList" --listItemId 147 --filePath "C:/Reports/File1.jpg"
48
+ ```
49
+
50
+ Add a new attachment to a list item from a local file by using list URL with a different filename
51
+
52
+ ```sh
53
+ m365 spo listitem attachment add --webUrl https://contoso.sharepoint.com/sites/project-x --listUrl "/sites/project-x/Lists/DemoList" --listItemId 147 --filePath "C:/Reports/File1.jpg" --fileName "File2"
54
+ ```
55
+
56
+ ## Response
57
+
58
+ <Tabs>
59
+ <TabItem value="JSON">
60
+
61
+ ```json
62
+ [
63
+ {
64
+ "FileName": "File1.jpg",
65
+ "FileNameAsPath": {
66
+ "DecodedUrl": "File1.jpg"
67
+ },
68
+ "ServerRelativePath": {
69
+ "DecodedUrl": "/Lists/DemoList/Attachments/147/File1.jpg"
70
+ },
71
+ "ServerRelativeUrl": "/Lists/Test/Attachments/147/File1.jpg"
72
+ }
73
+ ]
74
+ ```
75
+
76
+ </TabItem>
77
+ <TabItem value="Text">
78
+
79
+ ```text
80
+ FileName : File1.jpg
81
+ FileNameAsPath : {"DecodedUrl":"File1jpg"}
82
+ ServerRelativePath: {"DecodedUrl":"/Lists/DemoList/Attachments/743/File1.jpg"}
83
+ ServerRelativeUrl : /Lists/DemoList/Attachments/147/File1.jpg
84
+ ```
85
+
86
+ </TabItem>
87
+ <TabItem value="CSV">
88
+
89
+ ```csv
90
+ FileName,ServerRelativeUrl
91
+ File1.jpg,/Lists/DemoList/Attachments/147/File1.jpg
92
+ ```
93
+
94
+ </TabItem>
95
+ <TabItem value="Markdown">
96
+
97
+ ```md
98
+ # spo listitem attachment add --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle "DemoList" --listItemId 147 --filePath "C:/Reports/File1.jpg"
99
+
100
+ Date: 25/07/2023
101
+
102
+ Property | Value
103
+ ---------|-------
104
+ FileName | File1.jpg
105
+ ServerRelativeUrl | /Lists/DemoList/Attachments/147/File1.jpg
106
+ ```
107
+
108
+ </TabItem>
109
+ </Tabs>
110
+
@@ -0,0 +1,104 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # spo listitem attachment get
6
+
7
+ Gets an attachment from a list item
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 spo listitem attachment get [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-u, --webUrl <webUrl>`
19
+ : URL of the site where the list item is located.
20
+
21
+ `--listId [listId]`
22
+ : ID of the list. Specify either `listTitle`, `listId` or `listUrl`.
23
+
24
+ `--listTitle [listTitle]`
25
+ : Title of the list. Specify either `listTitle`, `listId` or `listUrl`.
26
+
27
+ `--listUrl [listUrl]`
28
+ : Server- or site-relative URL of the list. Specify either `listTitle`, `listId` or `listUrl`.
29
+
30
+ `--listItemId <listItemId>`
31
+ : The ID of the list item.
32
+
33
+ `-n, --fileName <fileName>`
34
+ : Name of the file to get.
35
+ ```
36
+
37
+ <Global />
38
+
39
+ ## Examples
40
+
41
+ Get an attachment from a list item by using list title.
42
+
43
+ ```sh
44
+ m365 spo listitem attachment get --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle "Demo List" --listItemId 147 --fileName "File1.jpg"
45
+ ```
46
+
47
+ Get an attachment from a list item by using list URL.
48
+
49
+ ```sh
50
+ m365 spo listitem attachment get --webUrl https://contoso.sharepoint.com/sites/project-x --listUrl "/sites/project-x/Lists/DemoList" --listItemId 147 --fileName "File1.jpg"
51
+ ```
52
+
53
+ ## Response
54
+
55
+ <Tabs>
56
+ <TabItem value="JSON">
57
+
58
+ ```json
59
+ {
60
+ "FileName": "File1.jpg",
61
+ "FileNameAsPath": {
62
+ "DecodedUrl": "File1.jpg"
63
+ },
64
+ "ServerRelativePath": {
65
+ "DecodedUrl": "/sites/project-x/Lists/DemoListAttachments/147/File1.jpg"
66
+ },
67
+ "ServerRelativeUrl": "/sites/project-x/Lists/DemoListAttachments/147/File1.jpg"
68
+ }
69
+ ```
70
+
71
+ </TabItem>
72
+ <TabItem value="Text">
73
+
74
+ ```text
75
+ FileName : File1.jpg
76
+ FileNameAsPath : {"DecodedUrl":"File1.jpg"}
77
+ ServerRelativePath: {"DecodedUrl":"/sites/project-x/Lists/DemoListAttachments/147/File1.jpg"}
78
+ ServerRelativeUrl : /sites/project-x/Lists/DemoListAttachments/147/File1.jpg
79
+ ```
80
+
81
+ </TabItem>
82
+ <TabItem value="CSV">
83
+
84
+ ```csv
85
+ FileName,ServerRelativeUrl
86
+ File1.jpg,/sites/project-x/Lists/DemoListAttachments/147/File1.jpg
87
+ ```
88
+
89
+ </TabItem>
90
+ <TabItem value="Markdown">
91
+
92
+ ```md
93
+ # spo listitem attachment get --webUrl "https://contoso.sharepoint.com/sites/project-x" --listTitle "PnP PowerShell List" --listItemId "1" --fileName "File1.jpg"
94
+
95
+ Date: 7/20/2023
96
+
97
+ Property | Value
98
+ ---------|-------
99
+ FileName | File1.jpg
100
+ ServerRelativeUrl | /sites/project-x/Lists/DemoListAttachments/147/File1.jpg
101
+ ```
102
+
103
+ </TabItem>
104
+ </Tabs>
@@ -0,0 +1,58 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # spo listitem attachment remove
6
+
7
+ Removes an attachment from a list item
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 spo listitem attachment remove [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-u, --webUrl <webUrl>`
19
+ : URL of the site where the list item is located.
20
+
21
+ `--listId [listId]`
22
+ : ID of the list. Specify either `listTitle`, `listId` or `listUrl`.
23
+
24
+ `--listTitle [listTitle]`
25
+ : Title of the list. Specify either `listTitle`, `listId` or `listUrl`.
26
+
27
+ `--listUrl [listUrl]`
28
+ : Server- or site-relative URL of the list. Specify either `listTitle`, `listId` or `listUrl`.
29
+
30
+ `--listItemId <listItemId>`
31
+ : The ID of the list item.
32
+
33
+ `-n, --fileName <fileName>`
34
+ : Name of the file to remove.
35
+
36
+ `-f, --force`
37
+ : Don't prompt for confirmation.
38
+ ```
39
+
40
+ <Global />
41
+
42
+ ## Examples
43
+
44
+ Remove an attachment from a list item using list tile.
45
+
46
+ ```sh
47
+ m365 spo listitem attachment remove --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle "Demo List" --listItemId 147 --fileName "File1.jpg"
48
+ ```
49
+
50
+ Remove an attachment from a list item using list URL.
51
+
52
+ ```sh
53
+ m365 spo listitem attachment remove --webUrl https://contoso.sharepoint.com/sites/project-x --listUrl "/sites/project-x/Lists/DemoList" --listItemId 147 --fileName "File1.jpg"
54
+ ```
55
+
56
+ ## Response
57
+
58
+ The command won't return a response on success.
@@ -0,0 +1,58 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+ import Tabs from '@theme/Tabs';
3
+ import TabItem from '@theme/TabItem';
4
+
5
+ # spo listitem attachment set
6
+
7
+ Updates an attachment from a list item
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ m365 spo listitem attachment set [options]
13
+ ```
14
+
15
+ ## Options
16
+
17
+ ```md definition-list
18
+ `-u, --webUrl <webUrl>`
19
+ : URL of the site where the list item is located.
20
+
21
+ `--listId [listId]`
22
+ : ID of the list. Specify either `listTitle`, `listId` or `listUrl`.
23
+
24
+ `--listTitle [listTitle]`
25
+ : Title of the list. Specify either `listTitle`, `listId` or `listUrl`.
26
+
27
+ `--listUrl [listUrl]`
28
+ : Server- or site-relative URL of the list. Specify either `listTitle`, `listId` or `listUrl`.
29
+
30
+ `--listItemId <listItemId>`
31
+ : The ID of the list item.
32
+
33
+ `-p, --filePath <filePath>`
34
+ : Local path used for updating the attachment contents.
35
+
36
+ `-n, --fileName <fileName>`
37
+ : Name of the file to update.
38
+ ```
39
+
40
+ <Global />
41
+
42
+ ## Examples
43
+
44
+ Update an attachment from a list item by using list title
45
+
46
+ ```sh
47
+ m365 spo listitem attachment set --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle "Demo List" --listItemId 147 --fileName "File1.jpg" --filePath "C:/Reports/File2.jpg"
48
+ ```
49
+
50
+ Update an attachment from a list item by using list URL
51
+
52
+ ```sh
53
+ m365 spo listitem attachment set --webUrl https://contoso.sharepoint.com/sites/project-x --listUrl "/sites/project-x/Lists/DemoList" --listItemId 147 --fileName "File1.jpg" --filePath "C:/Reports/File2.jpg"
54
+ ```
55
+
56
+ ## Response
57
+
58
+ The command won't return a response on success.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnp/cli-microsoft365",
3
- "version": "7.0.0-beta.8726fe8",
3
+ "version": "7.0.0-beta.88c4694",
4
4
  "description": "Manage Microsoft 365 and SharePoint Framework projects on any platform",
5
5
  "license": "MIT",
6
6
  "main": "./dist/api.js",