Skip to content

Commit

Permalink
Spin out node tools from openstreetmap.us
Browse files Browse the repository at this point in the history
  • Loading branch information
quincylvania committed Feb 9, 2024
1 parent b241987 commit d16d83c
Show file tree
Hide file tree
Showing 9 changed files with 878 additions and 0 deletions.
94 changes: 94 additions & 0 deletions _tools/frontmatter-validator/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// frontmatter-validator for dogwood
//
// This script checks that the frontmatter in all your
// Jekyll documents matches a known format. This is important
// since the theme relies on many custom variables.
//
// By default, the script will throw an error if you have
// additional properties to those expected. This catches
// typos like `authors` instead of `author`. Use the
// `--strict=false` option to turn off this behavior.

const matter = require('gray-matter');
const fs = require('fs');
const process = require('process')

const argv = require('minimist')(process.argv.slice(2));

let sourcePath = process.env.npm_config_srcdir || argv.srcdir || '.';
if (sourcePath.endsWith('/')) sourcePath.slice(0, -1);

const ZSchema = require("z-schema");

let zSchemaOptions = {};

let isStrict = true;
if (("npm_config_strict" in process.env && !process.env.npm_config_strict) ||
process.argv.includes("--strict=false")) {
isStrict = false;
}

if (isStrict) {
let strictOptions = {
assumeAdditional: true,
forceItems: true,
forceMinItems: true,
forceMinLength: true,
forceProperties: true,
noEmptyArrays: true,
noEmptyStrings: true,
noExtraKeywords: true,
noTypeless: true,
};
Object.assign(zSchemaOptions, strictOptions);
}

const jsonValidator = new ZSchema(zSchemaOptions);

let hasInvalid = false;

function validateJson(json, schema) {
const valid = jsonValidator.validate(json, schema);
const errors = jsonValidator.getLastErrors();
if (!valid) {
errors.forEach(function(error) {
console.log(error);
});
hasInvalid = true;
}
}

function validateFrontmatter(path, schemaPath) {
const schema = JSON.parse(fs.readFileSync(schemaPath));
const dir = fs.opendirSync(path);
let dirent;
while ((dirent = dir.readSync()) !== null) {
const subpath = path + '/' + dirent.name;
if (dirent.isFile()) {
const filedata = fs.readFileSync(subpath);
const info = matter(filedata);

// ignore files not in Jekyll format
if (Object.keys(info.data).length > 0) {
// parse to string and back again to make sure dates are in string format
let data = JSON.parse(JSON.stringify(info.data));
validateJson(data, schema);
}
} else if (dirent.isDirectory()) {
validateFrontmatter(subpath, schemaPath);
}
}
dir.closeSync();
}

var schemasDir = __dirname + '/schemas';

validateFrontmatter(sourcePath + '/_posts', schemasDir + '/post.json');
validateFrontmatter(sourcePath + '/_people', schemasDir + '/person.json');
validateFrontmatter(sourcePath + '/_pages', schemasDir + '/page.json');
validateFrontmatter(sourcePath + '/_redirects', schemasDir + '/redirect.json');

if (hasInvalid) {
// nonzero exit for GitHub Actions
process.exit(1);
}
281 changes: 281 additions & 0 deletions _tools/frontmatter-validator/schemas/page.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
{
"title": "Page",
"type": "object",
"properties": {
"title": {
"type": "string"
},
"temp_title": {
"type": "string"
},
"short_title": {
"type": "string"
},
"tagline": {
"type": "string"
},
"temp_tagline": {
"type": "string"
},
"blurb": {
"type": "string"
},
"temp_blurb": {
"type": "string"
},
"layout": {
"type": "string"
},
"event": {
"type": "string"
},
"event_series": {
"type": "string"
},
"caption": {
"type": "string"
},
"status": {
"type": "string"
},
"location": {
"type": "string"
},
"image": {
"type": "string"
},
"sign": {
"type": "string"
},
"logo": {
"type": "string"
},
"wordmark": {
"type": "string"
},
"icon": {
"type": "string"
},
"website": {
"type": "string"
},
"twitter": {
"type": "string"
},
"youtube_page": {
"type": "string",
"description": "Path to a page on youtube.com. Different from `youtube` since that parameter is a video ID which is used differently."
},
"facebook": {
"type": "string"
},
"slack_channel": {
"type": "string"
},
"instagram": {
"type": "string"
},
"email_list": {
"type": "string"
},
"meetup": {
"type": "string"
},
"reddit": {
"type": "string"
},
"mastodon": {
"type": "string"
},
"donate": {
"type": "string"
},
"links": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
}
}
}
},
"swag_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"url": {
"type": "string"
},
"image": {
"type": "string"
}
}
}
},
"swag_sections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"url": {
"type": "string"
},
"image": {
"type": "string"
}
}
}
}
}
}
},
"dropdown_links": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
}
}
}
},
"app_links": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
}
}
}
},
"footer_links": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
}
}
}
},
"buttons": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
}
}
}
},
"sessions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"blurb": {
"type": "string"
},
"date": {
"oneOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "string",
"pattern": "\\d{4}-[01]\\d-[0-3]\\d [0-2]\\d:[0-5]\\d(:[0-5]\\d)? ([+-][0-2]\\d[0-5]\\d)"
}
]
}
}
}
},
"section_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"team_name": {
"type": "string"
},
"max_posts": {
"type": "integer"
},
"updated": {
"type": "string",
"format": "date-time"
},
"timezone": {
"type": "string"
},
"filter_start": {
"type": "string",
"format": "date-time"
},
"filter_end": {
"type": "string",
"format": "date-time"
},
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
},
"map": {
"type": "object",
"properties": {
"points": {
"type": "string"
}
}
}
},
"required": [
"title"
]
}
Loading

0 comments on commit d16d83c

Please sign in to comment.