@public-ui/kolibri-cli 4.0.0-beta.1 → 4.0.0-ee1678914efc9a51fdc688bac71b570e768a8032.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/migrate/index.js +45 -15
- package/dist/migrate/runner/abstract-task.js +14 -0
- package/dist/migrate/runner/task-runner.js +86 -5
- package/dist/migrate/runner/tasks/common/HandleDependencyTask.js +23 -10
- package/dist/migrate/runner/tasks/v4/events.js +102 -0
- package/dist/migrate/runner/tasks/v4/index.js +2 -0
- package/dist/migrate/runner/tasks/v4/loader.js +3 -2
- package/dist/migrate/shares/reuse.js +3 -2
- package/dist/types.js +1 -1
- package/package.json +9 -10
package/dist/migrate/index.js
CHANGED
|
@@ -64,10 +64,12 @@ Target version of @public-ui/*: ${options.overwriteTargetVersion}
|
|
|
64
64
|
Source folder to migrate: ${baseDir}
|
|
65
65
|
`);
|
|
66
66
|
if (!fs_1.default.existsSync(baseDir)) {
|
|
67
|
-
|
|
67
|
+
const absolutePath = path_1.default.resolve(process.cwd(), baseDir);
|
|
68
|
+
throw (0, reuse_1.logAndCreateError)(`The specified source folder "${absolutePath}" (${baseDir}) does not exist or is inaccessible. Please check the path and try again.`);
|
|
68
69
|
}
|
|
69
70
|
if (!(0, reuse_1.hasKoliBriTags)(baseDir)) {
|
|
70
|
-
|
|
71
|
+
const absolutePath = path_1.default.resolve(process.cwd(), baseDir);
|
|
72
|
+
console.log(chalk_1.default.yellow(`No KoliBri components (web or React) found under "${absolutePath}" (${baseDir}). Check the path or your task configuration.`));
|
|
71
73
|
}
|
|
72
74
|
if (!options.ignoreGreaterVersion && semver_1.default.lt(options.overwriteTargetVersion, options.overwriteCurrentVersion)) {
|
|
73
75
|
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.');
|
|
@@ -109,41 +111,65 @@ Source folder to migrate: ${baseDir}
|
|
|
109
111
|
/**
|
|
110
112
|
* Sets the version of the @public-ui/* packages in the package.json file.
|
|
111
113
|
* @param {string} version Version to set
|
|
112
|
-
* @param {Function} cb Callback function
|
|
113
114
|
*/
|
|
114
|
-
function setVersionOfPublicUiPackages(version
|
|
115
|
+
function setVersionOfPublicUiPackages(version) {
|
|
115
116
|
let packageJson = (0, reuse_1.getContentOfProjectPkgJson)();
|
|
116
117
|
packageJson = packageJson.replace(/"(@public-ui\/[^"]+)":\s*"(.*)"/g, createVersionReplacer(version));
|
|
117
118
|
fs_1.default.writeFileSync(path_1.default.resolve(process.cwd(), 'package.json'), packageJson);
|
|
118
119
|
runner.setProjectVersion(version);
|
|
119
120
|
console.log(`- Update @public-ui/* to version ${version}`);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Runs the task runner in batch mode with collected version steps.
|
|
124
|
+
*/
|
|
125
|
+
async function runMigrationBatch() {
|
|
126
|
+
// Set execution mode to batch - tasks don't install immediately
|
|
127
|
+
runner.setExecutionMode('batch');
|
|
128
|
+
console.log(`\nStarting migration in batch mode...`);
|
|
129
|
+
// Start version is the current project version (from package.json or --overwrite-current-version)
|
|
130
|
+
const startVersion = options.overwriteCurrentVersion;
|
|
131
|
+
// Target version is --overwrite-target-version (CLI version = migration target)
|
|
132
|
+
const targetVersion = options.overwriteTargetVersion;
|
|
133
|
+
console.log(`Migration path: ${startVersion} → ${targetVersion}`);
|
|
134
|
+
// Run all tasks (they transform the code, not the dependencies)
|
|
135
|
+
runner.run();
|
|
136
|
+
// Write final target version to package.json (only once)
|
|
137
|
+
setVersionOfPublicUiPackages(targetVersion);
|
|
138
|
+
// Install only once at the end
|
|
139
|
+
console.log(`\nInstalling dependencies once...`);
|
|
140
|
+
await new Promise((resolve, reject) => {
|
|
141
|
+
(0, child_process_1.exec)((0, reuse_1.getPackageManagerCommand)('install'), (err) => {
|
|
142
|
+
if (err) {
|
|
143
|
+
console.error(`exec error: ${err.message}`);
|
|
144
|
+
reject(err);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
resolve();
|
|
148
|
+
});
|
|
126
149
|
});
|
|
150
|
+
console.log(`Dependencies installed successfully.`);
|
|
151
|
+
finish();
|
|
127
152
|
}
|
|
128
153
|
/**
|
|
129
|
-
* Runs the task runner in a loop until all tasks are completed.
|
|
154
|
+
* Runs the task runner in a loop until all tasks are completed (legacy mode - deprecated).
|
|
155
|
+
* @deprecated Use runMigrationBatch() instead for optimized single-pass installation
|
|
130
156
|
*/
|
|
131
157
|
function runLoop() {
|
|
132
158
|
runner.run();
|
|
133
159
|
if (version !== runner.getPendingMinVersion()) {
|
|
134
160
|
// Tasks
|
|
135
161
|
version = runner.getPendingMinVersion();
|
|
136
|
-
setVersionOfPublicUiPackages(version
|
|
162
|
+
setVersionOfPublicUiPackages(version);
|
|
137
163
|
}
|
|
138
164
|
else if (semver_1.default.lt(version, options.overwriteTargetVersion)) {
|
|
139
165
|
// CLI
|
|
140
166
|
version = options.overwriteTargetVersion;
|
|
141
|
-
setVersionOfPublicUiPackages(version
|
|
167
|
+
setVersionOfPublicUiPackages(version);
|
|
142
168
|
}
|
|
143
169
|
else if (semver_1.default.lt(version, options.overwriteCurrentVersion)) {
|
|
144
170
|
// Components
|
|
145
171
|
version = options.overwriteCurrentVersion;
|
|
146
|
-
setVersionOfPublicUiPackages(version
|
|
172
|
+
setVersionOfPublicUiPackages(version);
|
|
147
173
|
}
|
|
148
174
|
else {
|
|
149
175
|
finish();
|
|
@@ -221,7 +247,11 @@ If something is wrong, the migration can be reverted with ${chalk_1.default.ital
|
|
|
221
247
|
const status = runner.getStatus();
|
|
222
248
|
console.log(`
|
|
223
249
|
Execute ${status.total} registered tasks...`);
|
|
224
|
-
|
|
250
|
+
// Use optimized batch mode for single-pass installation
|
|
251
|
+
runMigrationBatch().catch((error) => {
|
|
252
|
+
console.error('Migration failed:', error);
|
|
253
|
+
process.exit(1);
|
|
254
|
+
});
|
|
225
255
|
});
|
|
226
256
|
});
|
|
227
257
|
}
|
|
@@ -14,6 +14,8 @@ class AbstractTask {
|
|
|
14
14
|
versionRange;
|
|
15
15
|
taskDependencies;
|
|
16
16
|
status = 'pending';
|
|
17
|
+
executionMode = 'immediate';
|
|
18
|
+
pendingExecutables = [];
|
|
17
19
|
static instances = new Map();
|
|
18
20
|
description;
|
|
19
21
|
constructor(identifier, title, extensions, versionRange, taskDependencies = [], options = {}) {
|
|
@@ -49,5 +51,17 @@ class AbstractTask {
|
|
|
49
51
|
getVersionRange() {
|
|
50
52
|
return this.versionRange;
|
|
51
53
|
}
|
|
54
|
+
setExecutionMode(mode) {
|
|
55
|
+
this.executionMode = mode;
|
|
56
|
+
}
|
|
57
|
+
getExecutionMode() {
|
|
58
|
+
return this.executionMode;
|
|
59
|
+
}
|
|
60
|
+
getPendingExecutables() {
|
|
61
|
+
return this.pendingExecutables;
|
|
62
|
+
}
|
|
63
|
+
clearPendingExecutables() {
|
|
64
|
+
this.pendingExecutables = [];
|
|
65
|
+
}
|
|
52
66
|
}
|
|
53
67
|
exports.AbstractTask = AbstractTask;
|
|
@@ -5,21 +5,45 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.TaskRunner = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
9
10
|
const path_1 = __importDefault(require("path"));
|
|
10
11
|
const semver_1 = __importDefault(require("semver"));
|
|
11
12
|
const reuse_1 = require("../shares/reuse");
|
|
12
13
|
const MIN_VERSION_OF_PUBLIC_UI = '1.4.2';
|
|
14
|
+
/**
|
|
15
|
+
* Displays a progress bar in the console.
|
|
16
|
+
* @param {number} current Current progress
|
|
17
|
+
* @param {number} total Total items
|
|
18
|
+
* @param {string} title Optional title
|
|
19
|
+
*/
|
|
20
|
+
function displayProgressBar(current, total, title = '') {
|
|
21
|
+
const barLength = 30;
|
|
22
|
+
const percentage = total === 0 ? 0 : (current / total) * 100;
|
|
23
|
+
const filledLength = Math.round((barLength * current) / total);
|
|
24
|
+
const emptyLength = barLength - filledLength;
|
|
25
|
+
const bar = chalk_1.default.green('█'.repeat(filledLength)) + chalk_1.default.gray('░'.repeat(emptyLength));
|
|
26
|
+
const percentStr = percentage.toFixed(0).padStart(3, ' ');
|
|
27
|
+
// Bestimme die maximale Ziffernzahl des totals
|
|
28
|
+
const totalDigits = total.toString().length;
|
|
29
|
+
const currentStr = current.toString().padStart(totalDigits, ' ');
|
|
30
|
+
const taskStr = `${currentStr}/${total}`;
|
|
31
|
+
const titleStr = title ? ` ${title}` : '';
|
|
32
|
+
process.stdout.write(`\r${bar} ${percentStr}% [${taskStr}]${titleStr}`);
|
|
33
|
+
}
|
|
13
34
|
class TaskRunner {
|
|
14
35
|
tasks = new Map();
|
|
15
36
|
baseDir = '/';
|
|
16
37
|
cliVersion = '0.0.0';
|
|
17
38
|
projectVersion = '0.0.0';
|
|
39
|
+
executionMode = 'immediate';
|
|
40
|
+
aggregatedCommands = new Map(); // taskId -> commands
|
|
18
41
|
config = {
|
|
19
42
|
migrate: {
|
|
20
43
|
tasks: {},
|
|
21
44
|
},
|
|
22
45
|
};
|
|
46
|
+
completedTasks = 0;
|
|
23
47
|
constructor(baseDir, cliVersion, projectVersion, config) {
|
|
24
48
|
this.setBaseDir(baseDir);
|
|
25
49
|
this.setCliVersion(cliVersion);
|
|
@@ -46,6 +70,12 @@ class TaskRunner {
|
|
|
46
70
|
this.projectVersion = version;
|
|
47
71
|
}
|
|
48
72
|
}
|
|
73
|
+
setExecutionMode(mode) {
|
|
74
|
+
this.executionMode = mode;
|
|
75
|
+
this.tasks.forEach((task) => {
|
|
76
|
+
task.setExecutionMode(mode);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
49
79
|
setConfig(config) {
|
|
50
80
|
if (config.migrate?.tasks) {
|
|
51
81
|
this.config.migrate.tasks = {
|
|
@@ -86,15 +116,22 @@ class TaskRunner {
|
|
|
86
116
|
}
|
|
87
117
|
else {
|
|
88
118
|
this.config.migrate.tasks[task.getIdentifier()] = true;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
const isProjectVersionGreater = semver_1.default.gtr(this.projectVersion, task.getVersionRange(), {
|
|
120
|
+
includePrerelease: true,
|
|
121
|
+
});
|
|
122
|
+
const isCliVersionLower = semver_1.default.ltr(this.cliVersion, task.getVersionRange(), {
|
|
123
|
+
includePrerelease: true,
|
|
124
|
+
});
|
|
125
|
+
if (task.getStatus() === 'pending' && !isProjectVersionGreater && !isCliVersionLower) {
|
|
93
126
|
// task.setStatus('running'); only of the task is async
|
|
94
127
|
if (!this.tasks.has(task.getIdentifier())) {
|
|
95
128
|
this.registerTask(task);
|
|
96
129
|
}
|
|
97
130
|
task.run(this.baseDir);
|
|
131
|
+
// Collect commands if in batch mode
|
|
132
|
+
if (this.executionMode === 'batch') {
|
|
133
|
+
this.aggregateCommandsFromTask(task);
|
|
134
|
+
}
|
|
98
135
|
task.setStatus('done');
|
|
99
136
|
}
|
|
100
137
|
}
|
|
@@ -103,14 +140,58 @@ class TaskRunner {
|
|
|
103
140
|
taskDependencies.forEach((dependentTask) => {
|
|
104
141
|
this.dependentTaskRun(dependentTask, dependentTask.getTaskDependencies());
|
|
105
142
|
});
|
|
106
|
-
if (taskDependencies.every((dependentTask) => dependentTask.getStatus() === 'done')) {
|
|
143
|
+
if (taskDependencies.length === 0 || taskDependencies.every((dependentTask) => dependentTask.getStatus() === 'done')) {
|
|
144
|
+
displayProgressBar(this.completedTasks, this.tasks.size, task.getTitle());
|
|
107
145
|
this.runTask(task);
|
|
146
|
+
this.completedTasks++;
|
|
108
147
|
}
|
|
109
148
|
}
|
|
110
149
|
run() {
|
|
150
|
+
this.completedTasks = 0;
|
|
151
|
+
this.aggregatedCommands.clear();
|
|
152
|
+
displayProgressBar(0, this.tasks.size);
|
|
111
153
|
this.tasks.forEach((task) => {
|
|
112
154
|
this.dependentTaskRun(task, task.getTaskDependencies());
|
|
113
155
|
});
|
|
156
|
+
displayProgressBar(this.tasks.size, this.tasks.size);
|
|
157
|
+
if (this.tasks.size > 0) {
|
|
158
|
+
console.log(); // New line after progress bar
|
|
159
|
+
}
|
|
160
|
+
// If in batch mode, collect and execute all commands at the end
|
|
161
|
+
if (this.executionMode === 'batch') {
|
|
162
|
+
this.executeAggregatedCommands();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
aggregateCommandsFromTask(task) {
|
|
166
|
+
// HandleDependencyTask has prepareExecutables method
|
|
167
|
+
if ('prepareExecutables' in task && typeof task.prepareExecutables === 'function') {
|
|
168
|
+
const commands = task.prepareExecutables();
|
|
169
|
+
if (commands && commands.length > 0) {
|
|
170
|
+
this.aggregatedCommands.set(task.getIdentifier(), commands);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
executeAggregatedCommands() {
|
|
175
|
+
const allCommands = [];
|
|
176
|
+
this.aggregatedCommands.forEach((commands) => {
|
|
177
|
+
allCommands.push(...commands);
|
|
178
|
+
});
|
|
179
|
+
if (allCommands.length === 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
console.log('\nExecuting aggregated dependency commands...');
|
|
183
|
+
allCommands.forEach((command) => {
|
|
184
|
+
try {
|
|
185
|
+
console.log(` Running: ${command}`);
|
|
186
|
+
(0, child_process_1.execSync)(command, {
|
|
187
|
+
encoding: 'utf8',
|
|
188
|
+
stdio: 'inherit',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
console.warn(`Warning: Failed to execute command: ${command}`, error);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
114
195
|
}
|
|
115
196
|
getPendingMinVersion() {
|
|
116
197
|
let version = this.cliVersion;
|
|
@@ -24,26 +24,39 @@ class HandleDependencyTask extends abstract_task_1.AbstractTask {
|
|
|
24
24
|
}
|
|
25
25
|
return this.instances.get(identifier);
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Collect dependency commands to be executed in batch mode.
|
|
29
|
+
* Does NOT execute immediately - returns commands for aggregation.
|
|
30
|
+
*/
|
|
31
|
+
prepareExecutables() {
|
|
32
|
+
const commands = [];
|
|
28
33
|
if (Object.keys(this.dependencies ?? {}).length > 0) {
|
|
29
34
|
let command = `${(0, reuse_1.getPackageManagerCommand)(this.command)}`;
|
|
30
35
|
Object.keys(this.dependencies ?? {}).forEach((dependency) => {
|
|
31
36
|
command += ` ${dependency}@${this.dependencies[dependency]}`;
|
|
32
37
|
});
|
|
33
|
-
|
|
34
|
-
(0, child_process_1.execSync)(command, {
|
|
35
|
-
encoding: 'utf8',
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
console.warn(error);
|
|
40
|
-
}
|
|
38
|
+
commands.push(command);
|
|
41
39
|
}
|
|
42
40
|
if (Object.keys(this.devDependencies ?? {}).length > 0) {
|
|
43
41
|
let command = `${(0, reuse_1.getPackageManagerCommand)(this.command)} -D`;
|
|
44
42
|
Object.keys(this.devDependencies ?? {}).forEach((dependency) => {
|
|
45
43
|
command += ` ${dependency}`;
|
|
46
44
|
});
|
|
45
|
+
commands.push(command);
|
|
46
|
+
}
|
|
47
|
+
return commands;
|
|
48
|
+
}
|
|
49
|
+
run() {
|
|
50
|
+
// In batch mode, commands are collected and executed later
|
|
51
|
+
// This method is kept for backward compatibility but does nothing
|
|
52
|
+
// Actual execution happens in TaskRunner with aggregated commands
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute collected commands immediately (used for backward compatibility).
|
|
56
|
+
*/
|
|
57
|
+
executeImmediate() {
|
|
58
|
+
const commands = this.prepareExecutables();
|
|
59
|
+
commands.forEach((command) => {
|
|
47
60
|
try {
|
|
48
61
|
(0, child_process_1.execSync)(command, {
|
|
49
62
|
encoding: 'utf8',
|
|
@@ -52,7 +65,7 @@ class HandleDependencyTask extends abstract_task_1.AbstractTask {
|
|
|
52
65
|
catch (error) {
|
|
53
66
|
console.warn(error);
|
|
54
67
|
}
|
|
55
|
-
}
|
|
68
|
+
});
|
|
56
69
|
}
|
|
57
70
|
}
|
|
58
71
|
exports.HandleDependencyTask = HandleDependencyTask;
|
|
@@ -0,0 +1,102 @@
|
|
|
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.RenameKolEventNamesTasks = exports.RenameKolEventNamesTask = 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
|
+
const EVENT_REPLACEMENTS = {
|
|
12
|
+
kolBlur: 'blur',
|
|
13
|
+
kolChange: 'change',
|
|
14
|
+
kolChangeHeaderCells: 'changeheadercells',
|
|
15
|
+
kolChangePage: 'changepage',
|
|
16
|
+
kolChangePageSize: 'changepagesize',
|
|
17
|
+
kolClick: 'click',
|
|
18
|
+
kolClose: 'close',
|
|
19
|
+
kolCreate: 'create',
|
|
20
|
+
kolFocus: 'focus',
|
|
21
|
+
kolInput: 'input',
|
|
22
|
+
kolKeydown: 'keydown',
|
|
23
|
+
kolMousedown: 'mousedown',
|
|
24
|
+
kolReset: 'reset',
|
|
25
|
+
kolSelect: 'select',
|
|
26
|
+
kolSelectionChange: 'selectionchange',
|
|
27
|
+
kolSort: 'sort',
|
|
28
|
+
kolSubmit: 'submit',
|
|
29
|
+
kolToggle: 'toggle',
|
|
30
|
+
};
|
|
31
|
+
class RenameKolEventNamesTask extends abstract_task_1.AbstractTask {
|
|
32
|
+
constructor(versionRange) {
|
|
33
|
+
super('rename-kol-events', 'Rename kol* DOM events to their native names', [...types_1.FILE_EXTENSIONS], versionRange);
|
|
34
|
+
}
|
|
35
|
+
static getInstance(versionRange) {
|
|
36
|
+
const identifier = `${versionRange}-rename-kol-events`;
|
|
37
|
+
if (!this.instances.has(identifier)) {
|
|
38
|
+
this.instances.set(identifier, new RenameKolEventNamesTask(versionRange));
|
|
39
|
+
}
|
|
40
|
+
return this.instances.get(identifier);
|
|
41
|
+
}
|
|
42
|
+
run(baseDir) {
|
|
43
|
+
(0, reuse_1.filterFilesByExt)(baseDir, this.extensions).forEach((file) => {
|
|
44
|
+
const content = fs_1.default.readFileSync(file, 'utf8');
|
|
45
|
+
const newContent = this.replaceEventNames(content);
|
|
46
|
+
if (content !== newContent) {
|
|
47
|
+
reuse_1.MODIFIED_FILES.add(file);
|
|
48
|
+
fs_1.default.writeFileSync(file, newContent);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
replaceEventNames(content) {
|
|
53
|
+
// Sort by key length descending to ensure longer event names are replaced first
|
|
54
|
+
// This prevents partial replacements (e.g., kolChange before kolChangeHeaderCells)
|
|
55
|
+
const sortedEntries = Object.entries(EVENT_REPLACEMENTS).sort(([keyA], [keyB]) => keyB.length - keyA.length);
|
|
56
|
+
return sortedEntries.reduce((updatedContent, [oldName, newName]) => {
|
|
57
|
+
return this.replaceEventNameInEventContexts(updatedContent, oldName, newName);
|
|
58
|
+
}, content);
|
|
59
|
+
}
|
|
60
|
+
replaceEventNameInEventContexts(content, oldName, newName) {
|
|
61
|
+
let updatedContent = content;
|
|
62
|
+
// Handle addEventListener('kolX', ...)
|
|
63
|
+
const addEventListenerPattern = new RegExp(`(addEventListener\\s*\\(\\s*['"])${oldName}(['"])`, 'g');
|
|
64
|
+
updatedContent = updatedContent.replace(addEventListenerPattern, `$1${newName}$2`);
|
|
65
|
+
// Handle removeEventListener('kolX', ...)
|
|
66
|
+
const removeEventListenerPattern = new RegExp(`(removeEventListener\\s*\\(\\s*['"])${oldName}(['"])`, 'g');
|
|
67
|
+
updatedContent = updatedContent.replace(removeEventListenerPattern, `$1${newName}$2`);
|
|
68
|
+
// Handle new CustomEvent('kolX', ...)
|
|
69
|
+
const customEventPattern = new RegExp(`(new\\s+CustomEvent\\s*\\(\\s*['"])${oldName}(['"])`, 'g');
|
|
70
|
+
updatedContent = updatedContent.replace(customEventPattern, `$1${newName}$2`);
|
|
71
|
+
// Handle assignments and object property values: foo = 'kolX', { event: 'kolX' }
|
|
72
|
+
const assignmentPattern = new RegExp(`([=:]\\s*['"])${oldName}(['"])`, 'g');
|
|
73
|
+
updatedContent = updatedContent.replace(assignmentPattern, `$1${newName}$2`);
|
|
74
|
+
// Handle JSX/TSX event handler props: onKolClick -> onClick, etc.
|
|
75
|
+
const capitalize = (value) => (value.length === 0 ? value : value[0].toUpperCase() + value.slice(1));
|
|
76
|
+
const oldPropName = `on${capitalize(oldName)}`;
|
|
77
|
+
const newPropName = `on${capitalize(newName)}`;
|
|
78
|
+
const jsxPropPattern = new RegExp(`\\b${oldPropName}\\b`, 'g');
|
|
79
|
+
updatedContent = updatedContent.replace(jsxPropPattern, newPropName);
|
|
80
|
+
// Handle simple template literals: `kolX`
|
|
81
|
+
const templateLiteralPattern = new RegExp(`(\`)${oldName}(\`)`, 'g');
|
|
82
|
+
updatedContent = updatedContent.replace(templateLiteralPattern, `$1${newName}$2`);
|
|
83
|
+
const dispatchEventPattern = new RegExp(`(dispatchEvent\\s*\\(\\s*new\\s+Event\\s*\\(\\s*['"])${oldName}(['"])`, 'g');
|
|
84
|
+
updatedContent = updatedContent.replace(dispatchEventPattern, `$1${newName}$2`);
|
|
85
|
+
const koliBriCreatorPattern = new RegExp(`(dispatchEvent\\s*\\(\\s*createKoliBriEvent\\s*\\(\\s*['"])${oldName}(['"])`, 'g');
|
|
86
|
+
updatedContent = updatedContent.replace(koliBriCreatorPattern, `$1${newName}$2`);
|
|
87
|
+
// Handle bare event names at statement boundaries and as function arguments
|
|
88
|
+
// Match: (start of line, whitespace, or parenthesis)eventName(whitespace, comma, semicolon, or end of line)
|
|
89
|
+
// This handles cases like:
|
|
90
|
+
// - kolChange (standalone at end of line)
|
|
91
|
+
// - addEventListener(kolClick, handler)
|
|
92
|
+
// - dispatchEvent(new Event(kolX))
|
|
93
|
+
// Negative lookahead/lookbehind would be better but JavaScript regex support is limited
|
|
94
|
+
// So we match the surrounding context and preserve it
|
|
95
|
+
const bareEventPattern = new RegExp(`(^|[\\s(])${oldName}([\\s,;\\n]|$)`, 'gm');
|
|
96
|
+
updatedContent = updatedContent.replace(bareEventPattern, `$1${newName}$2`);
|
|
97
|
+
return updatedContent;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.RenameKolEventNamesTask = RenameKolEventNamesTask;
|
|
101
|
+
const renameKolEventNamesTaskInstance = RenameKolEventNamesTask.getInstance('^4');
|
|
102
|
+
exports.RenameKolEventNamesTasks = [renameKolEventNamesTaskInstance];
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.v4Tasks = void 0;
|
|
4
4
|
const clear_button_1 = require("./clear-button");
|
|
5
|
+
const events_1 = require("./events");
|
|
5
6
|
const focus_1 = require("./focus");
|
|
6
7
|
const id_1 = require("./id");
|
|
7
8
|
const link_1 = require("./link");
|
|
@@ -17,6 +18,7 @@ exports.v4Tasks.push(...msg_1.RemoveMsgPropsTasks);
|
|
|
17
18
|
exports.v4Tasks.push(...clear_button_1.RenameClearButtonPropTasks);
|
|
18
19
|
exports.v4Tasks.push(focus_1.RenameKolFocusMethodsTask.getInstance('^4'));
|
|
19
20
|
exports.v4Tasks.push(modal_1.RenameTagNameKolModalToKolDialog);
|
|
21
|
+
exports.v4Tasks.push(...events_1.RenameKolEventNamesTasks);
|
|
20
22
|
exports.v4Tasks.push(toast_1.RemoveToastVariantTask.getInstance('^4'));
|
|
21
23
|
exports.v4Tasks.push(toaster_1.RemoveToasterGetInstanceOptionsTask.getInstance('^4'));
|
|
22
24
|
exports.v4Tasks.push(loader_1.UpdateLoaderImportPathTask.getInstance('^4'));
|
|
@@ -7,7 +7,8 @@ exports.UpdateLoaderImportPathTask = void 0;
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const reuse_1 = require("../../../shares/reuse");
|
|
9
9
|
const abstract_task_1 = require("../../abstract-task");
|
|
10
|
-
const LOADER_FILE_EXTENSIONS = ['js', 'jsx', 'ts', 'tsx', 'vue'];
|
|
10
|
+
const LOADER_FILE_EXTENSIONS = ['cjs', 'cts', 'js', 'jsx', 'mjs', 'mts', 'ts', 'tsx', 'vue'];
|
|
11
|
+
const LOADER_IMPORT_REGEX = /@public-ui\/components\/dist\/loader(?:\/[^\s'"]+)?/g;
|
|
11
12
|
class UpdateLoaderImportPathTask extends abstract_task_1.AbstractTask {
|
|
12
13
|
constructor(identifier, versionRange, dependentTasks, options) {
|
|
13
14
|
super(identifier, 'Update loader imports to @public-ui/components/loader', LOADER_FILE_EXTENSIONS, versionRange, dependentTasks, options);
|
|
@@ -25,7 +26,7 @@ class UpdateLoaderImportPathTask extends abstract_task_1.AbstractTask {
|
|
|
25
26
|
transpileFiles(baseDir) {
|
|
26
27
|
(0, reuse_1.filterFilesByExt)(baseDir, LOADER_FILE_EXTENSIONS).forEach((file) => {
|
|
27
28
|
const content = fs_1.default.readFileSync(file, 'utf8');
|
|
28
|
-
const newContent = content.replace(
|
|
29
|
+
const newContent = content.replace(LOADER_IMPORT_REGEX, '@public-ui/components/loader');
|
|
29
30
|
if (newContent !== content) {
|
|
30
31
|
reuse_1.MODIFIED_FILES.add(file);
|
|
31
32
|
fs_1.default.writeFileSync(file, newContent);
|
|
@@ -47,7 +47,7 @@ function filterFilesByExt(dir, ext) {
|
|
|
47
47
|
let files = [];
|
|
48
48
|
const dirPath = path_1.default.resolve(process.cwd(), dir);
|
|
49
49
|
fs_1.default.readdirSync(dirPath).forEach((file) => {
|
|
50
|
-
const fullPath = path_1.default.resolve(
|
|
50
|
+
const fullPath = path_1.default.resolve(dirPath, file);
|
|
51
51
|
if (fs_1.default.lstatSync(fullPath).isDirectory()) {
|
|
52
52
|
files = files.concat(filterFilesByExt(fullPath, ext));
|
|
53
53
|
}
|
|
@@ -65,7 +65,8 @@ function filterFilesByExt(dir, ext) {
|
|
|
65
65
|
*/
|
|
66
66
|
function hasKoliBriTags(dir) {
|
|
67
67
|
const regexes = [types_1.WEB_TAG_REGEX, types_1.REACT_TAG_REGEX];
|
|
68
|
-
const
|
|
68
|
+
const dirPath = path_1.default.resolve(process.cwd(), dir);
|
|
69
|
+
const files = filterFilesByExt(dirPath, types_1.MARKUP_EXTENSIONS);
|
|
69
70
|
for (const file of files) {
|
|
70
71
|
let fd;
|
|
71
72
|
try {
|
package/dist/types.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.REACT_TAG_REGEX = exports.WEB_TAG_REGEX = exports.SCSS_FILE_EXTENSIONS = exports.MARKUP_EXTENSIONS = exports.CUSTOM_ELEMENT_FILE_EXTENSIONS = exports.COMPONENT_FILE_EXTENSIONS = exports.FILE_EXTENSIONS = void 0;
|
|
4
|
-
exports.FILE_EXTENSIONS = ['
|
|
4
|
+
exports.FILE_EXTENSIONS = ['cjs', 'css', 'cts', 'html', 'js', 'json', 'jsx', 'mjs', 'mts', 'sass', 'scss', 'ts', 'tsx', 'vue', 'xhtml'];
|
|
5
5
|
exports.COMPONENT_FILE_EXTENSIONS = ['jsx', 'tsx', 'vue'];
|
|
6
6
|
exports.CUSTOM_ELEMENT_FILE_EXTENSIONS = ['html', 'xhtml', 'jsx', 'tsx', 'vue'];
|
|
7
7
|
exports.MARKUP_EXTENSIONS = exports.COMPONENT_FILE_EXTENSIONS.concat(exports.CUSTOM_ELEMENT_FILE_EXTENSIONS);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@public-ui/kolibri-cli",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-ee1678914efc9a51fdc688bac71b570e768a8032.0",
|
|
4
4
|
"license": "EUPL-1.2",
|
|
5
5
|
"homepage": "https://public-ui.github.io",
|
|
6
6
|
"repository": {
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
"prettier": "3.7.4",
|
|
30
30
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
31
31
|
"semver": "7.7.3",
|
|
32
|
-
"typed-bem": "1.0.2"
|
|
32
|
+
"typed-bem": "1.0.2",
|
|
33
|
+
"@public-ui/components": "4.0.0-ee1678914efc9a51fdc688bac71b570e768a8032.0"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/node": "24.10.4",
|
|
36
37
|
"@typescript-eslint/eslint-plugin": "7.18.0",
|
|
37
38
|
"@typescript-eslint/parser": "7.18.0",
|
|
38
|
-
"cpy-cli": "6.0.0",
|
|
39
39
|
"cross-env": "10.1.0",
|
|
40
40
|
"eslint": "8.57.1",
|
|
41
41
|
"eslint-config-prettier": "9.1.2",
|
|
@@ -43,27 +43,26 @@
|
|
|
43
43
|
"eslint-plugin-json": "3.1.0",
|
|
44
44
|
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
45
45
|
"eslint-plugin-react": "7.37.5",
|
|
46
|
-
"knip": "5.
|
|
46
|
+
"knip": "5.80.0",
|
|
47
47
|
"mocha": "11.7.5",
|
|
48
48
|
"nodemon": "3.1.11",
|
|
49
|
-
"rimraf": "6.1.2",
|
|
50
49
|
"ts-node": "10.9.2",
|
|
51
|
-
"typescript": "5.9.3"
|
|
52
|
-
|
|
50
|
+
"typescript": "5.9.3"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=22"
|
|
53
54
|
},
|
|
54
55
|
"files": [
|
|
55
56
|
"dist"
|
|
56
57
|
],
|
|
57
58
|
"scripts": {
|
|
58
59
|
"build": "tsc",
|
|
59
|
-
"reset": "pnpm i @public-ui/components@1.1.7",
|
|
60
60
|
"format": "prettier -c src",
|
|
61
61
|
"lint": "pnpm lint:eslint && pnpm lint:tsc",
|
|
62
62
|
"lint:eslint": "eslint src",
|
|
63
63
|
"lint:tsc": "tsc --noemit",
|
|
64
64
|
"pretest:unit": "pnpm build",
|
|
65
|
-
"
|
|
66
|
-
"start": "rimraf test && cpy \"../../samples/react/src/components\" test/src && cpy \"../../samples/react/public/*.html\" test/ && ts-node src/index.ts migrate --ignore-uncommitted-changes --test-tasks test",
|
|
65
|
+
"start": "ts-node src/index.ts migrate --ignore-uncommitted-changes --overwrite-current-version=2.2.19-rc.0 --overwrite-target-version=4.0.0 --test-tasks ../../../test-migration",
|
|
67
66
|
"test:unit": "cross-env TS_NODE_PROJECT=tsconfig.test.json mocha --require ts-node/register test/**/*.ts --no-experimental-strip-types",
|
|
68
67
|
"unused": "knip",
|
|
69
68
|
"watch": "nodemon --ignore package.json src/index.ts migrate --ignore-uncommitted-changes --test-tasks test"
|