@pega/custom-dx-components 25.1.25 → 25.1.26

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.
@@ -0,0 +1,77 @@
1
+ name: CI Validation
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - release/25.1
7
+ pull_request:
8
+ branches:
9
+ - release/25.1
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ concurrency:
16
+ group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ validate:
21
+ name: Validate 25.1
22
+ runs-on: ubuntu-latest
23
+ timeout-minutes: 45
24
+
25
+ steps:
26
+ - name: Check out repository
27
+ uses: actions/checkout@v7
28
+
29
+ - name: Set up Node.js
30
+ uses: actions/setup-node@v7
31
+ with:
32
+ node-version: 24.x
33
+ cache: npm
34
+
35
+ - name: Install dependencies
36
+ run: npm ci --no-audit --no-fund
37
+
38
+ - name: Audit dependencies
39
+ run: npm audit --audit-level=critical
40
+
41
+ - name: Audit consumer dependencies
42
+ if: always()
43
+ env:
44
+ CONSUMER_DIR: ${{ runner.temp }}/custom-dx-components-consumer
45
+ run: |
46
+ set -euo pipefail
47
+ rm -rf "$CONSUMER_DIR"
48
+ mkdir -p "$CONSUMER_DIR"
49
+ node --input-type=module <<'NODE'
50
+ import fs from 'node:fs/promises';
51
+ import path from 'node:path';
52
+ import mustache from 'mustache';
53
+
54
+ const templatePath = path.resolve('src/tasks/init/template/package.json.mustache');
55
+ const template = await fs.readFile(templatePath, 'utf8');
56
+ const packageJson = mustache.render(template, {
57
+ projectName: 'ci-consumer',
58
+ organization: 'Pega',
59
+ description: 'CI consumer dependency audit',
60
+ author: 'CI'
61
+ });
62
+
63
+ const manifest = JSON.parse(packageJson);
64
+ // The template pins the in-development version of this package, which is not on the
65
+ // registry yet. Its dependencies are already audited by the previous step.
66
+ delete manifest.devDependencies?.['@pega/custom-dx-components'];
67
+ delete manifest.dependencies?.['@pega/custom-dx-components'];
68
+ await fs.writeFile(
69
+ path.join(process.env.CONSUMER_DIR, 'package.json'),
70
+ `${JSON.stringify(manifest, null, 2)}\n`
71
+ );
72
+ NODE
73
+ npm install --prefix "$CONSUMER_DIR" --legacy-peer-deps --ignore-scripts --no-audit --no-fund
74
+ npm audit --prefix "$CONSUMER_DIR" --audit-level=critical
75
+
76
+ - name: Run unit tests
77
+ run: npm run test:unit:local
package/jest.config.cjs CHANGED
@@ -3,9 +3,13 @@ module.exports = {
3
3
  roots: ['./tests'],
4
4
  moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
5
5
  testEnvironment: 'jsdom',
6
+ setupFiles: ['./tests/setup.cjs'],
6
7
  transform: {
7
8
  '^.+\\.[t|j]sx?$': 'babel-jest'
8
9
  },
10
+ moduleNameMapper: {
11
+ '^file-type$': '<rootDir>/node_modules/file-type/index.js'
12
+ },
9
13
  collectCoverage: true,
10
14
  haste: {
11
15
  retainAllFiles: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/custom-dx-components",
3
- "version": "25.1.25",
3
+ "version": "25.1.26",
4
4
  "description": "Utility for building custom UI components",
5
5
  "bin": "./bin/index.js",
6
6
  "keywords": [
@@ -17,7 +17,7 @@
17
17
  "lint:spelling": "cspell **/*",
18
18
  "fix:es": "eslint --fix .",
19
19
  "fix:format": "prettier -w .",
20
- "test:unit:local": "node --input-type=module --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand /tests/unit",
20
+ "test:unit:local": "node --input-type=module --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --coverage=false /tests/unit",
21
21
  "test:functional:local": "jest --runInBand /tests/functional --detectOpenHandles --coverage"
22
22
  },
23
23
  "dependencies": {
@@ -25,7 +25,7 @@
25
25
  "@babel/plugin-transform-class-properties": "^7.27.1",
26
26
  "@babel/preset-react": "^7.27.1",
27
27
  "@pega/auth": "^0.2.31",
28
- "@pega/constellation-dx-components-build-utils": "^2.0.14",
28
+ "@pega/constellation-dx-components-build-utils": "^2.0.16",
29
29
  "@pega/inquirer-fuzzy-path": "^3.0.0",
30
30
  "ajv": "^8.17.1",
31
31
  "ajv-keywords": "^5.1.0",
package/src/constants.js CHANGED
@@ -22,8 +22,7 @@ export const ARCHIVES_PATH = 'store';
22
22
  export const BIN_ARCHIVES_PATH = 'bin-arch';
23
23
  export const TEMP_PATH = 'store/temp';
24
24
  export const COMPONENTS_CONFIG_FILE_NAME = 'componentsconfig.json';
25
- export const MAX_RFT_CHARS = 64;
26
-
25
+ export const MAX_RFT_CHARS = 256;
27
26
 
28
27
  /* REST end points */
29
28
  export const PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component';
@@ -42,13 +41,14 @@ export const LP_DELETE_COMPONENT_SERVICE_REST_ENDPOINT =
42
41
  'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
43
42
 
44
43
  export const PUBLISH_COMPONENT_LIBRARY_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component_library';
45
- export const PUBLISH_COMPONENT_LIBRARY_ARCHIVE_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component_library_archive';
44
+ export const PUBLISH_COMPONENT_LIBRARY_ARCHIVE_SERVICE_REST_ENDPOINT =
45
+ 'PRRestService/dev/v1/publish_component_library_archive';
46
46
  export const LIST_COMPONENT_LIBRARIES_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/list_component_libraries';
47
- export const LIST_COMPONENT_LIBRARY_ARCHIVES_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/list_component_library_archives';
47
+ export const LIST_COMPONENT_LIBRARY_ARCHIVES_SERVICE_REST_ENDPOINT =
48
+ 'PRRestService/dev/v1/list_component_library_archives';
48
49
  export const DELETE_COMPONENT_LIBRARY_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/delete_component_library';
49
50
  export const COMPONENT_LIBRARY_ARCHIVE_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/component_library_archive';
50
51
 
51
-
52
52
  export const FIELD_PATH = '/field';
53
53
  export const TEMPLATE_PATH = '/template';
54
54
  export const WIDGET_PATH = '/widget';
@@ -77,185 +77,181 @@ export const AUTHENTICATE_DEFAULTS = {
77
77
  clientId: '10095186356008396159',
78
78
  grantType: 'authCode',
79
79
  authService: 'pega',
80
- redirectUri: 'https://localhost:4010/'
80
+ redirectUri: 'https://localhost:4010/',
81
81
  };
82
82
 
83
- export const SHARED_FILE_NAMES = [
84
- "suggestions-handler.ts",
85
- "PConnProps.d.ts",
86
- "create-nonce.ts"
87
- ];
83
+ export const SHARED_FILE_NAMES = ['suggestions-handler.ts', 'PConnProps.d.ts', 'create-nonce.ts'];
88
84
 
89
85
  export const AUTHENTICATE_SCHEMA = {
90
86
  serverType: [
91
87
  {
92
88
  name: 'Infinity',
93
- value: 'infinity'
89
+ value: 'infinity',
94
90
  },
95
91
  {
96
92
  name: 'Launchpad',
97
- value: 'launchpad'
98
- }
93
+ value: 'launchpad',
94
+ },
99
95
  ],
100
96
  grantType: [
101
97
  {
102
98
  name: 'Authorization code',
103
- value: 'authCode'
99
+ value: 'authCode',
104
100
  },
105
101
  {
106
102
  name: 'Password credentials',
107
- value: 'passwordCreds'
103
+ value: 'passwordCreds',
108
104
  },
109
105
  {
110
106
  name: 'Client credentials',
111
- value: 'clientCreds'
112
- }
113
- ]
107
+ value: 'clientCreds',
108
+ },
109
+ ],
114
110
  };
115
111
 
116
112
  export const COMPONENT_SCHEMA = {
117
113
  framework: [
118
114
  {
119
115
  name: 'Constellation',
120
- value: 'Constellation'
116
+ value: 'Constellation',
121
117
  },
122
118
  {
123
119
  name: 'SDK Angular',
124
- value: 'SDK-Angular'
120
+ value: 'SDK-Angular',
125
121
  },
126
122
  {
127
123
  name: 'SDK React',
128
- value: 'SDK-React'
124
+ value: 'SDK-React',
129
125
  },
130
126
  {
131
127
  name: 'SDK Web Components',
132
- value: 'SDK-WebComponents'
133
- }
128
+ value: 'SDK-WebComponents',
129
+ },
134
130
  ],
135
131
  type: [
136
132
  {
137
133
  name: 'Field',
138
- value: 'Field'
134
+ value: 'Field',
139
135
  },
140
136
  {
141
137
  name: 'Layout template',
142
- value: 'Template'
138
+ value: 'Template',
143
139
  },
144
140
  {
145
141
  name: 'Widget',
146
- value: 'Widget'
147
- }
142
+ value: 'Widget',
143
+ },
148
144
  ],
149
145
  subtype: {
150
146
  field: [
151
147
  {
152
148
  name: 'Text',
153
- value: 'Text'
149
+ value: 'Text',
154
150
  },
155
151
  {
156
152
  name: 'Text Input',
157
- value: 'Text-Input'
153
+ value: 'Text-Input',
158
154
  },
159
155
  {
160
156
  name: 'Paragraph',
161
- value: 'Text-Paragraph'
157
+ value: 'Text-Paragraph',
162
158
  },
163
159
  {
164
160
  name: 'Email',
165
- value: 'Text-Email'
161
+ value: 'Text-Email',
166
162
  },
167
163
  {
168
164
  name: 'Phone',
169
- value: 'Text-Phone'
165
+ value: 'Text-Phone',
170
166
  },
171
167
  {
172
168
  name: 'URL',
173
- value: 'Text-URL'
169
+ value: 'Text-URL',
174
170
  },
175
171
  {
176
172
  name: 'Icon Button URL',
177
- value: 'Icon-Button-URL'
173
+ value: 'Icon-Button-URL',
178
174
  },
179
175
  {
180
176
  name: 'Integer',
181
- value: 'Integer'
177
+ value: 'Integer',
182
178
  },
183
179
  {
184
180
  name: 'Decimal',
185
- value: 'Decimal'
181
+ value: 'Decimal',
186
182
  },
187
183
  {
188
184
  name: 'Currency',
189
- value: 'Decimal-Currency'
185
+ value: 'Decimal-Currency',
190
186
  },
191
187
  {
192
188
  name: 'Percentage',
193
- value: 'Decimal-Percentage'
189
+ value: 'Decimal-Percentage',
194
190
  },
195
191
  {
196
192
  name: 'Boolean',
197
- value: 'Boolean'
193
+ value: 'Boolean',
198
194
  },
199
195
  {
200
196
  name: 'Date',
201
- value: 'Date'
197
+ value: 'Date',
202
198
  },
203
199
  {
204
200
  name: 'DateTime',
205
- value: 'DateTime'
201
+ value: 'DateTime',
206
202
  },
207
203
  {
208
204
  name: 'TimeOfDay',
209
- value: 'TimeOfDay'
205
+ value: 'TimeOfDay',
210
206
  },
211
207
  {
212
208
  name: 'Picklist',
213
- value: 'Picklist'
209
+ value: 'Picklist',
214
210
  },
215
211
  {
216
212
  name: 'Search box',
217
- value: 'Picklist-Autocomplete'
213
+ value: 'Picklist-Autocomplete',
218
214
  },
219
215
  {
220
216
  name: 'Radio buttons',
221
- value: 'Picklist-RadioButtons'
222
- }
217
+ value: 'Picklist-RadioButtons',
218
+ },
223
219
  ],
224
220
  template: [
225
221
  {
226
222
  name: 'DETAILS',
227
- value: 'DETAILS'
223
+ value: 'DETAILS',
228
224
  },
229
225
  {
230
226
  name: 'DETAILS region',
231
- value: 'DETAILS-region'
227
+ value: 'DETAILS-region',
232
228
  },
233
229
  {
234
230
  name: 'FORM',
235
- value: 'FORM'
231
+ value: 'FORM',
236
232
  },
237
233
  {
238
234
  name: 'FORM region',
239
- value: 'FORM-region'
235
+ value: 'FORM-region',
240
236
  },
241
237
  {
242
238
  name: 'PAGE',
243
- value: 'PAGE'
244
- }
239
+ value: 'PAGE',
240
+ },
245
241
  ],
246
242
  widget: [
247
243
  {
248
244
  name: 'CASE',
249
- value: 'CASE'
245
+ value: 'CASE',
250
246
  },
251
247
  {
252
248
  name: 'PAGE',
253
- value: 'PAGE'
249
+ value: 'PAGE',
254
250
  },
255
251
  {
256
252
  name: 'PAGE & CASE',
257
- value: ['PAGE', 'CASE']
258
- }
259
- ]
260
- }
253
+ value: ['PAGE', 'CASE'],
254
+ },
255
+ ],
256
+ },
261
257
  };
@@ -26,7 +26,7 @@ export default function GetNextWork(props: {{COMPONENT_CLASS_NAME}}WorkProps) {
26
26
  getPConnect()
27
27
  .getActionsApi()
28
28
  .getNextWork()
29
- .catch((err) => {
29
+ .catch((err: any) => {
30
30
  console.log(err);
31
31
  if (err[0].status === 404) {
32
32
  toasterCtx.push({
@@ -83,9 +83,9 @@
83
83
  "pega"
84
84
  ],
85
85
  "dependencies": {
86
- "@pega/cosmos-react-condition-builder": "^8.4.1",
87
- "@pega/cosmos-react-core": "^8.4.1",
88
- "@pega/cosmos-react-work": "^8.4.1",
86
+ "@pega/cosmos-react-condition-builder": "~8.21.8",
87
+ "@pega/cosmos-react-core": "~8.21.8",
88
+ "@pega/cosmos-react-work": "~8.21.8",
89
89
  "@pega/eslint-config": "^0.16.3",
90
90
  "@pega/tsconfig": "^0.16.3",
91
91
  "babel-loader": "^10.0.0",
@@ -108,7 +108,7 @@
108
108
  "@babel/preset-react": "^7.27.1",
109
109
  "@babel/preset-typescript": "^7.27.1",
110
110
  "@pega/configs": "^0.16.3",
111
- "@pega/custom-dx-components": "~25.1.25",
111
+ "@pega/custom-dx-components": "~25.1.26",
112
112
  "@pega/pcore-pconnect-typedefs": "^4.1.0",
113
113
  "@storybook/addon-actions": "^8.6.14",
114
114
  "@storybook/addon-essentials": "^8.6.14",
@@ -0,0 +1,11 @@
1
+ import type { PCore as PCoreType } from '@pega/pcore-pconnect-typedefs';
2
+
3
+ declare global {
4
+ const PCore: PCoreType;
5
+
6
+ interface Window {
7
+ PCore: PCoreType;
8
+ }
9
+ }
10
+
11
+ export {};
@@ -12,7 +12,7 @@
12
12
  "@pega/pcore-pconnect-typedefs/*": ["node_modules/@pega/pcore-pconnect-typedefs/*"]
13
13
  },
14
14
  "esModuleInterop": true,
15
- "types": ["jest", "node", "@types/jest"],
15
+ "types": ["jest", "node", "@types/jest", "@pega/pcore-pconnect-typedefs"],
16
16
  "verbatimModuleSyntax": false
17
17
  }
18
18
  }
@@ -0,0 +1,12 @@
1
+ globalThis.require ??= require;
2
+
3
+ const { TextDecoder, TextEncoder } = require('node:util');
4
+ const { MessagePort } = require('node:worker_threads');
5
+ const { ReadableStream, TransformStream, WritableStream } = require('node:stream/web');
6
+
7
+ globalThis.TextDecoder ??= TextDecoder;
8
+ globalThis.TextEncoder ??= TextEncoder;
9
+ globalThis.MessagePort ??= MessagePort;
10
+ globalThis.ReadableStream ??= ReadableStream;
11
+ globalThis.TransformStream ??= TransformStream;
12
+ globalThis.WritableStream ??= WritableStream;
@@ -1,7 +1,8 @@
1
- import fs, {Dirent, constants} from 'fs';
1
+ import fs, { Dirent, constants, copyFileSync, mkdtempSync, rmSync } from 'fs';
2
2
  import path from 'path';
3
3
  import { join } from 'path';
4
- import {expect, jest, test} from '@jest/globals';
4
+ import os from 'os';
5
+ import { expect, jest, test } from '@jest/globals';
5
6
  import chalk from 'chalk';
6
7
  import { createRequire } from 'module';
7
8
 
@@ -19,7 +20,8 @@ import {
19
20
  getComponentsObj,
20
21
  getPegaConfig,
21
22
  getPegaServerConfig,
22
- getComponentDefaults,
23
+ getConfigDefaults,
24
+ forceDefaultsUpdate,
23
25
  getComponentDirectoryPath,
24
26
  convertIntoPascalCase,
25
27
  isPascalCase,
@@ -38,22 +40,32 @@ const mockAcces = {
38
40
  }
39
41
 
40
42
  // should be overridden
41
- let libraryName = "not valid";
42
- let organizationName = "not valid";
43
- let version = "not valid";
44
-
45
- beforeAll( async () => {
46
- const thePath = process.cwd().replace("node_modules/@pega/custom-dx-components","");
47
- const cwdMock = jest.spyOn(process, 'cwd');
48
- cwdMock.mockReturnValue(thePath);
49
-
43
+ let libraryName = 'not valid';
44
+ let organizationName = 'not valid';
45
+ let version = 'not valid';
46
+ let cwdMock;
47
+ let testProjectDirectory;
48
+ let originalCwd;
49
+
50
+ beforeAll(async () => {
51
+ const repositoryRoot = process.cwd();
52
+ testProjectDirectory = mkdtempSync(join(os.tmpdir(), 'custom-dx-unit-'));
53
+ copyFileSync(path.join(repositoryRoot, 'src/tasks/init/template/tasks.config.json'), path.join(testProjectDirectory, 'tasks.config.json'));
54
+ originalCwd = process.cwd;
55
+ process.cwd = () => testProjectDirectory;
56
+ cwdMock = jest.spyOn(process, 'cwd');
57
+ cwdMock.mockReturnValue(testProjectDirectory);
50
58
 
51
59
  const oConf = await getPegaConfig();
52
60
  libraryName = oConf.component.library;
53
61
  version = oConf.component.version;
62
+ await forceDefaultsUpdate();
63
+ });
54
64
 
55
-
56
-
65
+ afterAll(() => {
66
+ cwdMock.mockRestore();
67
+ process.cwd = originalCwd;
68
+ rmSync(testProjectDirectory, { recursive: true, force: true });
57
69
  });
58
70
 
59
71
  // describe('utils fetch', () => {
@@ -333,7 +345,7 @@ describe('utils test', () => {
333
345
  const cwdMock = jest.spyOn(process, 'cwd');
334
346
  cwdMock.mockReturnValue(thePath);
335
347
 
336
- const oConf = await getComponentDefaults();
348
+ const oConf = await getConfigDefaults();
337
349
 
338
350
  expect(oConf).not.toBeNull;
339
351
  expect(oConf.library).toMatch(libraryName);