@pega/custom-dx-components 0.23.1 → 0.23.3
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 +2 -1
- package/src/constants.js +3 -0
- package/src/tasks/create/templates/Constellation/Field/Boolean/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Date/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/DateTime/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Decimal/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Decimal-Currency/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Decimal-Percentage/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Integer/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Picklist/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Text/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Text-Email/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Text-Input/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Text-Paragraph/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Text-Phone/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/Text-URL/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Field/TimeOfDay/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Template/DETAILS/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Template/DETAILS-region/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Template/FORM/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Template/FORM-region/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Template/PAGE/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Widget/CASE/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Widget/PAGE/config.json.mustache +1 -0
- package/src/tasks/create/templates/Constellation/Widget/PAGE-CASE/config.json.mustache +1 -0
- package/src/tasks/generate-ai/aiPrompt.txt.mustache +13 -111
- package/src/tasks/generate-ai/aiPromptDavinci.txt.mustache +14 -0
- package/src/tasks/generate-ai/helper.js +310 -104
- package/src/tasks/generate-ai/index.js +5 -4
- package/src/tasks/init/template/package.json.mustache +1 -1
- package/src/tasks/init/template/src/components/_components.md +1 -0
- package/src/util.js +125 -0
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURL.stories.tsx +0 -19
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURL.styles.ts +0 -5
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURL.types.ts +0 -10
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURLDisplay.tsx +0 -25
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/MediaURLInput.tsx +0 -24
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/config.json +0 -13
- package/src/tasks/init/template/src/components/Organization_Library_MediaURL/index.ts +0 -2
- package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/config.json +0 -44
- package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/demo.stories.jsx +0 -40
- package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/index.jsx +0 -42
- package/src/tasks/init/template/src/components/Organization_Library_VideoPlayer/styles.js +0 -5
|
@@ -1,184 +1,390 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import ora from 'ora';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { URL, fileURLToPath } from 'url';
|
|
6
|
-
import { join } from 'path';
|
|
7
1
|
import fs from 'fs';
|
|
2
|
+
import {sep, join} from 'path';
|
|
3
|
+
import { URL, fileURLToPath } from 'url';
|
|
8
4
|
|
|
9
|
-
import
|
|
10
|
-
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import inquirer from 'inquirer';
|
|
11
7
|
import _ from 'lodash';
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
import {
|
|
10
|
+
AI_PROMPT_FILENAME,
|
|
11
|
+
AI_DAVINCI_PROMPT_FILENAME
|
|
12
|
+
} from '../../constants.js';
|
|
14
13
|
import {
|
|
15
14
|
getComponents,
|
|
16
|
-
|
|
17
|
-
getAIPromptData,
|
|
15
|
+
getComponentsOfType,
|
|
18
16
|
getDirectoryFiles,
|
|
19
|
-
|
|
17
|
+
getInfinityAIComponent,
|
|
20
18
|
getComponentDirectoryPath,
|
|
21
19
|
compileMustacheTemplate,
|
|
22
|
-
getComponentConfigJson
|
|
20
|
+
getComponentConfigJson,
|
|
21
|
+
getComponentConfigType
|
|
23
22
|
} from '../../util.js';
|
|
24
|
-
import { str } from 'ajv';
|
|
25
23
|
|
|
24
|
+
export const renameFile = (oldFileName, newFileName) => {
|
|
25
|
+
try {
|
|
26
|
+
fs.renameSync(oldFileName, newFileName);
|
|
26
27
|
|
|
28
|
+
} catch(err) {
|
|
29
|
+
console.log(err)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
27
32
|
|
|
33
|
+
export const generateAIComponent = async (componentKey, designSystemComponents, additionalPromptInfo) => {
|
|
28
34
|
|
|
35
|
+
const fileName = "." + sep + AI_PROMPT_FILENAME;
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
// get config file
|
|
38
|
+
//
|
|
39
|
+
const targetDirectory = await getComponentDirectoryPath(componentKey);
|
|
40
|
+
const configFileData = await getComponentConfigJson(targetDirectory);
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
// let data = JSON.parse(configFileData);
|
|
43
|
+
// data.properties = [];
|
|
44
|
+
// configFileData = JSON.stringify(data);
|
|
34
45
|
|
|
35
|
-
if (localComponents.length > 0) {
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
let strPrompt = compileMustacheTemplate(fileURLToPath(new URL(fileName, import.meta.url)), {
|
|
48
|
+
COMPONENT_CONFIG: configFileData,
|
|
49
|
+
COMPONENT_DSC: designSystemComponents,
|
|
50
|
+
COMPONENT_ADDITIONAL: additionalPromptInfo
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
strPrompt = strPrompt.replaceAll("$", "//$");
|
|
54
|
+
|
|
55
|
+
strPrompt = _.unescape(strPrompt);
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
let aiComponent = await getInfinityAIComponent(strPrompt);
|
|
59
|
+
|
|
60
|
+
if (aiComponent) {
|
|
61
|
+
const indexFile = join(targetDirectory, "index.jsx");
|
|
62
|
+
|
|
63
|
+
// remove enclosed ``` and "Answer:"
|
|
64
|
+
aiComponent = aiComponent.substring(aiComponent.indexOf("import"));
|
|
65
|
+
aiComponent = aiComponent.substring(0, aiComponent.lastIndexOf("```"));
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
// get directory list
|
|
70
|
+
// check for index-template.jsx.old
|
|
71
|
+
// if not there, copy index.jsx to index-template.jsx.old and then copy aiComponent to index.jsx
|
|
72
|
+
// if there, check if have index-genai-1.jsx.old, if not, then copy index.jsx, to index-genai-1.jsx.old
|
|
73
|
+
// otherwise, find all index-genai-X and find biggest number and add one, and save index.jsx to that and then create index.jsx
|
|
74
|
+
|
|
75
|
+
const dirList = await getDirectoryFiles(targetDirectory);
|
|
76
|
+
|
|
77
|
+
if (dirList.includes("index-template.jsx.old")) {
|
|
78
|
+
|
|
79
|
+
const genList = dirList.map( (el) => {
|
|
80
|
+
if (el.indexOf("index-genai") >= 0) {
|
|
81
|
+
return el;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return "";
|
|
46
85
|
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (genList.length > 0) {
|
|
89
|
+
let lastIndex = 0;
|
|
90
|
+
|
|
91
|
+
genList.forEach((el) => {
|
|
92
|
+
const theName = el.split(".")[0];
|
|
93
|
+
const theIndex = theName.split("-")[2];
|
|
47
94
|
|
|
95
|
+
if (parseInt(theIndex) > lastIndex) {
|
|
96
|
+
lastIndex = parseInt(theIndex);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
48
99
|
|
|
49
|
-
|
|
100
|
+
lastIndex++;
|
|
101
|
+
|
|
102
|
+
const oldGenFileName = join(targetDirectory, "index.jsx");
|
|
103
|
+
const newGenFileName = join(targetDirectory, "index-genai-" + lastIndex + ".jsx.old");
|
|
104
|
+
|
|
105
|
+
renameFile(oldGenFileName, newGenFileName);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
const oldGenFileName = join(targetDirectory, "index.jsx");
|
|
109
|
+
const newGenFileName = join(targetDirectory, "index-genai-1.jsx.old");
|
|
110
|
+
|
|
111
|
+
renameFile(oldGenFileName, newGenFileName);
|
|
112
|
+
}
|
|
50
113
|
}
|
|
51
114
|
else {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
message: 'Select component to generateAI',
|
|
57
|
-
choices: localComponents,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'designSystemComponents',
|
|
61
|
-
message: 'Enter comma delimited string of Design system components (ie. Input, TextArea, etc.)'
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: 'additionalPromptInfo',
|
|
65
|
-
message: 'Enter any additional generation information',
|
|
66
|
-
}
|
|
67
|
-
|
|
115
|
+
// so only index.jsx, so rename index.jsx to index-template.jsx.old
|
|
116
|
+
// and create a new index.jsx
|
|
117
|
+
const oldFileName = join(targetDirectory, "index.jsx");
|
|
118
|
+
const newFileName = join(targetDirectory, "index-template.jsx.old");
|
|
68
119
|
|
|
69
|
-
|
|
120
|
+
renameFile(oldFileName, newFileName);
|
|
70
121
|
}
|
|
71
122
|
|
|
123
|
+
// creae new index.jsx
|
|
124
|
+
fs.writeFileSync(indexFile, aiComponent, err => {
|
|
125
|
+
if (err) {
|
|
126
|
+
Promise.reject(`${chalk.bold.red(err)}`);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
72
129
|
|
|
73
|
-
console.log(
|
|
130
|
+
console.log(`Updated file ${chalk.green('index.jsx')} in directory ${chalk.green(componentKey)} with AI generated code.`);
|
|
131
|
+
}
|
|
74
132
|
|
|
75
|
-
await generateAIComponent(enteredKey || answers.componentKey, answers.designSystemComponents, answers.additionalPropmtInfo);
|
|
76
133
|
|
|
77
|
-
} else {
|
|
78
|
-
console.log(chalk.bold.redBright(`No custom components in ${sourceOfComponents}`));
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
134
|
|
|
82
|
-
export const renameFile = (oldFileName, newFileName) => {
|
|
83
|
-
try {
|
|
84
|
-
fs.renameSync(oldFileName, newFileName);
|
|
85
135
|
|
|
86
|
-
} catch(err) {
|
|
87
|
-
console.log(err)
|
|
88
|
-
}
|
|
89
136
|
}
|
|
90
137
|
|
|
91
|
-
export const generateAIComponent = async (componentKey, designSystemComponents, additionalPromptInfo) => {
|
|
92
138
|
|
|
93
|
-
|
|
139
|
+
|
|
140
|
+
export const generateInfinityAIComponent = async (componentKey, additionalPromptInfo) => {
|
|
141
|
+
|
|
142
|
+
const fileName = "." + sep + AI_DAVINCI_PROMPT_FILENAME;
|
|
94
143
|
|
|
95
144
|
// get config file
|
|
96
145
|
//
|
|
97
146
|
const targetDirectory = await getComponentDirectoryPath(componentKey);
|
|
98
|
-
|
|
147
|
+
let configFileData = await getComponentConfigJson(targetDirectory);
|
|
148
|
+
|
|
149
|
+
// need to escape $
|
|
150
|
+
configFileData = configFileData.replaceAll("$", "\\$");
|
|
99
151
|
|
|
100
152
|
let strPrompt = compileMustacheTemplate(fileURLToPath(new URL(fileName, import.meta.url)), {
|
|
101
|
-
COMPONENT_CONFIG:
|
|
102
|
-
COMPONENT_DSC: designSystemComponents,
|
|
153
|
+
COMPONENT_CONFIG: configFileData,
|
|
103
154
|
COMPONENT_ADDITIONAL: additionalPromptInfo
|
|
104
155
|
});
|
|
105
156
|
|
|
106
157
|
strPrompt = _.unescape(strPrompt);
|
|
107
158
|
|
|
108
159
|
//let strPrompt = await getAIPromptData(fileURLToPath(new URL(fileName, import.meta.url)));
|
|
109
|
-
let aiComponent = await
|
|
160
|
+
let aiComponent = await getInfinityAIComponent(strPrompt);
|
|
110
161
|
|
|
111
162
|
//console.log(aiData);
|
|
112
|
-
const indexFile = join(targetDirectory, "index.jsx");
|
|
113
163
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
aiComponent = aiComponent.substring(0, aiComponent.lastIndexOf("```"));
|
|
164
|
+
if (aiComponent) {
|
|
165
|
+
const indexFile = join(targetDirectory, "index-genai.jsx.tmp");
|
|
117
166
|
|
|
167
|
+
// remove enclosed ``` and "Answer:"
|
|
168
|
+
if (aiComponent.indexOf("```") >= 0) {
|
|
169
|
+
aiComponent = aiComponent.substring(aiComponent.indexOf("```"));
|
|
170
|
+
aiComponent = aiComponent.substring(0, aiComponent.lastIndexOf("```"));
|
|
171
|
+
}
|
|
172
|
+
else if (aiComponent.indexOf("'") == 0) {
|
|
173
|
+
aiComponent = aiComponent.substring(aiComponent.indexOf("'"));
|
|
174
|
+
aiComponent = aiComponent.substring(0, aiComponent.lastIndexOf("'"));
|
|
175
|
+
}
|
|
118
176
|
|
|
119
177
|
|
|
120
|
-
// get directory list
|
|
121
|
-
// check for index-template.jsx.old
|
|
122
|
-
// if not there, copy index.jsx to index-template.jsx.old and then copy aiComponent to index.jsx
|
|
123
|
-
// if there, check if have index-genai-1.jsx.old, if not, then copy index.jsx, to index-genai-1.jsx.old
|
|
124
|
-
// otherwise, find all index-genai-X and find biggest number and add one, and save index.jsx to that and then create index.jsx
|
|
125
178
|
|
|
126
|
-
const dirList = await getDirectoryFiles(targetDirectory);
|
|
127
179
|
|
|
128
|
-
|
|
180
|
+
// get directory list
|
|
181
|
+
// check for index-template.jsx.old
|
|
182
|
+
// if not there, copy index.jsx to index-template.jsx.old and then copy aiComponent to index.jsx
|
|
183
|
+
// if there, check if have index-genai-1.jsx.old, if not, then copy index.jsx, to index-genai-1.jsx.old
|
|
184
|
+
// otherwise, find all index-genai-X and find biggest number and add one, and save index.jsx to that and then create index.jsx
|
|
185
|
+
|
|
186
|
+
const dirList = await getDirectoryFiles(targetDirectory);
|
|
187
|
+
|
|
129
188
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
189
|
+
|
|
190
|
+
const genList = dirList.map( (el) => {
|
|
191
|
+
if (el.indexOf("index-genai") >= 0) {
|
|
192
|
+
return el;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
return "";
|
|
196
|
+
}
|
|
197
|
+
});
|
|
138
198
|
|
|
139
199
|
if (genList.length > 0) {
|
|
140
|
-
let lastIndex =
|
|
200
|
+
let lastIndex = -1;
|
|
141
201
|
|
|
142
202
|
genList.forEach((el) => {
|
|
143
203
|
const theName = el.split(".")[0];
|
|
144
|
-
const theIndex = theName.split("-")[2];
|
|
145
204
|
|
|
146
|
-
if (
|
|
147
|
-
lastIndex
|
|
205
|
+
if (theName.indexOf("index-genai") >=0) {
|
|
206
|
+
if (lastIndex === -1) {
|
|
207
|
+
lastIndex = 0;
|
|
208
|
+
}
|
|
209
|
+
const theIndex = theName.split("-")[2];
|
|
210
|
+
|
|
211
|
+
if (parseInt(theIndex) > lastIndex) {
|
|
212
|
+
lastIndex = parseInt(theIndex);
|
|
213
|
+
}
|
|
148
214
|
}
|
|
215
|
+
|
|
149
216
|
});
|
|
150
217
|
|
|
151
218
|
lastIndex++;
|
|
152
219
|
|
|
153
|
-
|
|
154
|
-
|
|
220
|
+
if (lastIndex > 0) {
|
|
221
|
+
const oldGenFileName = join(targetDirectory, "index-genai.jsx.tmp");
|
|
222
|
+
const newGenFileName = join(targetDirectory, "index-genai-" + lastIndex + ".jsx.tmp");
|
|
223
|
+
|
|
224
|
+
renameFile(oldGenFileName, newGenFileName);
|
|
225
|
+
}
|
|
155
226
|
|
|
156
|
-
renameFile(oldGenFileName, newGenFileName);
|
|
157
227
|
}
|
|
158
|
-
else {
|
|
159
|
-
const oldGenFileName = join(targetDirectory, "index.jsx");
|
|
160
|
-
const newGenFileName = join(targetDirectory, "index-genai-1.jsx.old");
|
|
161
228
|
|
|
162
|
-
|
|
229
|
+
|
|
230
|
+
// creae new index.jsx
|
|
231
|
+
fs.writeFileSync(indexFile, aiComponent, err => {
|
|
232
|
+
if (err) {
|
|
233
|
+
Promise.reject(`${chalk.bold.red(err)}`);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
console.log(`Updated file ${chalk.green('index-genai.jsx.tmp')} in directory ${chalk.green(componentKey)} with AI generated code.`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export const getWidgetTemplateAndGenerateAI = async (enteredKey) => {
|
|
245
|
+
const localComponents = await getComponents();
|
|
246
|
+
|
|
247
|
+
let answers;
|
|
248
|
+
|
|
249
|
+
if (localComponents.length > 0) {
|
|
250
|
+
|
|
251
|
+
answers = await inquirer.prompt([
|
|
252
|
+
{
|
|
253
|
+
name: "fileOrText",
|
|
254
|
+
type: "rawlist",
|
|
255
|
+
choices: [ {name: "Prompt via a file", value:"File"}, {name: "Prompt entered text", value:"Text"}],
|
|
256
|
+
message: 'Enter how you want to propmt for component instructions '
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: 'fileName',
|
|
260
|
+
message: 'Enter file name? ',
|
|
261
|
+
default: 'prompt.txt',
|
|
262
|
+
when(answers) {
|
|
263
|
+
return answers.fileOrText === 'File';
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: 'additionalPromptInfo',
|
|
268
|
+
message: 'Enter what you would like this component to do? ',
|
|
269
|
+
when(answers) {
|
|
270
|
+
return answers.fileOrText === 'Text';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
]);
|
|
275
|
+
|
|
276
|
+
console.log("Generating component...");
|
|
277
|
+
|
|
278
|
+
if (answers.fileOrText === "Text") {
|
|
279
|
+
await generateInfinityAIComponent(enteredKey, answers.additionalPromptInfo);
|
|
280
|
+
}
|
|
281
|
+
else if (answers.fileOrText == "File") {
|
|
282
|
+
const strPrompt = await getFilePromptData(enteredKey, answers.fileName);
|
|
283
|
+
|
|
284
|
+
await generateInfinityAIComponent(enteredKey, strPrompt);
|
|
163
285
|
}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
} else {
|
|
290
|
+
console.log(chalk.bold.redBright(`No custom components in ${sourceOfComponents}`));
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export const getFilePromptData = async (componentKey, fileName) => {
|
|
295
|
+
const targetDirectory = await getComponentDirectoryPath(componentKey);
|
|
296
|
+
|
|
297
|
+
const fullFileName = join(targetDirectory, fileName);
|
|
298
|
+
|
|
299
|
+
if (fs.existsSync(fullFileName)) {
|
|
300
|
+
const promptData = fs.readFileSync(fullFileName, { encoding: 'utf8' });
|
|
301
|
+
return promptData;
|
|
164
302
|
}
|
|
165
303
|
else {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
304
|
+
console.log(chalk.bold.redBright(`File ${fileName} does not exist.`));
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export const getFieldAndGenerateAI = async (enteredKey) => {
|
|
312
|
+
const localComponents = await getComponents();
|
|
313
|
+
|
|
314
|
+
let answers;
|
|
315
|
+
|
|
316
|
+
if (localComponents.length > 0) {
|
|
317
|
+
|
|
318
|
+
answers = await inquirer.prompt([
|
|
319
|
+
{
|
|
320
|
+
name: 'designSystemComponents',
|
|
321
|
+
message: 'Enter comma delimited string of Design system components (ie. Input, TextArea, etc.)'
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: 'additionalPromptInfo',
|
|
325
|
+
message: 'Enter any additional generation information',
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
]);
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
console.log("Generating component...");
|
|
332
|
+
|
|
333
|
+
await generateAIComponent(enteredKey || answers.componentKey, answers.designSystemComponents, answers.additionalPropmtInfo);
|
|
170
334
|
|
|
171
|
-
|
|
335
|
+
} else {
|
|
336
|
+
console.log(chalk.bold.redBright(`No custom components in ${sourceOfComponents}`));
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
export const getSelectAComponent = async() => {
|
|
343
|
+
const localComponents = await getComponentsOfType("Widget,Template");
|
|
344
|
+
|
|
345
|
+
let answers;
|
|
346
|
+
|
|
347
|
+
if (localComponents.length > 0) {
|
|
348
|
+
answers = await inquirer.prompt([
|
|
349
|
+
{
|
|
350
|
+
name: 'componentKey',
|
|
351
|
+
type: 'rawlist',
|
|
352
|
+
message: 'Select component to generateAI',
|
|
353
|
+
choices: localComponents
|
|
354
|
+
}]);
|
|
172
355
|
}
|
|
173
356
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
357
|
+
return answers;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export const determineAndGenerateAI = async (enteredKey) => {
|
|
361
|
+
|
|
362
|
+
if (!enteredKey) {
|
|
363
|
+
const answer = await getSelectAComponent();
|
|
364
|
+
if (answer) {
|
|
365
|
+
enteredKey = answer.componentKey;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
console.log(chalk.bold.redBright(`No custom components to generate AI. Please create a Widget or Template component first.`));
|
|
369
|
+
process.exit(1);
|
|
178
370
|
}
|
|
179
|
-
});
|
|
180
371
|
|
|
181
|
-
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const targetDirectory = await getComponentDirectoryPath(enteredKey);
|
|
375
|
+
const configType = await getComponentConfigType(targetDirectory);
|
|
376
|
+
|
|
377
|
+
switch (configType.toLowerCase()) {
|
|
378
|
+
case "widget":
|
|
379
|
+
case "template":
|
|
380
|
+
await getWidgetTemplateAndGenerateAI(enteredKey);
|
|
381
|
+
break;
|
|
382
|
+
case "field":
|
|
383
|
+
await getFieldAndGenerateAI(enteredKey);
|
|
384
|
+
break;
|
|
385
|
+
default:
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
182
388
|
|
|
183
389
|
|
|
184
390
|
}
|
|
@@ -3,8 +3,7 @@ import ora from 'ora';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
generateAIComponent
|
|
6
|
+
determineAndGenerateAI
|
|
8
7
|
} from './helper.js';
|
|
9
8
|
|
|
10
9
|
import { showVersion } from '../../util.js';
|
|
@@ -19,11 +18,13 @@ export default async options => {
|
|
|
19
18
|
const sourceOfComponents = options.params[3];
|
|
20
19
|
|
|
21
20
|
//await generateAIComponent(sourceOfComponents);
|
|
22
|
-
await getComponentAndGenerateAI(sourceOfComponents);
|
|
21
|
+
//await getComponentAndGenerateAI(sourceOfComponents);
|
|
22
|
+
await determineAndGenerateAI(sourceOfComponents);
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
25
25
|
|
|
26
|
-
await getComponentAndGenerateAI();
|
|
26
|
+
//await getComponentAndGenerateAI();
|
|
27
|
+
await determineAndGenerateAI();
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@pega/configs": "^0.5.3",
|
|
60
|
-
"@pega/custom-dx-components": "^0.23.
|
|
60
|
+
"@pega/custom-dx-components": "^0.23.3",
|
|
61
61
|
"@pega/eslint-config": "^0.3.2",
|
|
62
62
|
"@storybook/addon-actions": "^6.5.12",
|
|
63
63
|
"@storybook/addon-essentials": "^6.5.12",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# directory for components #
|
package/src/util.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
import { join } from 'path';
|
|
3
4
|
import { promisify } from 'util';
|
|
4
5
|
import https from 'https';
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
OOTB_COMPONENTS,
|
|
22
23
|
SERVICES_AI_REST_ENDPOINT,
|
|
23
24
|
BOOTSTRAP_SERVICE_REST_ENDPOINT,
|
|
25
|
+
DXCOMPGENAI_SERVICE_REST_ENDPOINT,
|
|
24
26
|
SERVICE_TOKEN_PATH
|
|
25
27
|
} from './constants.js';
|
|
26
28
|
|
|
@@ -142,6 +144,46 @@ export const getComponents = async () => {
|
|
|
142
144
|
.map(dirent => dirent.name);
|
|
143
145
|
};
|
|
144
146
|
|
|
147
|
+
export const getComponentsOfType = async (componentType) => {
|
|
148
|
+
const componentList = await getComponents();
|
|
149
|
+
let filteredList = Array();
|
|
150
|
+
if (componentList.length > 0) {
|
|
151
|
+
|
|
152
|
+
const currentDirectory = process.cwd();
|
|
153
|
+
const pegaConfigJsonPath = join(currentDirectory, TASKS_CONFIG_JSON_FILENAME);
|
|
154
|
+
|
|
155
|
+
await checkPathAccess(pegaConfigJsonPath);
|
|
156
|
+
|
|
157
|
+
let data = fs.readFileSync(pegaConfigJsonPath, { encoding: 'utf8' });
|
|
158
|
+
data = JSON.parse(data);
|
|
159
|
+
|
|
160
|
+
if (!data[COMPONENTS_DIRECTORY_PATH]) {
|
|
161
|
+
console.error(
|
|
162
|
+
`${chalk.red.bold('ERROR')} Could not able find components directory path in config.json`
|
|
163
|
+
);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const directory = join(currentDirectory, data[COMPONENTS_DIRECTORY_PATH]);
|
|
168
|
+
const arTypes = componentType.split(",");
|
|
169
|
+
|
|
170
|
+
for (let index in componentList) {
|
|
171
|
+
let compDir = directory + path.sep + componentList[index];
|
|
172
|
+
let type = await getComponentConfigType(compDir);
|
|
173
|
+
if (arTypes.includes(type)) {
|
|
174
|
+
filteredList.push( componentList[index]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
return filteredList;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return componentList;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
145
187
|
|
|
146
188
|
|
|
147
189
|
|
|
@@ -219,6 +261,15 @@ export const getComponentConfigJson = async (componentDirectory) => {
|
|
|
219
261
|
return data;
|
|
220
262
|
}
|
|
221
263
|
|
|
264
|
+
export const getComponentConfigType = async (componentDirectory) => {
|
|
265
|
+
const configData = await getComponentConfigJson(componentDirectory);
|
|
266
|
+
|
|
267
|
+
let data = JSON.parse(configData);
|
|
268
|
+
|
|
269
|
+
return data.type;
|
|
270
|
+
|
|
271
|
+
}
|
|
272
|
+
|
|
222
273
|
export const getPegaServerConfig = async () => {
|
|
223
274
|
const config = await getPegaConfig();
|
|
224
275
|
return config['server-config'];
|
|
@@ -516,3 +567,77 @@ export const getAIComponent = async (prompt) => {
|
|
|
516
567
|
|
|
517
568
|
return returnCode;
|
|
518
569
|
};
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
export const getInfinityAIComponent = async (prompt) => {
|
|
573
|
+
const { server } = await getPegaServerConfig();
|
|
574
|
+
const dataPageUrl = constructCompleteUrl(server, DXCOMPGENAI_SERVICE_REST_ENDPOINT);
|
|
575
|
+
|
|
576
|
+
const jsonBody = { "dataViewParameters" : { "Prompt" : prompt } };
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
let returnCode = "";
|
|
581
|
+
|
|
582
|
+
try {
|
|
583
|
+
const OauthData = fs.readFileSync(TOKEN_PATH, 'utf8');
|
|
584
|
+
|
|
585
|
+
if (OauthData) {
|
|
586
|
+
let {
|
|
587
|
+
access_token: accessToken,
|
|
588
|
+
token_type: tokenType,
|
|
589
|
+
refresh_token: refreshToken
|
|
590
|
+
} = JSON.parse(OauthData);
|
|
591
|
+
|
|
592
|
+
// services needs Bearer with a big "B"
|
|
593
|
+
//tokenType = convertIntoPascalCase(tokenType);
|
|
594
|
+
|
|
595
|
+
await fetch(dataPageUrl, {
|
|
596
|
+
method: 'POST',
|
|
597
|
+
agent: new https.Agent({ rejectUnauthorized: false }),
|
|
598
|
+
headers: {
|
|
599
|
+
Authorization: `${tokenType} ${accessToken}`
|
|
600
|
+
},
|
|
601
|
+
body: JSON.stringify(jsonBody),
|
|
602
|
+
})
|
|
603
|
+
.then(response => response.text())
|
|
604
|
+
.then(data => {
|
|
605
|
+
|
|
606
|
+
try {
|
|
607
|
+
const returnData = JSON.parse(data);
|
|
608
|
+
|
|
609
|
+
if (returnData != null && returnData.data) {
|
|
610
|
+
returnCode = returnData.data[0].pyValue;
|
|
611
|
+
}
|
|
612
|
+
else if (returnData != null && returnData.errors) {
|
|
613
|
+
if (returnData.errors[0].message.indexOf("token") >= 0) {
|
|
614
|
+
Promise.reject(`${chalk.bold.red("ERROR: Need to authenticate or reauthenticate.")}`);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
returnCode = "";
|
|
619
|
+
Promise.reject(`Error in AI generation: \n ${chalk.bold.red(data)}`);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
catch {
|
|
623
|
+
Promise.reject(`Error in AI generation: \n ${chalk.bold.red(data)}`);
|
|
624
|
+
//throw new Error('Error occurred in validation', data);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
})
|
|
629
|
+
.catch(e => Promise.reject(`Error in AI generation: \n ${chalk.bold.red(e)}`));
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
if (error.code === 'ENOENT') {
|
|
634
|
+
Promise.reject(`${chalk.bold.red("ERROR: Need to authenticate or reauthenticate.")}`);
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
throw new Error('Error occurred in validation', error);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return returnCode;
|
|
643
|
+
};
|