@pnp/cli-microsoft365 12.0.0-beta.0be7d8d → 12.0.0-beta.c9bd7f3

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 (89) hide show
  1. package/allCommands.json +1 -1
  2. package/allCommandsFull.json +1 -1
  3. package/dist/Auth.js +2 -6
  4. package/dist/auth/FileTokenStorage.js +0 -3
  5. package/dist/auth/msalCachePlugin.js +201 -12
  6. package/dist/m365/commands/logout.js +2 -4
  7. package/dist/m365/entra/commands/m365group/m365group-remove.js +9 -2
  8. package/dist/m365/spe/commands/container/container-remove.js +6 -7
  9. package/dist/m365/spo/commands/file/file-archive.js +1 -1
  10. package/dist/m365/spo/commands/file/file-remove.js +5 -5
  11. package/dist/m365/spo/commands/file/file-unarchive.js +1 -1
  12. package/dist/m365/spo/commands/folder/folder-archive.js +1 -1
  13. package/dist/m365/spo/commands/folder/folder-remove.js +5 -5
  14. package/dist/m365/spo/commands/hidedefaultthemes/hidedefaultthemes-get.js +5 -0
  15. package/dist/m365/spo/commands/hidedefaultthemes/hidedefaultthemes-set.js +8 -26
  16. package/dist/m365/spo/commands/homesite/homesite-list.js +5 -0
  17. package/dist/m365/spo/commands/list/list-remove.js +4 -4
  18. package/dist/m365/spo/commands/listitem/listitem-batch-remove.js +5 -4
  19. package/dist/m365/spo/commands/listitem/listitem-remove.js +8 -5
  20. package/dist/m365/spo/commands/page/page-remove.js +7 -7
  21. package/dist/m365/spo/commands/site/site-list.js +60 -49
  22. package/dist/m365/spo/commands/site/site-remove.js +12 -6
  23. package/dist/m365/spo/commands/spo-get.js +5 -0
  24. package/dist/m365/spo/commands/spo-set.js +10 -21
  25. package/dist/m365/spo/commands/storageentity/storageentity-get.js +23 -17
  26. package/dist/m365/spo/commands/storageentity/storageentity-list.js +39 -36
  27. package/dist/m365/spo/commands/storageentity/storageentity-remove.js +26 -33
  28. package/dist/m365/spo/commands/storageentity/storageentity-set.js +26 -36
  29. package/dist/m365/spo/commands/user/user-ensure.js +24 -60
  30. package/dist/m365/spo/commands/user/user-get.js +25 -65
  31. package/dist/m365/spo/commands/user/user-list.js +10 -18
  32. package/dist/m365/spo/commands/user/user-remove.js +26 -68
  33. package/dist/m365/spo/commands/userprofile/userprofile-get.js +10 -23
  34. package/dist/m365/spo/commands/userprofile/userprofile-set.js +10 -19
  35. package/dist/m365/spo/commands/web/web-add.js +20 -55
  36. package/dist/m365/spo/commands/web/web-clientsidewebpart-list.js +10 -18
  37. package/dist/m365/spo/commands/web/web-get.js +12 -30
  38. package/dist/m365/spo/commands/web/web-installedlanguage-list.js +10 -18
  39. package/dist/m365/spo/commands/web/web-list.js +10 -18
  40. package/dist/m365/spo/commands/web/web-reindex.js +10 -18
  41. package/dist/m365/spo/commands/web/web-remove.js +11 -27
  42. package/dist/m365/spo/commands/web/web-retentionlabel-list.js +10 -18
  43. package/dist/m365/spo/commands/web/web-roleassignment-add.js +40 -64
  44. package/dist/m365/spo/commands/web/web-roleassignment-remove.js +31 -58
  45. package/dist/m365/spo/commands/web/web-roleinheritance-break.js +12 -36
  46. package/dist/m365/spo/commands/web/web-roleinheritance-reset.js +11 -29
  47. package/dist/m365/spo/commands/web/web-set.js +26 -96
  48. package/dist/m365/spo/commands.js +0 -4
  49. package/dist/m365/teams/commands/channel/channel-list.js +2 -6
  50. package/dist/m365/teams/commands/channel/channel-member-add.js +2 -6
  51. package/dist/m365/teams/commands/channel/channel-member-list.js +2 -6
  52. package/dist/m365/teams/commands/channel/channel-member-remove.js +2 -6
  53. package/dist/m365/teams/commands/channel/channel-member-set.js +2 -6
  54. package/dist/m365/teams/commands/channel/channel-remove.js +2 -8
  55. package/dist/m365/teams/commands/channel/channel-set.js +2 -8
  56. package/dist/m365/teams/commands/tab/tab-get.js +2 -6
  57. package/dist/m365/teams/commands/team/team-archive.js +2 -6
  58. package/dist/m365/teams/commands/team/team-remove.js +2 -6
  59. package/dist/m365/teams/commands/team/team-unarchive.js +2 -6
  60. package/docs/docs/cmd/entra/m365group/m365group-remove.mdx +6 -3
  61. package/docs/docs/cmd/spe/container/container-remove.mdx +5 -5
  62. package/docs/docs/cmd/spo/file/file-archive.mdx +8 -0
  63. package/docs/docs/cmd/spo/file/file-remove.mdx +4 -4
  64. package/docs/docs/cmd/spo/file/file-unarchive.mdx +8 -0
  65. package/docs/docs/cmd/spo/folder/folder-archive.mdx +6 -0
  66. package/docs/docs/cmd/spo/folder/folder-remove.mdx +4 -4
  67. package/docs/docs/cmd/spo/list/list-remove.mdx +4 -4
  68. package/docs/docs/cmd/spo/listitem/listitem-batch-remove.mdx +8 -2
  69. package/docs/docs/cmd/spo/listitem/listitem-remove.mdx +8 -2
  70. package/docs/docs/cmd/spo/page/page-remove.mdx +4 -4
  71. package/docs/docs/cmd/spo/site/site-apppermission-add.mdx +52 -21
  72. package/docs/docs/cmd/spo/site/site-list.mdx +22 -1
  73. package/docs/docs/cmd/spo/site/site-remove.mdx +5 -2
  74. package/docs/docs/cmd/spo/storageentity/storageentity-get.mdx +11 -2
  75. package/docs/docs/cmd/spo/storageentity/storageentity-list.mdx +9 -3
  76. package/docs/docs/cmd/spo/storageentity/storageentity-remove.mdx +6 -6
  77. package/docs/docs/cmd/spo/storageentity/storageentity-set.mdx +10 -4
  78. package/docs/docs/cmd/teams/app/app-install.mdx +21 -0
  79. package/docs/docs/cmd/teams/app/app-list.mdx +19 -0
  80. package/docs/docs/cmd/teams/app/app-publish.mdx +17 -0
  81. package/docs/docs/cmd/teams/app/app-remove.mdx +19 -0
  82. package/docs/docs/cmd/teams/app/app-uninstall.mdx +21 -0
  83. package/docs/docs/cmd/teams/app/app-update.mdx +19 -0
  84. package/npm-shrinkwrap.json +432 -0
  85. package/package.json +6 -1
  86. package/dist/m365/spo/commands/web/web-rule-list.js +0 -111
  87. package/dist/m365/spo/commands/web/web-rule-remove.js +0 -57
  88. package/docs/docs/cmd/spo/web/web-rule-list.mdx +0 -193
  89. package/docs/docs/cmd/spo/web/web-rule-remove.mdx +0 -71
package/dist/Auth.js CHANGED
@@ -262,7 +262,7 @@ export class Auth {
262
262
  return {
263
263
  auth: authConfig,
264
264
  cache: {
265
- cachePlugin: msalCachePlugin
265
+ cachePlugin: await msalCachePlugin.getCachePlugin()
266
266
  },
267
267
  system: {
268
268
  loggerOptions: {
@@ -735,8 +735,7 @@ export class Auth {
735
735
  await allConnectionsStorage.remove();
736
736
  // we need to manually clear MSAL cache, because MSAL doesn't have support
737
737
  // for logging out when using cert-based auth
738
- const msalCache = this.getMsalCacheStorage();
739
- await msalCache.remove();
738
+ await msalCachePlugin.clearMsalCache();
740
739
  }
741
740
  async removeConnectionInfo(connection, logger, debug) {
742
741
  const allConnections = await this.getAllConnections();
@@ -769,9 +768,6 @@ export class Auth {
769
768
  getConnectionStorage() {
770
769
  return new FileTokenStorage(FileTokenStorage.connectionInfoFilePath());
771
770
  }
772
- getMsalCacheStorage() {
773
- return new FileTokenStorage(FileTokenStorage.msalCacheFilePath());
774
- }
775
771
  getAllConnectionsStorage() {
776
772
  return new FileTokenStorage(FileTokenStorage.allConnectionsFilePath());
777
773
  }
@@ -2,9 +2,6 @@ import fs from 'fs';
2
2
  import os from 'os';
3
3
  import path from 'path';
4
4
  export class FileTokenStorage {
5
- static msalCacheFilePath() {
6
- return path.join(os.homedir(), '.cli-m365-msal.json');
7
- }
8
5
  static connectionInfoFilePath() {
9
6
  return path.join(os.homedir(), '.cli-m365-connection.json');
10
7
  }
@@ -1,29 +1,218 @@
1
- import { FileTokenStorage } from './FileTokenStorage.js';
2
- class MsalCachePlugin {
3
- constructor() {
4
- this.fileTokenStorage = new FileTokenStorage(FileTokenStorage.msalCacheFilePath());
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import { lock } from 'proper-lockfile';
5
+ const legacyCachePath = path.join(os.homedir(), '.cli-m365-msal.json');
6
+ const fallbackCachePath = path.join(os.homedir(), '.cli-m365-msal-cache.json');
7
+ const lockRetryCount = 500;
8
+ const lockRetryDelay = 100;
9
+ const staleLockThreshold = 10000;
10
+ const persistenceConfiguration = {
11
+ cachePath: fallbackCachePath,
12
+ serviceName: 'cli-microsoft365',
13
+ accountName: 'msal-cache',
14
+ usePlaintextFileOnLinux: true
15
+ };
16
+ export const fileLock = { lock };
17
+ let _initPromise;
18
+ // Fallback ICachePlugin that stores tokens as plain JSON on disk.
19
+ // @azure/msal-node-extensions ships a usePlaintextFileOnLinux option
20
+ // for Linux systems without libsecret, but the package's barrel export
21
+ // eagerly loads LibSecretPersistence which does `import keytar` at the
22
+ // top level. When libsecret is missing, the entire dynamic import of
23
+ // the package fails before any fallback logic can run. This class
24
+ // provides equivalent file-based persistence without depending on the
25
+ // package at all.
26
+ // See: https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/7170
27
+ class FileCachePlugin {
28
+ constructor(cachePath) {
29
+ this.cachePath = cachePath;
5
30
  }
6
31
  async beforeCacheAccess(tokenCacheContext) {
32
+ await this.acquireLock();
7
33
  try {
8
- const data = await this.fileTokenStorage.get();
9
- tokenCacheContext.tokenCache.deserialize(data);
34
+ if (fs.existsSync(this.cachePath)) {
35
+ const data = fs.readFileSync(this.cachePath, 'utf8');
36
+ tokenCacheContext.tokenCache.deserialize(data);
37
+ }
10
38
  }
11
39
  catch {
12
40
  // Do nothing
13
41
  }
14
42
  }
15
43
  async afterCacheAccess(tokenCacheContext) {
16
- if (!tokenCacheContext.cacheHasChanged) {
17
- return;
18
- }
19
44
  try {
20
- await this.fileTokenStorage.set(tokenCacheContext.tokenCache.serialize());
45
+ if (tokenCacheContext.cacheHasChanged) {
46
+ if (fs.existsSync(this.cachePath)) {
47
+ fs.chmodSync(this.cachePath, 0o600);
48
+ }
49
+ fs.writeFileSync(this.cachePath, tokenCacheContext.tokenCache.serialize(), { encoding: 'utf8', mode: 0o600 });
50
+ }
21
51
  }
22
52
  catch {
23
53
  // Do nothing
24
54
  }
55
+ finally {
56
+ await this.releaseLock();
57
+ }
58
+ }
59
+ async clearCache() {
60
+ await this.acquireLock();
61
+ try {
62
+ removeFile(this.cachePath);
63
+ }
64
+ finally {
65
+ await this.releaseLock();
66
+ }
67
+ }
68
+ async acquireLock() {
69
+ this.releaseCacheLock = await msalCachePlugin.acquireFileLock(this.cachePath);
70
+ }
71
+ async releaseLock() {
72
+ if (this.releaseCacheLock === undefined) {
73
+ return;
74
+ }
75
+ const releaseCacheLock = this.releaseCacheLock;
76
+ this.releaseCacheLock = undefined;
77
+ await releaseCacheLock();
78
+ }
79
+ }
80
+ class LockingCachePlugin {
81
+ constructor(plugin, lockPath) {
82
+ this.plugin = plugin;
83
+ this.lockPath = lockPath;
84
+ }
85
+ async beforeCacheAccess(tokenCacheContext) {
86
+ this.releaseCacheLock = await msalCachePlugin.acquireFileLock(this.lockPath);
87
+ try {
88
+ await this.plugin.beforeCacheAccess(tokenCacheContext);
89
+ }
90
+ catch (err) {
91
+ await this.releaseLock();
92
+ throw err;
93
+ }
94
+ }
95
+ async afterCacheAccess(tokenCacheContext) {
96
+ try {
97
+ await this.plugin.afterCacheAccess(tokenCacheContext);
98
+ }
99
+ finally {
100
+ await this.releaseLock();
101
+ }
102
+ }
103
+ async clearCache(clearCache) {
104
+ this.releaseCacheLock = await msalCachePlugin.acquireFileLock(this.lockPath);
105
+ try {
106
+ await clearCache();
107
+ }
108
+ finally {
109
+ await this.releaseLock();
110
+ }
111
+ }
112
+ async releaseLock() {
113
+ if (this.releaseCacheLock === undefined) {
114
+ return;
115
+ }
116
+ const releaseCacheLock = this.releaseCacheLock;
117
+ this.releaseCacheLock = undefined;
118
+ await releaseCacheLock();
25
119
  }
26
120
  }
27
- const msalCachePlugin = new MsalCachePlugin();
28
- export { msalCachePlugin };
121
+ function removeFile(filePath) {
122
+ try {
123
+ fs.unlinkSync(filePath);
124
+ }
125
+ catch (err) {
126
+ if (err.code !== 'ENOENT') {
127
+ throw err;
128
+ }
129
+ }
130
+ }
131
+ export const msalCachePlugin = {
132
+ async acquireFileLock(cachePath) {
133
+ return await fileLock.lock(cachePath, {
134
+ lockfilePath: `${cachePath}.lockfile`,
135
+ realpath: false,
136
+ stale: staleLockThreshold,
137
+ update: staleLockThreshold / 2,
138
+ retries: {
139
+ retries: lockRetryCount,
140
+ factor: 1,
141
+ minTimeout: lockRetryDelay,
142
+ maxTimeout: lockRetryDelay,
143
+ randomize: false
144
+ }
145
+ });
146
+ },
147
+ async importMsalExtensions() {
148
+ return await import('@azure/msal-node-extensions');
149
+ },
150
+ async createNativePersistence() {
151
+ const { DataProtectionScope, PersistenceCachePlugin, PersistenceCreator } = await msalCachePlugin.importMsalExtensions();
152
+ const persistence = await PersistenceCreator.createPersistence({
153
+ ...persistenceConfiguration,
154
+ dataProtectionScope: DataProtectionScope.CurrentUser
155
+ });
156
+ const plugin = new LockingCachePlugin(new PersistenceCachePlugin(persistence), `${persistence.getFilePath()}.cli-m365`);
157
+ return {
158
+ plugin,
159
+ clearCache: async () => { await plugin.clearCache(async () => { await persistence.delete(); }); },
160
+ isFileFallback: false
161
+ };
162
+ },
163
+ createFileFallback() {
164
+ const plugin = new FileCachePlugin(persistenceConfiguration.cachePath);
165
+ return {
166
+ plugin,
167
+ clearCache: async () => { await plugin.clearCache(); },
168
+ isFileFallback: true
169
+ };
170
+ },
171
+ removeLegacyCache() {
172
+ removeFile(legacyCachePath);
173
+ },
174
+ async getCachePlugin() {
175
+ _initPromise ?? (_initPromise = (async () => {
176
+ msalCachePlugin.removeLegacyCache();
177
+ try {
178
+ return await msalCachePlugin.createNativePersistence();
179
+ }
180
+ catch (err) {
181
+ // Fall back to file-based cache only on Linux where libsecret
182
+ // may not be installed. On Windows (DPAPI) and macOS (Keychain)
183
+ // native persistence should always work.
184
+ if (process.platform === 'linux') {
185
+ return msalCachePlugin.createFileFallback();
186
+ }
187
+ throw err;
188
+ }
189
+ })());
190
+ const { plugin } = await _initPromise;
191
+ return plugin;
192
+ },
193
+ async clearMsalCache() {
194
+ _initPromise ?? (_initPromise = (async () => {
195
+ msalCachePlugin.removeLegacyCache();
196
+ try {
197
+ return await msalCachePlugin.createNativePersistence();
198
+ }
199
+ catch (err) {
200
+ if (process.platform === 'linux') {
201
+ return msalCachePlugin.createFileFallback();
202
+ }
203
+ throw err;
204
+ }
205
+ })());
206
+ const { clearCache, isFileFallback } = await _initPromise;
207
+ await clearCache();
208
+ // Also remove the file-based fallback cache to ensure no tokens
209
+ // remain if the machine previously used file-based persistence
210
+ if (!isFileFallback) {
211
+ await msalCachePlugin.createFileFallback().clearCache();
212
+ }
213
+ },
214
+ resetForTesting() {
215
+ _initPromise = undefined;
216
+ }
217
+ };
29
218
  //# sourceMappingURL=msalCachePlugin.js.map
@@ -16,7 +16,6 @@ class LogoutCommand extends Command {
16
16
  if (this.verbose) {
17
17
  await logger.logToStderr('Logging out from Microsoft 365...');
18
18
  }
19
- const deactivate = () => auth.connection.deactivate();
20
19
  try {
21
20
  await auth.clearConnectionInfo();
22
21
  }
@@ -24,10 +23,9 @@ class LogoutCommand extends Command {
24
23
  if (this.debug) {
25
24
  await logger.logToStderr(new CommandError(error));
26
25
  }
26
+ throw new CommandError(error);
27
27
  }
28
- finally {
29
- deactivate();
30
- }
28
+ auth.connection.deactivate();
31
29
  }
32
30
  async action(logger, args) {
33
31
  try {
@@ -32,6 +32,10 @@ class EntraM365GroupRemoveCommand extends GraphCommand {
32
32
  __classPrivateFieldGet(this, _EntraM365GroupRemoveCommand_instances, "m", _EntraM365GroupRemoveCommand_initTypes).call(this);
33
33
  }
34
34
  async commandAction(logger, args) {
35
+ if (args.options.skipRecycleBin) {
36
+ await this.warn(logger, `Option 'skipRecycleBin' is deprecated. Please use 'permanent' instead.`);
37
+ args.options.permanent = true;
38
+ }
35
39
  const removeGroup = async () => {
36
40
  if (this.verbose) {
37
41
  await logger.logToStderr(`Removing Microsoft 365 Group: ${args.options.id || args.options.displayName}...`);
@@ -49,7 +53,7 @@ class EntraM365GroupRemoveCommand extends GraphCommand {
49
53
  const spoAdminUrl = await spo.getSpoAdminUrl(logger, this.debug);
50
54
  // Delete the Microsoft 365 group site. This operation will also delete the group.
51
55
  await this.deleteM365GroupSite(logger, siteUrl, spoAdminUrl);
52
- if (args.options.skipRecycleBin) {
56
+ if (args.options.permanent) {
53
57
  await this.deleteM365GroupFromRecycleBin(logger, groupId);
54
58
  await this.deleteSiteFromRecycleBin(logger, siteUrl, spoAdminUrl);
55
59
  }
@@ -169,7 +173,7 @@ _EntraM365GroupRemoveCommand_instances = new WeakSet(), _EntraM365GroupRemoveCom
169
173
  this.telemetry.push((args) => {
170
174
  Object.assign(this.telemetryProperties, {
171
175
  force: (!(!args.options.force)).toString(),
172
- skipRecycleBin: args.options.skipRecycleBin
176
+ permanent: !!(args.options.permanent || args.options.skipRecycleBin)
173
177
  });
174
178
  });
175
179
  }, _EntraM365GroupRemoveCommand_initOptions = function _EntraM365GroupRemoveCommand_initOptions() {
@@ -179,6 +183,8 @@ _EntraM365GroupRemoveCommand_instances = new WeakSet(), _EntraM365GroupRemoveCom
179
183
  option: '-n, --displayName [displayName]'
180
184
  }, {
181
185
  option: '-f, --force'
186
+ }, {
187
+ option: '--permanent'
182
188
  }, {
183
189
  option: '--skipRecycleBin'
184
190
  });
@@ -193,6 +199,7 @@ _EntraM365GroupRemoveCommand_instances = new WeakSet(), _EntraM365GroupRemoveCom
193
199
  this.optionSets.push({ options: ['id', 'displayName'] });
194
200
  }, _EntraM365GroupRemoveCommand_initTypes = function _EntraM365GroupRemoveCommand_initTypes() {
195
201
  this.types.string.push('id', 'displayName');
202
+ this.types.boolean.push('permanent', 'skipRecycleBin');
196
203
  };
197
204
  EntraM365GroupRemoveCommand.maxRetries = 10;
198
205
  export default new EntraM365GroupRemoveCommand();
@@ -11,7 +11,7 @@ export const options = z.strictObject({
11
11
  name: z.string().optional().alias('n'),
12
12
  containerTypeId: z.uuid().optional(),
13
13
  containerTypeName: z.string().optional(),
14
- recycle: z.boolean().optional(),
14
+ permanent: z.boolean().optional(),
15
15
  force: z.boolean().optional().alias('f')
16
16
  });
17
17
  class SpeContainerRemoveCommand extends GraphCommand {
@@ -46,7 +46,7 @@ class SpeContainerRemoveCommand extends GraphCommand {
46
46
  }
47
47
  async commandAction(logger, args) {
48
48
  if (!args.options.force) {
49
- const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove container '${args.options.id || args.options.name}'${!args.options.recycle ? ' permanently' : ''}?` });
49
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to ${args.options.permanent ? 'permanently remove' : 'recycle'} container '${args.options.id || args.options.name}'?` });
50
50
  if (!result) {
51
51
  return;
52
52
  }
@@ -63,13 +63,12 @@ class SpeContainerRemoveCommand extends GraphCommand {
63
63
  },
64
64
  responseType: 'json'
65
65
  };
66
- if (args.options.recycle) {
67
- await request.delete(requestOptions);
66
+ if (args.options.permanent) {
67
+ requestOptions.url += '/permanentDelete';
68
+ await request.post(requestOptions);
68
69
  return;
69
70
  }
70
- // Container should be permanently deleted
71
- requestOptions.url += '/permanentDelete';
72
- await request.post(requestOptions);
71
+ await request.delete(requestOptions);
73
72
  }
74
73
  catch (err) {
75
74
  this.handleRejectedODataJsonPromise(err);
@@ -40,7 +40,7 @@ class SpoFileArchiveCommand extends SpoCommand {
40
40
  async commandAction(logger, args) {
41
41
  const { webUrl, url, id, force, verbose } = args.options;
42
42
  if (!force) {
43
- const result = await cli.promptForConfirmation({ message: `Are you sure you would like to archive this item? You will be able to reactivate it instantly for the first 7 days. After that, it will take up to 24 hours to reactivate.` });
43
+ const result = await cli.promptForConfirmation({ message: `Are you sure you would like to archive this file? You will be able to reactivate it instantly for the first 7 days. After that, it will take up to 24 hours to reactivate.` });
44
44
  if (!result) {
45
45
  return;
46
46
  }
@@ -46,7 +46,7 @@ class SpoFileRemoveCommand extends SpoCommand {
46
46
  const serverRelativePath = urlUtil.getServerRelativePath(args.options.webUrl, args.options.url);
47
47
  requestUrl = `${args.options.webUrl}/_api/web/GetFileByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(serverRelativePath)}')`;
48
48
  }
49
- if (args.options.recycle) {
49
+ if (!args.options.permanent) {
50
50
  requestUrl += `/recycle()`;
51
51
  }
52
52
  const requestOptions = {
@@ -73,7 +73,7 @@ class SpoFileRemoveCommand extends SpoCommand {
73
73
  await removeFile();
74
74
  }
75
75
  else {
76
- const result = await cli.promptForConfirmation({ message: `Are you sure you want to ${args.options.recycle ? 'recycle' : 'remove'} the file ${args.options.id || args.options.url} located in site ${args.options.webUrl}?` });
76
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to ${args.options.permanent ? 'permanently remove' : 'recycle'} the file ${args.options.id || args.options.url} located in site ${args.options.webUrl}?` });
77
77
  if (result) {
78
78
  await removeFile();
79
79
  }
@@ -85,7 +85,7 @@ _SpoFileRemoveCommand_instances = new WeakSet(), _SpoFileRemoveCommand_initTelem
85
85
  Object.assign(this.telemetryProperties, {
86
86
  id: typeof args.options.id !== 'undefined',
87
87
  url: typeof args.options.url !== 'undefined',
88
- recycle: !!args.options.recycle,
88
+ permanent: !!args.options.permanent,
89
89
  bypassSharedLock: !!args.options.bypassSharedLock,
90
90
  force: !!args.options.force
91
91
  });
@@ -98,7 +98,7 @@ _SpoFileRemoveCommand_instances = new WeakSet(), _SpoFileRemoveCommand_initTelem
98
98
  }, {
99
99
  option: '--url [url]'
100
100
  }, {
101
- option: '--recycle'
101
+ option: '--permanent'
102
102
  }, {
103
103
  option: '--bypassSharedLock'
104
104
  }, {
@@ -120,7 +120,7 @@ _SpoFileRemoveCommand_instances = new WeakSet(), _SpoFileRemoveCommand_initTelem
120
120
  this.optionSets.push({ options: ['id', 'url'] });
121
121
  }, _SpoFileRemoveCommand_initTypes = function _SpoFileRemoveCommand_initTypes() {
122
122
  this.types.string.push('webUrl', 'id', 'url');
123
- this.types.boolean.push('recycle', 'bypassSharedLock', 'force');
123
+ this.types.boolean.push('permanent', 'bypassSharedLock', 'force');
124
124
  };
125
125
  export default new SpoFileRemoveCommand();
126
126
  //# sourceMappingURL=file-remove.js.map
@@ -40,7 +40,7 @@ class SpoFileUnarchiveCommand extends SpoCommand {
40
40
  async commandAction(logger, args) {
41
41
  const { webUrl, url, id, force, verbose } = args.options;
42
42
  if (!force) {
43
- const result = await cli.promptForConfirmation({ message: `Reactivation could take up to 24 hours. Files that are reactivated cannot be archived again for 30 days. Are you sure you would like to unarchive this item?` });
43
+ const result = await cli.promptForConfirmation({ message: `Reactivation could take up to 24 hours. Files that are reactivated cannot be archived again for a period of time. Are you sure you would like to unarchive this file?` });
44
44
  if (!result) {
45
45
  return;
46
46
  }
@@ -40,7 +40,7 @@ class SpoFolderArchiveCommand extends SpoCommand {
40
40
  async commandAction(logger, args) {
41
41
  const { webUrl, url, id, force } = args.options;
42
42
  if (!force) {
43
- const result = await cli.promptForConfirmation({ message: `Are you sure you would like to archive this item? You will be able to reactivate it instantly for the first 7 days. After that, it will take up to 24 hours to reactivate.` });
43
+ const result = await cli.promptForConfirmation({ message: `Are you sure you would like to archive this folder? You will be able to reactivate it instantly for the first 7 days. After that, it will take up to 24 hours to reactivate.` });
44
44
  if (!result) {
45
45
  return;
46
46
  }
@@ -34,7 +34,7 @@ class SpoFolderRemoveCommand extends SpoCommand {
34
34
  await this.removeFolder(logger, args.options);
35
35
  }
36
36
  else {
37
- const result = await cli.promptForConfirmation({ message: `Are you sure you want to ${args.options.recycle ? "recycle" : "remove"} the folder ${args.options.url} located in site ${args.options.webUrl}?` });
37
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to ${args.options.permanent ? 'permanently remove' : 'recycle'} the folder ${args.options.url} located in site ${args.options.webUrl}?` });
38
38
  if (result) {
39
39
  await this.removeFolder(logger, args.options);
40
40
  }
@@ -46,7 +46,7 @@ class SpoFolderRemoveCommand extends SpoCommand {
46
46
  }
47
47
  const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, options.url);
48
48
  let requestUrl = `${options.webUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(serverRelativePath)}')`;
49
- if (options.recycle) {
49
+ if (!options.permanent) {
50
50
  requestUrl += `/recycle()`;
51
51
  }
52
52
  const requestOptions = {
@@ -70,7 +70,7 @@ class SpoFolderRemoveCommand extends SpoCommand {
70
70
  _SpoFolderRemoveCommand_instances = new WeakSet(), _SpoFolderRemoveCommand_initTelemetry = function _SpoFolderRemoveCommand_initTelemetry() {
71
71
  this.telemetry.push((args) => {
72
72
  Object.assign(this.telemetryProperties, {
73
- recycle: !!args.options.recycle,
73
+ permanent: !!args.options.permanent,
74
74
  force: !!args.options.force
75
75
  });
76
76
  });
@@ -80,7 +80,7 @@ _SpoFolderRemoveCommand_instances = new WeakSet(), _SpoFolderRemoveCommand_initT
80
80
  }, {
81
81
  option: '--url <url>'
82
82
  }, {
83
- option: '--recycle'
83
+ option: '--permanent'
84
84
  }, {
85
85
  option: '-f, --force'
86
86
  });
@@ -88,7 +88,7 @@ _SpoFolderRemoveCommand_instances = new WeakSet(), _SpoFolderRemoveCommand_initT
88
88
  this.validators.push(async (args) => validation.isValidSharePointUrl(args.options.webUrl));
89
89
  }, _SpoFolderRemoveCommand_initTypes = function _SpoFolderRemoveCommand_initTypes() {
90
90
  this.types.string.push('webUrl', 'url');
91
- this.types.boolean.push('recycle', 'force');
91
+ this.types.boolean.push('permanent', 'force');
92
92
  };
93
93
  export default new SpoFolderRemoveCommand();
94
94
  //# sourceMappingURL=folder-remove.js.map
@@ -1,7 +1,9 @@
1
+ import { globalOptionsZod } from '../../../../Command.js';
1
2
  import request from '../../../../request.js';
2
3
  import { spo } from '../../../../utils/spo.js';
3
4
  import SpoCommand from '../../../base/SpoCommand.js';
4
5
  import commands from '../../commands.js';
6
+ export const options = globalOptionsZod.strict();
5
7
  class SpoHideDefaultThemesGetCommand extends SpoCommand {
6
8
  get name() {
7
9
  return commands.HIDEDEFAULTTHEMES_GET;
@@ -9,6 +11,9 @@ class SpoHideDefaultThemesGetCommand extends SpoCommand {
9
11
  get description() {
10
12
  return 'Gets the current value of the HideDefaultThemes setting';
11
13
  }
14
+ get schema() {
15
+ return options;
16
+ }
12
17
  async commandAction(logger) {
13
18
  try {
14
19
  const spoAdminUrl = await spo.getSpoAdminUrl(logger, this.debug);
@@ -1,13 +1,13 @@
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 _SpoHideDefaultThemesSetCommand_instances, _SpoHideDefaultThemesSetCommand_initTelemetry, _SpoHideDefaultThemesSetCommand_initOptions, _SpoHideDefaultThemesSetCommand_initTypes;
1
+ import { globalOptionsZod } from '../../../../Command.js';
7
2
  import request from '../../../../request.js';
8
3
  import { spo } from '../../../../utils/spo.js';
9
4
  import SpoCommand from '../../../base/SpoCommand.js';
10
5
  import commands from '../../commands.js';
6
+ import { z } from 'zod';
7
+ export const options = z.strictObject({
8
+ ...globalOptionsZod.shape,
9
+ hideDefaultThemes: z.enum(['true', 'false']).transform(val => val === 'true')
10
+ });
11
11
  class SpoHideDefaultThemesSetCommand extends SpoCommand {
12
12
  get name() {
13
13
  return commands.HIDEDEFAULTTHEMES_SET;
@@ -15,12 +15,8 @@ class SpoHideDefaultThemesSetCommand extends SpoCommand {
15
15
  get description() {
16
16
  return 'Sets the value of the HideDefaultThemes setting';
17
17
  }
18
- constructor() {
19
- super();
20
- _SpoHideDefaultThemesSetCommand_instances.add(this);
21
- __classPrivateFieldGet(this, _SpoHideDefaultThemesSetCommand_instances, "m", _SpoHideDefaultThemesSetCommand_initTelemetry).call(this);
22
- __classPrivateFieldGet(this, _SpoHideDefaultThemesSetCommand_instances, "m", _SpoHideDefaultThemesSetCommand_initOptions).call(this);
23
- __classPrivateFieldGet(this, _SpoHideDefaultThemesSetCommand_instances, "m", _SpoHideDefaultThemesSetCommand_initTypes).call(this);
18
+ get schema() {
19
+ return options;
24
20
  }
25
21
  async commandAction(logger, args) {
26
22
  try {
@@ -45,19 +41,5 @@ class SpoHideDefaultThemesSetCommand extends SpoCommand {
45
41
  }
46
42
  }
47
43
  }
48
- _SpoHideDefaultThemesSetCommand_instances = new WeakSet(), _SpoHideDefaultThemesSetCommand_initTelemetry = function _SpoHideDefaultThemesSetCommand_initTelemetry() {
49
- this.telemetry.push((args) => {
50
- Object.assign(this.telemetryProperties, {
51
- hideDefaultThemes: args.options.hideDefaultThemes
52
- });
53
- });
54
- }, _SpoHideDefaultThemesSetCommand_initOptions = function _SpoHideDefaultThemesSetCommand_initOptions() {
55
- this.options.unshift({
56
- option: '--hideDefaultThemes <hideDefaultThemes>',
57
- autocomplete: ['true', 'false']
58
- });
59
- }, _SpoHideDefaultThemesSetCommand_initTypes = function _SpoHideDefaultThemesSetCommand_initTypes() {
60
- this.types.boolean.push('hideDefaultThemes');
61
- };
62
44
  export default new SpoHideDefaultThemesSetCommand();
63
45
  //# sourceMappingURL=hidedefaultthemes-set.js.map
@@ -1,7 +1,9 @@
1
+ import { globalOptionsZod } from '../../../../Command.js';
1
2
  import { odata } from '../../../../utils/odata.js';
2
3
  import { spo } from '../../../../utils/spo.js';
3
4
  import SpoCommand from '../../../base/SpoCommand.js';
4
5
  import commands from '../../commands.js';
6
+ export const options = globalOptionsZod.strict();
5
7
  class SpoHomeSiteListCommand extends SpoCommand {
6
8
  get name() {
7
9
  return commands.HOMESITE_LIST;
@@ -9,6 +11,9 @@ class SpoHomeSiteListCommand extends SpoCommand {
9
11
  get description() {
10
12
  return 'Lists all home sites';
11
13
  }
14
+ get schema() {
15
+ return options;
16
+ }
12
17
  defaultProperties() {
13
18
  return ['Url', 'Title'];
14
19
  }
@@ -38,7 +38,7 @@ class SpoListRemoveCommand extends SpoCommand {
38
38
  else {
39
39
  requestUrl = `${args.options.webUrl}/_api/web/lists/GetByTitle('${formatting.encodeQueryParameter(args.options.title)}')`;
40
40
  }
41
- if (args.options.recycle) {
41
+ if (!args.options.permanent) {
42
42
  requestUrl += `/recycle`;
43
43
  }
44
44
  const requestOptions = {
@@ -75,7 +75,7 @@ _SpoListRemoveCommand_instances = new WeakSet(), _SpoListRemoveCommand_initTelem
75
75
  id: typeof args.options.id !== 'undefined',
76
76
  title: typeof args.options.title !== 'undefined',
77
77
  force: !!args.options.force,
78
- recycle: !!args.options.recycle
78
+ permanent: !!args.options.permanent
79
79
  });
80
80
  });
81
81
  }, _SpoListRemoveCommand_initOptions = function _SpoListRemoveCommand_initOptions() {
@@ -86,7 +86,7 @@ _SpoListRemoveCommand_instances = new WeakSet(), _SpoListRemoveCommand_initTelem
86
86
  }, {
87
87
  option: '-t, --title [title]'
88
88
  }, {
89
- option: '--recycle'
89
+ option: '--permanent'
90
90
  }, {
91
91
  option: '-f, --force'
92
92
  });
@@ -106,7 +106,7 @@ _SpoListRemoveCommand_instances = new WeakSet(), _SpoListRemoveCommand_initTelem
106
106
  this.optionSets.push({ options: ['id', 'title'] });
107
107
  }, _SpoListRemoveCommand_initTypes = function _SpoListRemoveCommand_initTypes() {
108
108
  this.types.string.push('id', 'title', 'webUrl');
109
- this.types.boolean.push('force', 'recycle');
109
+ this.types.boolean.push('force', 'permanent');
110
110
  };
111
111
  export default new SpoListRemoveCommand();
112
112
  //# sourceMappingURL=list-remove.js.map