vcf-to-json-converter 1.0.0 → 1.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.
Files changed (5) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +457 -241
  3. package/index.d.ts +32 -32
  4. package/index.js +252 -252
  5. package/package.json +7 -6
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Shubhanshu Rao
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shubhanshu Rao
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,241 +1,457 @@
1
- # VCF to JSON Converter
2
-
3
- A lightweight Node.js library and CLI tool to convert VCF (vCard) files to JSON format.
4
-
5
- ## Features
6
-
7
- - 📱 Convert VCF/vCard files to structured JSON
8
- - 🔧 Programmatic API for Node.js applications
9
- - 💻 Command-line interface for quick conversions
10
- - 🛡️ Robust error handling
11
- - 📊 Extracts comprehensive contact information
12
- - 🎯 TypeScript-friendly
13
-
14
- ## Installation
15
-
16
- ### Global Installation (for CLI usage)
17
-
18
- ```bash
19
- npm install -g vcf-to-json-converter
20
- ```
21
-
22
- ### Local Installation (for programmatic usage)
23
-
24
- ```bash
25
- npm install vcf-to-json-converter
26
- ```
27
-
28
- ## Usage
29
-
30
- ### Command Line Interface
31
-
32
- Convert a VCF file to JSON:
33
-
34
- ```bash
35
- # Convert and display JSON in terminal
36
- vcf-to-json contacts.vcf
37
-
38
- # Convert and save to file
39
- vcf-to-json contacts.vcf output.json
40
-
41
- # Convert with compact formatting
42
- vcf-to-json contacts.vcf output.json --compact
43
- ```
44
-
45
- ### Programmatic Usage
46
-
47
- ```javascript
48
- const {
49
- vcfToJson,
50
- vcfToJsonFromFile,
51
- saveJsonToFile,
52
- } = require("vcf-to-json-converter");
53
-
54
- // Convert VCF text content to JSON
55
- const vcfContent = `BEGIN:VCARD
56
- VERSION:2.1
57
- FN:John Doe
58
- TEL:+1234567890
59
- EMAIL:john@example.com
60
- END:VCARD`;
61
-
62
- const contacts = vcfToJson(vcfContent);
63
- console.log(contacts);
64
-
65
- // Convert VCF file to JSON
66
- try {
67
- const contacts = vcfToJsonFromFile("./contacts.vcf");
68
- console.log(`Converted ${contacts.length} contacts`);
69
-
70
- // Save to JSON file
71
- saveJsonToFile(contacts, "./output.json");
72
- } catch (error) {
73
- console.error("Conversion failed:", error.message);
74
- }
75
- ```
76
-
77
- ## API Reference
78
-
79
- ### `vcfToJson(vcfText)`
80
-
81
- Converts VCF text content to JSON.
82
-
83
- - **Parameters:**
84
- - `vcfText` (string): The VCF content as a string
85
- - **Returns:** Array of contact objects
86
- - **Throws:** Error if VCF content is invalid
87
-
88
- ### `vcfToJsonFromFile(filePath)`
89
-
90
- Converts a VCF file to JSON.
91
-
92
- - **Parameters:**
93
- - `filePath` (string): Path to the VCF file
94
- - **Returns:** Array of contact objects
95
- - **Throws:** Error if file doesn't exist or is invalid
96
-
97
- ### `saveJsonToFile(jsonData, outputPath, prettyPrint)`
98
-
99
- Saves JSON data to a file.
100
-
101
- - **Parameters:**
102
- - `jsonData` (Array): The JSON data to save
103
- - `outputPath` (string): Path where to save the JSON file
104
- - `prettyPrint` (boolean, optional): Whether to format JSON with indentation (default: true)
105
-
106
- ## Output Format
107
-
108
- Each contact is converted to the following JSON structure:
109
-
110
- ```json
111
- {
112
- "fullName": "John Doe",
113
- "firstName": "John",
114
- "lastName": "Doe",
115
- "phones": [
116
- {
117
- "value": "+1234567890",
118
- "type": "CELL"
119
- }
120
- ],
121
- "emails": [
122
- {
123
- "value": "john@example.com",
124
- "type": "HOME"
125
- }
126
- ],
127
- "organization": "ACME Corp",
128
- "title": "Software Engineer",
129
- "note": "Important contact",
130
- "photo": "",
131
- "url": "",
132
- "raw": {
133
- /* Original parsed vCard object */
134
- }
135
- }
136
- ```
137
-
138
- ## Supported vCard Fields
139
-
140
- - **Name:** Full name, first name, last name
141
- - **Phone:** Multiple phone numbers with types
142
- - **Email:** Multiple email addresses with types
143
- - **Organization:** Company/organization name
144
- - **Title:** Job title
145
- - **Note:** Notes/comments
146
- - **Photo:** Photo data (base64)
147
- - **URL:** Website URLs
148
- - **Raw:** Complete original vCard data
149
-
150
- ## Error Handling
151
-
152
- The library provides comprehensive error handling for:
153
-
154
- - Invalid file paths
155
- - Missing files
156
- - Permission errors
157
- - Malformed VCF content
158
- - Invalid input parameters
159
-
160
- ## Examples
161
-
162
- ### Basic Conversion
163
-
164
- ```javascript
165
- const { vcfToJsonFromFile } = require("vcf-to-json-converter");
166
-
167
- const contacts = vcfToJsonFromFile("my-contacts.vcf");
168
- console.log(`Found ${contacts.length} contacts`);
169
-
170
- contacts.forEach((contact) => {
171
- console.log(
172
- `${contact.fullName}: ${contact.phones.map((p) => p.value).join(", ")}`
173
- );
174
- });
175
- ```
176
-
177
- ### Batch Processing
178
-
179
- ```javascript
180
- const fs = require("fs");
181
- const path = require("path");
182
- const { vcfToJsonFromFile, saveJsonToFile } = require("vcf-to-json-converter");
183
-
184
- const vcfFiles = fs
185
- .readdirSync("./vcf-files")
186
- .filter((f) => f.endsWith(".vcf"));
187
-
188
- vcfFiles.forEach((file) => {
189
- try {
190
- const contacts = vcfToJsonFromFile(path.join("./vcf-files", file));
191
- const outputFile = file.replace(".vcf", ".json");
192
- saveJsonToFile(contacts, path.join("./json-output", outputFile));
193
- console.log(`✅ Converted ${file} (${contacts.length} contacts)`);
194
- } catch (error) {
195
- console.error(`❌ Failed to convert ${file}:`, error.message);
196
- }
197
- });
198
- ```
199
-
200
- ## CLI Examples
201
-
202
- ```bash
203
- # Show help
204
- vcf-to-json --help
205
-
206
- # Convert single file
207
- vcf-to-json contacts.vcf
208
-
209
- # Convert and save to specific file
210
- vcf-to-json contacts.vcf my-contacts.json
211
-
212
- # Compact output
213
- vcf-to-json contacts.vcf contacts.json --compact
214
- ```
215
-
216
- ## Requirements
217
-
218
- - Node.js 12.0.0 or higher
219
- - npm or yarn
220
-
221
- ## Contributing
222
-
223
- 1. Fork the repository
224
- 2. Create a feature branch
225
- 3. Make your changes
226
- 4. Add tests if applicable
227
- 5. Submit a pull request
228
-
229
- ## License
230
-
231
- MIT License - see LICENSE file for details.
232
-
233
- ## Changelog
234
-
235
- ### 1.0.0
236
-
237
- - Initial release
238
- - CLI support
239
- - Comprehensive vCard field parsing
240
- - Error handling
241
- - TypeScript-friendly exports
1
+ # vcf-to-json-converter
2
+
3
+ [![npm version](https://badge.fury.io/js/vcf-to-json-converter.svg)](https://badge.fury.io/js/vcf-to-json-converter)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Node.js Version](https://img.shields.io/node/v/vcf-to-json-converter.svg)](https://nodejs.org/)
6
+ [![Downloads](https://img.shields.io/npm/dm/vcf-to-json-converter.svg)](https://npmjs.org/package/vcf-to-json-converter)
7
+
8
+ A lightweight, fast, and reliable Node.js library to convert VCF (vCard) files to structured JSON format with full CLI support.
9
+
10
+ ```javascript
11
+ const { vcfToJsonFromFile } = require("vcf-to-json-converter");
12
+
13
+ const contacts = vcfToJsonFromFile("./contacts.vcf");
14
+ console.log(contacts);
15
+ ```
16
+
17
+ ## Table of Contents
18
+
19
+ - [Features](#features)
20
+ - [Installation](#installation)
21
+ - [Quick Start](#quick-start)
22
+ - [Usage](#usage)
23
+ - [Command Line Interface](#command-line-interface)
24
+ - [Programmatic Usage](#programmatic-usage)
25
+ - [TypeScript](#typescript)
26
+ - [API Reference](#api-reference)
27
+ - [Output Format](#output-format)
28
+ - [Supported vCard Fields](#supported-vcard-fields)
29
+ - [Examples](#examples)
30
+ - [Troubleshooting](#troubleshooting)
31
+ - [Contributing](#contributing)
32
+ - [License](#license)
33
+
34
+ ## Features
35
+
36
+ - **Complete VCF Support** - Convert VCF/vCard files (v2.1, v3.0, v4.0) to structured JSON
37
+ - **Programmatic API** - Easy integration into Node.js applications
38
+ - **CLI Tool** - Command-line interface for quick conversions
39
+ - **Robust Error Handling** - Comprehensive error handling and validation
40
+ - **Rich Data Extraction** - Extracts all contact information including photos, organizations, and notes
41
+ - **TypeScript Ready** - Full TypeScript definitions included
42
+ - **High Performance** - Efficiently processes large VCF files with multiple contacts
43
+ - **Cross Platform** - Works on Windows, macOS, and Linux
44
+ - **Zero Dependencies** - No external dependencies for maximum compatibility
45
+ - **UTF-8 Support** - Handles international characters and emojis correctly
46
+
47
+ ## Installation
48
+
49
+ Using npm:
50
+
51
+ ```bash
52
+ npm install vcf-to-json-converter
53
+ ```
54
+
55
+ For global CLI usage:
56
+
57
+ ```bash
58
+ npm install -g vcf-to-json-converter
59
+ ```
60
+
61
+ Using yarn:
62
+
63
+ ```bash
64
+ yarn add vcf-to-json-converter
65
+ ```
66
+
67
+ ## Quick Start
68
+
69
+ ```bash
70
+ # Install globally for CLI
71
+ npm install -g vcf-to-json-converter
72
+
73
+ # Convert a VCF file
74
+ vcf-to-json contacts.vcf output.json
75
+ ```
76
+
77
+ ```javascript
78
+ // Use in your Node.js project
79
+ const { vcfToJsonFromFile } = require("vcf-to-json-converter");
80
+
81
+ const contacts = vcfToJsonFromFile("./contacts.vcf");
82
+ console.log(`Converted ${contacts.length} contacts`);
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ ### Command Line Interface
88
+
89
+ ```bash
90
+ # Convert and display JSON in terminal
91
+ vcf-to-json contacts.vcf
92
+
93
+ # Convert and save to file
94
+ vcf-to-json contacts.vcf output.json
95
+
96
+ # Convert with compact formatting (minified JSON)
97
+ vcf-to-json contacts.vcf output.json --compact
98
+
99
+ # Show help and version
100
+ vcf-to-json --help
101
+ vcf-to-json --version
102
+ ```
103
+
104
+ ### Programmatic Usage
105
+
106
+ ```javascript
107
+ const {
108
+ vcfToJson,
109
+ vcfToJsonFromFile,
110
+ saveJsonToFile,
111
+ } = require("vcf-to-json-converter");
112
+
113
+ // Method 1: Convert VCF text content
114
+ const vcfContent = `BEGIN:VCARD
115
+ VERSION:3.0
116
+ FN:John Doe
117
+ N:Doe;John;;;
118
+ TEL;TYPE=CELL:+1234567890
119
+ EMAIL;TYPE=HOME:john@example.com
120
+ ORG:ACME Corp
121
+ TITLE:Software Engineer
122
+ END:VCARD`;
123
+
124
+ const contacts = vcfToJson(vcfContent);
125
+ console.log("Parsed contacts:", contacts.length);
126
+
127
+ // Method 2: Convert VCF file directly
128
+ try {
129
+ const contacts = vcfToJsonFromFile("./contacts.vcf");
130
+ console.log(`Converted ${contacts.length} contacts`);
131
+
132
+ // Save to JSON file with pretty formatting
133
+ saveJsonToFile(contacts, "./output.json", true);
134
+
135
+ // Access contact data
136
+ contacts.forEach((contact) => {
137
+ console.log(
138
+ `${contact.fullName}: ${contact.phones.length} phones, ${contact.emails.length} emails`
139
+ );
140
+ });
141
+ } catch (error) {
142
+ console.error("Conversion failed:", error.message);
143
+ }
144
+ ```
145
+
146
+ ### TypeScript
147
+
148
+ ```typescript
149
+ import { vcfToJsonFromFile, Contact } from "vcf-to-json-converter";
150
+
151
+ const contacts: Contact[] = vcfToJsonFromFile("./contacts.vcf");
152
+ console.log(contacts);
153
+ ```
154
+
155
+ ## API Reference
156
+
157
+ ### `vcfToJson(vcfText: string): Contact[]`
158
+
159
+ Converts VCF text content to JSON.
160
+
161
+ **Parameters:**
162
+
163
+ - `vcfText` _(string)_: The VCF content as a string
164
+
165
+ **Returns:** Array of contact objects
166
+
167
+ **Throws:** Error if VCF content is invalid
168
+
169
+ **Example:**
170
+
171
+ ```javascript
172
+ const contacts = vcfToJson("BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nEND:VCARD");
173
+ ```
174
+
175
+ ### `vcfToJsonFromFile(filePath: string): Contact[]`
176
+
177
+ Converts a VCF file to JSON.
178
+
179
+ **Parameters:**
180
+
181
+ - `filePath` _(string)_: Path to the VCF file
182
+
183
+ **Returns:** Array of contact objects
184
+
185
+ **Throws:** Error if file doesn't exist or is invalid
186
+
187
+ **Example:**
188
+
189
+ ```javascript
190
+ const contacts = vcfToJsonFromFile("./my-contacts.vcf");
191
+ ```
192
+
193
+ ### `saveJsonToFile(jsonData: Contact[], outputPath: string, prettyPrint?: boolean): void`
194
+
195
+ Saves JSON data to a file.
196
+
197
+ **Parameters:**
198
+
199
+ - `jsonData` _(Contact[])_: The JSON data to save
200
+ - `outputPath` _(string)_: Path where to save the JSON file
201
+ - `prettyPrint` _(boolean, optional)_: Whether to format JSON with indentation (default: true)
202
+
203
+ **Example:**
204
+
205
+ ```javascript
206
+ saveJsonToFile(contacts, "./output.json", true); // Pretty formatted
207
+ saveJsonToFile(contacts, "./compact.json", false); // Minified
208
+ ```
209
+
210
+ ## Output Format
211
+
212
+ Each contact is converted to the following JSON structure:
213
+
214
+ ```json
215
+ {
216
+ "fullName": "John Doe",
217
+ "firstName": "John",
218
+ "lastName": "Doe",
219
+ "phones": [
220
+ {
221
+ "value": "+1234567890",
222
+ "type": "CELL"
223
+ }
224
+ ],
225
+ "emails": [
226
+ {
227
+ "value": "john@example.com",
228
+ "type": "HOME"
229
+ }
230
+ ],
231
+ "organization": "ACME Corp",
232
+ "title": "Software Engineer",
233
+ "note": "Important contact",
234
+ "photo": "",
235
+ "url": "",
236
+ "raw": {
237
+ /* Original parsed vCard object */
238
+ }
239
+ }
240
+ ```
241
+
242
+ ## Supported vCard Fields
243
+
244
+ - **Name:** Full name, first name, last name
245
+ - **Phone:** Multiple phone numbers with types
246
+ - **Email:** Multiple email addresses with types
247
+ - **Organization:** Company/organization name
248
+ - **Title:** Job title
249
+ - **Note:** Notes/comments
250
+ - **Photo:** Photo data (base64)
251
+ - **URL:** Website URLs
252
+ - **Raw:** Complete original vCard data
253
+
254
+ ## Error Handling
255
+
256
+ The library provides comprehensive error handling for:
257
+
258
+ - Invalid file paths
259
+ - Missing files
260
+ - Permission errors
261
+ - Malformed VCF content
262
+ - Invalid input parameters
263
+
264
+ ## Examples
265
+
266
+ ### Basic Conversion
267
+
268
+ ```javascript
269
+ const { vcfToJsonFromFile } = require("vcf-to-json-converter");
270
+
271
+ const contacts = vcfToJsonFromFile("my-contacts.vcf");
272
+ console.log(`Found ${contacts.length} contacts`);
273
+
274
+ contacts.forEach((contact) => {
275
+ console.log(
276
+ `${contact.fullName}: ${contact.phones.map((p) => p.value).join(", ")}`
277
+ );
278
+ });
279
+ ```
280
+
281
+ ### Advanced Usage with Error Handling
282
+
283
+ ```javascript
284
+ const { vcfToJsonFromFile, saveJsonToFile } = require("vcf-to-json-converter");
285
+
286
+ try {
287
+ // Convert VCF file
288
+ const contacts = vcfToJsonFromFile("./contacts.vcf");
289
+
290
+ // Filter contacts with email addresses
291
+ const contactsWithEmail = contacts.filter(
292
+ (contact) => contact.emails.length > 0
293
+ );
294
+
295
+ // Extract business contacts
296
+ const businessContacts = contacts.filter((contact) => contact.organization);
297
+
298
+ console.log(
299
+ `Total: ${contacts.length}, With Email: ${contactsWithEmail.length}, Business: ${businessContacts.length}`
300
+ );
301
+
302
+ // Save different formats
303
+ saveJsonToFile(contacts, "./all-contacts.json", true); // Pretty
304
+ saveJsonToFile(businessContacts, "./business-contacts.json", false); // Compact
305
+ } catch (error) {
306
+ if (error.code === "ENOENT") {
307
+ console.error("File not found. Please check the file path.");
308
+ } else {
309
+ console.error("Conversion error:", error.message);
310
+ }
311
+ }
312
+ ```
313
+
314
+ ### Batch Processing
315
+
316
+ ```javascript
317
+ const fs = require("fs");
318
+ const path = require("path");
319
+ const { vcfToJsonFromFile, saveJsonToFile } = require("vcf-to-json-converter");
320
+
321
+ const vcfFiles = fs
322
+ .readdirSync("./vcf-files")
323
+ .filter((f) => f.endsWith(".vcf"));
324
+
325
+ vcfFiles.forEach((file) => {
326
+ try {
327
+ const contacts = vcfToJsonFromFile(path.join("./vcf-files", file));
328
+ const outputFile = file.replace(".vcf", ".json");
329
+ saveJsonToFile(contacts, path.join("./json-output", outputFile));
330
+ console.log(`Converted ${file} (${contacts.length} contacts)`);
331
+ } catch (error) {
332
+ console.error(`Failed to convert ${file}:`, error.message);
333
+ }
334
+ });
335
+ ```
336
+
337
+ ## Troubleshooting
338
+
339
+ ### Common Issues
340
+
341
+ **File not found error:**
342
+
343
+ ```bash
344
+ Error: ENOENT: no such file or directory
345
+ ```
346
+
347
+ - Ensure the VCF file path is correct
348
+ - Use absolute paths if relative paths don't work
349
+ - Check file permissions
350
+
351
+ **Invalid VCF format:**
352
+
353
+ ```bash
354
+ Error: Invalid VCF format
355
+ ```
356
+
357
+ - Ensure your file starts with `BEGIN:VCARD` and ends with `END:VCARD`
358
+ - Check for corrupted or incomplete vCard entries
359
+ - Validate the VCF file structure
360
+
361
+ **Empty output:**
362
+
363
+ - Check if the VCF file contains properly formatted vCard entries
364
+ - Ensure the file encoding is UTF-8
365
+ - Verify the VCF version is supported (v2.1, v3.0, v4.0)
366
+
367
+ **CLI command not found:**
368
+
369
+ ```bash
370
+ 'vcf-to-json' is not recognized as an internal or external command
371
+ ```
372
+
373
+ - Reinstall globally: `npm install -g vcf-to-json-converter`
374
+ - Check your PATH environment variable
375
+ - Try using `npx vcf-to-json-converter` instead
376
+
377
+ ## CLI Examples
378
+
379
+ ```bash
380
+ # Show help
381
+ vcf-to-json --help
382
+
383
+ # Convert single file
384
+ vcf-to-json contacts.vcf
385
+
386
+ # Convert and save to specific file
387
+ vcf-to-json contacts.vcf my-contacts.json
388
+
389
+ # Compact output
390
+ vcf-to-json contacts.vcf contacts.json --compact
391
+ ```
392
+
393
+ ## Requirements
394
+
395
+ - Node.js 12.0.0 or higher
396
+ - npm 6.0.0 or higher
397
+
398
+ ## Contributing
399
+
400
+ We welcome contributions! Please follow these steps:
401
+
402
+ 1. Fork the repository
403
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
404
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
405
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
406
+ 5. Open a Pull Request
407
+
408
+ ### Development Setup
409
+
410
+ ```bash
411
+ # Clone the repository
412
+ git clone https://github.com/shubhanshurav/vcf-to-json.git
413
+ cd vcf-to-json
414
+
415
+ # Install dependencies (if any)
416
+ npm install
417
+
418
+ # Run tests
419
+ npm test
420
+
421
+ # Test CLI locally
422
+ node index.js contacts.vcf
423
+ ```
424
+
425
+ ## License
426
+
427
+ MIT License - see [LICENSE](LICENSE) file for details.
428
+
429
+ ## Author
430
+
431
+ **Shubhanshu Rao**
432
+
433
+ - GitHub: [@shubhanshurav](https://github.com/shubhanshurav)
434
+ - Repository: [vcf-to-json](https://github.com/shubhanshurav/vcf-to-json)
435
+
436
+ ## Links
437
+
438
+ - [npm package](https://www.npmjs.com/package/vcf-to-json-converter)
439
+ - [GitHub repository](https://github.com/shubhanshurav/vcf-to-json)
440
+ - [Report Issues](https://github.com/shubhanshurav/vcf-to-json/issues)
441
+ - [Changelog](https://github.com/shubhanshurav/vcf-to-json/blob/main/CHANGELOG.md)
442
+
443
+ ## Version History
444
+
445
+ ### v1.0.0 (Latest)
446
+
447
+ - Initial release
448
+ - CLI support with global installation
449
+ - Comprehensive vCard field parsing (v2.1, v3.0, v4.0)
450
+ - Robust error handling and validation
451
+ - TypeScript definitions included
452
+ - UTF-8 and international character support
453
+ - Zero dependencies for maximum compatibility
454
+
455
+ ---
456
+
457
+ **Star this repository if you find it helpful!**
package/index.d.ts CHANGED
@@ -1,32 +1,32 @@
1
- export interface Phone {
2
- value: string;
3
- type: string;
4
- }
5
-
6
- export interface Email {
7
- value: string;
8
- type: string;
9
- }
10
-
11
- export interface Contact {
12
- fullName: string;
13
- firstName: string;
14
- lastName: string;
15
- phones: Phone[];
16
- emails: Email[];
17
- organization: string;
18
- title: string;
19
- note: string;
20
- photo: string;
21
- url: string;
22
- raw: any;
23
- }
24
-
25
- export declare function vcfToJson(vcfText: string): Contact[];
26
- export declare function vcfToJsonFromFile(filePath: string): Contact[];
27
- export declare function saveJsonToFile(
28
- jsonData: Contact[],
29
- outputPath: string,
30
- prettyPrint?: boolean
31
- ): void;
32
- export declare function cli(): void;
1
+ export interface Phone {
2
+ value: string;
3
+ type: string;
4
+ }
5
+
6
+ export interface Email {
7
+ value: string;
8
+ type: string;
9
+ }
10
+
11
+ export interface Contact {
12
+ fullName: string;
13
+ firstName: string;
14
+ lastName: string;
15
+ phones: Phone[];
16
+ emails: Email[];
17
+ organization: string;
18
+ title: string;
19
+ note: string;
20
+ photo: string;
21
+ url: string;
22
+ raw: any;
23
+ }
24
+
25
+ export declare function vcfToJson(vcfText: string): Contact[];
26
+ export declare function vcfToJsonFromFile(filePath: string): Contact[];
27
+ export declare function saveJsonToFile(
28
+ jsonData: Contact[],
29
+ outputPath: string,
30
+ prettyPrint?: boolean
31
+ ): void;
32
+ export declare function cli(): void;
package/index.js CHANGED
@@ -1,252 +1,252 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
-
4
- /**
5
- * Manual VCF parser that properly extracts contact information
6
- * @param {string} vcfText - The VCF content as string
7
- * @returns {Array} Array of contact objects
8
- */
9
- function parseVCF(vcfText) {
10
- const contacts = [];
11
-
12
- // Split by BEGIN:VCARD to handle multiple contacts
13
- const vCards = vcfText.split("BEGIN:VCARD").filter((card) => card.trim());
14
-
15
- for (const vCard of vCards) {
16
- const lines = vCard.split(/\r?\n/).filter((line) => line.trim());
17
-
18
- const contact = {
19
- fullName: "",
20
- firstName: "",
21
- lastName: "",
22
- phones: [],
23
- emails: [],
24
- organization: "",
25
- title: "",
26
- note: "",
27
- photo: "",
28
- url: "",
29
- raw: vCard, // Store original vCard text
30
- };
31
-
32
- for (const line of lines) {
33
- // Parse FN (Formatted Name) - supports UTF-8/Hindi
34
- if (line.startsWith("FN:")) {
35
- contact.fullName = line.substring(3).trim();
36
- }
37
-
38
- // Parse N (Name) for first and last name
39
- if (line.startsWith("N:")) {
40
- const nameParts = line.substring(2).split(";");
41
- // Format: Last;First;Middle;Prefix;Suffix
42
- contact.lastName = (nameParts[0] || "").trim();
43
- contact.firstName = (nameParts[1] || "").trim();
44
-
45
- // If fullName is empty, construct it from first and last name
46
- if (!contact.fullName) {
47
- contact.fullName = `${contact.firstName} ${contact.lastName}`.trim();
48
- }
49
- }
50
-
51
- // Parse TEL (Phone)
52
- if (line.startsWith("TEL")) {
53
- const phoneMatch = line.match(/:([\d\s\-+()]+)/);
54
- if (phoneMatch) {
55
- // Extract phone type from the TEL line
56
- let phoneType = "unknown";
57
- if (line.includes("CELL")) phoneType = "mobile";
58
- else if (line.includes("HOME")) phoneType = "home";
59
- else if (line.includes("WORK")) phoneType = "work";
60
- else if (line.includes("VOICE")) phoneType = "voice";
61
- else if (line.includes("PREF")) phoneType = "primary";
62
-
63
- contact.phones.push({
64
- value: phoneMatch[1].trim(),
65
- type: phoneType,
66
- });
67
- }
68
- }
69
-
70
- // Parse EMAIL
71
- if (line.startsWith("EMAIL")) {
72
- const emailMatch = line.match(/:(.+)/);
73
- if (emailMatch) {
74
- // Extract email type from the EMAIL line
75
- let emailType = "unknown";
76
- if (line.includes("HOME")) emailType = "home";
77
- else if (line.includes("WORK")) emailType = "work";
78
- else if (line.includes("PREF")) emailType = "primary";
79
-
80
- contact.emails.push({
81
- value: emailMatch[1].trim(),
82
- type: emailType,
83
- });
84
- }
85
- }
86
-
87
- // Parse ORG (Organization)
88
- if (line.startsWith("ORG:")) {
89
- contact.organization = line.substring(4).trim();
90
- }
91
-
92
- // Parse TITLE
93
- if (line.startsWith("TITLE:")) {
94
- contact.title = line.substring(6).trim();
95
- }
96
-
97
- // Parse NOTE
98
- if (line.startsWith("NOTE:")) {
99
- contact.note = line.substring(5).trim();
100
- }
101
-
102
- // Parse URL
103
- if (line.startsWith("URL:")) {
104
- contact.url = line.substring(4).trim();
105
- }
106
-
107
- // Parse PHOTO (basic support)
108
- if (line.startsWith("PHOTO:")) {
109
- contact.photo = line.substring(6).trim();
110
- }
111
- }
112
-
113
- // Only add contact if it has meaningful data
114
- if (
115
- contact.fullName ||
116
- contact.firstName ||
117
- contact.lastName ||
118
- contact.phones.length > 0
119
- ) {
120
- contacts.push(contact);
121
- }
122
- }
123
-
124
- return contacts;
125
- }
126
-
127
- /**
128
- * Convert VCF text content to JSON
129
- * @param {string} vcfText - The VCF content as string
130
- * @returns {Array} Array of contact objects
131
- */
132
- function vcfToJson(vcfText) {
133
- if (!vcfText || typeof vcfText !== "string") {
134
- throw new Error("Invalid VCF content. Expected non-empty string.");
135
- }
136
-
137
- try {
138
- return parseVCF(vcfText);
139
- } catch (error) {
140
- throw new Error(`Failed to parse VCF content: ${error.message}`);
141
- }
142
- }
143
-
144
- /**
145
- * Convert VCF file to JSON
146
- * @param {string} filePath - Path to the VCF file
147
- * @returns {Array} Array of contact objects
148
- */
149
- function vcfToJsonFromFile(filePath) {
150
- if (!filePath || typeof filePath !== "string") {
151
- throw new Error("File path is required and must be a string.");
152
- }
153
-
154
- try {
155
- if (!fs.existsSync(filePath)) {
156
- throw new Error(`File not found: ${filePath}`);
157
- }
158
-
159
- const vcfText = fs.readFileSync(filePath, "utf8");
160
- return vcfToJson(vcfText);
161
- } catch (error) {
162
- if (error.code === "ENOENT") {
163
- throw new Error(`File not found: ${filePath}`);
164
- }
165
- if (error.code === "EACCES") {
166
- throw new Error(`Permission denied: ${filePath}`);
167
- }
168
- throw error;
169
- }
170
- }
171
-
172
- /**
173
- * Save JSON data to file
174
- * @param {Array} jsonData - The JSON data to save
175
- * @param {string} outputPath - Path to save the JSON file
176
- * @param {boolean} prettyPrint - Whether to format JSON with indentation
177
- */
178
- function saveJsonToFile(jsonData, outputPath, prettyPrint = true) {
179
- if (!outputPath || typeof outputPath !== "string") {
180
- throw new Error("Output path is required and must be a string.");
181
- }
182
-
183
- try {
184
- const jsonString = prettyPrint
185
- ? JSON.stringify(jsonData, null, 2)
186
- : JSON.stringify(jsonData);
187
-
188
- fs.writeFileSync(outputPath, jsonString, "utf8");
189
- } catch (error) {
190
- throw new Error(`Failed to save JSON file: ${error.message}`);
191
- }
192
- }
193
-
194
- /**
195
- * CLI function to convert VCF to JSON
196
- */
197
- function cli() {
198
- const args = process.argv.slice(2);
199
-
200
- if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
201
- console.log(`
202
- VCF to JSON Converter
203
-
204
- Usage:
205
- vcf-to-json <input.vcf> [output.json] [options]
206
-
207
- Options:
208
- --compact, -c Output compact JSON (no formatting)
209
- --help, -h Show this help message
210
-
211
- Examples:
212
- vcf-to-json contacts.vcf
213
- vcf-to-json contacts.vcf output.json
214
- vcf-to-json contacts.vcf output.json --compact
215
- `);
216
- return;
217
- }
218
-
219
- const inputFile = args[0];
220
- const outputFile = args[1] || inputFile.replace(/\.vcf$/i, ".json");
221
- const compact = args.includes("--compact") || args.includes("-c");
222
-
223
- try {
224
- console.log(`Converting ${inputFile} to JSON...`);
225
- const jsonData = vcfToJsonFromFile(inputFile);
226
-
227
- if (args[1]) {
228
- saveJsonToFile(jsonData, outputFile, !compact);
229
- console.log(
230
- `✅ Converted ${jsonData.length} contacts and saved to ${outputFile}`
231
- );
232
- } else {
233
- console.log(JSON.stringify(jsonData, null, compact ? 0 : 2));
234
- }
235
- } catch (error) {
236
- console.error(`❌ Error: ${error.message}`);
237
- process.exit(1);
238
- }
239
- }
240
-
241
- // Export functions
242
- module.exports = {
243
- vcfToJson,
244
- vcfToJsonFromFile,
245
- saveJsonToFile,
246
- cli,
247
- };
248
-
249
- // If this file is run directly, execute CLI
250
- if (require.main === module) {
251
- cli();
252
- }
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ /**
5
+ * Manual VCF parser that properly extracts contact information
6
+ * @param {string} vcfText - The VCF content as string
7
+ * @returns {Array} Array of contact objects
8
+ */
9
+ function parseVCF(vcfText) {
10
+ const contacts = [];
11
+
12
+ // Split by BEGIN:VCARD to handle multiple contacts
13
+ const vCards = vcfText.split("BEGIN:VCARD").filter((card) => card.trim());
14
+
15
+ for (const vCard of vCards) {
16
+ const lines = vCard.split(/\r?\n/).filter((line) => line.trim());
17
+
18
+ const contact = {
19
+ fullName: "",
20
+ firstName: "",
21
+ lastName: "",
22
+ phones: [],
23
+ emails: [],
24
+ organization: "",
25
+ title: "",
26
+ note: "",
27
+ photo: "",
28
+ url: "",
29
+ raw: vCard, // Store original vCard text
30
+ };
31
+
32
+ for (const line of lines) {
33
+ // Parse FN (Formatted Name) - supports UTF-8/Hindi
34
+ if (line.startsWith("FN:")) {
35
+ contact.fullName = line.substring(3).trim();
36
+ }
37
+
38
+ // Parse N (Name) for first and last name
39
+ if (line.startsWith("N:")) {
40
+ const nameParts = line.substring(2).split(";");
41
+ // Format: Last;First;Middle;Prefix;Suffix
42
+ contact.lastName = (nameParts[0] || "").trim();
43
+ contact.firstName = (nameParts[1] || "").trim();
44
+
45
+ // If fullName is empty, construct it from first and last name
46
+ if (!contact.fullName) {
47
+ contact.fullName = `${contact.firstName} ${contact.lastName}`.trim();
48
+ }
49
+ }
50
+
51
+ // Parse TEL (Phone)
52
+ if (line.startsWith("TEL")) {
53
+ const phoneMatch = line.match(/:([\d\s\-+()]+)/);
54
+ if (phoneMatch) {
55
+ // Extract phone type from the TEL line
56
+ let phoneType = "unknown";
57
+ if (line.includes("CELL")) phoneType = "mobile";
58
+ else if (line.includes("HOME")) phoneType = "home";
59
+ else if (line.includes("WORK")) phoneType = "work";
60
+ else if (line.includes("VOICE")) phoneType = "voice";
61
+ else if (line.includes("PREF")) phoneType = "primary";
62
+
63
+ contact.phones.push({
64
+ value: phoneMatch[1].trim(),
65
+ type: phoneType,
66
+ });
67
+ }
68
+ }
69
+
70
+ // Parse EMAIL
71
+ if (line.startsWith("EMAIL")) {
72
+ const emailMatch = line.match(/:(.+)/);
73
+ if (emailMatch) {
74
+ // Extract email type from the EMAIL line
75
+ let emailType = "unknown";
76
+ if (line.includes("HOME")) emailType = "home";
77
+ else if (line.includes("WORK")) emailType = "work";
78
+ else if (line.includes("PREF")) emailType = "primary";
79
+
80
+ contact.emails.push({
81
+ value: emailMatch[1].trim(),
82
+ type: emailType,
83
+ });
84
+ }
85
+ }
86
+
87
+ // Parse ORG (Organization)
88
+ if (line.startsWith("ORG:")) {
89
+ contact.organization = line.substring(4).trim();
90
+ }
91
+
92
+ // Parse TITLE
93
+ if (line.startsWith("TITLE:")) {
94
+ contact.title = line.substring(6).trim();
95
+ }
96
+
97
+ // Parse NOTE
98
+ if (line.startsWith("NOTE:")) {
99
+ contact.note = line.substring(5).trim();
100
+ }
101
+
102
+ // Parse URL
103
+ if (line.startsWith("URL:")) {
104
+ contact.url = line.substring(4).trim();
105
+ }
106
+
107
+ // Parse PHOTO (basic support)
108
+ if (line.startsWith("PHOTO:")) {
109
+ contact.photo = line.substring(6).trim();
110
+ }
111
+ }
112
+
113
+ // Only add contact if it has meaningful data
114
+ if (
115
+ contact.fullName ||
116
+ contact.firstName ||
117
+ contact.lastName ||
118
+ contact.phones.length > 0
119
+ ) {
120
+ contacts.push(contact);
121
+ }
122
+ }
123
+
124
+ return contacts;
125
+ }
126
+
127
+ /**
128
+ * Convert VCF text content to JSON
129
+ * @param {string} vcfText - The VCF content as string
130
+ * @returns {Array} Array of contact objects
131
+ */
132
+ function vcfToJson(vcfText) {
133
+ if (!vcfText || typeof vcfText !== "string") {
134
+ throw new Error("Invalid VCF content. Expected non-empty string.");
135
+ }
136
+
137
+ try {
138
+ return parseVCF(vcfText);
139
+ } catch (error) {
140
+ throw new Error(`Failed to parse VCF content: ${error.message}`);
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Convert VCF file to JSON
146
+ * @param {string} filePath - Path to the VCF file
147
+ * @returns {Array} Array of contact objects
148
+ */
149
+ function vcfToJsonFromFile(filePath) {
150
+ if (!filePath || typeof filePath !== "string") {
151
+ throw new Error("File path is required and must be a string.");
152
+ }
153
+
154
+ try {
155
+ if (!fs.existsSync(filePath)) {
156
+ throw new Error(`File not found: ${filePath}`);
157
+ }
158
+
159
+ const vcfText = fs.readFileSync(filePath, "utf8");
160
+ return vcfToJson(vcfText);
161
+ } catch (error) {
162
+ if (error.code === "ENOENT") {
163
+ throw new Error(`File not found: ${filePath}`);
164
+ }
165
+ if (error.code === "EACCES") {
166
+ throw new Error(`Permission denied: ${filePath}`);
167
+ }
168
+ throw error;
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Save JSON data to file
174
+ * @param {Array} jsonData - The JSON data to save
175
+ * @param {string} outputPath - Path to save the JSON file
176
+ * @param {boolean} prettyPrint - Whether to format JSON with indentation
177
+ */
178
+ function saveJsonToFile(jsonData, outputPath, prettyPrint = true) {
179
+ if (!outputPath || typeof outputPath !== "string") {
180
+ throw new Error("Output path is required and must be a string.");
181
+ }
182
+
183
+ try {
184
+ const jsonString = prettyPrint
185
+ ? JSON.stringify(jsonData, null, 2)
186
+ : JSON.stringify(jsonData);
187
+
188
+ fs.writeFileSync(outputPath, jsonString, "utf8");
189
+ } catch (error) {
190
+ throw new Error(`Failed to save JSON file: ${error.message}`);
191
+ }
192
+ }
193
+
194
+ /**
195
+ * CLI function to convert VCF to JSON
196
+ */
197
+ function cli() {
198
+ const args = process.argv.slice(2);
199
+
200
+ if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
201
+ console.log(`
202
+ VCF to JSON Converter
203
+
204
+ Usage:
205
+ vcf-to-json <input.vcf> [output.json] [options]
206
+
207
+ Options:
208
+ --compact, -c Output compact JSON (no formatting)
209
+ --help, -h Show this help message
210
+
211
+ Examples:
212
+ vcf-to-json contacts.vcf
213
+ vcf-to-json contacts.vcf output.json
214
+ vcf-to-json contacts.vcf output.json --compact
215
+ `);
216
+ return;
217
+ }
218
+
219
+ const inputFile = args[0];
220
+ const outputFile = args[1] || inputFile.replace(/\.vcf$/i, ".json");
221
+ const compact = args.includes("--compact") || args.includes("-c");
222
+
223
+ try {
224
+ console.log(`Converting ${inputFile} to JSON...`);
225
+ const jsonData = vcfToJsonFromFile(inputFile);
226
+
227
+ if (args[1]) {
228
+ saveJsonToFile(jsonData, outputFile, !compact);
229
+ console.log(
230
+ `✅ Converted ${jsonData.length} contacts and saved to ${outputFile}`
231
+ );
232
+ } else {
233
+ console.log(JSON.stringify(jsonData, null, compact ? 0 : 2));
234
+ }
235
+ } catch (error) {
236
+ console.error(`❌ Error: ${error.message}`);
237
+ process.exit(1);
238
+ }
239
+ }
240
+
241
+ // Export functions
242
+ module.exports = {
243
+ vcfToJson,
244
+ vcfToJsonFromFile,
245
+ saveJsonToFile,
246
+ cli,
247
+ };
248
+
249
+ // If this file is run directly, execute CLI
250
+ if (require.main === module) {
251
+ cli();
252
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vcf-to-json-converter",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A lightweight Node.js library to convert VCF (vCard) files to JSON format with CLI support",
5
5
  "license": "MIT",
6
6
  "author": "Shubhanshu Rao",
@@ -8,12 +8,13 @@
8
8
  "main": "index.js",
9
9
  "types": "index.d.ts",
10
10
  "bin": {
11
- "vcf-to-json": "./index.js"
11
+ "vcf-to-json": "index.js"
12
12
  },
13
13
  "scripts": {
14
14
  "start": "node index.js",
15
15
  "test": "node test.js",
16
- "demo": "node index.js contacts.vcf"
16
+ "demo": "node index.js contacts.vcf",
17
+ "build": "node index.js"
17
18
  },
18
19
  "keywords": [
19
20
  "vcf",
@@ -26,12 +27,12 @@
26
27
  ],
27
28
  "repository": {
28
29
  "type": "git",
29
- "url": "https://github.com/your-username/vcf-to-json-converter"
30
+ "url": "git+https://github.com/shubhanshurav/vcf-to-json.git"
30
31
  },
31
32
  "bugs": {
32
- "url": "https://github.com/your-username/vcf-to-json-converter/issues"
33
+ "url": "https://github.com/shubhanshurav/vcf-to-json.git/issues"
33
34
  },
34
- "homepage": "https://github.com/your-username/vcf-to-json-converter#readme",
35
+ "homepage": "https://github.com/shubhanshurav/vcf-to-json#readme",
35
36
  "engines": {
36
37
  "node": ">=12.0.0"
37
38
  },