@elliemae/ds-codemods 3.60.0-next.3 → 3.60.0-next.30

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,25 @@
1
+ export const getLegacyDeprecation26dot3Questions = (originalOptions) => {
2
+ const extraOptions = [];
3
+ const { startingDirPath, gitIgnorePath } = originalOptions;
4
+ if (!startingDirPath && startingDirPath !== '') {
5
+ extraOptions.push({
6
+ type: 'input',
7
+ name: 'startingDirPath',
8
+ message: 'Please provide the project root directory (where node_modules folder lives)',
9
+ default: './',
10
+ });
11
+ }
12
+ if (!gitIgnorePath && gitIgnorePath !== '') {
13
+ extraOptions.push({
14
+ type: 'input',
15
+ name: 'gitIgnorePath',
16
+ message:
17
+ 'Please provide the path to the .gitignore file' +
18
+ '(if a non-matching path is provided, node_modules, dist and build will be ignored)',
19
+ default: './.gitignore',
20
+ });
21
+ }
22
+ // --debug is a CLI flag, not available as a question.
23
+
24
+ return extraOptions;
25
+ };
@@ -7,7 +7,7 @@ export const getPackagesInconsistenciesQuestions = (originalOptions) => {
7
7
  name: 'globPattern',
8
8
  message:
9
9
  'Please provide a comma separated list of globPatterns catching the file in which to check for inconsistencies',
10
- default: './package.json', // './packages/ds-codemods/test-ables/check-packages-inconsistencies/package.json.test',
10
+ default: './package.json', // './packages/ds-codemods/test-ables/check-packages-inconsistencies/package.json.test'
11
11
  });
12
12
  }
13
13
  if (!globPatternIgnore && globPatternIgnore !== '') {
@@ -5,6 +5,7 @@ import { checkDeprecatedPackages } from './check-deprecated-packages/index.mjs';
5
5
  import { helpMigrateToV3 } from './help-migrate-to-v3/index.mjs';
6
6
  import { deprecatedComponentsUsageReport } from './deprecated-components-usage-report/index.mjs';
7
7
  import { componentsUsageReport } from './components-usage-report/index.mjs';
8
+ import { legacyDeprecation26dot3 } from './legacy-deprecation-26-3/index.mjs';
8
9
  import { COMMANDS } from '../commands.mjs';
9
10
 
10
11
  export async function executeCommandsMap(args, options) {
@@ -33,6 +34,9 @@ export async function executeCommandsMap(args, options) {
33
34
  case COMMANDS.COMPONENT_USAGE_REPORT:
34
35
  componentsUsageReport(options);
35
36
  break;
37
+ case COMMANDS.LEGACY_DEPRECATION_26DOT3:
38
+ legacyDeprecation26dot3(options);
39
+ break;
36
40
  default:
37
41
  break;
38
42
  }
@@ -0,0 +1,52 @@
1
+ import fs from 'fs';
2
+ import fse from 'fs-extra';
3
+ import { filePathsWithGitIgnore } from '../../../utils/filepathsMatchers.mjs';
4
+ import { legacy26dot3ImportMap, executeMapReplacement } from './legacy26dot3ImportMap.mjs';
5
+ import { packageJsonReplaceLogic } from './packageJsonReplaceLogic.mjs';
6
+
7
+ /**
8
+ * generates a report of deprecated components usage
9
+ * @param {object} options - options *
10
+ * @param {string} options.startingDirPath - path to the project root directory (where node_modules folder lives)
11
+ * @param {string} options.gitIgnorePath - path to the .gitignore file
12
+ * @param {boolean} options.debug - debug flag
13
+ * @param {string} options.fileExtensions - comma separated list of file extensions to filter by
14
+ *
15
+ * @returns {void}
16
+ */
17
+ export const legacyDeprecation26dot3 = (options) => {
18
+ // 1- get all the "raw" code file paths using gitignore blacklist and file extension filter
19
+ const filesToParse = filePathsWithGitIgnore(options);
20
+ if (options.debug) console.log('legacy26dot3ImportMap :>> ', legacy26dot3ImportMap);
21
+ // 2- for each file, replace the imports from the legacy components with the new ones
22
+ filesToParse.forEach((path) => {
23
+ const fileContent = fs.readFileSync(path, {
24
+ encoding: 'utf8',
25
+ flag: 'r',
26
+ });
27
+ if (fileContent && typeof fileContent === 'string') {
28
+ const { finalString, matchesFound } = executeMapReplacement(fileContent);
29
+ const didChangeSomething = matchesFound.length > 0;
30
+ if (didChangeSomething) {
31
+ if (!options.debug) fse.outputFileSync(path, finalString);
32
+ else {
33
+ console.log(`File: ${path} - import(s) replacement(s) found!`);
34
+ console.log('matchesFound :>> ', matchesFound);
35
+ }
36
+ }
37
+ }
38
+ });
39
+ // 3- do something similar, but with opinionated "package.json" files and logic
40
+ // in particular:
41
+ // - we get the package.json files (multiple for monorepos?) and we parse them as json.
42
+ // - check the dependencies and devDependencies and peerDependencies for any legacy component
43
+ // (keyof legacy26dot3ImportMap) and replace it with the new one (value of legacy26dot3ImportMap)
44
+ const packageJsonPendingReplacements = packageJsonReplaceLogic(options);
45
+ if (options.debug) console.log('packageJsonPendingReplacements :>> ', packageJsonPendingReplacements);
46
+ else
47
+ Object.entries(packageJsonPendingReplacements).forEach(([path, newContent]) => {
48
+ fse.outputFileSync(path, newContent);
49
+ });
50
+ };
51
+
52
+ export default legacyDeprecation26dot3;
@@ -0,0 +1,191 @@
1
+ /* eslint-disable max-lines */
2
+ /*
3
+ we need an exact match of the imports, we can't do a lose match
4
+ why?
5
+ we have packages that are the old package name with a different append
6
+ E.G. @elliemae/ds-button (legacy) and @elliemae/ds-button-v2 (new)
7
+ we can't replace
8
+ @elliemae/ds-button-v2 to @elliemae/ds-legacy-button-v2
9
+ because @elliemae/ds-button is a substring of @elliemae/ds-button-v2
10
+ how do we solve this?
11
+ key: exact match of the imports
12
+ value:{
13
+ matchChange: string; // the new package name to replace with
14
+ regexp
15
+ regexp: RegExp; // new Regexp(/(['"])(${key})(['"])/)
16
+ }
17
+ this will allow regexp match and replace based on group capture, so we can keep the same quotes as the original import
18
+ E.G. we can replace
19
+ from '@elliemae/ds-button' to '@elliemae/ds-legacy-button'
20
+ but also
21
+ from "@elliemae/ds-button" to "@elliemae/ds-legacy-button"
22
+ without the risk of replacing
23
+ from '@elliemae/ds-button-v2' to '@elliemae/ds-legacy-button-v2'
24
+ */
25
+ export const legacy26dot3ImportMap = {
26
+ '@elliemae/ds-button': {
27
+ matchChange: '@elliemae/ds-legacy-button',
28
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-button)(['"])/g),
29
+ },
30
+ '@elliemae/ds-date-range-picker': {
31
+ matchChange: '@elliemae/ds-legacy-date-range-picker',
32
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-date-range-picker)(['"])/g),
33
+ },
34
+ '@elliemae/ds-header': {
35
+ matchChange: '@elliemae/ds-legacy-header',
36
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-header)(['"])/g),
37
+ },
38
+ '@elliemae/ds-number-range-field': {
39
+ matchChange: '@elliemae/ds-legacy-number-range-field',
40
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-number-range-field)(['"])/g),
41
+ },
42
+ '@elliemae/ds-slider': {
43
+ matchChange: '@elliemae/ds-legacy-slider',
44
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-slider)(['"])/g),
45
+ },
46
+ '@elliemae/ds-zipcode-search': {
47
+ matchChange: '@elliemae/ds-legacy-zipcode-search',
48
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-zipcode-search)(['"])/g),
49
+ },
50
+ '@elliemae/ds-button-group': {
51
+ matchChange: '@elliemae/ds-legacy-button-group',
52
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-button-group)(['"])/g),
53
+ },
54
+ '@elliemae/ds-date-range-selector': {
55
+ matchChange: '@elliemae/ds-legacy-date-range-selector',
56
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-date-range-selector)(['"])/g),
57
+ },
58
+ '@elliemae/ds-hidden': {
59
+ matchChange: '@elliemae/ds-legacy-hidden',
60
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-hidden)(['"])/g),
61
+ },
62
+ '@elliemae/ds-page-number': {
63
+ matchChange: '@elliemae/ds-legacy-page-number',
64
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-page-number)(['"])/g),
65
+ },
66
+ '@elliemae/ds-spinner': {
67
+ matchChange: '@elliemae/ds-legacy-spinner',
68
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-spinner)(['"])/g),
69
+ },
70
+ '@elliemae/ds-zoom': {
71
+ matchChange: '@elliemae/ds-legacy-zoom',
72
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-zoom)(['"])/g),
73
+ },
74
+ '@elliemae/ds-button-v1': {
75
+ matchChange: '@elliemae/ds-legacy-button-v1',
76
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-button-v1)(['"])/g),
77
+ },
78
+ '@elliemae/ds-date-time-recurrence-picker': {
79
+ matchChange: '@elliemae/ds-legacy-date-time-recurrence-picker',
80
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-date-time-recurrence-picker)(['"])/g),
81
+ },
82
+ '@elliemae/ds-label-value': {
83
+ matchChange: '@elliemae/ds-legacy-label-value',
84
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-label-value)(['"])/g),
85
+ },
86
+ '@elliemae/ds-pills': {
87
+ matchChange: '@elliemae/ds-legacy-pills',
88
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-pills)(['"])/g),
89
+ },
90
+ '@elliemae/ds-text-wrapper': {
91
+ matchChange: '@elliemae/ds-legacy-text-wrapper',
92
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-text-wrapper)(['"])/g),
93
+ },
94
+ '@elliemae/ds-card-array': {
95
+ matchChange: '@elliemae/ds-legacy-card-array',
96
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-card-array)(['"])/g),
97
+ },
98
+ '@elliemae/ds-dropdownmenu': {
99
+ matchChange: '@elliemae/ds-legacy-dropdownmenu',
100
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-dropdownmenu)(['"])/g),
101
+ },
102
+ '@elliemae/ds-list-section-header': {
103
+ matchChange: '@elliemae/ds-legacy-list-section-header',
104
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-list-section-header)(['"])/g),
105
+ },
106
+ '@elliemae/ds-popover': {
107
+ matchChange: '@elliemae/ds-legacy-popover',
108
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-popover)(['"])/g),
109
+ },
110
+ '@elliemae/ds-time-picker': {
111
+ matchChange: '@elliemae/ds-legacy-time-picker',
112
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-time-picker)(['"])/g),
113
+ },
114
+ '@elliemae/ds-common': {
115
+ matchChange: '@elliemae/ds-legacy-common',
116
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-common)(['"])/g),
117
+ },
118
+ '@elliemae/ds-filterbar': {
119
+ matchChange: '@elliemae/ds-legacy-filterbar',
120
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-filterbar)(['"])/g),
121
+ },
122
+ '@elliemae/ds-menu': {
123
+ matchChange: '@elliemae/ds-legacy-menu',
124
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-menu)(['"])/g),
125
+ },
126
+ '@elliemae/ds-popper': {
127
+ matchChange: '@elliemae/ds-legacy-popper',
128
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-popper)(['"])/g),
129
+ },
130
+ '@elliemae/ds-toolbar': {
131
+ matchChange: '@elliemae/ds-legacy-toolbar',
132
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-toolbar)(['"])/g),
133
+ },
134
+ '@elliemae/ds-datagrids': {
135
+ matchChange: '@elliemae/ds-legacy-datagrids',
136
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-datagrids)(['"])/g),
137
+ },
138
+ '@elliemae/ds-form': {
139
+ matchChange: '@elliemae/ds-legacy-form',
140
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-form)(['"])/g),
141
+ },
142
+ '@elliemae/ds-mini-toolbar': {
143
+ matchChange: '@elliemae/ds-legacy-mini-toolbar',
144
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-mini-toolbar)(['"])/g),
145
+ },
146
+ '@elliemae/ds-search-field': {
147
+ matchChange: '@elliemae/ds-legacy-search-field',
148
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-search-field)(['"])/g),
149
+ },
150
+ '@elliemae/ds-uploader': {
151
+ matchChange: '@elliemae/ds-legacy-uploader',
152
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-uploader)(['"])/g),
153
+ },
154
+ '@elliemae/ds-date-picker': {
155
+ matchChange: '@elliemae/ds-legacy-date-picker',
156
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-date-picker)(['"])/g),
157
+ },
158
+ '@elliemae/ds-group-box': {
159
+ matchChange: '@elliemae/ds-legacy-group-box',
160
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-group-box)(['"])/g),
161
+ },
162
+ '@elliemae/ds-modal': {
163
+ matchChange: '@elliemae/ds-legacy-modal',
164
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-modal)(['"])/g),
165
+ },
166
+ '@elliemae/ds-shuttle': {
167
+ matchChange: '@elliemae/ds-legacy-shuttle',
168
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-shuttle)(['"])/g),
169
+ },
170
+ '@elliemae/ds-wysiwygeditor': {
171
+ matchChange: '@elliemae/ds-legacy-wysiwygeditor',
172
+ regexp: new RegExp(/(from ['"])(@elliemae\/ds-wysiwygeditor)(['"])/g),
173
+ },
174
+ };
175
+
176
+ export const executeMapReplacement = (fullFileStringContent) => {
177
+ if (typeof fullFileStringContent !== 'string') {
178
+ const error = `expected string argument but received ${typeof fullFileStringContent}`;
179
+ console.error(error);
180
+ throw new Error(error);
181
+ }
182
+ let finalString = fullFileStringContent;
183
+ const matchesFound = [];
184
+ Object.entries(legacy26dot3ImportMap).forEach(([key, { matchChange, regexp }]) => {
185
+ if (regexp.test(finalString)) {
186
+ matchesFound.push(key);
187
+ finalString = finalString.replaceAll(regexp, `$1${matchChange}$3`);
188
+ }
189
+ });
190
+ return { finalString, matchesFound };
191
+ };
@@ -0,0 +1,124 @@
1
+ /* eslint-disable max-statements */
2
+ import fs from 'fs';
3
+ import { boldRedStr, yellowStr } from '../../../utils/CLI_COLORS.mjs';
4
+ import { filePathsWithGitIgnore } from '../../../utils/filepathsMatchers.mjs';
5
+ import { legacy26dot3ImportMap } from './legacy26dot3ImportMap.mjs';
6
+
7
+ /**
8
+ *
9
+ * parse a package.json, checks the dependencies(dev and peer included) for any legacy component
10
+ *
11
+ * if any legacy component is found,
12
+ * generates a new content for the file with the legacy component replaced with the new one and version set to "latest"
13
+ *
14
+ * @param {string} path - the package.json file path
15
+ * @param {object} options - options *
16
+ * @param {boolean} options.debug - debug flag
17
+ * @returns {string | -1} - the new content (json to string) if any change is needed,
18
+ * or -1 if no change is needed or in case of error
19
+ */
20
+ // eslint-disable-next-line complexity
21
+ const specificPackageJsonReplaceLogic = (path, options) => {
22
+ const fileContent = fs.readFileSync(path, {
23
+ encoding: 'utf8',
24
+ flag: 'r',
25
+ });
26
+ if (!fileContent || typeof fileContent !== 'string') {
27
+ if (options.debug) console.log(yellowStr(`Empty or invalid content in ${path}`));
28
+ return -1;
29
+ }
30
+ const parsedContent = JSON.parse(fileContent);
31
+ const newDeps = { ...parsedContent.dependencies };
32
+ let depsChanged = false;
33
+ Object.keys(parsedContent.dependencies || {}).forEach((oldPackageString) => {
34
+ if (legacy26dot3ImportMap[oldPackageString]) {
35
+ const newPackageString = legacy26dot3ImportMap[oldPackageString].matchChange;
36
+ newDeps[newPackageString] = 'latest';
37
+ delete newDeps[oldPackageString];
38
+ depsChanged = true;
39
+ }
40
+ });
41
+
42
+ const newDevDeps = { ...parsedContent.devDependencies };
43
+ let devDepsChanged = false;
44
+ Object.keys(parsedContent.devDependencies || {}).forEach((oldPackageString) => {
45
+ if (legacy26dot3ImportMap[oldPackageString]) {
46
+ const newPackageString = legacy26dot3ImportMap[oldPackageString].matchChange;
47
+ newDevDeps[newPackageString] = 'latest';
48
+ delete newDevDeps[oldPackageString];
49
+ devDepsChanged = true;
50
+ }
51
+ });
52
+ const newPeerDeps = { ...parsedContent.peerDependencies };
53
+ let peerDepsChanged = false;
54
+ Object.keys(parsedContent.peerDependencies || {}).forEach((oldPackageString) => {
55
+ if (legacy26dot3ImportMap[oldPackageString]) {
56
+ const newPackageString = legacy26dot3ImportMap[oldPackageString].matchChange;
57
+ newPeerDeps[newPackageString] = 'latest';
58
+ delete newPeerDeps[oldPackageString];
59
+ peerDepsChanged = true;
60
+ }
61
+ });
62
+ if (!depsChanged && !devDepsChanged && !peerDepsChanged) {
63
+ if (options.debug) console.log(yellowStr(`No legacy dependencies found in ${path}`));
64
+ return -1;
65
+ }
66
+ const newContent = {
67
+ ...parsedContent,
68
+ ...(depsChanged && { dependencies: newDeps }),
69
+ ...(devDepsChanged && { devDependencies: newDevDeps }),
70
+ ...(peerDepsChanged && { peerDependencies: newPeerDeps }),
71
+ };
72
+
73
+ return JSON.stringify(newContent, null, 2);
74
+ };
75
+
76
+ /**
77
+ * do something similar, but with opinionated "package.json" files and logic
78
+ *
79
+ * in particular:
80
+ * - we get the package.json files (multiple for monorepos?) and we parse them as json.
81
+ * - check the dependencies and devDependencies and peerDependencies for any legacy component
82
+ * (keyof legacy26dot3ImportMap) and replace it with the new one (value of legacy26dot3ImportMap)
83
+ * - if any change is needed, we return an object so that the caller can decide what to do with it
84
+ * (write it or just log it for the user to review)
85
+ * @param {object} options - options *
86
+ * @param {string} options.startingDirPath - path to the project root directory (where node_modules folder lives)
87
+ * @param {string} options.gitIgnorePath - path to the .gitignore file
88
+ * @param {boolean} options.debug - debug flag
89
+ * @param {string} options.fileExtensions - comma separated list of file extensions to filter by
90
+ * @returns {object} - an object with the (package.json) file path as key and the new content (json to string) as value,
91
+ * for each package.json file that needs changes
92
+ */
93
+ export const packageJsonReplaceLogic = (options) => {
94
+ // 1- get the package.json files (multiple for monorepos?) paths
95
+ const jsonFilesPaths = filePathsWithGitIgnore({ ...options, fileExtensions: '.json' });
96
+ // the above function doesn't allow for specific filename matching,
97
+ // this is a one-off right now so not extending the function
98
+ // instead we filter the results with a simple string match, to get only the package.json files paths
99
+ const packageJsonFilesPaths = jsonFilesPaths.filter((path) => path.endsWith('package.json'));
100
+ if (packageJsonFilesPaths.length === 0) {
101
+ console.log(boldRedStr('No package.json files! Please check the startingDirPath and gitIgnorePath options.'));
102
+ console.log(
103
+ yellowStr(
104
+ `To make sure migration is successful manually:
105
+ - check for any legacy components in your package.json
106
+ - replace them with the new ones.
107
+ - point them to "latest" version, the legacy library only get updated with critical security fixes and very rarely so.
108
+ - regenerate the lock file ( pnpm i --fix-lockfile or equivalent command/flow for your package manager)
109
+
110
+ The legacy components to look for are:`,
111
+ ),
112
+ );
113
+ console.log(legacy26dot3ImportMap);
114
+ return {};
115
+ }
116
+ const filesToChange = {};
117
+ // 2 - parse, check and generate new content for each package.json file
118
+ packageJsonFilesPaths.forEach((path) => {
119
+ if (options.debug) console.log('path :>> ', path);
120
+ const newContent = specificPackageJsonReplaceLogic(path, options);
121
+ if (newContent !== -1) filesToChange[path] = newContent;
122
+ });
123
+ return filesToChange;
124
+ };
@@ -7,6 +7,7 @@ export const COMMANDS = {
7
7
  HELP_MIGRATE_TO_V3: 'help-migrate-to-v3',
8
8
  DEPRECATED_PACKAGES_USAGE_REPORT: 'deprecated-components-usage-report',
9
9
  COMPONENT_USAGE_REPORT: 'components-usage-report',
10
+ LEGACY_DEPRECATION_26DOT3: 'legacy-deprecation-26dot3',
10
11
  EXIT: 'exit',
11
12
  };
12
13
 
@@ -6,7 +6,9 @@ import { getDeprecatedPackagesQuestions } from './command-arguments/promptDeprec
6
6
  import { getHelpMigrateToV3Questions } from './command-arguments/promptHelpMigrateToV3.mjs';
7
7
  import { getMissingPackagesQuestions } from './command-arguments/promptMissingPackages.mjs';
8
8
  import { getDeprecatedUsageReportQuestions } from './command-arguments/getDeprecatedUsageReportQuestions.mjs';
9
+ import { getLegacyDeprecation26dot3Questions } from './command-arguments/getLegacyDeprecation26dot3Questions.mjs';
9
10
 
11
+ // eslint-disable-next-line complexity
10
12
  async function promptForMissingScriptSpecificOptions({ originalOptions, promptOptions }) {
11
13
  const script = originalOptions.script || promptOptions.script;
12
14
  const scriptQuestions = [];
@@ -31,6 +33,9 @@ async function promptForMissingScriptSpecificOptions({ originalOptions, promptOp
31
33
  case COMMANDS.DEPRECATED_PACKAGES_USAGE_REPORT:
32
34
  scriptQuestions.push(...getDeprecatedUsageReportQuestions(originalOptions));
33
35
  break;
36
+ case COMMANDS.LEGACY_DEPRECATION_26DOT3:
37
+ scriptQuestions.push(...getLegacyDeprecation26dot3Questions(originalOptions));
38
+ break;
34
39
  default:
35
40
  break;
36
41
  }
@@ -47,7 +52,7 @@ export async function promptForMissingOptions(options) {
47
52
  const questions = [];
48
53
  if (!options.script) {
49
54
  questions.push({
50
- type: 'list',
55
+ type: 'select',
51
56
  name: 'script',
52
57
  message: 'Please choose which command to run',
53
58
  choices: COMMANDS_ARRAY,
@@ -18,7 +18,10 @@ const ig = ignore({
18
18
  * @param {string} pathString the path to convert
19
19
  * @returns {string} path with glob compatible POSIX slashes ( \ -- to --> /).
20
20
  */
21
- const generatePosixPath = (pathString) => pathString.replace(/\\/g, '/');
21
+ const generatePosixPath = (pathString) =>
22
+ pathString
23
+ .replace(/\\/g, '/') // convert backslashes to forward slashes for glob compatibility
24
+ .replace(/\/+/g, '/'); // replace multiple slashes with a single slash for consistency
22
25
 
23
26
  /**
24
27
  * prepend process.cwd() to a string and convert to POSIX (glob compatible) slashes ( \ -- to --> /).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-codemods",
3
- "version": "3.60.0-next.3",
3
+ "version": "3.60.0-next.30",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Code Mods",
6
6
  "files": [
@@ -29,6 +29,19 @@
29
29
  "reportFile": "tests.xml",
30
30
  "indent": 4
31
31
  },
32
+ "dependencies": {
33
+ "arg": "~5.0.2",
34
+ "depcheck": "~1.4.3",
35
+ "fs-extra": "~11.3.3",
36
+ "glob": "~13.0.0",
37
+ "ignore": "~7.0.5",
38
+ "inquirer": "~13.2.0",
39
+ "pacote": "~21.0.4"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "typeSafety": false
44
+ },
32
45
  "scripts": {
33
46
  "dev:install": "pnpm --filter {.}... i --no-lockfile",
34
47
  "test-codemods": "npx ./",
@@ -41,21 +54,5 @@
41
54
  "test-components-usage-report-complete-append": "npx ./ components-usage-report --outputPath=\"./test-with-org.csv\" --startingDirPath=\"../../../environments\" --gitIgnorePath=\"../../../.gitignore\" --repo=\"Dimsum2\" --org=\"ICE2\"",
42
55
  "test-help-migrate-to-v3": "npx ./ help-migrate-to-v3 --globPattern=\"test-ables/help-migrate-to-v3/**/*.js,./**/*.jsx,./**/*.ts,./**/*.tsx\" --globPatternIgnore=\"**/node_modules/**/*\"",
43
56
  "checkDeps": "exit 0 | echo"
44
- },
45
- "dependencies": {
46
- "arg": "~5.0.2",
47
- "depcheck": "~1.4.3",
48
- "fs-extra": "~11.1.1",
49
- "glob": "~10.2.5",
50
- "ignore": "^5.3.0",
51
- "inquirer": "~12.0.0",
52
- "pacote": "~20.0.0",
53
- "path": "~0.12.7",
54
- "voca": "~1.4.0"
55
- },
56
- "publishConfig": {
57
- "access": "public",
58
- "typeSafety": false
59
- },
60
- "gitHead": "2acff02dfc4ffface630b4f17f7e917c1722b9df"
61
- }
57
+ }
58
+ }