diff --git a/packages/contentstack-export/src/export/modules/marketplace-apps.ts b/packages/contentstack-export/src/export/modules/marketplace-apps.ts index 8cc2f65f3d..6f377614a8 100644 --- a/packages/contentstack-export/src/export/modules/marketplace-apps.ts +++ b/packages/contentstack-export/src/export/modules/marketplace-apps.ts @@ -1,36 +1,24 @@ import map from 'lodash/map'; import has from 'lodash/has'; import find from 'lodash/find'; +import omitBy from 'lodash/omitBy'; import entries from 'lodash/entries'; import isEmpty from 'lodash/isEmpty'; import { resolve as pResolve } from 'node:path'; import { - App, cliux, NodeCrypto, - HttpClient, - OauthDecorator, isAuthenticated, - HttpClientDecorator, marketplaceSDKClient, ContentstackMarketplaceClient, } from '@contentstack/cli-utilities'; -import { - log, - fsUtil, - getOrgUid, - formatError, - getDeveloperHubUrl, - getStackSpecificApps, - createNodeCryptoInstance, -} from '../../utils'; -import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig } from '../../types'; +import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation, Manifest } from '../../types'; +import { log, fsUtil, getOrgUid, formatError, getDeveloperHubUrl, createNodeCryptoInstance } from '../../utils'; export default class ExportMarketplaceApps { - protected httpClient: OauthDecorator | HttpClientDecorator | HttpClient; protected marketplaceAppConfig: MarketplaceAppsConfig; - protected installedApps: App[] = []; + protected installedApps: Installation[] = []; public developerHubBaseUrl: string; public marketplaceAppPath: string; public nodeCrypto: NodeCrypto; @@ -39,7 +27,6 @@ export default class ExportMarketplaceApps { constructor({ exportConfig }: Omit) { this.exportConfig = exportConfig; - this.httpClient = new HttpClient(); this.marketplaceAppConfig = exportConfig.modules.marketplace_apps; } @@ -67,50 +54,34 @@ export default class ExportMarketplaceApps { const host = this.developerHubBaseUrl.split('://').pop(); this.appSdk = await marketplaceSDKClient({ host }); - await this.setHttpClient(); - await this.getAllStackSpecificApps(); - await this.exportInstalledExtensions(); + await this.exportApps(); } - async setHttpClient(): Promise { - if (!this.exportConfig.auth_token) { - this.httpClient = new OauthDecorator(this.httpClient); - const headers = await this.httpClient.preHeadersCheck(this.exportConfig); - this.httpClient = this.httpClient.headers(headers); - } else { - this.httpClient = new HttpClientDecorator(this.httpClient); - this.httpClient.headers(this.exportConfig); - } - } - - async getAllStackSpecificApps(skip = 0): Promise { - const data = await getStackSpecificApps({ - developerHubBaseUrl: this.developerHubBaseUrl, - config: this.exportConfig, - skip, - }); - - const { data: apps, count } = data; + /** + * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto + * library if it is available. + */ + async exportApps(): Promise { + await this.getStackSpecificApps(); + await this.getAppManifestAndAppConfig(); - if (!this.nodeCrypto && find(apps, (app) => !isEmpty(app.configuration))) { + if (!this.nodeCrypto && find(this.installedApps, (app) => !isEmpty(app.configuration))) { this.nodeCrypto = await createNodeCryptoInstance(this.exportConfig); } - const stackApps = map(apps, (app) => { + this.installedApps = map(this.installedApps, (app) => { if (has(app, 'configuration')) { app['configuration'] = this.nodeCrypto.encrypt(app.configuration); } return app; }); - - this.installedApps = this.installedApps.concat(stackApps); - - if (count - (skip + 50) > 0) { - return await this.getAllStackSpecificApps(skip + 50); - } } - async exportInstalledExtensions(): Promise { + /** + * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed + * marketplace apps. + */ + async getAppManifestAndAppConfig(): Promise { if (isEmpty(this.installedApps)) { log(this.exportConfig, 'No marketplace apps found', 'info'); } else { @@ -139,7 +110,7 @@ export default class ExportMarketplaceApps { * installation details of an app. It contains information such as the UID (unique identifier) of the * app's manifest. */ - async getPrivateAppsManifest(index: number, appInstallation: App) { + async getPrivateAppsManifest(index: number, appInstallation: Installation) { const manifest = await this.appSdk .marketplace(this.exportConfig.org_uid) .app(appInstallation.manifest.uid) @@ -148,9 +119,21 @@ export default class ExportMarketplaceApps { log(this.exportConfig, error, 'error'); }); - this.installedApps[index].manifest = manifest; + if (manifest) { + this.installedApps[index].manifest = manifest as unknown as Manifest; + } } + /** + * The function `getAppConfigurations` exports the configuration of an app installation and encrypts + * the server configuration if it exists. + * @param {number} index - The `index` parameter is a number that represents the index of the app + * installation in an array or list. It is used to identify the specific app installation that needs + * to be processed or accessed. + * @param {any} appInstallation - The `appInstallation` parameter is an object that represents the + * installation details of an app. It contains information such as the app's manifest, unique + * identifier (uid), and other installation data. + */ async getAppConfigurations(index: number, appInstallation: any) { const appName = appInstallation?.manifest?.name; log(this.exportConfig, `Exporting ${appName} app and it's config.`, 'info'); @@ -182,4 +165,38 @@ export default class ExportMarketplaceApps { log(this.exportConfig, error, 'error'); }); } + + /** + * The function `getStackSpecificApps` retrieves a collection of marketplace apps specific to a stack + * and stores them in the `installedApps` array. + * @param [skip=0] - The `skip` parameter is used to determine the number of items to skip in the API + * response. It is used for pagination purposes, allowing you to fetch a specific range of items from + * the API. In this code, it is initially set to 0, indicating that no items should be skipped in + */ + async getStackSpecificApps(skip = 0) { + const collection = await this.appSdk + .marketplace(this.exportConfig.org_uid) + .installation() + .fetchAll({ target_uids: this.exportConfig.source_stack, skip }) + .catch((error) => { + log(this.exportConfig, `Failed to export marketplace-apps ${formatError(error)}`, 'error'); + log(this.exportConfig, error, 'error'); + }); + + if (collection) { + const { items: apps, count } = collection; + // NOTE Remove all the chain functions + const installation = map(apps, (app) => + omitBy(app, (val, _key) => { + if (val instanceof Function) return true; + return false; + }), + ) as unknown as Installation[]; + this.installedApps = this.installedApps.concat(installation); + + if (count - (skip + 50) > 0) { + await this.getStackSpecificApps(skip + 50); + } + } + } } diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index ee5121491b..77d2327cd0 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -140,3 +140,4 @@ export interface TermsConfig{ export { default as DefaultConfig } from './default-config'; export { default as ExportConfig } from './export-config'; +export * from './marketplace-app' diff --git a/packages/contentstack-export/src/types/marketplace-app.ts b/packages/contentstack-export/src/types/marketplace-app.ts new file mode 100644 index 0000000000..684d9015a6 --- /dev/null +++ b/packages/contentstack-export/src/types/marketplace-app.ts @@ -0,0 +1,65 @@ +type AppLocation = + | 'cs.cm.stack.config' + | 'cs.cm.stack.dashboard' + | 'cs.cm.stack.sidebar' + | 'cs.cm.stack.custom_field' + | 'cs.cm.stack.rte' + | 'cs.cm.stack.asset_sidebar' + | 'cs.org.config'; + +interface ExtensionMeta { + uid?: string; + name?: string; + description?: string; + path?: string; + signed: boolean; + extension_uid?: string; + data_type?: string; + enabled?: boolean; + width?: number; + blur?: boolean; + default_width?: 'full' | 'half'; +} + +interface Extension { + type: AppLocation; + meta: ExtensionMeta[]; +} + +interface LocationConfiguration { + signed: boolean; + base_url: string; + locations: Extension[]; +} + +interface AnyProperty { + [propName: string]: any; +} + +type Manifest = { + uid: string; + name: string; + icon?: string; + hosting?: any; + version?: number; + description: string; + organization_uid: string; + framework_version?: string; + oauth?: any; + webhook?: any; + ui_location: LocationConfiguration; + target_type: 'stack' | 'organization'; + visibility: 'private' | 'public' | 'public_unlisted'; +} & AnyProperty; + +type Installation = { + uid: string; + status: string; + manifest: Manifest; + configuration: any; + server_configuration: any; + target: { type: string; uid: string }; + ui_location: LocationConfiguration; +} & AnyProperty; + +export { Installation, Manifest }; diff --git a/packages/contentstack-export/src/utils/marketplace-app-helper.ts b/packages/contentstack-export/src/utils/marketplace-app-helper.ts index 36651f3547..b96db792ab 100644 --- a/packages/contentstack-export/src/utils/marketplace-app-helper.ts +++ b/packages/contentstack-export/src/utils/marketplace-app-helper.ts @@ -48,22 +48,3 @@ export async function createNodeCryptoInstance(config: ExportConfig): Promise { - const { developerHubBaseUrl, config, skip } = params; - const appSdkAxiosInstance = await managementSDKClient({ - endpoint: developerHubBaseUrl, - }); - return appSdkAxiosInstance.axiosInstance - .get(`${developerHubBaseUrl}/installations?target_uids=${config.source_stack}&skip=${skip}`, { - headers: { - organization_uid: config.org_uid, - }, - }) - .then((data: any) => data.data) - .catch((error: any) => log(config, `Failed to export marketplace-apps ${formatError(error)}`, 'error')); -}; diff --git a/packages/contentstack-export/test/unit/export/modules/marketplace-apps.test.ts b/packages/contentstack-export/test/unit/export/modules/marketplace-apps.test.ts index 42eec52769..a45614083f 100644 --- a/packages/contentstack-export/test/unit/export/modules/marketplace-apps.test.ts +++ b/packages/contentstack-export/test/unit/export/modules/marketplace-apps.test.ts @@ -1,5 +1,5 @@ import { expect } from '@oclif/test'; -import { App, FsUtility, marketplaceSDKClient } from '@contentstack/cli-utilities'; +import { App, FsUtility, cliux, marketplaceSDKClient } from '@contentstack/cli-utilities'; import { fancy } from '@contentstack/cli-dev-dependencies'; import defaultConfig from '../../../../src/config'; @@ -8,6 +8,7 @@ import * as utilities from '@contentstack/cli-utilities'; import ExportConfig from '../../../../lib/types/export-config'; import * as appUtility from '../../../../src/utils/marketplace-app-helper'; import ExportMarketplaceApps from '../../../../src/export/modules/marketplace-apps'; +import { Installation, MarketplaceAppsConfig } from '../../../../src/types'; describe('ExportMarketplaceApps class', () => { const exportConfig: ExportConfig = Object.assign(defaultConfig, { @@ -21,108 +22,104 @@ describe('ExportMarketplaceApps class', () => { const host = 'test-app.io'; describe('start method', () => { + fancy + .stub(utilities, 'isAuthenticated', () => false) + .stub(cliux, 'print', () => {}) + .spy(utilities, 'isAuthenticated') + .spy(cliux, 'print') + .spy(ExportMarketplaceApps.prototype, 'exportApps') + .it('should skip marketplace app export process if not authenticated', async ({ spy }) => { + const marketplaceApps = new ExportMarketplaceApps({ exportConfig }); + await marketplaceApps.start(); + + expect(spy.print.callCount).to.be.equals(1); + expect(spy.isAuthenticated.callCount).to.be.equals(1); + }); + fancy .stub(utilities, 'isAuthenticated', () => true) .stub(utilities, 'log', () => {}) .stub(FsUtility.prototype, 'makeDirectory', () => {}) .stub(appUtility, 'getOrgUid', () => 'ORG-UID') - .stub(ExportMarketplaceApps.prototype, 'setHttpClient', () => {}) - .stub(ExportMarketplaceApps.prototype, 'getAllStackSpecificApps', () => {}) - .stub(ExportMarketplaceApps.prototype, 'exportInstalledExtensions', () => {}) + .stub(ExportMarketplaceApps.prototype, 'exportApps', () => {}) .spy(appUtility, 'getOrgUid') - .spy(ExportMarketplaceApps.prototype, 'setHttpClient') - .spy(ExportMarketplaceApps.prototype, 'getAllStackSpecificApps') - .spy(ExportMarketplaceApps.prototype, 'exportInstalledExtensions') + .spy(ExportMarketplaceApps.prototype, 'exportApps') .it('should trigger start method', async ({ spy }) => { const marketplaceApps = new ExportMarketplaceApps({ exportConfig }); await marketplaceApps.start(); expect(spy.getOrgUid.callCount).to.be.equals(1); - expect(spy.setHttpClient.callCount).to.be.equals(1); - expect(spy.getAllStackSpecificApps.callCount).to.be.equals(1); - expect(spy.exportInstalledExtensions.callCount).to.be.equals(1); + expect(spy.exportApps.callCount).to.be.equals(1); }); }); - describe('getAllStackSpecificApps method', () => { + describe('exportApps method', () => { fancy - .stub(appUtility, 'getStackSpecificApps', () => ({ data: [], count: 0 })) - .spy(appUtility, 'getStackSpecificApps') - .it('should get call getStackSpecificApps to get stack specific apps', async ({ spy }) => { - const marketplaceApps = new ExportMarketplaceApps({ exportConfig }); - await marketplaceApps.getAllStackSpecificApps(); - - expect(spy.getStackSpecificApps.callCount).to.be.equals(1); - expect( - spy.getStackSpecificApps.calledWithExactly({ - developerHubBaseUrl: marketplaceApps.developerHubBaseUrl, - config: marketplaceApps.exportConfig, - skip: 0, - }), - ).to.be.true; - }); - - fancy - .stub(appUtility, 'getStackSpecificApps', () => ({ - data: [{ uid: 'UID', name: 'TEST-APP', configuration: { id: 'test' } }], - count: 51, - })) + .stub(ExportMarketplaceApps.prototype, 'getStackSpecificApps', () => {}) + .stub(ExportMarketplaceApps.prototype, 'getAppManifestAndAppConfig', () => {}) .stub(appUtility, 'createNodeCryptoInstance', () => ({ encrypt: (val: any) => val })) - .spy(appUtility, 'getStackSpecificApps') - .spy(appUtility, 'createNodeCryptoInstance') - .it('should paginate and get all the apps', async ({ spy }) => { - const marketplaceApps = new ExportMarketplaceApps({ exportConfig }); - marketplaceApps.developerHubBaseUrl = defaultConfig.developerHubBaseUrl; - await marketplaceApps.getAllStackSpecificApps(); + .spy(ExportMarketplaceApps.prototype, 'getStackSpecificApps') + .spy(ExportMarketplaceApps.prototype, 'getAppManifestAndAppConfig') + .it('should get call get all stack specif installation and manifest and configuration', async ({ spy }) => { + class MPApps extends ExportMarketplaceApps { + public installedApps = [ + { uid: 'UID', name: 'TEST-APP', configuration: { id: 'test' }, manifest: { visibility: 'private' } }, + ] as unknown as Installation[]; + } + const marketplaceApps = new MPApps({ exportConfig }); + await marketplaceApps.exportApps(); - expect(spy.getStackSpecificApps.callCount).to.be.equals(2); - expect(spy.createNodeCryptoInstance.callCount).to.be.equals(1); - expect( - spy.getStackSpecificApps.calledWith({ - developerHubBaseUrl: marketplaceApps.developerHubBaseUrl, - config: marketplaceApps.exportConfig, - skip: 50, - }), - ).to.be.true; + expect(spy.getStackSpecificApps.callCount).to.be.equals(1); + expect(spy.getAppManifestAndAppConfig.callCount).to.be.equals(1); + expect(marketplaceApps.installedApps).to.be.string; }); }); - describe('exportInstalledExtensions method', () => { + describe('getAppManifestAndAppConfig method', () => { fancy .stub(logUtil, 'log', () => {}) - .stub(FsUtility.prototype, 'writeFile', () => {}) .spy(logUtil, 'log') - .it("should log info 'No marketplace apps found'", async ({ spy }) => { - const marketplaceApps = new ExportMarketplaceApps({ exportConfig }); - await marketplaceApps.exportInstalledExtensions(); + .it( + "if no apps is exported from stack, It should log message that 'No marketplace apps found'", + async ({ spy }) => { + class MPApps extends ExportMarketplaceApps { + public installedApps = [] as unknown as Installation[]; + } + const marketplaceApps = new MPApps({ exportConfig }); + await marketplaceApps.getAppManifestAndAppConfig(); - expect(spy.log.callCount).to.be.equals(1); - expect(spy.log.calledWith(marketplaceApps.exportConfig, 'No marketplace apps found', 'info')).to.be.true; - }); + expect(spy.log.callCount).to.be.equals(1); + expect(spy.log.calledWith(marketplaceApps.exportConfig, 'No marketplace apps found', 'info')).to.be.true; + }, + ); fancy .stub(logUtil, 'log', () => {}) .stub(FsUtility.prototype, 'writeFile', () => {}) - .stub(ExportMarketplaceApps.prototype, 'getPrivateAppsManifest', () => {}) .stub(ExportMarketplaceApps.prototype, 'getAppConfigurations', () => {}) + .stub(ExportMarketplaceApps.prototype, 'getPrivateAppsManifest', () => {}) .spy(logUtil, 'log') .spy(FsUtility.prototype, 'writeFile') - .spy(ExportMarketplaceApps.prototype, 'getPrivateAppsManifest') .spy(ExportMarketplaceApps.prototype, 'getAppConfigurations') - .it('should export all the apps configuration and manifest if private apps', async ({ spy, stdout }) => { + .spy(ExportMarketplaceApps.prototype, 'getPrivateAppsManifest') + .it('should get all private apps manifest and all apps configurations', async ({ spy }) => { class MPApps extends ExportMarketplaceApps { - protected installedApps = [ - { uid: 'UID', name: 'TEST-APP', configuration: { id: 'test' }, manifest: { visibility: 'private' } }, - ] as unknown as App[]; - protected marketplaceAppConfig = { - dirName: 'test', - fileName: 'mp-apps.json', - }; + public installedApps = [ + { + uid: 'UID', + name: 'TEST-APP', + manifest: { uid: 'UID', visibility: 'private' }, + }, + ] as unknown as Installation[]; + public marketplaceAppConfig: MarketplaceAppsConfig; } const marketplaceApps = new MPApps({ exportConfig }); marketplaceApps.marketplaceAppPath = './'; - await marketplaceApps.exportInstalledExtensions(); + marketplaceApps.marketplaceAppConfig.fileName = 'mp-apps.json'; + await marketplaceApps.getAppManifestAndAppConfig(); + expect(spy.log.callCount).to.be.equals(1); + expect(spy.writeFile.callCount).to.be.equals(1); expect(spy.getPrivateAppsManifest.callCount).to.be.equals(1); expect(spy.getAppConfigurations.callCount).to.be.equals(1); expect( @@ -135,6 +132,67 @@ describe('ExportMarketplaceApps class', () => { }); }); + describe('getStackSpecificApps method', () => { + fancy + .nock(`https://${host}`, (api) => + api.get(`/installations?target_uids=STACK-UID&skip=0`).reply(200, { + count: 51, + data: [ + { + uid: 'UID', + name: 'TEST-APP', + configuration: () => {}, + fetch: () => {}, + manifest: { visibility: 'private' }, + }, + ], + }), + ) + .nock(`https://${host}`, (api) => + api.get(`/installations?target_uids=STACK-UID&skip=50`).reply(200, { + count: 51, + data: [ + { + uid: 'UID', + name: 'TEST-APP-2', + configuration: () => {}, + fetch: () => {}, + manifest: { visibility: 'private' }, + }, + ], + }), + ) + .it('should paginate and get all the apps', async () => { + class MPApps extends ExportMarketplaceApps { + public installedApps: Installation[] = []; + } + const marketplaceApps = new MPApps({ exportConfig }); + marketplaceApps.exportConfig.org_uid = 'ORG-UID'; + marketplaceApps.exportConfig.source_stack = 'STACK-UID'; + marketplaceApps.appSdk = await marketplaceSDKClient({ host }); + await marketplaceApps.getStackSpecificApps(); + + expect(marketplaceApps.installedApps.length).to.be.equals(2); + }); + + fancy + .stub(logUtil, 'log', () => {}) + .spy(logUtil, 'log') + .nock(`https://${host}`, (api) => api.get(`/installations?target_uids=STACK-UID&skip=0`).reply(400)) + .it('should catch and log api error', async ({ spy }) => { + class MPApps extends ExportMarketplaceApps { + public installedApps: Installation[] = []; + } + const marketplaceApps = new MPApps({ exportConfig }); + marketplaceApps.exportConfig.org_uid = 'ORG-UID'; + marketplaceApps.exportConfig.source_stack = 'STACK-UID'; + marketplaceApps.appSdk = await marketplaceSDKClient({ host }); + await marketplaceApps.getStackSpecificApps(); + + expect(spy.log.callCount).to.be.equals(2); + }); + }); + describe('getPrivateAppsManifest method', () => { fancy .nock(`https://${host}`, (api) => @@ -151,15 +209,38 @@ describe('ExportMarketplaceApps class', () => { configuration: { id: 'test' }, manifest: { uid: 'UID', visibility: 'private' }, }, - ] as unknown as App[]; + ] as unknown as Installation[]; } const marketplaceApps = new MPApps({ exportConfig }); marketplaceApps.exportConfig.org_uid = 'ORG-UID'; marketplaceApps.appSdk = await marketplaceSDKClient({ host }); - await marketplaceApps.getPrivateAppsManifest(0, { manifest: { uid: 'UID' } } as unknown as App); + await marketplaceApps.getPrivateAppsManifest(0, { manifest: { uid: 'UID' } } as unknown as Installation); expect(marketplaceApps.installedApps[0].manifest.config).to.be.include('test'); }); + + fancy + .stub(logUtil, 'log', () => {}) + .spy(logUtil, 'log') + .nock(`https://${host}`, (api) => api.get(`/manifests/UID?include_oauth=true`).reply(400)) + .it('should handle API/SDK errors and log them', async ({ spy }) => { + class MPApps extends ExportMarketplaceApps { + public installedApps = [ + { + uid: 'UID', + name: 'TEST-APP', + configuration: { id: 'test' }, + manifest: { uid: 'UID', visibility: 'private' }, + }, + ] as unknown as Installation[]; + } + const marketplaceApps = new MPApps({ exportConfig }); + marketplaceApps.exportConfig.org_uid = 'ORG-UID'; + marketplaceApps.appSdk = await marketplaceSDKClient({ host }); + await marketplaceApps.getPrivateAppsManifest(0, { manifest: { uid: 'UID' } } as unknown as Installation); + + expect(spy.log.callCount).to.be.equals(1); + }); }); describe('getAppConfigurations method', () => { @@ -180,7 +261,7 @@ describe('ExportMarketplaceApps class', () => { configuration: { id: 'test' }, manifest: { uid: 'UID', visibility: 'private' }, }, - ] as unknown as App[]; + ] as unknown as Installation[]; } const marketplaceApps = new MPApps({ exportConfig }); marketplaceApps.exportConfig.org_uid = 'ORG-UID'; @@ -190,6 +271,34 @@ describe('ExportMarketplaceApps class', () => { expect(marketplaceApps.installedApps[0].server_configuration).to.be.include('test-config'); }); + fancy + .stub(logUtil, 'log', () => {}) + .stub(appUtility, 'createNodeCryptoInstance', () => ({ encrypt: (val: any) => val })) + .spy(logUtil, 'log') + .nock(`https://${host}`, (api) => + api + .get(`/installations/UID/installationData`) + .reply(200, { data: { uid: 'UID', visibility: 'private', server_configuration: '' } }), + ) + .it('should skip encryption and log success message if server_config is empty', async ({ spy }) => { + class MPApps extends ExportMarketplaceApps { + public installedApps = [ + { + uid: 'UID', + name: 'TEST-APP', + configuration: { id: 'test' }, + manifest: { name: 'TEST-APP', uid: 'UID', visibility: 'private' }, + }, + ] as unknown as Installation[]; + } + const marketplaceApps = new MPApps({ exportConfig }); + marketplaceApps.exportConfig.org_uid = 'ORG-UID'; + marketplaceApps.appSdk = await marketplaceSDKClient({ host }); + await marketplaceApps.getAppConfigurations(0, { uid: 'UID', manifest: { name: 'TEST-APP' } } as unknown as App); + + expect(spy.log.calledWith(marketplaceApps.exportConfig, 'Exported TEST-APP app', 'success')).to.be.true; + }); + fancy .stub(logUtil, 'log', () => {}) .spy(logUtil, 'log') @@ -205,7 +314,7 @@ describe('ExportMarketplaceApps class', () => { configuration: { id: 'test' }, manifest: { uid: 'UID', visibility: 'private' }, }, - ] as unknown as App[]; + ] as unknown as Installation[]; } const marketplaceApps = new MPApps({ exportConfig }); marketplaceApps.exportConfig.org_uid = 'ORG-UID'; @@ -228,7 +337,7 @@ describe('ExportMarketplaceApps class', () => { await marketplaceApps.getAppConfigurations(0, { uid: 'UID', manifest: { name: 'TEST-APP' }, - } as unknown as App); + } as unknown as Installation); const [, errorObj]: any = spy.log.args[spy.log.args.length - 1]; expect(errorObj.error).to.be.include('API is broken'); diff --git a/packages/contentstack-utilities/src/contentstack-marketplace-sdk.ts b/packages/contentstack-utilities/src/contentstack-marketplace-sdk.ts index f3e8f712f8..20c4870ccd 100644 --- a/packages/contentstack-utilities/src/contentstack-marketplace-sdk.ts +++ b/packages/contentstack-utilities/src/contentstack-marketplace-sdk.ts @@ -4,9 +4,9 @@ import { client, ContentstackConfig, ContentstackClient, ContentstackToken } fro import authHandler from './auth-handler'; import configStore from './config-handler'; +import { Installation } from '@contentstack/marketplace-sdk/types/marketplace/installation'; type ConfigType = Pick & { - management_token?: string; skipTokenValidity?: string; }; type ContentstackMarketplaceConfig = ContentstackConfig; @@ -25,6 +25,8 @@ class MarketplaceSDKInitiator { retryLimit: 3, timeout: 60000, maxRequests: 10, + authtoken: '', + authorization: '', // host: 'api.contentstack.io', maxContentLength: 100000000, maxBodyLength: 1000000000, @@ -112,17 +114,12 @@ class MarketplaceSDKInitiator { option.headers['X-CS-CLI'] = this.analyticsInfo; } - if (!config.management_token) { - option.authtoken = ''; - option.authorization = ''; - - if (authorizationType === 'BASIC') { - option.authtoken = configStore.get('authtoken'); - } else if (authorizationType === 'OAUTH') { - if (!config.skipTokenValidity) { - await authHandler.compareOAuthExpiry(); - option.authorization = `Bearer ${configStore.get('oauthAccessToken')}`; - } + if (authorizationType === 'BASIC') { + option.authtoken = configStore.get('authtoken'); + } else if (authorizationType === 'OAUTH') { + if (!config.skipTokenValidity) { + await authHandler.compareOAuthExpiry(); + option.authorization = `Bearer ${configStore.get('oauthAccessToken')}`; } } @@ -133,6 +130,6 @@ class MarketplaceSDKInitiator { export const marketplaceSDKInitiator = new MarketplaceSDKInitiator(); const marketplaceSDKClient: typeof marketplaceSDKInitiator.createAppSDKClient = marketplaceSDKInitiator.createAppSDKClient.bind(marketplaceSDKInitiator); -export { App, MarketplaceSDKInitiator, ContentstackMarketplaceConfig, ContentstackMarketplaceClient }; +export { App, Installation, MarketplaceSDKInitiator, ContentstackMarketplaceConfig, ContentstackMarketplaceClient }; export default marketplaceSDKClient; diff --git a/packages/contentstack-utilities/src/index.ts b/packages/contentstack-utilities/src/index.ts index fe5094f6bc..339d250078 100644 --- a/packages/contentstack-utilities/src/index.ts +++ b/packages/contentstack-utilities/src/index.ts @@ -1,6 +1,7 @@ import Logger from './logger'; import marketplaceSDKClient, { App, + Installation, MarketplaceSDKInitiator, marketplaceSDKInitiator, ContentstackMarketplaceClient, @@ -32,6 +33,7 @@ export * from './add-locale'; // Marketplace SDK export export { App, + Installation, marketplaceSDKClient, MarketplaceSDKInitiator, marketplaceSDKInitiator,