Skip to content

Commit

Permalink
Fix: Skip if private app already exist in the sam org
Browse files Browse the repository at this point in the history
  • Loading branch information
antonyagustine committed Nov 30, 2023
1 parent ec6400b commit 50f0485
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
3 changes: 3 additions & 0 deletions packages/contentstack-import/src/commands/cm/stacks/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ export default class ImportCommand extends Command {
required: false,
description: '[optional] Override marketplace prompts',
}),
'skip-app-recreation': flags.boolean({
description: '[optional] Skip private apps recreation if already exist',
}),
'replace-existing': flags.boolean({
required: false,
description: 'Replaces the existing module in the target stack.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import filter from 'lodash/filter';
import isEmpty from 'lodash/isEmpty';
import toLower from 'lodash/toLower';
import {
App,
cliux,
HttpClient,
NodeCrypto,
Expand All @@ -17,12 +18,13 @@ import {
ContentstackClient,
HttpClientDecorator,
managementSDKClient,
marketplaceSDKClient,
ContentstackMarketplaceClient,
} from '@contentstack/cli-utilities';

import BaseClass from './base-class';
import { trace } from '../../utils/log';
import { askEncryptionKey } from '../../utils/interactive';
import { ModuleClassParams, MarketplaceAppsConfig } from '../../types';
import { ModuleClassParams, MarketplaceAppsConfig, ImportConfig } from '../../types';
import {
log,
fsUtil,
Expand All @@ -40,12 +42,13 @@ import {
getConfirmationToCreateApps,
} from '../../utils';

export default class ImportMarketplaceApps extends BaseClass {
export default class ImportMarketplaceApps {
public importConfig: ImportConfig;
private mapperDirPath: string;
private marketPlaceFolderPath: string;
private marketPlaceUidMapperPath: string;
private marketPlaceAppConfig: MarketplaceAppsConfig;
private marketplaceApps: Record<string, any>[];
private marketplaceApps: App[];
private httpClient: HttpClient | OauthDecorator | HttpClientDecorator;
private appNameMapping: Record<string, unknown>;
private appUidMapping: Record<string, unknown>;
Expand All @@ -56,9 +59,9 @@ export default class ImportMarketplaceApps extends BaseClass {
public sdkClient: ContentstackClient;
public nodeCrypto: NodeCrypto;
public appSdkAxiosInstance: any;
constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
public appSdk: ContentstackMarketplaceClient;

constructor({ importConfig }: ModuleClassParams) {
this.marketPlaceAppConfig = importConfig.modules.marketplace_apps;
this.mapperDirPath = join(this.importConfig.backupDir, 'mapper', 'marketplace_apps');
this.marketPlaceFolderPath = join(this.importConfig.backupDir, this.marketPlaceAppConfig.dirName);
Expand All @@ -82,7 +85,7 @@ export default class ImportMarketplaceApps extends BaseClass {
this.marketplaceApps = fsUtil.readFile(
join(this.marketPlaceFolderPath, this.marketPlaceAppConfig.fileName),
true,
) as Record<string, unknown>[];
) as App[];
} else {
log(this.importConfig, `No such file or directory - '${this.marketPlaceFolderPath}'`, 'error');
return;
Expand All @@ -99,6 +102,11 @@ export default class ImportMarketplaceApps extends BaseClass {
}
await fsUtil.makeDirectory(this.mapperDirPath);
this.developerHubBaseUrl = this.importConfig.developerHubBaseUrl || (await getDeveloperHubUrl(this.importConfig));

// NOTE init marketplace app sdk
const host = this.developerHubBaseUrl.split('://').pop();
this.appSdk = await marketplaceSDKClient({ host });

this.sdkClient = await managementSDKClient({ endpoint: this.developerHubBaseUrl });
this.appSdkAxiosInstance = await managementSDKClient({
host: this.developerHubBaseUrl.split('://').pop(),
Expand Down Expand Up @@ -236,6 +244,12 @@ export default class ImportMarketplaceApps extends BaseClass {
log(this.importConfig, 'Starting developer hub private apps re-creation', 'success');

for (let app of privateApps) {
if (this.importConfig.skipPrivateAppRecreationIfExist && (await this.isPrivateAppExistInDeveloperHub(app))) {
// NOTE Found app already exist in the same org
this.appUidMapping[app.uid] = app.uid;
continue;
}

// NOTE keys can be passed to install new app in the developer hub
const validKeys = [
'uid',
Expand All @@ -251,12 +265,30 @@ export default class ImportMarketplaceApps extends BaseClass {
];
const manifest = pick(app.manifest, validKeys);
this.appOriginalName = manifest.name;

await this.createPrivateApps(manifest);
}

this.appOriginalName = undefined;
}

/**
* The function checks if a private app exists in the developer hub.
* @param {App} app - The `app` parameter is an object representing an application. It likely has
* properties such as `uid` which is a unique identifier for the app.
* @returns a boolean value. It returns true if the installation object is not empty, and false if
* the installation object is empty.
*/
async isPrivateAppExistInDeveloperHub(app: App) {
const installation = await this.appSdk
.marketplace(this.importConfig.org_uid)
.installation(app.uid)
.fetch()
.catch((_) => {}); // NOTE Keeping this to avoid Unhandled exception

return !isEmpty(installation);
}

async createPrivateApps(app: any, appSuffix = 1) {
let locations = app?.ui_location?.locations;

Expand Down
1 change: 1 addition & 0 deletions packages/contentstack-import/src/types/import-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
management_token?: string;
apiKey: string;
forceStopMarketplaceAppsPrompt: boolean;
skipPrivateAppRecreationIfExist: boolean;
auth_token?: string;
branchName?: string;
securedAssets?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const setupConfig = async (importCmdFlags: any): Promise<ImportConfig> => {

config.importWebhookStatus = importCmdFlags['import-webhook-status'];
config.forceStopMarketplaceAppsPrompt = importCmdFlags.yes;
config.skipPrivateAppRecreationIfExist = importCmdFlags['skip-app-recreation'];

if (importCmdFlags['branch']) {
config.branchName = importCmdFlags['branch'];
Expand Down

0 comments on commit 50f0485

Please sign in to comment.