@minecraft-docker/mcctl 2.15.3 → 2.16.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/CHANGELOG.md +26 -0
- package/README.md +8 -9
- package/dist/commands/config-snapshot/create.d.ts +11 -0
- package/dist/commands/config-snapshot/create.d.ts.map +1 -0
- package/dist/commands/config-snapshot/create.js +39 -0
- package/dist/commands/config-snapshot/create.js.map +1 -0
- package/dist/commands/config-snapshot/delete.d.ts +10 -0
- package/dist/commands/config-snapshot/delete.d.ts.map +1 -0
- package/dist/commands/config-snapshot/delete.js +43 -0
- package/dist/commands/config-snapshot/delete.js.map +1 -0
- package/dist/commands/config-snapshot/diff.d.ts +14 -0
- package/dist/commands/config-snapshot/diff.d.ts.map +1 -0
- package/dist/commands/config-snapshot/diff.js +157 -0
- package/dist/commands/config-snapshot/diff.js.map +1 -0
- package/dist/commands/config-snapshot/index.d.ts +8 -0
- package/dist/commands/config-snapshot/index.d.ts.map +1 -0
- package/dist/commands/config-snapshot/index.js +9 -0
- package/dist/commands/config-snapshot/index.js.map +1 -0
- package/dist/commands/config-snapshot/list.d.ts +12 -0
- package/dist/commands/config-snapshot/list.d.ts.map +1 -0
- package/dist/commands/config-snapshot/list.js +55 -0
- package/dist/commands/config-snapshot/list.js.map +1 -0
- package/dist/commands/config-snapshot/restore.d.ts +11 -0
- package/dist/commands/config-snapshot/restore.d.ts.map +1 -0
- package/dist/commands/config-snapshot/restore.js +55 -0
- package/dist/commands/config-snapshot/restore.js.map +1 -0
- package/dist/commands/config-snapshot/schedule/add.d.ts +13 -0
- package/dist/commands/config-snapshot/schedule/add.d.ts.map +1 -0
- package/dist/commands/config-snapshot/schedule/add.js +46 -0
- package/dist/commands/config-snapshot/schedule/add.js.map +1 -0
- package/dist/commands/config-snapshot/schedule/index.d.ts +5 -0
- package/dist/commands/config-snapshot/schedule/index.d.ts.map +1 -0
- package/dist/commands/config-snapshot/schedule/index.js +5 -0
- package/dist/commands/config-snapshot/schedule/index.js.map +1 -0
- package/dist/commands/config-snapshot/schedule/list.d.ts +10 -0
- package/dist/commands/config-snapshot/schedule/list.d.ts.map +1 -0
- package/dist/commands/config-snapshot/schedule/list.js +57 -0
- package/dist/commands/config-snapshot/schedule/list.js.map +1 -0
- package/dist/commands/config-snapshot/schedule/remove.d.ts +10 -0
- package/dist/commands/config-snapshot/schedule/remove.d.ts.map +1 -0
- package/dist/commands/config-snapshot/schedule/remove.js +38 -0
- package/dist/commands/config-snapshot/schedule/remove.js.map +1 -0
- package/dist/commands/config-snapshot/schedule/toggle.d.ts +10 -0
- package/dist/commands/config-snapshot/schedule/toggle.d.ts.map +1 -0
- package/dist/commands/config-snapshot/schedule/toggle.js +34 -0
- package/dist/commands/config-snapshot/schedule/toggle.js.map +1 -0
- package/dist/commands/config-snapshot/show.d.ts +11 -0
- package/dist/commands/config-snapshot/show.d.ts.map +1 -0
- package/dist/commands/config-snapshot/show.js +53 -0
- package/dist/commands/config-snapshot/show.js.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/index.js +145 -2
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/di/container.d.ts +7 -1
- package/dist/infrastructure/di/container.d.ts.map +1 -1
- package/dist/infrastructure/di/container.js +30 -2
- package/dist/infrastructure/di/container.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.16.0] - 2026-02-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Config Snapshot** - Full-stack configuration snapshot system for server config versioning (#397~#406, #414~#424)
|
|
12
|
+
- **Domain Layer**: `ConfigSnapshot`, `ConfigSnapshotSchedule` entities with `SnapshotId`, `SnapshotType`, `SnapshotStatus` value objects (#397, #414)
|
|
13
|
+
- **Infrastructure**: `SqliteConfigSnapshotRepository` adapter with SQLite persistence (#398)
|
|
14
|
+
- **API**: RESTful Config Snapshot endpoints - CRUD, diff, restore, schedule management (#399, #400, #416)
|
|
15
|
+
- `ConfigSnapshotSchedulerService` with `node-cron` integration for automated snapshots (#405)
|
|
16
|
+
- Audit logging for all snapshot mutations
|
|
17
|
+
- **CLI**: `mcctl config-snapshot` commands for snapshot management (#401)
|
|
18
|
+
- **Console**: Config Snapshots tab on Backup page with full UI (#402)
|
|
19
|
+
- Config History tab on Server Detail page (#403)
|
|
20
|
+
- ConfigDiff viewer and ConfigRestore dialog components (#404)
|
|
21
|
+
- BFF proxy routes, React Query hooks, and TypeScript types
|
|
22
|
+
- **E2E Tests**: Config Snapshot E2E test fixtures and test files (#406)
|
|
23
|
+
|
|
24
|
+
- **Backup Retention Policy Pruning** - Implement `applyRetentionPolicy()` for automated backup cleanup (#396, #426)
|
|
25
|
+
- Git history truncation logic for old backups
|
|
26
|
+
- Integration with backup scheduler for automatic pruning
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- **Backup Git Path** - Fix git repository path and prevent shell injection (#423, #425)
|
|
30
|
+
- Replace `exec()` with `execFile()` to prevent shell injection vulnerabilities
|
|
31
|
+
- Correct git repository path resolution in backup routes
|
|
32
|
+
- Added test coverage for backup routes
|
|
33
|
+
|
|
8
34
|
## [2.15.3] - 2026-02-22
|
|
9
35
|
|
|
10
36
|
### Changed
|
package/README.md
CHANGED
|
@@ -77,6 +77,14 @@ mcctl logs myserver
|
|
|
77
77
|
|
|
78
78
|
## Changelog
|
|
79
79
|
|
|
80
|
+
### v2.16.0 (2026-02-23)
|
|
81
|
+
- **feat**: Config Snapshot system - full-stack server configuration versioning (#397~#406)
|
|
82
|
+
- Domain layer, infrastructure, API, CLI, Console UI, and E2E tests
|
|
83
|
+
- Automated snapshot scheduling with node-cron
|
|
84
|
+
- Config diff viewer and restore functionality
|
|
85
|
+
- **feat**: Backup retention policy pruning implementation (#396, #426)
|
|
86
|
+
- **fix**: Backup git path and shell injection prevention (#423, #425)
|
|
87
|
+
|
|
80
88
|
### v2.15.3 (2026-02-22)
|
|
81
89
|
- **docs**: Update README.md with Management Console features and architecture (#412, #413)
|
|
82
90
|
|
|
@@ -98,15 +106,6 @@ mcctl logs myserver
|
|
|
98
106
|
### v2.14.0 (2026-02-21)
|
|
99
107
|
- **feat(console)**: Enhanced installed mods display with rich card UI and batch API
|
|
100
108
|
|
|
101
|
-
### v2.13.0 (2026-02-21)
|
|
102
|
-
- **feat(console)**: Improve Server Activity tab to match Audit Logs page UI (#391, #392)
|
|
103
|
-
|
|
104
|
-
### v2.12.1 (2026-02-20)
|
|
105
|
-
- **docs**: Add server management guide (EN/KO) for start/stop operations
|
|
106
|
-
|
|
107
|
-
### v2.12.0 (2026-02-20)
|
|
108
|
-
- **refactor(console)**: Convert file editors from Dialog to inline Card-based views (#389, #390)
|
|
109
|
-
|
|
110
109
|
[Full Changelog](https://github.com/smallmiro/minecraft-server-manager/releases)
|
|
111
110
|
|
|
112
111
|
## AI Assistant
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ConfigSnapshotCreateOptions {
|
|
2
|
+
root?: string;
|
|
3
|
+
serverName?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create a new config snapshot for a server
|
|
9
|
+
*/
|
|
10
|
+
export declare function configSnapshotCreateCommand(options: ConfigSnapshotCreateOptions): Promise<number>;
|
|
11
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/config-snapshot/create.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,MAAM,CAAC,CAgDjB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { log, colors } from '@minecraft-docker/shared';
|
|
2
|
+
import { getContainer } from '../../infrastructure/di/container.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create a new config snapshot for a server
|
|
5
|
+
*/
|
|
6
|
+
export async function configSnapshotCreateCommand(options) {
|
|
7
|
+
const container = getContainer(options.root);
|
|
8
|
+
const useCase = container.configSnapshotUseCase;
|
|
9
|
+
// Validate server name
|
|
10
|
+
if (!options.serverName) {
|
|
11
|
+
log.error('Server name is required. Usage: mcctl config-snapshot create <server>');
|
|
12
|
+
return 1;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
console.log('');
|
|
16
|
+
console.log(colors.dim(`Creating snapshot for server "${options.serverName}"...`));
|
|
17
|
+
const snapshot = await useCase.create(options.serverName, options.description);
|
|
18
|
+
if (options.json) {
|
|
19
|
+
console.log(JSON.stringify(snapshot.toJSON(), null, 2));
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
console.log(colors.green('Snapshot created successfully!'));
|
|
23
|
+
console.log(` ID: ${colors.cyan(snapshot.id)}`);
|
|
24
|
+
console.log(` Server: ${colors.bold(snapshot.serverName.value)}`);
|
|
25
|
+
console.log(` Files: ${colors.yellow(String(snapshot.files.length))} files captured`);
|
|
26
|
+
console.log(` Time: ${colors.dim(snapshot.createdAt.toLocaleString())}`);
|
|
27
|
+
if (snapshot.description) {
|
|
28
|
+
console.log(` Note: ${colors.dim(snapshot.description)}`);
|
|
29
|
+
}
|
|
30
|
+
console.log('');
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
log.error(`Failed to create snapshot: ${message}`);
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/config-snapshot/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AASpE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAoC;IAEpC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,qBAAqB,CAAC;IAEhD,uBAAuB;IACvB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxB,GAAG,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;QACnF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,GAAG,CACR,iCAAiC,OAAO,CAAC,UAAU,MAAM,CAC1D,CACF,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CACnC,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,WAAW,CACpB,CAAC;QAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CACT,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAC3E,CAAC;QACF,OAAO,CAAC,GAAG,CACT,aAAa,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,EAAE,CAC/D,CAAC;QACF,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,GAAG,CAAC,KAAK,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ConfigSnapshotDeleteOptions {
|
|
2
|
+
root?: string;
|
|
3
|
+
id: string;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Delete a config snapshot
|
|
8
|
+
*/
|
|
9
|
+
export declare function configSnapshotDeleteCommand(options: ConfigSnapshotDeleteOptions): Promise<number>;
|
|
10
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/config-snapshot/delete.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,MAAM,CAAC,CA8CjB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { log, colors } from '@minecraft-docker/shared';
|
|
3
|
+
import { getContainer } from '../../infrastructure/di/container.js';
|
|
4
|
+
/**
|
|
5
|
+
* Delete a config snapshot
|
|
6
|
+
*/
|
|
7
|
+
export async function configSnapshotDeleteCommand(options) {
|
|
8
|
+
if (!options.id) {
|
|
9
|
+
log.error('Snapshot ID is required. Usage: mcctl config-snapshot delete <id>');
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
const container = getContainer(options.root);
|
|
13
|
+
const useCase = container.configSnapshotUseCase;
|
|
14
|
+
try {
|
|
15
|
+
const snapshot = await useCase.findById(options.id);
|
|
16
|
+
if (!snapshot) {
|
|
17
|
+
log.error(`Snapshot not found: ${options.id}`);
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
// Confirmation prompt (unless --force)
|
|
21
|
+
if (!options.force) {
|
|
22
|
+
const confirmed = await p.confirm({
|
|
23
|
+
message: `Delete snapshot ${colors.cyan(snapshot.id.substring(0, 8))} for server "${colors.bold(snapshot.serverName.value)}" (${snapshot.files.length} files, created ${snapshot.createdAt.toLocaleDateString()})?`,
|
|
24
|
+
initialValue: false,
|
|
25
|
+
});
|
|
26
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
27
|
+
console.log(colors.dim('\nDeletion cancelled.\n'));
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
await useCase.delete(options.id);
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(colors.green(`Snapshot deleted: ${colors.bold(snapshot.id.substring(0, 8))}...`));
|
|
34
|
+
console.log('');
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39
|
+
log.error(`Failed to delete snapshot: ${message}`);
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/commands/config-snapshot/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAQpE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAoC;IAEpC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,GAAG,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QAC/E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,qBAAqB,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,KAAK,CAAC,uBAAuB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,CAAC;QACX,CAAC;QAED,uCAAuC;QACvC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;gBAChC,OAAO,EAAE,mBAAmB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,mBAAmB,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI;gBACnN,YAAY,EAAE,KAAK;aACpB,CAAC,CAAC;YAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;gBACnD,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QAED,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,KAAK,CACV,qBAAqB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CACnE,CACF,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,GAAG,CAAC,KAAK,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ConfigSnapshotDiffOptions {
|
|
2
|
+
root?: string;
|
|
3
|
+
id1: string;
|
|
4
|
+
id2: string;
|
|
5
|
+
unified?: boolean;
|
|
6
|
+
sideBySide?: boolean;
|
|
7
|
+
filesOnly?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Display diff between two config snapshots
|
|
12
|
+
*/
|
|
13
|
+
export declare function configSnapshotDiffCommand(options: ConfigSnapshotDiffOptions): Promise<number>;
|
|
14
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/commands/config-snapshot/diff.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAmEjB"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { log, colors } from '@minecraft-docker/shared';
|
|
2
|
+
import { getContainer } from '../../infrastructure/di/container.js';
|
|
3
|
+
/**
|
|
4
|
+
* Display diff between two config snapshots
|
|
5
|
+
*/
|
|
6
|
+
export async function configSnapshotDiffCommand(options) {
|
|
7
|
+
if (!options.id1 || !options.id2) {
|
|
8
|
+
log.error('Two snapshot IDs are required. Usage: mcctl config-snapshot diff <id1> <id2>');
|
|
9
|
+
return 1;
|
|
10
|
+
}
|
|
11
|
+
const container = getContainer(options.root);
|
|
12
|
+
const useCase = container.configSnapshotUseCase;
|
|
13
|
+
try {
|
|
14
|
+
const diff = await useCase.diff(options.id1, options.id2);
|
|
15
|
+
if (options.json) {
|
|
16
|
+
console.log(JSON.stringify(diff.toJSON(), null, 2));
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
// Summary header
|
|
20
|
+
const { added, modified, deleted } = diff.summary;
|
|
21
|
+
console.log('');
|
|
22
|
+
console.log(colors.bold('Snapshot Diff'));
|
|
23
|
+
console.log(` Base: ${colors.dim(options.id1.substring(0, 8))}...`);
|
|
24
|
+
console.log(` Compare: ${colors.dim(options.id2.substring(0, 8))}...`);
|
|
25
|
+
console.log('');
|
|
26
|
+
if (!diff.hasChanges) {
|
|
27
|
+
console.log(colors.dim('No differences found between snapshots.'));
|
|
28
|
+
console.log('');
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
// Summary line
|
|
32
|
+
const summaryParts = [];
|
|
33
|
+
if (added > 0)
|
|
34
|
+
summaryParts.push(colors.green(`+${added} added`));
|
|
35
|
+
if (modified > 0)
|
|
36
|
+
summaryParts.push(colors.yellow(`~${modified} modified`));
|
|
37
|
+
if (deleted > 0)
|
|
38
|
+
summaryParts.push(colors.red(`-${deleted} deleted`));
|
|
39
|
+
console.log(` Changes: ${summaryParts.join(', ')}`);
|
|
40
|
+
console.log('');
|
|
41
|
+
if (options.filesOnly) {
|
|
42
|
+
// Show only file names with status indicators
|
|
43
|
+
console.log(colors.bold('Changed Files:'));
|
|
44
|
+
console.log('');
|
|
45
|
+
for (const change of diff.changes) {
|
|
46
|
+
const statusIcon = getStatusIcon(change.status);
|
|
47
|
+
const statusColor = getStatusColor(change.status);
|
|
48
|
+
console.log(` ${statusIcon} ${statusColor(change.path)}`);
|
|
49
|
+
}
|
|
50
|
+
console.log('');
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
// Full diff output
|
|
54
|
+
for (const change of diff.changes) {
|
|
55
|
+
printFileDiff(change);
|
|
56
|
+
}
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
61
|
+
log.error(`Failed to compute diff: ${message}`);
|
|
62
|
+
return 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the status icon for a file change
|
|
67
|
+
*/
|
|
68
|
+
function getStatusIcon(status) {
|
|
69
|
+
switch (status) {
|
|
70
|
+
case 'added':
|
|
71
|
+
return colors.green('+');
|
|
72
|
+
case 'deleted':
|
|
73
|
+
return colors.red('-');
|
|
74
|
+
case 'modified':
|
|
75
|
+
return colors.yellow('~');
|
|
76
|
+
default:
|
|
77
|
+
return ' ';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get the color function for a file change status
|
|
82
|
+
*/
|
|
83
|
+
function getStatusColor(status) {
|
|
84
|
+
switch (status) {
|
|
85
|
+
case 'added':
|
|
86
|
+
return colors.green;
|
|
87
|
+
case 'deleted':
|
|
88
|
+
return colors.red;
|
|
89
|
+
case 'modified':
|
|
90
|
+
return colors.yellow;
|
|
91
|
+
default:
|
|
92
|
+
return (t) => t;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Print unified diff output for a single file
|
|
97
|
+
*/
|
|
98
|
+
function printFileDiff(change) {
|
|
99
|
+
const statusLabel = change.status === 'added'
|
|
100
|
+
? colors.green('[ADDED]')
|
|
101
|
+
: change.status === 'deleted'
|
|
102
|
+
? colors.red('[DELETED]')
|
|
103
|
+
: colors.yellow('[MODIFIED]');
|
|
104
|
+
console.log(`${statusLabel} ${colors.bold(change.path)}`);
|
|
105
|
+
if (change.status === 'added' && change.newContent !== undefined) {
|
|
106
|
+
// Show added file content (first 10 lines)
|
|
107
|
+
const lines = change.newContent.split('\n').slice(0, 10);
|
|
108
|
+
for (const line of lines) {
|
|
109
|
+
console.log(colors.green(` + ${line}`));
|
|
110
|
+
}
|
|
111
|
+
if (change.newContent.split('\n').length > 10) {
|
|
112
|
+
console.log(colors.dim(' ... (truncated)'));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else if (change.status === 'deleted' && change.oldContent !== undefined) {
|
|
116
|
+
// Show deleted file content (first 10 lines)
|
|
117
|
+
const lines = change.oldContent.split('\n').slice(0, 10);
|
|
118
|
+
for (const line of lines) {
|
|
119
|
+
console.log(colors.red(` - ${line}`));
|
|
120
|
+
}
|
|
121
|
+
if (change.oldContent.split('\n').length > 10) {
|
|
122
|
+
console.log(colors.dim(' ... (truncated)'));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (change.status === 'modified' &&
|
|
126
|
+
change.oldContent !== undefined &&
|
|
127
|
+
change.newContent !== undefined) {
|
|
128
|
+
// Produce a simple line-by-line diff
|
|
129
|
+
const oldLines = change.oldContent.split('\n');
|
|
130
|
+
const newLines = change.newContent.split('\n');
|
|
131
|
+
const maxLines = Math.min(Math.max(oldLines.length, newLines.length), 20);
|
|
132
|
+
for (let i = 0; i < maxLines; i++) {
|
|
133
|
+
const oldLine = oldLines[i];
|
|
134
|
+
const newLine = newLines[i];
|
|
135
|
+
if (oldLine === undefined && newLine !== undefined) {
|
|
136
|
+
console.log(colors.green(` + ${newLine}`));
|
|
137
|
+
}
|
|
138
|
+
else if (newLine === undefined && oldLine !== undefined) {
|
|
139
|
+
console.log(colors.red(` - ${oldLine}`));
|
|
140
|
+
}
|
|
141
|
+
else if (oldLine !== newLine) {
|
|
142
|
+
if (oldLine !== undefined) {
|
|
143
|
+
console.log(colors.red(` - ${oldLine}`));
|
|
144
|
+
}
|
|
145
|
+
if (newLine !== undefined) {
|
|
146
|
+
console.log(colors.green(` + ${newLine}`));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const totalLines = Math.max(oldLines.length, newLines.length);
|
|
151
|
+
if (totalLines > 20) {
|
|
152
|
+
console.log(colors.dim(` ... (${totalLines - 20} more lines)`));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
console.log('');
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/commands/config-snapshot/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAapE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAkC;IAElC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,GAAG,CAAC,KAAK,CACP,8EAA8E,CAC/E,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,qBAAqB,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAE1D,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,iBAAiB;QACjB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,eAAe;QACf,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,IAAI,KAAK,GAAG,CAAC;YAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;QAClE,IAAI,QAAQ,GAAG,CAAC;YAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,QAAQ,WAAW,CAAC,CAAC,CAAC;QAC5E,IAAI,OAAO,GAAG,CAAC;YAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,cAAc,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,8CAA8C;YAC9C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAChD,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,KAAK,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,mBAAmB;QACnB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,aAAa,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,GAAG,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,MAAc;IACnC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,KAAK,UAAU;YACb,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B;YACE,OAAO,GAAG,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,MAAc;IAEd,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,GAAG,CAAC;QACpB,KAAK,UAAU;YACb,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB;YACE,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,MAAgB;IACrC,MAAM,WAAW,GACf,MAAM,CAAC,MAAM,KAAK,OAAO;QACvB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QACzB,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;YAC3B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;YACzB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAEpC,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE1D,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjE,2CAA2C;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC1E,6CAA6C;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;SAAM,IACL,MAAM,CAAC,MAAM,KAAK,UAAU;QAC5B,MAAM,CAAC,UAAU,KAAK,SAAS;QAC/B,MAAM,CAAC,UAAU,KAAK,SAAS,EAC/B,CAAC;QACD,qCAAqC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAE1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAE5B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBACnD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC;YAC9C,CAAC;iBAAM,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBAC/B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC5C,CAAC;gBACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,UAAU,GAAG,EAAE,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,UAAU,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { configSnapshotListCommand, type ConfigSnapshotListOptions, } from './list.js';
|
|
2
|
+
export { configSnapshotCreateCommand, type ConfigSnapshotCreateOptions, } from './create.js';
|
|
3
|
+
export { configSnapshotShowCommand, type ConfigSnapshotShowOptions, } from './show.js';
|
|
4
|
+
export { configSnapshotDeleteCommand, type ConfigSnapshotDeleteOptions, } from './delete.js';
|
|
5
|
+
export { configSnapshotDiffCommand, type ConfigSnapshotDiffOptions, } from './diff.js';
|
|
6
|
+
export { configSnapshotRestoreCommand, type ConfigSnapshotRestoreOptions, } from './restore.js';
|
|
7
|
+
export { configSnapshotScheduleListCommand, type ConfigSnapshotScheduleListOptions, configSnapshotScheduleAddCommand, type ConfigSnapshotScheduleAddOptions, configSnapshotScheduleRemoveCommand, type ConfigSnapshotScheduleRemoveOptions, configSnapshotScheduleToggleCommand, type ConfigSnapshotScheduleToggleOptions, } from './schedule/index.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config-snapshot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,2BAA2B,EAC3B,KAAK,2BAA2B,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,2BAA2B,EAC3B,KAAK,2BAA2B,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,4BAA4B,EAC5B,KAAK,4BAA4B,GAClC,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,EACtC,gCAAgC,EAChC,KAAK,gCAAgC,EACrC,mCAAmC,EACnC,KAAK,mCAAmC,EACxC,mCAAmC,EACnC,KAAK,mCAAmC,GACzC,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { configSnapshotListCommand, } from './list.js';
|
|
2
|
+
export { configSnapshotCreateCommand, } from './create.js';
|
|
3
|
+
export { configSnapshotShowCommand, } from './show.js';
|
|
4
|
+
export { configSnapshotDeleteCommand, } from './delete.js';
|
|
5
|
+
export { configSnapshotDiffCommand, } from './diff.js';
|
|
6
|
+
export { configSnapshotRestoreCommand, } from './restore.js';
|
|
7
|
+
// Schedule sub-commands
|
|
8
|
+
export { configSnapshotScheduleListCommand, configSnapshotScheduleAddCommand, configSnapshotScheduleRemoveCommand, configSnapshotScheduleToggleCommand, } from './schedule/index.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/config-snapshot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAE1B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,2BAA2B,GAE5B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,GAE1B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,2BAA2B,GAE5B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,GAE1B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,4BAA4B,GAE7B,MAAM,cAAc,CAAC;AAEtB,wBAAwB;AACxB,OAAO,EACL,iCAAiC,EAEjC,gCAAgC,EAEhC,mCAAmC,EAEnC,mCAAmC,GAEpC,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ConfigSnapshotListOptions {
|
|
2
|
+
root?: string;
|
|
3
|
+
serverName?: string;
|
|
4
|
+
limit?: number;
|
|
5
|
+
offset?: number;
|
|
6
|
+
json?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* List config snapshots (all servers or specific server)
|
|
10
|
+
*/
|
|
11
|
+
export declare function configSnapshotListCommand(options: ConfigSnapshotListOptions): Promise<number>;
|
|
12
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/config-snapshot/list.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAoEjB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { log, colors } from '@minecraft-docker/shared';
|
|
2
|
+
import { getContainer } from '../../infrastructure/di/container.js';
|
|
3
|
+
/**
|
|
4
|
+
* List config snapshots (all servers or specific server)
|
|
5
|
+
*/
|
|
6
|
+
export async function configSnapshotListCommand(options) {
|
|
7
|
+
const container = getContainer(options.root);
|
|
8
|
+
const useCase = container.configSnapshotUseCase;
|
|
9
|
+
const limit = options.limit ?? 20;
|
|
10
|
+
try {
|
|
11
|
+
const snapshots = await useCase.list(options.serverName, limit, options.offset);
|
|
12
|
+
if (options.json) {
|
|
13
|
+
console.log(JSON.stringify(snapshots.map((s) => s.toJSON()), null, 2));
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
if (snapshots.length === 0) {
|
|
17
|
+
console.log('');
|
|
18
|
+
if (options.serverName) {
|
|
19
|
+
console.log(colors.dim(`No snapshots found for server "${options.serverName}".`));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(colors.dim('No snapshots found.'));
|
|
23
|
+
}
|
|
24
|
+
console.log(colors.dim(' Use: mcctl config-snapshot create <server> to create one.'));
|
|
25
|
+
console.log('');
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
console.log('');
|
|
29
|
+
if (options.serverName) {
|
|
30
|
+
console.log(colors.bold(`Config Snapshots for ${options.serverName} (${snapshots.length}):`));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.log(colors.bold(`Config Snapshots (${snapshots.length}):`));
|
|
34
|
+
}
|
|
35
|
+
console.log('');
|
|
36
|
+
for (const snapshot of snapshots) {
|
|
37
|
+
const date = snapshot.createdAt.toLocaleString();
|
|
38
|
+
const server = colors.cyan(snapshot.serverName.value.padEnd(15));
|
|
39
|
+
const id = colors.dim(snapshot.id.substring(0, 8) + '...');
|
|
40
|
+
const fileCount = colors.yellow(`${snapshot.files.length} files`);
|
|
41
|
+
const desc = snapshot.description
|
|
42
|
+
? colors.dim(` "${snapshot.description}"`)
|
|
43
|
+
: '';
|
|
44
|
+
console.log(` ${server} ${colors.dim(date)} ${fileCount} ${id}${desc}`);
|
|
45
|
+
}
|
|
46
|
+
console.log('');
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
51
|
+
log.error(`Failed to list snapshots: ${message}`);
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/config-snapshot/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ConfigSnapshotRestoreOptions {
|
|
2
|
+
root?: string;
|
|
3
|
+
id: string;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
noSafety?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Restore server configuration from a config snapshot
|
|
9
|
+
*/
|
|
10
|
+
export declare function configSnapshotRestoreCommand(options: ConfigSnapshotRestoreOptions): Promise<number>;
|
|
11
|
+
//# sourceMappingURL=restore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../../src/commands/config-snapshot/restore.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,4BAA4B;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,MAAM,CAAC,CAoEjB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { log, colors } from '@minecraft-docker/shared';
|
|
3
|
+
import { getContainer } from '../../infrastructure/di/container.js';
|
|
4
|
+
/**
|
|
5
|
+
* Restore server configuration from a config snapshot
|
|
6
|
+
*/
|
|
7
|
+
export async function configSnapshotRestoreCommand(options) {
|
|
8
|
+
if (!options.id) {
|
|
9
|
+
log.error('Snapshot ID is required. Usage: mcctl config-snapshot restore <id>');
|
|
10
|
+
return 1;
|
|
11
|
+
}
|
|
12
|
+
const container = getContainer(options.root);
|
|
13
|
+
const useCase = container.configSnapshotUseCase;
|
|
14
|
+
try {
|
|
15
|
+
const snapshot = await useCase.findById(options.id);
|
|
16
|
+
if (!snapshot) {
|
|
17
|
+
log.error(`Snapshot not found: ${options.id}`);
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
// Confirmation prompt (unless --force)
|
|
21
|
+
if (!options.force) {
|
|
22
|
+
console.log('');
|
|
23
|
+
console.log(colors.bold('Restore Configuration'));
|
|
24
|
+
console.log(` Server: ${colors.bold(snapshot.serverName.value)}`);
|
|
25
|
+
console.log(` Snapshot: ${colors.cyan(snapshot.id.substring(0, 8))}...`);
|
|
26
|
+
console.log(` Created: ${colors.dim(snapshot.createdAt.toLocaleString())}`);
|
|
27
|
+
console.log(` Files: ${colors.yellow(String(snapshot.files.length))} files will be overwritten`);
|
|
28
|
+
if (snapshot.description) {
|
|
29
|
+
console.log(` Note: ${colors.dim(snapshot.description)}`);
|
|
30
|
+
}
|
|
31
|
+
console.log('');
|
|
32
|
+
const confirmed = await p.confirm({
|
|
33
|
+
message: `Restore ${snapshot.files.length} files for server "${snapshot.serverName.value}"? This will overwrite current configuration.`,
|
|
34
|
+
initialValue: false,
|
|
35
|
+
});
|
|
36
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
37
|
+
console.log(colors.dim('\nRestore cancelled.\n'));
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
console.log(colors.dim('\nRestoring configuration files...'));
|
|
42
|
+
await useCase.restore(options.id, options.force ?? false);
|
|
43
|
+
console.log('');
|
|
44
|
+
console.log(colors.green(`Configuration restored from snapshot ${colors.bold(snapshot.id.substring(0, 8))}...`));
|
|
45
|
+
console.log(` ${colors.yellow(String(snapshot.files.length))} files restored for server "${colors.bold(snapshot.serverName.value)}".`);
|
|
46
|
+
console.log('');
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
51
|
+
log.error(`Failed to restore snapshot: ${message}`);
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=restore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../../../src/commands/config-snapshot/restore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ConfigSnapshotScheduleAddOptions {
|
|
2
|
+
root?: string;
|
|
3
|
+
serverName?: string;
|
|
4
|
+
cron?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
retention?: number;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Add a new config snapshot schedule
|
|
11
|
+
*/
|
|
12
|
+
export declare function configSnapshotScheduleAddCommand(options: ConfigSnapshotScheduleAddOptions): Promise<number>;
|
|
13
|
+
//# sourceMappingURL=add.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../../src/commands/config-snapshot/schedule/add.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gCAAgC;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,MAAM,CAAC,CA6DjB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { log, colors } from '@minecraft-docker/shared';
|
|
2
|
+
import { getContainer } from '../../../infrastructure/di/container.js';
|
|
3
|
+
/**
|
|
4
|
+
* Add a new config snapshot schedule
|
|
5
|
+
*/
|
|
6
|
+
export async function configSnapshotScheduleAddCommand(options) {
|
|
7
|
+
const container = getContainer(options.root);
|
|
8
|
+
const useCase = container.configSnapshotScheduleUseCase;
|
|
9
|
+
// Validate required fields
|
|
10
|
+
if (!options.serverName) {
|
|
11
|
+
log.error('--server is required. Usage: mcctl config-snapshot schedule add --server <name> --cron "..." --name "..."');
|
|
12
|
+
return 1;
|
|
13
|
+
}
|
|
14
|
+
if (!options.cron) {
|
|
15
|
+
log.error('--cron is required. Example: --cron "0 3 * * *"');
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
if (!options.name) {
|
|
19
|
+
log.error('--name is required. Example: --name "Daily Snapshot"');
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
const retentionCount = options.retention ?? 10;
|
|
23
|
+
try {
|
|
24
|
+
const schedule = await useCase.create(options.serverName, options.name, options.cron, retentionCount);
|
|
25
|
+
if (options.json) {
|
|
26
|
+
console.log(JSON.stringify(schedule.toJSON(), null, 2));
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
console.log('');
|
|
30
|
+
console.log(colors.green('Config snapshot schedule created!'));
|
|
31
|
+
console.log(` Name: ${colors.bold(schedule.name)}`);
|
|
32
|
+
console.log(` Server: ${colors.bold(schedule.serverName.value)}`);
|
|
33
|
+
console.log(` Cron: ${colors.cyan(schedule.cronExpression.expression)}`);
|
|
34
|
+
console.log(` Schedule: ${schedule.cronExpression.toHumanReadable()}`);
|
|
35
|
+
console.log(` Retention: max ${colors.yellow(String(schedule.retentionCount))} snapshots`);
|
|
36
|
+
console.log(` ID: ${colors.dim(schedule.id)}`);
|
|
37
|
+
console.log('');
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42
|
+
log.error(`Failed to create schedule: ${message}`);
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=add.js.map
|