@pega/custom-dx-components 26.1.10-alpha-0.1 → 26.1.10-alpha-0.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.
Files changed (115) hide show
  1. package/.github/workflows/lint-and-format.yml +36 -0
  2. package/.prettierignore +15 -2
  3. package/.prettierrc.mjs +8 -0
  4. package/README.md +2 -2
  5. package/eslint.config.mjs +32 -20
  6. package/package.json +19 -7
  7. package/src/cli.js +1 -1
  8. package/src/constants.js +21 -14
  9. package/src/rules/no-pcore-pconnect-in-presentation.js +103 -0
  10. package/src/tasks/authenticate/helper.js +9 -37
  11. package/src/tasks/authenticate/index.js +10 -54
  12. package/src/tasks/build-all/helper.js +2 -3
  13. package/src/tasks/build-all/index.js +17 -26
  14. package/src/tasks/build-comp/helper.js +7 -22
  15. package/src/tasks/build-comp/index.js +8 -15
  16. package/src/tasks/build-jest-assets/index.js +62 -58
  17. package/src/tasks/build-lib/helper.js +8 -20
  18. package/src/tasks/build-lib/index.js +22 -43
  19. package/src/tasks/bundle/builder/index.js +27 -70
  20. package/src/tasks/bundle/builder/modules.js +7 -10
  21. package/src/tasks/bundle/builder/paths.js +2 -16
  22. package/src/tasks/bundle/builder/webpack.config.js +15 -0
  23. package/src/tasks/bundle/index.js +1 -1
  24. package/src/tasks/create/index.js +78 -95
  25. package/src/tasks/create/templates/Constellation/Field/DateTime/suggestions-handler.ts +0 -1
  26. package/src/tasks/create/templates/Constellation/Field/Picklist-Autocomplete/PConnProps.d.ts +17 -18
  27. package/src/tasks/create/templates/Constellation/Field/Picklist-RadioButtons/PConnProps.d.ts +17 -18
  28. package/src/tasks/create/templates/Constellation/Field/Text/PConnProps.d.ts +17 -18
  29. package/src/tasks/create/templates/Constellation/Field/Text-Email/PConnProps.d.ts +17 -18
  30. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/config.json.mustache +15 -0
  31. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/demo.stories.tsx.mustache +37 -0
  32. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/demo.test.tsx.mustache +19 -0
  33. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/index.tsx.mustache +93 -0
  34. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/localizations.json.mustache +15 -0
  35. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/mock.ts.mustache +33 -0
  36. package/src/tasks/create/templates/Constellation/Presentation/CASEVIEW/styles.ts.mustache +27 -0
  37. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/config.json.mustache +15 -0
  38. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/demo.stories.tsx.mustache +36 -0
  39. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/demo.test.tsx.mustache +18 -0
  40. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/index.tsx.mustache +64 -0
  41. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/localizations.json.mustache +9 -0
  42. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/mock.ts.mustache +27 -0
  43. package/src/tasks/create/templates/Constellation/Presentation/WSSCASEVIEW/styles.ts.mustache +27 -0
  44. package/src/tasks/create-all/index.js +113 -78
  45. package/src/tasks/create-lib/helper.js +29 -45
  46. package/src/tasks/create-lib/index.js +28 -49
  47. package/src/tasks/create-version/helper.js +39 -51
  48. package/src/tasks/create-version/index.js +39 -59
  49. package/src/tasks/delete/helper.js +32 -41
  50. package/src/tasks/delete/index.js +8 -16
  51. package/src/tasks/delete-all/helper.js +21 -39
  52. package/src/tasks/delete-all/index.js +1 -7
  53. package/src/tasks/delete-lib/helper.js +7 -8
  54. package/src/tasks/delete-lib/index.js +71 -120
  55. package/src/tasks/delete-pub/helper.js +22 -35
  56. package/src/tasks/delete-pub/index.js +61 -66
  57. package/src/tasks/delete-version/index.js +19 -29
  58. package/src/tasks/dev-server/index.js +5 -18
  59. package/src/tasks/export-archive/helper.js +54 -58
  60. package/src/tasks/export-archive/index.js +118 -170
  61. package/src/tasks/export-rc/helper.js +67 -84
  62. package/src/tasks/export-rc/index.js +23 -45
  63. package/src/tasks/import-archive/helper.js +231 -301
  64. package/src/tasks/import-archive/index.js +432 -534
  65. package/src/tasks/import-comp/helper.js +36 -44
  66. package/src/tasks/import-comp/index.js +73 -113
  67. package/src/tasks/init/index.js +11 -24
  68. package/src/tasks/init/template/.storybook/main.ts +4 -3
  69. package/src/tasks/init/template/.storybook/preview.tsx +7 -7
  70. package/src/tasks/init/template/.storybook/theme.js +1 -1
  71. package/src/tasks/init/template/README.md +2 -2
  72. package/src/tasks/init/template/babel.config.cjs +5 -5
  73. package/src/tasks/init/template/eslint.config.mjs +22 -22
  74. package/src/tasks/init/template/jest.config.cjs +8 -11
  75. package/src/tasks/init/template/package.json.mustache +3 -1
  76. package/src/tasks/init/template/setupTests.ts +7 -7
  77. package/src/tasks/init/template/tsconfig.build.json +1 -1
  78. package/src/tasks/linter/index.js +6 -8
  79. package/src/tasks/list/helper.js +59 -61
  80. package/src/tasks/list/index.js +9 -16
  81. package/src/tasks/list-lib/helper.js +25 -33
  82. package/src/tasks/list-lib/index.js +54 -65
  83. package/src/tasks/list-pub/helper.js +37 -55
  84. package/src/tasks/list-pub/index.js +87 -102
  85. package/src/tasks/move/helper.js +9 -15
  86. package/src/tasks/move/index.js +171 -239
  87. package/src/tasks/promote-webpack/index.js +12 -37
  88. package/src/tasks/promote-webpack/webpack.config.js +18 -20
  89. package/src/tasks/publish/helper.js +25 -37
  90. package/src/tasks/publish/index.js +20 -44
  91. package/src/tasks/publish-all/helper.js +12 -28
  92. package/src/tasks/publish-all/index.js +9 -16
  93. package/src/tasks/publish-archive/helper.js +13 -21
  94. package/src/tasks/publish-archive/index.js +117 -150
  95. package/src/tasks/publish-lib/helper.js +12 -16
  96. package/src/tasks/publish-lib/index.js +101 -124
  97. package/src/tasks/quarantine/index.js +18 -33
  98. package/src/tasks/rename/index.js +32 -90
  99. package/src/tasks/rename-lib/index.js +17 -47
  100. package/src/tasks/restore/index.js +12 -20
  101. package/src/tasks/restore-config/index.js +7 -18
  102. package/src/tasks/revert-webpack/index.js +4 -4
  103. package/src/tasks/set-perm/index.js +30 -53
  104. package/src/tasks/show-help/index.js +45 -46
  105. package/src/tasks/show-status/index.js +15 -27
  106. package/src/tasks/store/index.js +11 -21
  107. package/src/tasks/switch-lib/helper.js +23 -34
  108. package/src/tasks/switch-lib/index.js +19 -38
  109. package/src/tasks/switch-version/helper.js +8 -19
  110. package/src/tasks/switch-version/index.js +28 -48
  111. package/src/tasks/validator/index.js +116 -48
  112. package/src/util.js +763 -942
  113. package/tests/unit/validator-presentation.test.js +37 -0
  114. package/tsconfig.json +21 -0
  115. package/.prettierrc.json +0 -1
@@ -0,0 +1,36 @@
1
+ name: Lint and Format
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - master
10
+
11
+ jobs:
12
+ lint-and-format:
13
+ runs-on: ubuntu-latest
14
+
15
+ strategy:
16
+ matrix:
17
+ node-version: [20.x]
18
+
19
+ steps:
20
+ - name: Checkout code
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Set up Node.js
24
+ uses: actions/setup-node@v4
25
+ with:
26
+ node-version: ${{ matrix.node-version }}
27
+ cache: 'npm'
28
+
29
+ - name: Install dependencies
30
+ run: npm ci
31
+
32
+ - name: Run ESLint
33
+ run: npm run lint:es
34
+
35
+ - name: Check Prettier formatting
36
+ run: npm run lint:format
package/.prettierignore CHANGED
@@ -1,2 +1,15 @@
1
- node_modules
2
- *.md
1
+ **/.git
2
+ **/.github
3
+ **/.vscode
4
+ **/.svn
5
+ **/.hg
6
+ **/*.md
7
+ **/*.svg
8
+ **/assets
9
+ **/*.mustache
10
+ **/*.zip
11
+ **/*.key
12
+ **/*.crt
13
+ **/*.gitignore
14
+ **/*.npmrc
15
+ **/*.txt
@@ -0,0 +1,8 @@
1
+ import pegaPrettierConfig from "@pega/prettier-config";
2
+
3
+ export default {
4
+ ...pegaPrettierConfig,
5
+ printWidth: 150,
6
+ trailingComma: "none",
7
+ arrowParens: "avoid",
8
+ };
package/README.md CHANGED
@@ -37,9 +37,9 @@ Ensure you have access to the following in your system:
37
37
 
38
38
  - Git version 2.30 or later
39
39
 
40
- - System node version >= 22.15.0
40
+ - System node version >= 24.4.1
41
41
 
42
- - System npm version 10.9.2
42
+ - System npm version 11.4.2
43
43
 
44
44
  ## Latest Documentation
45
45
 
package/eslint.config.mjs CHANGED
@@ -8,8 +8,10 @@ import react from 'eslint-plugin-react';
8
8
  import reactHooks from 'eslint-plugin-react-hooks';
9
9
  // eslint.config.js
10
10
  import { defineConfig } from 'eslint/config';
11
+ import noPcorePconnectInPresentation from './src/rules/no-pcore-pconnect-in-presentation.js';
11
12
 
12
13
  const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
13
15
 
14
16
  export default defineConfig([
15
17
  eslint.configs.recommended,
@@ -40,7 +42,8 @@ export default defineConfig([
40
42
  '**/*.mjs',
41
43
  '**/paths.js',
42
44
  'dist/*',
43
- 'lib/*'
45
+ 'lib/*',
46
+ 'tests/*'
44
47
  ]),
45
48
  {
46
49
  languageOptions: {
@@ -56,7 +59,8 @@ export default defineConfig([
56
59
  sourceType: 'script',
57
60
 
58
61
  parserOptions: {
59
- project: 'tsconfig.json',
62
+ project: true,
63
+ tsconfigRootDir: __dirname,
60
64
  ecmaFeatures: {
61
65
  jsx: true
62
66
  }
@@ -79,8 +83,9 @@ export default defineConfig([
79
83
  }
80
84
  },
81
85
 
82
- plugins: { sonarjs, import: importPlugin, react, 'react-hooks': reactHooks },
86
+ plugins: { sonarjs, import: importPlugin, react, 'react-hooks': reactHooks, 'pega-presentation': { rules: { 'no-pcore-pconnect-in-presentation': noPcorePconnectInPresentation } } },
83
87
  rules: {
88
+ 'pega-presentation/no-pcore-pconnect-in-presentation': 'error',
84
89
  'prettier/prettier': 'off',
85
90
  'sonarjs/cognitive-complexity': 'off',
86
91
  'sonarjs/no-identical-functions': 'off',
@@ -121,60 +126,67 @@ export default defineConfig([
121
126
  '@typescript-eslint/ban-types': 'off',
122
127
  eqeqeq: 'off',
123
128
  'no-alert': 'off',
124
- 'no-console': 'error',
129
+ 'no-console': 'off',
125
130
  'no-fallthrough': 'error',
126
131
  'no-unused-vars': 'off',
127
132
  'no-var': 'off',
133
+ 'no-undef': 'off',
128
134
  yoda: 'error',
129
135
  'no-irregular-whitespace': 'off',
130
136
  'no-empty': 'off',
131
137
  'no-new-object': 'off',
132
138
  'import/no-relative-packages': 'off',
133
139
  'import/no-mutable-exports': 'error',
134
- 'sonarjs/max-switch-cases': 'error',
135
- 'sonarjs/no-collapsible-if': 'error',
140
+ 'sonarjs/max-switch-cases': 'off',
141
+ 'sonarjs/no-collapsible-if': 'off',
136
142
  'sonarjs/no-all-duplicated-branches': 'error',
137
143
  'sonarjs/no-duplicated-branches': 'error',
138
144
  'sonarjs/no-gratuitous-expressions': 'off',
139
145
  'sonarjs/no-ignored-return': 'error',
140
146
  'sonarjs/no-small-switch': 'error',
141
- 'sonarjs/prefer-object-literal': 'error',
142
- 'sonarjs/prefer-single-boolean-return': 'error',
143
- '@typescript-eslint/no-shadow': 'error',
147
+ 'sonarjs/prefer-object-literal': 'off',
148
+ 'sonarjs/prefer-single-boolean-return': 'off',
149
+ '@typescript-eslint/no-shadow': 'off',
144
150
  'react/default-props-match-prop-types': 'error',
145
151
  'react/no-unescaped-entities': 'error',
146
152
  'react/no-unused-prop-types': 'error',
147
153
  'react/static-property-placement': 'error',
148
154
  'array-callback-return': 'error',
149
- 'func-names': 'error',
150
- 'no-case-declarations': 'error',
151
- 'no-lonely-if': 'error',
152
- 'no-nested-ternary': 'error',
153
- 'no-plusplus': 'error',
155
+ 'func-names': 'off',
156
+ 'no-case-declarations': 'off',
157
+ 'no-lonely-if': 'off',
158
+ 'no-nested-ternary': 'off',
159
+ 'no-plusplus': 'off',
154
160
  'no-restricted-globals': 'error',
155
161
  'no-restricted-properties': 'error',
156
- 'no-shadow': 'error',
157
- radix: 'error',
162
+ 'no-shadow': 'off',
163
+ radix: 'off',
158
164
  'spaced-comment': 'error',
159
165
  'import/newline-after-import': 'error',
160
166
  'sonarjs/no-nested-switch': 'error',
161
167
  '@typescript-eslint/no-array-constructor': 'error',
162
- '@typescript-eslint/no-unused-vars': 'error',
168
+ '@typescript-eslint/no-unused-vars': 'off',
163
169
  '@typescript-eslint/no-useless-constructor': 'error',
164
170
  'react/button-has-type': 'error',
165
171
  'react/jsx-curly-brace-presence': 'error',
166
172
  'react/jsx-boolean-value': 'error',
167
173
  'react/no-array-index-key': 'error',
168
174
  'class-methods-use-this': 'error',
169
- 'guard-for-in': 'error',
175
+ 'guard-for-in': 'off',
170
176
  'no-unneeded-ternary': 'error',
171
177
  'no-unused-expressions': 'error',
172
178
  'operator-assignment': 'error',
173
179
  'prefer-template': 'error',
174
- 'vars-on-top': 'error',
180
+ 'vars-on-top': 'off',
175
181
  'prefer-regex-literals': 'off',
176
182
  'no-use-before-define': 'off',
177
- '@typescript-eslint/no-use-before-define': 'error'
183
+ '@typescript-eslint/no-use-before-define': 'off',
184
+ 'sonarjs/no-duplicated-branches': 'off',
185
+ 'no-useless-escape': 'off',
186
+ 'no-redeclare': 'off',
187
+ 'no-constant-binary-expression': 'off',
188
+ 'no-constant-condition': 'off',
189
+ 'no-useless-catch': 'off',
178
190
  }
179
191
  },
180
192
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/custom-dx-components",
3
- "version": "26.1.10-alpha-0.1",
3
+ "version": "26.1.10-alpha-0.3",
4
4
  "description": "Utility for building custom UI components",
5
5
  "bin": "./bin/index.js",
6
6
  "keywords": [
@@ -12,11 +12,11 @@
12
12
  "sideEffects": false,
13
13
  "type": "module",
14
14
  "scripts": {
15
- "lint:es": "eslint .",
16
- "lint:format": "prettier -c .",
15
+ "lint:es": "eslint --color --cache --cache-location node_modules/.cache/eslint/ \"src/**\"",
16
+ "lint:format": "prettier -c \"src/**\"",
17
17
  "lint:spelling": "cspell **/*",
18
18
  "fix:es": "eslint --fix .",
19
- "fix:format": "prettier -w .",
19
+ "fix:format": "prettier -w \"src/**\"",
20
20
  "test:unit:local": "node --input-type=module --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand /tests/unit",
21
21
  "test:functional:local": "jest --runInBand /tests/functional --detectOpenHandles --coverage"
22
22
  },
@@ -24,7 +24,7 @@
24
24
  "@babel/core": "^7.28.0",
25
25
  "@babel/plugin-transform-class-properties": "^7.27.1",
26
26
  "@babel/preset-react": "^7.27.1",
27
- "@pega/auth": "^0.2.31",
27
+ "@pega/auth": "^0.2.37",
28
28
  "@pega/constellation-dx-components-build-utils": "^2.0.11",
29
29
  "@pega/inquirer-fuzzy-path": "^3.0.0",
30
30
  "ajv": "^8.17.1",
@@ -37,7 +37,7 @@
37
37
  "compression-webpack-plugin": "^11.1.0",
38
38
  "css-loader": "7.1.2",
39
39
  "css-minimizer-webpack-plugin": "^7.0.2",
40
- "eslint": "^9.31.0",
40
+ "eslint": "^9.36.0",
41
41
  "execa": "^9.6.0",
42
42
  "file-loader": "6.2.0",
43
43
  "fs-extra": "^11.3.0",
@@ -65,6 +65,7 @@
65
65
  "ts-loader": "^9.5.2",
66
66
  "typescript": "~5.8.3",
67
67
  "unarchive": "^1.1.3",
68
+ "undici": "^7.21.0",
68
69
  "url-loader": "4.1.1",
69
70
  "webpack": "5.101.0",
70
71
  "webpack-cli": "^6.0.1"
@@ -74,12 +75,23 @@
74
75
  "@pega/configs": "^0.17.0",
75
76
  "@pega/prettier-config": "^0.17.0",
76
77
  "@types/jest": "^29.5.14",
78
+ "@typescript-eslint/eslint-plugin": "^6.15.0",
79
+ "@typescript-eslint/parser": "^8.34.1",
77
80
  "babel-jest": "^29.7.0",
78
81
  "cspell": "^8.19.4",
82
+ "eslint-plugin-import": "^2.32.0",
83
+ "eslint-plugin-jest": "^27.6.2",
84
+ "eslint-plugin-jsx-a11y": "^6.8.0",
85
+ "eslint-plugin-prettier": "^5.5.4",
86
+ "eslint-plugin-react": "^7.33.2",
87
+ "eslint-plugin-react-hooks": "^4.6.0",
88
+ "eslint-plugin-sonarjs": "^0.23.0",
89
+ "eslint-plugin-storybook": "^0.6.15",
79
90
  "jest": "^29.7.0",
80
91
  "jest-environment-jsdom": "^29.7.0",
81
92
  "jest-junit": "^16.0.0",
82
93
  "prettier": "3.6.2",
83
- "ts-jest": "^29.4.0"
94
+ "ts-jest": "^29.4.0",
95
+ "typescript-eslint": "^8.44.1"
84
96
  }
85
97
  }
package/src/cli.js CHANGED
@@ -293,4 +293,4 @@ export default async (args = []) => {
293
293
  break;
294
294
  }
295
295
  }
296
- }
296
+ };
package/src/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- // cSpell:ignore words timeofday caseview casepreview objectview
1
+ // cSpell:ignore words timeofday caseview casepreview objectview wsscaseview
2
2
  export const TASKS_CONFIG_JSON_FILENAME = 'tasks.config.json';
3
3
  export const INPUT_CONFIG_JSON_FILENAME = 'input.config.json';
4
4
  export const PACKAGE_JSON_FILENAME = 'package.json';
@@ -24,7 +24,6 @@ export const TEMP_PATH = 'store/temp';
24
24
  export const COMPONENTS_CONFIG_FILE_NAME = 'componentsconfig.json';
25
25
  export const MAX_RFT_CHARS = 64;
26
26
 
27
-
28
27
  /* REST end points */
29
28
  export const PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component';
30
29
  export const LIST_COMPONENT_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/list_component';
@@ -34,12 +33,9 @@ export const INF_TOKEN_URL_V1 = 'PRRestService/oauth2/v1/token';
34
33
  export const INF_AUTHORIZE_URL_V1 = 'PRRestService/oauth2/v1/authorize';
35
34
  export const LP_TOKEN_URL = 'uas/oauth/token';
36
35
  export const LP_AUTHORIZE_URL = 'uas/oauth/authorize';
37
- export const LP_LIST_COMPONENT_SERVICE_REST_ENDPOINT =
38
- 'pegalaunchpad/c11n/v103/app/appstudiox/componentslist?field0=type&value0={type}';
39
- export const LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT =
40
- 'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
41
- export const LP_DELETE_COMPONENT_SERVICE_REST_ENDPOINT =
42
- 'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
36
+ export const LP_LIST_COMPONENT_SERVICE_REST_ENDPOINT = 'pegalaunchpad/c11n/v103/app/appstudiox/componentslist?field0=type&value0={type}';
37
+ export const LP_PUBLISH_COMPONENT_SERVICE_REST_ENDPOINT = 'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
38
+ export const LP_DELETE_COMPONENT_SERVICE_REST_ENDPOINT = 'pegalaunchpad/c11n/isolations/{isolationId}/v102/assetsUpdate';
43
39
 
44
40
  export const PUBLISH_COMPONENT_LIBRARY_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component_library';
45
41
  export const PUBLISH_COMPONENT_LIBRARY_ARCHIVE_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/publish_component_library_archive';
@@ -48,14 +44,15 @@ export const LIST_COMPONENT_LIBRARY_ARCHIVES_SERVICE_REST_ENDPOINT = 'PRRestServ
48
44
  export const DELETE_COMPONENT_LIBRARY_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/delete_component_library';
49
45
  export const COMPONENT_LIBRARY_ARCHIVE_SERVICE_REST_ENDPOINT = 'PRRestService/dev/v1/component_library_archive';
50
46
 
51
-
52
47
  export const FIELD_PATH = '/field';
53
48
  export const TEMPLATE_PATH = '/template';
54
49
  export const WIDGET_PATH = '/widget';
50
+ export const PRESENTATION_PATH = '/presentation';
55
51
 
56
52
  export const COMPONENT_PREFIX_FIELD_PATH = 'field/';
57
53
  export const COMPONENT_PREFIX_TEMPLATE_PATH = 'template/';
58
54
  export const COMPONENT_PREFIX_WIDGET_PATH = 'widget/';
55
+ export const COMPONENT_PREFIX_PRESENTATION_PATH = 'presentation/';
59
56
 
60
57
  export const BUILDER_INDEX_FILE_PATH = '../bundle/builder/index.js';
61
58
  export const BUILDER_DIR_FILE_PATH = '../bundle/builder';
@@ -80,11 +77,7 @@ export const AUTHENTICATE_DEFAULTS = {
80
77
  redirectUri: 'https://localhost:4010/'
81
78
  };
82
79
 
83
- export const SHARED_FILE_NAMES = [
84
- "suggestions-handler.ts",
85
- "PConnProps.d.ts",
86
- "create-nonce.ts"
87
- ];
80
+ export const SHARED_FILE_NAMES = ['suggestions-handler.ts', 'PConnProps.d.ts', 'create-nonce.ts'];
88
81
 
89
82
  export const AUTHENTICATE_SCHEMA = {
90
83
  serverType: [
@@ -144,6 +137,10 @@ export const COMPONENT_SCHEMA = {
144
137
  {
145
138
  name: 'Widget',
146
139
  value: 'Widget'
140
+ },
141
+ {
142
+ name: 'Presentation',
143
+ value: 'Presentation'
147
144
  }
148
145
  ],
149
146
  subtype: {
@@ -256,6 +253,16 @@ export const COMPONENT_SCHEMA = {
256
253
  name: 'PAGE & CASE',
257
254
  value: ['PAGE', 'CASE']
258
255
  }
256
+ ],
257
+ presentation: [
258
+ {
259
+ name: 'CASEVIEW',
260
+ value: 'CASEVIEW'
261
+ },
262
+ {
263
+ name: 'WSSCASEVIEW',
264
+ value: 'WSSCASEVIEW'
265
+ }
259
266
  ]
260
267
  }
261
268
  };
@@ -0,0 +1,103 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ /** Cache: component directory → parsed config.json (or null) */
5
+ const configCache = new Map();
6
+
7
+ /**
8
+ * Walks up the directory tree from `startDir` to find a `config.json` file,
9
+ * stopping at the project root (`process.cwd()`) to avoid picking up unrelated configs.
10
+ * Results are cached per directory to minimise repeated filesystem reads.
11
+ */
12
+ function findComponentConfig(startDir) {
13
+ if (configCache.has(startDir)) {
14
+ return configCache.get(startDir);
15
+ }
16
+
17
+ const projectRoot = path.resolve(process.cwd());
18
+ let dir = path.resolve(startDir);
19
+
20
+ while (dir.startsWith(projectRoot)) {
21
+ const candidate = path.join(dir, 'config.json');
22
+ if (fs.existsSync(candidate)) {
23
+ let parsed = null;
24
+ try {
25
+ parsed = JSON.parse(fs.readFileSync(candidate, 'utf8'));
26
+ } catch {
27
+ // ignore malformed config
28
+ }
29
+ configCache.set(startDir, parsed);
30
+ return parsed;
31
+ }
32
+ const parent = path.dirname(dir);
33
+ if (parent === dir) break;
34
+ dir = parent;
35
+ }
36
+
37
+ configCache.set(startDir, null);
38
+ return null;
39
+ }
40
+
41
+ /** @type {import('eslint').Rule.RuleModule} */
42
+ const rule = {
43
+ meta: {
44
+ type: 'problem',
45
+ docs: {
46
+ description: 'Disallow PCore and getPConnect usage in Presentation components',
47
+ category: 'Pega DX Components',
48
+ recommended: true
49
+ },
50
+ messages: {
51
+ noPCore:
52
+ 'PCore must not be used in Presentation components (type="Presentation" in config.json). These are presentation-only components with no platform API access.',
53
+ noGetPConnect:
54
+ 'getPConnect must not be used in Presentation components (type="Presentation" in config.json). These are presentation-only components with no platform API access.'
55
+ },
56
+ schema: []
57
+ },
58
+
59
+ create(context) {
60
+ const filename = context.filename ?? context.getFilename();
61
+ const fileDir = path.dirname(filename);
62
+ const config = findComponentConfig(fileDir);
63
+
64
+ if (!config || config.type !== 'Presentation') {
65
+ return {};
66
+ }
67
+
68
+ return {
69
+ // Flag `PCore` used as a standalone identifier (e.g. PCore.getConstants())
70
+ Identifier(node) {
71
+ if (node.name === 'PCore') {
72
+ context.report({ node, messageId: 'noPCore' });
73
+ }
74
+ },
75
+
76
+ // Flag `getPConnect` in destructuring: const { getPConnect } = props
77
+ // and as a property access: props.getPConnect()
78
+ Property(node) {
79
+ if (node.key && node.key.name === 'getPConnect') {
80
+ context.report({ node, messageId: 'noGetPConnect' });
81
+ }
82
+ },
83
+
84
+ // Flag `getPConnect` as a member access: props.getPConnect or props['getPConnect']
85
+ MemberExpression(node) {
86
+ const prop = node.property;
87
+ const isGetPConnect = node.computed ? prop.type === 'Literal' && prop.value === 'getPConnect' : prop.name === 'getPConnect';
88
+ if (isGetPConnect) {
89
+ context.report({ node, messageId: 'noGetPConnect' });
90
+ }
91
+ },
92
+
93
+ // Flag `getPConnect` called directly as a standalone function: getPConnect()
94
+ CallExpression(node) {
95
+ if (node.callee.type === 'Identifier' && node.callee.name === 'getPConnect') {
96
+ context.report({ node, messageId: 'noGetPConnect' });
97
+ }
98
+ }
99
+ };
100
+ }
101
+ };
102
+
103
+ export default rule;
@@ -1,23 +1,15 @@
1
- /* eslint-disable import/prefer-default-export */
2
1
  import { AUTHENTICATE_SCHEMA, AUTHENTICATE_DEFAULTS } from '../../constants.js';
3
2
 
4
3
  export const getAuthQuestions = async dxcbConfig => {
5
4
  const defaultPegaConfig = dxcbConfig;
6
- const aAlwaysAsk = dxcbConfig.questions_askAlways
7
- ? dxcbConfig.questions_askAlways.split(',')
8
- : [];
5
+ const aAlwaysAsk = dxcbConfig.questions_askAlways ? dxcbConfig.questions_askAlways.split(',') : [];
9
6
  const aNeverAsk = dxcbConfig.questions_askNever ? dxcbConfig.questions_askNever.split(',') : [];
10
7
  const aAskOnce = dxcbConfig.questions_askOnce ? dxcbConfig.questions_askOnce.split(',') : [];
11
- const aAskedOnce = dxcbConfig.questions_askedOnce
12
- ? dxcbConfig.questions_askedOnce.split(',')
13
- : [];
8
+ const aAskedOnce = dxcbConfig.questions_askedOnce ? dxcbConfig.questions_askedOnce.split(',') : [];
14
9
 
15
10
  // Ask if various must, never, once criteria are met
16
11
  const askThisTime = prop => {
17
- return (
18
- aAlwaysAsk.includes(prop) ||
19
- (!aNeverAsk.includes(prop) && aAskOnce.includes(prop) && !aAskedOnce.includes(prop))
20
- );
12
+ return aAlwaysAsk.includes(prop) || (!aNeverAsk.includes(prop) && aAskOnce.includes(prop) && !aAskedOnce.includes(prop));
21
13
  };
22
14
 
23
15
  const initAnswer = (prop, defValue) => {
@@ -90,9 +82,7 @@ export const getAuthQuestions = async dxcbConfig => {
90
82
  message: 'Enter OAuth 2.0 grant type',
91
83
  default: defaultPegaConfig.grantType,
92
84
  choices: answers => {
93
- return AUTHENTICATE_SCHEMA.grantType.filter(
94
- gt => !(answers.serverType === 'launchpad' && gt.value === 'passwordCreds')
95
- );
85
+ return AUTHENTICATE_SCHEMA.grantType.filter(gt => !(answers.serverType === 'launchpad' && gt.value === 'passwordCreds'));
96
86
  },
97
87
  validate: value => {
98
88
  if (value.trim()) {
@@ -116,11 +106,7 @@ export const getAuthQuestions = async dxcbConfig => {
116
106
  return 'Authentication service alias cannot be empty';
117
107
  },
118
108
  when: answers => {
119
- return (
120
- answers.serverType === 'infinity' &&
121
- answers.grantType === 'authCode' &&
122
- fnStandardWhen('authService', answers)
123
- );
109
+ return answers.serverType === 'infinity' && answers.grantType === 'authCode' && fnStandardWhen('authService', answers);
124
110
  }
125
111
  },
126
112
  {
@@ -135,11 +121,7 @@ export const getAuthQuestions = async dxcbConfig => {
135
121
  return 'Redirect URI cannot be empty';
136
122
  },
137
123
  when: answers => {
138
- return (
139
- answers.serverType === 'infinity' &&
140
- answers.grantType === 'authCode' &&
141
- fnStandardWhen('redirectUri', answers)
142
- );
124
+ return answers.serverType === 'infinity' && answers.grantType === 'authCode' && fnStandardWhen('redirectUri', answers);
143
125
  }
144
126
  },
145
127
  {
@@ -154,11 +136,7 @@ export const getAuthQuestions = async dxcbConfig => {
154
136
  return 'Username cannot be empty';
155
137
  },
156
138
  when: answers => {
157
- return (
158
- answers.serverType === 'infinity' &&
159
- answers.grantType === 'passwordCreds' &&
160
- fnStandardWhen('user', answers)
161
- );
139
+ return answers.serverType === 'infinity' && answers.grantType === 'passwordCreds' && fnStandardWhen('user', answers);
162
140
  }
163
141
  },
164
142
  {
@@ -173,12 +151,7 @@ export const getAuthQuestions = async dxcbConfig => {
173
151
  return 'Password cannot be empty';
174
152
  },
175
153
  when: answers => {
176
- return (
177
- answers.user &&
178
- answers.serverType === 'infinity' &&
179
- answers.grantType === 'passwordCreds' &&
180
- fnStandardWhen('password', answers)
181
- );
154
+ return answers.user && answers.serverType === 'infinity' && answers.grantType === 'passwordCreds' && fnStandardWhen('password', answers);
182
155
  }
183
156
  },
184
157
  {
@@ -209,8 +182,7 @@ export const getAuthQuestions = async dxcbConfig => {
209
182
  },
210
183
  when: answers => {
211
184
  return (
212
- ((answers.serverType === 'infinity' && answers.grantType !== 'authCode') ||
213
- answers.serverType === 'launchpad') &&
185
+ ((answers.serverType === 'infinity' && answers.grantType !== 'authCode') || answers.serverType === 'launchpad') &&
214
186
  fnStandardWhen('clientSecret', answers)
215
187
  );
216
188
  }