@tideworthy/tidysites 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/tidysites.mjs +13 -1
- package/lib/validate.mjs +2 -2
- package/package.json +1 -1
package/bin/tidysites.mjs
CHANGED
|
@@ -87,11 +87,15 @@ function writeFiles(dir, files) {
|
|
|
87
87
|
function readLocal(dir, only = null) {
|
|
88
88
|
const local = {};
|
|
89
89
|
const problems = [];
|
|
90
|
+
// Only the website's own collections are entries; a folder of the person's own (notes, assets, source) is left alone.
|
|
91
|
+
const schema = readJson(join(dir, META, 'schema.json'));
|
|
92
|
+
const known = schema ? new Set((schema.collections?.items ?? schema.collections ?? []).map((c) => c.slug).filter(Boolean)) : null;
|
|
90
93
|
for (const name of readdirSync(dir)) {
|
|
91
94
|
if (name.startsWith('.') || name === 'node_modules') continue;
|
|
92
95
|
const colDir = join(dir, name);
|
|
93
96
|
if (!statSync(colDir).isDirectory()) continue;
|
|
94
97
|
if (!/^[a-z][a-z0-9_]*$/.test(name) || name === 'menus') continue;
|
|
98
|
+
if (known && known.size && !known.has(name)) continue;
|
|
95
99
|
if (only && !only.includes(name)) continue;
|
|
96
100
|
const sidecarExts = Object.keys(SIDECARS[name] ?? SIDECARS.default);
|
|
97
101
|
for (const file of readdirSync(colDir)) {
|
|
@@ -678,7 +682,15 @@ async function main() {
|
|
|
678
682
|
writeFileSync(join(dir, META, 'key'), `${key}\n`, { mode: 0o600 });
|
|
679
683
|
writeFileSync(join(dir, META, '.gitignore'), 'key\nshots/\nsource/\npages/\n');
|
|
680
684
|
say(`Connected ${relative(process.cwd(), dir) || '.'} to ${site} on ${host}.`);
|
|
681
|
-
|
|
685
|
+
// A website that is still being set up answers 404 on its content model for a few minutes; the first pull waits for it.
|
|
686
|
+
for (let attempt = 1; ; attempt++) {
|
|
687
|
+
try { await pull(config()); break; }
|
|
688
|
+
catch (e) {
|
|
689
|
+
if (e?.code !== 'website_unreachable' || attempt >= 20) throw e;
|
|
690
|
+
say(`The website is still being set up (${e.message.slice(0, 120)}); trying again in 30 seconds (${attempt}/20).`);
|
|
691
|
+
await new Promise((r) => setTimeout(r, 30_000));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
682
694
|
return;
|
|
683
695
|
}
|
|
684
696
|
case 'pull':
|
package/lib/validate.mjs
CHANGED
|
@@ -54,8 +54,8 @@ function checkScalar(type, value, at, errors) {
|
|
|
54
54
|
case 'file':
|
|
55
55
|
if (!isMedia(value)) errors.push(`${at}: an image is the stored value (from the pull or add_website_image) or { "$media": { "url": "https://..." | "file": "assets/x.png", "alt": "..." } }`);
|
|
56
56
|
else if (value.$media && typeof value.$media.file === 'string') {
|
|
57
|
-
const ok =
|
|
58
|
-
if (!ok.test(value.$media.file) || value.$media.file.startsWith('/') || value.$media.file.includes('..')) errors.push(`${at}: $media.file must be a file inside the folder (${
|
|
57
|
+
const ok = type === 'file' ? /\.(png|jpe?g|gif|webp|avif|svg|ico|mp4|webm|m4v|mov|woff2?|ttf|otf|pdf)$/i : /\.(png|jpe?g|gif|webp|avif|svg|ico)$/i;
|
|
58
|
+
if (!ok.test(value.$media.file) || value.$media.file.startsWith('/') || value.$media.file.includes('..')) errors.push(`${at}: $media.file must be a file inside the folder (${type === 'file' ? 'a picture, a video (mp4, webm), a font (woff2) or a pdf' : 'a picture: png, jpg, gif, webp, avif, svg, ico'})`);
|
|
59
59
|
}
|
|
60
60
|
else if (value.$media && (typeof value.$media.url !== 'string' || !/^https?:\/\//.test(value.$media.url))) errors.push(`${at}: $media.url must be an http(s) address (or $media.file for a picture in the folder)`);
|
|
61
61
|
else if (value.$media && typeof value.$media.alt !== 'string') errors.push(`${at}: $media.alt is required (what the image shows; "" for a decorative one)`);
|
package/package.json
CHANGED