@sitecore-content-sdk/cli 0.2.0-beta.2 → 0.2.0-beta.21
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/README.md +1 -1
- package/dist/cjs/bin/sitecore-tools.js +6 -4
- package/dist/cjs/cli.js +8 -4
- package/dist/cjs/scripts/auth/index.js +27 -0
- package/dist/cjs/scripts/auth/list.js +41 -0
- package/dist/cjs/scripts/auth/login.js +162 -0
- package/dist/cjs/scripts/auth/logout.js +36 -0
- package/dist/cjs/scripts/auth/status.js +40 -0
- package/dist/cjs/scripts/auth/switch.js +57 -0
- package/dist/cjs/scripts/index.js +5 -5
- package/dist/cjs/scripts/{build.js → project/build.js} +2 -2
- package/dist/cjs/scripts/project/component/index.js +55 -0
- package/dist/cjs/scripts/{scaffold.js → project/component/scaffold.js} +2 -2
- package/dist/cjs/scripts/project/index.js +56 -0
- package/dist/esm/cli.js +8 -4
- package/dist/esm/scripts/auth/index.js +24 -0
- package/dist/esm/scripts/auth/list.js +37 -0
- package/dist/esm/scripts/auth/login.js +158 -0
- package/dist/esm/scripts/auth/logout.js +32 -0
- package/dist/esm/scripts/auth/status.js +36 -0
- package/dist/esm/scripts/auth/switch.js +53 -0
- package/dist/esm/scripts/index.js +4 -3
- package/dist/esm/scripts/{build.js → project/build.js} +2 -2
- package/dist/esm/scripts/project/component/index.js +19 -0
- package/dist/esm/scripts/{scaffold.js → project/component/scaffold.js} +2 -2
- package/dist/esm/scripts/project/index.js +20 -0
- package/package.json +14 -15
- package/types/scripts/auth/index.d.ts +7 -0
- package/types/scripts/auth/list.d.ts +3 -0
- package/types/scripts/auth/login.d.ts +4 -0
- package/types/scripts/auth/logout.d.ts +3 -0
- package/types/scripts/auth/status.d.ts +3 -0
- package/types/scripts/auth/switch.d.ts +5 -0
- package/types/scripts/index.d.ts +4 -3
- package/types/scripts/{build.d.ts → project/build.d.ts} +1 -1
- package/types/scripts/project/component/index.d.ts +5 -0
- package/types/scripts/project/index.d.ts +5 -0
- /package/types/scripts/{scaffold.d.ts → project/component/scaffold.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -50,16 +50,18 @@ const commands = __importStar(require("../scripts"));
|
|
|
50
50
|
// library from a package.json. Instead, include it from a relative
|
|
51
51
|
// path to this script file (which is likely a globally installed
|
|
52
52
|
// npm package).
|
|
53
|
-
// Not erroring here because
|
|
53
|
+
// Not erroring here because cli can be used in global mode.
|
|
54
54
|
cli = require('../cli').default;
|
|
55
55
|
console.warn('Sitecore Content SDK CLI is running in global mode because it was not installed in the local node_modules folder.');
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
// No error implies a projectLocalCli, which will load whatever
|
|
59
|
-
// version of
|
|
59
|
+
// version of content sdk cli you have installed in a local package.json
|
|
60
60
|
cli = require(projectLocalCli).default;
|
|
61
|
-
// Since we are in context of a project, load its environment variables
|
|
62
|
-
(0, process_env_1.default)(process.cwd());
|
|
63
61
|
}
|
|
62
|
+
// load environment variables from current working directory
|
|
63
|
+
// if the current working directory is not an app project root .env file will be missing and nothing will be loaded
|
|
64
|
+
// in that case loading environment variables will be handled by the actual cli command
|
|
65
|
+
(0, process_env_1.default)(process.cwd());
|
|
64
66
|
cli(commands);
|
|
65
67
|
});
|
package/dist/cjs/cli.js
CHANGED
|
@@ -48,18 +48,22 @@ function cli(commands) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
appCommands
|
|
51
|
+
appCommands
|
|
52
|
+
.command({
|
|
52
53
|
command: '*',
|
|
53
54
|
handler: (argv) => {
|
|
54
55
|
if (argv._.length > 0) {
|
|
55
|
-
console.error(`Command not found: "${argv._[0]}"
|
|
56
|
+
console.error(`Command not found: "${argv._[0]}"`);
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
58
|
-
console.error('No command provided
|
|
59
|
+
console.error('No command provided');
|
|
59
60
|
}
|
|
61
|
+
yargs_1.default.showHelp();
|
|
60
62
|
process.exit(1);
|
|
61
63
|
},
|
|
62
|
-
})
|
|
64
|
+
})
|
|
65
|
+
.demandCommand(1, 'You need to specify a command to run')
|
|
66
|
+
.strict();
|
|
63
67
|
yield appCommands.argv;
|
|
64
68
|
});
|
|
65
69
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.builder = builder;
|
|
4
|
+
const login_1 = require("./login");
|
|
5
|
+
const logout_1 = require("./logout");
|
|
6
|
+
const status_1 = require("./status");
|
|
7
|
+
const list_1 = require("./list");
|
|
8
|
+
const switch_1 = require("./switch");
|
|
9
|
+
/**
|
|
10
|
+
* Registers the `auth` command group and its subcommands (`login`, `logout`, `status`, `list`) with Yargs.
|
|
11
|
+
* @param {Argv} yargs - The Yargs instance used to define CLI commands.
|
|
12
|
+
* @returns The configured Yargs command group for authentication operations.
|
|
13
|
+
*/
|
|
14
|
+
function builder(yargs) {
|
|
15
|
+
return yargs.command({
|
|
16
|
+
command: 'auth',
|
|
17
|
+
describe: 'Performs authentication for content services',
|
|
18
|
+
builder: (_yargs) => {
|
|
19
|
+
return _yargs
|
|
20
|
+
.command([login_1.login, logout_1.logout, status_1.status, list_1.list, switch_1.switchTenant])
|
|
21
|
+
.strict()
|
|
22
|
+
.demandCommand(1, 'You need to specify a command to run')
|
|
23
|
+
.help();
|
|
24
|
+
},
|
|
25
|
+
handler: () => { },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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.list = exports.unitMock = void 0;
|
|
13
|
+
const tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
14
|
+
let { getAllTenantsInfo } = tools_1.auth;
|
|
15
|
+
const unitMock = (authModule) => {
|
|
16
|
+
getAllTenantsInfo = authModule.getAllTenantsInfo;
|
|
17
|
+
};
|
|
18
|
+
exports.unitMock = unitMock;
|
|
19
|
+
exports.list = {
|
|
20
|
+
command: 'list',
|
|
21
|
+
describe: 'List all known tenants',
|
|
22
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
+
const tenants = getAllTenantsInfo();
|
|
24
|
+
if (tenants.length === 0) {
|
|
25
|
+
console.log('\n No tenant information found.');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.log('\nKnown tenants:\n');
|
|
29
|
+
tenants.forEach((tenant, index) => {
|
|
30
|
+
console.log(`Tenant ${index + 1}:`);
|
|
31
|
+
console.log(` Tenant ID : ${tenant.tenantId}`);
|
|
32
|
+
console.log(` Tenant Name : ${tenant.tenantName || 'N/A'}`);
|
|
33
|
+
console.log(` Organization ID : ${tenant.organizationId}`);
|
|
34
|
+
console.log(` Client ID : ${tenant.clientId}`);
|
|
35
|
+
console.log(` Authority : ${tenant.authority || 'N/A'}`);
|
|
36
|
+
console.log(` Audience : ${tenant.audience || 'N/A'}`);
|
|
37
|
+
console.log(` Base URL : ${tenant.baseUrl || 'N/A'}`);
|
|
38
|
+
console.log();
|
|
39
|
+
});
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
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.login = exports.unitMock = void 0;
|
|
13
|
+
const tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
14
|
+
const core_1 = require("@sitecore-content-sdk/core");
|
|
15
|
+
let { setActiveTenant, writeTenantAuthInfo, writeTenantInfo, clientCredentialsFlow, getRefreshAccessToken, pollForDeviceToken, startDeviceAuthFlow, } = tools_1.auth;
|
|
16
|
+
const unitMock = (formModule) => {
|
|
17
|
+
setActiveTenant = formModule.setActiveTenant;
|
|
18
|
+
writeTenantAuthInfo = formModule.writeTenantAuthInfo;
|
|
19
|
+
writeTenantInfo = formModule.writeTenantInfo;
|
|
20
|
+
clientCredentialsFlow = formModule.clientCredentialsFlow;
|
|
21
|
+
getRefreshAccessToken = formModule.getRefreshAccessToken;
|
|
22
|
+
pollForDeviceToken = formModule.pollForDeviceToken;
|
|
23
|
+
startDeviceAuthFlow = formModule.startDeviceAuthFlow;
|
|
24
|
+
};
|
|
25
|
+
exports.unitMock = unitMock;
|
|
26
|
+
exports.login = {
|
|
27
|
+
command: 'login',
|
|
28
|
+
describe: 'Login into a tenant',
|
|
29
|
+
builder: (yargs) => yargs
|
|
30
|
+
.option('clientId', {
|
|
31
|
+
type: 'string',
|
|
32
|
+
requiresArg: true,
|
|
33
|
+
demandOption: true,
|
|
34
|
+
describe: 'Client ID for authentication',
|
|
35
|
+
})
|
|
36
|
+
.option('clientSecret', {
|
|
37
|
+
type: 'string',
|
|
38
|
+
demandOption: false,
|
|
39
|
+
describe: 'Client secret for authentication',
|
|
40
|
+
})
|
|
41
|
+
.option('tenantId', {
|
|
42
|
+
type: 'string',
|
|
43
|
+
demandOption: false,
|
|
44
|
+
describe: 'Tenant ID to login into.',
|
|
45
|
+
})
|
|
46
|
+
.option('organizationId', {
|
|
47
|
+
type: 'string',
|
|
48
|
+
demandOption: false,
|
|
49
|
+
describe: 'Organization ID to authenticate against.',
|
|
50
|
+
})
|
|
51
|
+
.option('authority', {
|
|
52
|
+
type: 'string',
|
|
53
|
+
demandOption: false,
|
|
54
|
+
describe: 'OAuth 2.0 authority URL for authentication.',
|
|
55
|
+
})
|
|
56
|
+
.option('audience', {
|
|
57
|
+
type: 'string',
|
|
58
|
+
demandOption: false,
|
|
59
|
+
describe: 'Intended recipient of the token, usually the API base URL.',
|
|
60
|
+
})
|
|
61
|
+
.option('baseUrl', {
|
|
62
|
+
type: 'string',
|
|
63
|
+
demandOption: false,
|
|
64
|
+
describe: 'Base URL for the API, used to construct the audience.',
|
|
65
|
+
})
|
|
66
|
+
.group([
|
|
67
|
+
'clientId',
|
|
68
|
+
'clientSecret',
|
|
69
|
+
'tenantId',
|
|
70
|
+
'organizationId',
|
|
71
|
+
'authority',
|
|
72
|
+
'audience',
|
|
73
|
+
'baseUrl',
|
|
74
|
+
], 'Login Options:'),
|
|
75
|
+
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
+
const { DEFAULT_SITECORE_AUTH_DOMAIN, DEFAULT_SITECORE_AUTH_AUDIENCE, DEFAULT_SITECORE_AUTH_BASE_URL, } = core_1.constants;
|
|
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({
|
|
86
|
+
clientId,
|
|
87
|
+
clientSecret,
|
|
88
|
+
organizationId,
|
|
89
|
+
tenantId: inputTenantId,
|
|
90
|
+
audience,
|
|
91
|
+
authority,
|
|
92
|
+
baseUrl,
|
|
93
|
+
});
|
|
94
|
+
authResponse = data;
|
|
95
|
+
tenantId = tokenTenantId;
|
|
96
|
+
orgId = tokenOrgId;
|
|
97
|
+
tenantName = tokenTenantName;
|
|
98
|
+
}
|
|
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');
|
|
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}`);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(`\n Login failed: ${error.message}`);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
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.logout = exports.unitMock = void 0;
|
|
13
|
+
const tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
14
|
+
let { deleteTenantAuthInfo, getActiveTenant, clearActiveTenant, deleteKey } = tools_1.auth;
|
|
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
|
+
};
|
|
21
|
+
exports.unitMock = unitMock;
|
|
22
|
+
exports.logout = {
|
|
23
|
+
command: 'logout',
|
|
24
|
+
describe: 'Logout from the active tenant',
|
|
25
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
const tenantId = getActiveTenant();
|
|
27
|
+
if (!tenantId) {
|
|
28
|
+
console.error('\n No active tenant found. Please login first.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
yield deleteTenantAuthInfo(tenantId);
|
|
32
|
+
yield deleteKey(tenantId);
|
|
33
|
+
clearActiveTenant();
|
|
34
|
+
console.log(`\n Logged out from tenant ${tenantId}`);
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
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.status = exports.unitMock = void 0;
|
|
13
|
+
const tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
14
|
+
let { readTenantInfo, validateAndRenewAuthIfExpired } = tools_1.auth;
|
|
15
|
+
const unitMock = (authModule) => {
|
|
16
|
+
readTenantInfo = authModule.readTenantInfo || readTenantInfo;
|
|
17
|
+
validateAndRenewAuthIfExpired =
|
|
18
|
+
authModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
|
|
19
|
+
};
|
|
20
|
+
exports.unitMock = unitMock;
|
|
21
|
+
exports.status = {
|
|
22
|
+
command: 'status',
|
|
23
|
+
describe: 'Show current status of active tenant',
|
|
24
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const context = yield validateAndRenewAuthIfExpired();
|
|
26
|
+
if (!context) {
|
|
27
|
+
console.log('\n No valid authentication found. Please login.');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const tenantInfo = yield readTenantInfo(context.tenantId);
|
|
31
|
+
console.log('\n Active tenant:');
|
|
32
|
+
console.log(` Tenant ID : ${context.tenantId}`);
|
|
33
|
+
console.log(` Tenant Name : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.tenantName) || 'N/A'}`);
|
|
34
|
+
console.log(` Organization ID : ${tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.organizationId}`);
|
|
35
|
+
console.log(` Client ID : ${tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.clientId}`);
|
|
36
|
+
console.log(` Authority : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.authority) || 'N/A'}`);
|
|
37
|
+
console.log(` Audience : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.audience) || 'N/A'}`);
|
|
38
|
+
console.log(` Base URL : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.baseUrl) || 'N/A'}`);
|
|
39
|
+
}),
|
|
40
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -35,8 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
};
|
|
36
36
|
})();
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.
|
|
39
|
-
const
|
|
40
|
-
exports.
|
|
41
|
-
const
|
|
42
|
-
exports.
|
|
38
|
+
exports.auth = exports.project = void 0;
|
|
39
|
+
const project = __importStar(require("./project"));
|
|
40
|
+
exports.project = project;
|
|
41
|
+
const auth = __importStar(require("./auth"));
|
|
42
|
+
exports.auth = auth;
|
|
@@ -14,9 +14,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.builder = exports.describe = exports.command = void 0;
|
|
16
16
|
exports.handler = handler;
|
|
17
|
-
const load_config_1 = __importDefault(require("
|
|
17
|
+
const load_config_1 = __importDefault(require("../../utils/load-config"));
|
|
18
18
|
exports.command = 'build';
|
|
19
|
-
exports.describe = '
|
|
19
|
+
exports.describe = 'Performs build time automation';
|
|
20
20
|
exports.builder = {
|
|
21
21
|
config: {
|
|
22
22
|
requiresArg: false,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.builder = builder;
|
|
37
|
+
const scaffold = __importStar(require("./scaffold"));
|
|
38
|
+
/**
|
|
39
|
+
* @param {Argv} yargs
|
|
40
|
+
*/
|
|
41
|
+
function builder(yargs) {
|
|
42
|
+
return yargs.command({
|
|
43
|
+
command: 'component',
|
|
44
|
+
describe: 'Performs component level operations',
|
|
45
|
+
builder: (_yargs) => {
|
|
46
|
+
_yargs = _yargs
|
|
47
|
+
.command([scaffold])
|
|
48
|
+
.strict()
|
|
49
|
+
.demandCommand(1, 'You need to specify a command to run');
|
|
50
|
+
_yargs = scaffold.builder(_yargs);
|
|
51
|
+
return _yargs;
|
|
52
|
+
},
|
|
53
|
+
handler: () => { },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
@@ -7,13 +7,13 @@ exports.builder = builder;
|
|
|
7
7
|
exports.args = args;
|
|
8
8
|
exports.handler = handler;
|
|
9
9
|
const tools_1 = require("@sitecore-content-sdk/core/tools");
|
|
10
|
-
const load_config_1 = __importDefault(require("
|
|
10
|
+
const load_config_1 = __importDefault(require("../../../utils/load-config"));
|
|
11
11
|
const config_1 = require("@sitecore-content-sdk/core/config");
|
|
12
12
|
/**
|
|
13
13
|
* @param {Argv} yargs
|
|
14
14
|
*/
|
|
15
15
|
function builder(yargs) {
|
|
16
|
-
return yargs.command('scaffold <componentName>', 'Scaffolds a new component
|
|
16
|
+
return yargs.command('scaffold <componentName>', 'Scaffolds a new component', args, handler);
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* @param {Argv} yargs
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.builder = builder;
|
|
37
|
+
const build = __importStar(require("./build"));
|
|
38
|
+
const component = __importStar(require("./component"));
|
|
39
|
+
/**
|
|
40
|
+
* @param {Argv} yargs
|
|
41
|
+
*/
|
|
42
|
+
function builder(yargs) {
|
|
43
|
+
return yargs.command({
|
|
44
|
+
command: 'project',
|
|
45
|
+
describe: 'Performs project level operations',
|
|
46
|
+
builder: (_yargs) => {
|
|
47
|
+
_yargs = _yargs
|
|
48
|
+
.command([build, component])
|
|
49
|
+
.strict()
|
|
50
|
+
.demandCommand(1, 'You need to specify a command to run');
|
|
51
|
+
_yargs = component.builder(_yargs);
|
|
52
|
+
return _yargs;
|
|
53
|
+
},
|
|
54
|
+
handler: () => { },
|
|
55
|
+
});
|
|
56
|
+
}
|
package/dist/esm/cli.js
CHANGED
|
@@ -42,18 +42,22 @@ export default function cli(commands) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
appCommands
|
|
45
|
+
appCommands
|
|
46
|
+
.command({
|
|
46
47
|
command: '*',
|
|
47
48
|
handler: (argv) => {
|
|
48
49
|
if (argv._.length > 0) {
|
|
49
|
-
console.error(`Command not found: "${argv._[0]}"
|
|
50
|
+
console.error(`Command not found: "${argv._[0]}"`);
|
|
50
51
|
}
|
|
51
52
|
else {
|
|
52
|
-
console.error('No command provided
|
|
53
|
+
console.error('No command provided');
|
|
53
54
|
}
|
|
55
|
+
yargs.showHelp();
|
|
54
56
|
process.exit(1);
|
|
55
57
|
},
|
|
56
|
-
})
|
|
58
|
+
})
|
|
59
|
+
.demandCommand(1, 'You need to specify a command to run')
|
|
60
|
+
.strict();
|
|
57
61
|
yield appCommands.argv;
|
|
58
62
|
});
|
|
59
63
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { login } from './login';
|
|
2
|
+
import { logout } from './logout';
|
|
3
|
+
import { status } from './status';
|
|
4
|
+
import { list } from './list';
|
|
5
|
+
import { switchTenant } from './switch';
|
|
6
|
+
/**
|
|
7
|
+
* Registers the `auth` command group and its subcommands (`login`, `logout`, `status`, `list`) with Yargs.
|
|
8
|
+
* @param {Argv} yargs - The Yargs instance used to define CLI commands.
|
|
9
|
+
* @returns The configured Yargs command group for authentication operations.
|
|
10
|
+
*/
|
|
11
|
+
export function builder(yargs) {
|
|
12
|
+
return yargs.command({
|
|
13
|
+
command: 'auth',
|
|
14
|
+
describe: 'Performs authentication for content services',
|
|
15
|
+
builder: (_yargs) => {
|
|
16
|
+
return _yargs
|
|
17
|
+
.command([login, logout, status, list, switchTenant])
|
|
18
|
+
.strict()
|
|
19
|
+
.demandCommand(1, 'You need to specify a command to run')
|
|
20
|
+
.help();
|
|
21
|
+
},
|
|
22
|
+
handler: () => { },
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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 { getAllTenantsInfo } = auth;
|
|
12
|
+
export const unitMock = (authModule) => {
|
|
13
|
+
getAllTenantsInfo = authModule.getAllTenantsInfo;
|
|
14
|
+
};
|
|
15
|
+
export const list = {
|
|
16
|
+
command: 'list',
|
|
17
|
+
describe: 'List all known tenants',
|
|
18
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
const tenants = getAllTenantsInfo();
|
|
20
|
+
if (tenants.length === 0) {
|
|
21
|
+
console.log('\n No tenant information found.');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log('\nKnown tenants:\n');
|
|
25
|
+
tenants.forEach((tenant, index) => {
|
|
26
|
+
console.log(`Tenant ${index + 1}:`);
|
|
27
|
+
console.log(` Tenant ID : ${tenant.tenantId}`);
|
|
28
|
+
console.log(` Tenant Name : ${tenant.tenantName || 'N/A'}`);
|
|
29
|
+
console.log(` Organization ID : ${tenant.organizationId}`);
|
|
30
|
+
console.log(` Client ID : ${tenant.clientId}`);
|
|
31
|
+
console.log(` Authority : ${tenant.authority || 'N/A'}`);
|
|
32
|
+
console.log(` Audience : ${tenant.audience || 'N/A'}`);
|
|
33
|
+
console.log(` Base URL : ${tenant.baseUrl || 'N/A'}`);
|
|
34
|
+
console.log();
|
|
35
|
+
});
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
import { constants } from '@sitecore-content-sdk/core';
|
|
12
|
+
let { setActiveTenant, writeTenantAuthInfo, writeTenantInfo, clientCredentialsFlow, getRefreshAccessToken, pollForDeviceToken, startDeviceAuthFlow, } = auth;
|
|
13
|
+
export const unitMock = (formModule) => {
|
|
14
|
+
setActiveTenant = formModule.setActiveTenant;
|
|
15
|
+
writeTenantAuthInfo = formModule.writeTenantAuthInfo;
|
|
16
|
+
writeTenantInfo = formModule.writeTenantInfo;
|
|
17
|
+
clientCredentialsFlow = formModule.clientCredentialsFlow;
|
|
18
|
+
getRefreshAccessToken = formModule.getRefreshAccessToken;
|
|
19
|
+
pollForDeviceToken = formModule.pollForDeviceToken;
|
|
20
|
+
startDeviceAuthFlow = formModule.startDeviceAuthFlow;
|
|
21
|
+
};
|
|
22
|
+
export const login = {
|
|
23
|
+
command: 'login',
|
|
24
|
+
describe: 'Login into a tenant',
|
|
25
|
+
builder: (yargs) => yargs
|
|
26
|
+
.option('clientId', {
|
|
27
|
+
type: 'string',
|
|
28
|
+
requiresArg: true,
|
|
29
|
+
demandOption: true,
|
|
30
|
+
describe: 'Client ID for authentication',
|
|
31
|
+
})
|
|
32
|
+
.option('clientSecret', {
|
|
33
|
+
type: 'string',
|
|
34
|
+
demandOption: false,
|
|
35
|
+
describe: 'Client secret for authentication',
|
|
36
|
+
})
|
|
37
|
+
.option('tenantId', {
|
|
38
|
+
type: 'string',
|
|
39
|
+
demandOption: false,
|
|
40
|
+
describe: 'Tenant ID to login into.',
|
|
41
|
+
})
|
|
42
|
+
.option('organizationId', {
|
|
43
|
+
type: 'string',
|
|
44
|
+
demandOption: false,
|
|
45
|
+
describe: 'Organization ID to authenticate against.',
|
|
46
|
+
})
|
|
47
|
+
.option('authority', {
|
|
48
|
+
type: 'string',
|
|
49
|
+
demandOption: false,
|
|
50
|
+
describe: 'OAuth 2.0 authority URL for authentication.',
|
|
51
|
+
})
|
|
52
|
+
.option('audience', {
|
|
53
|
+
type: 'string',
|
|
54
|
+
demandOption: false,
|
|
55
|
+
describe: 'Intended recipient of the token, usually the API base URL.',
|
|
56
|
+
})
|
|
57
|
+
.option('baseUrl', {
|
|
58
|
+
type: 'string',
|
|
59
|
+
demandOption: false,
|
|
60
|
+
describe: 'Base URL for the API, used to construct the audience.',
|
|
61
|
+
})
|
|
62
|
+
.group([
|
|
63
|
+
'clientId',
|
|
64
|
+
'clientSecret',
|
|
65
|
+
'tenantId',
|
|
66
|
+
'organizationId',
|
|
67
|
+
'authority',
|
|
68
|
+
'audience',
|
|
69
|
+
'baseUrl',
|
|
70
|
+
], 'Login Options:'),
|
|
71
|
+
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
const { DEFAULT_SITECORE_AUTH_DOMAIN, DEFAULT_SITECORE_AUTH_AUDIENCE, DEFAULT_SITECORE_AUTH_BASE_URL, } = constants;
|
|
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({
|
|
82
|
+
clientId,
|
|
83
|
+
clientSecret,
|
|
84
|
+
organizationId,
|
|
85
|
+
tenantId: inputTenantId,
|
|
86
|
+
audience,
|
|
87
|
+
authority,
|
|
88
|
+
baseUrl,
|
|
89
|
+
});
|
|
90
|
+
authResponse = data;
|
|
91
|
+
tenantId = tokenTenantId;
|
|
92
|
+
orgId = tokenOrgId;
|
|
93
|
+
tenantName = tokenTenantName;
|
|
94
|
+
}
|
|
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');
|
|
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}`);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error(`\n Login failed: ${error.message}`);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
}),
|
|
158
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
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 { deleteTenantAuthInfo, getActiveTenant, clearActiveTenant, deleteKey } = auth;
|
|
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
|
+
};
|
|
18
|
+
export const logout = {
|
|
19
|
+
command: 'logout',
|
|
20
|
+
describe: 'Logout from the active tenant',
|
|
21
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
const tenantId = getActiveTenant();
|
|
23
|
+
if (!tenantId) {
|
|
24
|
+
console.error('\n No active tenant found. Please login first.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
yield deleteTenantAuthInfo(tenantId);
|
|
28
|
+
yield deleteKey(tenantId);
|
|
29
|
+
clearActiveTenant();
|
|
30
|
+
console.log(`\n Logged out from tenant ${tenantId}`);
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
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 { readTenantInfo, validateAndRenewAuthIfExpired } = auth;
|
|
12
|
+
export const unitMock = (authModule) => {
|
|
13
|
+
readTenantInfo = authModule.readTenantInfo || readTenantInfo;
|
|
14
|
+
validateAndRenewAuthIfExpired =
|
|
15
|
+
authModule.validateAndRenewAuthIfExpired || validateAndRenewAuthIfExpired;
|
|
16
|
+
};
|
|
17
|
+
export const status = {
|
|
18
|
+
command: 'status',
|
|
19
|
+
describe: 'Show current status of active tenant',
|
|
20
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
const context = yield validateAndRenewAuthIfExpired();
|
|
22
|
+
if (!context) {
|
|
23
|
+
console.log('\n No valid authentication found. Please login.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const tenantInfo = yield readTenantInfo(context.tenantId);
|
|
27
|
+
console.log('\n Active tenant:');
|
|
28
|
+
console.log(` Tenant ID : ${context.tenantId}`);
|
|
29
|
+
console.log(` Tenant Name : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.tenantName) || 'N/A'}`);
|
|
30
|
+
console.log(` Organization ID : ${tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.organizationId}`);
|
|
31
|
+
console.log(` Client ID : ${tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.clientId}`);
|
|
32
|
+
console.log(` Authority : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.authority) || 'N/A'}`);
|
|
33
|
+
console.log(` Audience : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.audience) || 'N/A'}`);
|
|
34
|
+
console.log(` Base URL : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.baseUrl) || 'N/A'}`);
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// commands available when running from an app location (with CLI installed to local node_modules)
|
|
2
2
|
// e.g. setup, deploy
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
5
|
-
export {
|
|
3
|
+
import * as project from './project';
|
|
4
|
+
import * as auth from './auth';
|
|
5
|
+
export { project };
|
|
6
|
+
export { auth };
|
|
@@ -7,9 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import loadCliConfig from '
|
|
10
|
+
import loadCliConfig from '../../utils/load-config';
|
|
11
11
|
export const command = 'build';
|
|
12
|
-
export const describe = '
|
|
12
|
+
export const describe = 'Performs build time automation';
|
|
13
13
|
export const builder = {
|
|
14
14
|
config: {
|
|
15
15
|
requiresArg: false,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as scaffold from './scaffold';
|
|
2
|
+
/**
|
|
3
|
+
* @param {Argv} yargs
|
|
4
|
+
*/
|
|
5
|
+
export function builder(yargs) {
|
|
6
|
+
return yargs.command({
|
|
7
|
+
command: 'component',
|
|
8
|
+
describe: 'Performs component level operations',
|
|
9
|
+
builder: (_yargs) => {
|
|
10
|
+
_yargs = _yargs
|
|
11
|
+
.command([scaffold])
|
|
12
|
+
.strict()
|
|
13
|
+
.demandCommand(1, 'You need to specify a command to run');
|
|
14
|
+
_yargs = scaffold.builder(_yargs);
|
|
15
|
+
return _yargs;
|
|
16
|
+
},
|
|
17
|
+
handler: () => { },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { scaffoldComponent } from '@sitecore-content-sdk/core/tools';
|
|
2
|
-
import loadCliConfig from '
|
|
2
|
+
import loadCliConfig from '../../../utils/load-config';
|
|
3
3
|
import { ComponentTemplateType } from '@sitecore-content-sdk/core/config';
|
|
4
4
|
/**
|
|
5
5
|
* @param {Argv} yargs
|
|
6
6
|
*/
|
|
7
7
|
export function builder(yargs) {
|
|
8
|
-
return yargs.command('scaffold <componentName>', 'Scaffolds a new component
|
|
8
|
+
return yargs.command('scaffold <componentName>', 'Scaffolds a new component', args, handler);
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* @param {Argv} yargs
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as build from './build';
|
|
2
|
+
import * as component from './component';
|
|
3
|
+
/**
|
|
4
|
+
* @param {Argv} yargs
|
|
5
|
+
*/
|
|
6
|
+
export function builder(yargs) {
|
|
7
|
+
return yargs.command({
|
|
8
|
+
command: 'project',
|
|
9
|
+
describe: 'Performs project level operations',
|
|
10
|
+
builder: (_yargs) => {
|
|
11
|
+
_yargs = _yargs
|
|
12
|
+
.command([build, component])
|
|
13
|
+
.strict()
|
|
14
|
+
.demandCommand(1, 'You need to specify a command to run');
|
|
15
|
+
_yargs = component.builder(_yargs);
|
|
16
|
+
return _yargs;
|
|
17
|
+
},
|
|
18
|
+
handler: () => { },
|
|
19
|
+
});
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-content-sdk/cli",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.21",
|
|
4
4
|
"description": "Sitecore Content SDK CLI",
|
|
5
5
|
"main": "dist/cjs/cli.js",
|
|
6
6
|
"module": "dist/esm/cli.js",
|
|
@@ -34,34 +34,33 @@
|
|
|
34
34
|
"url": "https://github.com/sitecore/content-sdk/issues"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@sitecore-content-sdk/core": "0.2.0-beta.
|
|
38
|
-
"dotenv": "^16.
|
|
39
|
-
"dotenv-expand": "^12.0.
|
|
37
|
+
"@sitecore-content-sdk/core": "0.2.0-beta.21",
|
|
38
|
+
"dotenv": "^16.5.0",
|
|
39
|
+
"dotenv-expand": "^12.0.2",
|
|
40
40
|
"resolve": "^1.22.10",
|
|
41
41
|
"tmp": "^0.2.3",
|
|
42
|
-
"tsx": "^4.19.
|
|
42
|
+
"tsx": "^4.19.4",
|
|
43
43
|
"yargs": "^17.7.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@types/chai": "^
|
|
46
|
+
"@types/chai": "^5.2.2",
|
|
47
47
|
"@types/mocha": "^10.0.10",
|
|
48
|
-
"@types/node": "^22.13
|
|
48
|
+
"@types/node": "^22.15.13",
|
|
49
49
|
"@types/resolve": "^1.20.6",
|
|
50
|
-
"@types/sinon": "^
|
|
50
|
+
"@types/sinon": "^17.0.4",
|
|
51
51
|
"@types/tmp": "^0.2.6",
|
|
52
52
|
"@types/yargs": "^17.0.33",
|
|
53
|
-
"chai": "^4.
|
|
54
|
-
"
|
|
55
|
-
"del-cli": "^5.0.0",
|
|
53
|
+
"chai": "^4.4.1",
|
|
54
|
+
"del-cli": "^6.0.0",
|
|
56
55
|
"eslint": "^8.56.0",
|
|
57
|
-
"mocha": "^11.
|
|
56
|
+
"mocha": "^11.2.2",
|
|
58
57
|
"nyc": "^17.1.0",
|
|
59
58
|
"proxyquire": "^2.1.3",
|
|
60
|
-
"sinon": "^
|
|
59
|
+
"sinon": "^20.0.0",
|
|
61
60
|
"ts-node": "^10.9.1",
|
|
62
|
-
"typescript": "~5.
|
|
61
|
+
"typescript": "~5.8.3"
|
|
63
62
|
},
|
|
64
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "09fafe89fe05ef49b349bfc139ed6174940564ba",
|
|
65
64
|
"files": [
|
|
66
65
|
"dist",
|
|
67
66
|
"types"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Argv } from 'yargs';
|
|
2
|
+
/**
|
|
3
|
+
* Registers the `auth` command group and its subcommands (`login`, `logout`, `status`, `list`) with Yargs.
|
|
4
|
+
* @param {Argv} yargs - The Yargs instance used to define CLI commands.
|
|
5
|
+
* @returns The configured Yargs command group for authentication operations.
|
|
6
|
+
*/
|
|
7
|
+
export declare function builder(yargs: Argv): Argv<{}>;
|
|
@@ -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>;
|
package/types/scripts/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as
|
|
3
|
-
export {
|
|
1
|
+
import * as project from './project';
|
|
2
|
+
import * as auth from './auth';
|
|
3
|
+
export { project };
|
|
4
|
+
export { auth };
|
|
File without changes
|