From df10595adb3b2a1e968241c72bf8b2539ae7dc80 Mon Sep 17 00:00:00 2001 From: rebeccahongsf Date: Thu, 5 Dec 2024 15:37:39 -0800 Subject: [PATCH] SOEOPSFY24-375 | restructure timeline data and add json validation --- data/timeline/1990.json | 18 ---- data/timeline/1990s/1990.json | 12 +++ data/timeline/{ => 2000s}/2000.json | 5 +- data/timeline/{2030.json => 2000s/2001.json} | 7 +- data/timeline/{2040.json => 2000s/2005.json} | 7 +- data/timeline/{ => 2010s}/2010.json | 5 +- data/timeline/{ => 2020s}/2021.json | 5 +- data/timeline/{ => 2020s}/2022.json | 5 +- data/timeline/{ => 2020s}/2023.json | 5 +- data/timeline/{ => 2020s}/2024.json | 5 +- data/timeline/{ => 2020s}/2025.json | 5 +- data/timeline/{ => 2020s}/2026.json | 5 +- data/timeline/{ => 2020s}/2027.json | 5 +- data/timeline/{ => 2020s}/2028.json | 5 +- data/timeline/{ => 2020s}/2029.json | 5 +- package.json | 5 +- scripts/validate-timeline.js | 95 ++++++++++++++++++++ tsconfig.json | 8 +- yarn.lock | 34 +++++++ 19 files changed, 164 insertions(+), 77 deletions(-) delete mode 100644 data/timeline/1990.json create mode 100644 data/timeline/1990s/1990.json rename data/timeline/{ => 2000s}/2000.json (52%) rename data/timeline/{2030.json => 2000s/2001.json} (56%) rename data/timeline/{2040.json => 2000s/2005.json} (58%) rename data/timeline/{ => 2010s}/2010.json (60%) rename data/timeline/{ => 2020s}/2021.json (54%) rename data/timeline/{ => 2020s}/2022.json (55%) rename data/timeline/{ => 2020s}/2023.json (55%) rename data/timeline/{ => 2020s}/2024.json (57%) rename data/timeline/{ => 2020s}/2025.json (55%) rename data/timeline/{ => 2020s}/2026.json (56%) rename data/timeline/{ => 2020s}/2027.json (58%) rename data/timeline/{ => 2020s}/2028.json (54%) rename data/timeline/{ => 2020s}/2029.json (55%) create mode 100644 scripts/validate-timeline.js diff --git a/data/timeline/1990.json b/data/timeline/1990.json deleted file mode 100644 index 83f1c95..0000000 --- a/data/timeline/1990.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "year": "1990", - "heading": "The Beginning", - "dek": "A New Era", - "body": "In 1990, the company was founded with a vision to revolutionize the tech industry.", - "href": "https://example.com/1990", - "image": "https://placecats.com/neo/300/200", - "uuid": 1 -}, -{ - "year": "1990", - "heading": "The Beginning", - "dek": "A New Era", - "body": "In 1990, the company was founded with a vision to revolutionize the tech industry.", - "href": "https://example.com/1990", - "image": "https://placecats.com/neo/300/200", - "uuid": 1 -}] \ No newline at end of file diff --git a/data/timeline/1990s/1990.json b/data/timeline/1990s/1990.json new file mode 100644 index 0000000..3948d8b --- /dev/null +++ b/data/timeline/1990s/1990.json @@ -0,0 +1,12 @@ +[{ + "year": "1990", + "heading": "The Beginning", + "body": "In 1990, the company was founded with a vision to revolutionize the tech industry.", + "image": "https://placecats.com/neo/300/200" +}, +{ + "year": "1990", + "heading": "Exploring the reengineering of immune cells", + "body": "The Sarafan ChEM-H Institute scholar is building a multidisciplinary lab to explore the reengineering of immune cells. Before coming to Stanford, she says, “I was thinking in terms of understanding. Now I feel that I can start thinking in terms of creating.", + "image": "/soe-centennial-nextjs/assets/images/lt-flynn-1994.jpeg" +}] \ No newline at end of file diff --git a/data/timeline/2000.json b/data/timeline/2000s/2000.json similarity index 52% rename from data/timeline/2000.json rename to data/timeline/2000s/2000.json index 1584b3a..4c5f3a1 100644 --- a/data/timeline/2000.json +++ b/data/timeline/2000s/2000.json @@ -1,9 +1,6 @@ { "year": "2000", "heading": "The Growth Phase", - "dek": "Expanding Horizons", "body": "By 2000, the company had grown exponentially, reaching international markets.", - "href": "https://example.com/2000", - "image": "https://placecats.com/millie/300/200", - "uuid": 2 + "image": "https://placecats.com/millie/300/200" } \ No newline at end of file diff --git a/data/timeline/2030.json b/data/timeline/2000s/2001.json similarity index 56% rename from data/timeline/2030.json rename to data/timeline/2000s/2001.json index 1c5132c..db8c3f7 100644 --- a/data/timeline/2030.json +++ b/data/timeline/2000s/2001.json @@ -1,9 +1,6 @@ { - "year": "2030", + "year": "2001", "heading": "The Sustainability Push", - "dek": "Green Technology", "body": "The 2030s marked a major commitment to sustainability, with innovative green technology solutions and global environmental initiatives.", - "href": "https://example.com/2030", - "image": "https://placecats.com/bella/300/200", - "uuid": 13 + "image": "https://placecats.com/bella/300/200" } \ No newline at end of file diff --git a/data/timeline/2040.json b/data/timeline/2000s/2005.json similarity index 58% rename from data/timeline/2040.json rename to data/timeline/2000s/2005.json index 09ef312..1b69706 100644 --- a/data/timeline/2040.json +++ b/data/timeline/2000s/2005.json @@ -1,9 +1,6 @@ { - "year": "2040", + "year": "2005", "heading": "The Global Frontier", - "dek": "Space Exploration", "body": "By 2040, the company expanded into space exploration, developing technologies to aid in interplanetary travel and settlement.", - "href": null, - "image": "https://placecats.com/neo_2/300/200", - "uuid": 14 + "image": "https://placecats.com/neo_2/300/200" } \ No newline at end of file diff --git a/data/timeline/2010.json b/data/timeline/2010s/2010.json similarity index 60% rename from data/timeline/2010.json rename to data/timeline/2010s/2010.json index 601fb80..ef399f3 100644 --- a/data/timeline/2010.json +++ b/data/timeline/2010s/2010.json @@ -1,9 +1,6 @@ { "year": "2010", "heading": "The Digital Age", - "dek": "Embracing Innovation", "body": "The 2010s marked the company's shift to digital-first strategies, leading the way in AI and machine learning.", - "href": null, - "image": "https://placecats.com/neo_banana/300/200", - "uuid": 3 + "image": "https://placecats.com/neo_banana/300/200" } \ No newline at end of file diff --git a/data/timeline/2021.json b/data/timeline/2020s/2021.json similarity index 54% rename from data/timeline/2021.json rename to data/timeline/2020s/2021.json index ad6be00..5fb18a4 100644 --- a/data/timeline/2021.json +++ b/data/timeline/2020s/2021.json @@ -1,9 +1,6 @@ { "year": "2021", "heading": "New Innovations", - "dek": "Pushing Boundaries", "body": "In 2021, the company introduced groundbreaking technologies that set a new industry standard.", - "href": "https://example.com/2021", - "image": "https://placecats.com/millie/300/200", - "uuid": 4 + "image": "https://placecats.com/millie/300/200" } \ No newline at end of file diff --git a/data/timeline/2022.json b/data/timeline/2020s/2022.json similarity index 55% rename from data/timeline/2022.json rename to data/timeline/2020s/2022.json index b0fa8cd..c5fc594 100644 --- a/data/timeline/2022.json +++ b/data/timeline/2020s/2022.json @@ -1,9 +1,6 @@ { "year": "2022", "heading": "Sustainability Focus", - "dek": "Eco-Friendly Solutions", "body": "The company made strides towards sustainability, implementing green technologies across its product line.", - "href": "https://example.com/2022", - "image": "https://placecats.com/neo_banana/300/200", - "uuid": 5 + "image": "https://placecats.com/neo_banana/300/200" } \ No newline at end of file diff --git a/data/timeline/2023.json b/data/timeline/2020s/2023.json similarity index 55% rename from data/timeline/2023.json rename to data/timeline/2020s/2023.json index 177d2c4..cfedcfb 100644 --- a/data/timeline/2023.json +++ b/data/timeline/2020s/2023.json @@ -1,9 +1,6 @@ { "year": "2023", "heading": "AI Revolution", - "dek": "A Step into the Future", "body": "By 2023, the company had integrated advanced AI into all its platforms, driving new levels of innovation.", - "href": "https://example.com/2023", - "image": "https://placecats.com/neo/300/200", - "uuid": 6 + "image": "https://placecats.com/neo/300/200" } \ No newline at end of file diff --git a/data/timeline/2024.json b/data/timeline/2020s/2024.json similarity index 57% rename from data/timeline/2024.json rename to data/timeline/2020s/2024.json index 5464020..65b7f6f 100644 --- a/data/timeline/2024.json +++ b/data/timeline/2020s/2024.json @@ -1,9 +1,6 @@ { "year": "2024", "heading": "Global Expansion", - "dek": "Reaching New Markets", "body": "The company continued its expansion into new global markets, making its products available to more people than ever.", - "href": "https://example.com/2024", - "image": "https://placecats.com/millie/300/200", - "uuid": 7 + "image": "https://placecats.com/millie/300/200" } \ No newline at end of file diff --git a/data/timeline/2025.json b/data/timeline/2020s/2025.json similarity index 55% rename from data/timeline/2025.json rename to data/timeline/2020s/2025.json index 055e87e..18db5e5 100644 --- a/data/timeline/2025.json +++ b/data/timeline/2020s/2025.json @@ -1,9 +1,6 @@ { "year": "2025", "heading": "Milestone Achievement", - "dek": "Celebrating 35 Years", "body": "In 2025, the company celebrated its 35th anniversary, marking decades of innovation and success.", - "href": "https://example.com/2025", - "image": "https://placecats.com/bella/300/200", - "uuid": 8 + "image": "https://placecats.com/bella/300/200" } \ No newline at end of file diff --git a/data/timeline/2026.json b/data/timeline/2020s/2026.json similarity index 56% rename from data/timeline/2026.json rename to data/timeline/2020s/2026.json index 93215f9..3d14b5b 100644 --- a/data/timeline/2026.json +++ b/data/timeline/2020s/2026.json @@ -1,9 +1,6 @@ { "year": "2026", "heading": "Quantum Leap", - "dek": "The Next Frontier", "body": "The company made its first foray into quantum computing, pushing the boundaries of what was possible.", - "href": "https://example.com/2026", - "image": "https://placecats.com/neo/300/200", - "uuid": 9 + "image": "https://placecats.com/neo/300/200" } \ No newline at end of file diff --git a/data/timeline/2027.json b/data/timeline/2020s/2027.json similarity index 58% rename from data/timeline/2027.json rename to data/timeline/2020s/2027.json index a23940f..deb3514 100644 --- a/data/timeline/2027.json +++ b/data/timeline/2020s/2027.json @@ -1,9 +1,6 @@ { "year": "2027", "heading": "Community Outreach", - "dek": "Giving Back", "body": "With a focus on corporate responsibility, the company launched new initiatives to support underserved communities.", - "href": "https://example.com/2027", - "image": "https://placecats.com/neo_banana/300/200", - "uuid": 10 + "image": "https://placecats.com/neo_banana/300/200" } \ No newline at end of file diff --git a/data/timeline/2028.json b/data/timeline/2020s/2028.json similarity index 54% rename from data/timeline/2028.json rename to data/timeline/2020s/2028.json index 6d67c79..ad44880 100644 --- a/data/timeline/2028.json +++ b/data/timeline/2020s/2028.json @@ -1,9 +1,6 @@ { "year": "2028", "heading": "AI-Powered Solutions", - "dek": "Automation Everywhere", "body": "In 2028, the company unveiled a suite of AI-powered tools aimed at transforming everyday life.", - "href": "https://example.com/2028", - "image": "https://placecats.com/millie/300/200", - "uuid": 11 + "image": "https://placecats.com/millie/300/200" } \ No newline at end of file diff --git a/data/timeline/2029.json b/data/timeline/2020s/2029.json similarity index 55% rename from data/timeline/2029.json rename to data/timeline/2020s/2029.json index bda21d2..7dc9f54 100644 --- a/data/timeline/2029.json +++ b/data/timeline/2020s/2029.json @@ -1,9 +1,6 @@ { "year": "2029", "heading": "Pioneering Robotics", - "dek": "The Future is Here", "body": "The company became a leader in robotics, developing advanced systems for both home and industry use.", - "href": "https://example.com/2029", - "image": "https://placecats.com/neo_banana/300/200", - "uuid": 12 + "image": "https://placecats.com/neo_banana/300/200" } \ No newline at end of file diff --git a/package.json b/package.json index d4d86b5..fa85389 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "soe-centennial-nextjs", "version": "0.1.0", "private": true, + "type": "module", "scripts": { "dev": "next dev", "build": "next build", @@ -9,13 +10,15 @@ "lint": "next lint", "lint:fix": "eslint \"app/**/*.{ts,tsx,js,jsx}\" --fix", "typecheck": "tsc --noEmit", - "tsc": "tsc" + "tsc": "tsc", + "validate:timeline": "node scripts/validate-timeline.js" }, "dependencies": { "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.13.0", "@heroicons/react": "^2.1.5", "@tailwindcss/container-queries": "^0.1.1", + "ajv": "^8.17.1", "cnbuilder": "^3.1.0", "flubber": "^0.4.2", "framer-motion": "^12.0.0-alpha.1", diff --git a/scripts/validate-timeline.js b/scripts/validate-timeline.js new file mode 100644 index 0000000..8ae4289 --- /dev/null +++ b/scripts/validate-timeline.js @@ -0,0 +1,95 @@ +/* eslint-disable no-console */ +import fs from 'fs'; +import path from 'path'; +import Ajv from 'ajv'; + +// Schema for the timeline items +const schema = { + oneOf: [ + { + // Case when the root is a single object + type: 'object', + properties: { + year: { type: 'string', pattern: '^(19|20)\\d{2}$' }, + heading: { type: 'string' }, + body: { type: 'string' }, + image: { type: 'string' }, // @TODO: Additional image path validation can be configured here + }, + required: ['year', 'heading', 'body', 'image'], + additionalProperties: false, + }, + { + // Case when the root is an array of objects + type: 'array', + items: { + type: 'object', + properties: { + year: { type: 'string', pattern: '^(19|20)\\d{2}$' }, + heading: { type: 'string' }, + body: { type: 'string' }, + image: { type: 'string' }, // @TODO: Additional image path validation can be configured here + }, + required: ['year', 'heading', 'body', 'image'], + additionalProperties: false, + }, + }, + ], +}; + +// Validate timeline data based on defined schema above +const validateTimeline = async () => { + const directoryPath = path.join(process.cwd(), 'data/timeline'); + const ajv = new Ajv(); + const validate = ajv.compile(schema); + + let isValid = true; + + // Recursively fetch all JSON files from the timeline directory and subdirectories + const getAllJsonFiles = (dirPath) => { + const items = fs.readdirSync(dirPath); + let files = []; + items.forEach(item => { + const fullPath = path.join(dirPath, item); + const stat = fs.statSync(fullPath); + if (stat.isDirectory()) { + files = [...files, ...getAllJsonFiles(fullPath)]; + } else if (stat.isFile() && item.endsWith('.json')) { + files.push(fullPath); + } + }); + return files; + }; + + // Fetch all the JSON files in the timeline directory and its subdirectories + const jsonFiles = getAllJsonFiles(directoryPath); + + // Review each JSON file + for (const filePath of jsonFiles) { + const fileContents = fs.readFileSync(filePath, 'utf-8'); + + try { + const data = JSON.parse(fileContents); + const valid = validate(data); + + if (!valid) { + isValid = false; + console.error(`Validation errors in file: ${filePath}`); + console.error(validate.errors); + } + } catch (error) { + isValid = false; + console.error(`Error parsing JSON in file: ${filePath}`); + console.error(error.message); + } + } + + if (isValid) { + console.log('All timeline JSON files are valid!'); + } else { + console.error('Some files failed validation.'); + process.exit(1); + } +}; + +// Run validation function +validateTimeline(); diff --git a/tsconfig.json b/tsconfig.json index bc55ffb..3eb8da4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,8 +10,8 @@ "strict": true, "noEmit": true, "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", + "module": "CommonJS", + "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", @@ -26,14 +26,14 @@ "./*" ] }, - "target": "es6", + "target": "es6" }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts" - ], +, "scripts/validate-timeline.js" ], "exclude": [ "node_modules" ] diff --git a/yarn.lock b/yarn.lock index 451df8e..0146d4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -812,6 +812,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.17.1": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -1992,6 +2004,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.0.3 + resolution: "fast-uri@npm:3.0.3" + checksum: 10c0/4b2c5ce681a062425eae4f15cdc8fc151fd310b2f69b1f96680677820a8b49c3cd6e80661a406e19d50f0c40a3f8bffdd458791baf66f4a879d80be28e10a320 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -2761,6 +2780,13 @@ __metadata: languageName: node linkType: hard +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6 + languageName: node + linkType: hard + "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -3654,6 +3680,13 @@ __metadata: languageName: node linkType: hard +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2 + languageName: node + linkType: hard + "resize-observer-polyfill@npm:^1.5.0": version: 1.5.1 resolution: "resize-observer-polyfill@npm:1.5.1" @@ -3986,6 +4019,7 @@ __metadata: "@types/react-dom": "npm:19.0.0-rc.1" "@types/react-slick": "npm:^0" "@xpd/tailwind-3dtransforms": "npm:^1.0.3" + ajv: "npm:^8.17.1" cnbuilder: "npm:^3.1.0" decanter: "npm:^7.3.0" eslint: "npm:^9.13.0"