@pega/custom-dx-components 8.8.9 → 8.8.11

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.
Files changed (22) hide show
  1. package/package.json +2 -1
  2. package/src/auth.js +587 -553
  3. package/src/constants.js +18 -7
  4. package/src/tasks/authenticate/helper.js +76 -13
  5. package/src/tasks/authenticate/index.js +20 -2
  6. package/src/tasks/create/templates/Constellation/Field/Text-Phone/index.jsx.mustache +0 -1
  7. package/src/tasks/init/template/README.md +2 -204
  8. package/src/tasks/init/template/package.json.mustache +1 -1
  9. package/src/tasks/init/template/src/components/_components.md +1 -0
  10. package/src/tasks/init/template/tasks.config.json +11 -7
  11. package/src/tasks/publish/helper.js +71 -27
  12. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURL.stories.tsx +0 -19
  13. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURL.styles.ts +0 -5
  14. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURL.types.ts +0 -10
  15. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURLDisplay.tsx +0 -25
  16. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURLInput.tsx +0 -24
  17. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/config.json +0 -13
  18. package/src/tasks/init/template/src/components/Organization_Library_MediaURL/index.ts +0 -2
  19. package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/config.json +0 -44
  20. package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/demo.stories.jsx +0 -40
  21. package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/index.jsx +0 -42
  22. package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/styles.js +0 -5
package/src/constants.js CHANGED
@@ -2,7 +2,7 @@
2
2
  export const TASKS_CONFIG_JSON_FILENAME = 'tasks.config.json';
3
3
  export const BUILD_CONFIG_JSON_FILENAME = 'build.config.json';
4
4
  export const COMPONENTS_DIRECTORY_PATH = 'components-directory-path';
5
- export const COMPONENTS_PATH = 'component'
5
+ export const COMPONENTS_PATH = 'component';
6
6
  export const TOKEN_PATH = 'node_modules/@pega/custom-dx-components/.access_token';
7
7
  export const OOTB_COMPONENTS = 'node_modules/@pega/custom-dx-components/.ootb_components';
8
8
 
@@ -15,18 +15,29 @@ export const INF_TOKEN_URL_V1 = 'PRRestService/oauth2/v1/token';
15
15
  export const INF_AUTHORIZE_URL_V1 = 'PRRestService/oauth2/v1/authorize';
16
16
  export const LP_TOKEN_URL = 'uas/oauth/token';
17
17
  export const LP_AUTHORIZE_URL = 'uas/oauth/authorize';
18
- export const LP_LIST_COMPONENT_SERVICE_REST_ENDPOINT = 'pegalaunchpad/c11n/v103/app/appstudiox/componentslist';
19
-
18
+ export const LP_LIST_COMPONENT_SERVICE_REST_ENDPOINT =
19
+ 'pegalaunchpad/c11n/v103/app/appstudiox/componentslist';
20
+ export const LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT =
21
+ 'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
20
22
 
21
23
  export const FIELD_PATH = '/field';
22
24
  export const TEMPLATE_PATH = '/template';
23
25
  export const WIDGET_PATH = '/widget';
24
26
 
25
- export const COMPONENT_PREFIX_FIELD_PATH = "field/";
26
- export const COMPONENT_PREFIX_TEMPLATE_PATH = "template/";
27
- export const COMPONENT_PREFIX_WIDGET_PATH = "widget/";
27
+ export const COMPONENT_PREFIX_FIELD_PATH = 'field/';
28
+ export const COMPONENT_PREFIX_TEMPLATE_PATH = 'template/';
29
+ export const COMPONENT_PREFIX_WIDGET_PATH = 'widget/';
30
+
31
+ export const CATEGORY_CONSTELLATION = 'constellation';
28
32
 
29
- export const CATEGORY_CONSTELLATION = "constellation";
33
+ export const AUTHENTICATE_DEFAULTS = {
34
+ serverType: 'infinity',
35
+ server: 'https://localhost:1080/prweb',
36
+ clientId: '10095186356008396159',
37
+ grantType: 'authCode',
38
+ authService: 'pega',
39
+ redirectUri: 'https://localhost:4010/'
40
+ };
30
41
 
31
42
  export const AUTHENTICATE_SCHEMA = {
32
43
  serverType: [
@@ -1,30 +1,47 @@
1
1
  /* eslint-disable import/prefer-default-export */
2
2
  import { getPegaServerConfig } from '../../util.js';
3
3
 
4
- import { AUTHENTICATE_SCHEMA } from '../../constants.js';
4
+ import { AUTHENTICATE_SCHEMA, AUTHENTICATE_DEFAULTS } from '../../constants.js';
5
5
 
6
6
  export const getAuthQuestions = async (dxcbConfig) => {
7
7
  const defaultPegaConfig = dxcbConfig;
8
- const aMustAsk = dxcbConfig['questions_askAlways'] ? dxcbConfig['questions_askAlways'].split(',') : [];
8
+ const aAlwaysAsk = dxcbConfig['questions_askAlways'] ? dxcbConfig['questions_askAlways'].split(',') : [];
9
9
  const aNeverAsk = dxcbConfig['questions_askNever'] ? dxcbConfig['questions_askNever'].split(',') : [];
10
+ const aAskOnce = dxcbConfig['questions_askOnce'] ? dxcbConfig['questions_askOnce'].split(',') : [];
11
+ const aAskedOnce = dxcbConfig['questions_askedOnce'] ? dxcbConfig['questions_askedOnce'].split(',') : [];
12
+
13
+ // Ask if various must, never, once criteria are met
14
+ const askThisTime = (prop) => {
15
+ const bAsk = aAlwaysAsk.includes(prop) ||
16
+ (!aNeverAsk.includes(prop) && (aAskOnce.includes(prop) && !aAskedOnce.includes(prop)));
17
+ return bAsk;
18
+ };
19
+
20
+ const initAnswer = (prop, answers, defValue) => {
21
+ return askThisTime(prop, answers) ? undefined : (defaultPegaConfig[prop] ? defaultPegaConfig[prop] : defValue);
22
+ };
10
23
 
11
24
  const initAnswers = (answers) => {
12
25
  // Setup default answers (if they are present and non-empty)
13
- answers.serverType = defaultPegaConfig.serverType || "infinity";
14
- answers.server = defaultPegaConfig.server || undefined;
15
- answers.isolationId = defaultPegaConfig.isolationId || undefined;
16
- answers.clientId = defaultPegaConfig.clientId || undefined;
17
- answers.grantType = defaultPegaConfig.grantType || "authCode";
18
- answers.clientSecret = defaultPegaConfig.clientSecret || undefined;
19
- answers.user = defaultPegaConfig.user || undefined;
20
- answers.password = defaultPegaConfig.password || undefined;
26
+ answers.serverType = initAnswer('serverType', answers, AUTHENTICATE_DEFAULTS.serverType);
27
+ answers.server = initAnswer('server', answers, AUTHENTICATE_DEFAULTS.server);
28
+ answers.isolationId = initAnswer('isolationId', answers);
29
+ answers.clientId = initAnswer('clientId', answers, AUTHENTICATE_DEFAULTS.clientId);
30
+ answers.grantType = initAnswer('grantType', answers, AUTHENTICATE_DEFAULTS.grantType);
31
+ answers.authService = initAnswer('authService', answers, AUTHENTICATE_DEFAULTS.authService);
32
+ answers.redirectUri = initAnswer('redirectUri', AUTHENTICATE_DEFAULTS.redirectUri);
33
+ answers.clientSecret = initAnswer('clientSecret', answers);
34
+ answers.user = initAnswer('user', answers);
35
+ answers.password = initAnswer('password', answers);
36
+ answers.aAsked = [];
21
37
  };
22
38
 
23
39
  const fnStandardWhen = (prop, answers) => {
24
- if (aNeverAsk.includes(prop)) {
25
- return false;
40
+ const ask = askThisTime(prop) || !answers[prop];
41
+ if (ask) {
42
+ answers.aAsked.push(prop);
26
43
  }
27
- return aMustAsk.includes(prop) || !answers[prop];
44
+ return ask;
28
45
  };
29
46
 
30
47
  return [
@@ -49,16 +66,30 @@ export const getAuthQuestions = async (dxcbConfig) => {
49
66
  },
50
67
  {
51
68
  name: 'server',
69
+ type: 'input',
52
70
  message: 'Enter pega server url',
53
71
  default: defaultPegaConfig.server,
72
+ validate: value => {
73
+ if (value.trim()) {
74
+ return true;
75
+ }
76
+ return 'Pega server cannot be empty';
77
+ },
54
78
  when: answers => {
55
79
  return fnStandardWhen('server', answers);
56
80
  }
57
81
  },
58
82
  {
59
83
  name: 'isolationId',
84
+ tpye: 'input',
60
85
  message: 'Enter isolation id',
61
86
  default: defaultPegaConfig.isolationId,
87
+ validate: value => {
88
+ if (value.trim()) {
89
+ return true;
90
+ }
91
+ return 'Launchpad isolationId cannot be empty';
92
+ },
62
93
  when: answers => {
63
94
  return answers.serverType === "launchpad" && fnStandardWhen('isolationId', answers);
64
95
  }
@@ -81,8 +112,39 @@ export const getAuthQuestions = async (dxcbConfig) => {
81
112
  return fnStandardWhen('grantType', answers);
82
113
  }
83
114
  },
115
+ {
116
+ name: 'authService',
117
+ type: 'input',
118
+ message: 'Enter authentication service alias',
119
+ default: defaultPegaConfig.authService,
120
+ validate: value => {
121
+ if (value.trim()) {
122
+ return true;
123
+ }
124
+ return 'Authentication service alias cannot be empty';
125
+ },
126
+ when: answers => {
127
+ return answers.serverType === "infinity" && answers.grantType === "authCode" && fnStandardWhen('authService', answers);
128
+ }
129
+ },
130
+ {
131
+ name: 'redirectUri',
132
+ type: 'input',
133
+ message: 'Enter valid redirect Uri within OAuth 2.0 client reg reccord',
134
+ default: defaultPegaConfig.redirectUri,
135
+ validate: value => {
136
+ if (value.trim()) {
137
+ return true;
138
+ }
139
+ return 'Redirect URI cannot be empty';
140
+ },
141
+ when: answers => {
142
+ return answers.serverType === "infinity" && answers.grantType === "authCode" && fnStandardWhen('redirectUri', answers);
143
+ }
144
+ },
84
145
  {
85
146
  name: 'user',
147
+ type: 'input',
86
148
  message: 'Enter user id',
87
149
  default: defaultPegaConfig.user,
88
150
  validate: (value, answers) => {
@@ -112,6 +174,7 @@ export const getAuthQuestions = async (dxcbConfig) => {
112
174
  },
113
175
  {
114
176
  name: 'clientId',
177
+ type: 'input',
115
178
  message: 'Enter clientId',
116
179
  default: defaultPegaConfig.clientId,
117
180
  validate: value => {
@@ -144,8 +144,9 @@ export default async options => {
144
144
  const questions = await getAuthQuestions(serverConfig);
145
145
  // console.log(`questions: ${JSON.stringify(questions)}`);
146
146
  const answers = await inquirer.prompt(questions);
147
- const aProps = ['serverType', 'server', 'isolationId', 'clientId', 'grantType', 'clientSecret', 'user', 'password'];
148
- serverConfig.authService = serverConfig.authService || 'pega';
147
+ const aAsked = answers.aAsked;
148
+ delete answers.aAsked;
149
+ const aProps = ['serverType', 'server', 'isolationId', 'clientId', 'grantType', 'authService', 'redirectUri', 'clientSecret', 'user', 'password'];
149
150
  const isLaunchPad = answers.serverType === "launchpad";
150
151
  let bWriteUpdate = false;
151
152
  for (let i = 0; i < aProps.length; i += 1) {
@@ -161,6 +162,23 @@ export default async options => {
161
162
  }
162
163
  }
163
164
  }
165
+ // Update the askedOnce array based on askOnce criteria
166
+ const aAskOnce = serverConfig['questions_askOnce'] ? serverConfig['questions_askOnce'].split(',') : [];
167
+ const aAskedOnce = serverConfig['questions_askedOnce'] ? serverConfig['questions_askedOnce'].split(',') : [];
168
+ let bAskedOnceUpdated = false;
169
+ for (let j = 0; j < aAsked.length; j += 1) {
170
+ const prop = aAsked[j];
171
+ if (aAskOnce.includes(prop) && !aAskedOnce.includes(prop)) {
172
+ // Add entries we want to only ask once to the asked list if appropriate
173
+ aAskedOnce.push(prop);
174
+ bAskedOnceUpdated = true;
175
+ }
176
+ }
177
+ // If askedOnce array was updated we need to update value in config
178
+ if (bAskedOnceUpdated) {
179
+ serverConfig['questions_askedOnce'] = aAskedOnce.join(',');
180
+ bWriteUpdate = true;
181
+ }
164
182
 
165
183
  try {
166
184
  // console.log(`serverConfig: ${JSON.stringify(serverConfig)}`);
@@ -14,7 +14,6 @@ import handleEvent from "./event-utils";
14
14
  import { suggestionsHandler } from './suggestions-handler';
15
15
 
16
16
  import Styled{{COMPONENT_CLASS_NAME}}Wrapper from './styles';
17
- import { } from "@pega/cosmos-react-core";
18
17
 
19
18
  export const formatExists = (formatterVal) => {
20
19
  const formatterValues = [
@@ -16,208 +16,6 @@ Ensure you have access to the following in your system:
16
16
 
17
17
  - System npm version 8
18
18
 
19
- ## Initialize a project
19
+ ## Latest Documentation
20
20
 
21
- Initialize the project by performing the following procedure in a terminal:
22
-
23
- 1. Enter the following command to initialize the project.
24
-
25
- Pega 8.7 - `npx @pega/custom-dx-components@1 init`
26
-
27
- Pega 8.8 - `npx @pega/custom-dx-components@2 init`
28
-
29
- 2. If prompted, enter `y` to install the Custom UI Components package.
30
- You will then be asked to set up the project by entering the required details.
31
-
32
- 3. Enter the following details:
33
- - Name of the project (required)
34
- Example - `mycustomcomponents`
35
- - Name of the organization (required)
36
- Example - `customorg`
37
- - Version (required)
38
- Example - `1.0.0`
39
- - Description of the project (optional)
40
- Example - `This project is intended to create and publish a custom component.`
41
- - Git repository URL (optional)
42
- Example - `https://git.custom-components.io/custom-cc.git`
43
- - Author (optional)
44
- Example - `Michelle`
45
-
46
- The workspace is now set up to create custom components and publish them to the server.
47
-
48
- ## Create custom components
49
-
50
- Create custom components using the following procedure:
51
-
52
- 1. Enter the following command to create a component:
53
- `npm run create`
54
- You will then be asked to enter or review the following details of the component:
55
- - Name of the component (required)
56
- Example - `customcomp0`
57
- - Name of component label (required)
58
- Example - `custom component`
59
- - Name of the library (required)
60
- Example - `basic`
61
- - Component version (required)
62
- Example - `0.0.1`
63
- - Type of component (required)
64
- Example - `Field`
65
- - Sub-type of component (required)
66
- Example - `Text`
67
- - Description of the component (optional)
68
- Example - `This is a customized searchbox that filters data.`
69
- The component is created in the following path: _/Users/your_user_name/project_name/src/components/component_name_
70
- You can also pre-configure the values for the above options in a tasks.config.json file as shown below.
71
-
72
- ```json
73
- {
74
- "component": {
75
- "library": "basic",
76
- "version": "0.0.1",
77
- "type": "field",
78
- "subtype": "text",
79
- "description": "basic field for capturing textual data",
80
- "icon": "basic-field-text.svg"
81
- }
82
- }
83
- ```
84
- >**Note**:
85
- Alternatively, you can enter the following command to skip entering the details of the component now and can manually enter the details in the config.json file after the component is created:
86
- `npm run create <enter_component_name>`
87
-
88
- A _src/components_ folder is created and the necessary files required to build the component are initialized as seen below.
89
-
90
- ```sh
91
- ├── src
92
- ├── components
93
- ├── <component_name>
94
- ├── index.js
95
- ├── demo.stories.js
96
- ├── config.json
97
- ```
98
-
99
-
100
- The *index.js* file contains the actual component rendering logic.
101
- The *demo.stories.js* file contains the demo that can be viewed in the storybook.
102
- The *config.json* file contains the mapping of properties for configuring the auto generated property panel. This property panel appears in AppStudio when an application is being authored to use the custom component.
103
-
104
-
105
- 2. Enter the following command to start the storybook to view the demo.
106
- `npm start`
107
-
108
- 3. Modify the source files to build your own component. You can also install and import third-party libraries if required for your component.
109
-
110
- The custom component is now created. We use the information provided to create uniquely namespaced components in this convention - `<organization>_<library>_<component name>`.
111
-
112
- 4. local build, you can build the component locally to check for config validation and component validation. Enter
113
- `npm buildComponent`
114
-
115
- buildComponent will do the same first 2 steps as publish, but will not publish to the server. This allows you to compile your component locally and fix errors before publish.
116
-
117
- ## Authenticate the user
118
-
119
- Before we publish the custom component to the Pega Infinity Server, authenticate the user to access the resources in the Pega Infinity Server.
120
-
121
- >**Note**:
122
- It is required that you configure a value for clientId, clientSecret, and accessTokenUri.
123
- 1. Login to Pega Infinity Server, navigate to Records / Security / OAuth 2.0 Client Registration landing page and open the *DX-CustomComponents* record.
124
- 2. Click **Regenerate Client Secret**, download the Client Credentials (as the Client ID, Client Secret, and Access token endpoint will be needed), and save the record.
125
- 3. Update the the task.config.json file with these downloaded values:
126
- ```json
127
- "server-config": {
128
- "server": "https://127.0.0.1:8080/prweb",
129
- "user": "customcomponentoperator",
130
- "password": "pwd",
131
- "clientId": "<mention client ID here>",
132
- "clientSecret": "<mention client secret here>",
133
- "accessTokenUri": "https://127.0.0.1:8080/prweb/PRRestService/oauth2/v1/token"
134
- },
135
- ```
136
- 4. Enter the following command to initiate authentication.
137
- `npm run authenticate`
138
-
139
- The user is now authenticated and can proceed to either publish or list the components.
140
-
141
- ## Publish custom components
142
- Enter the following command to publish custom components to Pega Infinity Server:
143
- `npm run publish`
144
- `npm run publishAll`
145
- Publish the finalized custom components changes to Pega Infinity Server so that it can be discoverable in authoring (design palette).
146
- You will then be asked to enter the following details:
147
-
148
- - The component to be published to Pega Infinity Server. It will be updated if the component exists.
149
- - If publishAll, then you won't get a list
150
- - The name of the ruleset where the component must be published.
151
- - The version of the ruleset where the component must be published.
152
- - Specify if the development build should be generated for debugging.
153
-
154
- - If publishAll, will sequentiall go through the list of local components and publish them
155
- You can also pre-configure the values for the above options in a tasks.config.json file as shown below. The server, user name, and password must be pre-configured.
156
-
157
- ```json
158
- {
159
- "components-server-config": {
160
- "server": "http://127.0.0.1:8080/prweb",
161
- "user": "customcomponentoperator",
162
- "password": "pwd"
163
- "rulesetName": "TestPega-C11nGall",
164
- "rulesetVersion": "01-01-03",
165
- "sourceOfComponents": "Server",
166
- "devBuild": false,
167
- }
168
- }
169
- ```
170
- When the component is successfully published, you can use the newly published component in App Studio's view authoring.
171
-
172
- > **Note**:
173
- > The Rule-UI-Component instance (with component name) is created on the Pega Infinity Server after publishing the component.
174
-
175
- ## List custom components
176
-
177
- View the available components in the local machine or the server.
178
-
179
- Enter the following command to list custom components:
180
- `npm run list`
181
-
182
- You will then be asked to enter the following details:
183
-
184
- - List components from Server or Local?
185
- Example - `Server`
186
-
187
- The custom components will now be listed in the terminal.
188
-
189
- ## Delete custom components
190
-
191
- Delete the available or published components in the local machine or the server.
192
-
193
- Enter the following command to delete custom components:
194
- `npm run delete`
195
- `npm run deleteAll`
196
-
197
- You will then be asked to enter the following details:
198
-
199
- - Delete components from Server or Local?
200
- Example - `Local`
201
-
202
- - Select component to delete
203
- The list of available components in the following path will be displayed: \_/Users/your_user_name/project_name/src/components
204
- Select the component to be deleted from this list.
205
- - For deleteAll you will see the full list and asked if you want to delete them all.
206
-
207
- - Are you sure?
208
- Example - `yes`
209
-
210
- > **Note**:
211
- > If you choose to delete components from the server, the successfully published components along with their ruleset name and ruleset version from the Pega Infinity Server will be displayed. Select the component to be deleted from this list.
212
-
213
- ## View existing custom components in storybook
214
-
215
- View custom components in a storybook by performing the following procedure:
216
-
217
- 1. Enter the following command to open the project.
218
- `cd <enter your project's name>`
219
-
220
- 2. Enter the following command to start the storybook in development mode.
221
- `npm start`
222
-
223
- The storybook is launched in a browser where you can view the components working in isolation.
21
+ Find the latest documentation on using **DX Component Builder** [here](https://docs.pega.com/bundle/constellation-dx-components-88/page/constellation-dx-components/custom-components/lifecycle-dx-cosmos-components.html)
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "devDependencies": {
58
58
  "@pega/configs": "^0.5.3",
59
- "@pega/custom-dx-components": "^8.8.9",
59
+ "@pega/custom-dx-components": "^8.8.11",
60
60
  "@pega/eslint-config": "^0.3.2",
61
61
  "@storybook/addon-actions": "^6.5.12",
62
62
  "@storybook/addon-essentials": "^6.5.12",
@@ -0,0 +1 @@
1
+ # directory for components #
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "components-directory-path": "src/components",
3
3
  "server-config": {
4
- "rulesetName": "rulesetName",
5
- "rulesetVersion": "rulesetVersion",
4
+ "rulesetName": "CustomDXComponents",
5
+ "rulesetVersion": "01-01-01",
6
6
  "sourceOfComponents": "Server",
7
7
  "devBuild": false,
8
8
  "serverType": "infinity",
9
- "server": "https://localhost:38764/prweb",
9
+ "server": "https://localhost:1080/prweb",
10
10
  "clientId": "10095186356008396159",
11
11
  "clientSecret_comment": "Needed only when using 'passwordCreds' or 'clientCreds' grantType",
12
12
  "clientSecret": "",
13
13
  "grantType": "authCode",
14
14
  "redirectUri": "https://localhost:4010/",
15
+ "authService_comment": "Infinity authentication service alias (when grantType is set to 'authCode')",
16
+ "authService": "pega",
15
17
  "cert_and_key_comment": "Path to SSL certificate file and SSL key file to use when starting local HTTPS server",
16
18
  "cert_and_key_comment2": "Needed only when using 'authCode' grantType and redirectUri begins with 'https://localhost'",
17
19
  "cert": "./keys/dxcb.crt",
@@ -19,14 +21,16 @@
19
21
  "user_and_password_comment": "useful primarily when grantType is set to 'passwordCreds'",
20
22
  "user": "",
21
23
  "password": "",
22
- "questions_comment": "useful for designating certain questions should always or never be asked during npm run authenticate",
24
+ "questions_comment": "useful for designating how frequently questions should be asked during npm run authenticate",
23
25
  "questions_askAlways": "",
24
- "questions_askNever": ""
26
+ "questions_askNever": "",
27
+ "questions_askOnce": "server,authService",
28
+ "questions_askedOnce": ""
25
29
  },
26
30
  "component": {
27
- "library": "",
31
+ "library": "Extensions",
28
32
  "type": "",
29
- "version": "",
33
+ "version": "1.0.0",
30
34
  "subtype": "",
31
35
  "description": "",
32
36
  "icon": ""
@@ -13,7 +13,11 @@ import {
13
13
  getPegaServerConfig,
14
14
  validateRulesetVersion
15
15
  } from '../../util.js';
16
- import { PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT, TOKEN_PATH } from '../../constants.js';
16
+ import {
17
+ PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT,
18
+ LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT,
19
+ TOKEN_PATH
20
+ } from '../../constants.js';
17
21
 
18
22
  export const getPublishComponentQuestions = async () => {
19
23
  const components = await getComponents();
@@ -35,6 +39,9 @@ export const getPublishComponentQuestions = async () => {
35
39
  return true;
36
40
  }
37
41
  return 'Ruleset name cannot be empty';
42
+ },
43
+ when: answers => {
44
+ return answers.serverType === 'infinity';
38
45
  }
39
46
  },
40
47
  {
@@ -46,12 +53,16 @@ export const getPublishComponentQuestions = async () => {
46
53
  return true;
47
54
  }
48
55
  return 'Please provide compatible version e.g 01-01-01';
56
+ },
57
+ when: answers => {
58
+ return answers.serverType === 'infinity';
49
59
  }
50
60
  },
51
61
  {
52
62
  name: 'sourceMap',
53
63
  message: 'Generate source map ?',
54
64
  default: defaultPegaConfig.sourceMap,
65
+ // eslint-disable-next-line sonarjs/no-redundant-boolean
55
66
  when: () => false && !process.env.SOURCE_MAP
56
67
  },
57
68
  {
@@ -86,37 +97,65 @@ export const zipComponent = async componentKey => {
86
97
  };
87
98
 
88
99
  export const publishComponentToServer = async data => {
89
- const { configContent, zipContent, componentKey, rulesetName, rulesetVersion } = data;
90
-
91
- const apiBody = {
92
- configContent,
93
- zipContent,
94
- componentKey: JSON.parse(configContent).componentKey,
95
- publishFor: 'constellation',
96
- rulesetName,
97
- rulesetVersion,
98
- category: ''
99
- };
100
+ const { configContent, zipContent, rulesetName, rulesetVersion } = data;
101
+
102
+ const defaultPegaServerConfig = await getPegaServerConfig();
103
+ const { serverType, isolationId } = defaultPegaServerConfig;
104
+ const isLaunchpad = serverType === 'launchpad';
105
+ const launchpadRestEndpoint = LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT.replace(
106
+ '{isolationId}',
107
+ isolationId
108
+ );
109
+ let apiBody;
110
+
111
+ if (isLaunchpad) {
112
+ apiBody = {
113
+ type: 'CustomComponent',
114
+ zipContent,
115
+ componentName: JSON.parse(configContent).componentKey,
116
+ pxUpdateDateTime: '',
117
+ environmentID: defaultPegaServerConfig.isolationId
118
+ };
119
+ } else {
120
+ apiBody = {
121
+ configContent,
122
+ zipContent,
123
+ componentKey: JSON.parse(configContent).componentKey,
124
+ publishFor: 'constellation',
125
+ rulesetName,
126
+ rulesetVersion,
127
+ category: ''
128
+ };
129
+ }
130
+
100
131
  const defaultPegaConfig = await getPegaServerConfig();
101
132
  const url = constructCompleteUrl(
102
133
  defaultPegaConfig.server,
103
- PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT
134
+ isLaunchpad ? launchpadRestEndpoint : PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT
104
135
  );
136
+
105
137
  try {
106
138
  const OauthData = fs.readFileSync(TOKEN_PATH, 'utf8');
107
139
  if (OauthData) {
108
140
  const {
109
141
  access_token: accessToken,
110
- token_type: tokenType,
111
- refresh_token: refreshToken
142
+ token_type: tokenType
143
+ // refresh_token: refreshToken
112
144
  } = JSON.parse(OauthData);
113
145
  let status = 500;
146
+ const headers = {};
147
+
148
+ if (isLaunchpad) {
149
+ headers.cookie = `Pega-AAT=${accessToken}`;
150
+ headers['Content-Type'] = 'application/json';
151
+ } else {
152
+ headers.Authorization = `${tokenType} ${accessToken}`;
153
+ }
154
+
114
155
  fetch(url, {
115
156
  method: 'POST',
116
157
  agent: new https.Agent({ rejectUnauthorized: false }),
117
- headers: {
118
- Authorization: `${tokenType} ${accessToken}`
119
- },
158
+ headers,
120
159
  body: JSON.stringify(apiBody)
121
160
  })
122
161
  .then(response => {
@@ -124,27 +163,32 @@ export const publishComponentToServer = async data => {
124
163
  return response.text();
125
164
  })
126
165
  .then(resp => {
127
- const respData = JSON.parse(resp);
166
+ const respData = isLaunchpad ? resp : JSON.parse(resp);
128
167
  if (status === 401) {
129
168
  throw new Error(
130
169
  'Error occurred in authentication. Please regenerate using authenticate'
131
170
  );
132
171
  // console.log(accessTokenUri, refreshToken);
133
172
  /* TODO - Handle refresh_token */
134
- } else if (status == 200) {
135
- console.log(chalk.bold.green(`Success : ${respData.message}`));
173
+ } else if (status === 200 || status === 201) {
174
+ console.log(chalk.bold.green(`Success : ${isLaunchpad ? respData : respData.message}`));
136
175
  } else {
137
176
  throw new Error(`${respData.message}`);
138
177
  }
139
178
  })
140
- .catch( e => {
141
- if (e.code == 'ECONNREFUSED') {
142
- Promise.reject(`${chalk.bold.red('Error occurred in authentication. Please regenerate using authenticate')}`);
143
- }
144
- else {
179
+ .catch(e => {
180
+ if (e.code === 'ECONNREFUSED') {
181
+ // eslint-disable-next-line prefer-promise-reject-errors
182
+ Promise.reject(
183
+ `${chalk.bold.red(
184
+ 'Error occurred in authentication. Please regenerate using authenticate'
185
+ )}`
186
+ );
187
+ } else {
188
+ // eslint-disable-next-line prefer-promise-reject-errors
145
189
  Promise.reject(`${chalk.bold.red(e)}`);
146
190
  }
147
- })
191
+ });
148
192
  } else {
149
193
  throw new Error(`Error occurred in authentication. Please regenerate using authenticate`);
150
194
  }