@pnp/cli-microsoft365 11.8.0-beta.52da392 → 11.8.0-beta.6d1d954

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.
@@ -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@v4"
19
+ uses: "actions/checkout@v6"
20
20
  },
21
21
  {
22
22
  name: "Use Node.js",
23
- uses: "actions/setup-node@v4",
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@v2.2.4",
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@v4.0.0",
48
+ uses: "pnp/action-cli-deploy@v6",
49
49
  with: {
50
- "APP_FILE_PATH": "sharepoint/solution/{{ solutionName }}.sppkg",
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.updatePipeline(solutionName, pipeline, args.options);
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(solutionName, pipeline, options) {
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/solution/$(PackageName)' --appCatalogScope sitecollection --appCatalogUrl '$(SiteAppCatalogUrl)' --overwrite`);
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/solution/$(PackageName)' --overwrite`);
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 (solutionName) {
105
- this.assignPipelineVariables(pipeline, 'PackageName', `${solutionName}.sppkg`);
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 `);
@@ -308,6 +308,8 @@ ${f.resolution}
308
308
  const packagesDepExact = [];
309
309
  const packagesDepUn = [];
310
310
  const packagesDevUn = [];
311
+ const packagesOverride = [];
312
+ const packagesOverrideRemove = [];
311
313
  findings.forEach(f => {
312
314
  packageManager.mapPackageManagerCommand({
313
315
  command: f.resolution,
@@ -315,6 +317,8 @@ ${f.resolution}
315
317
  packagesDepExact,
316
318
  packagesDepUn,
317
319
  packagesDevUn,
320
+ packagesOverride,
321
+ packagesOverrideRemove,
318
322
  packageMgr: this.packageManager
319
323
  });
320
324
  });
@@ -323,6 +327,8 @@ ${f.resolution}
323
327
  packagesDevExact,
324
328
  packagesDepUn,
325
329
  packagesDevUn,
330
+ packagesOverride,
331
+ packagesOverrideRemove,
326
332
  packageMgr: this.packageManager
327
333
  });
328
334
  if (this.packageManager === 'npm') {
@@ -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.updateWorkflow(solutionName, workflow, args.options);
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 (solutionName) {
95
+ if (sppkgPath) {
94
96
  const deployAction = this.getDeployAction(workflow);
95
- deployAction.with.APP_FILE_PATH = deployAction.with.APP_FILE_PATH.replace('{{ solutionName }}', solutionName);
97
+ deployAction.with.APP_FILE_PATH = deployAction.with.APP_FILE_PATH.replace('{{ sppkgPath }}', sppkgPath);
96
98
  }
97
99
  }
98
100
  assignNodeVersion(workflow, nodeVersion) {
@@ -7,7 +7,7 @@ var _DependencyRule_instances, _DependencyRule_needsUpdate, _DependencyRule_getM
7
7
  import semver from 'semver';
8
8
  import { JsonRule } from '../../JsonRule.js';
9
9
  export class DependencyRule extends JsonRule {
10
- constructor(packageName, packageVersion, isDevDep = false, isOptional = false, add = true) {
10
+ constructor(packageName, packageVersion, isDevDep = false, isOptional = false, add = true, isOverride = false) {
11
11
  super();
12
12
  _DependencyRule_instances.add(this);
13
13
  this.packageName = packageName;
@@ -15,14 +15,20 @@ export class DependencyRule extends JsonRule {
15
15
  this.isDevDep = isDevDep;
16
16
  this.isOptional = isOptional;
17
17
  this.add = add;
18
+ this.isOverride = isOverride;
18
19
  }
19
20
  get title() {
20
21
  return this.packageName;
21
22
  }
22
23
  get description() {
23
- return `${(this.add ? 'Upgrade' : 'Remove')} SharePoint Framework ${(this.isDevDep ? 'dev ' : '')}dependency package ${this.packageName}`;
24
+ return `${(this.add ? 'Upgrade' : 'Remove')} SharePoint Framework ${(this.isOverride ? 'override ' : this.isDevDep ? 'dev ' : '')}dependency package ${this.packageName}`;
24
25
  }
25
26
  get resolution() {
27
+ if (this.isOverride) {
28
+ return this.add ?
29
+ `override overrides.${this.packageName}=${this.packageVersion}` :
30
+ `removeOverride overrides.${this.packageName}`;
31
+ }
26
32
  return this.add ?
27
33
  `${(this.isDevDep ? 'installDev' : 'install')} ${this.packageName}@${this.packageVersion}` :
28
34
  `${(this.isDevDep ? 'uninstallDev' : 'uninstall')} ${this.packageName}`;
@@ -44,10 +50,10 @@ export class DependencyRule extends JsonRule {
44
50
  if (!project.packageJson) {
45
51
  return;
46
52
  }
47
- const projectDependencies = this.isDevDep ? project.packageJson.devDependencies : project.packageJson.dependencies;
53
+ const projectDependencies = this.isOverride ? project.packageJson.overrides : this.isDevDep ? project.packageJson.devDependencies : project.packageJson.dependencies;
48
54
  const versionEntry = projectDependencies ? projectDependencies[this.packageName] : '';
49
55
  if (this.add) {
50
- let jsonProperty = this.isDevDep ? 'devDependencies' : 'dependencies';
56
+ let jsonProperty = this.isOverride ? 'overrides' : this.isDevDep ? 'devDependencies' : 'dependencies';
51
57
  if (versionEntry) {
52
58
  jsonProperty += `.${this.packageName}`;
53
59
  if (__classPrivateFieldGet(this, _DependencyRule_instances, "m", _DependencyRule_needsUpdate).call(this, this.packageVersion, versionEntry)) {
@@ -67,7 +73,7 @@ export class DependencyRule extends JsonRule {
67
73
  }
68
74
  }
69
75
  else {
70
- const jsonProperty = `${(this.isDevDep ? 'devDependencies' : 'dependencies')}.${this.packageName}`;
76
+ const jsonProperty = `${(this.isOverride ? 'overrides' : this.isDevDep ? 'devDependencies' : 'dependencies')}.${this.packageName}`;
71
77
  if (versionEntry) {
72
78
  const node = this.getAstNodeFromFile(project.packageJson, jsonProperty);
73
79
  this.addFindingWithPosition(findings, node);
@@ -0,0 +1,10 @@
1
+ import { DependencyRule } from "./DependencyRule.js";
2
+ export class FN027001_OVERRIDES_rushstack_heft extends DependencyRule {
3
+ constructor(version) {
4
+ super('@rushstack/heft', version, false, false, true, true);
5
+ }
6
+ get id() {
7
+ return 'FN027001';
8
+ }
9
+ }
10
+ //# sourceMappingURL=FN027001_OVERRIDES_rushstack_heft.js.map
@@ -48,7 +48,7 @@ import { FN021005_PKG_scripts_test } from './rules/FN021005_PKG_scripts_test.js'
48
48
  import { FN021006_PKG_scripts_clean } from './rules/FN021006_PKG_scripts_clean.js';
49
49
  import { FN021007_PKG_scripts_start } from './rules/FN021007_PKG_scripts_start.js';
50
50
  import { FN021008_PKG_scripts_eject_webpack } from './rules/FN021008_PKG_scripts_eject_webpack.js';
51
- import { FN021009_PKG_overrides_rushstack_heft } from './rules/FN021009_PKG_overrides_rushstack_heft.js';
51
+ import { FN027001_OVERRIDES_rushstack_heft } from './rules/FN027001_OVERRIDES_rushstack_heft.js';
52
52
  import { FN023003_GITIGNORE_libdts } from './rules/FN023003_GITIGNORE_libdts.js';
53
53
  import { FN023004_GITIGNORE_libcommonjs } from './rules/FN023004_GITIGNORE_libcommonjs.js';
54
54
  import { FN023005_GITIGNORE_libesm } from './rules/FN023005_GITIGNORE_libesm.js';
@@ -151,7 +151,7 @@ export default [
151
151
  new FN021006_PKG_scripts_clean('heft clean'),
152
152
  new FN021007_PKG_scripts_start('heft start --clean'),
153
153
  new FN021008_PKG_scripts_eject_webpack('heft eject-webpack'),
154
- new FN021009_PKG_overrides_rushstack_heft('1.1.2'),
154
+ new FN027001_OVERRIDES_rushstack_heft('1.1.2'),
155
155
  new FN023003_GITIGNORE_libdts(),
156
156
  new FN023004_GITIGNORE_libcommonjs(),
157
157
  new FN023005_GITIGNORE_libesm(),
@@ -31,7 +31,7 @@ import { FN002034_DEVDEP_microsoft_spfx_heft_plugins } from './rules/FN002034_DE
31
31
  import { FN010001_YORC_version } from './rules/FN010001_YORC_version.js';
32
32
  import { FN015008_FILE_eslintrc_js } from './rules/FN015008_FILE_eslintrc_js.js';
33
33
  import { FN015016_FILE_eslint_config_js } from './rules/FN015016_FILE_eslint_config_js.js';
34
- import { FN021009_PKG_overrides_rushstack_heft } from './rules/FN021009_PKG_overrides_rushstack_heft.js';
34
+ import { FN027001_OVERRIDES_rushstack_heft } from './rules/FN027001_OVERRIDES_rushstack_heft.js';
35
35
  export default [
36
36
  new FN001001_DEP_microsoft_sp_core_library('1.23.0-rc.0'),
37
37
  new FN001002_DEP_microsoft_sp_lodash_subset('1.23.0-rc.0'),
@@ -60,7 +60,7 @@ export default [
60
60
  new FN002034_DEVDEP_microsoft_spfx_heft_plugins('1.23.0-rc.0'),
61
61
  new FN010001_YORC_version('1.23.0-rc.0'),
62
62
  new FN002031_DEVDEP_rushstack_heft('1.2.7'),
63
- new FN021009_PKG_overrides_rushstack_heft('1.2.7'),
63
+ new FN027001_OVERRIDES_rushstack_heft('1.2.7'),
64
64
  new FN002025_DEVDEP_eslint_plugin_react_hooks('5.2.0'),
65
65
  new FN002024_DEVDEP_eslint('9.37.0'),
66
66
  new FN015016_FILE_eslint_config_js(true, `const spfxProfile = require('@microsoft/eslint-config-spfx/lib/flat-profiles/react');
@@ -12,7 +12,7 @@ import { BaseProjectCommand } from './base-project-command.js';
12
12
  import { FN017001_MISC_npm_dedupe } from './project-upgrade/rules/FN017001_MISC_npm_dedupe.js';
13
13
  export const options = z.strictObject({
14
14
  ...globalOptionsZod.shape,
15
- packageManager: z.enum(['npm', 'pnpm', 'yarn']).default('npm'),
15
+ packageManager: z.enum(['npm', 'pnpm']).default('npm'),
16
16
  preview: z.boolean().optional(),
17
17
  toVersion: z.string().optional().alias('v'),
18
18
  shell: z.enum(['bash', 'powershell', 'cmd']).default('powershell'),
@@ -201,7 +201,15 @@ class SpfxProjectUpgradeCommand extends BaseProjectCommand {
201
201
  // replace package operation tokens with command for the specific package manager
202
202
  findingsToReport.forEach(f => {
203
203
  // matches must be in this particular order to avoid false matches, eg.
204
- // uninstallDev contains install
204
+ // uninstallDev contains install, removeOverride contains override
205
+ if (f.resolution.startsWith('removeOverride')) {
206
+ f.resolution = f.resolution.replace('removeOverride', packageManager.getPackageManagerCommand('removeOverride', this.packageManager));
207
+ return;
208
+ }
209
+ if (f.resolution.startsWith('override')) {
210
+ f.resolution = f.resolution.replace('override', packageManager.getPackageManagerCommand('override', this.packageManager));
211
+ return;
212
+ }
205
213
  if (f.resolution.startsWith('uninstallDev')) {
206
214
  f.resolution = f.resolution.replace('uninstallDev', packageManager.getPackageManagerCommand('uninstallDev', this.packageManager));
207
215
  return;
@@ -296,7 +304,9 @@ class SpfxProjectUpgradeCommand extends BaseProjectCommand {
296
304
  .filter((command) => command.indexOf(packageManager.getPackageManagerCommand('install', this.packageManager)) === -1 &&
297
305
  command.indexOf(packageManager.getPackageManagerCommand('installDev', this.packageManager)) === -1 &&
298
306
  command.indexOf(packageManager.getPackageManagerCommand('uninstall', this.packageManager)) === -1 &&
299
- command.indexOf(packageManager.getPackageManagerCommand('uninstallDev', this.packageManager)) === -1))).join(os.EOL), os.EOL,
307
+ command.indexOf(packageManager.getPackageManagerCommand('uninstallDev', this.packageManager)) === -1 &&
308
+ command.indexOf(packageManager.getPackageManagerCommand('override', this.packageManager)) === -1 &&
309
+ command.indexOf(packageManager.getPackageManagerCommand('removeOverride', this.packageManager)) === -1))).join(os.EOL), os.EOL,
300
310
  os.EOL,
301
311
  Object.keys(reportData.modificationPerFile).map(file => {
302
312
  return [
@@ -356,7 +366,9 @@ ${f.resolution}
356
366
  .filter((command) => command.indexOf(packageManager.getPackageManagerCommand('install', this.packageManager)) === -1 &&
357
367
  command.indexOf(packageManager.getPackageManagerCommand('installDev', this.packageManager)) === -1 &&
358
368
  command.indexOf(packageManager.getPackageManagerCommand('uninstall', this.packageManager)) === -1 &&
359
- command.indexOf(packageManager.getPackageManagerCommand('uninstallDev', this.packageManager)) === -1))).join(os.EOL), os.EOL,
369
+ command.indexOf(packageManager.getPackageManagerCommand('uninstallDev', this.packageManager)) === -1 &&
370
+ command.indexOf(packageManager.getPackageManagerCommand('override', this.packageManager)) === -1 &&
371
+ command.indexOf(packageManager.getPackageManagerCommand('removeOverride', this.packageManager)) === -1))).join(os.EOL), os.EOL,
360
372
  '```', os.EOL,
361
373
  os.EOL,
362
374
  '### Modify files', os.EOL,
@@ -433,16 +445,19 @@ ${f.resolution}
433
445
  const packagesDepExact = [];
434
446
  const packagesDepUn = [];
435
447
  const packagesDevUn = [];
448
+ const packagesOverride = [];
449
+ const packagesOverrideRemove = [];
436
450
  findings.forEach(f => {
437
451
  if (f.resolutionType === 'cmd') {
438
- if (f.resolution.indexOf('npm') > -1 ||
439
- f.resolution.indexOf('yarn') > -1) {
452
+ if (f.resolution.indexOf('npm') > -1) {
440
453
  packageManager.mapPackageManagerCommand({
441
454
  command: f.resolution,
442
455
  packagesDevExact,
443
456
  packagesDepExact,
444
457
  packagesDepUn,
445
458
  packagesDevUn,
459
+ packagesOverride,
460
+ packagesOverrideRemove,
446
461
  packageMgr: this.packageManager
447
462
  });
448
463
  }
@@ -468,6 +483,8 @@ ${f.resolution}
468
483
  packagesDevExact,
469
484
  packagesDepUn,
470
485
  packagesDevUn,
486
+ packagesOverride,
487
+ packagesOverrideRemove,
471
488
  packageMgr: this.packageManager
472
489
  });
473
490
  if (this.packageManager === 'npm') {
package/dist/request.js CHANGED
@@ -34,7 +34,7 @@ class Request {
34
34
  await this._logger.logToStderr('Response:');
35
35
  const properties = ['status', 'statusText', 'headers'];
36
36
  if (response.headers['content-type'] &&
37
- response.headers['content-type'].indexOf('json') > -1) {
37
+ response.headers['content-type'].toString().indexOf('json') > -1) {
38
38
  properties.push('data');
39
39
  }
40
40
  await this._logger.logToStderr(JSON.stringify({
@@ -3,28 +3,41 @@ const packageCommands = {
3
3
  install: 'npm i -SE',
4
4
  installDev: 'npm i -DE',
5
5
  uninstall: 'npm un -S',
6
- uninstallDev: 'npm un -D'
6
+ uninstallDev: 'npm un -D',
7
+ override: 'npm pkg set',
8
+ removeOverride: 'npm pkg delete'
7
9
  },
8
10
  pnpm: {
9
11
  install: 'pnpm i -E',
10
12
  installDev: 'pnpm i -DE',
11
13
  uninstall: 'pnpm un',
12
- uninstallDev: 'pnpm un'
14
+ uninstallDev: 'pnpm un',
15
+ override: 'pnpm pkg set',
16
+ removeOverride: 'pnpm pkg delete'
13
17
  },
14
18
  yarn: {
15
19
  install: 'yarn add -E',
16
20
  installDev: 'yarn add -DE',
17
21
  uninstall: 'yarn remove',
18
22
  uninstallDev: 'yarn remove'
23
+ // Yarn is not supported for project upgrade since their CLI does not support setting overrides.
19
24
  }
20
25
  };
21
26
  export const packageManager = {
22
27
  getPackageManagerCommand(command, packageManager) {
23
28
  return packageCommands[packageManager][command];
24
29
  },
25
- mapPackageManagerCommand({ command, packagesDepExact, packagesDevExact, packagesDepUn, packagesDevUn, packageMgr }) {
30
+ mapPackageManagerCommand({ command, packagesDepExact, packagesDevExact, packagesDepUn, packagesDevUn, packagesOverride, packagesOverrideRemove, packageMgr }) {
26
31
  // matches must be in this particular order to avoid false matches, eg.
27
- // uninstallDev contains install
32
+ // uninstallDev contains install, removeOverride contains override
33
+ if (command.startsWith(`${packageManager.getPackageManagerCommand('removeOverride', packageMgr)} `)) {
34
+ packagesOverrideRemove.push(command.replace(packageManager.getPackageManagerCommand('removeOverride', packageMgr), '').trim());
35
+ return;
36
+ }
37
+ if (command.startsWith(`${packageManager.getPackageManagerCommand('override', packageMgr)} `)) {
38
+ packagesOverride.push(command.replace(packageManager.getPackageManagerCommand('override', packageMgr), '').trim());
39
+ return;
40
+ }
28
41
  if (command.startsWith(`${packageManager.getPackageManagerCommand('uninstallDev', packageMgr)} `)) {
29
42
  packagesDevUn.push(command.replace(packageManager.getPackageManagerCommand('uninstallDev', packageMgr), '').trim());
30
43
  return;
@@ -41,10 +54,19 @@ export const packageManager = {
41
54
  packagesDepExact.push(command.replace(packageManager.getPackageManagerCommand('install', packageMgr), '').trim());
42
55
  }
43
56
  },
44
- reducePackageManagerCommand({ packagesDepExact, packagesDevExact, packagesDepUn, packagesDevUn, packageMgr }) {
57
+ reducePackageManagerCommand({ packagesDepExact, packagesDevExact, packagesDepUn, packagesDevUn, packagesOverride, packagesOverrideRemove, packageMgr }) {
45
58
  const commandsToExecute = [];
46
- // uninstall commands must come first otherwise there is a chance that
47
- // whatever we recommended to install, will be immediately uninstalled
59
+ // override commands must come first to ensure that install/uninstall operations
60
+ // use the correct package version when an override is added or removed for a
61
+ // package that is being updated, installed, or uninstalled
62
+ // uninstall commands must come before install commands otherwise there is a
63
+ // chance that whatever we recommended to install will be immediately uninstalled
64
+ if (packagesOverrideRemove.length > 0) {
65
+ commandsToExecute.push(`${packageManager.getPackageManagerCommand('removeOverride', packageMgr)} ${packagesOverrideRemove.join(' ')}`);
66
+ }
67
+ if (packagesOverride.length > 0) {
68
+ commandsToExecute.push(`${packageManager.getPackageManagerCommand('override', packageMgr)} ${packagesOverride.join(' ')}`);
69
+ }
48
70
  if (packagesDepUn.length > 0) {
49
71
  commandsToExecute.push(`${packageManager.getPackageManagerCommand('uninstall', packageMgr)} ${packagesDepUn.join(' ')}`);
50
72
  }
@@ -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.
@@ -19,7 +19,7 @@ m365 spfx project upgrade [options]
19
19
  : The version of SharePoint Framework to which upgrade the project
20
20
 
21
21
  `--packageManager [packageManager]`
22
- : The package manager you use. Supported managers `npm`, `pnpm`, `yarn`. Default `npm`
22
+ : The package manager you use. Supported managers `npm` or `pnpm`. Default `npm`
23
23
 
24
24
  `--shell [shell]`
25
25
  : The shell you use. Supported shells `bash`, `powershell`, `cmd`. Default `powershell`