@sitecore-content-sdk/cli 0.2.0-beta.16 → 0.2.0-beta.18

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.
@@ -5,6 +5,7 @@ const login_1 = require("./login");
5
5
  const logout_1 = require("./logout");
6
6
  const status_1 = require("./status");
7
7
  const list_1 = require("./list");
8
+ const switch_1 = require("./switch");
8
9
  /**
9
10
  * Registers the `auth` command group and its subcommands (`login`, `logout`, `status`, `list`) with Yargs.
10
11
  * @param {Argv} yargs - The Yargs instance used to define CLI commands.
@@ -16,7 +17,7 @@ function builder(yargs) {
16
17
  describe: 'Performs authentication for content services',
17
18
  builder: (_yargs) => {
18
19
  return _yargs
19
- .command([login_1.login, logout_1.logout, status_1.status, list_1.list])
20
+ .command([login_1.login, logout_1.logout, status_1.status, list_1.list, switch_1.switchTenant])
20
21
  .strict()
21
22
  .demandCommand(1, 'You need to specify a command to run')
22
23
  .help();
@@ -25,7 +25,7 @@ exports.list = {
25
25
  console.log('\n No tenant information found.');
26
26
  return;
27
27
  }
28
- console.log('\n Known tenants:\n');
28
+ console.log('\nKnown tenants:\n');
29
29
  tenants.forEach((tenant, index) => {
30
30
  console.log(`Tenant ${index + 1}:`);
31
31
  console.log(` Tenant ID : ${tenant.tenantId}`);
@@ -12,12 +12,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.login = exports.unitMock = void 0;
13
13
  const tools_1 = require("@sitecore-content-sdk/core/tools");
14
14
  const core_1 = require("@sitecore-content-sdk/core");
15
- let { setActiveTenant, writeTenantAuthInfo, writeTenantInfo, clientCredentialsFlow } = tools_1.auth;
15
+ let { setActiveTenant, writeTenantAuthInfo, writeTenantInfo, clientCredentialsFlow, getRefreshAccessToken, pollForDeviceToken, startDeviceAuthFlow, } = tools_1.auth;
16
16
  const unitMock = (formModule) => {
17
17
  setActiveTenant = formModule.setActiveTenant;
18
18
  writeTenantAuthInfo = formModule.writeTenantAuthInfo;
19
19
  writeTenantInfo = formModule.writeTenantInfo;
20
20
  clientCredentialsFlow = formModule.clientCredentialsFlow;
21
+ getRefreshAccessToken = formModule.getRefreshAccessToken;
22
+ pollForDeviceToken = formModule.pollForDeviceToken;
23
+ startDeviceAuthFlow = formModule.startDeviceAuthFlow;
21
24
  };
22
25
  exports.unitMock = unitMock;
23
26
  exports.login = {
@@ -70,51 +73,90 @@ exports.login = {
70
73
  'baseUrl',
71
74
  ], 'Login Options:'),
72
75
  handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
73
- const { clientId } = argv;
74
- let authResult, tenantId, organizationId, tenantName;
75
76
  const { DEFAULT_SITECORE_AUTH_DOMAIN, DEFAULT_SITECORE_AUTH_AUDIENCE, DEFAULT_SITECORE_AUTH_BASE_URL, } = core_1.constants;
76
- if (argv.clientSecret) {
77
- try {
78
- const authData = yield clientCredentialsFlow({
77
+ const { clientId, clientSecret, organizationId, tenantId: inputTenantId, audience = DEFAULT_SITECORE_AUTH_AUDIENCE, authority = DEFAULT_SITECORE_AUTH_DOMAIN, baseUrl = DEFAULT_SITECORE_AUTH_BASE_URL, } = argv;
78
+ let authResponse;
79
+ let tenantId;
80
+ let tenantName;
81
+ let orgId;
82
+ try {
83
+ if (clientSecret) {
84
+ console.log('\n Using Client Credentials Flow...');
85
+ const { data, tokenTenantId, tokenOrgId, tokenTenantName } = yield clientCredentialsFlow({
79
86
  clientId,
80
- clientSecret: argv.clientSecret,
81
- organizationId: argv.organizationId,
82
- tenantId: argv.tenantId,
83
- audience: argv.audience,
84
- authority: argv.authority,
85
- baseUrl: argv.baseUrl,
87
+ clientSecret,
88
+ organizationId,
89
+ tenantId: inputTenantId,
90
+ audience,
91
+ authority,
92
+ baseUrl,
86
93
  });
87
- authResult = authData.data;
88
- tenantId = authData.tokenTenantId;
89
- organizationId = authData.tokenOrgId;
90
- tenantName = authData.tokenTenantName;
94
+ authResponse = data;
95
+ tenantId = tokenTenantId;
96
+ orgId = tokenOrgId;
97
+ tenantName = tokenTenantName;
91
98
  }
92
- catch (err) {
93
- console.error(`\n Login failed: ${err.message}`);
94
- process.exit(1);
99
+ else {
100
+ console.log('\n Using Device Authorization Flow...');
101
+ if (!inputTenantId) {
102
+ throw new Error('\n Tenant ID is required for Device Code Flow.');
103
+ }
104
+ if (!organizationId) {
105
+ throw new Error('\n Organization ID is required for Device Code Flow.');
106
+ }
107
+ const deviceAuthData = yield startDeviceAuthFlow({
108
+ clientId,
109
+ audience,
110
+ authority,
111
+ baseUrl,
112
+ });
113
+ const { device_code, user_code, verification_uri, verification_uri_complete, interval, } = deviceAuthData;
114
+ console.log('\nšŸ” Device Authorization Started');
115
+ if (verification_uri_complete) {
116
+ console.log(`\n šŸ‘‰ Open the following URL to authenticate:\n ${verification_uri_complete}`);
117
+ }
118
+ else {
119
+ console.log(`šŸ‘‰ Visit: ${verification_uri}`);
120
+ console.log(`šŸ”‘ Then enter the code: ${user_code}`);
121
+ }
122
+ const { refresh_token } = yield pollForDeviceToken({
123
+ clientId,
124
+ device_code,
125
+ authority,
126
+ interval,
127
+ });
128
+ // The initial device code flow does not support custom claims (e.g., tenantId, organizationId),
129
+ // which are required for proper token validation in our multi-tenant system.
130
+ // To include these claims, we immediately use the returned refresh_token to request a new
131
+ // access token with tenantId and organizationId explicitly provided.
132
+ authResponse = yield getRefreshAccessToken({
133
+ clientId,
134
+ refreshToken: refresh_token,
135
+ tenantId: inputTenantId,
136
+ organizationId,
137
+ authority,
138
+ });
139
+ tenantId = inputTenantId;
140
+ orgId = organizationId;
141
+ tenantName = authResponse.tenantName;
142
+ console.log('\n Device Authorization Completed');
95
143
  }
144
+ yield writeTenantAuthInfo(tenantId || inputTenantId, Object.assign({ expires_at: new Date(Date.now() + authResponse.expires_in * 1000).toISOString() }, authResponse));
145
+ yield writeTenantInfo({
146
+ tenantId,
147
+ organizationId: orgId,
148
+ clientId,
149
+ tenantName,
150
+ authority,
151
+ audience,
152
+ baseUrl,
153
+ });
154
+ setActiveTenant(tenantId);
155
+ console.log(`\n Logged in successfully to tenant: ${tenantId}`);
96
156
  }
97
- else {
98
- // TODO: Implement Device Authorization Flow when clientSecret is not provided.
99
- console.log('\n Please provide client secret for authentication.');
157
+ catch (error) {
158
+ console.error(`\n Login failed: ${error.message}`);
100
159
  process.exit(1);
101
160
  }
102
- yield writeTenantAuthInfo(tenantId, {
103
- clientSecret: argv.clientSecret,
104
- access_token: authResult.access_token,
105
- expires_in: authResult.expires_in,
106
- expires_at: new Date(Date.now() + authResult.expires_in * 1000).toISOString(),
107
- });
108
- yield writeTenantInfo({
109
- tenantId,
110
- organizationId,
111
- clientId,
112
- tenantName,
113
- authority: argv.authority || DEFAULT_SITECORE_AUTH_DOMAIN,
114
- audience: argv.audience || DEFAULT_SITECORE_AUTH_AUDIENCE,
115
- baseUrl: argv.baseUrl || DEFAULT_SITECORE_AUTH_BASE_URL,
116
- });
117
- setActiveTenant(tenantId);
118
- console.info(`\n Logged in successfully to tenant ${tenantId}.`);
119
161
  }),
120
162
  };
@@ -12,11 +12,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.logout = exports.unitMock = void 0;
13
13
  const tools_1 = require("@sitecore-content-sdk/core/tools");
14
14
  let { deleteTenantAuthInfo, getActiveTenant, clearActiveTenant, deleteKey } = tools_1.auth;
15
- const unitMock = (formModule) => {
16
- deleteTenantAuthInfo = formModule.deleteTenantAuthInfo || deleteTenantAuthInfo;
17
- getActiveTenant = formModule.getActiveTenant || getActiveTenant;
18
- clearActiveTenant = formModule.clearActiveTenant || clearActiveTenant;
19
- deleteKey = formModule.deleteKey || deleteKey;
15
+ const unitMock = (authModule) => {
16
+ deleteTenantAuthInfo = authModule.deleteTenantAuthInfo || deleteTenantAuthInfo;
17
+ getActiveTenant = authModule.getActiveTenant || getActiveTenant;
18
+ clearActiveTenant = authModule.clearActiveTenant || clearActiveTenant;
19
+ deleteKey = authModule.deleteKey || deleteKey;
20
20
  };
21
21
  exports.unitMock = unitMock;
22
22
  exports.logout = {
@@ -28,9 +28,9 @@ exports.logout = {
28
28
  console.error('\n No active tenant found. Please login first.');
29
29
  return;
30
30
  }
31
- deleteTenantAuthInfo(tenantId);
32
- deleteKey(tenantId);
31
+ yield deleteTenantAuthInfo(tenantId);
32
+ yield deleteKey(tenantId);
33
33
  clearActiveTenant();
34
- console.info(`\n Logged out from tenant ${tenantId}`);
34
+ console.log(`\n Logged out from tenant ${tenantId}`);
35
35
  }),
36
36
  };
@@ -12,10 +12,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.status = exports.unitMock = void 0;
13
13
  const tools_1 = require("@sitecore-content-sdk/core/tools");
14
14
  let { readTenantInfo, validateAndRenewAuthIfExpired } = tools_1.auth;
15
- const unitMock = (formModule) => {
16
- readTenantInfo = formModule.readTenantInfo || readTenantInfo;
15
+ const unitMock = (authModule) => {
16
+ readTenantInfo = authModule.readTenantInfo || readTenantInfo;
17
17
  validateAndRenewAuthIfExpired =
18
- formModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
18
+ authModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
19
19
  };
20
20
  exports.unitMock = unitMock;
21
21
  exports.status = {
@@ -24,7 +24,7 @@ exports.status = {
24
24
  handler: () => __awaiter(void 0, void 0, void 0, function* () {
25
25
  const context = yield validateAndRenewAuthIfExpired();
26
26
  if (!context) {
27
- console.log('\nNo valid authentication found. Please login.');
27
+ console.log('\n No valid authentication found. Please login.');
28
28
  return;
29
29
  }
30
30
  const tenantInfo = yield readTenantInfo(context.tenantId);
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.switchTenant = exports.unitMock = void 0;
13
+ const tools_1 = require("@sitecore-content-sdk/core/tools");
14
+ let { readTenantAuthInfo, validateAndRenewAuthIfExpired, setActiveTenant } = tools_1.auth;
15
+ const unitMock = (authModule) => {
16
+ readTenantAuthInfo = authModule.readTenantAuthInfo || readTenantAuthInfo;
17
+ setActiveTenant = authModule.setActiveTenant || setActiveTenant;
18
+ validateAndRenewAuthIfExpired =
19
+ authModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
20
+ };
21
+ exports.unitMock = unitMock;
22
+ exports.switchTenant = {
23
+ command: 'switch <tenantId>',
24
+ describe: 'Switch into another tenant that you have logged into previously',
25
+ builder: (yargs) => yargs.positional('tenantId', {
26
+ positional: true,
27
+ demandOption: true,
28
+ type: 'string',
29
+ describe: 'Tenant ID to switch into.',
30
+ }),
31
+ handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
32
+ const tenantId = argv.tenantId;
33
+ const currentContext = yield validateAndRenewAuthIfExpired();
34
+ if (!currentContext) {
35
+ console.error('\nNo valid authentication found. Please login.');
36
+ return;
37
+ }
38
+ if (currentContext.tenantId === tenantId) {
39
+ console.log(`Already in tenant: ${tenantId}`);
40
+ return;
41
+ }
42
+ const newTenantInfo = yield readTenantAuthInfo(tenantId);
43
+ if (!newTenantInfo) {
44
+ console.error(`Tenant info for ID '${tenantId}' not found in local storage.`);
45
+ console.error('Please ensure you have logged into the tenant by running the auth login command');
46
+ return;
47
+ }
48
+ setActiveTenant(tenantId);
49
+ const tenantContext = validateAndRenewAuthIfExpired();
50
+ if (!tenantContext) {
51
+ console.error(`Failed to switch to tenant '${tenantId}', remaining in tenant '${currentContext.tenantId}'.`);
52
+ setActiveTenant(currentContext.tenantId);
53
+ return;
54
+ }
55
+ console.log(`Switched to tenant: ${tenantId}`);
56
+ }),
57
+ };
@@ -2,6 +2,7 @@ import { login } from './login';
2
2
  import { logout } from './logout';
3
3
  import { status } from './status';
4
4
  import { list } from './list';
5
+ import { switchTenant } from './switch';
5
6
  /**
6
7
  * Registers the `auth` command group and its subcommands (`login`, `logout`, `status`, `list`) with Yargs.
7
8
  * @param {Argv} yargs - The Yargs instance used to define CLI commands.
@@ -13,7 +14,7 @@ export function builder(yargs) {
13
14
  describe: 'Performs authentication for content services',
14
15
  builder: (_yargs) => {
15
16
  return _yargs
16
- .command([login, logout, status, list])
17
+ .command([login, logout, status, list, switchTenant])
17
18
  .strict()
18
19
  .demandCommand(1, 'You need to specify a command to run')
19
20
  .help();
@@ -21,7 +21,7 @@ export const list = {
21
21
  console.log('\n No tenant information found.');
22
22
  return;
23
23
  }
24
- console.log('\n Known tenants:\n');
24
+ console.log('\nKnown tenants:\n');
25
25
  tenants.forEach((tenant, index) => {
26
26
  console.log(`Tenant ${index + 1}:`);
27
27
  console.log(` Tenant ID : ${tenant.tenantId}`);
@@ -9,12 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { auth } from '@sitecore-content-sdk/core/tools';
11
11
  import { constants } from '@sitecore-content-sdk/core';
12
- let { setActiveTenant, writeTenantAuthInfo, writeTenantInfo, clientCredentialsFlow } = auth;
12
+ let { setActiveTenant, writeTenantAuthInfo, writeTenantInfo, clientCredentialsFlow, getRefreshAccessToken, pollForDeviceToken, startDeviceAuthFlow, } = auth;
13
13
  export const unitMock = (formModule) => {
14
14
  setActiveTenant = formModule.setActiveTenant;
15
15
  writeTenantAuthInfo = formModule.writeTenantAuthInfo;
16
16
  writeTenantInfo = formModule.writeTenantInfo;
17
17
  clientCredentialsFlow = formModule.clientCredentialsFlow;
18
+ getRefreshAccessToken = formModule.getRefreshAccessToken;
19
+ pollForDeviceToken = formModule.pollForDeviceToken;
20
+ startDeviceAuthFlow = formModule.startDeviceAuthFlow;
18
21
  };
19
22
  export const login = {
20
23
  command: 'login',
@@ -66,51 +69,90 @@ export const login = {
66
69
  'baseUrl',
67
70
  ], 'Login Options:'),
68
71
  handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
69
- const { clientId } = argv;
70
- let authResult, tenantId, organizationId, tenantName;
71
72
  const { DEFAULT_SITECORE_AUTH_DOMAIN, DEFAULT_SITECORE_AUTH_AUDIENCE, DEFAULT_SITECORE_AUTH_BASE_URL, } = constants;
72
- if (argv.clientSecret) {
73
- try {
74
- const authData = yield clientCredentialsFlow({
73
+ const { clientId, clientSecret, organizationId, tenantId: inputTenantId, audience = DEFAULT_SITECORE_AUTH_AUDIENCE, authority = DEFAULT_SITECORE_AUTH_DOMAIN, baseUrl = DEFAULT_SITECORE_AUTH_BASE_URL, } = argv;
74
+ let authResponse;
75
+ let tenantId;
76
+ let tenantName;
77
+ let orgId;
78
+ try {
79
+ if (clientSecret) {
80
+ console.log('\n Using Client Credentials Flow...');
81
+ const { data, tokenTenantId, tokenOrgId, tokenTenantName } = yield clientCredentialsFlow({
75
82
  clientId,
76
- clientSecret: argv.clientSecret,
77
- organizationId: argv.organizationId,
78
- tenantId: argv.tenantId,
79
- audience: argv.audience,
80
- authority: argv.authority,
81
- baseUrl: argv.baseUrl,
83
+ clientSecret,
84
+ organizationId,
85
+ tenantId: inputTenantId,
86
+ audience,
87
+ authority,
88
+ baseUrl,
82
89
  });
83
- authResult = authData.data;
84
- tenantId = authData.tokenTenantId;
85
- organizationId = authData.tokenOrgId;
86
- tenantName = authData.tokenTenantName;
90
+ authResponse = data;
91
+ tenantId = tokenTenantId;
92
+ orgId = tokenOrgId;
93
+ tenantName = tokenTenantName;
87
94
  }
88
- catch (err) {
89
- console.error(`\n Login failed: ${err.message}`);
90
- process.exit(1);
95
+ else {
96
+ console.log('\n Using Device Authorization Flow...');
97
+ if (!inputTenantId) {
98
+ throw new Error('\n Tenant ID is required for Device Code Flow.');
99
+ }
100
+ if (!organizationId) {
101
+ throw new Error('\n Organization ID is required for Device Code Flow.');
102
+ }
103
+ const deviceAuthData = yield startDeviceAuthFlow({
104
+ clientId,
105
+ audience,
106
+ authority,
107
+ baseUrl,
108
+ });
109
+ const { device_code, user_code, verification_uri, verification_uri_complete, interval, } = deviceAuthData;
110
+ console.log('\nšŸ” Device Authorization Started');
111
+ if (verification_uri_complete) {
112
+ console.log(`\n šŸ‘‰ Open the following URL to authenticate:\n ${verification_uri_complete}`);
113
+ }
114
+ else {
115
+ console.log(`šŸ‘‰ Visit: ${verification_uri}`);
116
+ console.log(`šŸ”‘ Then enter the code: ${user_code}`);
117
+ }
118
+ const { refresh_token } = yield pollForDeviceToken({
119
+ clientId,
120
+ device_code,
121
+ authority,
122
+ interval,
123
+ });
124
+ // The initial device code flow does not support custom claims (e.g., tenantId, organizationId),
125
+ // which are required for proper token validation in our multi-tenant system.
126
+ // To include these claims, we immediately use the returned refresh_token to request a new
127
+ // access token with tenantId and organizationId explicitly provided.
128
+ authResponse = yield getRefreshAccessToken({
129
+ clientId,
130
+ refreshToken: refresh_token,
131
+ tenantId: inputTenantId,
132
+ organizationId,
133
+ authority,
134
+ });
135
+ tenantId = inputTenantId;
136
+ orgId = organizationId;
137
+ tenantName = authResponse.tenantName;
138
+ console.log('\n Device Authorization Completed');
91
139
  }
140
+ yield writeTenantAuthInfo(tenantId || inputTenantId, Object.assign({ expires_at: new Date(Date.now() + authResponse.expires_in * 1000).toISOString() }, authResponse));
141
+ yield writeTenantInfo({
142
+ tenantId,
143
+ organizationId: orgId,
144
+ clientId,
145
+ tenantName,
146
+ authority,
147
+ audience,
148
+ baseUrl,
149
+ });
150
+ setActiveTenant(tenantId);
151
+ console.log(`\n Logged in successfully to tenant: ${tenantId}`);
92
152
  }
93
- else {
94
- // TODO: Implement Device Authorization Flow when clientSecret is not provided.
95
- console.log('\n Please provide client secret for authentication.');
153
+ catch (error) {
154
+ console.error(`\n Login failed: ${error.message}`);
96
155
  process.exit(1);
97
156
  }
98
- yield writeTenantAuthInfo(tenantId, {
99
- clientSecret: argv.clientSecret,
100
- access_token: authResult.access_token,
101
- expires_in: authResult.expires_in,
102
- expires_at: new Date(Date.now() + authResult.expires_in * 1000).toISOString(),
103
- });
104
- yield writeTenantInfo({
105
- tenantId,
106
- organizationId,
107
- clientId,
108
- tenantName,
109
- authority: argv.authority || DEFAULT_SITECORE_AUTH_DOMAIN,
110
- audience: argv.audience || DEFAULT_SITECORE_AUTH_AUDIENCE,
111
- baseUrl: argv.baseUrl || DEFAULT_SITECORE_AUTH_BASE_URL,
112
- });
113
- setActiveTenant(tenantId);
114
- console.info(`\n Logged in successfully to tenant ${tenantId}.`);
115
157
  }),
116
158
  };
@@ -9,11 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { auth } from '@sitecore-content-sdk/core/tools';
11
11
  let { deleteTenantAuthInfo, getActiveTenant, clearActiveTenant, deleteKey } = auth;
12
- export const unitMock = (formModule) => {
13
- deleteTenantAuthInfo = formModule.deleteTenantAuthInfo || deleteTenantAuthInfo;
14
- getActiveTenant = formModule.getActiveTenant || getActiveTenant;
15
- clearActiveTenant = formModule.clearActiveTenant || clearActiveTenant;
16
- deleteKey = formModule.deleteKey || deleteKey;
12
+ export const unitMock = (authModule) => {
13
+ deleteTenantAuthInfo = authModule.deleteTenantAuthInfo || deleteTenantAuthInfo;
14
+ getActiveTenant = authModule.getActiveTenant || getActiveTenant;
15
+ clearActiveTenant = authModule.clearActiveTenant || clearActiveTenant;
16
+ deleteKey = authModule.deleteKey || deleteKey;
17
17
  };
18
18
  export const logout = {
19
19
  command: 'logout',
@@ -24,9 +24,9 @@ export const logout = {
24
24
  console.error('\n No active tenant found. Please login first.');
25
25
  return;
26
26
  }
27
- deleteTenantAuthInfo(tenantId);
28
- deleteKey(tenantId);
27
+ yield deleteTenantAuthInfo(tenantId);
28
+ yield deleteKey(tenantId);
29
29
  clearActiveTenant();
30
- console.info(`\n Logged out from tenant ${tenantId}`);
30
+ console.log(`\n Logged out from tenant ${tenantId}`);
31
31
  }),
32
32
  };
@@ -9,10 +9,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { auth } from '@sitecore-content-sdk/core/tools';
11
11
  let { readTenantInfo, validateAndRenewAuthIfExpired } = auth;
12
- export const unitMock = (formModule) => {
13
- readTenantInfo = formModule.readTenantInfo || readTenantInfo;
12
+ export const unitMock = (authModule) => {
13
+ readTenantInfo = authModule.readTenantInfo || readTenantInfo;
14
14
  validateAndRenewAuthIfExpired =
15
- formModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
15
+ authModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
16
16
  };
17
17
  export const status = {
18
18
  command: 'status',
@@ -20,7 +20,7 @@ export const status = {
20
20
  handler: () => __awaiter(void 0, void 0, void 0, function* () {
21
21
  const context = yield validateAndRenewAuthIfExpired();
22
22
  if (!context) {
23
- console.log('\nNo valid authentication found. Please login.');
23
+ console.log('\n No valid authentication found. Please login.');
24
24
  return;
25
25
  }
26
26
  const tenantInfo = yield readTenantInfo(context.tenantId);
@@ -0,0 +1,53 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { auth } from '@sitecore-content-sdk/core/tools';
11
+ let { readTenantAuthInfo, validateAndRenewAuthIfExpired, setActiveTenant } = auth;
12
+ export const unitMock = (authModule) => {
13
+ readTenantAuthInfo = authModule.readTenantAuthInfo || readTenantAuthInfo;
14
+ setActiveTenant = authModule.setActiveTenant || setActiveTenant;
15
+ validateAndRenewAuthIfExpired =
16
+ authModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
17
+ };
18
+ export const switchTenant = {
19
+ command: 'switch <tenantId>',
20
+ describe: 'Switch into another tenant that you have logged into previously',
21
+ builder: (yargs) => yargs.positional('tenantId', {
22
+ positional: true,
23
+ demandOption: true,
24
+ type: 'string',
25
+ describe: 'Tenant ID to switch into.',
26
+ }),
27
+ handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
28
+ const tenantId = argv.tenantId;
29
+ const currentContext = yield validateAndRenewAuthIfExpired();
30
+ if (!currentContext) {
31
+ console.error('\nNo valid authentication found. Please login.');
32
+ return;
33
+ }
34
+ if (currentContext.tenantId === tenantId) {
35
+ console.log(`Already in tenant: ${tenantId}`);
36
+ return;
37
+ }
38
+ const newTenantInfo = yield readTenantAuthInfo(tenantId);
39
+ if (!newTenantInfo) {
40
+ console.error(`Tenant info for ID '${tenantId}' not found in local storage.`);
41
+ console.error('Please ensure you have logged into the tenant by running the auth login command');
42
+ return;
43
+ }
44
+ setActiveTenant(tenantId);
45
+ const tenantContext = validateAndRenewAuthIfExpired();
46
+ if (!tenantContext) {
47
+ console.error(`Failed to switch to tenant '${tenantId}', remaining in tenant '${currentContext.tenantId}'.`);
48
+ setActiveTenant(currentContext.tenantId);
49
+ return;
50
+ }
51
+ console.log(`Switched to tenant: ${tenantId}`);
52
+ }),
53
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-content-sdk/cli",
3
- "version": "0.2.0-beta.16",
3
+ "version": "0.2.0-beta.18",
4
4
  "description": "Sitecore Content SDK CLI",
5
5
  "main": "dist/cjs/cli.js",
6
6
  "module": "dist/esm/cli.js",
@@ -34,7 +34,7 @@
34
34
  "url": "https://github.com/sitecore/content-sdk/issues"
35
35
  },
36
36
  "dependencies": {
37
- "@sitecore-content-sdk/core": "0.2.0-beta.16",
37
+ "@sitecore-content-sdk/core": "0.2.0-beta.18",
38
38
  "dotenv": "^16.5.0",
39
39
  "dotenv-expand": "^12.0.2",
40
40
  "resolve": "^1.22.10",
@@ -60,7 +60,7 @@
60
60
  "ts-node": "^10.9.1",
61
61
  "typescript": "~5.8.3"
62
62
  },
63
- "gitHead": "c3fdb664842dd1bf000cb6bca7c55cf6d33ff446",
63
+ "gitHead": "358368ae9455c999c64af4cf63d7daef08a4fcb1",
64
64
  "files": [
65
65
  "dist",
66
66
  "types"
@@ -1,3 +1,3 @@
1
1
  import { CommandModule } from 'yargs';
2
- export declare const unitMock: (formModule: any) => void;
2
+ export declare const unitMock: (authModule: any) => void;
3
3
  export declare const logout: CommandModule;
@@ -1,3 +1,3 @@
1
1
  import { CommandModule } from 'yargs';
2
- export declare const unitMock: (formModule: any) => void;
2
+ export declare const unitMock: (authModule: any) => void;
3
3
  export declare const status: CommandModule;
@@ -0,0 +1,5 @@
1
+ import { CommandModule } from 'yargs';
2
+ import { TenantInfo } from '@sitecore-content-sdk/core/tools';
3
+ export declare const unitMock: (authModule: any) => void;
4
+ export type SwitchArgs = Pick<TenantInfo, 'tenantId'>;
5
+ export declare const switchTenant: CommandModule<object, SwitchArgs>;