-
-
Notifications
You must be signed in to change notification settings - Fork 800
feat: add VCF to CSV converter #497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add support for converting VCF contact files to CSV format - Implement TypeScript-based VCF parsing without external dependencies - Create CSV export with proper quote escaping - Add comprehensive test coverage for various VCF formats - Update documentation and converter registry Closes C4illin#396
Add support for converting VCF contact files to CSV format - Implement TypeScript-based VCF parsing without external dependencies - Create CSV export with proper quote escaping - Add comprehensive test coverage for various VCF formats - Update documentation and converter registry Closes C4illin#396
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 4 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/converters/vcf.ts">
<violation number="1" location="src/converters/vcf.ts:28">
P1: VCF parsing ignores vCard parameters and folded lines, dropping FN/N values and truncating long fields</violation>
<violation number="2" location="src/converters/vcf.ts:51">
P1: CSV headers are derived only from the first contact, so fields present only in later contacts are omitted and their values are dropped from the CSV output.</violation>
<violation number="3" location="src/converters/vcf.ts:52">
P1: CSV output does not neutralize leading formula characters, allowing spreadsheet formula injection if VCF data starts with =, +, - or @.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| const first = data[0]; | ||
| if (!first) return ""; | ||
| const headers = Object.keys(first); | ||
| const escape = (str: string) => `"${str.replace(/"/g, '""')}"`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: CSV output does not neutralize leading formula characters, allowing spreadsheet formula injection if VCF data starts with =, +, - or @.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/converters/vcf.ts, line 52:
<comment>CSV output does not neutralize leading formula characters, allowing spreadsheet formula injection if VCF data starts with =, +, - or @.</comment>
<file context>
@@ -0,0 +1,69 @@
+ const first = data[0];
+ if (!first) return "";
+ const headers = Object.keys(first);
+ const escape = (str: string) => `"${str.replace(/"/g, '""')}"`;
+ const rows = data.map((row) => headers.map((h) => escape(row[h] || "")).join(","));
+ return [headers.join(","), ...rows].join("\n");
</file context>
| if (!data.length) return ""; | ||
| const first = data[0]; | ||
| if (!first) return ""; | ||
| const headers = Object.keys(first); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: CSV headers are derived only from the first contact, so fields present only in later contacts are omitted and their values are dropped from the CSV output.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/converters/vcf.ts, line 51:
<comment>CSV headers are derived only from the first contact, so fields present only in later contacts are omitted and their values are dropped from the CSV output.</comment>
<file context>
@@ -0,0 +1,69 @@
+ if (!data.length) return "";
+ const first = data[0];
+ if (!first) return "";
+ const headers = Object.keys(first);
+ const escape = (str: string) => `"${str.replace(/"/g, '""')}"`;
+ const rows = data.map((row) => headers.map((h) => escape(row[h] || "")).join(","));
</file context>
| const headers = Object.keys(first); | |
| const headers = Array.from(new Set(data.flatMap((row) => Object.keys(row)))); |
| if (colonIndex === -1) continue; | ||
| const key = line.slice(0, colonIndex).trim(); | ||
| const value = line.slice(colonIndex + 1).trim(); | ||
| if (key === "FN") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: VCF parsing ignores vCard parameters and folded lines, dropping FN/N values and truncating long fields
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/converters/vcf.ts, line 28:
<comment>VCF parsing ignores vCard parameters and folded lines, dropping FN/N values and truncating long fields</comment>
<file context>
@@ -0,0 +1,69 @@
+ if (colonIndex === -1) continue;
+ const key = line.slice(0, colonIndex).trim();
+ const value = line.slice(colonIndex + 1).trim();
+ if (key === "FN") {
+ contact["Full Name"] = value;
+ } else if (key === "N") {
</file context>
|
Nice work! Everything seems to work with the vCards I have tested. Should I merge it? |
|
Yeah I think everything is good from my end |
This PR adds support for converting VCF (vCard) contact files to CSV format, addressing issue #396. The implementation provides a pure TypeScript solution without external dependencies.
VCF Parsing