@pnp/cli-microsoft365 9.0.0-beta.2f8dd1e → 9.0.0-beta.59b026e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -0
- package/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/Auth.js +10 -18
- package/dist/Command.js +49 -2
- package/dist/chili/chili.js +0 -23
- package/dist/cli/cli.js +61 -101
- package/dist/config.js +1 -1
- package/dist/m365/app/commands/permission/permission-add.js +9 -9
- package/dist/m365/commands/login.js +44 -96
- package/dist/m365/commands/setup.js +0 -4
- package/dist/m365/commands/status.js +2 -2
- package/dist/m365/connection/commands/connection-remove.js +6 -2
- package/dist/m365/connection/commands/connection-set.js +4 -1
- package/dist/m365/connection/commands/connection-use.js +25 -4
- package/dist/m365/entra/commands/enterpriseapp/enterpriseapp-add.js +13 -13
- package/dist/m365/entra/commands/enterpriseapp/enterpriseapp-get.js +18 -18
- package/dist/m365/entra/commands/enterpriseapp/enterpriseapp-list.js +1 -1
- package/dist/m365/entra/commands/group/group-user-list.js +4 -4
- package/dist/m365/entra/commands/m365group/m365group-conversation-post-list.js +4 -4
- package/dist/m365/entra/commands/m365group/m365group-recyclebinitem-list.js +3 -3
- package/dist/m365/entra/commands/m365group/m365group-set.js +66 -29
- package/dist/m365/entra/commands/m365group/m365group-user-add.js +109 -32
- package/dist/m365/entra/commands/m365group/m365group-user-list.js +6 -9
- package/dist/m365/entra/commands/m365group/m365group-user-set.js +159 -84
- package/dist/m365/entra/commands/multitenant/MultitenantOrganization.js +2 -0
- package/dist/m365/entra/commands/multitenant/multitenant-add.js +65 -0
- package/dist/m365/entra/commands/multitenant/multitenant-get.js +32 -0
- package/dist/m365/entra/commands/multitenant/multitenant-remove.js +118 -0
- package/dist/m365/entra/commands/multitenant/multitenant-set.js +72 -0
- package/dist/m365/entra/commands.js +4 -0
- package/dist/m365/external/commands/connection/connection-doctor.js +10 -24
- package/dist/m365/flow/commands/flow-get.js +1 -1
- package/dist/m365/flow/commands/flow-list.js +23 -24
- package/dist/m365/graph/commands/subscription/subscription-add.js +4 -2
- package/dist/m365/outlook/commands/message/message-get.js +11 -11
- package/dist/m365/spe/ContainerTypeProperties.js +2 -0
- package/dist/m365/spe/commands/containertype/containertype-list.js +49 -0
- package/dist/m365/spe/commands.js +2 -1
- package/dist/m365/spfx/commands/project/DeployWorkflow.js +1 -1
- package/dist/m365/spfx/commands/project/base-project-command.js +36 -126
- package/dist/m365/spfx/commands/project/project-github-workflow-add.js +1 -10
- package/dist/m365/spo/commands/applicationcustomizer/applicationcustomizer-get.js +16 -21
- package/dist/m365/spo/commands/cdn/cdn-get.js +12 -15
- package/dist/m365/spo/commands/cdn/cdn-set.js +6 -4
- package/dist/m365/spo/commands/commandset/commandset-get.js +31 -17
- package/dist/m365/spo/commands/contenttype/contenttype-field-list.js +124 -0
- package/dist/m365/spo/commands/field/field-list.js +1 -1
- package/dist/m365/spo/commands/file/file-copy.js +55 -34
- package/dist/m365/spo/commands/file/file-roleassignment-add.js +1 -1
- package/dist/m365/spo/commands/file/file-roleinheritance-break.js +1 -1
- package/dist/m365/spo/commands/file/file-roleinheritance-reset.js +1 -1
- package/dist/m365/spo/commands/folder/folder-retentionlabel-ensure.js +1 -1
- package/dist/m365/spo/commands/folder/folder-set.js +0 -4
- package/dist/m365/spo/commands/folder/folder-sharinglink-get.js +86 -0
- package/dist/m365/spo/commands/folder/folder-sharinglink-list.js +110 -0
- package/dist/m365/spo/commands/group/group-member-add.js +103 -99
- package/dist/m365/spo/commands/list/ListInstance.js +6 -1
- package/dist/m365/spo/commands/list/list-get.js +9 -3
- package/dist/m365/spo/commands/list/list-list.js +1 -4
- package/dist/m365/spo/commands/list/list-roleassignment-add.js +46 -21
- package/dist/m365/spo/commands/list/list-roleassignment-remove.js +48 -46
- package/dist/m365/spo/commands/page/page-clientsidewebpart-add.js +2 -3
- package/dist/m365/spo/commands/page/page-text-add.js +2 -3
- package/dist/m365/spo/commands/site/site-appcatalog-remove.js +48 -24
- package/dist/m365/spo/commands/site/site-remove.js +1 -7
- package/dist/m365/spo/commands/spo-search.js +3 -4
- package/dist/m365/spo/commands/tenant/tenant-applicationcustomizer-get.js +19 -5
- package/dist/m365/spo/commands/tenant/tenant-commandset-get.js +20 -6
- package/dist/m365/spo/commands/tenant/tenant-recyclebinitem-restore.js +2 -22
- package/dist/m365/spo/commands.js +3 -1
- package/dist/m365/teams/commands/meeting/meeting-attendancereport-get.js +119 -0
- package/dist/m365/teams/commands/message/message-remove.js +112 -0
- package/dist/m365/teams/commands.js +2 -0
- package/dist/m365/viva/commands/engage/engage-community-add.js +166 -0
- package/dist/m365/viva/commands.js +1 -0
- package/dist/utils/drive.js +61 -0
- package/dist/utils/formatting.js +30 -1
- package/dist/utils/spo.js +143 -6
- package/dist/utils/teams.js +49 -0
- package/dist/utils/validation.js +19 -0
- package/dist/utils/zod.js +124 -0
- package/docs/docs/cmd/app/permission/permission-add.mdx +5 -5
- package/docs/docs/cmd/connection/connection-use.mdx +8 -2
- package/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-add.mdx +12 -12
- package/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-get.mdx +14 -14
- package/docs/docs/cmd/entra/enterpriseapp/enterpriseapp-list.mdx +5 -5
- package/docs/docs/cmd/entra/group/group-user-list.mdx +7 -7
- package/docs/docs/cmd/entra/m365group/m365group-conversation-post-list.mdx +5 -5
- package/docs/docs/cmd/entra/m365group/m365group-recyclebinitem-list.mdx +3 -3
- package/docs/docs/cmd/entra/m365group/m365group-set.mdx +37 -7
- package/docs/docs/cmd/entra/m365group/m365group-user-add.mdx +28 -10
- package/docs/docs/cmd/entra/m365group/m365group-user-list.mdx +1 -1
- package/docs/docs/cmd/entra/m365group/m365group-user-set.mdx +35 -11
- package/docs/docs/cmd/entra/multitenant/multitenant-add.mdx +107 -0
- package/docs/docs/cmd/entra/multitenant/multitenant-get.mdx +94 -0
- package/docs/docs/cmd/entra/multitenant/multitenant-remove.mdx +58 -0
- package/docs/docs/cmd/entra/multitenant/multitenant-set.mdx +53 -0
- package/docs/docs/cmd/external/connection/connection-doctor.mdx +9 -9
- package/docs/docs/cmd/flow/flow-get.mdx +149 -283
- package/docs/docs/cmd/flow/flow-list.mdx +114 -56
- package/docs/docs/cmd/graph/subscription/subscription-add.mdx +18 -0
- package/docs/docs/cmd/outlook/message/message-get.mdx +5 -5
- package/docs/docs/cmd/planner/plan/plan-remove.mdx +1 -1
- package/docs/docs/cmd/spe/containertype/containertype-list.mdx +102 -0
- package/docs/docs/cmd/spfx/project/project-github-workflow-add.mdx +11 -12
- package/docs/docs/cmd/spo/applicationcustomizer/applicationcustomizer-get.mdx +87 -38
- package/docs/docs/cmd/spo/applicationcustomizer/applicationcustomizer-list.mdx +22 -28
- package/docs/docs/cmd/spo/cdn/cdn-set.mdx +3 -3
- package/docs/docs/cmd/spo/commandset/commandset-get.mdx +75 -24
- package/docs/docs/cmd/spo/commandset/commandset-list.mdx +26 -32
- package/docs/docs/cmd/spo/contenttype/contenttype-field-list.mdx +172 -0
- package/docs/docs/cmd/spo/contenttype/contenttype-list.mdx +3 -3
- package/docs/docs/cmd/spo/field/field-list.mdx +3 -3
- package/docs/docs/cmd/spo/file/file-copy.mdx +119 -12
- package/docs/docs/cmd/spo/file/file-retentionlabel-ensure.mdx +1 -1
- package/docs/docs/cmd/spo/file/file-roleassignment-add.mdx +2 -2
- package/docs/docs/cmd/spo/file/file-roleassignment-remove.mdx +1 -1
- package/docs/docs/cmd/spo/file/file-roleinheritance-break.mdx +1 -1
- package/docs/docs/cmd/spo/file/file-roleinheritance-reset.mdx +1 -1
- package/docs/docs/cmd/spo/folder/folder-retentionlabel-ensure.mdx +2 -2
- package/docs/docs/cmd/spo/folder/folder-set.mdx +0 -6
- package/docs/docs/cmd/spo/folder/folder-sharinglink-get.mdx +110 -0
- package/docs/docs/cmd/spo/folder/folder-sharinglink-list.mdx +114 -0
- package/docs/docs/cmd/spo/group/group-member-add.mdx +34 -27
- package/docs/docs/cmd/spo/list/list-get.mdx +6 -0
- package/docs/docs/cmd/spo/list/list-list.mdx +5 -7
- package/docs/docs/cmd/spo/list/list-roleassignment-add.mdx +15 -3
- package/docs/docs/cmd/spo/list/list-roleassignment-remove.mdx +15 -3
- package/docs/docs/cmd/spo/listitem/listitem-retentionlabel-ensure.mdx +4 -4
- package/docs/docs/cmd/spo/listitem/listitem-retentionlabel-remove.mdx +1 -1
- package/docs/docs/cmd/spo/listitem/listitem-roleassignment-add.mdx +9 -9
- package/docs/docs/cmd/spo/listitem/listitem-roleassignment-remove.mdx +7 -7
- package/docs/docs/cmd/spo/site/site-appcatalog-remove.mdx +11 -2
- package/docs/docs/cmd/spo/site/site-recyclebinitem-list.mdx +1 -1
- package/docs/docs/cmd/spo/site/site-remove.mdx +0 -3
- package/docs/docs/cmd/spo/tenant/tenant-applicationcustomizer-get.mdx +79 -30
- package/docs/docs/cmd/spo/tenant/tenant-applicationcustomizer-list.mdx +20 -19
- package/docs/docs/cmd/spo/tenant/tenant-commandset-get.mdx +84 -38
- package/docs/docs/cmd/spo/tenant/tenant-commandset-list.mdx +20 -19
- package/docs/docs/cmd/spo/tenant/tenant-recyclebinitem-restore.mdx +2 -49
- package/docs/docs/cmd/spo/web/web-roleassignment-add.mdx +1 -1
- package/docs/docs/cmd/spo/web/web-roleassignment-remove.mdx +1 -1
- package/docs/docs/cmd/teams/meeting/meeting-attendancereport-get.mdx +138 -0
- package/docs/docs/cmd/teams/meeting/meeting-list.mdx +7 -3
- package/docs/docs/cmd/teams/message/message-remove.mdx +63 -0
- package/docs/docs/cmd/viva/engage/engage-community-add.mdx +168 -0
- package/npm-shrinkwrap.json +588 -1022
- package/package.json +7 -3
package/dist/Auth.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AzureCloudInstance } from '@azure/msal-common';
|
|
2
|
+
import assert from 'assert';
|
|
2
3
|
import { CommandError } from './Command.js';
|
|
3
4
|
import { FileTokenStorage } from './auth/FileTokenStorage.js';
|
|
4
5
|
import { msalCachePlugin } from './auth/msalCachePlugin.js';
|
|
@@ -6,16 +7,15 @@ import { cli } from './cli/cli.js';
|
|
|
6
7
|
import config from './config.js';
|
|
7
8
|
import request from './request.js';
|
|
8
9
|
import { settingsNames } from './settingsNames.js';
|
|
9
|
-
import { browserUtil } from './utils/browserUtil.js';
|
|
10
10
|
import * as accessTokenUtil from './utils/accessToken.js';
|
|
11
|
-
import
|
|
11
|
+
import { browserUtil } from './utils/browserUtil.js';
|
|
12
12
|
export var CloudType;
|
|
13
13
|
(function (CloudType) {
|
|
14
|
-
CloudType[
|
|
15
|
-
CloudType[
|
|
16
|
-
CloudType[
|
|
17
|
-
CloudType[
|
|
18
|
-
CloudType[
|
|
14
|
+
CloudType["Public"] = "Public";
|
|
15
|
+
CloudType["USGov"] = "USGov";
|
|
16
|
+
CloudType["USGovHigh"] = "USGovHigh";
|
|
17
|
+
CloudType["USGovDoD"] = "USGovDoD";
|
|
18
|
+
CloudType["China"] = "China";
|
|
19
19
|
})(CloudType || (CloudType = {}));
|
|
20
20
|
export class Connection {
|
|
21
21
|
constructor() {
|
|
@@ -354,15 +354,7 @@ export class Auth {
|
|
|
354
354
|
await logger.logToStderr(response);
|
|
355
355
|
await logger.logToStderr('');
|
|
356
356
|
}
|
|
357
|
-
|
|
358
|
-
cli.spinner.spinner = {
|
|
359
|
-
frames: ['🌶️ ']
|
|
360
|
-
};
|
|
361
|
-
// don't show spinner if running tests
|
|
362
|
-
/* c8 ignore next 3 */
|
|
363
|
-
if (!cli.spinner.isSpinning && typeof global.it === 'undefined') {
|
|
364
|
-
cli.spinner.start();
|
|
365
|
-
}
|
|
357
|
+
await logger.logToStderr(`🌶️ ${response.message}`);
|
|
366
358
|
if (cli.getSettingWithDefaultValue(settingsNames.autoOpenLinksInBrowser, false)) {
|
|
367
359
|
await browserUtil.open(response.verificationUri);
|
|
368
360
|
}
|
|
@@ -699,7 +691,7 @@ export class Auth {
|
|
|
699
691
|
const allConnections = await this.getAllConnections();
|
|
700
692
|
const connection = allConnections.find(i => i.name === name);
|
|
701
693
|
if (!connection) {
|
|
702
|
-
throw new CommandError(`The connection '${name}' cannot be found
|
|
694
|
+
throw new CommandError(`The connection '${name}' cannot be found.`);
|
|
703
695
|
}
|
|
704
696
|
return connection;
|
|
705
697
|
}
|
|
@@ -718,7 +710,7 @@ export class Auth {
|
|
|
718
710
|
return details;
|
|
719
711
|
}
|
|
720
712
|
}
|
|
721
|
-
Auth.cloudEndpoints =
|
|
713
|
+
Auth.cloudEndpoints = {};
|
|
722
714
|
Auth.initialize();
|
|
723
715
|
export default new Auth();
|
|
724
716
|
//# sourceMappingURL=Auth.js.map
|
package/dist/Command.js
CHANGED
|
@@ -5,6 +5,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
5
5
|
};
|
|
6
6
|
var _Command_instances, _Command_initTelemetry, _Command_initOptions, _Command_initValidators;
|
|
7
7
|
import os from 'os';
|
|
8
|
+
import { z } from 'zod';
|
|
8
9
|
import auth from './Auth.js';
|
|
9
10
|
import { cli } from './cli/cli.js';
|
|
10
11
|
import request from './request.js';
|
|
@@ -13,6 +14,7 @@ import { telemetry } from './telemetry.js';
|
|
|
13
14
|
import { accessToken } from './utils/accessToken.js';
|
|
14
15
|
import { md } from './utils/md.js';
|
|
15
16
|
import { prompt } from './utils/prompt.js';
|
|
17
|
+
import { zod } from './utils/zod.js';
|
|
16
18
|
export class CommandError {
|
|
17
19
|
constructor(message, code) {
|
|
18
20
|
this.message = message;
|
|
@@ -25,10 +27,26 @@ export class CommandErrorWithOutput {
|
|
|
25
27
|
this.stderr = stderr;
|
|
26
28
|
}
|
|
27
29
|
}
|
|
30
|
+
export const globalOptionsZod = z.object({
|
|
31
|
+
query: z.string().optional(),
|
|
32
|
+
output: zod.alias('o', z.enum(['csv', 'json', 'md', 'text', 'none']).optional()),
|
|
33
|
+
debug: z.boolean().default(false),
|
|
34
|
+
verbose: z.boolean().default(false)
|
|
35
|
+
});
|
|
28
36
|
class Command {
|
|
29
37
|
get allowedOutputs() {
|
|
30
38
|
return ['csv', 'json', 'md', 'text', 'none'];
|
|
31
39
|
}
|
|
40
|
+
get schema() {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
|
+
getRefinedSchema(schema) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
getSchemaToParse() {
|
|
48
|
+
return this.getRefinedSchema(this.schema) ?? this.schema;
|
|
49
|
+
}
|
|
32
50
|
constructor() {
|
|
33
51
|
// These functions must be defined with # so that they're truly private
|
|
34
52
|
// otherwise you'll get a ts2415 error (Types have separate declarations of
|
|
@@ -48,6 +66,9 @@ class Command {
|
|
|
48
66
|
string: []
|
|
49
67
|
};
|
|
50
68
|
this.validators = [];
|
|
69
|
+
// metadata for command's options
|
|
70
|
+
// used for building telemetry
|
|
71
|
+
this.optionsInfo = [];
|
|
51
72
|
__classPrivateFieldGet(this, _Command_instances, "m", _Command_initTelemetry).call(this);
|
|
52
73
|
__classPrivateFieldGet(this, _Command_instances, "m", _Command_initOptions).call(this);
|
|
53
74
|
__classPrivateFieldGet(this, _Command_instances, "m", _Command_initValidators).call(this);
|
|
@@ -410,8 +431,34 @@ class Command {
|
|
|
410
431
|
return '';
|
|
411
432
|
}
|
|
412
433
|
getTelemetryProperties(args) {
|
|
413
|
-
this.
|
|
414
|
-
|
|
434
|
+
if (this.schema) {
|
|
435
|
+
const telemetryProperties = {};
|
|
436
|
+
this.optionsInfo.forEach(o => {
|
|
437
|
+
if (o.required) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (typeof args.options[o.name] === 'undefined') {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
switch (o.type) {
|
|
444
|
+
case 'string':
|
|
445
|
+
telemetryProperties[o.name] = o.autocomplete ? args.options[o.name] : typeof args.options[o.name] !== 'undefined';
|
|
446
|
+
break;
|
|
447
|
+
case 'boolean':
|
|
448
|
+
telemetryProperties[o.name] = args.options[o.name];
|
|
449
|
+
break;
|
|
450
|
+
case 'number':
|
|
451
|
+
telemetryProperties[o.name] = typeof args.options[o.name] !== 'undefined';
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
;
|
|
455
|
+
});
|
|
456
|
+
return telemetryProperties;
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
this.telemetry.forEach(t => t(args));
|
|
460
|
+
return this.telemetryProperties;
|
|
461
|
+
}
|
|
415
462
|
}
|
|
416
463
|
async getTextOutput(logStatement) {
|
|
417
464
|
// display object as a list of key-value pairs
|
package/dist/chili/chili.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import ora from 'ora';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import url from 'url';
|
|
5
|
-
import { cli } from '../cli/cli.js';
|
|
6
4
|
import request from '../request.js';
|
|
7
|
-
import { settingsNames } from '../settingsNames.js';
|
|
8
5
|
import { md } from '../utils/md.js';
|
|
9
6
|
import { prompt } from '../utils/prompt.js';
|
|
10
7
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
11
8
|
const mendableBaseUrl = 'https://api.mendable.ai/v1';
|
|
12
9
|
const mendableApiKey = 'd3313d54-6f8e-40e0-90d3-4095019d4be7';
|
|
13
|
-
const spinner = ora({ discardStdin: false });
|
|
14
10
|
let showHelp = false;
|
|
15
11
|
let debug = false;
|
|
16
12
|
let conversationId = 0;
|
|
17
13
|
let initialPrompt = '';
|
|
18
14
|
let history = [];
|
|
19
|
-
const showSpinner = cli.getSettingWithDefaultValue(settingsNames.showSpinner, true) && typeof global.it === 'undefined';
|
|
20
15
|
request.logger = {
|
|
21
16
|
/* c8 ignore next 3 */
|
|
22
17
|
log: async (msg) => console.log(msg),
|
|
@@ -74,20 +69,11 @@ async function promptForPrompt() {
|
|
|
74
69
|
}
|
|
75
70
|
async function runConversationTurn(conversationId, question) {
|
|
76
71
|
console.log('');
|
|
77
|
-
/* c8 ignore next 4 */
|
|
78
|
-
if (showSpinner) {
|
|
79
|
-
spinner.text = 'Searching documentation...';
|
|
80
|
-
spinner.start();
|
|
81
|
-
}
|
|
82
72
|
const response = await runMendableChat(conversationId, question);
|
|
83
73
|
history.push({
|
|
84
74
|
prompt: question,
|
|
85
75
|
response: response.answer.text
|
|
86
76
|
});
|
|
87
|
-
/* c8 ignore next 3 */
|
|
88
|
-
if (showSpinner) {
|
|
89
|
-
spinner.stop();
|
|
90
|
-
}
|
|
91
77
|
console.log(md.md2plain(response.answer.text, ''));
|
|
92
78
|
console.log('');
|
|
93
79
|
console.log('Source:');
|
|
@@ -141,16 +127,7 @@ async function endConversation(conversationId) {
|
|
|
141
127
|
conversation_id: conversationId
|
|
142
128
|
}
|
|
143
129
|
};
|
|
144
|
-
/* c8 ignore next 4 */
|
|
145
|
-
if (showSpinner) {
|
|
146
|
-
spinner.text = 'Ending conversation...';
|
|
147
|
-
spinner.start();
|
|
148
|
-
}
|
|
149
130
|
await request.post(requestOptions);
|
|
150
|
-
/* c8 ignore next 3 */
|
|
151
|
-
if (showSpinner) {
|
|
152
|
-
spinner.stop();
|
|
153
|
-
}
|
|
154
131
|
}
|
|
155
132
|
async function runMendableChat(conversationId, question) {
|
|
156
133
|
const requestOptions = {
|
package/dist/cli/cli.js
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import Configstore from 'configstore';
|
|
2
2
|
import fs from 'fs';
|
|
3
|
-
import minimist from 'minimist';
|
|
4
3
|
import { createRequire } from 'module';
|
|
5
|
-
import ora from 'ora';
|
|
6
4
|
import os from 'os';
|
|
7
5
|
import path from 'path';
|
|
8
6
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
7
|
+
import yargs from 'yargs-parser';
|
|
8
|
+
import { ZodError } from 'zod';
|
|
9
9
|
import Command, { CommandError } from '../Command.js';
|
|
10
10
|
import config from '../config.js';
|
|
11
11
|
import request from '../request.js';
|
|
12
12
|
import { settingsNames } from '../settingsNames.js';
|
|
13
13
|
import { telemetry } from '../telemetry.js';
|
|
14
14
|
import { app } from '../utils/app.js';
|
|
15
|
+
import { browserUtil } from '../utils/browserUtil.js';
|
|
15
16
|
import { formatting } from '../utils/formatting.js';
|
|
16
17
|
import { md } from '../utils/md.js';
|
|
17
|
-
import { validation } from '../utils/validation.js';
|
|
18
18
|
import { prompt } from '../utils/prompt.js';
|
|
19
|
+
import { validation } from '../utils/validation.js';
|
|
20
|
+
import { zod } from '../utils/zod.js';
|
|
19
21
|
import { timings } from './timings.js';
|
|
20
|
-
import { browserUtil } from '../utils/browserUtil.js';
|
|
21
22
|
const require = createRequire(import.meta.url);
|
|
22
23
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
23
24
|
let _config;
|
|
24
|
-
// we assign it through exported function to support mocking
|
|
25
|
-
// eslint-disable-next-line prefer-const
|
|
26
|
-
let spinner = ora();
|
|
27
25
|
const commands = [];
|
|
28
26
|
/**
|
|
29
27
|
* Command to execute
|
|
@@ -68,7 +66,7 @@ async function execute(rawArgs) {
|
|
|
68
66
|
rawArgs.shift();
|
|
69
67
|
}
|
|
70
68
|
// parse args to see if a command has been specified
|
|
71
|
-
const parsedArgs =
|
|
69
|
+
const parsedArgs = yargs(rawArgs);
|
|
72
70
|
// load command
|
|
73
71
|
await cli.loadCommandFromArgs(parsedArgs._);
|
|
74
72
|
if (cli.commandToExecute) {
|
|
@@ -81,8 +79,7 @@ async function execute(rawArgs) {
|
|
|
81
79
|
};
|
|
82
80
|
}
|
|
83
81
|
catch (e) {
|
|
84
|
-
|
|
85
|
-
return cli.closeWithError(e.message, optionsWithoutShorts, false);
|
|
82
|
+
return cli.closeWithError(e.message, { options: parsedArgs }, false);
|
|
86
83
|
}
|
|
87
84
|
}
|
|
88
85
|
else {
|
|
@@ -130,18 +127,30 @@ async function execute(rawArgs) {
|
|
|
130
127
|
if (cli.optionsFromArgs.options.output === undefined) {
|
|
131
128
|
cli.optionsFromArgs.options.output = cli.getSettingWithDefaultValue(settingsNames.output, 'json');
|
|
132
129
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
let finalArgs = cli.optionsFromArgs.options;
|
|
131
|
+
if (cli.commandToExecute?.command.schema) {
|
|
132
|
+
const startValidation = process.hrtime.bigint();
|
|
133
|
+
const result = cli.commandToExecute.command.getSchemaToParse().safeParse(cli.optionsFromArgs.options);
|
|
134
|
+
const endValidation = process.hrtime.bigint();
|
|
135
|
+
timings.validation.push(Number(endValidation - startValidation));
|
|
136
|
+
if (!result.success) {
|
|
137
|
+
return cli.closeWithError(result.error, cli.optionsFromArgs, true);
|
|
138
|
+
}
|
|
139
|
+
finalArgs = result.data;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const startValidation = process.hrtime.bigint();
|
|
143
|
+
const validationResult = await cli.commandToExecute.command.validate(cli.optionsFromArgs, cli.commandToExecute);
|
|
144
|
+
const endValidation = process.hrtime.bigint();
|
|
145
|
+
timings.validation.push(Number(endValidation - startValidation));
|
|
146
|
+
if (validationResult !== true) {
|
|
147
|
+
return cli.closeWithError(validationResult, cli.optionsFromArgs, true);
|
|
148
|
+
}
|
|
139
149
|
}
|
|
140
|
-
cli.optionsFromArgs = removeShortOptions(cli.optionsFromArgs);
|
|
141
150
|
const end = process.hrtime.bigint();
|
|
142
151
|
timings.core.push(Number(end - start));
|
|
143
152
|
try {
|
|
144
|
-
await cli.executeCommand(cli.commandToExecute.command,
|
|
153
|
+
await cli.executeCommand(cli.commandToExecute.command, { options: finalArgs });
|
|
145
154
|
const endTotal = process.hrtime.bigint();
|
|
146
155
|
timings.total.push(Number(endTotal - start));
|
|
147
156
|
await printTimings(rawArgs);
|
|
@@ -190,12 +199,6 @@ async function executeCommand(command, args) {
|
|
|
190
199
|
// the command to execute
|
|
191
200
|
const parentCommandName = cli.currentCommandName;
|
|
192
201
|
cli.currentCommandName = command.getCommandName(cli.currentCommandName);
|
|
193
|
-
const showSpinner = cli.getSettingWithDefaultValue(settingsNames.showSpinner, true) && args.options.output !== 'none';
|
|
194
|
-
// don't show spinner if running tests
|
|
195
|
-
/* c8 ignore next 3 */
|
|
196
|
-
if (showSpinner && typeof global.it === 'undefined') {
|
|
197
|
-
cli.spinner.start();
|
|
198
|
-
}
|
|
199
202
|
const startCommand = process.hrtime.bigint();
|
|
200
203
|
try {
|
|
201
204
|
await command.action(logger, args);
|
|
@@ -207,10 +210,6 @@ async function executeCommand(command, args) {
|
|
|
207
210
|
finally {
|
|
208
211
|
// restore the original command name
|
|
209
212
|
cli.currentCommandName = parentCommandName;
|
|
210
|
-
/* c8 ignore next 3 */
|
|
211
|
-
if (cli.spinner.isSpinning) {
|
|
212
|
-
cli.spinner.stop();
|
|
213
|
-
}
|
|
214
213
|
const endCommand = process.hrtime.bigint();
|
|
215
214
|
timings.command.push(Number(endCommand - startCommand));
|
|
216
215
|
}
|
|
@@ -361,12 +360,14 @@ async function loadCommandFromFile(commandFileUrl) {
|
|
|
361
360
|
catch { }
|
|
362
361
|
}
|
|
363
362
|
function getCommandInfo(command, filePath = '', helpFilePath = '') {
|
|
363
|
+
const options = command.schema ? zod.schemaToOptions(command.schema) : getCommandOptions(command);
|
|
364
|
+
command.optionsInfo = options;
|
|
364
365
|
return {
|
|
365
366
|
aliases: command.alias(),
|
|
366
367
|
name: command.name,
|
|
367
368
|
description: command.description,
|
|
368
369
|
command: command,
|
|
369
|
-
options
|
|
370
|
+
options,
|
|
370
371
|
defaultProperties: command.defaultProperties(),
|
|
371
372
|
file: filePath,
|
|
372
373
|
help: helpFilePath
|
|
@@ -401,36 +402,47 @@ function getCommandOptions(command) {
|
|
|
401
402
|
return options;
|
|
402
403
|
}
|
|
403
404
|
function getCommandOptionsFromArgs(args, commandInfo) {
|
|
404
|
-
const
|
|
405
|
-
alias: {}
|
|
405
|
+
const yargsOptions = {
|
|
406
|
+
alias: {},
|
|
407
|
+
configuration: {
|
|
408
|
+
"parse-numbers": false,
|
|
409
|
+
"strip-aliased": true,
|
|
410
|
+
"strip-dashed": true
|
|
411
|
+
}
|
|
406
412
|
};
|
|
407
413
|
let argsToParse = args;
|
|
408
414
|
if (commandInfo) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
415
|
+
if (commandInfo.command.schema) {
|
|
416
|
+
yargsOptions.string = commandInfo.options.filter(o => o.type === 'string').map(o => o.name);
|
|
417
|
+
yargsOptions.boolean = commandInfo.options.filter(o => o.type === 'boolean').map(o => o.name);
|
|
418
|
+
yargsOptions.number = commandInfo.options.filter(o => o.type === 'number').map(o => o.name);
|
|
419
|
+
argsToParse = getRewrittenArgs(args, yargsOptions.boolean);
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
const commandTypes = commandInfo.command.types;
|
|
423
|
+
if (commandTypes) {
|
|
424
|
+
yargsOptions.string = commandTypes.string;
|
|
425
|
+
// minimist will parse unused boolean options to 'false' (unused options => options that are not included in the args)
|
|
426
|
+
// But in the CLI booleans are nullable. They can can be true, false or undefined.
|
|
427
|
+
// For this reason we only pass boolean types that are actually used as arg.
|
|
428
|
+
yargsOptions.boolean = commandTypes.boolean.filter(optionName => args.some(arg => `--${optionName}` === arg || `-${optionName}` === arg));
|
|
429
|
+
}
|
|
430
|
+
argsToParse = getRewrittenArgs(args, commandTypes.boolean);
|
|
431
|
+
}
|
|
418
432
|
commandInfo.options.forEach(option => {
|
|
419
433
|
if (option.short && option.long) {
|
|
420
|
-
|
|
434
|
+
yargsOptions.alias[option.long] = option.short;
|
|
421
435
|
}
|
|
422
436
|
});
|
|
423
|
-
argsToParse = getRewrittenArgs(args, commandTypes);
|
|
424
437
|
}
|
|
425
|
-
return
|
|
438
|
+
return yargs(argsToParse, yargsOptions);
|
|
426
439
|
}
|
|
427
440
|
/**
|
|
428
441
|
* Rewrites arguments (if necessary) before passing them into minimist.
|
|
429
442
|
* Currently only boolean values are checked and fixed.
|
|
430
443
|
* Args are only checked and rewritten if the option has been added to the 'types.boolean' array.
|
|
431
444
|
*/
|
|
432
|
-
function getRewrittenArgs(args,
|
|
433
|
-
const booleanTypes = commandTypes.boolean;
|
|
445
|
+
function getRewrittenArgs(args, booleanTypes) {
|
|
434
446
|
if (booleanTypes.length === 0) {
|
|
435
447
|
return args;
|
|
436
448
|
}
|
|
@@ -736,6 +748,9 @@ async function closeWithError(error, args, showHelpIfEnabled = false) {
|
|
|
736
748
|
return process.exit(exitCode);
|
|
737
749
|
}
|
|
738
750
|
let errorMessage = error instanceof CommandError ? error.message : error;
|
|
751
|
+
if (error instanceof ZodError) {
|
|
752
|
+
errorMessage = error.errors.map(e => `${e.path}: ${e.message}`).join(os.EOL);
|
|
753
|
+
}
|
|
739
754
|
if ((!args.options.output || args.options.output === 'json') &&
|
|
740
755
|
!cli.getSettingWithDefaultValue(settingsNames.printErrorsAsPlainText, true)) {
|
|
741
756
|
errorMessage = JSON.stringify({ error: errorMessage });
|
|
@@ -758,29 +773,14 @@ async function closeWithError(error, args, showHelpIfEnabled = false) {
|
|
|
758
773
|
/* c8 ignore next */
|
|
759
774
|
}
|
|
760
775
|
function log(message, ...optionalParams) {
|
|
761
|
-
const spinnerSpinning = cli.spinner.isSpinning;
|
|
762
|
-
/* c8 ignore next 3 */
|
|
763
|
-
if (spinnerSpinning) {
|
|
764
|
-
cli.spinner.stop();
|
|
765
|
-
}
|
|
766
776
|
if (message) {
|
|
767
777
|
console.log(message, ...optionalParams);
|
|
768
778
|
}
|
|
769
779
|
else {
|
|
770
780
|
console.log();
|
|
771
781
|
}
|
|
772
|
-
// Restart the spinner if it was running before the log
|
|
773
|
-
/* c8 ignore next 3 */
|
|
774
|
-
if (spinnerSpinning) {
|
|
775
|
-
cli.spinner.start();
|
|
776
|
-
}
|
|
777
782
|
}
|
|
778
783
|
async function error(message, ...optionalParams) {
|
|
779
|
-
const spinnerSpinning = cli.spinner.isSpinning;
|
|
780
|
-
/* c8 ignore next 3 */
|
|
781
|
-
if (spinnerSpinning) {
|
|
782
|
-
cli.spinner.stop();
|
|
783
|
-
}
|
|
784
784
|
const errorOutput = cli.getSettingWithDefaultValue(settingsNames.errorOutput, 'stderr');
|
|
785
785
|
if (errorOutput === 'stdout') {
|
|
786
786
|
console.log(message, ...optionalParams);
|
|
@@ -788,40 +788,15 @@ async function error(message, ...optionalParams) {
|
|
|
788
788
|
else {
|
|
789
789
|
console.error(message, ...optionalParams);
|
|
790
790
|
}
|
|
791
|
-
// Restart the spinner if it was running before the log
|
|
792
|
-
/* c8 ignore next 3 */
|
|
793
|
-
if (spinnerSpinning) {
|
|
794
|
-
cli.spinner.start();
|
|
795
|
-
}
|
|
796
791
|
}
|
|
797
792
|
async function promptForSelection(config) {
|
|
798
|
-
const spinnerSpinning = cli.spinner.isSpinning;
|
|
799
|
-
/* c8 ignore next 3 */
|
|
800
|
-
if (spinnerSpinning) {
|
|
801
|
-
cli.spinner.stop();
|
|
802
|
-
}
|
|
803
793
|
const answer = await prompt.forSelection(config);
|
|
804
794
|
await cli.error('');
|
|
805
|
-
// Restart the spinner if it was running before the prompt
|
|
806
|
-
/* c8 ignore next 3 */
|
|
807
|
-
if (spinnerSpinning) {
|
|
808
|
-
cli.spinner.start();
|
|
809
|
-
}
|
|
810
795
|
return answer;
|
|
811
796
|
}
|
|
812
797
|
async function promptForConfirmation(config) {
|
|
813
|
-
const spinnerSpinning = cli.spinner.isSpinning;
|
|
814
|
-
/* c8 ignore next 3 */
|
|
815
|
-
if (spinnerSpinning) {
|
|
816
|
-
cli.spinner.stop();
|
|
817
|
-
}
|
|
818
798
|
const answer = await prompt.forConfirmation(config);
|
|
819
799
|
await cli.error('');
|
|
820
|
-
// Restart the spinner if it was running before the prompt
|
|
821
|
-
/* c8 ignore next 3 */
|
|
822
|
-
if (spinnerSpinning) {
|
|
823
|
-
cli.spinner.start();
|
|
824
|
-
}
|
|
825
800
|
return answer;
|
|
826
801
|
}
|
|
827
802
|
async function handleMultipleResultsFound(message, values) {
|
|
@@ -834,13 +809,6 @@ async function handleMultipleResultsFound(message, values) {
|
|
|
834
809
|
const response = await cli.promptForSelection({ message: `Please choose one:`, choices });
|
|
835
810
|
return values[response];
|
|
836
811
|
}
|
|
837
|
-
function removeShortOptions(args) {
|
|
838
|
-
const filteredArgs = JSON.parse(JSON.stringify(args));
|
|
839
|
-
const optionsToRemove = Object.getOwnPropertyNames(args.options)
|
|
840
|
-
.filter(option => option.length === 1 || option === '--');
|
|
841
|
-
optionsToRemove.forEach(option => delete filteredArgs.options[option]);
|
|
842
|
-
return filteredArgs;
|
|
843
|
-
}
|
|
844
812
|
function loadOptionValuesFromFiles(args) {
|
|
845
813
|
const optionNames = Object.getOwnPropertyNames(args.options);
|
|
846
814
|
optionNames.forEach(option => {
|
|
@@ -885,14 +853,6 @@ export const cli = {
|
|
|
885
853
|
printAvailableCommands,
|
|
886
854
|
promptForConfirmation,
|
|
887
855
|
promptForSelection,
|
|
888
|
-
shouldTrimOutput
|
|
889
|
-
spinner
|
|
890
|
-
};
|
|
891
|
-
const spinnerOptions = {
|
|
892
|
-
text: 'Running command...',
|
|
893
|
-
/* c8 ignore next 1 */
|
|
894
|
-
stream: cli.getSettingWithDefaultValue('errorOutput', 'stderr') === 'stderr' ? process.stderr : process.stdout,
|
|
895
|
-
discardStdin: false
|
|
856
|
+
shouldTrimOutput
|
|
896
857
|
};
|
|
897
|
-
cli.spinner = ora(spinnerOptions);
|
|
898
858
|
//# sourceMappingURL=cli.js.map
|
package/dist/config.js
CHANGED
|
@@ -3,7 +3,7 @@ const cliEntraAppId = '31359c7f-bd7e-475c-86db-fdb8c937548e';
|
|
|
3
3
|
export default {
|
|
4
4
|
applicationName: `CLI for Microsoft 365 v${app.packageJson().version}`,
|
|
5
5
|
delimiter: 'm365\$',
|
|
6
|
-
cliEntraAppId: process.env.CLIMICROSOFT365_ENTRAAPPID ||
|
|
6
|
+
cliEntraAppId: process.env.CLIMICROSOFT365_ENTRAAPPID || cliEntraAppId,
|
|
7
7
|
tenant: process.env.CLIMICROSOFT365_TENANT || 'common',
|
|
8
8
|
configstoreName: 'cli-m365-config'
|
|
9
9
|
};
|
|
@@ -33,12 +33,12 @@ class AppPermissionAddCommand extends AppCommand {
|
|
|
33
33
|
const appObject = await this.getAppObject();
|
|
34
34
|
const servicePrincipals = await odata.getAllItems(`${this.resource}/v1.0/myorganization/servicePrincipals?$select=appId,appRoles,id,oauth2PermissionScopes,servicePrincipalNames`);
|
|
35
35
|
const appPermissions = [];
|
|
36
|
-
if (args.options.
|
|
37
|
-
const delegatedPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.
|
|
36
|
+
if (args.options.delegatedPermissions) {
|
|
37
|
+
const delegatedPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.delegatedPermissions, ScopeType.Scope, appPermissions, logger);
|
|
38
38
|
this.addPermissionsToResourceArray(delegatedPermissions, appObject.requiredResourceAccess);
|
|
39
39
|
}
|
|
40
|
-
if (args.options.
|
|
41
|
-
const applicationPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.
|
|
40
|
+
if (args.options.applicationPermissions) {
|
|
41
|
+
const applicationPermissions = await this.getRequiredResourceAccessForApis(servicePrincipals, args.options.applicationPermissions, ScopeType.Role, appPermissions, logger);
|
|
42
42
|
this.addPermissionsToResourceArray(applicationPermissions, appObject.requiredResourceAccess);
|
|
43
43
|
}
|
|
44
44
|
const addPermissionsRequestOptions = {
|
|
@@ -198,17 +198,17 @@ _AppPermissionAddCommand_instances = new WeakSet(), _AppPermissionAddCommand_ini
|
|
|
198
198
|
this.telemetry.push((args) => {
|
|
199
199
|
Object.assign(this.telemetryProperties, {
|
|
200
200
|
appId: typeof args.options.appId !== 'undefined',
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
applicationPermissions: typeof args.options.applicationPermissions !== 'undefined',
|
|
202
|
+
delegatedPermissions: typeof args.options.delegatedPermissions !== 'undefined',
|
|
203
203
|
grantAdminConsent: !!args.options.grantAdminConsent
|
|
204
204
|
});
|
|
205
205
|
});
|
|
206
206
|
}, _AppPermissionAddCommand_initOptions = function _AppPermissionAddCommand_initOptions() {
|
|
207
|
-
this.options.unshift({ option: '--appId [appId]' }, { option: '--
|
|
207
|
+
this.options.unshift({ option: '--appId [appId]' }, { option: '--applicationPermissions [applicationPermissions]' }, { option: '--delegatedPermissions [delegatedPermissions]' }, { option: '--grantAdminConsent' });
|
|
208
208
|
}, _AppPermissionAddCommand_initOptionSets = function _AppPermissionAddCommand_initOptionSets() {
|
|
209
209
|
this.optionSets.push({
|
|
210
|
-
options: ['
|
|
211
|
-
runsWhen: (args) => args.options.
|
|
210
|
+
options: ['applicationPermissions', 'delegatedPermissions'],
|
|
211
|
+
runsWhen: (args) => args.options.delegatedPermissions === undefined && args.options.applicationPermissions === undefined
|
|
212
212
|
});
|
|
213
213
|
};
|
|
214
214
|
export default new AppPermissionAddCommand();
|