Compare commits
19 Commits
1115a7afdd
...
main
Author | SHA1 | Date | |
---|---|---|---|
2840715cb6 | |||
5c6a07e87b | |||
cd0dd430c6 | |||
115f5692e3 | |||
45c625994b | |||
93aea2e385 | |||
d5a43e291c | |||
f499b594da | |||
7beb704808 | |||
3f642f0a47 | |||
c0450242ea | |||
cb627abe06 | |||
b56bcbc26d | |||
d5f71fa043 | |||
0bde4eb0d1 | |||
22bad851e0 | |||
2c861f868a | |||
a31c158cc5 | |||
78b35a7d83 |
@@ -1,9 +1,9 @@
|
||||
FROM node:22 AS builder
|
||||
FROM node:24 AS builder
|
||||
|
||||
COPY . /src
|
||||
WORKDIR /src
|
||||
RUN npm install && node ./index.js
|
||||
|
||||
FROM caddy:2.9.1
|
||||
FROM caddy:2.10.2
|
||||
|
||||
COPY --from=builder /src/build /usr/share/caddy
|
||||
|
40
index.js
40
index.js
@@ -1,13 +1,15 @@
|
||||
import { load } from "cheerio";
|
||||
import { readFile, writeFileSync, mkdirSync, cpSync, rmSync } from "fs";
|
||||
import process from "child_process";
|
||||
import { simpleSitemapAndIndex } from "sitemap";
|
||||
|
||||
import stores from "./stores.json" with { type: "json" };
|
||||
|
||||
function mkDir(path) {
|
||||
try {
|
||||
return mkdirSync(path)
|
||||
return mkdirSync(path);
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err
|
||||
if (err.code !== "EEXIST") throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +19,7 @@ function writeFile(path, content) {
|
||||
} catch (err) {
|
||||
if (err) throw err;
|
||||
}
|
||||
console.log(`${path} updated.`);
|
||||
console.log(`${path} updated.`);
|
||||
}
|
||||
|
||||
function slugify(str) {
|
||||
@@ -41,10 +43,15 @@ function cleanWebsite(str) {
|
||||
}
|
||||
|
||||
function metaDescription({ name, meta, description }) {
|
||||
if (meta && (meta.length > 155 || meta.length < 145 && meta.length !== 0)) {
|
||||
console.log(`warning: meta tag for ${name} is invalid: 145/${meta.length}/155`)
|
||||
if (meta && (meta.length > 155 || (meta.length < 145 && meta.length !== 0))) {
|
||||
console.log(
|
||||
`warning: meta tag for ${name} is invalid: 145/${meta.length}/155`
|
||||
);
|
||||
}
|
||||
return meta || description.length > 155 ? description.slice(0, 153) + "..." : description || "A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
|
||||
return meta || description.length > 155
|
||||
? description.slice(0, 153) + "..."
|
||||
: description ||
|
||||
"A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions.";
|
||||
}
|
||||
|
||||
function GetRecentChanges() {
|
||||
@@ -176,15 +183,17 @@ readFile("./index.tmpl.html", function (err, data) {
|
||||
|
||||
rmSync("./build", { recursive: true, force: true });
|
||||
|
||||
mkDir("./build")
|
||||
|
||||
writeFile("./build/index.html", $.html())
|
||||
mkDir("./build");
|
||||
|
||||
writeFile("./build/index.html", $.html());
|
||||
|
||||
cpSync("./site.css", "./build/site.css");
|
||||
cpSync("./robots.txt", "./build/robots.txt");
|
||||
cpSync("./img", "./build/img", {recursive: true});
|
||||
cpSync("./img", "./build/img", { recursive: true });
|
||||
cpSync("./stores.json", "./build/stores.json");
|
||||
|
||||
let pages = [{ url: `/` }];
|
||||
|
||||
stores.forEach((store) => {
|
||||
$("#selected").html(SelectedStoreTemplate(store));
|
||||
$("#info").addClass("hidden");
|
||||
@@ -192,7 +201,18 @@ readFile("./index.tmpl.html", function (err, data) {
|
||||
$("title").html(title);
|
||||
$("meta[name='title']").attr("content", title);
|
||||
$("meta[name='description']").attr("content", metaDescription(store));
|
||||
$("link[rel='canonical']").attr(
|
||||
"href",
|
||||
`https://www.nycbookstores.org/${slugify(store.name)}/`
|
||||
);
|
||||
mkDir(`./build/${slugify(store.name)}`);
|
||||
writeFile(`./build/${slugify(store.name)}/index.html`, $.html());
|
||||
pages.push({ url: `/${slugify(store.name)}/` });
|
||||
});
|
||||
simpleSitemapAndIndex({
|
||||
hostname: "https://www.nycbookstores.org/",
|
||||
destinationDir: `./build/`,
|
||||
sourceData: pages,
|
||||
gzip: false,
|
||||
});
|
||||
});
|
||||
|
249
package-lock.json
generated
249
package-lock.json
generated
@@ -9,33 +9,55 @@
|
||||
"version": "1.0.0",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.12"
|
||||
"cheerio": "^1.0.0",
|
||||
"sitemap": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "17.0.45",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
|
||||
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/sax": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
|
||||
"integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||
},
|
||||
"node_modules/cheerio": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
|
||||
"integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz",
|
||||
"integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==",
|
||||
"dependencies": {
|
||||
"cheerio-select": "^2.1.0",
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.1.0",
|
||||
"encoding-sniffer": "^0.2.0",
|
||||
"htmlparser2": "^9.1.0",
|
||||
"parse5": "^7.1.2",
|
||||
"parse5-htmlparser2-tree-adapter": "^7.0.0",
|
||||
"domutils": "^3.2.2",
|
||||
"encoding-sniffer": "^0.2.1",
|
||||
"htmlparser2": "^10.0.0",
|
||||
"parse5": "^7.3.0",
|
||||
"parse5-htmlparser2-tree-adapter": "^7.1.0",
|
||||
"parse5-parser-stream": "^7.1.2",
|
||||
"undici": "^6.19.5",
|
||||
"undici": "^7.12.0",
|
||||
"whatwg-mimetype": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
"node": ">=20.18.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
|
||||
@@ -122,9 +144,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
||||
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
||||
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
@@ -135,9 +157,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/encoding-sniffer": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
|
||||
"integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
|
||||
"integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.3",
|
||||
"whatwg-encoding": "^3.1.1"
|
||||
@@ -158,9 +180,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
|
||||
"integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
|
||||
"integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
|
||||
"funding": [
|
||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||
{
|
||||
@@ -171,8 +193,19 @@
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.1.0",
|
||||
"entities": "^4.5.0"
|
||||
"domutils": "^3.2.1",
|
||||
"entities": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2/node_modules/entities": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
|
||||
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
@@ -198,22 +231,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/parse5": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
|
||||
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
|
||||
"integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
|
||||
"dependencies": {
|
||||
"entities": "^4.4.0"
|
||||
"entities": "^6.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5-htmlparser2-tree-adapter": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
|
||||
"integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
|
||||
"integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
|
||||
"dependencies": {
|
||||
"domhandler": "^5.0.2",
|
||||
"domhandler": "^5.0.3",
|
||||
"parse5": "^7.0.0"
|
||||
},
|
||||
"funding": {
|
||||
@@ -231,17 +264,53 @@
|
||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/parse5/node_modules/entities": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
|
||||
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz",
|
||||
"integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==",
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/sitemap": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.0.tgz",
|
||||
"integrity": "sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "^17.0.5",
|
||||
"@types/sax": "^1.2.1",
|
||||
"arg": "^5.0.0",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"bin": {
|
||||
"sitemap": "dist/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
"node": ">=14.0.0",
|
||||
"npm": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.15.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.15.0.tgz",
|
||||
"integrity": "sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ==",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-encoding": {
|
||||
@@ -265,26 +334,44 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "17.0.45",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
|
||||
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="
|
||||
},
|
||||
"@types/sax": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
|
||||
"integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
|
||||
},
|
||||
"boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||
},
|
||||
"cheerio": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
|
||||
"integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz",
|
||||
"integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==",
|
||||
"requires": {
|
||||
"cheerio-select": "^2.1.0",
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.1.0",
|
||||
"encoding-sniffer": "^0.2.0",
|
||||
"htmlparser2": "^9.1.0",
|
||||
"parse5": "^7.1.2",
|
||||
"parse5-htmlparser2-tree-adapter": "^7.0.0",
|
||||
"domutils": "^3.2.2",
|
||||
"encoding-sniffer": "^0.2.1",
|
||||
"htmlparser2": "^10.0.0",
|
||||
"parse5": "^7.3.0",
|
||||
"parse5-htmlparser2-tree-adapter": "^7.1.0",
|
||||
"parse5-parser-stream": "^7.1.2",
|
||||
"undici": "^6.19.5",
|
||||
"undici": "^7.12.0",
|
||||
"whatwg-mimetype": "^4.0.0"
|
||||
}
|
||||
},
|
||||
@@ -342,9 +429,9 @@
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
||||
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
||||
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
||||
"requires": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
@@ -352,9 +439,9 @@
|
||||
}
|
||||
},
|
||||
"encoding-sniffer": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
|
||||
"integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
|
||||
"integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
|
||||
"requires": {
|
||||
"iconv-lite": "^0.6.3",
|
||||
"whatwg-encoding": "^3.1.1"
|
||||
@@ -366,14 +453,21 @@
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
|
||||
"integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
|
||||
"integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.1.0",
|
||||
"entities": "^4.5.0"
|
||||
"domutils": "^3.2.1",
|
||||
"entities": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
|
||||
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
@@ -393,19 +487,26 @@
|
||||
}
|
||||
},
|
||||
"parse5": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
|
||||
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
|
||||
"integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
|
||||
"requires": {
|
||||
"entities": "^4.4.0"
|
||||
"entities": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
|
||||
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"parse5-htmlparser2-tree-adapter": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
|
||||
"integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
|
||||
"integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
|
||||
"requires": {
|
||||
"domhandler": "^5.0.2",
|
||||
"domhandler": "^5.0.3",
|
||||
"parse5": "^7.0.0"
|
||||
}
|
||||
},
|
||||
@@ -422,10 +523,26 @@
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"sitemap": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.0.tgz",
|
||||
"integrity": "sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==",
|
||||
"requires": {
|
||||
"@types/node": "^17.0.5",
|
||||
"@types/sax": "^1.2.1",
|
||||
"arg": "^5.0.0",
|
||||
"sax": "^1.2.4"
|
||||
}
|
||||
},
|
||||
"undici": {
|
||||
"version": "6.19.7",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz",
|
||||
"integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A=="
|
||||
"version": "7.15.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.15.0.tgz",
|
||||
"integrity": "sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ=="
|
||||
},
|
||||
"whatwg-encoding": {
|
||||
"version": "3.1.1",
|
||||
|
@@ -14,7 +14,8 @@
|
||||
},
|
||||
"homepage": "https://www.nycbookstores.org/",
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.12"
|
||||
"cheerio": "^1.0.0",
|
||||
"sitemap": "^8.0.0"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
@@ -0,0 +1 @@
|
||||
Sitemap: https://nycbookstores.org/sitemap-index.xml
|
||||
|
94
stores.json
94
stores.json
@@ -329,21 +329,6 @@
|
||||
"cafe": "No",
|
||||
"meta": "Three Lives & Company, in the West Village, Manhattan, is a gorgeous neighborhood bookstore with knowledgable staff and a selection of literary fiction."
|
||||
},
|
||||
{
|
||||
"name": "Shakespeare & Company",
|
||||
"address": "939 Lexington Ave",
|
||||
"city": "New York",
|
||||
"state": "NY",
|
||||
"postcode": "10065",
|
||||
"description": "Sharing a name with the famous Parisian bookshop but no other official ties, this store has a general-interest selection of books on its main level and, downstairs, textbooks for the nearby colleges.",
|
||||
"lat": "40.768188",
|
||||
"long": "-73.963531",
|
||||
"country": "USA",
|
||||
"website": "https://shop.shakeandco.com/",
|
||||
"events": "Yes",
|
||||
"cafe": "Yes",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "Book Culture",
|
||||
"address": "536 W 112th St",
|
||||
@@ -1185,12 +1170,12 @@
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "Shakespeare & Company (Upper West Side)",
|
||||
"name": "Strand Bookstore (Upper West Side)",
|
||||
"address": "2020 Broadway",
|
||||
"city": "New York",
|
||||
"state": "NY",
|
||||
"postcode": "10023",
|
||||
"description": "",
|
||||
"description": "Formerly Shakespeare and Company Lincoln Center.",
|
||||
"lat": "40.776484",
|
||||
"long": "-73.981811",
|
||||
"country": "USA",
|
||||
@@ -1709,21 +1694,6 @@
|
||||
"cafe": "Yes",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "Shakespeare & Company (Manhattan Valley/Columbia University)",
|
||||
"address": "2736 Broadway",
|
||||
"city": "New York",
|
||||
"state": "NY",
|
||||
"postcode": "10025",
|
||||
"description": "",
|
||||
"lat": "40.800259699774",
|
||||
"long": "-73.96768731230581",
|
||||
"country": "USA",
|
||||
"website": "https://shop.shakeandco.com/",
|
||||
"events": "Yes",
|
||||
"cafe": "No",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "Liz's Book Bar",
|
||||
"address": "315 Smith St",
|
||||
@@ -1798,5 +1768,65 @@
|
||||
"events": "Yes",
|
||||
"cafe": "Yes",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "The Fountain Bookshop",
|
||||
"address": "803 W 187th St",
|
||||
"city": "New York",
|
||||
"state": "NY",
|
||||
"postcode": "10033",
|
||||
"description": "",
|
||||
"lat": "40.85536319660771",
|
||||
"long": "-73.9369908112493",
|
||||
"country": "USA",
|
||||
"website": "https://fountainbookshop.com/",
|
||||
"events": "Yes",
|
||||
"cafe": "Yes",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "Twisted Spine Books",
|
||||
"address": "306 Grand St",
|
||||
"city": "Brooklyn",
|
||||
"state": "NY",
|
||||
"postcode": "11211",
|
||||
"description": "",
|
||||
"lat": "40.71281455385764",
|
||||
"long": "-73.95724940889518",
|
||||
"country": "USA",
|
||||
"website": "https://www.twistedspinebooks.com/",
|
||||
"events": "Yes",
|
||||
"cafe": "No",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "Gladys Books & Wine",
|
||||
"address": "306 Malcolm X Blvd",
|
||||
"city": "Brooklyn",
|
||||
"state": "NY",
|
||||
"postcode": "11233",
|
||||
"description": "",
|
||||
"lat": "40.682375148825216",
|
||||
"long": "-73.92910519253844",
|
||||
"country": "USA",
|
||||
"website": "https://www.gladysbooksandwine.com/",
|
||||
"events": "Yes",
|
||||
"cafe": "Yes",
|
||||
"meta": ""
|
||||
},
|
||||
{
|
||||
"name": "White Rabbit's Books",
|
||||
"address": "200 West 86th St",
|
||||
"city": "New York",
|
||||
"state": "NY",
|
||||
"postcode": "10024",
|
||||
"description": "",
|
||||
"lat": "40.78773297148539",
|
||||
"long": "-73.9754510091096",
|
||||
"country": "USA",
|
||||
"website": "https://whiterabbitsbooks.com/",
|
||||
"events": "Yes",
|
||||
"cafe": "No",
|
||||
"meta": ""
|
||||
}
|
||||
]
|
||||
|
Reference in New Issue
Block a user