Skip to content

Commit

Permalink
Merge pull request #1286 from contentstack/feat/CS-42473-live-preview
Browse files Browse the repository at this point in the history
Feat/CS-42473 live preview
  • Loading branch information
cs-raj authored Feb 6, 2024
2 parents 59d4c56 + d4496b8 commit 1aaf97e
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 55 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/contentstack-bootstrap/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-cm-bootstrap",
"description": "Bootstrap contentstack apps",
"version": "1.7.1",
"version": "1.8.0",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Stream } from 'stream';
import * as zlib from 'zlib';
import * as tar from 'tar';
import * as mkdirp from 'mkdirp';
const mkdirp = require('mkdirp')
import { HttpRequestConfig, HttpClient } from '@contentstack/cli-utilities';

import GithubError from './github-error';
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-bootstrap/src/bootstrap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default class Bootstrap {

if (this.options.livePreviewEnabled) {
cliux.print(
'Important: set management token and app host in the environment file before running the application',
'Note: Before running the app, please configure a preview token, preview host, and app host in the environment file',
{
color: 'yellow',
},
Expand Down
11 changes: 11 additions & 0 deletions packages/contentstack-bootstrap/src/bootstrap/interactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,14 @@ export async function inquireLivePreviewSupport() {
});
return livePreviewEnabled;
}

export async function continueBootstrapCommand() {
const { shouldContinue } = await inquirer.prompt({
type: 'list',
name: 'shouldContinue',
message: `To continue with the Bootstrap command without Live Preview, please select Yes.`,
choices: ['yes', 'no'],
loop: false,
});
return shouldContinue;
}
137 changes: 99 additions & 38 deletions packages/contentstack-bootstrap/src/bootstrap/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { cliux } from '@contentstack/cli-utilities';

import { continueBootstrapCommand } from '../bootstrap/interactive';
import { AppConfig } from '../config';
import messageHandler from '../messages';

Expand All @@ -10,6 +10,7 @@ interface EnviornmentVariables {
deliveryToken: string;
environment: string;
livePreviewEnabled?: boolean;
preview_token: string;
}

/**
Expand Down Expand Up @@ -54,30 +55,45 @@ export const setupEnvironments = async (
],
},
};
if (!managementToken) {
try {
const tokenResult = await managementAPIClient.stack({ api_key }).deliveryToken().create(body);
if (tokenResult.token) {
const environmentVariables: EnviornmentVariables = {
api_key,
deliveryToken: tokenResult.token,
environment: environment.name,
livePreviewEnabled,
};
await envFileHandler(
appConfig.appConfigKey || '',
environmentVariables,
clonedDirectory,
region,
livePreviewEnabled,
);
} else {
cliux.print(messageHandler.parse('CLI_BOOTSTRAP_APP_FAILED_TO_CREATE_TOKEN_FOR_ENV', environment.name));
try {
const tokenResult = !managementToken
? await managementAPIClient
.stack({ api_key })
.deliveryToken()
.create(body, livePreviewEnabled ? { create_with_preview_token: true } : {})
: {};
if (livePreviewEnabled && !tokenResult.preview_token && !managementToken) {
cliux.print(
`Info: Failed to generate a preview token for the ${environment.name} environment.\nNote: Live Preview using a preview token is not available in your plan. Please contact the admin for support.`,
{
color: 'yellow',
},
);
if ((await continueBootstrapCommand()) === 'no') {
return;
}
} catch (error) {
console.log('error', error);
cliux.print(messageHandler.parse('CLI_BOOTSTRAP_APP_FAILED_TO_CREATE_ENV_FILE_FOR_ENV', environment.name));
}
if (tokenResult.token) {
const environmentVariables: EnviornmentVariables = {
api_key,
deliveryToken: tokenResult.token ?? '',
environment: environment.name,
livePreviewEnabled,
preview_token: tokenResult.preview_token ?? '',
};
await envFileHandler(
appConfig.appConfigKey || '',
environmentVariables,
clonedDirectory,
region,
livePreviewEnabled,
);
} else {
cliux.print(messageHandler.parse('CLI_BOOTSTRAP_APP_FAILED_TO_CREATE_TOKEN_FOR_ENV', environment.name));
}
} catch (error) {
console.log('error', error);
cliux.print(messageHandler.parse('CLI_BOOTSTRAP_APP_FAILED_TO_CREATE_ENV_FILE_FOR_ENV', environment.name));
}
} else {
cliux.print('No environments name found for the environment');
Expand Down Expand Up @@ -123,11 +139,15 @@ const envFileHandler = async (
let filePath;
let fileName;
let customHost;
let previewHost: string;
let appHost: string;
const managementAPIHost = region?.cma?.substring('8');
const regionName = region && region.name && region.name.toLowerCase();
const managementAPIHost = region.cma && region.cma.substring('8');
previewHost = region?.cda?.substring(8)?.replace('cdn', 'rest-preview');
appHost = region?.uiHost?.substring(8);
const isUSRegion = regionName === 'us' || regionName === 'na';
if (regionName !== 'eu' && !isUSRegion) {
customHost = region.cma && region.cma.substring('8');
customHost = region?.cma?.substring(8);
}
const production = environmentVariables.environment === 'production' ? true : false;
switch (appConfigKey) {
Expand All @@ -137,9 +157,13 @@ const envFileHandler = async (
filePath = path.join(clonedDirectory, fileName);
content = `REACT_APP_CONTENTSTACK_API_KEY=${
environmentVariables.api_key
}\nREACT_APP_CONTENTSTACK_DELIVERY_TOKEN=${
environmentVariables.deliveryToken
}\nREACT_APP_CONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}${
}\nREACT_APP_CONTENTSTACK_DELIVERY_TOKEN=${environmentVariables.deliveryToken}${
livePreviewEnabled
? `\nREACT_APP_CONTENTSTACK_PREVIEW_TOKEN=${
environmentVariables.preview_token || `''`
}\nREACT_APP_CONTENTSTACK_PREVIEW_HOST=${previewHost}\nREACT_APP_CONTENTSTACK_APP_HOST=${appHost}\n`
: '\n'
}\nREACT_APP_CONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}\n${
customHost ? '\nREACT_APP_CONTENTSTACK_API_HOST=' + customHost : ''
}${
!isUSRegion && !customHost ? '\nREACT_APP_CONTENTSTACK_REGION=' + region.name : ''
Expand All @@ -152,26 +176,45 @@ const envFileHandler = async (
filePath = path.join(clonedDirectory, fileName);
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${
environmentVariables.deliveryToken
}\nCONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}\nCONTENTSTACK_API_HOST=${
}\n${
livePreviewEnabled
? `\nCONTENTSTACK_PREVIEW_TOKEN=${
environmentVariables.preview_token || `''`
}\nCONTENTSTACK_PREVIEW_HOST=${previewHost}\nCONTENTSTACK_APP_HOST=${appHost}\n`
: '\n'
}CONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}\nCONTENTSTACK_API_HOST=${
customHost ? customHost : managementAPIHost
}${
!isUSRegion && !customHost ? '\nCONTENTSTACK_REGION=' + region.name : ''
}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}\nCONTENTSTACK_MANAGEMENT_TOKEN=''\nCONTENTSTACK_APP_HOST=''\nCONTENTSTACK_LIVE_EDIT_TAGS=false`;
}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}\nCONTENTSTACK_LIVE_EDIT_TAGS=false`;
result = await writeEnvFile(content, filePath);
break;
case 'gatsby':
case 'gatsby-starter':
fileName = `.env.${environmentVariables.environment}`;
filePath = path.join(clonedDirectory, fileName);
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${environmentVariables.deliveryToken}\nCONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}\nCONTENTSTACK_API_HOST=${managementAPIHost}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}`;
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${
environmentVariables.deliveryToken
}\n${
livePreviewEnabled
? `\nCONTENTSTACK_PREVIEW_TOKEN=${environmentVariables.preview_token || `''`}\nCONTENTSTACK_PREVIEW_HOST=${previewHost}\nCONTENTSTACK_APP_HOST=${appHost}\n`: '\n'
}\nCONTENTSTACK_ENVIRONMENT=${
environmentVariables.environment
}\nCONTENTSTACK_API_HOST=${managementAPIHost}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}`;
result = await writeEnvFile(content, filePath);
break;
case 'angular':
content = `export const environment = { \n\tproduction:${
environmentVariables.environment === 'production' ? true : false
}, \n\tconfig : { \n\t\tapi_key: '${environmentVariables.api_key}', \n\t\tdelivery_token: '${
environmentVariables.deliveryToken
}', \n\t\tenvironment: '${environmentVariables.environment}'${
}',\n${
livePreviewEnabled
? `\n\tpreivew_token:'${
environmentVariables.preview_token || `''`
}'\n\tpreview_host:'${previewHost}'\n\tapp_host:'${appHost}'\n`
: '\n'
},\n\t\tenvironment: '${environmentVariables.environment}'${
!isUSRegion && !customHost ? `,\n\t\tregion: '${region.name}'` : ''
} \n\t } \n };`;
fileName = `environment${environmentVariables.environment === 'production' ? '.prod.' : '.'}ts`;
Expand All @@ -181,11 +224,16 @@ const envFileHandler = async (
case 'angular-starter':
content = `export const environment = { \n\tproduction: true \n}; \nexport const Config = { \n\tapi_key: '${
environmentVariables.api_key
}', \n\tdelivery_token: '${environmentVariables.deliveryToken}', \n\tenvironment: '${
environmentVariables.environment
}'${!isUSRegion && !customHost ? `,\n\tregion: '${region.name}'` : ''},\n\tapi_host: '${
}', \n\tdelivery_token: '${environmentVariables.deliveryToken}',\n\t${
livePreviewEnabled
? `\npreview_token:'${environmentVariables.preview_token || ''}',\npreview_host:'${previewHost
}',\napp_host:'${appHost}'`
: '\n'
},\n\tenvironment: '${environmentVariables.environment}'${
!isUSRegion && !customHost ? `,\n\tregion: '${region.name}'` : ''
},\n\tapi_host: '${
customHost ? customHost : managementAPIHost
}',\n\tapp_host: '',\n\tmanagement_token: '',\n\tlive_preview: ${livePreviewEnabled}\n};`;
}',\n\tlive_preview: ${livePreviewEnabled}\n};`;
fileName = `environment${environmentVariables.environment === 'production' ? '.prod.' : '.'}ts`;
filePath = path.join(clonedDirectory, 'src', 'environments', fileName);
result = await writeEnvFile(content, filePath);
Expand All @@ -198,18 +246,31 @@ const envFileHandler = async (
// Note: Stencil app needs all the env variables, even if they are not having values otherwise the rollup does not work properly and throws process in undefined error.
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${
environmentVariables.deliveryToken
}\n${
livePreviewEnabled
? `\nCONTENTSTACK_PREVIEW_TOKEN=${environmentVariables.preview_token || `''`}\nCONTENTSTACK_PREVIEW_HOST=${
customHost ?? previewHost
}\nCONTENTSTACK_APP_HOST=${appHost}`
: '\n'
}\nCONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}${
!isUSRegion && !customHost ? '\nCONTENTSTACK_REGION=' + region.name : ''
}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}\nCONTENTSTACK_MANAGEMENT_TOKEN=''\nCONTENTSTACK_API_HOST='${
}\nCONTENTSTACK_API_HOST=${
customHost ? customHost : managementAPIHost
}'\nCONTENTSTACK_APP_HOST=''\nCONTENTSTACK_LIVE_EDIT_TAGS=false`;
}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}\n\nCONTENTSTACK_LIVE_EDIT_TAGS=false`;
result = await writeEnvFile(content, filePath);
break;
case 'vue-starter':
fileName = '.env';
filePath = path.join(clonedDirectory, fileName);
content = `VUE_APP_CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nVUE_APP_CONTENTSTACK_DELIVERY_TOKEN=${
environmentVariables.deliveryToken
}\n${
livePreviewEnabled
? `\nVUE_APP_CONTENTSTACK_PREVIEW_TOKEN=${
environmentVariables.preview_token || `''`
}\nVUE_APP_CONTENTSTACK_PREVIEW_HOST=${previewHost
}\nVUE_APP_CONTENTSTACK_APP_HOST=${appHost}\n`
: '\n'
}\nVUE_APP_CONTENTSTACK_ENVIRONMENT=${environmentVariables.environment}${
customHost ? '\nVUE_APP_CONTENTSTACK_API_HOST=' + customHost : ''
}${
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-bootstrap/test/github.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('Github Client', function () {
it('Git Tarball url creation', () => {
const repo = GitHubClient.parsePath('contentstack/contentstack-nextjs-react-universal-demo');
const gClient = new GitHubClient(repo);
expect(gClient.gitTarBallUrl).to.be.equal('https://api.github.com/repos/contentstack/contentstack-nextjs-react-universal-demo/tarball/master')
expect(gClient.gitTarBallUrl).to.be.equal('https://api.github.com/repos/contentstack/contentstack-nextjs-react-universal-demo/tarball/cli-use')
})

it('Clone the source repo', async function () {
Expand Down
Loading

0 comments on commit 1aaf97e

Please sign in to comment.