create-campsitejs 0.0.1 ā 0.0.3
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/index.js +105 -18
- package/package.json +1 -1
- package/template/campsite.config.js +2 -0
- package/template/src/layouts/base.njk +9 -25
- package/template/src/pages/404.njk +13 -0
package/index.js
CHANGED
|
@@ -11,6 +11,17 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
11
11
|
const templateDir = join(__dirname, "template");
|
|
12
12
|
// Variant pages live under the template folder
|
|
13
13
|
const variantDir = join(templateDir, "variants");
|
|
14
|
+
const pkgJsonPath = join(__dirname, "package.json");
|
|
15
|
+
|
|
16
|
+
async function getCliVersion() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await readFile(pkgJsonPath, "utf8");
|
|
19
|
+
const pkg = JSON.parse(raw);
|
|
20
|
+
return pkg.version || "0.0.0";
|
|
21
|
+
} catch {
|
|
22
|
+
return "0.0.0";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
14
25
|
|
|
15
26
|
function formatPackageName(name) {
|
|
16
27
|
return name
|
|
@@ -71,11 +82,13 @@ async function writeConfig(targetDir, answers) {
|
|
|
71
82
|
outDir: "dist",
|
|
72
83
|
templateEngine: "${primaryEngine}",
|
|
73
84
|
markdown: ${answers.markdown},
|
|
85
|
+
minifyCSS: false,
|
|
86
|
+
minifyHTML: false,
|
|
74
87
|
integrations: {
|
|
75
88
|
nunjucks: ${answers.templateEngines.includes("nunjucks")},
|
|
76
89
|
liquid: ${answers.templateEngines.includes("liquid")},
|
|
77
|
-
vue: ${answers.
|
|
78
|
-
alpine: ${answers.
|
|
90
|
+
vue: ${answers.jsFrameworks.includes("vue")},
|
|
91
|
+
alpine: ${answers.jsFrameworks.includes("alpine")}
|
|
79
92
|
}
|
|
80
93
|
};
|
|
81
94
|
`;
|
|
@@ -90,19 +103,60 @@ async function updatePackageJson(targetDir, answers) {
|
|
|
90
103
|
pkg.devDependencies = pkg.devDependencies || {};
|
|
91
104
|
const deps = pkg.dependencies;
|
|
92
105
|
const devDeps = pkg.devDependencies;
|
|
106
|
+
pkg.scripts = pkg.scripts || {};
|
|
93
107
|
const localCoreDir = resolve(__dirname, "../basecampjs");
|
|
94
108
|
if (existsSync(localCoreDir)) {
|
|
95
109
|
const relCore = relative(targetDir, localCoreDir) || ".";
|
|
96
|
-
|
|
110
|
+
devDeps["basecampjs"] = `file:${relCore}`;
|
|
111
|
+
} else {
|
|
112
|
+
devDeps["basecampjs"] = "^0.0.1";
|
|
113
|
+
}
|
|
114
|
+
if (answers.markdown) devDeps["markdown-it"] = "^14.1.0";
|
|
115
|
+
if (answers.templateEngines.includes("nunjucks")) devDeps["nunjucks"] = "^3.2.4";
|
|
116
|
+
if (answers.templateEngines.includes("liquid")) devDeps["liquidjs"] = "^10.12.0";
|
|
117
|
+
if (answers.jsFrameworks.includes("vue")) deps["vue"] = "^3.4.0";
|
|
118
|
+
if (answers.jsFrameworks.includes("alpine")) deps["alpinejs"] = "^3.13.0";
|
|
119
|
+
|
|
120
|
+
// CSS framework selection
|
|
121
|
+
const cssFramework = answers.cssFramework || "tailwind";
|
|
122
|
+
const cssDeps = {
|
|
123
|
+
bootstrap: ["bootstrap", "^5.3.3"],
|
|
124
|
+
foundation: ["foundation-sites", "^6.8.1"],
|
|
125
|
+
bulma: ["bulma", "^0.9.4"]
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Reset CSS-related scripts before applying framework-specific ones
|
|
129
|
+
["build:css", "dev:css", "dev:site", "prebuild", "postinstall"].forEach((script) => {
|
|
130
|
+
delete pkg.scripts[script];
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (cssFramework === "tailwind") {
|
|
134
|
+
devDeps["tailwindcss"] = "^3.4.13";
|
|
135
|
+
devDeps["npm-run-all"] = "^4.1.5";
|
|
136
|
+
pkg.scripts["build:css"] = "tailwindcss -c tailwind.config.cjs -i ./src/styles/tailwind.css -o ./public/style.css --minify";
|
|
137
|
+
pkg.scripts["dev:css"] = "tailwindcss -c tailwind.config.cjs -i ./src/styles/tailwind.css -o ./public/style.css --watch";
|
|
138
|
+
pkg.scripts["dev:site"] = "campsite dev";
|
|
139
|
+
pkg.scripts["dev"] = "npm-run-all -p dev:css dev:site";
|
|
140
|
+
pkg.scripts["prebuild"] = "npm run build:css";
|
|
141
|
+
pkg.scripts["build"] = "campsite build";
|
|
142
|
+
pkg.scripts["serve"] = "campsite serve";
|
|
143
|
+
pkg.scripts["postinstall"] = "npm run build:css";
|
|
97
144
|
} else {
|
|
98
|
-
|
|
145
|
+
delete devDeps["tailwindcss"];
|
|
146
|
+
delete devDeps["npm-run-all"];
|
|
147
|
+
Object.entries(cssDeps).forEach(([key, [name]]) => {
|
|
148
|
+
if (key !== cssFramework) delete deps[name];
|
|
149
|
+
});
|
|
150
|
+
const selected = cssDeps[cssFramework];
|
|
151
|
+
if (selected) {
|
|
152
|
+
const [name, version] = selected;
|
|
153
|
+
deps[name] = version;
|
|
154
|
+
}
|
|
155
|
+
pkg.scripts["dev"] = "campsite dev";
|
|
156
|
+
pkg.scripts["build"] = "campsite build";
|
|
157
|
+
pkg.scripts["serve"] = "campsite serve";
|
|
99
158
|
}
|
|
100
|
-
|
|
101
|
-
if (answers.templateEngines.includes("nunjucks")) deps["nunjucks"] = "^3.2.4";
|
|
102
|
-
if (answers.templateEngines.includes("liquid")) deps["liquidjs"] = "^10.12.0";
|
|
103
|
-
if (answers.templateEngines.includes("vue")) deps["vue"] = "^3.4.0";
|
|
104
|
-
if (answers.templateEngines.includes("alpine")) deps["alpinejs"] = "^3.13.0";
|
|
105
|
-
devDeps["tailwindcss"] = "^3.4.13";
|
|
159
|
+
|
|
106
160
|
await writeFile(pkgPath, JSON.stringify(pkg, null, 2), "utf8");
|
|
107
161
|
}
|
|
108
162
|
|
|
@@ -119,14 +173,23 @@ async function swapPageTemplates(targetDir, answers) {
|
|
|
119
173
|
|
|
120
174
|
async function pruneComponents(targetDir, answers) {
|
|
121
175
|
const componentDir = join(targetDir, "src", "components");
|
|
122
|
-
if (!answers.
|
|
176
|
+
if (!answers.jsFrameworks.includes("vue")) {
|
|
123
177
|
await rm(join(componentDir, "HelloCampsite.vue")).catch(() => {});
|
|
124
178
|
}
|
|
125
|
-
if (!answers.
|
|
179
|
+
if (!answers.jsFrameworks.includes("alpine")) {
|
|
126
180
|
await rm(join(componentDir, "alpine-card.html")).catch(() => {});
|
|
127
181
|
}
|
|
128
182
|
}
|
|
129
183
|
|
|
184
|
+
async function pruneCssFramework(targetDir, answers) {
|
|
185
|
+
if (answers.cssFramework === "tailwind") return;
|
|
186
|
+
const tailwindFiles = [
|
|
187
|
+
join(targetDir, "tailwind.config.cjs"),
|
|
188
|
+
join(targetDir, "src", "styles", "tailwind.css")
|
|
189
|
+
];
|
|
190
|
+
await Promise.all(tailwindFiles.map((file) => rm(file).catch(() => {})));
|
|
191
|
+
}
|
|
192
|
+
|
|
130
193
|
async function installDependencies(targetDir, packageManager) {
|
|
131
194
|
return new Promise((resolve, reject) => {
|
|
132
195
|
const child = spawn(packageManager, ["install"], {
|
|
@@ -142,8 +205,9 @@ async function installDependencies(targetDir, packageManager) {
|
|
|
142
205
|
}
|
|
143
206
|
|
|
144
207
|
async function main() {
|
|
145
|
-
|
|
146
|
-
console.log(kleur.
|
|
208
|
+
const version = await getCliVersion();
|
|
209
|
+
console.log(kleur.bold().cyan(`\nšļø Welcome to CampSiteJS v${version}`));
|
|
210
|
+
console.log(kleur.dim("Build a cozy static campsite in seconds.\n"));
|
|
147
211
|
|
|
148
212
|
const argProjectName = process.argv[2];
|
|
149
213
|
const defaultProjectName = argProjectName || nextCampsiteName(process.cwd());
|
|
@@ -165,15 +229,37 @@ async function main() {
|
|
|
165
229
|
{
|
|
166
230
|
type: "multiselect",
|
|
167
231
|
name: "templateEngines",
|
|
168
|
-
message: "Choose templating
|
|
232
|
+
message: "Choose templating engines",
|
|
169
233
|
hint: "Use space to toggle, enter to confirm",
|
|
170
234
|
instructions: false,
|
|
171
235
|
min: 1,
|
|
172
236
|
choices: [
|
|
173
237
|
{ title: "Nunjucks", value: "nunjucks", selected: true },
|
|
174
|
-
{ title: "Liquid", value: "liquid"
|
|
175
|
-
|
|
176
|
-
|
|
238
|
+
{ title: "Liquid", value: "liquid" }
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: "multiselect",
|
|
243
|
+
name: "jsFrameworks",
|
|
244
|
+
message: "Sprinkle in JS frameworks?",
|
|
245
|
+
hint: "Use space to toggle, enter to confirm",
|
|
246
|
+
instructions: false,
|
|
247
|
+
min: 0,
|
|
248
|
+
choices: [
|
|
249
|
+
{ title: "Alpine.js", value: "alpine", selected: true },
|
|
250
|
+
{ title: "Vue.js", value: "vue" }
|
|
251
|
+
]
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
type: "select",
|
|
255
|
+
name: "cssFramework",
|
|
256
|
+
message: "CSS framework",
|
|
257
|
+
initial: 0,
|
|
258
|
+
choices: [
|
|
259
|
+
{ title: "Tailwind CSS", value: "tailwind" },
|
|
260
|
+
{ title: "Bootstrap", value: "bootstrap" },
|
|
261
|
+
{ title: "Foundation", value: "foundation" },
|
|
262
|
+
{ title: "Bulma", value: "bulma" }
|
|
177
263
|
]
|
|
178
264
|
},
|
|
179
265
|
{
|
|
@@ -208,6 +294,7 @@ async function main() {
|
|
|
208
294
|
await copyBaseTemplate(targetDir);
|
|
209
295
|
await swapPageTemplates(targetDir, answers);
|
|
210
296
|
await pruneComponents(targetDir, answers);
|
|
297
|
+
await pruneCssFramework(targetDir, answers);
|
|
211
298
|
await writeConfig(targetDir, answers);
|
|
212
299
|
await updatePackageJson(targetDir, answers);
|
|
213
300
|
|
package/package.json
CHANGED
|
@@ -1,35 +1,26 @@
|
|
|
1
|
-
<!doctype html>
|
|
1
|
+
{% set meta_title = frontmatter.title or title or site.name %}{% set meta_description = frontmatter.description or page.description or "A cozy Campsite starter." %}{% set meta_url = frontmatter.canonical or frontmatter.url %}<!doctype html>
|
|
2
2
|
<html lang="en" class="min-h-screen bg-radial bg-gradient-to-br from-campfire-900 from-10% to-black to-90%">
|
|
3
|
-
|
|
4
3
|
<head>
|
|
5
4
|
<meta charset="UTF-8">
|
|
6
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
{% set meta_title = frontmatter.title or title or site.name %}
|
|
8
|
-
{% set meta_description = frontmatter.description or page.description or "A cozy Campsite starter." %}
|
|
9
|
-
{% set meta_url = frontmatter.canonical or frontmatter.url %}
|
|
10
6
|
<title>{{ meta_title }}</title>
|
|
11
|
-
<meta name="description" content="{{ meta_description }}">
|
|
12
|
-
{
|
|
13
|
-
<meta name="robots" content="{{ frontmatter.robots }}">{% endif %}
|
|
14
|
-
{% if meta_url %}
|
|
7
|
+
<meta name="description" content="{{ meta_description }}">{% if frontmatter.robots %}
|
|
8
|
+
<meta name="robots" content="{{ frontmatter.robots }}">{% endif %}{% if meta_url %}
|
|
15
9
|
<link rel="canonical" href="{{ meta_url }}">{% endif %}
|
|
16
10
|
<meta property="og:title" content="{{ meta_title }}">
|
|
17
|
-
<meta property="og:description" content="{{ meta_description }}">
|
|
18
|
-
{% if meta_url %}
|
|
11
|
+
<meta property="og:description" content="{{ meta_description }}">{% if meta_url %}
|
|
19
12
|
<meta property="og:url" content="{{ meta_url }}">{% endif %}
|
|
20
13
|
<meta property="og:type" content="{{ frontmatter.og_type or " website" }}">
|
|
21
14
|
<meta property="og:site_name" content="{{ site.name }}">
|
|
22
15
|
<meta name="twitter:card" content="{{ frontmatter.twitter_card or " summary_large_image" }}">
|
|
23
16
|
<meta name="twitter:title" content="{{ meta_title }}">
|
|
24
|
-
<meta name="twitter:description" content="{{ meta_description }}">
|
|
25
|
-
{% if meta_url %}
|
|
17
|
+
<meta name="twitter:description" content="{{ meta_description }}">{% if meta_url %}
|
|
26
18
|
<meta name="twitter:url" content="{{ meta_url }}">{% endif %}
|
|
27
19
|
<link rel="stylesheet" href="/style.css">
|
|
28
20
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
29
21
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
30
22
|
<link href="https://fonts.googleapis.com/css2?family=Caprasimo&display=swap" rel="stylesheet">
|
|
31
23
|
</head>
|
|
32
|
-
|
|
33
24
|
<body class="space-y-12 font-serif">
|
|
34
25
|
<header class="bg-stone-950 flex items-stretch justify-between py-2 px-6">
|
|
35
26
|
<a href="/" class="inline-flex items-center text-amber-50 font-bold text-lg tracking-wide py-3">
|
|
@@ -37,7 +28,7 @@
|
|
|
37
28
|
</a>
|
|
38
29
|
<nav class="flex items-center gap-2">
|
|
39
30
|
<a href="/" class="px-2">Home</a>
|
|
40
|
-
<a href="https://
|
|
31
|
+
<a href="https://campsite.foxgrovemedia.com/docs/overview" target="_blank" rel="noreferrer" class="px-2">Docs</a>
|
|
41
32
|
<a href="https://github.com/FoxGroveMedia" target="_blank" rel="noreferrer">
|
|
42
33
|
<svg class="size-7" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
|
|
43
34
|
viewBox="0 0 640 640"><!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
|
@@ -57,24 +48,17 @@
|
|
|
57
48
|
<main class="mx-auto max-w-5xl px-4 sm:px-6 lg:px-8">
|
|
58
49
|
<div
|
|
59
50
|
class="rounded-lg bg-white/5 shadow dark:bg-gray-800/50 dark:shadow-none dark:outline dark:outline-1 dark:-outline-offset-1 dark:outline-white/10 text-white">
|
|
60
|
-
<div class="px-4 py-5 sm:p-6">
|
|
61
|
-
{
|
|
62
|
-
{% if content %}
|
|
63
|
-
{{ content | safe }}
|
|
64
|
-
{% else %}
|
|
51
|
+
<div class="px-4 py-5 sm:p-6">{% block content %}{% if content %}
|
|
52
|
+
{{ content | safe }}{% else %}
|
|
65
53
|
<section class="hero">
|
|
66
54
|
<p class="eyebrow">Campfire ready</p>
|
|
67
55
|
<h1>Welcome to Campsite</h1>
|
|
68
56
|
<p>Edit <code>src/pages/index.md</code> to get started.</p>
|
|
69
|
-
</section>
|
|
70
|
-
{% endif %}
|
|
71
|
-
{% endblock %}
|
|
72
|
-
</div>
|
|
57
|
+
</section>{% endif %}{% endblock %}</div>
|
|
73
58
|
</div>
|
|
74
59
|
</main>
|
|
75
60
|
<footer class="text-xs text-amber-50/40 text-center">
|
|
76
61
|
<p>Built with <span class="font-semibold text-amber-50/60">Campsite</span>.</p>
|
|
77
62
|
</footer>
|
|
78
63
|
</body>
|
|
79
|
-
|
|
80
64
|
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Error 404 - Page Not Found
|
|
3
|
+
layout: base.njk
|
|
4
|
+
description: The page you are looking for does not exist.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<div class="flex min-h-96 flex-col items-center justify-center bg-stone-900 px-4 text-center">
|
|
8
|
+
<h1 class="text-6xl font-display font-bold text-amber-500 mb-4">404</h1>
|
|
9
|
+
<p class="text-xl text-stone-400 mb-8">Oops! The page you're looking for can't be found.</p>
|
|
10
|
+
<a href="/" class="inline-block rounded bg-amber-500 px-6 py-3 font-semibold text-white hover:bg-amber-600 transition">
|
|
11
|
+
Go Back Home
|
|
12
|
+
</a>
|
|
13
|
+
</div>
|