@sitecore-content-sdk/cli 0.2.0-beta.1 → 0.2.0-beta.11

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 (50) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/bin/sitecore-tools.js +6 -4
  3. package/dist/cjs/cli.js +8 -4
  4. package/dist/cjs/scripts/auth/index.js +26 -0
  5. package/dist/cjs/scripts/auth/list.js +36 -0
  6. package/dist/cjs/scripts/auth/login.js +112 -0
  7. package/dist/cjs/scripts/auth/logout.js +28 -0
  8. package/dist/cjs/scripts/auth/models.js +2 -0
  9. package/dist/cjs/scripts/auth/status.js +34 -0
  10. package/dist/cjs/scripts/index.js +5 -5
  11. package/dist/cjs/scripts/{build.js → project/build.js} +2 -2
  12. package/dist/cjs/scripts/project/component/index.js +55 -0
  13. package/dist/cjs/scripts/{scaffold.js → project/component/scaffold.js} +2 -2
  14. package/dist/cjs/scripts/project/index.js +56 -0
  15. package/dist/cjs/utils/auth/flow.js +72 -0
  16. package/dist/cjs/utils/auth/renewal.js +95 -0
  17. package/dist/cjs/utils/auth/tenant-state.js +91 -0
  18. package/dist/cjs/utils/auth/tenant-store.js +212 -0
  19. package/dist/esm/cli.js +8 -4
  20. package/dist/esm/scripts/auth/index.js +23 -0
  21. package/dist/esm/scripts/auth/list.js +33 -0
  22. package/dist/esm/scripts/auth/login.js +109 -0
  23. package/dist/esm/scripts/auth/logout.js +25 -0
  24. package/dist/esm/scripts/auth/models.js +1 -0
  25. package/dist/esm/scripts/auth/status.js +31 -0
  26. package/dist/esm/scripts/index.js +4 -3
  27. package/dist/esm/scripts/{build.js → project/build.js} +2 -2
  28. package/dist/esm/scripts/project/component/index.js +19 -0
  29. package/dist/esm/scripts/{scaffold.js → project/component/scaffold.js} +2 -2
  30. package/dist/esm/scripts/project/index.js +20 -0
  31. package/dist/esm/utils/auth/flow.js +68 -0
  32. package/dist/esm/utils/auth/renewal.js +90 -0
  33. package/dist/esm/utils/auth/tenant-state.js +53 -0
  34. package/dist/esm/utils/auth/tenant-store.js +170 -0
  35. package/package.json +14 -15
  36. package/types/scripts/auth/index.d.ts +7 -0
  37. package/types/scripts/auth/list.d.ts +2 -0
  38. package/types/scripts/auth/login.d.ts +3 -0
  39. package/types/scripts/auth/logout.d.ts +2 -0
  40. package/types/scripts/auth/models.d.ts +94 -0
  41. package/types/scripts/auth/status.d.ts +2 -0
  42. package/types/scripts/index.d.ts +4 -3
  43. package/types/scripts/{build.d.ts → project/build.d.ts} +1 -1
  44. package/types/scripts/project/component/index.d.ts +5 -0
  45. package/types/scripts/project/index.d.ts +5 -0
  46. package/types/utils/auth/flow.d.ts +24 -0
  47. package/types/utils/auth/renewal.d.ts +22 -0
  48. package/types/utils/auth/tenant-state.d.ts +14 -0
  49. package/types/utils/auth/tenant-store.d.ts +40 -0
  50. /package/types/scripts/{scaffold.d.ts → project/component/scaffold.d.ts} +0 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Sitecore Content SDK CLI Tools
1
+ # Sitecore Content SDK CLI
2
2
 
3
3
  This module is provided as a part of Sitecore Contents SDK. It contains the Sitecore Content SDK command line interface.
4
4
 
@@ -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 we might use this in future for scaffolding.
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 jss-cli you have installed in a local package.json
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.command({
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]}". Use --help to see available commands.`);
56
+ console.error(`Command not found: "${argv._[0]}"`);
56
57
  }
57
58
  else {
58
- console.error('No command provided. Use --help to see available commands.');
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,26 @@
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
+ /**
9
+ * Registers the `auth` command group and its subcommands (`login`, `logout`, `status`, `list`) with Yargs.
10
+ * @param {Argv} yargs - The Yargs instance used to define CLI commands.
11
+ * @returns The configured Yargs command group for authentication operations.
12
+ */
13
+ function builder(yargs) {
14
+ return yargs.command({
15
+ command: 'auth',
16
+ describe: 'Performs authentication for content services',
17
+ builder: (_yargs) => {
18
+ return _yargs
19
+ .command([login_1.login, logout_1.logout, status_1.status, list_1.list])
20
+ .strict()
21
+ .demandCommand(1, 'You need to specify a command to run')
22
+ .help();
23
+ },
24
+ handler: () => { },
25
+ });
26
+ }
@@ -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.list = void 0;
13
+ const tenant_store_1 = require("../../utils/auth/tenant-store");
14
+ exports.list = {
15
+ command: 'list',
16
+ describe: 'List all known tenants',
17
+ handler: () => __awaiter(void 0, void 0, void 0, function* () {
18
+ const tenants = (0, tenant_store_1.getAllTenantsInfo)();
19
+ if (tenants.length === 0) {
20
+ console.log('\n No tenant information found.');
21
+ return;
22
+ }
23
+ console.log('\n Known tenants:\n');
24
+ tenants.forEach((tenant, index) => {
25
+ console.log(`Tenant ${index + 1}:`);
26
+ console.log(` Tenant ID : ${tenant.tenantId}`);
27
+ console.log(` Tenant Name : ${tenant.tenantName || 'N/A'}`);
28
+ console.log(` Organization ID : ${tenant.organizationId}`);
29
+ console.log(` Client ID : ${tenant.clientId}`);
30
+ console.log(` Authority : ${tenant.authority || 'N/A'}`);
31
+ console.log(` Audience : ${tenant.audience || 'N/A'}`);
32
+ console.log(` Base URL : ${tenant.baseUrl || 'N/A'}`);
33
+ console.log();
34
+ });
35
+ }),
36
+ };
@@ -0,0 +1,112 @@
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 = void 0;
13
+ const flow_1 = require("../../utils/auth/flow");
14
+ const tenant_store_1 = require("../../utils/auth/tenant-store");
15
+ const tenant_state_1 = require("../../utils/auth/tenant-state");
16
+ exports.login = {
17
+ command: 'login',
18
+ describe: 'Login into a tenant',
19
+ builder: (yargs) => yargs
20
+ .option('clientId', {
21
+ type: 'string',
22
+ requiresArg: true,
23
+ demandOption: true,
24
+ describe: 'Client ID for authentication',
25
+ })
26
+ .option('clientSecret', {
27
+ type: 'string',
28
+ demandOption: false,
29
+ describe: 'Client secret for authentication',
30
+ })
31
+ .option('tenantId', {
32
+ type: 'string',
33
+ demandOption: false,
34
+ describe: 'Tenant ID to login into.',
35
+ })
36
+ .option('organizationId', {
37
+ type: 'string',
38
+ demandOption: false,
39
+ describe: 'Organization ID to authenticate against.',
40
+ })
41
+ .option('authority', {
42
+ type: 'string',
43
+ demandOption: false,
44
+ describe: 'OAuth 2.0 authority URL for authentication.',
45
+ })
46
+ .option('audience', {
47
+ type: 'string',
48
+ demandOption: false,
49
+ describe: 'Intended recipient of the token, usually the API base URL.',
50
+ })
51
+ .option('baseUrl', {
52
+ type: 'string',
53
+ demandOption: false,
54
+ describe: 'Base URL for the API, used to construct the audience.',
55
+ })
56
+ .group([
57
+ 'clientId',
58
+ 'clientSecret',
59
+ 'tenantId',
60
+ 'organizationId',
61
+ 'authority',
62
+ 'audience',
63
+ 'baseUrl',
64
+ ], 'Login Options:'),
65
+ handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
66
+ const { clientId } = argv;
67
+ let authResult, tenantId, organizationId, tenantName;
68
+ if (argv.clientSecret) {
69
+ try {
70
+ const authData = yield (0, flow_1.clientCredentialsFlow)({
71
+ clientId,
72
+ clientSecret: argv.clientSecret,
73
+ organizationId: argv.organizationId,
74
+ tenantId: argv.tenantId,
75
+ audience: argv.audience,
76
+ authority: argv.authority,
77
+ baseUrl: argv.baseUrl,
78
+ });
79
+ authResult = authData.data;
80
+ tenantId = authData.tokenTenantId;
81
+ organizationId = authData.tokenOrgId;
82
+ tenantName = authData.tokenTenantName;
83
+ }
84
+ catch (err) {
85
+ console.error(`\n Login failed: ${err.message}`);
86
+ process.exit(1);
87
+ }
88
+ }
89
+ else {
90
+ // TODO: Implement Device Authorization Flow when clientSecret is not provided.
91
+ console.log('\n Please provide client secret for authentication.');
92
+ process.exit(1);
93
+ }
94
+ yield (0, tenant_store_1.writeTenantAuthInfo)(tenantId, {
95
+ clientSecret: argv.clientSecret,
96
+ access_token: authResult.access_token,
97
+ expires_in: authResult.expires_in,
98
+ expires_at: new Date(Date.now() + authResult.expires_in * 1000).toISOString(),
99
+ });
100
+ yield (0, tenant_store_1.writeTenantInfo)({
101
+ tenantId,
102
+ organizationId,
103
+ clientId,
104
+ tenantName,
105
+ authority: argv.authority || flow_1.AUTH0_DOMAIN,
106
+ audience: argv.audience || flow_1.AUDIENCE,
107
+ baseUrl: argv.baseUrl || flow_1.BASE_URL,
108
+ });
109
+ (0, tenant_state_1.setActiveTenant)(tenantId);
110
+ console.info(`\n Logged in successfully to tenant ${tenantId}.`);
111
+ }),
112
+ };
@@ -0,0 +1,28 @@
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 = void 0;
13
+ const tenant_state_1 = require("../../utils/auth/tenant-state");
14
+ const tenant_store_1 = require("../../utils/auth/tenant-store");
15
+ exports.logout = {
16
+ command: 'logout',
17
+ describe: 'Logout from the active tenant',
18
+ handler: () => __awaiter(void 0, void 0, void 0, function* () {
19
+ const tenantId = (0, tenant_state_1.getActiveTenant)();
20
+ if (!tenantId) {
21
+ console.error('\n No active tenant found. Please login first.');
22
+ return;
23
+ }
24
+ (0, tenant_state_1.clearActiveTenant)();
25
+ (0, tenant_store_1.deleteTenantAuthInfo)(tenantId);
26
+ console.info(`\n Logged out from tenant ${tenantId}`);
27
+ }),
28
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,34 @@
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 = void 0;
13
+ const tenant_store_1 = require("../../utils/auth/tenant-store");
14
+ const renewal_1 = require("../../utils/auth/renewal");
15
+ exports.status = {
16
+ command: 'status',
17
+ describe: 'Show current status of active tenant',
18
+ handler: () => __awaiter(void 0, void 0, void 0, function* () {
19
+ const context = yield (0, renewal_1.renewAuthIfExpired)();
20
+ if (!context) {
21
+ console.log('\n No valid authentication found. Please login.');
22
+ return;
23
+ }
24
+ const tenantInfo = yield (0, tenant_store_1.readTenantInfo)(context.tenantId);
25
+ console.log('\n Active tenant:');
26
+ console.log(` Tenant ID : ${context.tenantId}`);
27
+ console.log(` Tenant Name : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.tenantName) || 'N/A'}`);
28
+ console.log(` Organization ID : ${tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.organizationId}`);
29
+ console.log(` Client ID : ${tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.clientId}`);
30
+ console.log(` Authority : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.authority) || 'N/A'}`);
31
+ console.log(` Audience : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.audience) || 'N/A'}`);
32
+ console.log(` Base URL : ${(tenantInfo === null || tenantInfo === void 0 ? void 0 : tenantInfo.baseUrl) || 'N/A'}`);
33
+ }),
34
+ };
@@ -35,8 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  };
36
36
  })();
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.scaffold = exports.build = void 0;
39
- const build = __importStar(require("./build"));
40
- exports.build = build;
41
- const scaffold = __importStar(require("./scaffold"));
42
- exports.scaffold = scaffold;
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("../utils/load-config"));
17
+ const load_config_1 = __importDefault(require("../../utils/load-config"));
18
18
  exports.command = 'build';
19
- exports.describe = 'Handles build time automation';
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("../utils/load-config"));
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. Use `sitecore-tools scaffold --help` for available options.', args, handler);
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
+ }
@@ -0,0 +1,72 @@
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.BASE_URL = exports.AUDIENCE = exports.AUTH0_DOMAIN = void 0;
13
+ exports.clientCredentialsFlow = clientCredentialsFlow;
14
+ const tenant_store_1 = require("./tenant-store");
15
+ exports.AUTH0_DOMAIN = 'https://auth.sitecorecloud.io';
16
+ exports.AUDIENCE = 'https://api.sitecorecloud.io';
17
+ exports.BASE_URL = 'https://edge-platform.sitecorecloud.io/cs/api';
18
+ const GRANT_TYPE = 'client_credentials';
19
+ /**
20
+ * Performs the OAuth 2.0 client credentials flow to obtain a JWT access token
21
+ * from the Sitecore Identity Provider using the provided client credentials.
22
+ * @param {object} [args] - The arguments for client credentials flow
23
+ * @param {string} [args.clientId] - The client ID registered with Sitecore Identity
24
+ * @param {string} [args.clientSecret] - The client secret associated with the client ID
25
+ * @param {string} [args.organizationId] - The ID of the organization the client belongs to
26
+ * @param {string} [args.tenantId] - The tenant ID representing the specific Sitecore environment
27
+ * @param {string} [args.audience] - The API audience the token is intended for. Defaults to `AUDIENCE`
28
+ * @param {string} [args.authority] - The auth server base URL. Defaults to `AUTH0_DOMAIN`
29
+ * @param {string} [args.baseUrl] - The base URL for the API, used to construct the audience
30
+ * @returns A Promise that resolves to the access token response (including access token, token type, expiry, etc.)
31
+ * @throws Will log and exit the process if the request fails or returns a non-OK status
32
+ */
33
+ function clientCredentialsFlow(_a) {
34
+ return __awaiter(this, arguments, void 0, function* ({ clientId, clientSecret, organizationId, tenantId, audience = exports.AUDIENCE, authority = exports.AUTH0_DOMAIN, baseUrl = exports.BASE_URL, }) {
35
+ const params = new URLSearchParams({
36
+ client_id: clientId,
37
+ client_secret: clientSecret !== null && clientSecret !== void 0 ? clientSecret : '',
38
+ organization_id: organizationId !== null && organizationId !== void 0 ? organizationId : '',
39
+ tenant_id: tenantId !== null && tenantId !== void 0 ? tenantId : '',
40
+ audience,
41
+ grant_type: GRANT_TYPE,
42
+ baseUrl: baseUrl !== null && baseUrl !== void 0 ? baseUrl : '',
43
+ });
44
+ try {
45
+ const response = yield fetch(`${authority}/oauth/token`, {
46
+ method: 'POST',
47
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
48
+ body: params.toString(),
49
+ });
50
+ const data = yield response.json();
51
+ if (!response.ok) {
52
+ throw new Error(data.error_description || data.error || 'Error during client credentials flow');
53
+ }
54
+ const decodedPayload = (0, tenant_store_1.decodeJwtPayload)(data.access_token) || {};
55
+ if (!(decodedPayload === null || decodedPayload === void 0 ? void 0 : decodedPayload.tokenTenantId) || !decodedPayload.tokenOrgId) {
56
+ throw new Error('\n Token is missing required claims tenant_id or org_id.');
57
+ }
58
+ const { tokenTenantId, tokenOrgId, tokenTenantName } = decodedPayload;
59
+ if (tenantId && tenantId !== tokenTenantId) {
60
+ throw new Error('\n Mismatch: Provided tenant ID does not match claims tenant ID.');
61
+ }
62
+ if (organizationId && organizationId !== tokenOrgId) {
63
+ throw new Error('\n Mismatch: Provided organization ID does not match claims organization ID.');
64
+ }
65
+ return { data, tokenOrgId, tokenTenantId, tokenTenantName };
66
+ }
67
+ catch (error) {
68
+ console.error('\n Error during client credentials flow:', error instanceof Error ? error.message : error);
69
+ throw error;
70
+ }
71
+ });
72
+ }
@@ -0,0 +1,95 @@
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.validateAuthInfo = validateAuthInfo;
13
+ exports.renewClientToken = renewClientToken;
14
+ exports.renewAuthIfExpired = renewAuthIfExpired;
15
+ const tenant_state_1 = require("./tenant-state");
16
+ const flow_1 = require("./flow");
17
+ const tenant_store_1 = require("./tenant-store");
18
+ /**
19
+ * Validates whether a given auth config is still valid (i.e., not expired).
20
+ * @param {TenantAuth} authInfo - The tenant auth configuration.
21
+ * @returns True if the token is still valid, false if expired.
22
+ */
23
+ function validateAuthInfo(authInfo) {
24
+ const now = new Date();
25
+ const expiry = new Date(authInfo.expires_at);
26
+ return now < expiry;
27
+ }
28
+ /**
29
+ * Renews the token for a given tenant using stored credentials.
30
+ * @param {TenantAuth} authInfo - Current authentication info for the tenant.
31
+ * @param {TenantInfo} tenantInfo - Public metadata about the tenant (e.g., clientId).
32
+ * @returns Promise<void>
33
+ * @throws If credentials are missing or renewal fails.
34
+ */
35
+ function renewClientToken(authInfo, tenantInfo) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ const result = yield (0, flow_1.clientCredentialsFlow)({
38
+ clientId: tenantInfo.clientId,
39
+ clientSecret: authInfo.clientSecret,
40
+ organizationId: tenantInfo.organizationId,
41
+ tenantId: tenantInfo.tenantId,
42
+ audience: tenantInfo.audience,
43
+ authority: tenantInfo.authority,
44
+ baseUrl: tenantInfo.baseUrl,
45
+ });
46
+ const tenantId = tenantInfo.tenantId;
47
+ yield (0, tenant_store_1.writeTenantAuthInfo)(tenantId, {
48
+ clientSecret: authInfo.clientSecret,
49
+ access_token: result.data.access_token,
50
+ expires_in: result.data.expires_in,
51
+ expires_at: new Date(Date.now() + result.data.expires_in * 1000).toISOString(),
52
+ });
53
+ console.info(`\n Token for tenant ${tenantId} renewed.`);
54
+ });
55
+ }
56
+ /**
57
+ * Ensures a valid token exists, renews it if expired.
58
+ * Returns tenant context if successful, otherwise null.
59
+ */
60
+ function renewAuthIfExpired() {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const tenantId = (0, tenant_state_1.getActiveTenant)();
63
+ if (!tenantId)
64
+ return null;
65
+ const authInfo = yield (0, tenant_store_1.readTenantAuthInfo)(tenantId);
66
+ if (!authInfo)
67
+ return null;
68
+ const isValid = validateAuthInfo(authInfo);
69
+ if (isValid) {
70
+ return { tenantId };
71
+ }
72
+ const tenantInfo = yield (0, tenant_store_1.readTenantInfo)(tenantId);
73
+ if (!tenantInfo)
74
+ return null;
75
+ console.info(`\n Token for tenant ${tenantId} is expired. Renewing...`);
76
+ try {
77
+ if (authInfo.clientSecret) {
78
+ yield renewClientToken(authInfo, tenantInfo);
79
+ }
80
+ else {
81
+ // <TODO>: Implement Device auth token renewal.
82
+ throw new Error('\n Please use clientSecret for authentication.');
83
+ }
84
+ return { tenantId };
85
+ }
86
+ catch (err) {
87
+ console.error(`\n Failed to renew token for tenant '${tenantId}'`);
88
+ console.warn(`\n Cleaning up stale authentication data for tenant '${tenantId}'...`);
89
+ yield (0, tenant_store_1.deleteTenantAuthInfo)(tenantId);
90
+ (0, tenant_state_1.clearActiveTenant)();
91
+ console.info('\n You will need to login again to re-authenticate.');
92
+ process.exit(1);
93
+ }
94
+ });
95
+ }