@pega/custom-dx-components
Version:
Utility for building custom UI components
246 lines (216 loc) • 7.34 kB
JavaScript
import fs from 'fs';
import path from 'path';
import fetch from 'node-fetch';
import archiver from 'archiver';
import chalk from 'chalk';
import {
constructCompleteUrl,
getComponentDirectoryPath,
getComponents,
getPegaServerConfig,
validateRulesetVersion,
getHttpsAgent,
addDebugLog
} from '../../util.js';
import {
PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT,
LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT,
TOKEN_PATH
} from '../../constants.js';
export const getPublishComponentQuestions = async componentKey => {
addDebugLog("getPublishComponentQuestions", `componentKey: ${componentKey}`, "");
const components = await getComponents();
if (components.length === 0) {
console.log(chalk.redBright('No components to publish'));
process.exit();
}
const defaultPegaConfig = await getPegaServerConfig();
return [
{
name: 'componentKey',
type: 'rawlist',
message: 'Select component to publish',
choices: components,
default: componentKey,
when: () => !componentKey
},
{
name: 'rulesetName',
message: 'Enter ruleset name',
default: defaultPegaConfig.rulesetName,
validate: value => {
if (value.trim()) {
return true;
}
return 'Ruleset name cannot be empty';
},
when: () => {
return defaultPegaConfig.serverType === 'infinity';
}
},
{
name: 'rulesetVersion',
message: 'Enter ruleset version',
default: defaultPegaConfig.rulesetVersion,
validate: value => {
if (validateRulesetVersion(value)) {
return true;
}
return 'Please provide compatible version e.g 01-01-01';
},
when: () => {
return defaultPegaConfig.serverType === 'infinity';
}
},
{
name: 'sourceMap',
message: 'Generate source map ?',
default: defaultPegaConfig.sourceMap,
// eslint-disable-next-line sonarjs/no-redundant-boolean
when: () => false && !process.env.SOURCE_MAP
},
{
name: 'devBuild',
type: 'confirm',
message: 'Generate development build ?',
default: defaultPegaConfig.devBuild,
when: () => componentKey !== "LibraryMode"
}
];
};
export const zipComponent = async componentKey => {
addDebugLog("zipComponent", `componentKey: ${componentKey}`, "");
const srcDirectory = await getComponentDirectoryPath(componentKey);
const buildDirectory = await path.join(path.resolve(), 'dist/components', componentKey);
const configJson = `${srcDirectory}/config.json`;
const localizationJson = `${srcDirectory}/localizations.json`;
const archive = archiver('zip', { zlib: { level: 9 } });
const zipChunks = [];
archive.on('data', chunk => zipChunks.push(chunk));
// Add src directory
archive.directory(srcDirectory, 'src');
// Add config.json file
if (fs.existsSync(configJson)) {
archive.file(configJson, { name: path.basename(configJson) });
}
// Add localizations.json file if it exists
if (fs.existsSync(localizationJson)) {
archive.file(localizationJson, { name: path.basename(localizationJson) });
}
// Add build directory
archive.directory(buildDirectory, false);
await archive.finalize();
const zipBuffer = Buffer.concat(zipChunks);
console.log(chalk.green(`component zipped with size: ${Math.ceil(zipBuffer.length / 1024)} KB`));
const zipContent = zipBuffer.toString('base64');
const configContent = Buffer.from(fs.readFileSync(configJson)).toString();
if (fs.existsSync('dist')) {
fs.rm('dist', { recursive: true }, err => {
if (err) {
throw err;
}
});
}
return { zipContent, configContent };
};
export const publishComponentToServer = async (data, doFetch) => {
addDebugLog("publishComponentToServer", `data: ${data}`, "");
const { configContent, zipContent, rulesetName, rulesetVersion } = data;
const defaultPegaServerConfig = await getPegaServerConfig();
const { serverType, isolationId } = defaultPegaServerConfig;
const isLaunchpad = serverType === 'launchpad';
const launchpadRestEndpoint = LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT.replace(
'{isolationId}',
isolationId || 'undefined'
);
let apiBody;
if (isLaunchpad) {
apiBody = {
type: 'CustomComponent',
zipContent,
componentName: JSON.parse(configContent).componentKey,
pxUpdateDateTime: '',
environmentID: defaultPegaServerConfig.isolationId
};
} else {
apiBody = {
configContent,
zipContent,
componentKey: JSON.parse(configContent).componentKey,
publishFor: 'constellation',
rulesetName,
rulesetVersion,
category: ''
};
}
const defaultPegaConfig = await getPegaServerConfig();
const url = constructCompleteUrl(
defaultPegaConfig.server,
isLaunchpad ? launchpadRestEndpoint : PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT
);
if (doFetch) {
try {
const OauthData = fs.readFileSync(TOKEN_PATH, 'utf8');
if (OauthData) {
const {
access_token: accessToken,
token_type: tokenType
// refresh_token: refreshToken
} = JSON.parse(OauthData);
let status = 500;
let headers = {};
if (isLaunchpad) {
headers.cookie = `Pega-AAT=${accessToken}`;
headers['Content-Type'] = 'application/json';
} else {
headers.Authorization = `${tokenType} ${accessToken}`;
}
const response = await fetch(url, {
method: 'POST',
agent: getHttpsAgent(defaultPegaConfig),
headers,
body: JSON.stringify(apiBody)
});
status = response.status;
if (!response.ok) {
if (status === 401) {
throw new Error(
'Error occurred in authentication. Please regenerate using authenticate'
);
// console.log(accessTokenUri, refreshToken);
/* TODO - Handle refresh_token */
} else if (status === 404) {
throw new Error('404: Server resource not found');
} else if (status === 405) {
throw new Error('405: Server method not allowed');
} else if (status === 408) {
throw new Error('408: Server timed out');
} else if (response.status === 403) {
throw new Error('Error forbidden: User does not have privileges to Publish.');
}
}
try {
const respData = isLaunchpad ? await response.text() : await response.json();
if (status === 500) {
status = 999;
throw Error( "\n" + respData.message);
}
console.log(chalk.bold.green(`Success : ${isLaunchpad ? respData : respData.message}`));
} catch (err) {
if (status === 500) {
throw new Error(
`Error occurred in authentication. Please regenerate using authenticate`
);
} else if (status === 999) {
throw Error(err);
}
}
} else {
throw new Error(`Error occurred in authentication. Please regenerate using authenticate`);
}
} catch (err) {
// throw new Error(`Error occurred in authentication. Please regenerate using authenticate`);
throw Error(err);
}
}
};