@lumy-pack/syncpoint 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import Ajv from "ajv";
2
+ declare const ajv: Ajv;
3
+ export { ajv };
@@ -0,0 +1,4 @@
1
+ export declare function validateConfig(data: unknown): {
2
+ valid: boolean;
3
+ errors?: string[];
4
+ };
@@ -0,0 +1,4 @@
1
+ export declare function validateMetadata(data: unknown): {
2
+ valid: boolean;
3
+ errors?: string[];
4
+ };
@@ -0,0 +1,4 @@
1
+ export declare function validateTemplate(data: unknown): {
2
+ valid: boolean;
3
+ errors?: string[];
4
+ };
@@ -0,0 +1,2 @@
1
+ export declare function getAssetPath(filename: string): string;
2
+ export declare function readAsset(filename: string): string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Format bytes into a human-readable string.
3
+ * e.g. 4096 -> "4.0 KB"
4
+ */
5
+ export declare function formatBytes(bytes: number): string;
6
+ /**
7
+ * Format a Date to "YYYY-MM-DD HH:mm".
8
+ */
9
+ export declare function formatDate(date: Date): string;
10
+ /**
11
+ * Format a Date to "YYYY-MM-DD_HHmmss" for filenames.
12
+ */
13
+ export declare function formatDatetime(date: Date): string;
14
+ /**
15
+ * Format a relative time string.
16
+ * e.g. "2 hours ago", "37 days ago"
17
+ */
18
+ export declare function formatRelativeTime(date: Date): string;
19
+ /**
20
+ * Generate a backup filename from the pattern.
21
+ * Supported placeholders: {hostname}, {date}, {time}, {datetime}, {tag}
22
+ */
23
+ export declare function generateFilename(pattern: string, options?: {
24
+ tag?: string;
25
+ date?: Date;
26
+ hostname?: string;
27
+ }): string;
@@ -0,0 +1,6 @@
1
+ export declare const logger: {
2
+ info(message: string): void;
3
+ success(message: string): void;
4
+ warn(message: string): void;
5
+ error(message: string): void;
6
+ };
@@ -0,0 +1,22 @@
1
+ export declare function getHomeDir(): string;
2
+ /**
3
+ * Expand ~ to the user's home directory.
4
+ */
5
+ export declare function expandTilde(p: string): string;
6
+ /**
7
+ * Contract the home directory prefix back to ~.
8
+ */
9
+ export declare function contractTilde(p: string): string;
10
+ /**
11
+ * Resolve a target path (expand tilde, resolve relative).
12
+ */
13
+ export declare function resolveTargetPath(p: string): string;
14
+ /**
15
+ * Ensure a directory exists, creating it recursively if needed.
16
+ */
17
+ export declare function ensureDir(dirPath: string): Promise<void>;
18
+ /**
19
+ * Check if a file exists.
20
+ */
21
+ export declare function fileExists(filePath: string): Promise<boolean>;
22
+ export declare function isInsideDir(filePath: string, dir: string): boolean;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Check whether sudo credentials are already cached.
3
+ * Returns true if `sudo -n true` succeeds (no password needed).
4
+ */
5
+ export declare function isSudoCached(): boolean;
6
+ /**
7
+ * Ensure sudo credentials are available before Ink captures stdin.
8
+ *
9
+ * 1. If already cached, returns silently.
10
+ * 2. Otherwise, warns the user and runs `sudo -v` which prompts
11
+ * for their password using the real terminal.
12
+ *
13
+ * Must be called BEFORE Ink render().
14
+ * Calls process.exit(1) if authentication fails.
15
+ */
16
+ export declare function ensureSudo(templateName: string): void;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Get the machine hostname.
3
+ */
4
+ export declare function getHostname(): string;
5
+ /**
6
+ * Get system information for metadata.
7
+ */
8
+ export declare function getSystemInfo(): {
9
+ platform: string;
10
+ release: string;
11
+ arch: string;
12
+ };
13
+ /**
14
+ * Sanitize hostname for use in filenames.
15
+ * Replace dots and spaces with dashes, remove non-alphanumeric except dashes.
16
+ */
17
+ export declare function formatHostname(name?: string): string;
@@ -0,0 +1,136 @@
1
+ export interface SyncpointConfig {
2
+ backup: {
3
+ targets: string[];
4
+ exclude: string[];
5
+ filename: string;
6
+ destination?: string;
7
+ };
8
+ scripts: {
9
+ includeInBackup: boolean;
10
+ };
11
+ }
12
+ export interface BackupMetadata {
13
+ version: string;
14
+ toolVersion: string;
15
+ createdAt: string;
16
+ hostname: string;
17
+ system: {
18
+ platform: string;
19
+ release: string;
20
+ arch: string;
21
+ };
22
+ config: {
23
+ filename: string;
24
+ destination?: string;
25
+ };
26
+ files: FileEntry[];
27
+ summary: {
28
+ fileCount: number;
29
+ totalSize: number;
30
+ };
31
+ }
32
+ export interface FileEntry {
33
+ path: string;
34
+ absolutePath: string;
35
+ size: number;
36
+ hash: string;
37
+ type?: string;
38
+ }
39
+ export interface TemplateConfig {
40
+ name: string;
41
+ description: string;
42
+ backup?: string;
43
+ sudo?: boolean;
44
+ steps: TemplateStep[];
45
+ }
46
+ export interface TemplateStep {
47
+ name: string;
48
+ description?: string;
49
+ command: string;
50
+ skip_if?: string;
51
+ continue_on_error?: boolean;
52
+ }
53
+ export interface BackupResult {
54
+ archivePath: string;
55
+ metadata: BackupMetadata;
56
+ }
57
+ export interface RestoreResult {
58
+ restoredFiles: string[];
59
+ skippedFiles: string[];
60
+ safetyBackupPath?: string;
61
+ }
62
+ export interface RestorePlan {
63
+ metadata: BackupMetadata;
64
+ actions: RestoreAction[];
65
+ }
66
+ export interface RestoreAction {
67
+ path: string;
68
+ action: "overwrite" | "skip" | "create";
69
+ currentSize?: number;
70
+ backupSize?: number;
71
+ reason: string;
72
+ }
73
+ export interface ProvisionResult {
74
+ steps: StepResult[];
75
+ totalDuration: number;
76
+ }
77
+ export interface StepResult {
78
+ name: string;
79
+ status: "success" | "skipped" | "failed" | "running" | "pending";
80
+ duration?: number;
81
+ error?: string;
82
+ output?: string;
83
+ }
84
+ export interface BackupOptions {
85
+ dryRun?: boolean;
86
+ tag?: string;
87
+ }
88
+ export interface RestoreOptions {
89
+ dryRun?: boolean;
90
+ }
91
+ export interface ProvisionOptions {
92
+ dryRun?: boolean;
93
+ skipRestore?: boolean;
94
+ }
95
+ export interface BackupInfo {
96
+ filename: string;
97
+ path: string;
98
+ size: number;
99
+ createdAt: Date;
100
+ hostname?: string;
101
+ fileCount?: number;
102
+ }
103
+ export interface StatusInfo {
104
+ backups: {
105
+ count: number;
106
+ totalSize: number;
107
+ };
108
+ templates: {
109
+ count: number;
110
+ totalSize: number;
111
+ };
112
+ scripts: {
113
+ count: number;
114
+ totalSize: number;
115
+ };
116
+ logs: {
117
+ count: number;
118
+ totalSize: number;
119
+ };
120
+ lastBackup?: Date;
121
+ oldestBackup?: Date;
122
+ }
123
+ export interface CleanupPolicy {
124
+ type: "keep-recent" | "older-than" | "select";
125
+ count?: number;
126
+ days?: number;
127
+ indices?: number[];
128
+ }
129
+ export interface InitOptions {
130
+ template: string;
131
+ directory?: string;
132
+ dryRun: boolean;
133
+ }
134
+ export interface CliOptions {
135
+ verbose?: boolean;
136
+ }
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@lumy-pack/syncpoint",
3
+ "version": "0.0.1",
4
+ "description": "CLI tool for project synchronization and scaffolding",
5
+ "keywords": [
6
+ "cli",
7
+ "sync",
8
+ "syncpoint",
9
+ "scaffolding"
10
+ ],
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/vincent-kk/lumy-pack.git",
14
+ "directory": "packages/syncpoint"
15
+ },
16
+ "license": "MIT",
17
+ "author": {
18
+ "name": "Vincent K. Kelvin",
19
+ "email": "lunox273@gmail.com"
20
+ },
21
+ "sideEffects": false,
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "source": "./src/index.ts",
27
+ "import": "./dist/index.mjs",
28
+ "require": "./dist/index.cjs"
29
+ }
30
+ },
31
+ "main": "dist/index.cjs",
32
+ "module": "dist/index.mjs",
33
+ "types": "dist/index.d.ts",
34
+ "bin": "./dist/cli.mjs",
35
+ "files": [
36
+ "dist",
37
+ "assets",
38
+ "README.md"
39
+ ],
40
+ "dependencies": {
41
+ "ajv": "^8.0.0",
42
+ "ajv-formats": "^3.0.0",
43
+ "commander": "^12.1.0",
44
+ "fast-glob": "^3.0.0",
45
+ "ink": "^5.0.0",
46
+ "ink-select-input": "^6.0.0",
47
+ "ink-spinner": "^5.0.0",
48
+ "picocolors": "^1.1.1",
49
+ "react": "^18.0.0",
50
+ "tar": "^7.0.0",
51
+ "yaml": "^2.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^20.11.0",
55
+ "@types/react": "^18.0.0",
56
+ "@types/tar": "^6.1.13",
57
+ "@vitest/coverage-v8": "^3.2.4",
58
+ "ink-testing-library": "^4.0.0"
59
+ },
60
+ "scripts": {
61
+ "build": "tsup && pnpm build:types",
62
+ "build:types": "tsc -p ./tsconfig.declarations.json",
63
+ "build:publish:npm": "pnpm build && pnpm publish:npm",
64
+ "dev": "tsx src/cli.ts",
65
+ "format": "prettier --write \"src/**/*.ts\"",
66
+ "lint": "eslint \"src/**/*.ts\"",
67
+ "publish:npm": "pnpm publish --access public --no-git-checks",
68
+ "test": "vitest",
69
+ "test:run": "vitest run",
70
+ "test:e2e": "vitest run --config vitest.e2e.config.ts src/__tests__/e2e/",
71
+ "test:docker": "vitest run --config vitest.e2e.config.ts src/__tests__/docker/",
72
+ "test:all": "vitest run && pnpm test:e2e && pnpm test:docker",
73
+ "version:major": "pnpm version major",
74
+ "version:minor": "pnpm version minor",
75
+ "version:patch": "pnpm version patch"
76
+ }
77
+ }