@khoaha/spek-cli 1.0.4 → 1.0.5

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 (56) hide show
  1. package/dist/commands/svg-to-vd/handler.d.ts +14 -0
  2. package/dist/commands/svg-to-vd/handler.d.ts.map +1 -0
  3. package/dist/commands/svg-to-vd/handler.js +119 -0
  4. package/dist/commands/svg-to-vd/handler.js.map +1 -0
  5. package/dist/config/manager.d.ts +18 -0
  6. package/dist/config/manager.d.ts.map +1 -0
  7. package/dist/config/manager.js +53 -0
  8. package/dist/config/manager.js.map +1 -0
  9. package/dist/directus/client.d.ts +14 -0
  10. package/dist/directus/client.d.ts.map +1 -0
  11. package/dist/directus/client.js +81 -0
  12. package/dist/directus/client.js.map +1 -0
  13. package/dist/download/handler.d.ts +6 -0
  14. package/dist/download/handler.d.ts.map +1 -0
  15. package/dist/download/handler.js +100 -0
  16. package/dist/download/handler.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +209 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/prompts/index.d.ts +14 -0
  22. package/dist/prompts/index.d.ts.map +1 -0
  23. package/dist/prompts/index.js +69 -0
  24. package/dist/prompts/index.js.map +1 -0
  25. package/dist/types/index.d.ts +67 -0
  26. package/dist/types/index.d.ts.map +1 -0
  27. package/dist/types/index.js +2 -0
  28. package/dist/types/index.js.map +1 -0
  29. package/dist/utils/file-utils.d.ts +28 -0
  30. package/dist/utils/file-utils.d.ts.map +1 -0
  31. package/dist/utils/file-utils.js +61 -0
  32. package/dist/utils/file-utils.js.map +1 -0
  33. package/dist/utils/svg-converter.d.ts +44 -0
  34. package/dist/utils/svg-converter.d.ts.map +1 -0
  35. package/dist/utils/svg-converter.js +149 -0
  36. package/dist/utils/svg-converter.js.map +1 -0
  37. package/package.json +7 -1
  38. package/docs/ARCHITECTURE.md +0 -286
  39. package/docs/PUBLISH_QUICK_REFERENCE.md +0 -135
  40. package/docs/SVG_TO_VECTOR_DRAWABLE.md +0 -186
  41. package/docs/TESTING.md +0 -429
  42. package/docs/USAGE_EXAMPLES.md +0 -520
  43. package/docs/WINDOWS_DEVELOPMENT.md +0 -487
  44. package/docs/WORKFLOW.md +0 -479
  45. package/scripts/publish.ps1 +0 -193
  46. package/scripts/publish.sh +0 -170
  47. package/src/commands/svg-to-vd/handler.ts +0 -131
  48. package/src/config/manager.ts +0 -58
  49. package/src/directus/client.ts +0 -101
  50. package/src/download/handler.ts +0 -116
  51. package/src/index.ts +0 -231
  52. package/src/prompts/index.ts +0 -76
  53. package/src/types/index.ts +0 -72
  54. package/src/utils/file-utils.ts +0 -69
  55. package/src/utils/svg-converter.ts +0 -196
  56. package/tsconfig.json +0 -20
@@ -0,0 +1,14 @@
1
+ /**
2
+ * SVG to Vector Drawable Command Handler
3
+ *
4
+ * Handles the svg-to-vd command for converting SVG files/content to Android Vector Drawable XML
5
+ */
6
+ import type { SvgToVdOptions, SvgConversionResult } from '../../types/index.js';
7
+ /**
8
+ * Handle SVG to Vector Drawable conversion command
9
+ *
10
+ * @param options - Conversion options from CLI
11
+ * @returns Conversion result
12
+ */
13
+ export declare function handleSvgToVd(options: SvgToVdOptions): Promise<SvgConversionResult>;
14
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/commands/svg-to-vd/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiHzF"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * SVG to Vector Drawable Command Handler
3
+ *
4
+ * Handles the svg-to-vd command for converting SVG files/content to Android Vector Drawable XML
5
+ */
6
+ import chalk from 'chalk';
7
+ import { convertSvgToVectorDrawable, validateSvgContent } from '../../utils/svg-converter.js';
8
+ import { detectInputType, writeFileContent } from '../../utils/file-utils.js';
9
+ /**
10
+ * Handle SVG to Vector Drawable conversion command
11
+ *
12
+ * @param options - Conversion options from CLI
13
+ * @returns Conversion result
14
+ */
15
+ export async function handleSvgToVd(options) {
16
+ try {
17
+ console.log(chalk.blue('šŸ”„ Converting SVG to Vector Drawable...\n'));
18
+ // Validate required options
19
+ if (!options.input) {
20
+ return {
21
+ success: false,
22
+ error: 'Input is required. Use -i or --input to specify SVG file path or content.\n' +
23
+ chalk.dim('Example: spek-cli svg-to-vd -i ./icon.svg -o ./icon.xml')
24
+ };
25
+ }
26
+ if (!options.output) {
27
+ return {
28
+ success: false,
29
+ error: 'Output path is required. Use -o or --output to specify destination file path.\n' +
30
+ chalk.dim('Example: spek-cli svg-to-vd -i ./icon.svg -o ./drawables/icon.xml')
31
+ };
32
+ }
33
+ // Auto-detect input type (file path or SVG content)
34
+ console.log(chalk.dim('šŸ“ Detecting input type...'));
35
+ let svgContent;
36
+ let inputType;
37
+ try {
38
+ const detection = await detectInputType(options.input);
39
+ svgContent = detection.content;
40
+ inputType = detection.isFile ? 'file' : 'content';
41
+ if (detection.isFile) {
42
+ console.log(chalk.dim(` āœ“ Reading from file: ${options.input}`));
43
+ }
44
+ else {
45
+ console.log(chalk.dim(' āœ“ Using raw SVG content'));
46
+ }
47
+ }
48
+ catch (error) {
49
+ return {
50
+ success: false,
51
+ error: `Failed to read input: ${error.message}\n` +
52
+ chalk.dim('Tip: Check if the file path is correct or if the SVG content is valid.')
53
+ };
54
+ }
55
+ // Validate SVG content
56
+ console.log(chalk.dim('šŸ” Validating SVG content...'));
57
+ const validation = validateSvgContent(svgContent);
58
+ if (!validation.isValid) {
59
+ return {
60
+ success: false,
61
+ error: `Invalid SVG content:\n${validation.errors.map(e => ` • ${e}`).join('\n')}\n` +
62
+ chalk.dim('Tip: Ensure your SVG has proper opening and closing <svg> tags.')
63
+ };
64
+ }
65
+ console.log(chalk.dim(' āœ“ SVG content is valid'));
66
+ // Convert SVG to Vector Drawable
67
+ console.log(chalk.dim('āš™ļø Converting to Vector Drawable...'));
68
+ const conversionOptions = options.tint ? { tint: options.tint } : {};
69
+ let result;
70
+ try {
71
+ result = await convertSvgToVectorDrawable(svgContent, conversionOptions);
72
+ }
73
+ catch (error) {
74
+ return {
75
+ success: false,
76
+ error: `Conversion failed: ${error.message}\n` +
77
+ chalk.dim('Tip: Some complex SVG features may not be supported. Try simplifying your SVG.')
78
+ };
79
+ }
80
+ console.log(chalk.dim(' āœ“ Conversion successful'));
81
+ // Write output file
82
+ console.log(chalk.dim(`šŸ’¾ Writing to: ${options.output}`));
83
+ try {
84
+ await writeFileContent(options.output, result.vectorDrawable);
85
+ }
86
+ catch (error) {
87
+ return {
88
+ success: false,
89
+ error: `Failed to write output file: ${error.message}\n` +
90
+ chalk.dim('Tip: Check if you have write permissions for the output directory.')
91
+ };
92
+ }
93
+ console.log(chalk.dim(' āœ“ File written successfully'));
94
+ // Show warnings if any
95
+ if (result.warnings.length > 0) {
96
+ console.log(chalk.yellow('\nāš ļø Warnings:'));
97
+ result.warnings.forEach((warning) => {
98
+ console.log(chalk.yellow(` • ${warning}`));
99
+ });
100
+ }
101
+ // Show tint info if applied
102
+ if (options.tint) {
103
+ console.log(chalk.dim(`\nšŸŽØ Applied tint: ${options.tint}`));
104
+ }
105
+ console.log(chalk.green(`\nāœ“ Successfully converted to: ${options.output}`));
106
+ return {
107
+ success: true,
108
+ outputPath: options.output
109
+ };
110
+ }
111
+ catch (error) {
112
+ return {
113
+ success: false,
114
+ error: `Unexpected error: ${error.message}\n` +
115
+ chalk.dim('Please report this issue if it persists.')
116
+ };
117
+ }
118
+ }
119
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/commands/svg-to-vd/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { VaultConfig } from '../types/index.js';
2
+ /**
3
+ * Check if configuration file exists
4
+ */
5
+ export declare function configExists(): boolean;
6
+ /**
7
+ * Load configuration from ~/.spek-cli/config.json
8
+ */
9
+ export declare function loadConfig(): VaultConfig | null;
10
+ /**
11
+ * Save configuration to ~/.spek-cli/config.json
12
+ */
13
+ export declare function saveConfig(config: Omit<VaultConfig, 'createdAt'>): void;
14
+ /**
15
+ * Get config file path for display purposes
16
+ */
17
+ export declare function getConfigPath(): string;
18
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKrD;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,WAAW,GAAG,IAAI,CAW/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI,CAgBvE;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -0,0 +1,53 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
4
+ const CONFIG_DIR = join(homedir(), '.spek-cli');
5
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
6
+ /**
7
+ * Check if configuration file exists
8
+ */
9
+ export function configExists() {
10
+ return existsSync(CONFIG_FILE);
11
+ }
12
+ /**
13
+ * Load configuration from ~/.spek-cli/config.json
14
+ */
15
+ export function loadConfig() {
16
+ try {
17
+ if (!configExists()) {
18
+ return null;
19
+ }
20
+ const data = readFileSync(CONFIG_FILE, 'utf-8');
21
+ return JSON.parse(data);
22
+ }
23
+ catch (error) {
24
+ console.error('Error loading config:', error);
25
+ return null;
26
+ }
27
+ }
28
+ /**
29
+ * Save configuration to ~/.spek-cli/config.json
30
+ */
31
+ export function saveConfig(config) {
32
+ try {
33
+ // Ensure config directory exists
34
+ if (!existsSync(CONFIG_DIR)) {
35
+ mkdirSync(CONFIG_DIR, { recursive: true });
36
+ }
37
+ const fullConfig = {
38
+ ...config,
39
+ createdAt: new Date().toISOString(),
40
+ };
41
+ writeFileSync(CONFIG_FILE, JSON.stringify(fullConfig, null, 2), 'utf-8');
42
+ }
43
+ catch (error) {
44
+ throw new Error(`Failed to save config: ${error}`);
45
+ }
46
+ }
47
+ /**
48
+ * Get config file path for display purposes
49
+ */
50
+ export function getConfigPath() {
51
+ return CONFIG_FILE;
52
+ }
53
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAChD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAsC;IAC/D,IAAI,CAAC;QACH,iCAAiC;QACjC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,UAAU,GAAgB;YAC9B,GAAG,MAAM;YACT,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { VaultConfig, FileMetadata } from '../types/index.js';
2
+ /**
3
+ * Create authenticated Directus client
4
+ */
5
+ export declare function createAuthenticatedClient(config: VaultConfig): import("@directus/sdk").DirectusClient<any> & import("@directus/sdk").AuthenticationClient<any> & import("@directus/sdk").RestClient<any>;
6
+ /**
7
+ * Get file metadata from Directus
8
+ */
9
+ export declare function getFileMetadata(config: VaultConfig, fileId: string): Promise<FileMetadata>;
10
+ /**
11
+ * Download file from Directus using SDK
12
+ */
13
+ export declare function downloadFile(config: VaultConfig, fileId: string): Promise<Buffer>;
14
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/directus/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEnE;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,WAAW,6IAM5D;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CA4BvB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CA4CjB"}
@@ -0,0 +1,81 @@
1
+ import { createDirectus, rest, authentication, readAssetRaw, readFile } from '@directus/sdk';
2
+ /**
3
+ * Create authenticated Directus client
4
+ */
5
+ export function createAuthenticatedClient(config) {
6
+ const client = createDirectus(config.directusUrl)
7
+ .with(authentication('json'))
8
+ .with(rest());
9
+ return client;
10
+ }
11
+ /**
12
+ * Get file metadata from Directus
13
+ */
14
+ export async function getFileMetadata(config, fileId) {
15
+ try {
16
+ const client = createAuthenticatedClient(config);
17
+ // Set the access token
18
+ await client.setToken(config.accessToken);
19
+ // Get file metadata
20
+ const fileInfo = await client.request(readFile(fileId, {
21
+ fields: ['id', 'filename_download', 'title'],
22
+ }));
23
+ return {
24
+ id: fileInfo.id,
25
+ filename_download: fileInfo.filename_download || 'download.zip',
26
+ title: fileInfo.title,
27
+ };
28
+ }
29
+ catch (error) {
30
+ if (error?.response?.status === 401) {
31
+ throw new Error('Authentication failed. Please check your access token.');
32
+ }
33
+ if (error?.response?.status === 404) {
34
+ throw new Error(`File not found: ${fileId}`);
35
+ }
36
+ throw new Error(`Failed to get file metadata: ${error?.message || error}`);
37
+ }
38
+ }
39
+ /**
40
+ * Download file from Directus using SDK
41
+ */
42
+ export async function downloadFile(config, fileId) {
43
+ try {
44
+ const client = createAuthenticatedClient(config);
45
+ // Set the access token
46
+ await client.setToken(config.accessToken);
47
+ // Download the file
48
+ const fileData = await client.request(readAssetRaw(fileId));
49
+ // Convert ReadableStream to Buffer
50
+ if (fileData instanceof ReadableStream) {
51
+ const reader = fileData.getReader();
52
+ const chunks = [];
53
+ while (true) {
54
+ const { done, value } = await reader.read();
55
+ if (done)
56
+ break;
57
+ chunks.push(value);
58
+ }
59
+ const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
60
+ const result = new Uint8Array(totalLength);
61
+ let offset = 0;
62
+ for (const chunk of chunks) {
63
+ result.set(chunk, offset);
64
+ offset += chunk.length;
65
+ }
66
+ return Buffer.from(result);
67
+ }
68
+ // If it's already a buffer-like object
69
+ return Buffer.from(fileData);
70
+ }
71
+ catch (error) {
72
+ if (error?.response?.status === 401) {
73
+ throw new Error('Authentication failed. Please check your access token.');
74
+ }
75
+ if (error?.response?.status === 404) {
76
+ throw new Error(`File not found: ${fileId}`);
77
+ }
78
+ throw new Error(`Failed to download file: ${error?.message || error}`);
79
+ }
80
+ }
81
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/directus/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { VaultConfig, DownloadResult } from '../types/index.js';
2
+ /**
3
+ * Download and extract file from Directus
4
+ */
5
+ export declare function handleDownload(config: VaultConfig, fileId: string): Promise<DownloadResult>;
6
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/download/handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmBrE;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC,CAoFzB"}
@@ -0,0 +1,100 @@
1
+ import AdmZip from 'adm-zip';
2
+ import { existsSync, mkdirSync, writeFileSync, unlinkSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { tmpdir } from 'os';
5
+ import { downloadFile, getFileMetadata } from '../directus/client.js';
6
+ import { promptOverwrite } from '../prompts/index.js';
7
+ /**
8
+ * Get folder name from filename (remove .zip extension)
9
+ */
10
+ function getFolderNameFromFile(filename) {
11
+ // Remove .zip extension if present
12
+ const name = filename.replace(/\.zip$/i, '');
13
+ // Sanitize folder name (remove invalid characters)
14
+ return name.replace(/[<>:"/\\|?*]/g, '_');
15
+ }
16
+ /**
17
+ * Check if target directory exists
18
+ */
19
+ function checkDirectoryExists(targetPath) {
20
+ return existsSync(targetPath);
21
+ }
22
+ /**
23
+ * Download and extract file from Directus
24
+ */
25
+ export async function handleDownload(config, fileId) {
26
+ let tempFilePath = null;
27
+ try {
28
+ console.log(`\nšŸ“„ Downloading file: ${fileId}...`);
29
+ // Get file metadata to get the filename
30
+ const metadata = await getFileMetadata(config, fileId);
31
+ const folderName = getFolderNameFromFile(metadata.filename_download);
32
+ console.log(`šŸ“ File name: ${metadata.filename_download}`);
33
+ console.log(`šŸ“‚ Extract to folder: ${folderName}`);
34
+ // Download file from Directus
35
+ const fileBuffer = await downloadFile(config, fileId);
36
+ // Save to temp file
37
+ tempFilePath = join(tmpdir(), `spek-cli-${Date.now()}.zip`);
38
+ writeFileSync(tempFilePath, Buffer.from(fileBuffer));
39
+ console.log('āœ“ Download complete');
40
+ // Validate ZIP file
41
+ console.log('šŸ” Validating ZIP file...');
42
+ let zip;
43
+ try {
44
+ zip = new AdmZip(tempFilePath);
45
+ }
46
+ catch (error) {
47
+ throw new Error('Invalid or corrupted ZIP file');
48
+ }
49
+ const entries = zip.getEntries();
50
+ if (entries.length === 0) {
51
+ throw new Error('ZIP file is empty');
52
+ }
53
+ console.log('āœ“ ZIP file is valid');
54
+ // Create target directory path
55
+ const cwd = process.cwd();
56
+ const targetPath = join(cwd, folderName);
57
+ // Check if directory already exists
58
+ if (checkDirectoryExists(targetPath)) {
59
+ console.log(`\nāš ļø Warning: Directory "${folderName}" already exists`);
60
+ const shouldOverwrite = await promptOverwrite();
61
+ if (!shouldOverwrite) {
62
+ console.log('\nāŒ Operation cancelled by user');
63
+ return {
64
+ success: false,
65
+ error: 'User cancelled overwrite',
66
+ };
67
+ }
68
+ }
69
+ else {
70
+ // Create directory if it doesn't exist
71
+ mkdirSync(targetPath, { recursive: true });
72
+ }
73
+ // Extract to target directory
74
+ console.log('šŸ“¦ Extracting files...');
75
+ zip.extractAllTo(targetPath, true); // true = overwrite
76
+ console.log(`āœ“ Files extracted successfully to: ${folderName}/`);
77
+ return {
78
+ success: true,
79
+ extractPath: targetPath,
80
+ };
81
+ }
82
+ catch (error) {
83
+ return {
84
+ success: false,
85
+ error: error?.message || String(error),
86
+ };
87
+ }
88
+ finally {
89
+ // Cleanup temp file
90
+ if (tempFilePath && existsSync(tempFilePath)) {
91
+ try {
92
+ unlinkSync(tempFilePath);
93
+ }
94
+ catch {
95
+ // Ignore cleanup errors
96
+ }
97
+ }
98
+ }
99
+ }
100
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/download/handler.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACtE,OAAO,EAAE,IAAI,EAAY,MAAM,MAAM,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;GAEG;AACH,SAAS,qBAAqB,CAAC,QAAgB;IAC7C,mCAAmC;IACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC7C,mDAAmD;IACnD,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,OAAO,UAAU,CAAC,UAAU,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAmB,EACnB,MAAc;IAEd,IAAI,YAAY,GAAkB,IAAI,CAAC;IAEvC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,0BAA0B,MAAM,KAAK,CAAC,CAAC;QAEnD,wCAAwC;QACxC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,qBAAqB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;QAErE,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;QAEnD,8BAA8B;QAC9B,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEtD,oBAAoB;QACpB,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5D,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAEnC,oBAAoB;QACpB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAEnC,+BAA+B;QAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAEzC,oCAAoC;QACpC,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,6BAA6B,UAAU,kBAAkB,CAAC,CAAC;YACvE,MAAM,eAAe,GAAG,MAAM,eAAe,EAAE,CAAC;YAEhD,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gBAC/C,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,0BAA0B;iBAClC,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,uCAAuC;YACvC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,8BAA8B;QAC9B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,mBAAmB;QAEvD,OAAO,CAAC,GAAG,CAAC,sCAAsC,UAAU,GAAG,CAAC,CAAC;QAEjE,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,UAAU;SACxB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC;SACvC,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,oBAAoB;QACpB,IAAI,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,UAAU,CAAC,YAAY,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}