Skip to content

Commit

Permalink
feat(mc-scripts): attempt to automatically refresh the access token (#…
Browse files Browse the repository at this point in the history
…2864)

* feat(mc-scripts): attempt to automatically refresh the access token

* fix: test
  • Loading branch information
emmenko authored Nov 9, 2022
1 parent 2d4e968 commit bbfdd84
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 89 deletions.
5 changes: 5 additions & 0 deletions .changeset/soft-dogs-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@commercetools-frontend/mc-scripts': minor
---

The CLI command `config:sync` now attempts to automatically refresh the access token.
7 changes: 6 additions & 1 deletion packages/mc-scripts/bin/cli.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#!/usr/bin/env node

require('@commercetools-frontend/mc-scripts/cli').run();
const { run } = require('@commercetools-frontend/mc-scripts/cli');

run().catch((error) => {
console.error(error.message || error.stack || error);
process.exit(1);
});
3 changes: 2 additions & 1 deletion packages/mc-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"dotenv": "16.0.3",
"dotenv-expand": "8.0.3",
"fs-extra": "10.1.0",
"graphql-request": "^4.3.0",
"graphql": "16.6.0",
"graphql-request": "5.0.0",
"graphql-tag": "^2.12.6",
"html-webpack-plugin": "5.5.0",
"json-loader": "0.5.7",
Expand Down
7 changes: 4 additions & 3 deletions packages/mc-scripts/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ process.on('unhandledRejection', (err) => {
// Get the current directory where the CLI is executed from. Usually this is the application folder.
const applicationDirectory = fs.realpathSync(process.cwd());

const run = () => {
async function run() {
cli.option(
'--env <path>',
`(optional) Parses the file path as a dotenv file and adds the variables to the environment. Multiple flags are allowed.`
Expand Down Expand Up @@ -199,8 +199,9 @@ const run = () => {
cli.help();
cli.version(pkgJson.version);

cli.parse();
};
cli.parse(process.argv, { run: false });
await cli.runMatchedCommand();
}

// Load dotenv files into the process environment.
// This is essentially what `dotenv-cli` does, but it's now built into this CLI.
Expand Down
77 changes: 54 additions & 23 deletions packages/mc-scripts/src/commands/config-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,23 @@ async function run(options: TCliCommandConfigSyncOptions) {
const { data: localCustomAppData } = applicationConfig;
const { mcApiUrl } = applicationConfig.env;

const token = credentialsStorage.getToken(mcApiUrl);
if (!token) {
console.log(`Using Merchant Center environment "${chalk.green(mcApiUrl)}".`);
console.log();

const isSessionValid = credentialsStorage.isSessionValid(mcApiUrl);
if (!isSessionValid) {
throw new Error(
`You don't have a valid session for the ${mcApiUrl} environment. Please, run the "mc-scripts login" command to authenticate yourself.`
`You don't have a valid session. Please, run the "mc-scripts login" command to authenticate yourself.`
);
}

const fetchedCustomApplication = await fetchCustomApplication({
mcApiUrl,
token,
entryPointUriPath: localCustomAppData.entryPointUriPath,
});

if (!fetchedCustomApplication) {
const userOrganizations = await fetchUserOrganizations({ mcApiUrl, token });
const userOrganizations = await fetchUserOrganizations({ mcApiUrl });

let organizationId: string, organizationName: string;

Expand All @@ -71,7 +73,7 @@ async function run(options: TCliCommandConfigSyncOptions) {
const { organizationId: selectedOrganizationId } = await prompts({
type: 'select',
name: 'organizationId',
message: 'Select Organization',
message: 'Select an Organization',
choices: organizationChoices,
initial: 0,
});
Expand All @@ -91,7 +93,15 @@ async function run(options: TCliCommandConfigSyncOptions) {
const { confirmation } = await prompts({
type: 'text',
name: 'confirmation',
message: `You are about to create a new Custom Application in the "${organizationName}" organization for the ${mcApiUrl} environment. Are you sure you want to proceed?`,
message: [
`You are about to create a new Custom Application in the "${chalk.green(
organizationName
)}" organization. Are you sure you want to proceed?`,
options.dryRun &&
chalk.gray('Using "--dry-run", no data will be created.'),
]
.filter(Boolean)
.join('\n'),
initial: 'yes',
});
if (!confirmation || confirmation.toLowerCase().charAt(0) !== 'y') {
Expand All @@ -101,16 +111,16 @@ async function run(options: TCliCommandConfigSyncOptions) {

const data = omit(localCustomAppData, ['id']);
if (options.dryRun) {
console.log(chalk.gray('DRY RUN mode'));
console.log();
console.log(
`A new Custom Application would be created for the Organization ${organizationName} with the following payload:`
`The following payload would be used to create a new Custom Application.`
);
console.log(JSON.stringify(data));
console.log();
console.log(chalk.gray(JSON.stringify(data, null, 2)));
return;
}
const createdCustomApplication = await createCustomApplication({
mcApiUrl,
token,
organizationId,
data,
});
Expand All @@ -130,9 +140,16 @@ async function run(options: TCliCommandConfigSyncOptions) {
);
console.log(
chalk.green(
`Custom Application created.\nThe "applicationId" in your local Custom Application config file should be updated with the application ID: ${createdCustomApplication.id}.\nYou can see the Custom Application data in the Merchant Center at ${customAppLink}.`
`Custom Application created.\nPlease update the "env.production.applicationId" field in your local Custom Application config file with the following value: "${chalk.green(
createdCustomApplication.id
)}".`
)
);
console.log(
`You can inspect the Custom Application data in the Merchant Center at "${chalk.gray(
customAppLink
)}".`
);
return;
}

Expand All @@ -148,20 +165,31 @@ async function run(options: TCliCommandConfigSyncOptions) {
);

if (!configDiff) {
console.log(chalk.green(`Custom Application up-to-date.`));
console.log(
chalk.green(
`Custom Application is already up to date.\nYou can see the Custom Application data in the Merchant Center at ${customAppLink}.`
)
`You can inspect the Custom Application data in the Merchant Center at "${chalk.gray(
customAppLink
)}".`
);
return;
}

console.log('Changes detected:');
console.log(configDiff);
console.log();

const { confirmation } = await prompts({
type: 'text',
name: 'confirmation',
message: `You are about to update the Custom Application "${localCustomAppData.entryPointUriPath}" with the changes above, in the ${mcApiUrl} environment. Are you sure you want to proceed?`,
message: [
`You are about to update the Custom Application "${chalk.green(
localCustomAppData.entryPointUriPath
)}" with the changes above. Are you sure you want to proceed?`,
options.dryRun &&
chalk.gray('Using "--dry-run", no data will be updated.'),
]
.filter(Boolean)
.join('\n'),
initial: 'yes',
});
if (!confirmation || confirmation.toLowerCase().charAt(0) !== 'y') {
Expand All @@ -171,26 +199,29 @@ async function run(options: TCliCommandConfigSyncOptions) {

const data = omit(localCustomAppData, ['id']);
if (options.dryRun) {
console.log(chalk.gray('DRY RUN mode'));
console.log();
console.log(
`The Custom Application ${data.name} would be updated with the following payload:`
`The following payload would be used to update the Custom Application "${chalk.green(
data.entryPointUriPath
)}".`
);
console.log(JSON.stringify(data));
console.log();
console.log(chalk.gray(JSON.stringify(data, null, 2)));
return;
}

await updateCustomApplication({
mcApiUrl,
token,
organizationId: fetchedCustomApplication.organizationId,
data: omit(localCustomAppData, ['id']),
applicationId: fetchedCustomApplication.application.id,
});

console.log(chalk.green(`Custom Application updated.`));
console.log(
chalk.green(
`Custom Application updated.\nYou can see the Custom Application data in the Merchant Center at ${customAppLink}.`
)
`You can inspect the Custom Application data in the Merchant Center at "${chalk.gray(
customAppLink
)}".`
);
}

Expand Down
11 changes: 5 additions & 6 deletions packages/mc-scripts/src/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ async function run() {
const applicationConfig = processConfig();
const { mcApiUrl } = applicationConfig.env;

console.log(`Using Merchant Center environment "${chalk.green(mcApiUrl)}".`);
console.log();

if (credentialsStorage.isSessionValid(mcApiUrl)) {
console.log(
`You already have a valid session for the ${mcApiUrl} environment.\n`
);
console.log(`You already have a valid session.`);
return;
}

console.log(
chalk.gray(`Enter the login credentials for the ${mcApiUrl} environment.\n`)
);
console.log(`Enter the login credentials:`);

const { email } = await prompts({
type: 'text',
Expand Down
4 changes: 0 additions & 4 deletions packages/mc-scripts/src/utils/graphql-requests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ describe('fetch custom application data', () => {
await fetchCustomApplication({
entryPointUriPath: 'test-custom-app',
mcApiUrl,
token: 'test-token',
});
expect(
organizationExtensionForCustomApplication?.application.entryPointUriPath
Expand Down Expand Up @@ -107,7 +106,6 @@ describe('register custom application', () => {
it('should match returned data', async () => {
const createdCustomAppsData = await createCustomApplication({
mcApiUrl,
token: 'token',
organizationId: 'organization-id',
data: {
url: 'https://test.com',
Expand Down Expand Up @@ -154,7 +152,6 @@ describe('update custom application', () => {
it('should match returned data', async () => {
const updatedCustomAppsData = await updateCustomApplication({
mcApiUrl,
token: 'token',
organizationId: 'organization-id',
applicationId: 'application-id',
data: {
Expand Down Expand Up @@ -208,7 +205,6 @@ describe('fetch user organizations', () => {
it('should match returned data', async () => {
const data = await fetchUserOrganizations({
mcApiUrl,
token: 'test-token',
});
expect(data.results[0].id).toEqual('test-organization-id');
expect(data.results[0].name).toEqual('test-organization-name');
Expand Down
Loading

1 comment on commit bbfdd84

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for merchant-center-application-kit ready!

✅ Preview
https://merchant-center-application-4dtpmf5zt-commercetools.vercel.app

Built with commit bbfdd84.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.