vcf-to-json-converter 1.0.0

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 -0
  2. package/README.md +241 -0
  3. package/index.d.ts +32 -0
  4. package/index.js +252 -0
  5. package/package.json +46 -0
package/LICENSE ADDED
@@ -0,0 +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.
package/README.md ADDED
@@ -0,0 +1,241 @@
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
package/index.d.ts ADDED
@@ -0,0 +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;
package/index.js ADDED
@@ -0,0 +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
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "vcf-to-json-converter",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight Node.js library to convert VCF (vCard) files to JSON format with CLI support",
5
+ "license": "MIT",
6
+ "author": "Shubhanshu Rao",
7
+ "type": "commonjs",
8
+ "main": "index.js",
9
+ "types": "index.d.ts",
10
+ "bin": {
11
+ "vcf-to-json": "./index.js"
12
+ },
13
+ "scripts": {
14
+ "start": "node index.js",
15
+ "test": "node test.js",
16
+ "demo": "node index.js contacts.vcf"
17
+ },
18
+ "keywords": [
19
+ "vcf",
20
+ "vcard",
21
+ "json",
22
+ "converter",
23
+ "contacts",
24
+ "parser",
25
+ "cli"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/your-username/vcf-to-json-converter"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/your-username/vcf-to-json-converter/issues"
33
+ },
34
+ "homepage": "https://github.com/your-username/vcf-to-json-converter#readme",
35
+ "engines": {
36
+ "node": ">=12.0.0"
37
+ },
38
+ "files": [
39
+ "index.js",
40
+ "index.d.ts",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "dependencies": {},
45
+ "devDependencies": {}
46
+ }