@pega/custom-dx-components 0.25.13 → 0.25.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/custom-dx-components",
3
- "version": "0.25.13",
3
+ "version": "0.25.14",
4
4
  "description": "Utility for building custom UI components",
5
5
  "bin": "./bin/index.js",
6
6
  "scripts": {
@@ -19,7 +19,7 @@
19
19
  "@babel/plugin-transform-class-properties": "^7.25.9",
20
20
  "@babel/preset-react": "^7.26.3",
21
21
  "@pega/auth": "^0.2.23",
22
- "@pega/constellation-dx-components-build-utils": "^1.0.1",
22
+ "@pega/constellation-dx-components-build-utils": "^2.0.0-dev",
23
23
  "@pega/inquirer-fuzzy-path": "^3.0.0",
24
24
  "ajv": "^8.17.1",
25
25
  "ajv-keywords": "^5.1.0",
package/src/constants.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // cSpell:ignore words timeofday caseview casepreview objectview
2
2
  export const TASKS_CONFIG_JSON_FILENAME = 'tasks.config.json';
3
3
  export const PACKAGE_JSON_FILENAME = 'package.json';
4
+ export const PACKAGE_LOCK_JSON_FILENAME = 'package-lock.json';
4
5
  export const BUILD_CONFIG_JSON_FILENAME = 'build.config.json';
5
6
  export const WEBPACK_CONFIG_JS_FILENAME = 'webpack.config.js';
6
7
  export const WEBPACK_PATHS_JS_FILENAME = 'paths.js';
@@ -39,6 +40,9 @@ export const LP_DELETE_COMPONENT_SERVICE_REST_ENDPOINT =
39
40
  'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
40
41
 
41
42
  export const PUBLISH_COMPONENT_LIBRARY_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component_library';
43
+ export const PUBLISH_COMPONENT_ARCHIVE_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component_archive';
44
+ export const LIST_COMPONENT_LIBRARIES_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/list_component_libraries';
45
+
42
46
 
43
47
  export const FIELD_PATH = '/field';
44
48
  export const TEMPLATE_PATH = '/template';
@@ -3,7 +3,7 @@ import inquirer from 'inquirer';
3
3
  import { Listr } from 'listr2';
4
4
  import chalk from 'chalk';
5
5
 
6
- import { buildLib } from '@pega/constellation-dx-components-build-utils/index.js';
6
+ import { buildLib, buildLibV3 } from '@pega/constellation-dx-components-build-utils/index.js';
7
7
 
8
8
  import validate from '../validator/index.js';
9
9
  import { lintComponent } from '../linter/index.js';
@@ -115,7 +115,7 @@ addDebugLog("localBuildLibrary", `organization: ${organization}, library: ${libr
115
115
  // with subdirectories for each version.
116
116
  // If "buildDev", we append to version "-dev". Currently, only "-dev" versions, when published, can be deleted.
117
117
  addDebugLog("buildLib", "services call", "");
118
- buildLib(
118
+ buildLibV3(
119
119
  buildLibName,
120
120
  buildVersion,
121
121
  tokenAndStaticServer.C11NB2S,
@@ -110,6 +110,20 @@ addDebugLog("getLibraryVersionQuestion", "", "");
110
110
  ];
111
111
  };
112
112
 
113
+ export const getServerOrDirectoryQuestion = async () => {
114
+ addDebugLog("getLibraryVersionQuestion", "", "");
115
+
116
+ return [
117
+ {
118
+ name: 'exportTo',
119
+ type: 'rawlist',
120
+ message: `Export to`,
121
+ choices: [{name: 'Local directory', value: 'Directory'}, {name: 'Server', value: 'Server'}],
122
+ defaut: 'Directory'
123
+ }
124
+ ];
125
+ };
126
+
113
127
  export const getFullArchiveQuestions = async () => {
114
128
 
115
129
  return [
@@ -14,13 +14,16 @@ import {
14
14
  checkLibraryAndArchives,
15
15
  getConfigDefaults,
16
16
  getLibraryBased,
17
+ getLibraryBasedCL,
17
18
  zipVersionAndArchive,
18
19
  zipVersionAndArchiveCL,
19
- cleanUpTemp
20
+ cleanUpTemp,
21
+ checkAccessTokenExpiration
20
22
  } from '../../util.js';
21
23
  import { TASKS_CONFIG_JSON_FILENAME, ARCHIVES_PATH, BIN_ARCHIVES_PATH } from '../../constants.js';
22
- import { getFilePathQuestions, getLibraryQuestion, getLibraryVersionQuestion, updateSavedExportFilePath, getFullArchiveQuestions } from './helper.js';
24
+ import { getFilePathQuestions, getLibraryQuestion, getLibraryVersionQuestion, updateSavedExportFilePath, getFullArchiveQuestions, getServerOrDirectoryQuestion } from './helper.js';
23
25
  import { localBuildLibrary } from '../build-lib/index.js';
26
+ import publishArchive from '../publish-archive/index.js';
24
27
 
25
28
  import inquirerFuzzyPath from '@pega/inquirer-fuzzy-path';
26
29
 
@@ -293,22 +296,26 @@ export default async options => {
293
296
  await checkLibraryAndArchives();
294
297
 
295
298
  await checkPathAccess(pegaConfigJsonPath);
299
+
296
300
  const isLibraryBased = getLibraryBased();
297
301
  if (!isLibraryBased) {
298
302
  console.log(`Command only supported for ${chalk.bold.green('library mode')} components.`)
299
303
  process.exit();
300
304
  }
305
+ const isLibraryBasedCL = getLibraryBasedCL();
301
306
 
302
307
  await cleanUpTemp();
303
308
 
304
309
  addDebugLog("exportArchive", "", "+");
305
310
 
311
+ let exportTo = "";
306
312
 
307
313
  if (options.params.length >= 8) {
308
314
  let fullArchive = options.params[3];
309
315
  const libraryName = options.params[4];
310
316
  const libraryVersion = options.params[5];
311
317
  const filePath = options.params[6];
318
+ exportTo = "Directory";
312
319
 
313
320
 
314
321
  const currentOrArchive = options.params[7];
@@ -321,6 +328,7 @@ export default async options => {
321
328
  let selectedVersion = "";
322
329
  let fullArchive = "";
323
330
 
331
+
324
332
  if (options.params.length >= 5) {
325
333
  fullArchive = options.params[3];
326
334
  orgLibName = options.params[4];
@@ -370,23 +378,48 @@ export default async options => {
370
378
  ({ selectedVersion } = libraryVersionAnswer);
371
379
  }
372
380
 
373
- inquirer.registerPrompt('fuzzypath', inquirerFuzzyPath);
381
+ if (isLibraryBasedCL) {
382
+ if (exportTo === "") {
383
+ const serverOrDirectoryQuestion = await getServerOrDirectoryQuestion();
384
+ const serverOrDirectoryAnswer = await inquirer.prompt(serverOrDirectoryQuestion);
385
+ ({ exportTo } = serverOrDirectoryAnswer);
386
+ }
387
+ }
388
+ else {
389
+ exportTo = "Directory";
390
+ }
374
391
 
375
- filePathQuestions = await getFilePathQuestions();
376
- filePathAnswers = await inquirer.prompt(filePathQuestions);
377
- ({ filePath } = filePathAnswers);
378
392
 
379
- await updateSavedExportFilePath(filePath);
393
+ if (exportTo === "Directory") {
394
+ inquirer.registerPrompt('fuzzypath', inquirerFuzzyPath);
395
+
396
+ filePathQuestions = await getFilePathQuestions();
397
+ filePathAnswers = await inquirer.prompt(filePathQuestions);
398
+ ({ filePath } = filePathAnswers);
399
+
400
+ await updateSavedExportFilePath(filePath);
401
+
402
+ // if (path.sep === "/") {
403
+ // if (filePath.lastIndexOf(path.sep) != filePath.length - 1) {
404
+ // filePath = filePath.concat(path.sep);
405
+ // }
406
+ // }
407
+
408
+ await exportArch( filePath, orgLibName, selectedVersion, fullArchive);
409
+
410
+ }
411
+ else {
412
+ await checkAccessTokenExpiration();
413
+
414
+ // publish to server
415
+ await publishArchive(orgLibName, selectedVersion);
416
+
417
+ }
418
+
380
419
 
381
420
  }
382
421
 
383
- // if (path.sep === "/") {
384
- // if (filePath.lastIndexOf(path.sep) != filePath.length - 1) {
385
- // filePath = filePath.concat(path.sep);
386
- // }
387
- // }
388
422
 
389
- await exportArch( filePath, orgLibName, selectedVersion, fullArchive);
390
423
 
391
424
  }
392
425
 
@@ -106,7 +106,7 @@
106
106
  "@babel/preset-react": "^7.26.3",
107
107
  "@babel/preset-typescript": "^7.26.0",
108
108
  "@pega/configs": "^0.16.2",
109
- "@pega/custom-dx-components": "~0.25.13",
109
+ "@pega/custom-dx-components": "~0.25.14",
110
110
  "@pega/pcore-pconnect-typedefs": "^4.1.0-alpha.1",
111
111
  "@storybook/addon-actions": "^7.6.19",
112
112
  "@storybook/addon-essentials": "^7.6.19",
@@ -1,12 +1,22 @@
1
+
2
+ import fs from 'fs';
3
+ import path from 'path';
1
4
  import chalk from 'chalk';
5
+ import fetch from 'node-fetch';
6
+ import { join } from 'path';
2
7
 
3
8
  import {
4
9
  getPegaServerConfig,
5
10
  addDebugLog,
6
- getC11NB2STokenAndStaticServer
11
+ getC11NB2STokenAndStaticServer,
12
+ getApplicationAndVersionFromToken,
13
+ constructCompleteUrl,
14
+ getHttpsAgent,
15
+ getConfigDefaults
7
16
  } from '../../util.js';
8
17
 
9
18
  import { listLibJSONResponse } from '@pega/constellation-dx-components-build-utils/index.js';
19
+ import { LIST_COMPONENT_LIBRARIES_SERVICE_REST_ENDPOINT, TOKEN_PATH } from '../../constants.js';
10
20
 
11
21
  export const SOURCE_OF_COMPONENT_TYPES = {
12
22
  SERVER: 'Server',
@@ -72,3 +82,96 @@ addDebugLog("listLibJSONResponse", "services end", "");
72
82
  return [];
73
83
 
74
84
  }
85
+
86
+ async function fetchComponenLibrariessFromInfinity(apiUrl, headers) {
87
+ addDebugLog("fetchComponenLibrariessFromInfinity", `apiUrl: ${apiUrl}`, "");
88
+ const serverConfig = await getPegaServerConfig();
89
+ return new Promise((resolve, reject) => {
90
+ let status = 500;
91
+ fetch(apiUrl, {
92
+ method: 'GET',
93
+ agent: getHttpsAgent(serverConfig),
94
+ headers
95
+ })
96
+ .then((response) => {
97
+ status = response.status;
98
+ if (status === 401) {
99
+ throw new Error('Error occurred in authentication. Please regenerate using authenticate');
100
+ }
101
+ else if (status === 404){
102
+ throw new Error('404: Server resource not found');
103
+ }
104
+ else if (status === 405){
105
+ throw new Error('405: Server method not allowed');
106
+ }
107
+ else if (status === 408){
108
+ throw new Error('408: Server timed out');
109
+ }
110
+ return response.json();
111
+ })
112
+ .then((resp) => {
113
+ // const respData = JSON.parse(resp);
114
+ if (status === 401) {
115
+ throw new Error('Error occurred in authentication. Please regenerate using authenticate');
116
+ // console.log(accessTokenUri, refreshToken);
117
+ /* TODO - Handle refresh_token */
118
+ } else if (status === 200) {
119
+ resolve(resp);
120
+ } else {
121
+ throw new Error(`${resp.message}`);
122
+ }
123
+ })
124
+ // eslint-disable-next-line prefer-promise-reject-errors
125
+ .catch((e) => reject(`${chalk.bold.red(e)}`));
126
+ });
127
+ }
128
+
129
+ export const getInfinityLibraries = async() => {
130
+ addDebugLog("getInfinityLibraries", '', "");
131
+
132
+ const { app_name, app_version } = await getApplicationAndVersionFromToken();
133
+ const defaultPegaServerConfig = await getPegaServerConfig();
134
+ let url = constructCompleteUrl(
135
+ defaultPegaServerConfig.server,
136
+ LIST_COMPONENT_LIBRARIES_SERVICE_REST_ENDPOINT
137
+ );
138
+
139
+ const ApplicationName = app_name;
140
+ const ApplicationVersion = app_version;
141
+ const rulesetName = defaultPegaServerConfig.rulesetName;
142
+ const rulesetVersion = defaultPegaServerConfig.rulesetVersion;
143
+
144
+ let urlParams = `/AppName/${ApplicationName}/AppVersion/${ApplicationVersion}/ruleset/${rulesetName}/rulesetVersion/${rulesetVersion}`;
145
+ //let urlParams = `&ApplicationName=${ApplicationName}&ApplicationVersion=${ApplicationVersion}&RulesetName=${rulesetName}&RulesetVersion=${rulesetVersion}`;
146
+ //urlParams = encodeURIComponent(urlParams);
147
+
148
+
149
+ url = url.concat(urlParams);
150
+
151
+ return new Promise((resolve, reject) => {
152
+ try {
153
+ fs.readFile(TOKEN_PATH, 'utf8', (err, data) => {
154
+ if (err) {
155
+ // eslint-disable-next-line prefer-promise-reject-errors
156
+ reject(`\n${chalk.bold.red('Error occurred in authentication. Please regenerate using authenticate')}`);
157
+ }
158
+ if (data) {
159
+ const { access_token: accessToken, token_type: tokenType } = JSON.parse(data);
160
+
161
+ const headers = {};
162
+ headers.Authorization = `${tokenType} ${accessToken}`;
163
+
164
+ fetchComponenLibrariessFromInfinity(url, headers)
165
+ .then((response) => resolve(response))
166
+ .catch((e) => reject(e));
167
+
168
+ }
169
+ });
170
+ } catch (error) {
171
+ console.log(`\n${chalk.bold.red(error)}`);
172
+ // eslint-disable-next-line prefer-promise-reject-errors
173
+ reject(`${chalk.bold.red(error)}`);
174
+ }
175
+ });
176
+
177
+ }
@@ -1,11 +1,11 @@
1
1
  import inquirer from 'inquirer';
2
2
  import chalk from 'chalk';
3
3
 
4
- import {showVersion, getC11NB2STokenAndStaticServer, getLocalLibraries, getLocalLibraryVersions, getLocalLibraryVersionData, getLibraryBased, addDebugLog, checkLibraryAndArchives, getConfigDefaults, cleanUpTemp } from '../../util.js';
4
+ import {showVersion, getC11NB2STokenAndStaticServer, getLocalLibraries, getLocalLibraryVersions, getLocalLibraryVersionData, getLibraryBased, addDebugLog, checkLibraryAndArchives, getConfigDefaults, cleanUpTemp, getPegaServerConfig } from '../../util.js';
5
5
 
6
6
  import { listLibJSONResponse } from '@pega/constellation-dx-components-build-utils/index.js';
7
7
 
8
- import { getListLibraryQuestions, SOURCE_OF_COMPONENT_TYPES, getServerLibraries, getServerLocalQuestion } from './helper.js';
8
+ import { getListLibraryQuestions, SOURCE_OF_COMPONENT_TYPES, getServerLibraries, getInfinityLibraries, getServerLocalQuestion } from './helper.js';
9
9
 
10
10
 
11
11
 
@@ -139,6 +139,50 @@ addDebugLog("listPublished", "END", "-");
139
139
  }
140
140
  else {
141
141
 
142
+ const arLibs = await getInfinityLibraries();
143
+
144
+ if (arLibs && arLibs.pxResults && arLibs.pxResults.length > 0) {
145
+
146
+ const libs = arLibs.pxResults.map((oLib, index) => ({ name: oLib.pyLabel, value: index}));
147
+
148
+
149
+ const libAnswers = await inquirer.prompt([
150
+ {
151
+ name: 'library',
152
+ type: 'rawlist',
153
+ message: 'Pick library',
154
+ choices: libs
155
+ }
156
+ ]);
157
+
158
+ const libraryIndex = libAnswers.library;
159
+
160
+ const data = JSON.parse(arLibs.pxResults[libraryIndex].pxComponentDefinition);
161
+
162
+ // get built on from first component if exists
163
+ let builtOn = "(date unavailable)";
164
+ if (data[0] && data[0].buildDate) {
165
+ builtOn = data[0].buildDate;
166
+ }
167
+
168
+ let libData = data.map((component) => ( {'Component': component.name, 'Label': component.label, 'Version': component.version, 'Type': component.type, 'Sub Type' : component.subtype}));
169
+ console.log(chalk.bold.blueBright(`\nList of ${libraryName}:${selectedVersion} components built on ${builtOn}.`));
170
+ console.table(libData, ['Component', 'Label', 'Version', 'Type', 'Sub Type']);
171
+
172
+ }
173
+ else {
174
+ // No library with that name
175
+ const serverConfig = await getPegaServerConfig();
176
+ console.log(chalk.redBright(`No server component libraries exist in given ruleset ${chalk.bold(`${serverConfig.rulesetName}:${serverConfig.rulesetVersion}`)}`));
177
+ console.log(chalk.redBright(`You need to publish a library to this ruleset first.`));
178
+ addDebugLog("listPublished", "END", "-");
179
+ process.exit(1);
180
+
181
+ }
182
+
183
+ /*
184
+ // old app static server
185
+
142
186
  const arLibs = await getServerLibraries();
143
187
  if (arLibs && arLibs.length > 0) {
144
188
 
@@ -180,11 +224,10 @@ addDebugLog("listPublished", "END", "-");
180
224
  let libData = data.map((component) => ( {'Component': component.name, 'Label': component.label, 'Version': component.version, 'Type': component.type, 'Sub Type' : component.subtype}));
181
225
  console.log(chalk.bold.blueBright(`\nList of ${libraryName}:${selectedVersion} components built on ${builtOn}.`));
182
226
  console.table(libData, ['Component', 'Label', 'Version', 'Type', 'Sub Type']);
183
- }
184
- else {
185
- console.log(chalk.red("No libraries available on server."));
186
- }
187
-
227
+ }
228
+ else {
229
+ console.log(chalk.red("No libraries available on server."));
230
+ }
188
231
 
189
232
 
190
233
  }
@@ -196,6 +239,7 @@ addDebugLog("listPublished", "END", "-");
196
239
  process.exit(1);
197
240
 
198
241
  }
242
+ */
199
243
 
200
244
  }
201
245
 
@@ -6,7 +6,7 @@ import fs from 'fs';
6
6
  import validate from '../validator/index.js';
7
7
  import bundleComponent from '../bundle/index.js';
8
8
  import { lintComponent } from '../linter/index.js';
9
- import { getComponentDirectoryPath, showVersion, getLibraryBased, addDebugLog, getPegaServerConfig, updateServerConfigRuleSetAndVersion, checkLibraryAndArchives, getConfigDevBuild, checkAccessTokenExpiration, checkJWTExpiration, getConfigDefaults } from '../../util.js';
9
+ import { getComponentDirectoryPath, showVersion, getLibraryBased, addDebugLog, updateServerConfigRuleSetAndVersion, checkLibraryAndArchives, getConfigDevBuild, checkAccessTokenExpiration, checkJWTExpiration, getConfigDefaults } from '../../util.js';
10
10
 
11
11
  import { getPublishComponentQuestions, publishComponentToServer, zipComponent } from './helper.js';
12
12
  import { default as buildLibrary } from '../build-lib/index.js';
@@ -26,6 +26,9 @@ addDebugLog("publish", "", "+");
26
26
 
27
27
  await checkAccessTokenExpiration();
28
28
 
29
+ //
30
+ // library based V2 publishing
31
+ //
29
32
  if (isLibraryBased) {
30
33
 
31
34
  await checkJWTExpiration();
@@ -106,9 +109,15 @@ addDebugLog("publish", "", "+");
106
109
 
107
110
  }
108
111
 
112
+ // end of V2 publishing
109
113
  return true;
110
114
  }
111
115
 
116
+ // otherwise continue with original V1 publishig of individual components
117
+
118
+ //
119
+ // orginial V1 publish
120
+ //
112
121
 
113
122
  let OauthData;
114
123
  try {
@@ -0,0 +1,58 @@
1
+ import {
2
+ addDebugLog,
3
+ getPegaServerConfig,
4
+ validateRulesetVersion
5
+ } from '../../util.js';
6
+
7
+
8
+ export const getLibraryVersionQuestion = async(libVersions) => {
9
+ addDebugLog("getLibraryVersionQuestion", `libVersions: ${libVersions}`, "");
10
+ return [
11
+ {
12
+ name: 'version',
13
+ type: 'rawlist',
14
+ message: 'Select library version to publish',
15
+ choices: libVersions
16
+ }
17
+ ];
18
+
19
+ }
20
+
21
+ export const getPublishComponentQuestions = async componentKey => {
22
+ addDebugLog("getPublishComponentQuestions", `componentKey: ${componentKey}`, "");
23
+
24
+
25
+ const defaultPegaConfig = await getPegaServerConfig();
26
+
27
+ return [
28
+ {
29
+ name: 'rulesetName',
30
+ message: 'Enter ruleset name',
31
+ default: defaultPegaConfig.rulesetName,
32
+ validate: value => {
33
+ if (value.trim()) {
34
+ return true;
35
+ }
36
+ return 'Ruleset name cannot be empty';
37
+ },
38
+ when: () => {
39
+ return defaultPegaConfig.serverType === 'infinity';
40
+ }
41
+ },
42
+ {
43
+ name: 'rulesetVersion',
44
+ message: 'Enter ruleset version',
45
+ default: defaultPegaConfig.rulesetVersion,
46
+ validate: value => {
47
+ if (validateRulesetVersion(value)) {
48
+ return true;
49
+ }
50
+ return 'Please provide compatible version e.g 01-01-01';
51
+ },
52
+ when: () => {
53
+ return defaultPegaConfig.serverType === 'infinity';
54
+ }
55
+ }
56
+ ];
57
+
58
+ };
@@ -0,0 +1,257 @@
1
+ import inquirer from 'inquirer';
2
+ import chalk from 'chalk';
3
+ import fetch from 'node-fetch';
4
+ import { join } from 'path';
5
+ import fs from 'fs';
6
+
7
+
8
+ import { zipUnArchiveToTempAndReturnBuffer, constructCompleteUrl, getHttpsAgent, getPegaServerConfig, addDebugLog, getConfigDefaults, zipVersionAndArchiveAndReturnBuffer } from '../../util.js';
9
+
10
+ import { getPublishComponentQuestions } from './helper.js';
11
+
12
+ import {
13
+ LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT,
14
+ PUBLISH_COMPONENT_ARCHIVE_SERVICE_REST_ENDPOINT,
15
+ TEMP_PATH,
16
+ TOKEN_PATH,
17
+ ARCHIVES_PATH
18
+ } from '../../constants.js';
19
+
20
+
21
+ export const publishComponentLibraryArchiveToServer = async (data, doFetch) => {
22
+ addDebugLog("publishComponentToServer", `data: ${data}`, "");
23
+ const { zipContent, rulesetName, rulesetVersion, libraryName, version } = data;
24
+
25
+ const defaultPegaServerConfig = await getPegaServerConfig();
26
+ const { serverType, isolationId } = defaultPegaServerConfig;
27
+ const isLaunchpad = serverType === 'launchpad';
28
+ const launchpadRestEndpoint = LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT.replace(
29
+ '{isolationId}',
30
+ isolationId || 'undefined'
31
+ );
32
+ let apiBody;
33
+
34
+ if (isLaunchpad) {
35
+ // currently no launchpad records to rule resolve a library
36
+
37
+ // apiBody = {
38
+ // type: 'CustomComponent',
39
+ // zipContent,
40
+ // componentName: JSON.parse(configContent).componentKey,
41
+ // pxUpdateDateTime: '',
42
+ // environmentID: defaultPegaServerConfig.isolationId
43
+ // };
44
+ } else {
45
+ apiBody = {
46
+ zipContent,
47
+ publishFor: 'constellation',
48
+ rulesetName,
49
+ rulesetVersion,
50
+ libraryName,
51
+ version,
52
+ category: ''
53
+ };
54
+ }
55
+
56
+ const defaultPegaConfig = await getPegaServerConfig();
57
+ const url = constructCompleteUrl(
58
+ defaultPegaConfig.server,
59
+ isLaunchpad ? launchpadRestEndpoint : PUBLISH_COMPONENT_ARCHIVE_SERVICE_REST_ENDPOINT
60
+ );
61
+
62
+ if (doFetch) {
63
+ try {
64
+ const OauthData = fs.readFileSync(TOKEN_PATH, 'utf8');
65
+ if (OauthData) {
66
+ const {
67
+ access_token: accessToken,
68
+ token_type: tokenType
69
+ // refresh_token: refreshToken
70
+ } = JSON.parse(OauthData);
71
+ let status = 500;
72
+ let headers = {};
73
+
74
+ if (isLaunchpad) {
75
+ headers.cookie = `Pega-AAT=${accessToken}`;
76
+ headers['Content-Type'] = 'application/json';
77
+ } else {
78
+ headers.Authorization = `${tokenType} ${accessToken}`;
79
+ }
80
+
81
+ const response = await fetch(url, {
82
+ method: 'POST',
83
+ agent: getHttpsAgent(defaultPegaConfig),
84
+ headers,
85
+ body: JSON.stringify(apiBody)
86
+ });
87
+
88
+ status = response.status;
89
+ if (!response.ok) {
90
+ if (status === 401) {
91
+ throw new Error(
92
+ 'Error occurred in authentication. Please regenerate using authenticate'
93
+ );
94
+ // console.log(accessTokenUri, refreshToken);
95
+ /* TODO - Handle refresh_token */
96
+ } else if (status === 404) {
97
+ throw new Error('404: Server resource not found');
98
+ } else if (status === 405) {
99
+ throw new Error('405: Server method not allowed');
100
+ } else if (status === 408) {
101
+ throw new Error('408: Server timed out');
102
+ } else if (response.status === 403) {
103
+ throw new Error('Error forbidden: User does not have privileges to Publish.');
104
+ }
105
+ }
106
+
107
+ try {
108
+ const respData = isLaunchpad ? await response.text() : await response.json();
109
+ console.log(chalk.bold.green(`Success : ${isLaunchpad ? respData : respData.message}`));
110
+
111
+ if (status === 500) {
112
+ status = 999;
113
+ throw new Error(respData.message);
114
+ }
115
+ } catch (err) {
116
+ if (status === 500) {
117
+ throw new Error(
118
+ `Error occurred in authentication. Please regenerate using authenticate`
119
+ );
120
+ } else if (status === 999) {
121
+ throw new Error(err);
122
+ }
123
+ }
124
+ } else {
125
+ throw new Error(`Error occurred in authentication. Please regenerate using authenticate`);
126
+ }
127
+ } catch (err) {
128
+ // throw new Error(`Error occurred in authentication. Please regenerate using authenticate`);
129
+ throw Error(err);
130
+ }
131
+ }
132
+ };
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+ export default async (orgLibName, selectedVersion) => {
142
+ // console.log(orgLibName + ", " + selectedVersion);
143
+ const configDef = await getConfigDefaults();
144
+ let archiveBeforeStore = false;
145
+
146
+
147
+ const rulesetQuestions = await getPublishComponentQuestions();
148
+ const rulesetAnswers = await inquirer.prompt(rulesetQuestions);
149
+ const { rulesetName, rulesetVersion} = rulesetAnswers;
150
+
151
+ let content = {
152
+ libraryName : orgLibName,
153
+ version : selectedVersion,
154
+ rulesetName, rulesetVersion
155
+ };
156
+
157
+
158
+ if (orgLibName === configDef.currentOrgLib && selectedVersion === configDef.buildVersion) {
159
+
160
+ console.log("\nYou've selected the current working library/version.");
161
+ console.log("Export store or the current.");
162
+ const archAnswers = await inquirer.prompt([
163
+ {
164
+ name: 'currentOrStore',
165
+ type: 'rawlist',
166
+ message: 'Select current or store',
167
+ default: "Current",
168
+ choices: ["Current", "Store"]
169
+ },
170
+ ]);
171
+
172
+ const currentOrStore = archAnswers.currentOrStore;
173
+
174
+ if (currentOrStore === "Current") {
175
+ archiveBeforeStore = true;
176
+ }
177
+
178
+ if (archiveBeforeStore) {
179
+
180
+ // returns both the output promise and the buffer that can be sent to PegaInfinity
181
+ let zipBuffer = await zipVersionAndArchiveAndReturnBuffer(configDef.currentOrgLib, configDef.buildVersion);
182
+
183
+ zipBuffer.output.on('close', function() {
184
+ if (zipBuffer.zipContent != null) {
185
+ content = { ...content, zipContent: zipBuffer.zipContent};
186
+
187
+ try {
188
+ publishComponentLibraryArchiveToServer(content, true )
189
+ .then( () => {
190
+ console.log(chalk.green.bold(`Success: Published Archive ${content.libraryName}/${content.version} to server.`));
191
+ })
192
+ .catch( (err) => {
193
+ console.log(chalk.red.bold(err));
194
+ })
195
+ }
196
+ catch (err) {
197
+ console.log(chalk.bold.red(err.toString()));
198
+ }
199
+
200
+ }
201
+
202
+ });
203
+
204
+ return;
205
+
206
+ }
207
+ }
208
+ else {
209
+
210
+ // for now, to get a "buffer" from a zip file, need to unzip it in a /temp directory
211
+ // then re-zip. During the re-zip, create a buffer that can be passed to PegaInfinity
212
+
213
+ const mainDirectory = process.cwd();
214
+ const archiveFileName = `${orgLibName}_${selectedVersion}.arch.zip`;
215
+ const archiveDirectory = join (mainDirectory, ARCHIVES_PATH, `${orgLibName}`, `${selectedVersion}`);
216
+ if (fs.existsSync(archiveDirectory)) {
217
+ const archiveFile = join(archiveDirectory, archiveFileName);
218
+
219
+ // unzip to /temp, then re-zip and retrieve the buffer (remove /temp later)
220
+ let zipBuffer = await zipUnArchiveToTempAndReturnBuffer(orgLibName, selectedVersion);
221
+
222
+ zipBuffer.output.on('close', function() {
223
+
224
+ // get rid of temp directory, regardless
225
+ const tempDirectory = join (mainDirectory, TEMP_PATH);
226
+ if (fs.existsSync(tempDirectory)) {
227
+ fs.rmSync(tempDirectory, { recursive: true });
228
+ }
229
+
230
+ if (zipBuffer.zipContent != null) {
231
+
232
+ content = { ...content, zipContent: zipBuffer.zipContent};
233
+
234
+ try {
235
+ publishComponentLibraryArchiveToServer(content, true )
236
+ .then( () => {
237
+ console.log(chalk.green.bold(`Success: Published Archive ${content.libraryName}/${content.version} to server.`));
238
+ })
239
+ .catch( (err) => {
240
+ console.log(chalk.red.bold(err));
241
+ })
242
+ }
243
+ catch (err) {
244
+ console.log(chalk.bold.red(err.toString()));
245
+ }
246
+
247
+
248
+
249
+ }
250
+
251
+ });
252
+
253
+ }
254
+
255
+
256
+ }
257
+ };
@@ -11,6 +11,7 @@ import { lintComponent } from '../linter/index.js';
11
11
  import { constructCompleteUrl, getComponentDirectoryPath, getHttpsAgent, getPegaServerConfig, showVersion, getC11NB2STokenAndStaticServer, getLocalLibraryVersions, getLibraryBased, getLibraryBasedCL, deletePublishExtras, addDebugLog, checkLibraryAndArchives, checkJWTExpiration, getConfigDefaults } from '../../util.js';
12
12
 
13
13
  import { publishLib, listLibJSONResponse, deleteLibVersion } from '@pega/constellation-dx-components-build-utils/index.js';
14
+ import { default as buildLibrary } from '../build-lib/index.js';
14
15
 
15
16
  import { getLibraryVersionQuestion } from './helper.js';
16
17
 
@@ -192,18 +193,25 @@ export const publishComponentLibraryToServer = async (data, doFetch) => {
192
193
  }
193
194
 
194
195
  try {
195
- const respData = isLaunchpad ? await response.text() : await response.json();
196
- console.log(chalk.bold.green(`Success : ${isLaunchpad ? respData : respData.message}`));
196
+ // const respData = isLaunchpad ? await response.text() : await response.json();
197
+ const headerType = response.headers.get('content-type');
198
+ const respData = headerType.includes("json") ? await response.json() : await response.text();
199
+ let respMessage = headerType.includes("json") ? respData.message : respData;
200
+
197
201
 
198
202
  if (status === 500) {
199
203
  status = 999;
200
- throw new Error(respData.message);
204
+ if (respMessage === '') {
205
+ respMessage = `Server error, please check server logs for error.`;
206
+ }
207
+ throw new Error(respMessage);
201
208
  }
209
+
210
+ console.log(chalk.bold.green(`Success : ${respMessage }`));
211
+
202
212
  } catch (err) {
203
213
  if (status === 500) {
204
- throw new Error(
205
- `Error occurred in authentication. Please regenerate using authenticate`
206
- );
214
+ throw new Error(`Server error, please check server logs for error.`);
207
215
  } else if (status === 999) {
208
216
  throw new Error(err);
209
217
  }
@@ -417,62 +425,64 @@ addDebugLog("publishLibrary", "", "+");
417
425
  return;
418
426
  }
419
427
 
420
- if (okToPublish) {
421
-
422
- // /*
423
-
424
- let libVersionExists = await doesLibraryExist(libraryName, version);
425
- let overrideExisting = false;
426
- let checkDeleted = false;
427
428
 
428
- await deletePublishExtras(libraryName, version);
429
+ const isLibraryBasedCL = getLibraryBasedCL();
430
+ if (okToPublish) {
431
+ if (isLibraryBasedCL) {
432
+ // developer test
429
433
 
434
+ let content = { libraryName, version, rulesetName, rulesetVersion };
435
+ await publishUILibraryComponentToInfinity(content);
430
436
 
431
- if (libVersionExists) {
432
- console.log("\nLibrary " + chalk.bold.yellow(`${libraryName}/${version}`) + " already exists.");
433
- const questions = [
434
- {
435
- name: 'override',
436
- type: 'confirm',
437
- message: `Do you wish to overrite it`,
438
- default: false
439
- }
440
- ];
441
437
 
442
- await inquirer.prompt(questions).then(async answers => {
443
- overrideExisting = answers.override;
444
- });
445
438
  }
446
-
447
- if (libVersionExists) {
448
- if (overrideExisting) {
449
- console.log("\nDeleting existing library " + chalk.bold.yellow(`${libraryName}:${version}`) + " ...");
450
- addDebugLog("deleteLibVersion", `services call: libraryName: ${libraryName}, version: ${version}`, "");
451
- await deleteLibVersion(libraryName, version, tokenAndStaticServer.C11NB2S, tokenAndStaticServer.appStaticContentServer);
452
- addDebugLog("deleteLibVersion", "services end", "");
453
- checkDeleted = true;
454
- }
455
- else {
456
- // don't override, so end
457
- console.log(chalk.yellow(`You will need to increment your library version to publish`));
458
- addDebugLog("publishLibrary", "END", "-");
459
- return;
439
+ else {
440
+ let libVersionExists = await doesLibraryExist(libraryName, version);
441
+ let overrideExisting = false;
442
+ let checkDeleted = false;
443
+
444
+ await deletePublishExtras(libraryName, version);
445
+
446
+
447
+ if (libVersionExists) {
448
+ console.log("\nLibrary " + chalk.bold.yellow(`${libraryName}/${version}`) + " already exists.");
449
+ const questions = [
450
+ {
451
+ name: 'override',
452
+ type: 'confirm',
453
+ message: `Do you wish to overrite it`,
454
+ default: false
455
+ }
456
+ ];
457
+
458
+ await inquirer.prompt(questions).then(async answers => {
459
+ overrideExisting = answers.override;
460
+ });
460
461
  }
461
- }
462
462
 
463
- // need a timeout to give services time to delete the library
464
- // setTimeout( function(){ await publishNewLibraryAsync(libraryName, version, checkDeleted)}, 700 );
465
- await publishNewLibraryAsync(libraryName, version, checkDeleted);
466
- // */
463
+ if (libVersionExists) {
464
+ if (overrideExisting) {
465
+ console.log("\nDeleting existing library " + chalk.bold.yellow(`${libraryName}:${version}`) + " ...");
466
+ addDebugLog("deleteLibVersion", `services call: libraryName: ${libraryName}, version: ${version}`, "");
467
+ await deleteLibVersion(libraryName, version, tokenAndStaticServer.C11NB2S, tokenAndStaticServer.appStaticContentServer);
468
+ addDebugLog("deleteLibVersion", "services end", "");
469
+ checkDeleted = true;
470
+ }
471
+ else {
472
+ // don't override, so end
473
+ console.log(chalk.yellow(`You will need to increment your library version to publish`));
474
+ addDebugLog("publishLibrary", "END", "-");
475
+ return;
476
+ }
477
+ }
467
478
 
468
- // developer test
469
- const isLibraryBasedCL = getLibraryBasedCL();
470
- if (isLibraryBasedCL) {
471
- let content = { libraryName, version, rulesetName, rulesetVersion };
479
+ // need a timeout to give services time to delete the library
480
+ // setTimeout( function(){ await publishNewLibraryAsync(libraryName, version, checkDeleted)}, 700 );
481
+ await publishNewLibraryAsync(libraryName, version, checkDeleted);
472
482
 
473
- await publishUILibraryComponentToInfinity(content);
474
483
  }
475
484
 
485
+
476
486
  }
477
487
 
478
488
  }
package/src/util.js CHANGED
@@ -21,6 +21,7 @@ import {
21
21
  COMPONENTS_CONFIG_FILE_NAME,
22
22
  TASKS_CONFIG_JSON_FILENAME,
23
23
  PACKAGE_JSON_FILENAME,
24
+ PACKAGE_LOCK_JSON_FILENAME,
24
25
  TOKEN_PATH,
25
26
  OOTB_COMPONENT_SERVICE_REST_ENDPOINT,
26
27
  DELETE_COMPONENT_SERVICE_REST_ENDPOINT,
@@ -42,6 +43,7 @@ import {
42
43
  } from './constants.js';
43
44
 
44
45
 
46
+
45
47
  const access = promisify(fs.access);
46
48
 
47
49
  let showDebug = false;
@@ -288,19 +290,34 @@ export const applyPegaData = async (configJson) => {
288
290
  if (showDebug) addDebugLog("applyPegaData", "", "");
289
291
  const tokenAndStaticServer = await getC11NB2STokenAndStaticServer();
290
292
  const currentDirectory = process.cwd()
291
- const currentPackagePath = join(currentDirectory, PACKAGE_JSON_FILENAME);
292
- let currentPackageData;
293
+ // const currentPackagePath = join(currentDirectory, PACKAGE_JSON_FILENAME);
294
+ const currentPackageLockPath = join(currentDirectory, PACKAGE_LOCK_JSON_FILENAME);
295
+ // let currentPackageData;
296
+ let currentPackageLockData;
297
+
298
+ // try {
299
+ // currentPackageData = fs.readFileSync(currentPackagePath);
300
+ // }
301
+ // catch (ex) {
302
+ // console.log(chalk.red(`\nUnable to retrieve current package.json.`));
303
+ // process.exit(1);
304
+ // }
293
305
 
294
306
  try {
295
- currentPackageData = fs.readFileSync(currentPackagePath);
307
+ currentPackageLockData = fs.readFileSync(currentPackageLockPath);
296
308
  }
297
309
  catch (ex) {
298
- console.log($chalk.red(`\nUnable to retrieve current package.json.`))
310
+ console.log(chalk.red(`\nUnable to retrieve current package-lock.json.`));
299
311
  process.exit(1);
300
312
  }
301
313
 
302
- const cData = JSON.parse(currentPackageData);
303
- const cosmosVersion = cData.dependencies["@pega/cosmos-react-core"];
314
+ // const cData = JSON.parse(currentPackageData);
315
+ // const cosmosVersion = cData.dependencies["@pega/cosmos-react-core"];
316
+
317
+ const cData = JSON.parse(currentPackageLockData);
318
+ const cosmosReact = cData.packages["node_modules/@pega/cosmos-react-core"];
319
+ const cosmosVersion = cosmosReact.version;
320
+
304
321
  let infinityVersion = "";
305
322
 
306
323
  if (tokenAndStaticServer.C11NB2S === undefined) {
@@ -361,6 +378,20 @@ export const checkAccessTokenExpiration = async() => {
361
378
 
362
379
  }
363
380
 
381
+ export const getApplicationAndVersionFromToken = async() => {
382
+ const tokenAndStaticServer = await getC11NB2STokenAndStaticServer();
383
+
384
+ if (tokenAndStaticServer.access_token === undefined) {
385
+ console.log(chalk.redBright("Need to authenticate, missing token.\n"));
386
+ process.exit(1);
387
+ }
388
+
389
+ const jwt = jwtDecode(tokenAndStaticServer.access_token);
390
+ const { app_name, app_version } = jwt;
391
+ return { app_name, app_version };
392
+
393
+ }
394
+
364
395
  export const getLibraryBased = () => {
365
396
  if (showDebug) addDebugLog("getLibraryBased", "", "");
366
397
  // const currentDirectory = process.cwd();
@@ -1729,6 +1760,161 @@ if (showDebug) addDebugLog("zipVersionAndArchive", `orgLibName: ${orgLibName}, v
1729
1760
 
1730
1761
  };
1731
1762
 
1763
+ export const zipVersionAndArchiveAndReturnBuffer = async (orgLibName, version, currentDirectory = "") => {
1764
+ if (showDebug) addDebugLog("zipVersionAndArchive", `orgLibName: ${orgLibName}, version: ${version}`, "");
1765
+ // const srcDirectoryPath = await getSrcDirectoryPath();
1766
+ if (currentDirectory === "") {
1767
+ currentDirectory = process.cwd();
1768
+ }
1769
+ const srcDirectoryPath = join(currentDirectory, "src");
1770
+ const tasksConfig = join(currentDirectory, TASKS_CONFIG_JSON_FILENAME);
1771
+ const packageJson = join(currentDirectory, PACKAGE_JSON_FILENAME);
1772
+ const archiveFileName = `${orgLibName}_${version}.arch.zip`;
1773
+
1774
+
1775
+ // const configContent = Buffer.from(fs.readFileSync(configJson)).toString();
1776
+ const mainDirectory = process.cwd();
1777
+ const archiveDirectory = join (mainDirectory, ARCHIVES_PATH, `${orgLibName}`, `${version}`);
1778
+ if (!fs.existsSync(archiveDirectory)) {
1779
+ fs.mkdirSync(archiveDirectory, { recursive: true });
1780
+ }
1781
+
1782
+ // create componentsconfig.json
1783
+ await createComponentsConfigFile(archiveDirectory, join(srcDirectoryPath, "components"));
1784
+
1785
+ const archiveFile = join(archiveDirectory, archiveFileName);
1786
+ if (fs.existsSync(orgLibName)) {
1787
+
1788
+ }
1789
+
1790
+ const output = fs.createWriteStream(archiveFile);
1791
+ const archive = archiver('zip', {
1792
+ zlib: { level: 9 } // Sets the compression level.
1793
+ });
1794
+
1795
+ const zipChunks = [];
1796
+ archive.on('data', chunk => zipChunks.push(chunk));
1797
+
1798
+
1799
+ // Add src directory
1800
+ archive.directory(srcDirectoryPath, 'src');
1801
+
1802
+ // grab all files (not directories and archive)
1803
+ const configFiles = await getTopLevelConfigFiles(currentDirectory);
1804
+ if (configFiles && configFiles.length > 0) {
1805
+ for (const configF of configFiles) {
1806
+ if (configF !== "package-lock.json") {
1807
+ archive.file(
1808
+ join(currentDirectory, configF), { name: configF });
1809
+ }
1810
+
1811
+ }
1812
+ }
1813
+
1814
+ // pipe archive data to the file
1815
+ archive.pipe(output);
1816
+
1817
+ output.on('end', function() {
1818
+ console.log('Data has been drained');
1819
+ });
1820
+
1821
+
1822
+ // good practice to catch warnings (ie stat failures and other non-blocking errors)
1823
+ archive.on('warning', function(err) {
1824
+ if (err.code === 'ENOENT') {
1825
+ // log warning
1826
+ } else {
1827
+ // throw error
1828
+ throw err;
1829
+ }
1830
+ });
1831
+
1832
+ // good practice to catch this error explicitly
1833
+ archive.on('error', function(err) {
1834
+ throw err;
1835
+ });
1836
+
1837
+ await archive.finalize();
1838
+
1839
+ const zipBuffer = Buffer.concat(zipChunks);
1840
+ const zipContent = zipBuffer.toString('base64');
1841
+
1842
+ return { output, zipContent};
1843
+
1844
+ };
1845
+
1846
+ export const zipUnArchiveToTempAndReturnBuffer = async(orgLibName, version) => {
1847
+
1848
+ // unarchive to temp
1849
+ const currentDirectory = process.cwd();
1850
+ const tempDirectory = join (currentDirectory, TEMP_PATH);
1851
+ const srcDirectoryPath = join(tempDirectory, "src");
1852
+
1853
+ const archiveFileName = `${orgLibName}_${version}.arch.zip`;
1854
+ const archiveDirectory = join (currentDirectory, ARCHIVES_PATH, `${orgLibName}`, `${version}`);
1855
+ const archFileName = join(archiveDirectory, archiveFileName);
1856
+
1857
+ await unZipFromArchive(archFileName);
1858
+
1859
+ // archive is in temp directory
1860
+ const archiveFile = join(tempDirectory, archiveFileName);
1861
+
1862
+ const output = fs.createWriteStream(archiveFile);
1863
+ const archive = archiver('zip', {
1864
+ zlib: { level: 9 } // Sets the compression level.
1865
+ });
1866
+
1867
+ const zipChunks = [];
1868
+ archive.on('data', chunk => zipChunks.push(chunk));
1869
+
1870
+ // Add src directory
1871
+ archive.directory(srcDirectoryPath, 'src');
1872
+
1873
+ // grab all files (not directories and archive)
1874
+ const configFiles = await getTopLevelConfigFiles(tempDirectory);
1875
+ if (configFiles && configFiles.length > 0) {
1876
+ for (const configF of configFiles) {
1877
+ if (configF !== "package-lock.json") {
1878
+ archive.file(
1879
+ join(currentDirectory, configF), { name: configF });
1880
+ }
1881
+
1882
+ }
1883
+ }
1884
+
1885
+ // pipe archive data to the file
1886
+ archive.pipe(output);
1887
+
1888
+ output.on('end', function() {
1889
+ console.log('Data has been drained');
1890
+ });
1891
+
1892
+
1893
+ // good practice to catch warnings (ie stat failures and other non-blocking errors)
1894
+ archive.on('warning', function(err) {
1895
+ if (err.code === 'ENOENT') {
1896
+ // log warning
1897
+ } else {
1898
+ // throw error
1899
+ throw err;
1900
+ }
1901
+ });
1902
+
1903
+ // good practice to catch this error explicitly
1904
+ archive.on('error', function(err) {
1905
+ throw err;
1906
+ });
1907
+
1908
+ await archive.finalize();
1909
+
1910
+ const zipBuffer = Buffer.concat(zipChunks);
1911
+ const zipContent = zipBuffer.toString('base64');
1912
+
1913
+ return { output, zipContent};
1914
+
1915
+
1916
+ }
1917
+
1732
1918
  export const zipVersionAndArchiveCL = async (orgLibName, version, currentDirectory = "") => {
1733
1919
  if (showDebug) addDebugLog("zipVersionAndArchiveCL", `orgLibName: ${orgLibName}, version: ${version}, currentDirectory: ${currentDirectory}`, "");
1734
1920
  // const srcDirectoryPath = await getSrcDirectoryPath();