@pnp/cli-microsoft365 12.0.0-beta.1752794 → 12.0.0-beta.47b768f

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.
Files changed (52) hide show
  1. package/allCommands.json +1 -1
  2. package/allCommandsFull.json +1 -1
  3. package/dist/Auth.js +15 -1
  4. package/dist/m365/spfx/commands/SpfxCompatibilityMatrix.js +15 -0
  5. package/dist/m365/spfx/commands/project/project-doctor/doctor-1.24.0-rc.0.js +19 -0
  6. package/dist/m365/spfx/commands/project/project-doctor.js +2 -1
  7. package/dist/m365/spfx/commands/project/project-upgrade/rules/FN012021_TSC_excludeDirectories.js +43 -0
  8. package/dist/m365/spfx/commands/project/project-upgrade/rules/FN027002_OVERRIDES_qs.js +33 -0
  9. package/dist/m365/spfx/commands/project/project-upgrade/rules/FN027003_OVERRIDES_uuid.js +33 -0
  10. package/dist/m365/spfx/commands/project/project-upgrade/upgrade-1.24.0-rc.0.js +77 -0
  11. package/dist/m365/spfx/commands/project/project-upgrade.js +12 -11
  12. package/dist/m365/spo/commands/commandset/commandset-add.js +17 -59
  13. package/dist/m365/spo/commands/commandset/commandset-get.js +24 -62
  14. package/dist/m365/spo/commands/commandset/commandset-list.js +11 -34
  15. package/dist/m365/spo/commands/commandset/commandset-remove.js +21 -54
  16. package/dist/m365/spo/commands/commandset/commandset-set.js +30 -83
  17. package/dist/m365/spo/commands/navigation/navigation-node-add.js +74 -120
  18. package/dist/m365/spo/commands/navigation/navigation-node-get.js +4 -13
  19. package/dist/m365/spo/commands/navigation/navigation-node-set.js +53 -114
  20. package/dist/m365/spo/commands/page/page-unpublish.js +53 -0
  21. package/dist/m365/spo/commands/sitescript/sitescript-add.js +22 -37
  22. package/dist/m365/spo/commands/sitescript/sitescript-get.js +9 -26
  23. package/dist/m365/spo/commands/sitescript/sitescript-list.js +5 -0
  24. package/dist/m365/spo/commands/sitescript/sitescript-remove.js +9 -33
  25. package/dist/m365/spo/commands/sitescript/sitescript-set.js +29 -56
  26. package/dist/m365/spo/commands.js +1 -0
  27. package/dist/m365/spp/commands/contentcenter/contentcenter-list.js +5 -0
  28. package/dist/m365/spp/commands/model/model-get.js +25 -45
  29. package/dist/m365/spp/commands/model/model-list.js +12 -23
  30. package/dist/m365/spp/commands/model/model-remove.js +25 -45
  31. package/dist/m365/teams/commands/meeting/meeting-add.js +57 -68
  32. package/dist/m365/teams/commands/meeting/meeting-attendancereport-get.js +33 -58
  33. package/dist/m365/teams/commands/meeting/meeting-attendancereport-list.js +14 -38
  34. package/dist/m365/teams/commands/meeting/meeting-get.js +14 -38
  35. package/dist/m365/teams/commands/meeting/meeting-list.js +34 -59
  36. package/dist/m365/teams/commands/meeting/meeting-transcript-get.js +34 -58
  37. package/dist/m365/teams/commands/meeting/meeting-transcript-list.js +29 -50
  38. package/dist/utils/spo.js +39 -0
  39. package/docs/docs/cmd/login.mdx +15 -2
  40. package/docs/docs/cmd/spo/navigation/navigation-node-add.mdx +45 -30
  41. package/docs/docs/cmd/spo/navigation/navigation-node-get.mdx +64 -42
  42. package/docs/docs/cmd/spo/navigation/navigation-node-set.mdx +10 -8
  43. package/docs/docs/cmd/spo/page/page-unpublish.mdx +63 -0
  44. package/docs/docs/cmd/teams/tab/tab-add.mdx +19 -0
  45. package/docs/docs/cmd/teams/tab/tab-get.mdx +19 -0
  46. package/docs/docs/cmd/teams/tab/tab-list.mdx +19 -0
  47. package/docs/docs/cmd/teams/tab/tab-remove.mdx +21 -0
  48. package/docs/docs/cmd/viva/engage/engage-message-add.mdx +17 -0
  49. package/docs/docs/cmd/viva/engage/engage-message-get.mdx +17 -0
  50. package/docs/docs/cmd/viva/engage/engage-message-list.mdx +17 -0
  51. package/docs/docs/cmd/viva/engage/engage-message-remove.mdx +19 -0
  52. package/package.json +4 -6
@@ -1,10 +1,6 @@
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 _TeamsMeetingGetCommand_instances, _TeamsMeetingGetCommand_initTelemetry, _TeamsMeetingGetCommand_initOptions, _TeamsMeetingGetCommand_initValidators;
7
1
  import auth from '../../../../Auth.js';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { z } from 'zod';
8
4
  import request from '../../../../request.js';
9
5
  import { entraUser } from '../../../../utils/entraUser.js';
10
6
  import { accessToken } from '../../../../utils/accessToken.js';
@@ -12,6 +8,16 @@ import { formatting } from '../../../../utils/formatting.js';
12
8
  import { validation } from '../../../../utils/validation.js';
13
9
  import GraphCommand from "../../../base/GraphCommand.js";
14
10
  import commands from '../../commands.js';
11
+ export const options = z.strictObject({
12
+ ...globalOptionsZod.shape,
13
+ userId: z.string()
14
+ .refine(value => validation.isValidGuid(value), {
15
+ message: 'The userId value must be a valid GUID.'
16
+ }).optional().alias('u'),
17
+ userName: z.string().optional().alias('n'),
18
+ email: z.string().optional(),
19
+ joinUrl: z.string().alias('j')
20
+ });
15
21
  class TeamsMeetingGetCommand extends GraphCommand {
16
22
  get name() {
17
23
  return commands.MEETING_GET;
@@ -19,12 +25,8 @@ class TeamsMeetingGetCommand extends GraphCommand {
19
25
  get description() {
20
26
  return 'Gets specified meeting details';
21
27
  }
22
- constructor() {
23
- super();
24
- _TeamsMeetingGetCommand_instances.add(this);
25
- __classPrivateFieldGet(this, _TeamsMeetingGetCommand_instances, "m", _TeamsMeetingGetCommand_initTelemetry).call(this);
26
- __classPrivateFieldGet(this, _TeamsMeetingGetCommand_instances, "m", _TeamsMeetingGetCommand_initOptions).call(this);
27
- __classPrivateFieldGet(this, _TeamsMeetingGetCommand_instances, "m", _TeamsMeetingGetCommand_initValidators).call(this);
28
+ get schema() {
29
+ return options;
28
30
  }
29
31
  async commandAction(logger, args) {
30
32
  const isAppOnlyAccessToken = accessToken.isAppOnlyAccessToken(auth.connection.accessTokens[this.resource].accessToken);
@@ -81,31 +83,5 @@ class TeamsMeetingGetCommand extends GraphCommand {
81
83
  return entraUser.getUserIdByEmail(options.email);
82
84
  }
83
85
  }
84
- _TeamsMeetingGetCommand_instances = new WeakSet(), _TeamsMeetingGetCommand_initTelemetry = function _TeamsMeetingGetCommand_initTelemetry() {
85
- this.telemetry.push((args) => {
86
- Object.assign(this.telemetryProperties, {
87
- userId: typeof args.options.userId !== 'undefined',
88
- userName: typeof args.options.userName !== 'undefined',
89
- email: typeof args.options.email !== 'undefined'
90
- });
91
- });
92
- }, _TeamsMeetingGetCommand_initOptions = function _TeamsMeetingGetCommand_initOptions() {
93
- this.options.unshift({
94
- option: '-u, --userId [userId]'
95
- }, {
96
- option: '-n, --userName [userName]'
97
- }, {
98
- option: '--email [email]'
99
- }, {
100
- option: '-j, --joinUrl <joinUrl>'
101
- });
102
- }, _TeamsMeetingGetCommand_initValidators = function _TeamsMeetingGetCommand_initValidators() {
103
- this.validators.push(async (args) => {
104
- if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
105
- return `${args.options.userId} is not a valid Guid`;
106
- }
107
- return true;
108
- });
109
- };
110
86
  export default new TeamsMeetingGetCommand();
111
87
  //# sourceMappingURL=meeting-get.js.map
@@ -1,10 +1,6 @@
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 _TeamsMeetingListCommand_instances, _TeamsMeetingListCommand_initTelemetry, _TeamsMeetingListCommand_initOptions, _TeamsMeetingListCommand_initValidators;
7
1
  import auth from '../../../../Auth.js';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { z } from 'zod';
8
4
  import { entraUser } from '../../../../utils/entraUser.js';
9
5
  import { accessToken } from '../../../../utils/accessToken.js';
10
6
  import { odata } from '../../../../utils/odata.js';
@@ -13,6 +9,30 @@ import GraphCommand from "../../../base/GraphCommand.js";
13
9
  import commands from '../../commands.js';
14
10
  import request from '../../../../request.js';
15
11
  import { formatting } from '../../../../utils/formatting.js';
12
+ export const options = z.strictObject({
13
+ ...globalOptionsZod.shape,
14
+ userId: z.string()
15
+ .refine(value => validation.isValidGuid(value), {
16
+ message: 'The userId value must be a valid GUID.'
17
+ }).optional().alias('u'),
18
+ userName: z.string()
19
+ .refine(value => validation.isValidUserPrincipalName(value), {
20
+ message: 'The userName value must be a valid user principal name (UPN).'
21
+ }).optional().alias('n'),
22
+ email: z.string()
23
+ .refine(value => validation.isValidUserPrincipalName(value), {
24
+ message: 'The email value must be a valid email.'
25
+ }).optional(),
26
+ startDateTime: z.string()
27
+ .refine(value => validation.isValidISODateTime(value), {
28
+ error: issue => `'${issue.input}' is not a valid ISO date string for startDateTime.`
29
+ }),
30
+ endDateTime: z.string()
31
+ .refine(value => validation.isValidISODateTime(value), {
32
+ error: issue => `'${issue.input}' is not a valid ISO date string for endDateTime.`
33
+ }).optional(),
34
+ isOrganizer: z.boolean().optional()
35
+ });
16
36
  class TeamsMeetingListCommand extends GraphCommand {
17
37
  get name() {
18
38
  return commands.MEETING_LIST;
@@ -23,12 +43,14 @@ class TeamsMeetingListCommand extends GraphCommand {
23
43
  defaultProperties() {
24
44
  return ['subject', 'startDateTime', 'endDateTime'];
25
45
  }
26
- constructor() {
27
- super();
28
- _TeamsMeetingListCommand_instances.add(this);
29
- __classPrivateFieldGet(this, _TeamsMeetingListCommand_instances, "m", _TeamsMeetingListCommand_initTelemetry).call(this);
30
- __classPrivateFieldGet(this, _TeamsMeetingListCommand_instances, "m", _TeamsMeetingListCommand_initOptions).call(this);
31
- __classPrivateFieldGet(this, _TeamsMeetingListCommand_instances, "m", _TeamsMeetingListCommand_initValidators).call(this);
46
+ get schema() {
47
+ return options;
48
+ }
49
+ getRefinedSchema(schema) {
50
+ return schema.refine(options => !options.endDateTime || options.startDateTime <= options.endDateTime, {
51
+ message: 'startDateTime value must be before endDateTime.',
52
+ path: ['startDateTime']
53
+ });
32
54
  }
33
55
  async commandAction(logger, args) {
34
56
  try {
@@ -127,52 +149,5 @@ class TeamsMeetingListCommand extends GraphCommand {
127
149
  return result;
128
150
  }
129
151
  }
130
- _TeamsMeetingListCommand_instances = new WeakSet(), _TeamsMeetingListCommand_initTelemetry = function _TeamsMeetingListCommand_initTelemetry() {
131
- this.telemetry.push((args) => {
132
- Object.assign(this.telemetryProperties, {
133
- userId: typeof args.options.userId !== 'undefined',
134
- userName: typeof args.options.userName !== 'undefined',
135
- email: typeof args.options.email !== 'undefined',
136
- endDateTime: typeof args.options.endDateTime !== 'undefined',
137
- isOrganizer: !!args.options.isOrganizer
138
- });
139
- });
140
- }, _TeamsMeetingListCommand_initOptions = function _TeamsMeetingListCommand_initOptions() {
141
- this.options.unshift({
142
- option: '-u, --userId [userId]'
143
- }, {
144
- option: '-n, --userName [userName]'
145
- }, {
146
- option: '--email [email]'
147
- }, {
148
- option: '--startDateTime <startDateTime>'
149
- }, {
150
- option: '--endDateTime [endDateTime]'
151
- }, {
152
- option: '--isOrganizer'
153
- });
154
- }, _TeamsMeetingListCommand_initValidators = function _TeamsMeetingListCommand_initValidators() {
155
- this.validators.push(async (args) => {
156
- if (!validation.isValidISODateTime(args.options.startDateTime)) {
157
- return `'${args.options.startDateTime}' is not a valid ISO date string for startDateTime.`;
158
- }
159
- if (args.options.endDateTime && !validation.isValidISODateTime(args.options.endDateTime)) {
160
- return `'${args.options.startDateTime}' is not a valid ISO date string for endDateTime.`;
161
- }
162
- if (args.options.startDateTime && args.options.endDateTime && args.options.startDateTime > args.options.endDateTime) {
163
- return 'startDateTime value must be before endDateTime.';
164
- }
165
- if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
166
- return `${args.options.userId} is not a valid GUID for userId.`;
167
- }
168
- if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) {
169
- return `'${args.options.userName}' is not a valid UPN for userName.`;
170
- }
171
- if (args.options.email && !validation.isValidUserPrincipalName(args.options.email)) {
172
- return `'${args.options.email}' is not a valid UPN for email.`;
173
- }
174
- return true;
175
- });
176
- };
177
152
  export default new TeamsMeetingListCommand();
178
153
  //# sourceMappingURL=meeting-list.js.map
@@ -1,10 +1,6 @@
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 _TeamsMeetingTranscriptGetCommand_instances, _TeamsMeetingTranscriptGetCommand_initTelemetry, _TeamsMeetingTranscriptGetCommand_initOptions, _TeamsMeetingTranscriptGetCommand_initValidators, _TeamsMeetingTranscriptGetCommand_initOptionSets;
7
1
  import auth from '../../../../Auth.js';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { z } from 'zod';
8
4
  import request from '../../../../request.js';
9
5
  import { entraUser } from '../../../../utils/entraUser.js';
10
6
  import { accessToken } from '../../../../utils/accessToken.js';
@@ -13,6 +9,27 @@ import GraphCommand from '../../../base/GraphCommand.js';
13
9
  import commands from '../../commands.js';
14
10
  import fs from 'fs';
15
11
  import path from 'path';
12
+ export const options = z.strictObject({
13
+ ...globalOptionsZod.shape,
14
+ userId: z.string()
15
+ .refine(value => validation.isValidGuid(value), {
16
+ message: 'The userId value must be a valid GUID.'
17
+ }).optional().alias('u'),
18
+ userName: z.string()
19
+ .refine(value => validation.isValidUserPrincipalName(value), {
20
+ message: 'The userName value must be a valid user principal name (UPN).'
21
+ }).optional().alias('n'),
22
+ email: z.string()
23
+ .refine(value => validation.isValidUserPrincipalName(value), {
24
+ message: 'The email value must be a valid email.'
25
+ }).optional(),
26
+ meetingId: z.string().alias('m'),
27
+ id: z.string().alias('i'),
28
+ outputFile: z.string()
29
+ .refine(value => fs.existsSync(path.dirname(value)), {
30
+ message: 'Specified path where to save the file does not exist.'
31
+ }).optional().alias('f')
32
+ });
16
33
  class TeamsMeetingTranscriptGetCommand extends GraphCommand {
17
34
  get name() {
18
35
  return commands.MEETING_TRANSCRIPT_GET;
@@ -20,13 +37,17 @@ class TeamsMeetingTranscriptGetCommand extends GraphCommand {
20
37
  get description() {
21
38
  return 'Downloads a transcript for a given meeting';
22
39
  }
23
- constructor() {
24
- super();
25
- _TeamsMeetingTranscriptGetCommand_instances.add(this);
26
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptGetCommand_instances, "m", _TeamsMeetingTranscriptGetCommand_initTelemetry).call(this);
27
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptGetCommand_instances, "m", _TeamsMeetingTranscriptGetCommand_initOptions).call(this);
28
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptGetCommand_instances, "m", _TeamsMeetingTranscriptGetCommand_initValidators).call(this);
29
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptGetCommand_instances, "m", _TeamsMeetingTranscriptGetCommand_initOptionSets).call(this);
40
+ get schema() {
41
+ return options;
42
+ }
43
+ getRefinedSchema(schema) {
44
+ return schema.refine(options => [options.userId, options.userName, options.email].filter(value => value !== undefined).length <= 1, {
45
+ message: 'Specify either userId, userName or email, but not multiple.',
46
+ params: {
47
+ customCode: 'optionSet',
48
+ options: ['userId', 'userName', 'email']
49
+ }
50
+ });
30
51
  }
31
52
  async commandAction(logger, args) {
32
53
  try {
@@ -103,50 +124,5 @@ class TeamsMeetingTranscriptGetCommand extends GraphCommand {
103
124
  }
104
125
  }
105
126
  }
106
- _TeamsMeetingTranscriptGetCommand_instances = new WeakSet(), _TeamsMeetingTranscriptGetCommand_initTelemetry = function _TeamsMeetingTranscriptGetCommand_initTelemetry() {
107
- this.telemetry.push((args) => {
108
- Object.assign(this.telemetryProperties, {
109
- userId: typeof args.options.userId !== 'undefined',
110
- userName: typeof args.options.userName !== 'undefined',
111
- email: typeof args.options.email !== 'undefined',
112
- outputFile: typeof args.options.outputFile !== 'undefined'
113
- });
114
- });
115
- }, _TeamsMeetingTranscriptGetCommand_initOptions = function _TeamsMeetingTranscriptGetCommand_initOptions() {
116
- this.options.unshift({
117
- option: '-u, --userId [userId]'
118
- }, {
119
- option: '-n, --userName [userName]'
120
- }, {
121
- option: '--email [email]'
122
- }, {
123
- option: '-m, --meetingId <meetingId>'
124
- }, {
125
- option: '-i, --id <id>'
126
- }, {
127
- option: '-f, --outputFile [outputFile]'
128
- });
129
- }, _TeamsMeetingTranscriptGetCommand_initValidators = function _TeamsMeetingTranscriptGetCommand_initValidators() {
130
- this.validators.push(async (args) => {
131
- if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
132
- return `${args.options.userId} is not a valid Guid`;
133
- }
134
- if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) {
135
- return `${args.options.userName} is not a valid user principal name (UPN)`;
136
- }
137
- if (args.options.email && !validation.isValidUserPrincipalName(args.options.email)) {
138
- return `${args.options.email} is not a valid email`;
139
- }
140
- if (args.options.outputFile && !fs.existsSync(path.dirname(args.options.outputFile))) {
141
- return 'Specified path where to save the file does not exits';
142
- }
143
- return true;
144
- });
145
- }, _TeamsMeetingTranscriptGetCommand_initOptionSets = function _TeamsMeetingTranscriptGetCommand_initOptionSets() {
146
- this.optionSets.push({
147
- options: ['userId', 'userName', 'email'],
148
- runsWhen: (args) => args.options.userId || args.options.userName || args.options.email
149
- });
150
- };
151
127
  export default new TeamsMeetingTranscriptGetCommand();
152
128
  //# sourceMappingURL=meeting-transcript-get.js.map
@@ -1,16 +1,28 @@
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 _TeamsMeetingTranscriptListCommand_instances, _TeamsMeetingTranscriptListCommand_initTelemetry, _TeamsMeetingTranscriptListCommand_initOptions, _TeamsMeetingTranscriptListCommand_initValidators, _TeamsMeetingTranscriptListCommand_initOptionSets;
7
1
  import auth from '../../../../Auth.js';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { z } from 'zod';
8
4
  import { entraUser } from '../../../../utils/entraUser.js';
9
5
  import { accessToken } from '../../../../utils/accessToken.js';
10
6
  import { odata } from '../../../../utils/odata.js';
11
7
  import { validation } from '../../../../utils/validation.js';
12
8
  import GraphCommand from '../../../base/GraphCommand.js';
13
9
  import commands from '../../commands.js';
10
+ export const options = z.strictObject({
11
+ ...globalOptionsZod.shape,
12
+ userId: z.string()
13
+ .refine(value => validation.isValidGuid(value), {
14
+ message: 'The userId value must be a valid GUID.'
15
+ }).optional().alias('u'),
16
+ userName: z.string()
17
+ .refine(value => validation.isValidUserPrincipalName(value), {
18
+ message: 'The userName value must be a valid user principal name (UPN).'
19
+ }).optional().alias('n'),
20
+ email: z.string()
21
+ .refine(value => validation.isValidUserPrincipalName(value), {
22
+ message: 'The email value must be a valid email.'
23
+ }).optional(),
24
+ meetingId: z.string().alias('m')
25
+ });
14
26
  class TeamsMeetingTranscriptListCommand extends GraphCommand {
15
27
  get name() {
16
28
  return commands.MEETING_TRANSCRIPT_LIST;
@@ -21,13 +33,17 @@ class TeamsMeetingTranscriptListCommand extends GraphCommand {
21
33
  defaultProperties() {
22
34
  return ['id', 'createdDateTime'];
23
35
  }
24
- constructor() {
25
- super();
26
- _TeamsMeetingTranscriptListCommand_instances.add(this);
27
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptListCommand_instances, "m", _TeamsMeetingTranscriptListCommand_initTelemetry).call(this);
28
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptListCommand_instances, "m", _TeamsMeetingTranscriptListCommand_initOptions).call(this);
29
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptListCommand_instances, "m", _TeamsMeetingTranscriptListCommand_initValidators).call(this);
30
- __classPrivateFieldGet(this, _TeamsMeetingTranscriptListCommand_instances, "m", _TeamsMeetingTranscriptListCommand_initOptionSets).call(this);
36
+ get schema() {
37
+ return options;
38
+ }
39
+ getRefinedSchema(schema) {
40
+ return schema.refine(options => [options.userId, options.userName, options.email].filter(value => value !== undefined).length <= 1, {
41
+ message: 'Specify either userId, userName or email, but not multiple.',
42
+ params: {
43
+ customCode: 'optionSet',
44
+ options: ['userId', 'userName', 'email']
45
+ }
46
+ });
31
47
  }
32
48
  async commandAction(logger, args) {
33
49
  try {
@@ -70,42 +86,5 @@ class TeamsMeetingTranscriptListCommand extends GraphCommand {
70
86
  }
71
87
  }
72
88
  }
73
- _TeamsMeetingTranscriptListCommand_instances = new WeakSet(), _TeamsMeetingTranscriptListCommand_initTelemetry = function _TeamsMeetingTranscriptListCommand_initTelemetry() {
74
- this.telemetry.push((args) => {
75
- Object.assign(this.telemetryProperties, {
76
- userId: typeof args.options.userId !== 'undefined',
77
- userName: typeof args.options.userName !== 'undefined',
78
- email: typeof args.options.email !== 'undefined'
79
- });
80
- });
81
- }, _TeamsMeetingTranscriptListCommand_initOptions = function _TeamsMeetingTranscriptListCommand_initOptions() {
82
- this.options.unshift({
83
- option: '-u, --userId [userId]'
84
- }, {
85
- option: '-n, --userName [userName]'
86
- }, {
87
- option: '--email [email]'
88
- }, {
89
- option: '-m, --meetingId <meetingId>'
90
- });
91
- }, _TeamsMeetingTranscriptListCommand_initValidators = function _TeamsMeetingTranscriptListCommand_initValidators() {
92
- this.validators.push(async (args) => {
93
- if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
94
- return `${args.options.userId} is not a valid Guid`;
95
- }
96
- if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) {
97
- return `${args.options.userName} is not a valid user principal name (UPN)`;
98
- }
99
- if (args.options.email && !validation.isValidUserPrincipalName(args.options.email)) {
100
- return `${args.options.email} is not a valid email`;
101
- }
102
- return true;
103
- });
104
- }, _TeamsMeetingTranscriptListCommand_initOptionSets = function _TeamsMeetingTranscriptListCommand_initOptionSets() {
105
- this.optionSets.push({
106
- options: ['userId', 'userName', 'email'],
107
- runsWhen: (args) => args.options.userId || args.options.userName || args.options.email
108
- });
109
- };
110
89
  export default new TeamsMeetingTranscriptListCommand();
111
90
  //# sourceMappingURL=meeting-transcript-list.js.map
package/dist/utils/spo.js CHANGED
@@ -576,6 +576,45 @@ export const spo = {
576
576
  return request.post(requestOptions);
577
577
  },
578
578
  /**
579
+ * Retrieves the navigation node with the specified key.
580
+ * Returns the node along with the menu state that contains it.
581
+ * @param webUrl Web url
582
+ * @param key Key (ID) of the navigation node
583
+ * @param location Navigation to search. When not specified, searches the quick launch first and then the top navigation
584
+ */
585
+ async getMenuStateNodeByKey(webUrl, key, location) {
586
+ const locations = location ? [location] : ['QuickLaunch', 'TopNavigationBar'];
587
+ for (const navigationLocation of locations) {
588
+ const menuState = navigationLocation === 'TopNavigationBar'
589
+ ? await this.getTopNavigationMenuState(webUrl)
590
+ : await this.getQuickLaunchMenuState(webUrl);
591
+ const node = this.findMenuStateNode(menuState.Nodes, key);
592
+ if (node) {
593
+ return { menuState, node };
594
+ }
595
+ }
596
+ throw location
597
+ ? `Navigation node with id '${key}' not found in ${location}.`
598
+ : `Navigation node with id '${key}' not found.`;
599
+ },
600
+ /**
601
+ * Recursively searches the specified menu state nodes for the node with the specified key.
602
+ * @param nodes Menu state nodes to search
603
+ * @param key Key (ID) of the navigation node
604
+ */
605
+ findMenuStateNode(nodes, key) {
606
+ for (const node of nodes) {
607
+ if (node.Key === key) {
608
+ return node;
609
+ }
610
+ const childNode = this.findMenuStateNode(node.Nodes, key);
611
+ if (childNode) {
612
+ return childNode;
613
+ }
614
+ }
615
+ return undefined;
616
+ },
617
+ /**
579
618
  * Retrieves the spo group by name.
580
619
  * Returns a group object
581
620
  * @param webUrl Web url
@@ -78,7 +78,20 @@ When logging in to Microsoft 365 using the user name and password, next to the a
78
78
 
79
79
  When logging in to Microsoft 365 using a certificate, the CLI for Microsoft 365 will store the contents of the certificate so that it can automatically re-authenticate if necessary. The contents of the certificate are removed by re-authenticating using the device code or by calling the [logout](logout.mdx) command.
80
80
 
81
- Federated Identity is currently supported in GitHub Actions. To use this you need to set `authType` to `federatedIdentity` and specify `appId` and `tenant` to the values of the app registration you've configured a federated credential on.
81
+ Federated Identity is currently supported in GitHub Actions, Azure DevOps and GitLab CI/CD. To use this you need to set `authType` to `federatedIdentity` and specify `appId` and `tenant` to the values of the app registration you've configured a federated credential on.
82
+
83
+ To use Federated Identity in GitLab CI/CD, the job must request an ID token named `GITLAB_OIDC_TOKEN` with audience `api://AzureADTokenExchange`, for example:
84
+
85
+ ```yaml
86
+ job:
87
+ id_tokens:
88
+ GITLAB_OIDC_TOKEN:
89
+ aud: "api://AzureADTokenExchange"
90
+ script:
91
+ - m365 login --authType federatedIdentity --appId eb96cfd0-abfa-4477-8d1d-c6dfde3efb19 --tenant 9a1a1bbd-e158-4cf5-967d-a53b8e85c628
92
+ ```
93
+
94
+ The corresponding federated credential on the Microsoft Entra app registration must have issuer `https://gitlab.com` (or your self-managed GitLab instance URL) and a subject matching the GitLab OIDC claim for the job, for example `project_path:<group>/<project>:ref_type:branch:ref:<branch>`.
82
95
 
83
96
  To log in to Microsoft 365 using a certificate or secret, you will typically [create a custom Microsoft Entra application](../user-guide/using-own-identity.mdx). To use this application with the CLI for Microsoft 365, you will set the `CLIMICROSOFT365_ENTRAAPPID` environment variable to the application's ID and the `CLIMICROSOFT365_TENANT` environment variable to the ID of the Microsoft Entra tenant, where you created the Microsoft Entra application. Also, please make sure to read about [the caveats when using the certificate login option](../user-guide/cli-certificate-caveats.mdx).
84
97
 
@@ -202,7 +215,7 @@ Log in to Microsoft 365 using a user-assigned managed identity with `clientId` s
202
215
  m365 login --authType identity --userName ac9fbed5-804c-4362-a369-21a4ec51109e
203
216
  ```
204
217
 
205
- Log in to Microsoft 365 using a federated identity. Can currently only be used in GitHub Actions.
218
+ Log in to Microsoft 365 using a federated identity. Can currently only be used in GitHub Actions, Azure DevOps and GitLab CI/CD.
206
219
 
207
220
  ```sh
208
221
  m365 login --authType federatedIdentity --appId eb96cfd0-abfa-4477-8d1d-c6dfde3efb19 --tenant 9a1a1bbd-e158-4cf5-967d-a53b8e85c628
@@ -30,9 +30,6 @@ m365 spo navigation node add [options]
30
30
  `--parentNodeId [parentNodeId]`
31
31
  : ID of the node below which the node should be added. Specify either `location` or `parentNodeId` but not both.
32
32
 
33
- `--isExternal`
34
- : Set, if the navigation node points to an external URL.
35
-
36
33
  `--audienceIds [audienceIds]`
37
34
  : Comma-separated list of group IDs that will be used for audience targeting. The limit is 10 ids per navigation node.
38
35
 
@@ -57,7 +54,7 @@ m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-
57
54
  Add a navigation node pointing to an external page to the quick launch.
58
55
 
59
56
  ```sh
60
- m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-a --location QuickLaunch --title "About us" --url https://contoso.com/about-us --isExternal
57
+ m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-a --location QuickLaunch --title "About us" --url https://contoso.com/about-us
61
58
  ```
62
59
 
63
60
  Add a navigation node below an existing node and opens it in a new window.
@@ -72,6 +69,12 @@ Add a navigation node to the top navigation which is audience targetted and open
72
69
  m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-a --location TopNavigationBar --title About --url /sites/team-s/sitepages/about.aspx --audienceIds "7aa4a1ca-4035-4f2f-bac7-7beada59b5ba,4bbf236f-a131-4019-b4a2-315902fcfa3a" --openInNewWindow
73
70
  ```
74
71
 
72
+ Add a linkless label to the quick launch.
73
+
74
+ ```sh
75
+ m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-a --location QuickLaunch --title Resources
76
+ ```
77
+
75
78
  ## Response
76
79
 
77
80
  <Tabs>
@@ -83,13 +86,18 @@ m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-
83
86
  "7aa4a1ca-4035-4f2f-bac7-7beada59b5ba"
84
87
  ],
85
88
  "CurrentLCID": 1033,
86
- "Id": 2030,
87
- "IsDocLib": true,
88
- "IsExternal": true,
89
- "IsVisible": true,
90
- "ListTemplateType": 0,
89
+ "CustomProperties": [],
90
+ "FriendlyUrlSegment": "",
91
+ "IsDeleted": false,
92
+ "IsHidden": false,
93
+ "IsTitleForExistingLanguage": false,
94
+ "Key": "2030",
95
+ "Nodes": [],
96
+ "NodeType": 0,
97
+ "OpenInNewWindow": true,
98
+ "SimpleUrl": "https://contoso.sharepoint.com",
91
99
  "Title": "Navigation Link",
92
- "Url": "https://contoso.sharepoint.com"
100
+ "Translations": []
93
101
  }
94
102
  ```
95
103
 
@@ -97,45 +105,52 @@ m365 spo navigation node add --webUrl https://contoso.sharepoint.com/sites/team-
97
105
  <TabItem value="Text">
98
106
 
99
107
  ```text
100
- AudienceIds : ["7aa4a1ca-4035-4f2f-bac7-7beada59b5ba"]
101
- CurrentLCID : 1033
102
- Id : 2031
103
- IsDocLib : true
104
- IsExternal : true
105
- IsVisible : true
106
- ListTemplateType: 0
107
- Title : Navigation Link
108
- Url : https://contoso.sharepoint.com
108
+ AudienceIds : ["7aa4a1ca-4035-4f2f-bac7-7beada59b5ba"]
109
+ CurrentLCID : 1033
110
+ CustomProperties : []
111
+ FriendlyUrlSegment :
112
+ IsDeleted : false
113
+ IsHidden : false
114
+ IsTitleForExistingLanguage: false
115
+ Key : 2030
116
+ NodeType : 0
117
+ Nodes : []
118
+ OpenInNewWindow : true
119
+ SimpleUrl : https://contoso.sharepoint.com
120
+ Title : Navigation Link
121
+ Translations : []
109
122
  ```
110
123
 
111
124
  </TabItem>
112
125
  <TabItem value="CSV">
113
126
 
114
127
  ```csv
115
- AudienceIds,CurrentLCID,Id,IsDocLib,IsExternal,IsVisible,ListTemplateType,Title,Url
116
- "[""7aa4a1ca-4035-4f2f-bac7-7beada59b5ba""]",1033,2032,1,1,1,0,Navigation Link,https://contoso.sharepoint.com
128
+ CurrentLCID,FriendlyUrlSegment,IsDeleted,IsHidden,IsTitleForExistingLanguage,Key,NodeType,OpenInNewWindow,SimpleUrl,Title
129
+ 1033,,0,0,0,2030,0,1,https://contoso.sharepoint.com,Navigation Link
117
130
  ```
118
131
 
119
132
  </TabItem>
120
133
  <TabItem value="Markdown">
121
134
 
122
135
  ```md
123
- # spo navigation node get --webUrl "https://contoso.sharepoint.com/sites/team-a" --location "TopNavigationBar" --title "Navigation Link" --url "https://contoso.sharepoint.com"
136
+ # spo navigation node add --webUrl "https://contoso.sharepoint.com/sites/team-a" --location "TopNavigationBar" --title "Navigation Link" --url "https://contoso.sharepoint.com" --openInNewWindow "true"
124
137
 
125
- Date: 2/20/2023
138
+ Date: 10/7/2026
126
139
 
127
- ## Navigation Link (2030)
140
+ ## Navigation Link
128
141
 
129
142
  Property | Value
130
143
  ---------|-------
131
144
  CurrentLCID | 1033
132
- Id | 2030
133
- IsDocLib | true
134
- IsExternal | false
135
- IsVisible | true
136
- ListTemplateType | 0
145
+ FriendlyUrlSegment |
146
+ IsDeleted | false
147
+ IsHidden | false
148
+ IsTitleForExistingLanguage | false
149
+ Key | 2030
150
+ NodeType | 0
151
+ OpenInNewWindow | true
152
+ SimpleUrl | https://contoso.sharepoint.com
137
153
  Title | Navigation Link
138
- Url | https://contoso.sharepoint.com
139
154
  ```
140
155
 
141
156
  </TabItem>