@pnp/cli-microsoft365 11.7.0 → 11.8.0-beta.ae98113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/allCommands.json +1 -1
- package/allCommandsFull.json +1 -1
- package/dist/m365/outlook/commands/calendargroup/calendargroup-remove.js +98 -0
- package/dist/m365/outlook/commands.js +1 -0
- package/dist/m365/spfx/commands/project/DeployWorkflow.js +9 -5
- package/dist/m365/spfx/commands/project/project-azuredevops-pipeline-add.js +10 -9
- package/dist/m365/spfx/commands/project/project-github-workflow-add.js +12 -10
- package/docs/docs/cmd/outlook/calendargroup/calendargroup-remove.mdx +91 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { globalOptionsZod } from '../../../../Command.js';
|
|
3
|
+
import GraphCommand from '../../../base/GraphCommand.js';
|
|
4
|
+
import { cli } from '../../../../cli/cli.js';
|
|
5
|
+
import commands from '../../commands.js';
|
|
6
|
+
import { validation } from '../../../../utils/validation.js';
|
|
7
|
+
import { accessToken } from '../../../../utils/accessToken.js';
|
|
8
|
+
import auth from '../../../../Auth.js';
|
|
9
|
+
import request from '../../../../request.js';
|
|
10
|
+
import { formatting } from '../../../../utils/formatting.js';
|
|
11
|
+
import { calendarGroup } from '../../../../utils/calendarGroup.js';
|
|
12
|
+
export const options = z.strictObject({
|
|
13
|
+
...globalOptionsZod.shape,
|
|
14
|
+
id: z.string().optional(),
|
|
15
|
+
name: z.string().optional(),
|
|
16
|
+
userId: z.string().refine(id => validation.isValidGuid(id), {
|
|
17
|
+
error: e => `'${e.input}' is not a valid GUID.`
|
|
18
|
+
}).optional(),
|
|
19
|
+
userName: z.string().refine(name => validation.isValidUserPrincipalName(name), {
|
|
20
|
+
error: e => `'${e.input}' is not a valid UPN.`
|
|
21
|
+
}).optional(),
|
|
22
|
+
force: z.boolean().optional().alias('f')
|
|
23
|
+
});
|
|
24
|
+
class OutlookCalendarGroupRemoveCommand extends GraphCommand {
|
|
25
|
+
get name() {
|
|
26
|
+
return commands.CALENDARGROUP_REMOVE;
|
|
27
|
+
}
|
|
28
|
+
get description() {
|
|
29
|
+
return 'Removes a calendar group';
|
|
30
|
+
}
|
|
31
|
+
get schema() {
|
|
32
|
+
return options;
|
|
33
|
+
}
|
|
34
|
+
getRefinedSchema(schema) {
|
|
35
|
+
return schema
|
|
36
|
+
.refine(options => options.id || options.name, {
|
|
37
|
+
error: 'Specify either id or name.'
|
|
38
|
+
})
|
|
39
|
+
.refine(options => !(options.id && options.name), {
|
|
40
|
+
error: 'Specify either id or name, but not both.'
|
|
41
|
+
})
|
|
42
|
+
.refine(options => !(options.userId && options.userName), {
|
|
43
|
+
error: 'Specify either userId or userName, but not both.'
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async commandAction(logger, args) {
|
|
47
|
+
const removeCalendarGroup = async () => {
|
|
48
|
+
try {
|
|
49
|
+
const token = auth.connection.accessTokens[auth.defaultResource].accessToken;
|
|
50
|
+
const isAppOnlyAccessToken = accessToken.isAppOnlyAccessToken(token);
|
|
51
|
+
if (isAppOnlyAccessToken && !args.options.userId && !args.options.userName) {
|
|
52
|
+
throw 'When running with application permissions either userId or userName is required.';
|
|
53
|
+
}
|
|
54
|
+
let endpoint;
|
|
55
|
+
let graphUserId;
|
|
56
|
+
if (args.options.userId || args.options.userName) {
|
|
57
|
+
graphUserId = (args.options.userId ?? args.options.userName);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
graphUserId = accessToken.getUserIdFromAccessToken(token);
|
|
61
|
+
}
|
|
62
|
+
endpoint = `${this.resource}/v1.0/users('${formatting.encodeQueryParameter(graphUserId)}')`;
|
|
63
|
+
let calendarGroupId = args.options.id;
|
|
64
|
+
if (args.options.name) {
|
|
65
|
+
if (this.verbose) {
|
|
66
|
+
await logger.logToStderr(`Retrieving calendar group by name '${args.options.name}'...`);
|
|
67
|
+
}
|
|
68
|
+
const calendarGroupResult = await calendarGroup.getUserCalendarGroupByName(graphUserId, args.options.name);
|
|
69
|
+
calendarGroupId = calendarGroupResult.id;
|
|
70
|
+
}
|
|
71
|
+
if (this.verbose) {
|
|
72
|
+
await logger.logToStderr(`Removing calendar group '${calendarGroupId}'...`);
|
|
73
|
+
}
|
|
74
|
+
const requestOptions = {
|
|
75
|
+
url: `${endpoint}/calendarGroups/${calendarGroupId}`,
|
|
76
|
+
headers: {
|
|
77
|
+
accept: 'application/json;odata.metadata=none'
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
await request.delete(requestOptions);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
this.handleRejectedODataJsonPromise(err);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (args.options.force) {
|
|
87
|
+
await removeCalendarGroup();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove calendar group '${args.options.id || args.options.name}'?` });
|
|
91
|
+
if (result) {
|
|
92
|
+
await removeCalendarGroup();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export default new OutlookCalendarGroupRemoveCommand();
|
|
98
|
+
//# sourceMappingURL=calendargroup-remove.js.map
|
|
@@ -6,6 +6,7 @@ export default {
|
|
|
6
6
|
CALENDAR_SET: `${prefix} calendar set`,
|
|
7
7
|
CALENDARGROUP_GET: `${prefix} calendargroup get`,
|
|
8
8
|
CALENDARGROUP_LIST: `${prefix} calendargroup list`,
|
|
9
|
+
CALENDARGROUP_REMOVE: `${prefix} calendargroup remove`,
|
|
9
10
|
CALENDARGROUP_SET: `${prefix} calendargroup set`,
|
|
10
11
|
EVENT_CANCEL: `${prefix} event cancel`,
|
|
11
12
|
EVENT_LIST: `${prefix} event list`,
|
|
@@ -16,11 +16,11 @@ export const workflow = {
|
|
|
16
16
|
steps: [
|
|
17
17
|
{
|
|
18
18
|
name: "Checkout",
|
|
19
|
-
uses: "actions/checkout@
|
|
19
|
+
uses: "actions/checkout@v6"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
name: "Use Node.js",
|
|
23
|
-
uses: "actions/setup-node@
|
|
23
|
+
uses: "actions/setup-node@v6",
|
|
24
24
|
with: {
|
|
25
25
|
"node-version": "${{ env.NodeVersion }}"
|
|
26
26
|
}
|
|
@@ -35,7 +35,7 @@ export const workflow = {
|
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
name: "CLI for Microsoft 365 Login",
|
|
38
|
-
uses: "pnp/action-cli-login@
|
|
38
|
+
uses: "pnp/action-cli-login@v4",
|
|
39
39
|
with: {
|
|
40
40
|
"CERTIFICATE_ENCODED": "${{ secrets.CERTIFICATE_ENCODED }}",
|
|
41
41
|
"CERTIFICATE_PASSWORD": "${{ secrets.CERTIFICATE_PASSWORD }}",
|
|
@@ -45,9 +45,9 @@ export const workflow = {
|
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
name: "CLI for Microsoft 365 Deploy App",
|
|
48
|
-
uses: "pnp/action-cli-deploy@
|
|
48
|
+
uses: "pnp/action-cli-deploy@v6",
|
|
49
49
|
with: {
|
|
50
|
-
"APP_FILE_PATH": "sharepoint/
|
|
50
|
+
"APP_FILE_PATH": "sharepoint/{{ sppkgPath }}",
|
|
51
51
|
"SKIP_FEATURE_DEPLOYMENT": false,
|
|
52
52
|
"OVERWRITE": true
|
|
53
53
|
}
|
|
@@ -105,6 +105,10 @@ export const pipeline = {
|
|
|
105
105
|
name: "PackageName",
|
|
106
106
|
value: ""
|
|
107
107
|
},
|
|
108
|
+
{
|
|
109
|
+
name: "SppkgPath",
|
|
110
|
+
value: ""
|
|
111
|
+
},
|
|
108
112
|
{
|
|
109
113
|
name: "SiteAppCatalogUrl",
|
|
110
114
|
value: ""
|
|
@@ -34,14 +34,14 @@ class SpfxProjectAzureDevOpsPipelineAddCommand extends BaseProjectCommand {
|
|
|
34
34
|
if (this.projectRootPath === null) {
|
|
35
35
|
throw new CommandError(`Couldn't find project root folder`, _a.ERROR_NO_PROJECT_ROOT_FOLDER);
|
|
36
36
|
}
|
|
37
|
-
const solutionPackageJsonFile = path.join(this.projectRootPath, 'package.json');
|
|
38
|
-
const packageJson = fs.readFileSync(solutionPackageJsonFile, 'utf-8');
|
|
39
|
-
const solutionName = JSON.parse(packageJson).name;
|
|
40
37
|
if (this.debug) {
|
|
41
38
|
await logger.logToStderr(`Adding Azure DevOps pipeline in the current SPFx project`);
|
|
42
39
|
}
|
|
43
40
|
try {
|
|
44
|
-
this.
|
|
41
|
+
const project = { path: this.projectRootPath };
|
|
42
|
+
this.readAndParseJsonFile(path.join(this.projectRootPath, 'config', 'package-solution.json'), project, 'packageSolutionJson');
|
|
43
|
+
const sppkgPath = project.packageSolutionJson?.paths?.zippedPackage;
|
|
44
|
+
this.updatePipeline(sppkgPath, pipeline, args.options);
|
|
45
45
|
this.savePipeline(pipeline);
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
@@ -56,7 +56,7 @@ class SpfxProjectAzureDevOpsPipelineAddCommand extends BaseProjectCommand {
|
|
|
56
56
|
const pipelineFile = path.join(pipelinesPath, 'deploy-spfx-solution.yml');
|
|
57
57
|
fs.writeFileSync(path.resolve(pipelineFile), yaml.stringify(pipeline), 'utf-8');
|
|
58
58
|
}
|
|
59
|
-
updatePipeline(
|
|
59
|
+
updatePipeline(sppkgPath, pipeline, options) {
|
|
60
60
|
if (options.name) {
|
|
61
61
|
pipeline.name = options.name;
|
|
62
62
|
}
|
|
@@ -93,16 +93,17 @@ class SpfxProjectAzureDevOpsPipelineAddCommand extends BaseProjectCommand {
|
|
|
93
93
|
}
|
|
94
94
|
if (options.scope === 'sitecollection') {
|
|
95
95
|
script.script = script.script.replace(`{{deploy}}`, `m365 spo app deploy --name '$(PackageName)' --appCatalogScope sitecollection --appCatalogUrl '$(SiteAppCatalogUrl)'`);
|
|
96
|
-
script.script = script.script.replace(`{{addApp}}`, `m365 spo app add --filePath '$(Build.SourcesDirectory)/sharepoint
|
|
96
|
+
script.script = script.script.replace(`{{addApp}}`, `m365 spo app add --filePath '$(Build.SourcesDirectory)/sharepoint/$(SppkgPath)' --appCatalogScope sitecollection --appCatalogUrl '$(SiteAppCatalogUrl)' --overwrite`);
|
|
97
97
|
this.assignPipelineVariables(pipeline, 'SiteAppCatalogUrl', options.siteUrl);
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
script.script = script.script.replace(`{{deploy}}`, `m365 spo app deploy --name '$(PackageName)' --appCatalogScope 'tenant'`);
|
|
101
|
-
script.script = script.script.replace(`{{addApp}}`, `m365 spo app add --filePath '$(Build.SourcesDirectory)/sharepoint
|
|
101
|
+
script.script = script.script.replace(`{{addApp}}`, `m365 spo app add --filePath '$(Build.SourcesDirectory)/sharepoint/$(SppkgPath)' --overwrite`);
|
|
102
102
|
pipeline.variables = pipeline.variables.filter(v => v.name !== 'SiteAppCatalogUrl');
|
|
103
103
|
}
|
|
104
|
-
if (
|
|
105
|
-
this.assignPipelineVariables(pipeline, '
|
|
104
|
+
if (sppkgPath) {
|
|
105
|
+
this.assignPipelineVariables(pipeline, 'SppkgPath', sppkgPath);
|
|
106
|
+
this.assignPipelineVariables(pipeline, 'PackageName', path.basename(sppkgPath));
|
|
106
107
|
}
|
|
107
108
|
if (options.skipFeatureDeployment) {
|
|
108
109
|
script.script = script.script.replace(`m365 spo app deploy `, `m365 spo app deploy --skipFeatureDeployment `);
|
|
@@ -34,14 +34,16 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand {
|
|
|
34
34
|
if (this.projectRootPath === null) {
|
|
35
35
|
throw new CommandError(`Couldn't find project root folder`, _a.ERROR_NO_PROJECT_ROOT_FOLDER);
|
|
36
36
|
}
|
|
37
|
-
const solutionPackageJsonFile = path.join(this.projectRootPath, 'package.json');
|
|
38
|
-
const packageJson = fs.readFileSync(solutionPackageJsonFile, 'utf-8');
|
|
39
|
-
const solutionName = JSON.parse(packageJson).name;
|
|
40
|
-
if (this.debug) {
|
|
41
|
-
await logger.logToStderr(`Adding GitHub workflow in the current SPFx project`);
|
|
42
|
-
}
|
|
43
37
|
try {
|
|
44
|
-
this.
|
|
38
|
+
const project = { path: this.projectRootPath };
|
|
39
|
+
this.readAndParseJsonFile(path.join(this.projectRootPath, 'package.json'), project, 'packageJson');
|
|
40
|
+
this.readAndParseJsonFile(path.join(this.projectRootPath, 'config', 'package-solution.json'), project, 'packageSolutionJson');
|
|
41
|
+
const solutionName = project.packageJson.name;
|
|
42
|
+
const sppkgPath = project.packageSolutionJson?.paths?.zippedPackage;
|
|
43
|
+
if (this.debug) {
|
|
44
|
+
await logger.logToStderr(`Adding GitHub workflow in the current SPFx project`);
|
|
45
|
+
}
|
|
46
|
+
this.updateWorkflow(solutionName, sppkgPath, workflow, args.options);
|
|
45
47
|
this.saveWorkflow(workflow);
|
|
46
48
|
}
|
|
47
49
|
catch (error) {
|
|
@@ -56,7 +58,7 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand {
|
|
|
56
58
|
const workflowFile = path.join(workflowPath, 'deploy-spfx-solution.yml');
|
|
57
59
|
fs.writeFileSync(path.resolve(workflowFile), yaml.stringify(workflow), 'utf-8');
|
|
58
60
|
}
|
|
59
|
-
updateWorkflow(solutionName, workflow, options) {
|
|
61
|
+
updateWorkflow(solutionName, sppkgPath, workflow, options) {
|
|
60
62
|
workflow.name = options.name ? options.name : workflow.name.replace('{{ name }}', solutionName);
|
|
61
63
|
if (options.branchName) {
|
|
62
64
|
workflow.on.push.branches[0] = options.branchName;
|
|
@@ -90,9 +92,9 @@ class SpfxProjectGithubWorkflowAddCommand extends BaseProjectCommand {
|
|
|
90
92
|
deployAction.with.SCOPE = 'sitecollection';
|
|
91
93
|
deployAction.with.SITE_COLLECTION_URL = options.siteUrl;
|
|
92
94
|
}
|
|
93
|
-
if (
|
|
95
|
+
if (sppkgPath) {
|
|
94
96
|
const deployAction = this.getDeployAction(workflow);
|
|
95
|
-
deployAction.with.APP_FILE_PATH = deployAction.with.APP_FILE_PATH.replace('{{
|
|
97
|
+
deployAction.with.APP_FILE_PATH = deployAction.with.APP_FILE_PATH.replace('{{ sppkgPath }}', sppkgPath);
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
assignNodeVersion(workflow, nodeVersion) {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Global from '../../_global.mdx';
|
|
2
|
+
import Tabs from '@theme/Tabs';
|
|
3
|
+
import TabItem from '@theme/TabItem';
|
|
4
|
+
|
|
5
|
+
# outlook calendargroup remove
|
|
6
|
+
|
|
7
|
+
Removes a calendar group.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
m365 outlook calendargroup remove [options]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Options
|
|
16
|
+
|
|
17
|
+
```md definition-list
|
|
18
|
+
`--id [id]`
|
|
19
|
+
: ID of the calendar group to remove. Specify either `id` or `name`, but not both.
|
|
20
|
+
|
|
21
|
+
`--name [name]`
|
|
22
|
+
: Name of the calendar group to remove. Specify either `id` or `name`, but not both.
|
|
23
|
+
|
|
24
|
+
`--userId [userId]`
|
|
25
|
+
: ID of the user. Specify either `userId` or `userName`, but not both. This option is required when using application permissions.
|
|
26
|
+
|
|
27
|
+
`--userName [userName]`
|
|
28
|
+
: UPN of the user. Specify either `userId` or `userName`, but not both. This option is required when using application permissions.
|
|
29
|
+
|
|
30
|
+
`-f, --force`
|
|
31
|
+
: Don't prompt for confirmation.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
<Global />
|
|
35
|
+
|
|
36
|
+
## Permissions
|
|
37
|
+
|
|
38
|
+
<Tabs>
|
|
39
|
+
<TabItem value="Delegated">
|
|
40
|
+
|
|
41
|
+
| Resource | Permissions |
|
|
42
|
+
|-----------------|----------------------|
|
|
43
|
+
| Microsoft Graph | Calendars.ReadWrite |
|
|
44
|
+
|
|
45
|
+
</TabItem>
|
|
46
|
+
<TabItem value="Application">
|
|
47
|
+
|
|
48
|
+
| Resource | Permissions |
|
|
49
|
+
|-----------------|----------------------|
|
|
50
|
+
| Microsoft Graph | Calendars.ReadWrite |
|
|
51
|
+
|
|
52
|
+
</TabItem>
|
|
53
|
+
</Tabs>
|
|
54
|
+
|
|
55
|
+
## Remarks
|
|
56
|
+
|
|
57
|
+
:::warning
|
|
58
|
+
|
|
59
|
+
The calendar group must be empty before it can be removed. Make sure to delete all calendars in the group first.
|
|
60
|
+
|
|
61
|
+
:::
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
Remove a calendar group specified by id for the signed-in user.
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
m365 outlook calendargroup remove --id "AAMkAGE0MGM1Y2M5LWEzMmUtNGVlNy05MjRlLTk0YmYyY2I5NTM3ZAAuAAAAAAC_0WfqSjt_SqLtNkuO-bj1AQAbfYq5lmBxQ6a4t1fGbeYAAAAAAEOAAA="
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Remove a calendar group specified by name for the signed-in user.
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
m365 outlook calendargroup remove --name "Personal Events"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Remove a calendar group specified by id for a user specified by id.
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
m365 outlook calendargroup remove --id "AAMkADIxYjJiYm" --userId "44288f7d-7710-4293-8c8e-36f310ed2e6a"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Remove a calendar group specified by name for a user specified by UPN without prompting for confirmation.
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
m365 outlook calendargroup remove --name "Personal Events" --userName "john.doe@contoso.com" --force
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Response
|
|
90
|
+
|
|
91
|
+
The command won't return a response on success.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnp/cli-microsoft365",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.8.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@pnp/cli-microsoft365",
|
|
9
|
-
"version": "11.
|
|
9
|
+
"version": "11.8.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@azure/msal-common": "^16.4.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnp/cli-microsoft365",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.8.0-beta.ae98113",
|
|
4
4
|
"description": "Manage Microsoft 365 and SharePoint Framework projects on any platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/api.js",
|
|
@@ -341,4 +341,4 @@
|
|
|
341
341
|
"source-map-support": "^0.5.21",
|
|
342
342
|
"tsc-watch": "^7.2.0"
|
|
343
343
|
}
|
|
344
|
-
}
|
|
344
|
+
}
|