My personal website
1// src/scripts/convertCsvToJson.ts
2
3import fs from 'node:fs';
4import path from 'node:path';
5import { parse } from 'csv-parse/sync';
6import type { Article, CaseStudy, Company, ContentData, Job, ProjectType, Skill } from '@/types/content';
7
8// Define interfaces for raw CSV data
9interface RawCSVRow {
10 [key: string]: string;
11}
12
13// Helper function to parse CSV file
14function parseCsvFile(filePath: string): RawCSVRow[] {
15 const fileContent = fs.readFileSync(filePath, 'utf-8');
16 return parse(fileContent, {
17 columns: true,
18 skip_empty_lines: true,
19 });
20}
21
22// Convert Companies CSV
23function convertCompanies(data: RawCSVRow[]): Company[] {
24 return data.map((row) => ({
25 name: row.Name,
26 slug: row.Slug,
27 collectionId: row['Collection ID'],
28 itemId: row['Item ID'],
29 createdOn: row['Created On'],
30 updatedOn: row['Updated On'],
31 publishedOn: row['Published On'],
32 website: row.Website,
33 type: row.Type as Company['type'],
34 industry: row.Industry,
35 city: row.City,
36 country: row.Country,
37 logo: row.Logo,
38 }));
39}
40
41// Convert Skills CSV
42function convertSkills(data: RawCSVRow[]): Skill[] {
43 return data.map((row) => ({
44 name: row.Skill,
45 slug: row.Slug,
46 collectionId: row['Collection ID'],
47 itemId: row['Item ID'],
48 createdOn: row['Created On'],
49 updatedOn: row['Updated On'],
50 publishedOn: row['Published On'],
51 }));
52}
53
54// Convert Portfolio/Case Studies CSV
55function convertCaseStudies(data: RawCSVRow[]): CaseStudy[] {
56 return data.map((row) => ({
57 name: row['Case Study Name'],
58 slug: row.Slug,
59 collectionId: row['Collection ID'],
60 itemId: row['Item ID'],
61 createdOn: row['Created On'],
62 updatedOn: row['Updated On'],
63 publishedOn: row['Published On'],
64 summary: row.Summary,
65 body: row.Body,
66 pitchEmbed: row['Pitch Embed'],
67 coverImage: row['Cover Image'],
68 type: row.Type as ProjectType,
69 endDate: row['End Date'],
70 role: row.Role,
71 company: row.Company,
72 relevantSkills: row['Relevant Skills']?.split(';').map((s: string) => s.trim()) || [],
73 }));
74}
75
76// Convert Jobs CSV
77function convertJobs(data: RawCSVRow[]): Job[] {
78 return data.map((row) => ({
79 jobTitle: row['Job title'],
80 slug: row.Slug,
81 collectionId: row['Collection ID'],
82 itemId: row['Item ID'],
83 createdOn: row['Created On'],
84 updatedOn: row['Updated On'],
85 publishedOn: row['Published On'],
86 cover: row.cover,
87 jobDescription: row['Job description'],
88 userNeed: row['User need'],
89 startDate: row['Start date'],
90 endDate: row['End date'],
91 employmentType: row['Employment type'] as Job['employmentType'],
92 company: row.Company,
93 skills: row.Skills?.split(';').map((s: string) => s.trim()) || [],
94 caseStudies: row['Case Studies']?.split(';').map((s: string) => s.trim()) || [],
95 client: row.Client,
96 }));
97}
98
99// Convert Articles CSV
100function convertArticles(data: RawCSVRow[]): Article[] {
101 return data.map((row) => ({
102 title: row.Title,
103 slug: row.Slug,
104 collectionId: row['Collection ID'],
105 itemId: row['Item ID'],
106 createdOn: row['Created On'],
107 updatedOn: row['Updated On'],
108 publishedOn: row['Published On'],
109 subtitle: row.Subtitle,
110 featured: row.Featured === 'true',
111 coverImage: row.Cover,
112 articleUrl: row['Article URL'],
113 published: row.Published,
114 publication: row.Publication,
115 publicationUrl: row['Publication URL'],
116 }));
117}
118
119// Main conversion function
120async function convertCsvToJson(): Promise<void> {
121 const inputDir = path.join(process.cwd(), 'src', 'data', 'csv');
122 const outputDir = path.join(process.cwd(), 'src', 'data', 'json');
123
124 // Ensure output directory exists
125 if (!fs.existsSync(outputDir)) {
126 fs.mkdirSync(outputDir, { recursive: true });
127 }
128
129 // Read and convert all CSV files
130 const companies = convertCompanies(parseCsvFile(path.join(inputDir, 'Barry Prendergast - Companies.csv')));
131 const skills = convertSkills(parseCsvFile(path.join(inputDir, 'Barry Prendergast - Skills.csv')));
132 const caseStudies = convertCaseStudies(parseCsvFile(path.join(inputDir, 'Barry Prendergast - Portfolio.csv')));
133 const jobs = convertJobs(parseCsvFile(path.join(inputDir, 'Barry Prendergast - Jobs.csv')));
134 const articles = convertArticles(parseCsvFile(path.join(inputDir, 'Barry Prendergast - Articles.csv')));
135
136 // Create combined content data
137 const contentData: ContentData = {
138 companies,
139 skills,
140 caseStudies,
141 jobs,
142 articles,
143 };
144
145 // Write individual JSON files
146 fs.writeFileSync(path.join(outputDir, 'companies.json'), JSON.stringify(companies, null, 2));
147 fs.writeFileSync(path.join(outputDir, 'skills.json'), JSON.stringify(skills, null, 2));
148 fs.writeFileSync(path.join(outputDir, 'case-studies.json'), JSON.stringify(caseStudies, null, 2));
149 fs.writeFileSync(path.join(outputDir, 'jobs.json'), JSON.stringify(jobs, null, 2));
150 fs.writeFileSync(path.join(outputDir, 'articles.json'), JSON.stringify(articles, null, 2));
151
152 // Write combined content data
153 fs.writeFileSync(path.join(outputDir, 'content.json'), JSON.stringify(contentData, null, 2));
154}
155
156// Run the conversion
157convertCsvToJson().catch(console.error);