Merge branch 'prettier' into 'main'
Prettier with pre-commit hook See merge request gaiety/pronoun-monster!2
This commit is contained in:
commit
7ab4147764
11 changed files with 1208 additions and 171 deletions
|
@ -44,10 +44,6 @@ unit-test-job: # This job runs in the test stage.
|
||||||
lint-test-job: # This job also runs in the test stage.
|
lint-test-job: # This job also runs in the test stage.
|
||||||
stage: test # It can run at the same time as unit-test-job (in parallel).
|
stage: test # It can run at the same time as unit-test-job (in parallel).
|
||||||
script:
|
script:
|
||||||
- echo "Linting code... TBD"
|
- echo "Linting code..."
|
||||||
|
- npm i
|
||||||
deploy-job: # This job runs in the deploy stage.
|
- npm run lint
|
||||||
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
|
|
||||||
environment: production
|
|
||||||
script:
|
|
||||||
- echo "Deploying application... TBD lol"
|
|
||||||
|
|
10
.prettierignore
Normal file
10
.prettierignore
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Ignore artifacts:
|
||||||
|
build
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# project
|
||||||
|
dist
|
||||||
|
|
||||||
|
# ignore handlebars due to prettier bug https://github.com/prettier/prettier/issues/11834
|
||||||
|
src/views/**/*.hbs
|
||||||
|
src/views/**/*.handlebars
|
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -4,7 +4,7 @@ Inspired by [@morganastra](https://twitter.com/morganastra)'s [pronoun.is](https
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
* [NodeJS](https://nodejs.org/en/)
|
- [NodeJS](https://nodejs.org/en/)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm i # Installs Dependencies
|
npm i # Installs Dependencies
|
||||||
|
|
120
app.js
120
app.js
|
@ -1,69 +1,113 @@
|
||||||
import express from 'express'
|
import express from "express";
|
||||||
import { engine } from 'express-handlebars'
|
import { engine } from "express-handlebars";
|
||||||
import fetchData from './data.js'
|
import fetchData from "./data.js";
|
||||||
|
|
||||||
const app = express()
|
const app = express();
|
||||||
const data = fetchData()
|
const data = fetchData();
|
||||||
|
|
||||||
app.engine('handlebars', engine())
|
app.engine("handlebars", engine());
|
||||||
app.set('view engine', 'handlebars')
|
app.set("view engine", "handlebars");
|
||||||
app.set('views', './src/views')
|
app.set("views", "./src/views");
|
||||||
|
|
||||||
app.use(express.static('dist'))
|
app.use(express.static("dist"));
|
||||||
app.use(express.static('public'))
|
app.use(express.static("public"));
|
||||||
|
|
||||||
const siteName = "Pronoun Monster"
|
const siteName = "Pronoun Monster";
|
||||||
const pronounsToDisplayOnHome = 6
|
const pronounsToDisplayOnHome = 6;
|
||||||
|
|
||||||
function constructLexicon(nominative, accusative, pronominalPossessive, predicativePossessive, reflexive) {
|
function constructLexicon(
|
||||||
|
nominative,
|
||||||
|
accusative,
|
||||||
|
pronominalPossessive,
|
||||||
|
predicativePossessive,
|
||||||
|
reflexive
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
nominative: { name: "Nominative", value: nominative },
|
nominative: { name: "Nominative", value: nominative },
|
||||||
accusative: { name: "Accusative", value: accusative },
|
accusative: { name: "Accusative", value: accusative },
|
||||||
pronominalPossessive: { name: "Pronominal Possessive", value: pronominalPossessive},
|
pronominalPossessive: {
|
||||||
predicativePossessive: { name: "Predicative Possessive", value: predicativePossessive},
|
name: "Pronominal Possessive",
|
||||||
reflexive: { name: "Reflexive", value: reflexive}
|
value: pronominalPossessive,
|
||||||
}
|
},
|
||||||
|
predicativePossessive: {
|
||||||
|
name: "Predicative Possessive",
|
||||||
|
value: predicativePossessive,
|
||||||
|
},
|
||||||
|
reflexive: { name: "Reflexive", value: reflexive },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
app.get("/", (req, res) => {
|
||||||
const pageTitle = siteName;
|
const pageTitle = siteName;
|
||||||
const pronounListLimited = data.map(pronounObject => Object.values(pronounObject).join('/')).slice(0, pronounsToDisplayOnHome)
|
const pronounListLimited = data
|
||||||
res.render('home', { siteName, pageTitle, pronounList: pronounListLimited } )
|
.map((pronounObject) => Object.values(pronounObject).join("/"))
|
||||||
})
|
.slice(0, pronounsToDisplayOnHome);
|
||||||
|
res.render("home", { siteName, pageTitle, pronounList: pronounListLimited });
|
||||||
|
});
|
||||||
|
|
||||||
app.get('/list', (req, res) => {
|
app.get("/list", (req, res) => {
|
||||||
const pageTitle = "List";
|
const pageTitle = "List";
|
||||||
const pronounList = data.map(pronounObject => Object.values(pronounObject).join('/'))
|
const pronounList = data.map((pronounObject) =>
|
||||||
res.render('list', { siteName, pageTitle, pronounList } )
|
Object.values(pronounObject).join("/")
|
||||||
})
|
);
|
||||||
|
res.render("list", { siteName, pageTitle, pronounList });
|
||||||
|
});
|
||||||
|
|
||||||
app.get('/:nominative/:accusative/:predicative_possessive/:reflexive', (req, res) => {
|
app.get(
|
||||||
|
"/:nominative/:accusative/:predicative_possessive/:reflexive",
|
||||||
|
(req, res) => {
|
||||||
const {
|
const {
|
||||||
nominative,
|
nominative,
|
||||||
accusative,
|
accusative,
|
||||||
predicative_possessive: predicativePossessive,
|
predicative_possessive: predicativePossessive,
|
||||||
reflexive,
|
reflexive,
|
||||||
} = req.params
|
} = req.params;
|
||||||
|
|
||||||
const lexicon = constructLexicon(nominative, accusative, accusative, predicativePossessive, reflexive);
|
const lexicon = constructLexicon(
|
||||||
const pageTitle = Object.values(lexicon).map(entry => entry.value).join("/") + " - " + siteName;
|
nominative,
|
||||||
|
accusative,
|
||||||
|
accusative,
|
||||||
|
predicativePossessive,
|
||||||
|
reflexive
|
||||||
|
);
|
||||||
|
const pageTitle =
|
||||||
|
Object.values(lexicon)
|
||||||
|
.map((entry) => entry.value)
|
||||||
|
.join("/") +
|
||||||
|
" - " +
|
||||||
|
siteName;
|
||||||
|
|
||||||
res.render('individual', { siteName, pageTitle, lexicon })
|
res.render("individual", { siteName, pageTitle, lexicon });
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
app.get('/:nominative/:accusative/:pronominal_possessive/:predicative_possessive/:reflexive', (req, res) => {
|
app.get(
|
||||||
|
"/:nominative/:accusative/:pronominal_possessive/:predicative_possessive/:reflexive",
|
||||||
|
(req, res) => {
|
||||||
const {
|
const {
|
||||||
nominative,
|
nominative,
|
||||||
accusative,
|
accusative,
|
||||||
pronominal_possessive: pronominalPossessive,
|
pronominal_possessive: pronominalPossessive,
|
||||||
predicative_possessive: predicativePossessive,
|
predicative_possessive: predicativePossessive,
|
||||||
reflexive,
|
reflexive,
|
||||||
} = req.params
|
} = req.params;
|
||||||
|
|
||||||
const lexicon = constructLexicon(nominative, accusative, pronominalPossessive, predicativePossessive, reflexive);
|
const lexicon = constructLexicon(
|
||||||
const pageTitle = Object.values(lexicon).map(entry => entry.value).join("/") + " - " + siteName;
|
nominative,
|
||||||
|
accusative,
|
||||||
|
pronominalPossessive,
|
||||||
|
predicativePossessive,
|
||||||
|
reflexive
|
||||||
|
);
|
||||||
|
const pageTitle =
|
||||||
|
Object.values(lexicon)
|
||||||
|
.map((entry) => entry.value)
|
||||||
|
.join("/") +
|
||||||
|
" - " +
|
||||||
|
siteName;
|
||||||
|
|
||||||
res.render('individual', { siteName, pageTitle, lexicon })
|
res.render("individual", { siteName, pageTitle, lexicon });
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
app.listen(3000)
|
app.listen(3000);
|
||||||
|
|
37
data.js
37
data.js
|
@ -1,20 +1,21 @@
|
||||||
import fs from 'fs'
|
import fs from "fs";
|
||||||
|
|
||||||
const databaseCSV = fs.readFileSync('database.csv', {encoding:'utf8', flag:'r'})
|
const databaseCSV = fs.readFileSync("database.csv", {
|
||||||
|
encoding: "utf8",
|
||||||
|
flag: "r",
|
||||||
|
});
|
||||||
|
|
||||||
export function splitNewLines(string) {
|
export function splitNewLines(string) {
|
||||||
return string.split(/\n/)
|
return string.split(/\n/);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cleanupArrayOfStrings(arrayOfStrings) {
|
export function cleanupArrayOfStrings(arrayOfStrings) {
|
||||||
return arrayOfStrings
|
return arrayOfStrings.map((line) => line.trim()).filter((line) => line != "");
|
||||||
.map(line => line.trim())
|
|
||||||
.filter(line => line != '')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stringCsvToDataObject(string) {
|
export function stringCsvToDataObject(string) {
|
||||||
let splitString = string.split(',')
|
let splitString = string.split(",");
|
||||||
if (splitString[2].trim() == '') splitString[2] = splitString[1]
|
if (splitString[2].trim() == "") splitString[2] = splitString[1];
|
||||||
|
|
||||||
const [
|
const [
|
||||||
nominative,
|
nominative,
|
||||||
|
@ -22,15 +23,23 @@ export function stringCsvToDataObject(string) {
|
||||||
pronominalPossessive,
|
pronominalPossessive,
|
||||||
predicativePossessive,
|
predicativePossessive,
|
||||||
reflexive,
|
reflexive,
|
||||||
] = cleanupArrayOfStrings(splitString)
|
] = cleanupArrayOfStrings(splitString);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
nominative, accusative, pronominalPossessive, predicativePossessive, reflexive
|
nominative,
|
||||||
}
|
accusative,
|
||||||
|
pronominalPossessive,
|
||||||
|
predicativePossessive,
|
||||||
|
reflexive,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
const databaseCSV = fs.readFileSync('database.csv', {encoding:'utf8', flag:'r'})
|
const databaseCSV = fs.readFileSync("database.csv", {
|
||||||
return cleanupArrayOfStrings(splitNewLines(databaseCSV)).map(line => stringCsvToDataObject(line))
|
encoding: "utf8",
|
||||||
|
flag: "r",
|
||||||
|
});
|
||||||
|
return cleanupArrayOfStrings(splitNewLines(databaseCSV)).map((line) =>
|
||||||
|
stringCsvToDataObject(line)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
956
package-lock.json
generated
956
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
@ -12,7 +12,9 @@
|
||||||
"serve:svg": "nodemon --watch 'src/svgs/*' -e svg --exec 'npm run build:svg'",
|
"serve:svg": "nodemon --watch 'src/svgs/*' -e svg --exec 'npm run build:svg'",
|
||||||
"build:css": "tailwindcss -i ./src/app.css -o ./dist/app.css",
|
"build:css": "tailwindcss -i ./src/app.css -o ./dist/app.css",
|
||||||
"build:svg": "svgdir2sprite ./src/svgs ./dist/spritesheet.svg",
|
"build:svg": "svgdir2sprite ./src/svgs ./dist/spritesheet.svg",
|
||||||
"test": "ava"
|
"test": "ava",
|
||||||
|
"lint": "prettier --check .",
|
||||||
|
"prepare": "husky install"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -31,8 +33,14 @@
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-handlebars": "^7.0.2",
|
"express-handlebars": "^7.0.2",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
|
"husky": "^8.0.3",
|
||||||
|
"lint-staged": "^13.2.0",
|
||||||
"nodemon": "^2.0.21",
|
"nodemon": "^2.0.21",
|
||||||
|
"prettier": "2.8.4",
|
||||||
"svgdir2sprite": "^1.0.5",
|
"svgdir2sprite": "^1.0.5",
|
||||||
"tailwindcss": "^3.2.7"
|
"tailwindcss": "^3.2.7"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"**/*": "prettier --write --ignore-unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
34
src/app.css
34
src/app.css
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* light */
|
/* light */
|
||||||
--background: #F8FAF9; /* Sage/Light/2 */
|
--background: #f8faf9; /* Sage/Light/2 */
|
||||||
--callout: #ECEFED; /* Sage/Light/4 */
|
--callout: #ecefed; /* Sage/Light/4 */
|
||||||
--stroke: #D7DCDA; /* Sage/Light/7 */
|
--stroke: #d7dcda; /* Sage/Light/7 */
|
||||||
--text-shout: #236E4A; /* Green/Dark/8 */
|
--text-shout: #236e4a; /* Green/Dark/8 */
|
||||||
--text-murmur: #113123; /* Green/Dark/4 */
|
--text-murmur: #113123; /* Green/Dark/4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,34 +15,40 @@
|
||||||
:root {
|
:root {
|
||||||
/* dark */
|
/* dark */
|
||||||
--background: #141716; /* Sage/Dark/1 */
|
--background: #141716; /* Sage/Dark/1 */
|
||||||
--callout: #252A27; /* Sage/Dark/4 */
|
--callout: #252a27; /* Sage/Dark/4 */
|
||||||
--stroke: #393F3C; /* Sage/Dark/7 */
|
--stroke: #393f3c; /* Sage/Dark/7 */
|
||||||
--text-shout: #92CEAC; /* Green/Light/7 */
|
--text-shout: #92ceac; /* Green/Light/7 */
|
||||||
--text-murmur: #99A29E; /* Green/Dark/11 */
|
--text-murmur: #99a29e; /* Green/Dark/11 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
color: var(--text-murmur);
|
color: var(--text-murmur);
|
||||||
font-family: Manrope, 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
|
font-family: Manrope, "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
|
||||||
|
"Lucida Sans Unicode", Geneva, Verdana, sans-serif;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2, h3, h4 {
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
color: var(--text-shout);
|
color: var(--text-shout);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-family: "Redaction", Georgia, 'Times New Roman', Times, serif;
|
font-family: "Redaction", Georgia, "Times New Roman", Times, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-family: "Redaction 10", Georgia, 'Times New Roman', Times, serif;
|
font-family: "Redaction 10", Georgia, "Times New Roman", Times, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
|
@ -93,7 +99,7 @@ footer {
|
||||||
.button-cta:active {
|
.button-cta:active {
|
||||||
border-top: 1px solid var(--text-shout);
|
border-top: 1px solid var(--text-shout);
|
||||||
border-right: 1px solid var(--text-shout);
|
border-right: 1px solid var(--text-shout);
|
||||||
transform: translate(-1px, 2px)
|
transform: translate(-1px, 2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: 1024px) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ['./src/views/**/*.{handlebars,hbs,html,htm,js}'],
|
content: ["./src/views/**/*.{handlebars,hbs,html,htm,js}"],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,55 +1,62 @@
|
||||||
import fs from 'fs'
|
import fs from "fs";
|
||||||
import test from 'ava'
|
import test from "ava";
|
||||||
import fetchData, { splitNewLines, cleanupArrayOfStrings, stringCsvToDataObject } from '../data.js'
|
import fetchData, {
|
||||||
|
splitNewLines,
|
||||||
|
cleanupArrayOfStrings,
|
||||||
|
stringCsvToDataObject,
|
||||||
|
} from "../data.js";
|
||||||
|
|
||||||
test('splitNewLines', t => {
|
test("splitNewLines", (t) => {
|
||||||
const result = splitNewLines(`foo\nbar`)
|
const result = splitNewLines(`foo\nbar`);
|
||||||
|
|
||||||
t.deepEqual(result, ['foo', 'bar'])
|
t.deepEqual(result, ["foo", "bar"]);
|
||||||
})
|
});
|
||||||
|
|
||||||
test('cleanupArrayOfStrings', t => {
|
test("cleanupArrayOfStrings", (t) => {
|
||||||
const result = cleanupArrayOfStrings([
|
const result = cleanupArrayOfStrings(["", " foo", "bar ", ""]);
|
||||||
'',
|
|
||||||
' foo',
|
|
||||||
'bar ',
|
|
||||||
''
|
|
||||||
])
|
|
||||||
|
|
||||||
t.deepEqual(result, ['foo', 'bar'])
|
t.deepEqual(result, ["foo", "bar"]);
|
||||||
})
|
});
|
||||||
|
|
||||||
test('clean an array made from a string of new lines', t => {
|
test("clean an array made from a string of new lines", (t) => {
|
||||||
const result = cleanupArrayOfStrings(
|
const result = cleanupArrayOfStrings(
|
||||||
splitNewLines(`
|
splitNewLines(`
|
||||||
foo
|
foo
|
||||||
bar
|
bar
|
||||||
`)
|
`)
|
||||||
)
|
);
|
||||||
|
|
||||||
t.deepEqual(result, ['foo', 'bar'])
|
t.deepEqual(result, ["foo", "bar"]);
|
||||||
})
|
});
|
||||||
|
|
||||||
test('stringCsvToDataObject', t => {
|
test("stringCsvToDataObject", (t) => {
|
||||||
const result = stringCsvToDataObject('they,them,them, their,themself')
|
const result = stringCsvToDataObject("they,them,them, their,themself");
|
||||||
|
|
||||||
t.deepEqual(result, {
|
t.deepEqual(result, {
|
||||||
nominative: 'they', accusative: 'them', pronominalPossessive: 'them', predicativePossessive: 'their', reflexive: 'themself'
|
nominative: "they",
|
||||||
})
|
accusative: "them",
|
||||||
})
|
pronominalPossessive: "them",
|
||||||
|
predicativePossessive: "their",
|
||||||
|
reflexive: "themself",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('stringCsvToDataObject with missing pronominalPossessive', t => {
|
test("stringCsvToDataObject with missing pronominalPossessive", (t) => {
|
||||||
const result = stringCsvToDataObject('they,them,,their,themself')
|
const result = stringCsvToDataObject("they,them,,their,themself");
|
||||||
|
|
||||||
t.deepEqual(result, {
|
t.deepEqual(result, {
|
||||||
nominative: 'they', accusative: 'them', pronominalPossessive: 'them', predicativePossessive: 'their', reflexive: 'themself'
|
nominative: "they",
|
||||||
})
|
accusative: "them",
|
||||||
})
|
pronominalPossessive: "them",
|
||||||
|
predicativePossessive: "their",
|
||||||
|
reflexive: "themself",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('database.csv loads into array of valid data', t => {
|
test("database.csv loads into array of valid data", (t) => {
|
||||||
const data = fetchData()
|
const data = fetchData();
|
||||||
|
|
||||||
t.truthy(Array.isArray(data))
|
t.truthy(Array.isArray(data));
|
||||||
t.is(typeof data[0], 'object')
|
t.is(typeof data[0], "object");
|
||||||
t.is(typeof data[0].nominative, 'string')
|
t.is(typeof data[0].nominative, "string");
|
||||||
})
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue