@fgv/ts-res-browser-cli 5.0.0-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.
- package/.rush/temp/45629f175c0b2c015132e9451c317583db1c0e2d.tar.log +32 -0
- package/.rush/temp/chunked-rush-logs/ts-res-browser-cli.build.chunks.jsonl +5 -0
- package/.rush/temp/operation/build/all.log +5 -0
- package/.rush/temp/operation/build/log-chunks.jsonl +5 -0
- package/.rush/temp/operation/build/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +651 -0
- package/README.md +131 -0
- package/bin/ts-res-browser-cli.js +40 -0
- package/config/rig.json +16 -0
- package/lib/browserLauncher.d.ts +53 -0
- package/lib/browserLauncher.d.ts.map +1 -0
- package/lib/browserLauncher.js +347 -0
- package/lib/browserLauncher.js.map +1 -0
- package/lib/cli.d.ts +37 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +373 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +42 -0
- package/lib/index.js.map +1 -0
- package/lib/options.d.ts +95 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +24 -0
- package/lib/options.js.map +1 -0
- package/lib/zipArchiver.d.ts +35 -0
- package/lib/zipArchiver.d.ts.map +1 -0
- package/lib/zipArchiver.js +148 -0
- package/lib/zipArchiver.js.map +1 -0
- package/package.json +49 -0
- package/rush-logs/ts-res-browser-cli.build.cache.log +3 -0
- package/rush-logs/ts-res-browser-cli.build.log +5 -0
- package/src/browserLauncher.ts +366 -0
- package/src/cli.ts +423 -0
- package/src/index.ts +26 -0
- package/src/options.ts +133 -0
- package/src/zipArchiver.ts +153 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as archiver from 'archiver';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import { Result, succeed, fail } from '@fgv/ts-utils';
|
|
6
|
+
|
|
7
|
+
export interface ZipArchiveOptions {
|
|
8
|
+
input?: string;
|
|
9
|
+
config?: string;
|
|
10
|
+
outputDir?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ZipArchiveResult {
|
|
14
|
+
zipPath: string;
|
|
15
|
+
manifest: ZipManifest;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ZipManifest {
|
|
19
|
+
timestamp: string;
|
|
20
|
+
input?: {
|
|
21
|
+
type: 'file' | 'directory';
|
|
22
|
+
originalPath: string;
|
|
23
|
+
archivePath: string;
|
|
24
|
+
};
|
|
25
|
+
config?: {
|
|
26
|
+
type: 'file';
|
|
27
|
+
originalPath: string;
|
|
28
|
+
archivePath: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class ZipArchiver {
|
|
33
|
+
/**
|
|
34
|
+
* Create a ZIP archive containing the specified input and config files/directories
|
|
35
|
+
*/
|
|
36
|
+
async createArchive(options: ZipArchiveOptions): Promise<Result<ZipArchiveResult>> {
|
|
37
|
+
try {
|
|
38
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
39
|
+
const outputDir = options.outputDir || path.join(os.homedir(), 'Downloads');
|
|
40
|
+
const zipFileName = `ts-res-bundle-${timestamp}.zip`;
|
|
41
|
+
const zipPath = path.join(outputDir, zipFileName);
|
|
42
|
+
|
|
43
|
+
// Ensure output directory exists
|
|
44
|
+
if (!fs.existsSync(outputDir)) {
|
|
45
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const output = fs.createWriteStream(zipPath);
|
|
49
|
+
const archive = archiver.create('zip', {
|
|
50
|
+
zlib: { level: 6 } // Good compression level
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Create manifest
|
|
54
|
+
const manifest: ZipManifest = {
|
|
55
|
+
timestamp: new Date().toISOString()
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Promise to handle async archiving
|
|
59
|
+
const archivePromise = new Promise<void>((resolve, reject) => {
|
|
60
|
+
output.on('close', () => {
|
|
61
|
+
resolve();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
output.on('error', (err: Error) => {
|
|
65
|
+
reject(err);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
archive.on('error', (err: Error) => {
|
|
69
|
+
reject(err);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Pipe archive data to the file
|
|
74
|
+
archive.pipe(output);
|
|
75
|
+
|
|
76
|
+
// Add input files/directory
|
|
77
|
+
if (options.input) {
|
|
78
|
+
const inputPath = path.resolve(options.input);
|
|
79
|
+
|
|
80
|
+
if (!fs.existsSync(inputPath)) {
|
|
81
|
+
return fail(`Input path does not exist: ${inputPath}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const stats = fs.statSync(inputPath);
|
|
85
|
+
if (stats.isDirectory()) {
|
|
86
|
+
// Add entire directory recursively, preserving structure
|
|
87
|
+
const dirName = path.basename(inputPath);
|
|
88
|
+
archive.directory(inputPath, `input/${dirName}`);
|
|
89
|
+
manifest.input = {
|
|
90
|
+
type: 'directory',
|
|
91
|
+
originalPath: inputPath,
|
|
92
|
+
archivePath: `input/${dirName}`
|
|
93
|
+
};
|
|
94
|
+
} else if (stats.isFile()) {
|
|
95
|
+
// Add single file
|
|
96
|
+
const fileName = path.basename(inputPath);
|
|
97
|
+
archive.file(inputPath, { name: `input/${fileName}` });
|
|
98
|
+
manifest.input = {
|
|
99
|
+
type: 'file',
|
|
100
|
+
originalPath: inputPath,
|
|
101
|
+
archivePath: `input/${fileName}`
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Add config file
|
|
107
|
+
if (options.config) {
|
|
108
|
+
const configPath = path.resolve(options.config);
|
|
109
|
+
|
|
110
|
+
if (!fs.existsSync(configPath)) {
|
|
111
|
+
return fail(`Config file does not exist: ${configPath}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const stats = fs.statSync(configPath);
|
|
115
|
+
if (!stats.isFile()) {
|
|
116
|
+
return fail(`Config path must be a file: ${configPath}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const fileName = path.basename(configPath);
|
|
120
|
+
archive.file(configPath, { name: `config/${fileName}` });
|
|
121
|
+
manifest.config = {
|
|
122
|
+
type: 'file',
|
|
123
|
+
originalPath: configPath,
|
|
124
|
+
archivePath: `config/${fileName}`
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Add manifest
|
|
129
|
+
archive.append(JSON.stringify(manifest, null, 2), { name: 'manifest.json' });
|
|
130
|
+
|
|
131
|
+
// Finalize the archive
|
|
132
|
+
await archive.finalize();
|
|
133
|
+
await archivePromise;
|
|
134
|
+
|
|
135
|
+
return succeed({
|
|
136
|
+
zipPath,
|
|
137
|
+
manifest
|
|
138
|
+
});
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return fail(`Failed to create ZIP archive: ${error instanceof Error ? error.message : String(error)}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get the default downloads directory path
|
|
146
|
+
*/
|
|
147
|
+
getDefaultDownloadsDir(): string {
|
|
148
|
+
return path.join(os.homedir(), 'Downloads');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Export singleton instance
|
|
153
|
+
export const zipArchiver = new ZipArchiver();
|