Skip to content

Commit 0308e14

Browse files
committed
feat(add): support for pulse and validation
1 parent 9933138 commit 0308e14

8 files changed

Lines changed: 246 additions & 0 deletions

File tree

.github/FUNDING.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github: NodeByteHosting
2+
custom: nodebyte.host

.github/workflows/validate_kb.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Validate articles.json
2+
3+
on:
4+
push:
5+
paths:
6+
- 'markdown/kb/articles.json'
7+
pull_request:
8+
paths:
9+
- 'markdown/kb/articles.json'
10+
11+
jobs:
12+
validate-json:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v2
18+
19+
- name: Set up Node.js
20+
uses: actions/setup-node@v2
21+
with:
22+
node-version: '14'
23+
24+
- name: Install dependencies
25+
run: npm install
26+
27+
- name: Validate articles.json
28+
run: node validation/kb_layout.js
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Validate Pulse Layout
2+
3+
on:
4+
push:
5+
paths:
6+
- 'markdown/pulse/articles.json'
7+
pull_request:
8+
paths:
9+
- 'markdown/pulse/articles.json'
10+
11+
jobs:
12+
validate-json:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v2
18+
19+
- name: Set up Node.js
20+
uses: actions/setup-node@v2
21+
with:
22+
node-version: '14'
23+
24+
- name: Install dependencies
25+
run: npm install
26+
27+
- name: Validate Pulse JSON Schema
28+
run: node validation/pulse_layout.js

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
.contentlayer
9+
package-lock.json
10+
bun.lockb
11+
12+
# testing
13+
/coverage
14+
15+
# next.js
16+
/.next/
17+
/out/
18+
19+
# production
20+
/build
21+
22+
# misc
23+
.DS_Store
24+
*.pem
25+
26+
# debug
27+
npm-debug.log*
28+
yarn-debug.log*
29+
yarn-error.log*
30+
31+
# local env files
32+
.env
33+
.env*.local

markdown/pulse/articles.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[
2+
{
3+
"slug": "pulse",
4+
"title": "Community Pulse",
5+
"description": "Stay up to date with our latest news and updates.",
6+
"sections": [
7+
{
8+
"title": "Panel Updates",
9+
"description": "This section will detail our latest panel updates and future plans.",
10+
"path": "pulse/panel",
11+
"slug": "panel",
12+
"data": []
13+
}
14+
]
15+
}
16+
]

package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "@nbh/assets",
3+
"scripts": {
4+
"validate:kb": "node validation/kb_layout.js",
5+
"validate:pulse": "node validation/pulse_layout.js"
6+
},
7+
"dependencies": {
8+
"fs": "^0.0.1-security",
9+
"path": "^0.12.7"
10+
}
11+
}

validation/kb_layout.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
const filePath = path.join(__dirname, '../markdown/kb/articles.json');
5+
6+
function validateJSONStructure(json) {
7+
if (!Array.isArray(json)) {
8+
throw new Error('Root element should be an array');
9+
}
10+
11+
json.forEach((item, itemIndex) => {
12+
if (!item.section) {
13+
throw new Error(`Item at index ${itemIndex} is missing 'section'. Expected a string.`);
14+
}
15+
if (!item.about) {
16+
throw new Error(`Item at index ${itemIndex} is missing 'about'. Expected a string.`);
17+
}
18+
if (!item.slug) {
19+
throw new Error(`Item at index ${itemIndex} is missing 'slug'. Expected a string.`);
20+
}
21+
if (!Array.isArray(item.articles)) {
22+
throw new Error(`Item at index ${itemIndex} has invalid 'articles'. Expected an array.`);
23+
}
24+
25+
item.articles.forEach((article, articleIndex) => {
26+
if (!article.slug) {
27+
throw new Error(`Article at index ${articleIndex} in item ${itemIndex} is missing 'slug'. Expected a string.`);
28+
}
29+
if (!article.title) {
30+
throw new Error(`Article at index ${articleIndex} in item ${itemIndex} is missing 'title'. Expected a string.`);
31+
}
32+
if (!article.description) {
33+
throw new Error(`Article at index ${articleIndex} in item ${itemIndex} is missing 'description'. Expected a string.`);
34+
}
35+
if (!article.section) {
36+
throw new Error(`Article at index ${articleIndex} in item ${itemIndex} is missing 'section'. Expected a string.`);
37+
}
38+
if (!article.path) {
39+
throw new Error(`Article at index ${articleIndex} in item ${itemIndex} is missing 'path'. Expected a string.`);
40+
}
41+
});
42+
});
43+
}
44+
45+
try {
46+
const jsonData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
47+
validateJSONStructure(jsonData);
48+
console.log('Validation passed');
49+
} catch (error) {
50+
console.error('Validation failed:', error.message);
51+
process.exit(1);
52+
}

validation/pulse_layout.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
const filePath = path.join(__dirname, '../markdown/pulse/articles.json');
5+
6+
function validateJSONStructure(json) {
7+
if (!Array.isArray(json)) {
8+
throw new Error('Root element should be an array');
9+
}
10+
11+
json.forEach((item, itemIndex) => {
12+
if (!item.slug) {
13+
throw new Error(`Item at index ${itemIndex} is missing 'slug'. Expected a string.`);
14+
}
15+
if (!item.title) {
16+
throw new Error(`Item at index ${itemIndex} is missing 'title'. Expected a string.`);
17+
}
18+
if (!item.description) {
19+
throw new Error(`Item at index ${itemIndex} is missing 'description'. Expected a string.`);
20+
}
21+
if (!Array.isArray(item.sections)) {
22+
throw new Error(`Item at index ${itemIndex} has invalid 'sections'. Expected an array.`);
23+
}
24+
25+
item.sections.forEach((section, sectionIndex) => {
26+
if (!section.title) {
27+
throw new Error(`Section at index ${sectionIndex} in item ${itemIndex} is missing 'title'. Expected a string.`);
28+
}
29+
if (!section.description) {
30+
throw new Error(`Section at index ${sectionIndex} in item ${itemIndex} is missing 'description'. Expected a string.`);
31+
}
32+
if (!section.path) {
33+
throw new Error(`Section at index ${sectionIndex} in item ${itemIndex} is missing 'path'. Expected a string.`);
34+
}
35+
if (!section.slug) {
36+
throw new Error(`Section at index ${sectionIndex} in item ${itemIndex} is missing 'slug'. Expected a string.`);
37+
}
38+
39+
if (section.data !== null && !Array.isArray(section.data)) {
40+
throw new Error(`Section 'data' at index ${sectionIndex} in item ${itemIndex} should be an array or null.`);
41+
}
42+
43+
if (Array.isArray(section.data)) {
44+
section.data.forEach((dataItem, dataIndex) => {
45+
if (!dataItem.title) {
46+
throw new Error(`Data item at index ${dataIndex} in section ${sectionIndex} of item ${itemIndex} is missing 'title'. Expected a string.`);
47+
}
48+
if (!dataItem.description) {
49+
throw new Error(`Data item at index ${dataIndex} in section ${sectionIndex} of item ${itemIndex} is missing 'description'. Expected a string.`);
50+
}
51+
if (!dataItem.date) {
52+
throw new Error(`Data item at index ${dataIndex} in section ${sectionIndex} of item ${itemIndex} is missing 'date'. Expected a string.`);
53+
}
54+
if (!dataItem.path) {
55+
throw new Error(`Data item at index ${dataIndex} in section ${sectionIndex} of item ${itemIndex} is missing 'path'. Expected a string.`);
56+
}
57+
if (!dataItem.slug) {
58+
throw new Error(`Data item at index ${dataIndex} in section ${sectionIndex} of item ${itemIndex} is missing 'slug'. Expected a string.`);
59+
}
60+
if (!Array.isArray(dataItem.tags)) {
61+
throw new Error(`Data item 'tags' at index ${dataIndex} in section ${sectionIndex} of item ${itemIndex} should be an array.`);
62+
}
63+
});
64+
}
65+
});
66+
});
67+
}
68+
69+
try {
70+
const jsonData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
71+
validateJSONStructure(jsonData);
72+
console.log('Validation passed');
73+
} catch (error) {
74+
console.error('Validation failed:', error.message);
75+
process.exit(1);
76+
}

0 commit comments

Comments
 (0)