on d6964fa help sign in
urbit.org/lib/lib.js
177 lines 5.4 kB history raw
1import fs from "fs";
2import { join, parse } from "path";
3import matter from "gray-matter";
4import toml from "@iarna/toml";
5import { DateTime } from "luxon";
6import { getPostBySlug, getPostSlugs } from "@urbit/foundation-design-system";
8// NB Gavin: This could be much simpler if we converted everything to a more common standard, like YAML
9const options = {
10 engines: {
11 toml: toml.parse.bind(toml),
12 },
13 language: "toml",
14 delimiters: "+++",
15};
17const directories = (dir) => {
18 switch (dir) {
19 case "blog":
20 return join(process.cwd(), "content/blog");
21 case "events":
22 return join(process.cwd(), "content/events");
23 case "docs":
24 return join(process.cwd(), "content/docs");
25 case "grants":
26 return join(process.cwd(), "content/grants");
27 case "media":
28 return join(process.cwd(), "content/media");
29 case "updates":
30 return join(process.cwd(), "content/updates");
31 case "/":
32 return join(process.cwd(), "content");
33 default:
34 return join(process.cwd(), `content/${dir}`);
35 }
36};
38export function getAllPosts(fields = [], key, sort = "") {
39 const slugs = getPostSlugs(key);
40 const posts = slugs
41 .map((slug) => getPostBySlug(slug, fields, key))
42 // sort posts by date in descending order
43 .sort((post1, post2) => {
44 if (sort === "date") {
45 return DateTime.fromISO(post1.date) > DateTime.fromISO(post2.date)
46 ? -1
47 : 1;
48 } else if (sort === "weight") {
49 return post1.weight > post2.weight ? -1 : 1;
50 }
51 });
52 return posts;
55export function getAllEvents(fields = [], key) {
56 const slugs = getPostSlugs(key);
57 const posts = slugs
58 .map((slug) => getPostBySlug(slug, fields, key))
59 // sort posts by date in descending order
60 .sort((post1, post2) =>
61 DateTime.fromISO(post1.starts) > DateTime.fromISO(post2.starts) ? -1 : 1
62 );
63 return posts;
66function getAllPaths(dirPath, arrayOfFiles) {
67 let files = fs.readdirSync(dirPath);
69 arrayOfFiles = arrayOfFiles || [];
71 files.forEach(function (file) {
72 if (fs.statSync(dirPath + "/" + file).isDirectory()) {
73 arrayOfFiles = getAllPaths(dirPath + "/" + file, arrayOfFiles);
74 } else {
75 arrayOfFiles.push(join(dirPath, "/", file));
76 }
77 });
79 return arrayOfFiles;
82export function getDocsPaths() {
83 return getAllPaths(directories("docs"), []);
86export function formatDateWithTime(d) {
87 const date = DateTime.fromISO(d, {
88 setZone: true,
89 }).toLocaleString(DateTime.DATETIME_FULL);
90 return date;
93// Formats a DateTime object to something like "July 15, 2021, 5:00 PM"
94export function formatDateAndTime(dateTimeObject) {
95 return dateTimeObject.toLocaleString(DateTime.DATETIME_HUGE);
98// Returns an array of unique grants categories
99export function getGrantsCategories() {
100 const paths = fs.readdirSync(directories("grants"));
101 const uniqueCategories = paths
102 // Get only markdown files
103 .filter((path) => parse(path).ext === ".md")
104 // Parse frontmatter
105 .map((path) =>
106 matter(fs.readFileSync(join(directories("grants"), path)), options)
107 )
108 // Each markdown file has an array of categories. Collapse these arrays into one array.
109 .reduce((acc, metadata) => {
110 return [...acc, ...metadata.data.taxonomies.grant_category];
111 }, [])
112 // Deduplicate single array of categories such that the output is an array where each category is represented only once.
113 .reduce((acc, uniqueItem) => {
114 if (acc.includes(uniqueItem)) {
115 return acc;
116 }
117 return [...acc, uniqueItem];
118 }, []);
119 return uniqueCategories;
122// Returns an array of unique grants types
123export function getGrantsTypes() {
124 const paths = fs.readdirSync(directories("grants"));
125 const uniqueTypes = paths
126 // Get only markdown files
127 .filter((path) => parse(path).ext === ".md")
128 // Parse frontmatter to JSON
129 .map((path) =>
130 matter(fs.readFileSync(join(directories("grants"), path)), options)
131 )
132 // Each markdown file has an array of types. Collapse these arrays into one array.
133 .reduce((acc, metadata) => {
134 return [...acc, ...metadata.data.taxonomies.grant_type];
135 }, [])
136 // Deduplicate single array of types such that the output is an array where each type is represented only once.
137 .reduce((acc, uniqueItem) => {
138 if (acc.includes(uniqueItem)) {
139 return acc;
140 }
141 return [...acc, uniqueItem];
142 }, []);
143 return uniqueTypes;
146// Returns a number which represents how many grants are open, or uncompleted
147export function getOpenGrantsCount() {
148 const paths = fs.readdirSync(directories("grants"));
149 const count = paths
150 // Get only markdown files
151 .filter((path) => parse(path).ext === ".md")
152 // Parse frontmatter to JSON
153 .map((path) =>
154 matter(fs.readFileSync(join(directories("grants"), path)), options)
155 )
156 // Count grants which are both uncompleted and not assigned
157 .reduce((acc, metadata) => {
158 if (
159 !metadata.data.extra.completed &&
160 !metadata.data.extra.canceled &&
161 metadata.data.extra.assignee?.[0] === ""
162 ) {
163 return acc + 1;
164 }
165 return acc;
166 }, 0);
167 return count;
170// Groups arrays into an array of arrays with 2 members
171export const pair = (arr) =>
172 arr.reduce(function (rows, key, index) {
173 return (
174 (index % 2 == 0 ? rows.push([key]) : rows[rows.length - 1].push(key)) &&
175 rows
176 );
177 }, []);