@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,149 @@
1
+ /**
2
+ * SVG to Vector Drawable Conversion Utility
3
+ *
4
+ * Converts SVG content to Android Vector Drawable XML format using vd-tool
5
+ */
6
+ import { writeFile, unlink, mkdtemp, readFile } from 'fs/promises';
7
+ import { join } from 'path';
8
+ import { tmpdir } from 'os';
9
+ import { vdConvert } from 'vd-tool';
10
+ /**
11
+ * Validates SVG content format
12
+ *
13
+ * @param svgContent - The SVG content to validate
14
+ * @returns Validation result with isValid boolean and errors array
15
+ */
16
+ export function validateSvgContent(svgContent) {
17
+ const errors = [];
18
+ if (!svgContent || typeof svgContent !== 'string') {
19
+ errors.push('SVG content is required and must be a string');
20
+ }
21
+ else {
22
+ if (svgContent.trim().length === 0) {
23
+ errors.push('SVG content cannot be empty');
24
+ }
25
+ if (!svgContent.includes('<svg')) {
26
+ errors.push('SVG content must contain an opening <svg> tag');
27
+ }
28
+ if (!svgContent.includes('</svg>')) {
29
+ errors.push('SVG content must contain a closing </svg> tag');
30
+ }
31
+ // Check for basic XML structure
32
+ const openTags = (svgContent.match(/<svg[^>]*>/g) || []).length;
33
+ const closeTags = (svgContent.match(/<\/svg>/g) || []).length;
34
+ if (openTags !== closeTags) {
35
+ errors.push('SVG content has mismatched <svg> tags');
36
+ }
37
+ }
38
+ return {
39
+ isValid: errors.length === 0,
40
+ errors
41
+ };
42
+ }
43
+ /**
44
+ * Applies customizations to the Vector Drawable XML
45
+ *
46
+ * @param vectorDrawableXml - The Vector Drawable XML content
47
+ * @param options - Customization options
48
+ * @returns Customized Vector Drawable XML
49
+ */
50
+ function applyCustomizations(vectorDrawableXml, options) {
51
+ let customizedXml = vectorDrawableXml;
52
+ // Apply tint if specified
53
+ if (options.tint) {
54
+ customizedXml = customizedXml.replace(/<vector([^>]*)>/, `<vector$1 android:tint="${options.tint}">`);
55
+ }
56
+ return customizedXml;
57
+ }
58
+ /**
59
+ * Cleans up temporary files and directories
60
+ *
61
+ * @param svgFile - Path to temporary SVG file
62
+ * @param vdFile - Path to temporary Vector Drawable file
63
+ * @param tempDir - Path to temporary directory
64
+ */
65
+ async function cleanup(svgFile, vdFile, tempDir) {
66
+ try {
67
+ if (svgFile)
68
+ await unlink(svgFile).catch(() => { });
69
+ if (vdFile)
70
+ await unlink(vdFile).catch(() => { });
71
+ if (tempDir) {
72
+ const { rm } = await import('fs/promises');
73
+ await rm(tempDir, { recursive: true, force: true }).catch(() => { });
74
+ }
75
+ }
76
+ catch (error) {
77
+ // Ignore cleanup errors
78
+ }
79
+ }
80
+ /**
81
+ * Converts SVG content to Android Vector Drawable XML format
82
+ *
83
+ * @param svgContent - The SVG content to convert
84
+ * @param options - Conversion options
85
+ * @returns Conversion result with vectorDrawable XML and optional warnings
86
+ * @throws Error if conversion fails
87
+ */
88
+ export async function convertSvgToVectorDrawable(svgContent, options = {}) {
89
+ // Input validation
90
+ if (!svgContent || typeof svgContent !== 'string') {
91
+ throw new Error('SVG content is required and must be a string');
92
+ }
93
+ if (svgContent.trim().length === 0) {
94
+ throw new Error('SVG content cannot be empty');
95
+ }
96
+ // Basic SVG format validation
97
+ if (!svgContent.includes('<svg') || !svgContent.includes('</svg>')) {
98
+ throw new Error('Invalid SVG format: must contain <svg> tags');
99
+ }
100
+ let tempDir = null;
101
+ let tempSvgFile = null;
102
+ let tempVdFile = null;
103
+ try {
104
+ // Create temporary directory
105
+ tempDir = await mkdtemp(join(tmpdir(), 'svg-to-vd-'));
106
+ tempSvgFile = join(tempDir, 'input.svg');
107
+ tempVdFile = join(tempDir, 'input.xml');
108
+ // Write SVG content to temporary file
109
+ await writeFile(tempSvgFile, svgContent, 'utf8');
110
+ // Use vd-tool library for conversion
111
+ try {
112
+ await vdConvert(tempSvgFile, {
113
+ outDir: tempDir
114
+ });
115
+ }
116
+ catch (conversionError) {
117
+ const errorMessage = conversionError.message || 'Unknown conversion error';
118
+ throw new Error(`SVG to Vector Drawable conversion failed: ${errorMessage}`);
119
+ }
120
+ // Read the generated Vector Drawable XML
121
+ let vectorDrawableContent;
122
+ try {
123
+ vectorDrawableContent = await readFile(tempVdFile, 'utf8');
124
+ }
125
+ catch (readError) {
126
+ throw new Error('Failed to read converted Vector Drawable file');
127
+ }
128
+ // Apply customizations if provided
129
+ if (options.tint) {
130
+ vectorDrawableContent = applyCustomizations(vectorDrawableContent, options);
131
+ }
132
+ // Clean up temporary files
133
+ await cleanup(tempSvgFile, tempVdFile, tempDir);
134
+ return {
135
+ vectorDrawable: vectorDrawableContent,
136
+ warnings: []
137
+ };
138
+ }
139
+ catch (error) {
140
+ // Clean up temporary files in case of error
141
+ if (tempSvgFile || tempVdFile || tempDir) {
142
+ await cleanup(tempSvgFile, tempVdFile, tempDir).catch(() => {
143
+ // Ignore cleanup errors
144
+ });
145
+ }
146
+ throw error;
147
+ }
148
+ }
149
+ //# sourceMappingURL=svg-converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-converter.js","sourceRoot":"","sources":["../../src/utils/svg-converter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "@khoaha/spek-cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "CLI tool to download and extract Figma design specs from Directus",
5
5
  "type": "module",
6
+ "files": [
7
+ "dist",
8
+ "bin",
9
+ "README.md",
10
+ "QUICKSTART.md"
11
+ ],
6
12
  "bin": {
7
13
  "spek-cli": "./bin/cli.js"
8
14
  },
@@ -1,286 +0,0 @@
1
- # CLI Tool Architecture
2
-
3
- ## Overview
4
-
5
- `spek-cli` is a standalone CLI tool for downloading and extracting Figma design specs from Directus vault storage. It's built with TypeScript and uses the official Directus SDK for authentication and file downloads.
6
-
7
- ## Architecture Diagram
8
-
9
- ```
10
- ┌─────────────────────────────────────────────────────────────┐
11
- │ User │
12
- └────────────────────┬────────────────────────────────────────┘
13
-
14
-
15
- ┌─────────────────────────────────────────────────────────────┐
16
- │ CLI Entry Point │
17
- │ (src/index.ts) │
18
- │ • Parse arguments (-d, --download, --help, --version) │
19
- │ • Orchestrate workflow │
20
- └────────────┬────────────────────────────────────────────────┘
21
-
22
-
23
- ┌─────────────────────────────────────────────────────────────┐
24
- │ Configuration Manager │
25
- │ (src/config/manager.ts) │
26
- │ • Check if config exists │
27
- │ • Load from ~/.spek-cli/config.json │
28
- │ • Save new configuration │
29
- └────────────┬────────────────────────────────────────────────┘
30
-
31
-
32
- ┌─────────────────────────────────────────────────────────────┐
33
- │ Prompts Module │
34
- │ (src/prompts/index.ts) │
35
- │ • Prompt for Directus URL (first run) │
36
- │ • Prompt for access token (first run) │
37
- │ • Prompt for file ID (interactive mode) │
38
- │ • Prompt for overwrite confirmation │
39
- └────────────┬────────────────────────────────────────────────┘
40
-
41
-
42
- ┌─────────────────────────────────────────────────────────────┐
43
- │ Directus Client │
44
- │ (src/directus/client.ts) │
45
- │ • Create authenticated Directus SDK client │
46
- │ • Download file using readAssetRaw() │
47
- │ • Handle authentication and errors │
48
- └────────────┬────────────────────────────────────────────────┘
49
-
50
-
51
- ┌─────────────────────────────────────────────────────────────┐
52
- │ Download Handler │
53
- │ (src/download/handler.ts) │
54
- │ • Download file to temp location │
55
- │ • Validate ZIP file │
56
- │ • Check for existing files │
57
- │ • Extract to current working directory │
58
- │ • Cleanup temp files │
59
- └─────────────────────────────────────────────────────────────┘
60
- ```
61
-
62
- ## Module Breakdown
63
-
64
- ### 1. Entry Point (`src/index.ts`)
65
-
66
- **Responsibilities:**
67
- - Parse command-line arguments
68
- - Check/initialize configuration
69
- - Orchestrate the download workflow
70
- - Handle errors and display results
71
-
72
- **Key Functions:**
73
- - `parseArgs()` - Parse CLI arguments
74
- - `showHelp()` - Display help message
75
- - `showVersion()` - Display version
76
- - `main()` - Main entry point
77
-
78
- **Flow:**
79
- ```
80
- 1. Parse arguments
81
- 2. Load or initialize config
82
- 3. Get file ID (from args or prompt)
83
- 4. Call download handler
84
- 5. Display result
85
- ```
86
-
87
- ### 2. Configuration Manager (`src/config/manager.ts`)
88
-
89
- **Responsibilities:**
90
- - Manage configuration file at `~/.spek-cli/config.json`
91
- - Load, save, and validate configuration
92
- - Ensure config directory exists
93
-
94
- **Key Functions:**
95
- - `configExists()` - Check if config file exists
96
- - `loadConfig()` - Load configuration from disk
97
- - `saveConfig()` - Save configuration to disk
98
- - `getConfigPath()` - Get config file path
99
-
100
- **Configuration Structure:**
101
- ```typescript
102
- interface VaultConfig {
103
- directusUrl: string; // e.g., https://my.directus.app
104
- accessToken: string; // Directus access token
105
- createdAt: string; // ISO timestamp
106
- }
107
- ```
108
-
109
- ### 3. Prompts Module (`src/prompts/index.ts`)
110
-
111
- **Responsibilities:**
112
- - Interactive user input collection
113
- - Validation of user inputs
114
- - Confirmation dialogs
115
-
116
- **Key Functions:**
117
- - `promptForConfig()` - First-run configuration setup
118
- - `promptForFileId()` - Get file ID in interactive mode
119
- - `promptOverwrite()` - Confirm overwrite of existing files
120
-
121
- **Uses:** `prompts` package (v2.4.2) for user-friendly CLI prompts
122
-
123
- ### 4. Directus Client (`src/directus/client.ts`)
124
-
125
- **Responsibilities:**
126
- - Create authenticated Directus SDK client
127
- - Download files from Directus assets
128
- - Handle authentication and API errors
129
-
130
- **Key Functions:**
131
- - `createAuthenticatedClient()` - Initialize Directus client
132
- - `downloadFile()` - Download file by ID
133
-
134
- **Error Handling:**
135
- - 401: Authentication failed
136
- - 404: File not found
137
- - Network errors: Connection issues
138
-
139
- **Implementation Details:**
140
- - Uses `@directus/sdk` with `authentication()` and `rest()` modules
141
- - Converts `ReadableStream` to `Buffer` for file processing
142
- - Sets access token before making requests
143
-
144
- ### 5. Download Handler (`src/download/handler.ts`)
145
-
146
- **Responsibilities:**
147
- - Orchestrate download and extraction process
148
- - Validate ZIP files
149
- - Check for file conflicts
150
- - Extract to current working directory
151
- - Cleanup temporary files
152
-
153
- **Key Functions:**
154
- - `checkExistingFiles()` - Check if extraction would overwrite files
155
- - `handleDownload()` - Main download and extract workflow
156
-
157
- **Flow:**
158
- ```
159
- 1. Download file from Directus
160
- 2. Save to temp file
161
- 3. Validate ZIP structure
162
- 4. Check for existing files
163
- 5. Prompt for overwrite if needed
164
- 6. Extract to CWD
165
- 7. Cleanup temp files
166
- 8. Return result
167
- ```
168
-
169
- **Uses:** `adm-zip` for ZIP file operations
170
-
171
- ## Data Flow
172
-
173
- ```
174
- User Input
175
-
176
- CLI Arguments / Prompts
177
-
178
- Configuration (from file or new setup)
179
-
180
- Directus SDK Client
181
-
182
- Download File (via Directus API)
183
-
184
- Temp File Storage
185
-
186
- ZIP Validation
187
-
188
- Overwrite Check
189
-
190
- Extract to CWD
191
-
192
- Cleanup & Result
193
- ```
194
-
195
- ## Error Handling Strategy
196
-
197
- ### Configuration Errors
198
- - Missing config → Auto-trigger setup wizard
199
- - Invalid config → Show error, suggest re-setup
200
-
201
- ### Authentication Errors
202
- - 401 Unauthorized → Check access token message
203
- - Invalid URL → Validation during setup
204
-
205
- ### Download Errors
206
- - 404 Not Found → File ID doesn't exist
207
- - Network errors → Connection issues
208
- - Timeout → Retry suggestion
209
-
210
- ### Extraction Errors
211
- - Invalid ZIP → Corrupted file message
212
- - Permission errors → Write access issues
213
- - Disk space → Insufficient space
214
-
215
- ### User Cancellation
216
- - Ctrl+C during prompts → Graceful exit
217
- - Overwrite declined → Cancel operation
218
-
219
- ## Dependencies
220
-
221
- ### Production Dependencies
222
- - `@directus/sdk` (^17.0.0) - Official Directus SDK
223
- - `prompts` (^2.4.2) - Interactive CLI prompts
224
- - `adm-zip` (^0.5.10) - ZIP file operations
225
- - `chalk` (^5.3.0) - Terminal colors
226
-
227
- ### Development Dependencies
228
- - `typescript` (^5.3.3) - TypeScript compiler
229
- - `@types/node` (^20.11.0) - Node.js type definitions
230
- - `@types/adm-zip` (^0.5.5) - adm-zip type definitions
231
- - `@types/prompts` (^2.4.9) - prompts type definitions
232
-
233
- ## Build System
234
-
235
- **Compiler:** TypeScript 5.3.3
236
-
237
- **Target:** ES2022 with Node.js modules
238
-
239
- **Output:** `dist/` directory with compiled JavaScript + source maps
240
-
241
- **Entry Point:** `dist/index.js` (with shebang for CLI execution)
242
-
243
- ## Configuration File Location
244
-
245
- **Path:** `~/.spek-cli/config.json`
246
-
247
- **Platform-specific:**
248
- - Windows: `C:\Users\<username>\.spek-cli\config.json`
249
- - macOS: `/Users/<username>/.spek-cli/config.json`
250
- - Linux: `/home/<username>/.spek-cli/config.json`
251
-
252
- ## Security Considerations
253
-
254
- 1. **Access Token Storage**
255
- - Stored in user's home directory
256
- - File permissions should be restricted (user-only)
257
- - Never logged or displayed in output
258
-
259
- 2. **HTTPS Enforcement**
260
- - Directus URL validated to be valid URL
261
- - SDK handles HTTPS connections
262
-
263
- 3. **Input Validation**
264
- - URL validation during setup
265
- - File ID passed through without modification
266
- - No shell command injection risks
267
-
268
- ## Performance Characteristics
269
-
270
- - **Download Speed:** Limited by network and Directus server
271
- - **Memory Usage:** Streams file to temp, then loads ZIP into memory
272
- - **Disk Usage:** Temporary file during download (auto-cleaned)
273
- - **Startup Time:** ~100ms for config load + argument parsing
274
-
275
- ## Future Enhancements
276
-
277
- Potential features for future versions:
278
-
279
- 1. **Progress Bar:** Show download progress for large files
280
- 2. **Resume Downloads:** Support partial download resume
281
- 3. **Batch Downloads:** Download multiple files at once
282
- 4. **Config Management:** Commands to view/edit/reset config
283
- 5. **Dry Run:** Preview what would be extracted without extracting
284
- 6. **Custom Output:** Specify extraction directory
285
- 7. **Compression:** Support other archive formats
286
- 8. **Logging:** Verbose mode with detailed logs
@@ -1,135 +0,0 @@
1
- # 🚀 Quick Publish Reference
2
-
3
- ## Pre-Publish Checklist
4
-
5
- ```bash
6
- # 1. Verify token is configured
7
- cat .env | grep NPM_ACCESS_TOKEN
8
-
9
- # 2. Clean build
10
- npm run build
11
-
12
- # 3. Test locally
13
- node dist/index.js --help
14
- node dist/index.js --version
15
-
16
- # 4. Dry run
17
- npm publish --dry-run
18
- ```
19
-
20
- ## Publish Commands
21
-
22
- ### Linux/macOS
23
- ```bash
24
- # Make executable (first time only)
25
- chmod +x scripts/publish.sh
26
-
27
- # Publish (choose one)
28
- ./scripts/publish.sh # Patch: 1.0.0 → 1.0.1
29
- ./scripts/publish.sh minor # Minor: 1.0.0 → 1.1.0
30
- ./scripts/publish.sh major # Major: 1.0.0 → 2.0.0
31
- ./scripts/publish.sh 2.5.3 # Specific version
32
- ```
33
-
34
- ### Windows (PowerShell)
35
- ```powershell
36
- # Publish (choose one)
37
- .\scripts\publish.ps1 # Patch: 1.0.0 → 1.0.1
38
- .\scripts\publish.ps1 minor # Minor: 1.0.0 → 1.1.0
39
- .\scripts\publish.ps1 major # Major: 1.0.0 → 2.0.0
40
- .\scripts\publish.ps1 2.5.3 # Specific version
41
- ```
42
-
43
- ### Or Use npm Scripts
44
- ```bash
45
- npm run publish:patch # 1.0.0 → 1.0.1
46
- npm run publish:minor # 1.0.0 → 1.1.0
47
- npm run publish:major # 1.0.0 → 2.0.0
48
- ```
49
-
50
- ## Post-Publish
51
-
52
- ```bash
53
- # 1. Verify on npm
54
- https://www.npmjs.com/package/spek-cli
55
-
56
- # 2. Test installation
57
- npx spek-cli@latest --version
58
-
59
- # 3. Push git tag
60
- git push origin v1.0.0
61
-
62
- # 4. Test full workflow
63
- npx spek-cli -d <test-file-id>
64
- ```
65
-
66
- ## Quick Test
67
-
68
- ```bash
69
- # Test without publishing
70
- npm link
71
- spek-cli --help
72
- spek-cli --version
73
- npm unlink -g spek-cli
74
- ```
75
-
76
- ## Environment
77
-
78
- Required in `.env`:
79
- ```bash
80
- NPM_ACCESS_TOKEN=npm_xxxxxxxxxxxxxxxxxxxxxx
81
- ```
82
-
83
- ## What the Script Does
84
-
85
- 1. ✓ Checks git status
86
- 2. ✓ Clean installs dependencies
87
- 3. ✓ Builds TypeScript
88
- 4. ✓ Verifies build output
89
- 5. ✓ Bumps version
90
- 6. ✓ Creates .npmrc with token
91
- 7. ✓ Runs dry-run
92
- 8. ✓ Asks for confirmation
93
- 9. ✓ Publishes to npm
94
- 10. ✓ Cleans up .npmrc
95
- 11. ✓ Creates git tag
96
- 12. ✓ Shows success message
97
-
98
- ## Troubleshooting
99
-
100
- ### "NPM_ACCESS_TOKEN not found"
101
- ```bash
102
- # Check .env file exists
103
- ls -la .env
104
-
105
- # Create if missing
106
- echo "NPM_ACCESS_TOKEN=your-token-here" > .env
107
- ```
108
-
109
- ### "401 Unauthorized"
110
- - Generate new token at https://www.npmjs.com/settings/~/tokens
111
- - Update `.env` with new token
112
-
113
- ### "403 Forbidden"
114
- - Package name already exists
115
- - Or insufficient token permissions
116
-
117
- ### Build fails
118
- ```bash
119
- rm -rf dist node_modules
120
- npm install
121
- npm run build
122
- ```
123
-
124
- ## Quick Links
125
-
126
- - **Publishing Guide**: `docs/PUBLISHING.md`
127
- - **npm Registry**: https://www.npmjs.com/package/spek-cli
128
- - **Token Settings**: https://www.npmjs.com/settings/~/tokens
129
- - **Rename Summary**: `RENAME_COMPLETE.md`
130
-
131
- ---
132
-
133
- **Current Version**: 1.0.0 (unpublished)
134
- **Ready**: ✅ Yes - All files updated and tested
135
- **Next**: Run publish script