@public-ui/kolibri-cli 4.0.0-alpha.0 → 4.0.0-alpha.2

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 (49) hide show
  1. package/README.md +61 -0
  2. package/dist/generate-scss/index.js +18 -0
  3. package/dist/index.js +5 -5
  4. package/dist/info/index.js +17 -4
  5. package/dist/migrate/index.js +17 -2
  6. package/dist/migrate/runner/abstract-task.js +8 -2
  7. package/dist/migrate/runner/task-runner.js +18 -19
  8. package/dist/migrate/runner/tasks/common/ExecTask.js +1 -0
  9. package/dist/migrate/runner/tasks/common/GenericRenamePropertyTask.js +4 -0
  10. package/dist/migrate/runner/tasks/common/GenericRenameSlotNameTask.js +5 -0
  11. package/dist/migrate/runner/tasks/common/GenericRenameTagNameTask.js +5 -2
  12. package/dist/migrate/runner/tasks/common/GenericUpdatePropertyValueTask.js +70 -0
  13. package/dist/migrate/runner/tasks/common/GitIgnoreAddRuleTask.js +1 -0
  14. package/dist/migrate/runner/tasks/common/HandleDependencyTask.js +9 -7
  15. package/dist/migrate/runner/tasks/common/JsonTask.js +2 -1
  16. package/dist/migrate/runner/tasks/common/LabelExpertSlot.js +7 -0
  17. package/dist/migrate/runner/tasks/common/MergeHtmlTask.js +3 -0
  18. package/dist/migrate/runner/tasks/common/NpmRcAddRuleTask.js +1 -0
  19. package/dist/migrate/runner/tasks/common/RefactorPropertyErrorToMsg.js +59 -0
  20. package/dist/migrate/runner/tasks/common/RefactorPropertyIconAlign.js +4 -3
  21. package/dist/migrate/runner/tasks/common/RefactorPropertyLabelReplaceFalse.js +2 -2
  22. package/dist/migrate/runner/tasks/common/RemoveMsgPropsTask.js +54 -0
  23. package/dist/migrate/runner/tasks/common/RemovePropertyNameTask.js +6 -0
  24. package/dist/migrate/runner/tasks/common/RenamePropertyNameTask.js +1 -2
  25. package/dist/migrate/runner/tasks/common/RenameTagNameTask.js +1 -2
  26. package/dist/migrate/runner/tasks/common/ScssAddSelectorTask.js +203 -0
  27. package/dist/migrate/runner/tasks/common/ScssRemoveSelectorTask.js +275 -0
  28. package/dist/migrate/runner/tasks/common/ScssRenameBlockTask.js +43 -0
  29. package/dist/migrate/runner/tasks/common/ScssRenameElementTask.js +48 -0
  30. package/dist/migrate/runner/tasks/common/ScssRenameModifierTask.js +48 -0
  31. package/dist/migrate/runner/tasks/common/ScssUpdateTokenTask.js +51 -0
  32. package/dist/migrate/runner/tasks/common/TsConfigReconfigureTask.js +3 -1
  33. package/dist/migrate/runner/tasks/common/UpdatePropertyValueTask.js +14 -0
  34. package/dist/migrate/runner/tasks/common/VsCodeSettingsReconfigureTask.js +3 -1
  35. package/dist/migrate/runner/tasks/v3/abbr.js +5 -0
  36. package/dist/migrate/runner/tasks/v3/all-input.js +27 -0
  37. package/dist/migrate/runner/tasks/v3/index.js +17 -0
  38. package/dist/migrate/runner/tasks/v3/input-file.js +5 -0
  39. package/dist/migrate/runner/tasks/v3/modal.js +5 -0
  40. package/dist/migrate/runner/tasks/v3/textarea.js +6 -0
  41. package/dist/migrate/runner/tasks/v3/toaster.js +34 -0
  42. package/dist/migrate/runner/tasks/v4/id.js +26 -0
  43. package/dist/migrate/runner/tasks/v4/index.js +12 -0
  44. package/dist/migrate/runner/tasks/v4/msg.js +5 -0
  45. package/dist/migrate/runner/tasks/v4/toast.js +56 -0
  46. package/dist/migrate/runner/tasks/v4/toaster.js +68 -0
  47. package/dist/migrate/shares/reuse.js +40 -0
  48. package/dist/types.js +5 -2
  49. package/package.json +27 -19
package/README.md CHANGED
@@ -1,8 +1,19 @@
1
1
  # KoliBri - CLI-Tools
2
2
 
3
+ Command line utilities to help maintain and migrate KoliBri projects.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@public-ui/kolibri-cli)](https://www.npmjs.com/package/@public-ui/components)
6
+ [![license](https://img.shields.io/npm/l/@public-ui/kolibri-cli)](https://github.com/public-ui/kolibri/blob/main/LICENSE)
7
+ [![downloads](https://img.shields.io/npm/dt/@public-ui/kolibri-cli)](https://www.npmjs.com/package/@public-ui/kolibri-cli)
8
+ [![issues](https://img.shields.io/github/issues/public-ui/kolibri)](https://github.com/public-ui/kolibri/issues)
9
+ [![pull requests](https://img.shields.io/github/issues-pr/public-ui/kolibri)](https://github.com/public-ui/kolibri/pulls)
10
+ [![size](https://img.shields.io/bundlephobia/min/@public-ui/kolibri-cli)](https://bundlephobia.com/result?p=@public-ui/kolibri-cli)
11
+ ![contributors](https://img.shields.io/github/contributors/public-ui/kolibri)
12
+
3
13
  ## Motivation
4
14
 
5
15
  The `KoliBri` CLI-Tools are a collection of tools to support the development with `KoliBri` components.
16
+ They also help migrating projects when new components or design tokens are introduced.
6
17
 
7
18
  ## Installation
8
19
 
@@ -14,6 +25,8 @@ pnpm i -g @public-ui/kolibri-cli
14
25
  yarn add -g @public-ui/kolibri-cli
15
26
  ```
16
27
 
28
+ > **Important:** Install exactly the CLI version you want to upgrade to. The migration tool compares your locally installed `@public-ui/components` version with the CLI version to decide which migration tasks must run and in which order.
29
+
17
30
  ## Usage
18
31
 
19
32
  The `KoliBri` CLI is intended to be executed in your project root directory. Use the `kolibri` command to start the CLI.
@@ -45,6 +58,7 @@ Commands:
45
58
  ```
46
59
 
47
60
  ### Info
61
+
48
62
  With the `info` command you can show the current system and KoliBri package information.
49
63
 
50
64
  This command is mainly needed for our bug issue templates.
@@ -77,6 +91,53 @@ Actually the following migration tasks from version 1 to version 2 are available
77
91
  - Detection of `_iconOnly` in TSX is not stable ([#5404](https://github.com/public-ui/kolibri/issues/5404)) ⏰
78
92
  - Handle the remove `@public-ui/core` package ([#???](https://github.com/public-ui/kolibri/issues/????)) ⏰
79
93
 
94
+ #### Theme Migration
95
+
96
+ The CLI also supports migrating KoliBri themes alongside component updates to ensure theme packages remain synchronized with breaking changes in the component library.
97
+
98
+ ##### Goal
99
+
100
+ Synchronies breaking changes in components with the styling of each theme package so that upgrades require minimal manual work.
101
+
102
+ ##### Requirements
103
+
104
+ - Components and themes follow the BEM naming convention via `typed-bem`.
105
+ - Each theme lives under `packages/themes` and keeps its SCSS sources in `src/`.
106
+ - The CLI migration tool can read and modify `.scss` files.
107
+
108
+ ##### Concept
109
+
110
+ 1. **Central BEM schemas**
111
+ - Every component exports its BEM schema. These schemas are used by the CLI to generate SCSS files and by themes to reference selectors.
112
+ - When a selector changes, the same schema information allows the migration to update all theme packages consistently.
113
+
114
+ 2. **SCSS migration tasks**
115
+ The CLI runner is extended with task types operating on SCSS. They behave like the existing property tasks and are idempotent.
116
+ - `RenameBlockTask` – rename a block selector everywhere in a theme.
117
+ - `RenameElementTask` – rename an element within a block.
118
+ - `RenameModifierTask` – rename or replace a modifier.
119
+ - `AddSelectorTask` and `RemoveSelectorTask` – insert or remove entire rule sets.
120
+ - `UpdateTokenTask` – adjust variable names or values when tokens change.
121
+ - `MoveRulesTask` – move declarations from one selector to another if the DOM structure changes.
122
+
123
+ Tasks scan the SCSS with regular expressions or an AST parser. If a pattern is missing the task logs a warning instead of failing.
124
+
125
+ 3. **Safe execution**
126
+ - Migrations abort when uncommitted changes are detected unless `--ignore-uncommitted-changes` is specified.
127
+ - Each task logs the files it touched. After completion Prettier can format them automatically.
128
+ - Because tasks are idempotent, rerunning the migration produces no new changes. To undo a run, reset the Git state.
129
+
130
+ ##### Theme Migration Workflow Example
131
+
132
+ ```bash
133
+ pnpm i -g @public-ui/kolibri-cli@2 # install the CLI matching the next version
134
+ kolibri migrate path/to/project # run all tasks for the upgrade
135
+ pnpm format # format changed files
136
+ git diff # review results and commit
137
+ ```
138
+
139
+ Using these tasks, theme packages remain aligned with component updates. Future breaking changes can be scripted and applied via the CLI so that projects can upgrade in a controlled and reproducible way.
140
+
80
141
  #### How does it work?
81
142
 
82
143
  1. The migration command will check your project for clear `git history` and the `installed version` of `KoliBri`. Now it loads all available migration tasks.
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const components_1 = require("@public-ui/components");
5
+ const scss_1 = require("typed-bem/scss");
6
+ /**
7
+ * This function is used to register the scss generator command.
8
+ * @param {Command} program The program object to register the command
9
+ */
10
+ function default_1(program) {
11
+ program
12
+ .command('generate-scss')
13
+ .description('Generate SCSS files with BEM selectors for KoliBri components (experimental).')
14
+ .action(() => {
15
+ (0, scss_1.generateBemScssFile)(components_1.BEM_ALERT, 'alert');
16
+ (0, scss_1.generateBemScssFile)(components_1.BEM_ICON, 'icon');
17
+ });
18
+ }
package/dist/index.js CHANGED
@@ -6,24 +6,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const commander_1 = require("commander");
8
8
  const gradient_string_1 = __importDefault(require("gradient-string"));
9
+ const generate_scss_1 = __importDefault(require("./generate-scss"));
9
10
  const info_1 = __importDefault(require("./info"));
10
11
  const migrate_1 = __importDefault(require("./migrate"));
11
12
  const reuse_1 = require("./migrate/shares/reuse");
12
13
  const versionOfPublicUiKoliBriCli = (0, reuse_1.getVersionOfPublicUiKoliBriCli)();
13
- const banner = gradient_string_1.default.atlas.multiline(`
14
+ const banner = (0, gradient_string_1.default)(['red', 'green'], { interpolation: 'hsv', hsvSpin: 'long' }).multiline(`
14
15
  ,--. ,--. ,--. ,--. ,-----. ,--.
15
16
  | .' / ,---. | | \`--' | |) /_ ,--.--. \`--'
16
17
  | . ' | .-. | | | ,--. | .-. \\ | .--' ,--.
17
18
  | |\\ \\ | '-' | | | | | | '--' / | | | |
18
19
  \`--' \`--´ \`---´ \`--' \`--' \`------´ \`--' \`--'
19
20
  🚹 The accessible HTML-Standard | 👉 https://public-ui.github.io | ${versionOfPublicUiKoliBriCli}
20
- `, {
21
- interpolation: 'hsv',
22
- });
21
+ `);
23
22
  console.log(banner);
24
23
  const program = new commander_1.Command();
25
24
  program.name('kolibri').description('CLI for executing some helpful commands for KoliBri projects.').version(versionOfPublicUiKoliBriCli);
26
25
  // Add commands
26
+ (0, generate_scss_1.default)(program);
27
27
  (0, info_1.default)(program);
28
28
  (0, migrate_1.default)(program);
29
- program.parse();
29
+ void program.parseAsync();
@@ -11,9 +11,22 @@ const fs_1 = __importDefault(require("fs"));
11
11
  // Function to get the binary version
12
12
  const getBinaryVersion = (command) => {
13
13
  try {
14
+ // For yarn, use a temporary directory to prevent package.json modification
15
+ // Yarn with Corepack automatically adds packageManager field when executed
16
+ if (command === 'yarn') {
17
+ const originalCwd = process.cwd();
18
+ const tmpDir = os_1.default.tmpdir();
19
+ process.chdir(tmpDir);
20
+ try {
21
+ return (0, child_process_1.execSync)(`${command} --version`, { encoding: 'utf8' }).trim();
22
+ }
23
+ finally {
24
+ process.chdir(originalCwd);
25
+ }
26
+ }
14
27
  return (0, child_process_1.execSync)(`${command} --version`, { encoding: 'utf8' }).trim();
15
28
  }
16
- catch (_a) {
29
+ catch {
17
30
  return 'N/A';
18
31
  }
19
32
  };
@@ -36,16 +49,16 @@ const getRelevantPackagesInfo = () => {
36
49
  const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
37
50
  const packagePattern = /^@public-ui\//;
38
51
  const packagesInfo = {};
39
- const allDependencies = Object.assign(Object.assign({}, packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies), packageJson === null || packageJson === void 0 ? void 0 : packageJson.devDependencies);
52
+ const allDependencies = { ...packageJson?.dependencies, ...packageJson?.devDependencies };
40
53
  Object.keys(allDependencies).forEach((pkg) => {
41
54
  if (packagePattern.test(pkg)) {
42
- packagesInfo[pkg] = allDependencies === null || allDependencies === void 0 ? void 0 : allDependencies[pkg];
55
+ packagesInfo[pkg] = allDependencies?.[pkg];
43
56
  }
44
57
  });
45
58
  // Add specific packages not matching the pattern
46
59
  const additionalPackages = ['react', 'react-dom', 'typescript'];
47
60
  additionalPackages.forEach((pkg) => {
48
- packagesInfo[pkg] = (allDependencies === null || allDependencies === void 0 ? void 0 : allDependencies[pkg]) || 'N/A';
61
+ packagesInfo[pkg] = allDependencies?.[pkg] || 'N/A';
49
62
  });
50
63
  return packagesInfo;
51
64
  };
@@ -16,6 +16,8 @@ const tasks_1 = require("./runner/tasks");
16
16
  const test_1 = require("./runner/tasks/test");
17
17
  const v1_1 = require("./runner/tasks/v1");
18
18
  const v2_1 = require("./runner/tasks/v2");
19
+ const v3_1 = require("./runner/tasks/v3");
20
+ const v4_1 = require("./runner/tasks/v4");
19
21
  const assets_1 = require("./runner/tasks/v1/assets");
20
22
  const reuse_1 = require("./shares/reuse");
21
23
  const types_1 = require("./types");
@@ -61,6 +63,12 @@ Current version of @public-ui/*: ${options.overwriteCurrentVersion}
61
63
  Target version of @public-ui/*: ${options.overwriteTargetVersion}
62
64
  Source folder to migrate: ${baseDir}
63
65
  `);
66
+ if (!fs_1.default.existsSync(baseDir)) {
67
+ throw (0, reuse_1.logAndCreateError)(`The specified source folder "${baseDir}" does not exist or is inaccessible. Please check the path and try again.`);
68
+ }
69
+ if (!(0, reuse_1.hasKoliBriTags)(baseDir)) {
70
+ console.log(chalk_1.default.yellow(`No KoliBri components (web or React) found under "${baseDir}". Check the path or your task configuration.`));
71
+ }
64
72
  if (!options.ignoreGreaterVersion && semver_1.default.lt(options.overwriteTargetVersion, options.overwriteCurrentVersion)) {
65
73
  throw (0, reuse_1.logAndCreateError)('Your current version of @public-ui/components is greater than the version of @public-ui/kolibri-cli. Please update @public-ui/kolibri-cli or force the migration with --ignore-greater-version.');
66
74
  }
@@ -78,6 +86,8 @@ Source folder to migrate: ${baseDir}
78
86
  runner.registerTasks(tasks_1.commonTasks);
79
87
  runner.registerTasks(v1_1.v1Tasks);
80
88
  runner.registerTasks(v2_1.v2Tasks);
89
+ runner.registerTasks(v3_1.v3Tasks);
90
+ runner.registerTasks(v4_1.v4Tasks);
81
91
  runner.registerTasks((0, assets_1.getAssetTasks)(baseDir));
82
92
  if (options.testTasks) {
83
93
  runner.registerTasks(test_1.testTasks);
@@ -143,14 +153,16 @@ Source folder to migrate: ${baseDir}
143
153
  * Prints the status of the task runner and the modified files.
144
154
  */
145
155
  function finish() {
146
- var _a, _b;
147
156
  console.log(`
148
157
  Status of all executed Tasks:`);
149
158
  const status = runner.getStatus(true);
150
159
  // Merge config with current config of Runner
151
160
  config = {
152
161
  migrate: {
153
- tasks: Object.assign(Object.assign({}, (_a = status.config.migrate) === null || _a === void 0 ? void 0 : _a.tasks), (_b = config.migrate) === null || _b === void 0 ? void 0 : _b.tasks),
162
+ tasks: {
163
+ ...status.config.migrate?.tasks,
164
+ ...config.migrate?.tasks,
165
+ },
154
166
  },
155
167
  };
156
168
  fs_1.default.writeFileSync(configFile, JSON.stringify(config, null, 2));
@@ -159,6 +171,9 @@ Modified files: ${reuse_1.MODIFIED_FILES.size}`);
159
171
  reuse_1.MODIFIED_FILES.forEach((file) => {
160
172
  console.log(`- ${file}`);
161
173
  });
174
+ if (reuse_1.MODIFIED_FILES.size === 0) {
175
+ console.log(chalk_1.default.yellow(`No files were modified. Verify the folder "${baseDir}" or check your .kolibri.config.json tasks.`));
176
+ }
162
177
  if (reuse_1.MODIFIED_FILES.size > 0 && options.format) {
163
178
  console.log(`
164
179
  We try to format the modified files with prettier...`);
@@ -8,13 +8,20 @@ const semver_1 = __importDefault(require("semver"));
8
8
  const types_1 = require("../../types");
9
9
  const reuse_1 = require("../shares/reuse");
10
10
  class AbstractTask {
11
+ identifier;
12
+ title;
13
+ extensions;
14
+ versionRange;
15
+ taskDependencies;
16
+ status = 'pending';
17
+ static instances = new Map();
18
+ description;
11
19
  constructor(identifier, title, extensions, versionRange, taskDependencies = [], options = {}) {
12
20
  this.identifier = identifier;
13
21
  this.title = title;
14
22
  this.extensions = extensions;
15
23
  this.versionRange = versionRange;
16
24
  this.taskDependencies = taskDependencies;
17
- this.status = 'pending';
18
25
  this.description = options.description;
19
26
  this.extensions = this.extensions.filter((ext) => types_1.FILE_EXTENSIONS.includes(ext));
20
27
  if (!semver_1.default.validRange(this.versionRange)) {
@@ -44,4 +51,3 @@ class AbstractTask {
44
51
  }
45
52
  }
46
53
  exports.AbstractTask = AbstractTask;
47
- AbstractTask.instances = new Map();
@@ -11,20 +11,20 @@ const semver_1 = __importDefault(require("semver"));
11
11
  const reuse_1 = require("../shares/reuse");
12
12
  const MIN_VERSION_OF_PUBLIC_UI = '1.4.2';
13
13
  class TaskRunner {
14
+ tasks = new Map();
15
+ baseDir = '/';
16
+ cliVersion = '0.0.0';
17
+ projectVersion = '0.0.0';
18
+ config = {
19
+ migrate: {
20
+ tasks: {},
21
+ },
22
+ };
14
23
  constructor(baseDir, cliVersion, projectVersion, config) {
15
- this.tasks = new Map();
16
- this.baseDir = '/';
17
- this.cliVersion = '0.0.0';
18
- this.projectVersion = '0.0.0';
19
- this.config = {
20
- migrate: {
21
- tasks: {},
22
- },
23
- };
24
24
  this.setBaseDir(baseDir);
25
25
  this.setCliVersion(cliVersion);
26
26
  this.setProjectVersion(projectVersion);
27
- this.setConfig(Object.assign({}, config)); // clone config
27
+ this.setConfig({ ...config }); // clone config
28
28
  }
29
29
  setBaseDir(baseDir) {
30
30
  if (!fs_1.default.existsSync(path_1.default.resolve(process.cwd(), baseDir))) {
@@ -47,9 +47,11 @@ class TaskRunner {
47
47
  }
48
48
  }
49
49
  setConfig(config) {
50
- var _a, _b;
51
- if ((_a = config.migrate) === null || _a === void 0 ? void 0 : _a.tasks) {
52
- this.config.migrate.tasks = Object.assign(Object.assign({}, this.config.migrate.tasks), (_b = config.migrate) === null || _b === void 0 ? void 0 : _b.tasks);
50
+ if (config.migrate?.tasks) {
51
+ this.config.migrate.tasks = {
52
+ ...this.config.migrate.tasks,
53
+ ...config.migrate?.tasks,
54
+ };
53
55
  }
54
56
  }
55
57
  registerTasks(tasks) {
@@ -79,8 +81,7 @@ class TaskRunner {
79
81
  this.registerTasks([task]);
80
82
  }
81
83
  runTask(task) {
82
- var _a;
83
- if (((_a = this.config.migrate) === null || _a === void 0 ? void 0 : _a.tasks[task.getIdentifier()]) === false) {
84
+ if (this.config.migrate?.tasks[task.getIdentifier()] === false) {
84
85
  task.setStatus('skipped');
85
86
  }
86
87
  else {
@@ -112,18 +113,16 @@ class TaskRunner {
112
113
  });
113
114
  }
114
115
  getPendingMinVersion() {
115
- var _a;
116
116
  let version = this.cliVersion;
117
117
  this.tasks.forEach((task) => {
118
- var _a, _b;
119
118
  if (task.getStatus() === 'pending') {
120
- const minVersion = (_b = (_a = semver_1.default.minVersion(task.getVersionRange())) === null || _a === void 0 ? void 0 : _a.raw) !== null && _b !== void 0 ? _b : this.cliVersion;
119
+ const minVersion = semver_1.default.minVersion(task.getVersionRange())?.raw ?? this.cliVersion;
121
120
  if (semver_1.default.gt(version, minVersion)) {
122
121
  version = minVersion;
123
122
  }
124
123
  }
125
124
  });
126
- return (_a = semver_1.default.maxSatisfying([version], `>=${MIN_VERSION_OF_PUBLIC_UI}`)) !== null && _a !== void 0 ? _a : MIN_VERSION_OF_PUBLIC_UI;
125
+ return semver_1.default.maxSatisfying([version], `>=${MIN_VERSION_OF_PUBLIC_UI}`) ?? MIN_VERSION_OF_PUBLIC_UI;
127
126
  }
128
127
  getStatus(outline = false) {
129
128
  let done = 0;
@@ -4,6 +4,7 @@ exports.ExecTask = void 0;
4
4
  const child_process_1 = require("child_process");
5
5
  const abstract_task_1 = require("../../abstract-task");
6
6
  class ExecTask extends abstract_task_1.AbstractTask {
7
+ command;
7
8
  constructor(identifier, title, command, versionRange, dependentTasks, options) {
8
9
  super(identifier, title, [], versionRange, dependentTasks, options);
9
10
  this.command = command;
@@ -11,6 +11,10 @@ const abstract_task_1 = require("../../abstract-task");
11
11
  const DATA_REMOVED_REGEXP = /DataRemoved_/gi; // not /DataRemoved-_/g
12
12
  const DATA_REMOVEDS_REGEXP = /(data-removed-){2,}/g;
13
13
  class GenericRenamePropertyTask extends abstract_task_1.AbstractTask {
14
+ newProperty;
15
+ componentRegExp;
16
+ customElementRegExp;
17
+ newPropertyInCamelCase;
14
18
  constructor(identifier, description, tag, oldProperty, newProperty, versionRange, dependentTasks = [], options = {}) {
15
19
  super(identifier, description, types_1.MARKUP_EXTENSIONS, versionRange, dependentTasks, options);
16
20
  this.newProperty = newProperty;
@@ -9,6 +9,11 @@ const types_1 = require("../../../../types");
9
9
  const reuse_1 = require("../../../shares/reuse");
10
10
  const abstract_task_1 = require("../../abstract-task");
11
11
  class GenericRenameSlotNameTask extends abstract_task_1.AbstractTask {
12
+ newSlotName;
13
+ slotAttributeName;
14
+ regExpCurlyBrackets;
15
+ regExpQuotationMarks;
16
+ regExpCurlyBracketsAndQuotationMarks;
12
17
  constructor(identifier, description, tag, oldSlotName, newSlotName, slotAttributeName, versionRange, dependentTasks, options) {
13
18
  super(identifier, description, types_1.MARKUP_EXTENSIONS, versionRange, dependentTasks, options);
14
19
  this.newSlotName = newSlotName;
@@ -9,6 +9,11 @@ const types_1 = require("../../../../types");
9
9
  const reuse_1 = require("../../../shares/reuse");
10
10
  const abstract_task_1 = require("../../abstract-task");
11
11
  class GenericRenameTagNameTask extends abstract_task_1.AbstractTask {
12
+ newTagName;
13
+ componentRegExp;
14
+ componentImportRegExp;
15
+ customElementRegExp;
16
+ newTagNameInCamelCase;
12
17
  constructor(identifier, description, oldTagName, newTagName, versionRange, dependentTasks = [], options = {}) {
13
18
  super(identifier, description, types_1.MARKUP_EXTENSIONS, versionRange, dependentTasks, options);
14
19
  this.newTagName = newTagName;
@@ -30,7 +35,6 @@ class GenericRenameTagNameTask extends abstract_task_1.AbstractTask {
30
35
  transpileComponentFileRename(baseDir) {
31
36
  (0, reuse_1.filterFilesByExt)(baseDir, types_1.COMPONENT_FILE_EXTENSIONS).forEach((file) => {
32
37
  const content = fs_1.default.readFileSync(file, 'utf8');
33
- console.log('CONTENT: ', content);
34
38
  const newContent = content
35
39
  // Replacements
36
40
  .replace(this.componentRegExp, `$1${this.newTagNameInCamelCase}$2`)
@@ -39,7 +43,6 @@ class GenericRenameTagNameTask extends abstract_task_1.AbstractTask {
39
43
  reuse_1.MODIFIED_FILES.add(file);
40
44
  fs_1.default.writeFileSync(file, newContent);
41
45
  }
42
- console.log('NEW CONTENT: ', newContent);
43
46
  });
44
47
  }
45
48
  transpileCustomElementFileRename(baseDir) {
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GenericUpdatePropertyValueTask = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const types_1 = require("../../../../types");
9
+ const reuse_1 = require("../../../shares/reuse");
10
+ const abstract_task_1 = require("../../abstract-task");
11
+ class GenericUpdatePropertyValueTask extends abstract_task_1.AbstractTask {
12
+ oldValue;
13
+ newValue;
14
+ componentRegExp;
15
+ customElementRegExp;
16
+ constructor(identifier, description, tag, property, oldValue, newValue, versionRange, dependentTasks = [], options = {}) {
17
+ super(identifier, description, types_1.MARKUP_EXTENSIONS, versionRange, dependentTasks, options);
18
+ this.oldValue = oldValue;
19
+ this.newValue = newValue;
20
+ if (!reuse_1.isTagKebabCaseRegExp.test(tag)) {
21
+ throw (0, reuse_1.logAndCreateError)(`Tag "${tag}" is not in kebab case.`);
22
+ }
23
+ if (!reuse_1.isPropertyKebabCaseRegExp.test(property)) {
24
+ throw (0, reuse_1.logAndCreateError)(`Property "${property}" is not in kebab case.`);
25
+ }
26
+ const propertyInCamelCase = (0, reuse_1.kebabToCamelCase)(property);
27
+ // Use propertyInCamelCase for Angular components
28
+ this.componentRegExp = new RegExp(`<${(0, reuse_1.kebabToCapitalCase)(tag)}[^>]+${propertyInCamelCase}=['"]${oldValue}['"]`, 'g');
29
+ // Use original property name for custom elements
30
+ this.customElementRegExp = new RegExp(`<${tag}[^>]+${property}=['"]${oldValue}['"]`, 'g');
31
+ }
32
+ run(baseDir) {
33
+ this.transpileComponentFileUpdate(baseDir);
34
+ this.transpileCustomElementFileUpdate(baseDir);
35
+ }
36
+ transpileComponentFileUpdate(baseDir) {
37
+ (0, reuse_1.filterFilesByExt)(baseDir, types_1.COMPONENT_FILE_EXTENSIONS).forEach((file) => {
38
+ const content = fs_1.default.readFileSync(file, 'utf8');
39
+ const newContent = updateAttributeValue(content, this.componentRegExp, this.oldValue, this.newValue);
40
+ if (content !== newContent) {
41
+ reuse_1.MODIFIED_FILES.add(file);
42
+ fs_1.default.writeFileSync(file, newContent);
43
+ }
44
+ });
45
+ }
46
+ transpileCustomElementFileUpdate(baseDir) {
47
+ (0, reuse_1.filterFilesByExt)(baseDir, types_1.CUSTOM_ELEMENT_FILE_EXTENSIONS).forEach((file) => {
48
+ const content = fs_1.default.readFileSync(file, 'utf8');
49
+ const newContent = updateAttributeValue(content, this.customElementRegExp, this.oldValue, this.newValue);
50
+ if (content !== newContent) {
51
+ reuse_1.MODIFIED_FILES.add(file);
52
+ fs_1.default.writeFileSync(file, newContent);
53
+ }
54
+ });
55
+ }
56
+ }
57
+ exports.GenericUpdatePropertyValueTask = GenericUpdatePropertyValueTask;
58
+ // Helper function to update attribute values in HTML strings
59
+ /**
60
+ *
61
+ * @param htmlString
62
+ * @param tagRegExp
63
+ * @param oldValue
64
+ * @param newValue
65
+ */
66
+ function updateAttributeValue(htmlString, tagRegExp, oldValue, newValue) {
67
+ return htmlString.replace(tagRegExp, (match) => {
68
+ return match.replace(`="${oldValue}"`, `="${newValue}"`).replace(`='${oldValue}'`, `='${newValue}'`);
69
+ });
70
+ }
@@ -9,6 +9,7 @@ const path_1 = __importDefault(require("path"));
9
9
  const reuse_1 = require("../../../shares/reuse");
10
10
  const abstract_task_1 = require("../../abstract-task");
11
11
  class GitIgnoreAddRuleTask extends abstract_task_1.AbstractTask {
12
+ rule;
12
13
  constructor(identifier, rule, versionRange, dependentTasks = [], options = {}) {
13
14
  super(identifier, `Add the rule "${rule}" to the .gitignore of your project.`, [], versionRange, dependentTasks, options);
14
15
  this.rule = rule;
@@ -5,6 +5,9 @@ const child_process_1 = require("child_process");
5
5
  const abstract_task_1 = require("../../abstract-task");
6
6
  const reuse_1 = require("../../../shares/reuse");
7
7
  class HandleDependencyTask extends abstract_task_1.AbstractTask {
8
+ command;
9
+ dependencies;
10
+ devDependencies;
8
11
  constructor(identifier, title, command, dependencies, // Map<string, string | null>
9
12
  devDependencies, // Map<string, string | null>
10
13
  versionRange, dependentTasks, options) {
@@ -14,18 +17,17 @@ class HandleDependencyTask extends abstract_task_1.AbstractTask {
14
17
  this.devDependencies = devDependencies;
15
18
  }
16
19
  static getInstance(command, dependencies, devDependencies, versionRange, dependentTasks = [], options = {}) {
17
- const identifier = `${command}-${Object.keys(dependencies !== null && dependencies !== void 0 ? dependencies : {}).join(',')}-${Object.keys(devDependencies !== null && devDependencies !== void 0 ? devDependencies : {}).join(',')}`;
18
- const title = `${command === 'add' ? 'Add' : command === 'install' ? 'Install' : 'Remove'} dependency "${Object.keys(dependencies !== null && dependencies !== void 0 ? dependencies : {}).join(', ')}" and devDependency "${Object.keys(devDependencies !== null && devDependencies !== void 0 ? devDependencies : {}).join(', ')}".`;
20
+ const identifier = `${command}-${Object.keys(dependencies ?? {}).join(',')}-${Object.keys(devDependencies ?? {}).join(',')}`;
21
+ const title = `${command === 'add' ? 'Add' : command === 'install' ? 'Install' : 'Remove'} dependency "${Object.keys(dependencies ?? {}).join(', ')}" and devDependency "${Object.keys(devDependencies ?? {}).join(', ')}".`;
19
22
  if (!this.instances.has(identifier)) {
20
23
  this.instances.set(identifier, new HandleDependencyTask(identifier, title, command, dependencies, devDependencies, versionRange, dependentTasks, options));
21
24
  }
22
25
  return this.instances.get(identifier);
23
26
  }
24
27
  run() {
25
- var _a, _b, _c, _d;
26
- if (Object.keys((_a = this.dependencies) !== null && _a !== void 0 ? _a : {}).length > 0) {
28
+ if (Object.keys(this.dependencies ?? {}).length > 0) {
27
29
  let command = `${(0, reuse_1.getPackageManagerCommand)(this.command)}`;
28
- Object.keys((_b = this.dependencies) !== null && _b !== void 0 ? _b : {}).forEach((dependency) => {
30
+ Object.keys(this.dependencies ?? {}).forEach((dependency) => {
29
31
  command += ` ${dependency}@${this.dependencies[dependency]}`;
30
32
  });
31
33
  try {
@@ -37,9 +39,9 @@ class HandleDependencyTask extends abstract_task_1.AbstractTask {
37
39
  console.warn(error);
38
40
  }
39
41
  }
40
- if (Object.keys((_c = this.devDependencies) !== null && _c !== void 0 ? _c : {}).length > 0) {
42
+ if (Object.keys(this.devDependencies ?? {}).length > 0) {
41
43
  let command = `${(0, reuse_1.getPackageManagerCommand)(this.command)} -D`;
42
- Object.keys((_d = this.devDependencies) !== null && _d !== void 0 ? _d : {}).forEach((dependency) => {
44
+ Object.keys(this.devDependencies ?? {}).forEach((dependency) => {
43
45
  command += ` ${dependency}`;
44
46
  });
45
47
  try {
@@ -10,6 +10,7 @@ const path_1 = __importDefault(require("path"));
10
10
  const reuse_1 = require("../../../shares/reuse");
11
11
  const abstract_task_1 = require("../../abstract-task");
12
12
  class JsonTask extends abstract_task_1.AbstractTask {
13
+ json;
13
14
  constructor(identifier, key, json, versionRange, dependentTasks = [], options = {}) {
14
15
  super(identifier, `Reconfigure "${key}" in package.json of your project.`, [], versionRange, dependentTasks, options);
15
16
  this.json = json;
@@ -19,7 +20,7 @@ class JsonTask extends abstract_task_1.AbstractTask {
19
20
  try {
20
21
  JSON.stringify(json);
21
22
  }
22
- catch (_a) {
23
+ catch {
23
24
  throw (0, reuse_1.logAndCreateError)(`Value of task "${this.identifier}" is not able to stringify (JSON).`);
24
25
  }
25
26
  }
@@ -12,6 +12,13 @@ const removeLineBreaksAndSpaces = (match) => {
12
12
  return match.replace(/\r?\n/g, ' ').replace(/>\s+/g, '>').replace(/\s+</g, '<');
13
13
  };
14
14
  class LabelExpertSlot extends abstract_task_1.AbstractTask {
15
+ tag;
16
+ property;
17
+ componentRegExp;
18
+ componentNoLabelPropRegExp;
19
+ customElementRegExp;
20
+ customElementNoLabelPropRegExp;
21
+ propertyInCamelCase;
15
22
  constructor(identifier, tag, property, versionRange, dependentTasks, options) {
16
23
  super(identifier, `Move innerText of "${tag}" component to property "${property}"`, types_1.MARKUP_EXTENSIONS, versionRange, dependentTasks, options);
17
24
  this.tag = tag;
@@ -8,6 +8,9 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const reuse_1 = require("../../../shares/reuse");
9
9
  const abstract_task_1 = require("../../abstract-task");
10
10
  class MergeHtmlTask extends abstract_task_1.AbstractTask {
11
+ path;
12
+ filename;
13
+ html;
11
14
  constructor(identifier, title, path, filename, html, versionRange, dependentTasks, options) {
12
15
  super(identifier, title, [], versionRange, dependentTasks, options);
13
16
  this.path = path;
@@ -9,6 +9,7 @@ const path_1 = __importDefault(require("path"));
9
9
  const reuse_1 = require("../../../shares/reuse");
10
10
  const abstract_task_1 = require("../../abstract-task");
11
11
  class NpmRcAddRuleTask extends abstract_task_1.AbstractTask {
12
+ rule;
12
13
  constructor(identifier, rule, versionRange, dependentTasks = [], options = {}) {
13
14
  super(identifier, `Add the rule "${rule}" to the .npmrc of your project.`, [], versionRange, dependentTasks, options);
14
15
  this.rule = rule;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RefactorPropertyErrorToMsg = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const types_1 = require("../../../../types");
9
+ const reuse_1 = require("../../../shares/reuse");
10
+ const abstract_task_1 = require("../../abstract-task");
11
+ class RefactorPropertyErrorToMsg extends abstract_task_1.AbstractTask {
12
+ componentRegExpCurlyBrackets;
13
+ componentRegExpQuotationMarks;
14
+ customElementRegExpQuotationMarks;
15
+ constructor(identifier, tag, versionRange) {
16
+ super(identifier, `Refactor property "_error" to "_msg" of "${tag}" component`, types_1.MARKUP_EXTENSIONS, versionRange);
17
+ if (!reuse_1.isTagKebabCaseRegExp.test(tag)) {
18
+ throw (0, reuse_1.logAndCreateError)(`Tag "${tag}" is not in kebab case.`);
19
+ }
20
+ const tagCapitalCase = (0, reuse_1.kebabToCapitalCase)(tag);
21
+ this.componentRegExpCurlyBrackets = new RegExp(`(<${tagCapitalCase}[^>]+)_error=\\{([^\\}]+)\\}`, 'g');
22
+ this.componentRegExpQuotationMarks = new RegExp(`(<${tagCapitalCase}[^>]+)_error="([^"]+)"`, 'g');
23
+ this.customElementRegExpQuotationMarks = new RegExp(`(<${tag}[^>]+)_error="([^"]+)"`, 'g');
24
+ }
25
+ static getInstance(tag, versionRange) {
26
+ const identifier = `${tag}-refactor-property-error-to-msg`;
27
+ if (!this.instances.has(identifier)) {
28
+ this.instances.set(identifier, new RefactorPropertyErrorToMsg(identifier, tag, versionRange));
29
+ }
30
+ return this.instances.get(identifier);
31
+ }
32
+ run(baseDir) {
33
+ this.transpileComponentFiles(baseDir);
34
+ this.transpileCustomElementFiles(baseDir);
35
+ }
36
+ transpileComponentFiles(baseDir) {
37
+ (0, reuse_1.filterFilesByExt)(baseDir, types_1.COMPONENT_FILE_EXTENSIONS).forEach((file) => {
38
+ const content = fs_1.default.readFileSync(file, 'utf8');
39
+ const newContent = content
40
+ .replace(this.componentRegExpCurlyBrackets, `$1_msg={{ _type: 'error', _description: $2 }}`)
41
+ .replace(this.componentRegExpQuotationMarks, `$1_msg={{ _type: 'error', _description: '$2' }}`);
42
+ if (content !== newContent) {
43
+ reuse_1.MODIFIED_FILES.add(file);
44
+ fs_1.default.writeFileSync(file, newContent);
45
+ }
46
+ });
47
+ }
48
+ transpileCustomElementFiles(baseDir) {
49
+ (0, reuse_1.filterFilesByExt)(baseDir, types_1.CUSTOM_ELEMENT_FILE_EXTENSIONS).forEach((file) => {
50
+ const content = fs_1.default.readFileSync(file, 'utf8');
51
+ const newContent = content.replace(this.customElementRegExpQuotationMarks, `$1_msg='${JSON.stringify({ _type: 'error', _description: '$2' })}'`);
52
+ if (content !== newContent) {
53
+ reuse_1.MODIFIED_FILES.add(file);
54
+ fs_1.default.writeFileSync(file, newContent);
55
+ }
56
+ });
57
+ }
58
+ }
59
+ exports.RefactorPropertyErrorToMsg = RefactorPropertyErrorToMsg;