@zvndev/darkmown 0.19.0 → 0.20.0
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/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/package.json +21 -3
- package/src/builder.js +20 -14
- package/src/cli.js +216 -77
- package/src/compiler/body.js +432 -0
- package/src/compiler/context.js +160 -0
- package/src/compiler/directives.js +1149 -0
- package/src/compiler/frontmatter.js +117 -0
- package/src/compiler/includes.js +116 -0
- package/src/compiler/index.js +22 -0
- package/src/compiler/interpolation.js +189 -0
- package/src/compiler/loops.js +644 -0
- package/src/compiler/markdown.js +233 -0
- package/src/compiler/page.js +267 -0
- package/src/compiler/predicates.js +281 -0
- package/src/compiler.js +26 -2932
- package/src/dev.js +3 -1
- package/src/headers.js +3 -4
- package/src/index.js +22 -0
- package/src/router.js +3 -1
- package/src/scaffold.js +158 -131
- package/src/skin.js +2 -1
- package/site/_/og.png +0 -0
package/src/dev.js
CHANGED
|
@@ -8,7 +8,9 @@ export const devEventsPath = "/__wd/dev-events";
|
|
|
8
8
|
*/
|
|
9
9
|
export function injectDevClient(html) {
|
|
10
10
|
const script = `<script type="module" src="${devClientPath}"></script>`;
|
|
11
|
-
return html.includes("</body>")
|
|
11
|
+
return html.includes("</body>")
|
|
12
|
+
? html.replace("</body>", `${script}\n</body>`)
|
|
13
|
+
: `${html}\n${script}`;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
package/src/headers.js
CHANGED
|
@@ -65,10 +65,9 @@ export const REACTIVE_CSP = [
|
|
|
65
65
|
* keep `'unsafe-inline'` on script/style.
|
|
66
66
|
* @type {string}
|
|
67
67
|
*/
|
|
68
|
-
export const STATIC_CSP = [
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
].join("; ");
|
|
68
|
+
export const STATIC_CSP = ["script-src 'self' 'unsafe-inline'", ...COMMON_CSP_DIRECTIVES].join(
|
|
69
|
+
"; "
|
|
70
|
+
);
|
|
72
71
|
|
|
73
72
|
/**
|
|
74
73
|
* Baseline security headers applied to every HTML response, independent of the
|
package/src/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Public API barrel for @zvndev/darkmown.
|
|
2
|
+
// Mirrors the type surface declared in `types/index.d.ts`. Importing the
|
|
3
|
+
// package (`import { buildSite } from "@zvndev/darkmown"`) resolves here via the
|
|
4
|
+
// `exports` map; individual modules stay importable by their own path too.
|
|
5
|
+
|
|
6
|
+
export { buildSite } from "./builder.js";
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
compileDocument,
|
|
10
|
+
compilePage,
|
|
11
|
+
escapeHtml,
|
|
12
|
+
loopKeyOf,
|
|
13
|
+
parseFrontmatter
|
|
14
|
+
} from "./compiler.js";
|
|
15
|
+
|
|
16
|
+
export { createPaths, isHiddenName, pageExtensions } from "./config.js";
|
|
17
|
+
export { devClientScript, injectDevClient } from "./dev.js";
|
|
18
|
+
export { discoverRoutes, outputPathForRoute, routeFromFile } from "./router.js";
|
|
19
|
+
|
|
20
|
+
export { initProject } from "./scaffold.js";
|
|
21
|
+
export { compileSkin } from "./skin.js";
|
|
22
|
+
export { contentType, resolvePublicFile, serve } from "./statics.js";
|
package/src/router.js
CHANGED
|
@@ -43,7 +43,9 @@ export function discoverRoutes(routesRoot) {
|
|
|
43
43
|
const seen = new Map();
|
|
44
44
|
for (const route of routes) {
|
|
45
45
|
if (seen.has(route.route)) {
|
|
46
|
-
throw new Error(
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Duplicate route "${route.route}" from ${seen.get(route.route)} and ${route.file}`
|
|
48
|
+
);
|
|
47
49
|
}
|
|
48
50
|
seen.set(route.route, route.file);
|
|
49
51
|
}
|
package/src/scaffold.js
CHANGED
|
@@ -12,136 +12,164 @@ const darkmownVersion = JSON.parse(
|
|
|
12
12
|
*/
|
|
13
13
|
export function initProject(root) {
|
|
14
14
|
fs.mkdirSync(root, { recursive: true });
|
|
15
|
-
writeNew(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"",
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"",
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"",
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
""
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"",
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
15
|
+
writeNew(
|
|
16
|
+
root,
|
|
17
|
+
"package.json",
|
|
18
|
+
JSON.stringify(
|
|
19
|
+
{
|
|
20
|
+
name: packageNameFromRoot(root),
|
|
21
|
+
private: true,
|
|
22
|
+
scripts: {
|
|
23
|
+
dev: "darkmown dev",
|
|
24
|
+
build: "darkmown build",
|
|
25
|
+
preview: "darkmown serve"
|
|
26
|
+
},
|
|
27
|
+
devDependencies: {
|
|
28
|
+
"@zvndev/darkmown": `^${darkmownVersion}`
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
null,
|
|
32
|
+
2
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
writeNew(
|
|
36
|
+
root,
|
|
37
|
+
"site/pages/index.wd",
|
|
38
|
+
[
|
|
39
|
+
"---",
|
|
40
|
+
"title: My Darkmown site",
|
|
41
|
+
"---",
|
|
42
|
+
"",
|
|
43
|
+
"@include /nav.wd",
|
|
44
|
+
"",
|
|
45
|
+
"<main>",
|
|
46
|
+
"",
|
|
47
|
+
"# My Darkmown site",
|
|
48
|
+
"",
|
|
49
|
+
"Plain Markdown works. Rename to `.wd` when you want directives.",
|
|
50
|
+
"",
|
|
51
|
+
":state count = 0",
|
|
52
|
+
"",
|
|
53
|
+
"Count: { count }",
|
|
54
|
+
"",
|
|
55
|
+
':button "Increment" -> count++',
|
|
56
|
+
"",
|
|
57
|
+
':state todos = ["Write a page"]',
|
|
58
|
+
"",
|
|
59
|
+
"@loop todos into todo",
|
|
60
|
+
"- { todo }",
|
|
61
|
+
"@endloop",
|
|
62
|
+
"",
|
|
63
|
+
':button "Add" -> todos += "Add a loop"',
|
|
64
|
+
"",
|
|
65
|
+
"</main>"
|
|
66
|
+
].join("\n")
|
|
67
|
+
);
|
|
68
|
+
writeNew(
|
|
69
|
+
root,
|
|
70
|
+
"site/pages/index.skin",
|
|
71
|
+
[
|
|
72
|
+
"tokens",
|
|
73
|
+
" ink #172026",
|
|
74
|
+
" paper #f7f2e8",
|
|
75
|
+
" accent #0f8b8d",
|
|
76
|
+
"",
|
|
77
|
+
"page",
|
|
78
|
+
" margin 0",
|
|
79
|
+
" font ui-sans-serif, system-ui, sans-serif",
|
|
80
|
+
" color $ink",
|
|
81
|
+
" bg $paper",
|
|
82
|
+
"",
|
|
83
|
+
"main",
|
|
84
|
+
" max-width 760px",
|
|
85
|
+
" margin 0 auto",
|
|
86
|
+
" padding 3rem 1.5rem",
|
|
87
|
+
"",
|
|
88
|
+
"nav",
|
|
89
|
+
" display flex",
|
|
90
|
+
" align-items center",
|
|
91
|
+
" justify-content space-between",
|
|
92
|
+
" gap 1rem",
|
|
93
|
+
" max-width 760px",
|
|
94
|
+
" margin 0 auto",
|
|
95
|
+
" padding 1.25rem 1.5rem",
|
|
96
|
+
"",
|
|
97
|
+
"nav strong",
|
|
98
|
+
" font-size 1.1rem",
|
|
99
|
+
"",
|
|
100
|
+
"nav .links",
|
|
101
|
+
" display flex",
|
|
102
|
+
" gap 1.25rem",
|
|
103
|
+
"",
|
|
104
|
+
"nav a",
|
|
105
|
+
" color $ink",
|
|
106
|
+
" text-decoration none",
|
|
107
|
+
" opacity .8",
|
|
108
|
+
"",
|
|
109
|
+
"nav a:hover",
|
|
110
|
+
" opacity 1",
|
|
111
|
+
" color $accent",
|
|
112
|
+
"",
|
|
113
|
+
"button",
|
|
114
|
+
" bg $accent",
|
|
115
|
+
" color white",
|
|
116
|
+
" border 0",
|
|
117
|
+
" padding .75rem 1rem",
|
|
118
|
+
" radius 8px"
|
|
119
|
+
].join("\n")
|
|
120
|
+
);
|
|
121
|
+
writeNew(
|
|
122
|
+
root,
|
|
123
|
+
"site/_/nav.wd",
|
|
124
|
+
[
|
|
125
|
+
"<nav>",
|
|
126
|
+
" <strong>My site</strong>",
|
|
127
|
+
' <span class="links">',
|
|
128
|
+
' <a href="/">Home</a>',
|
|
129
|
+
' <a href="/about/">About</a>',
|
|
130
|
+
" </span>",
|
|
131
|
+
"</nav>"
|
|
132
|
+
].join("\n")
|
|
133
|
+
);
|
|
134
|
+
writeNew(
|
|
135
|
+
root,
|
|
136
|
+
"site/pages/about.md",
|
|
137
|
+
[
|
|
138
|
+
"---",
|
|
139
|
+
"title: About",
|
|
140
|
+
"---",
|
|
141
|
+
"",
|
|
142
|
+
"# About",
|
|
143
|
+
"",
|
|
144
|
+
"This page is plain Markdown (`.md`) — strict CommonMark, zero framework JavaScript.",
|
|
145
|
+
"Rename it to `.wd` when you want directives like state, loops, or forms.",
|
|
146
|
+
"",
|
|
147
|
+
"[Back home](/)"
|
|
148
|
+
].join("\n")
|
|
149
|
+
);
|
|
150
|
+
writeNew(
|
|
151
|
+
root,
|
|
152
|
+
"README.md",
|
|
153
|
+
[
|
|
154
|
+
"# My Darkmown site",
|
|
155
|
+
"",
|
|
156
|
+
"Run `npm install` and `npm run dev` to start the live compiler.",
|
|
157
|
+
"",
|
|
158
|
+
"## Commands",
|
|
159
|
+
"",
|
|
160
|
+
"- `npm run dev` — live compiler on http://localhost:5173 with hot reload.",
|
|
161
|
+
"- `npm run build` — compile the site to `dist/`.",
|
|
162
|
+
"- `npm run preview` — serve the built `dist/` locally.",
|
|
163
|
+
"",
|
|
164
|
+
"## Layout",
|
|
165
|
+
"",
|
|
166
|
+
"- Pages live in `site/pages`.",
|
|
167
|
+
"- Shared includes live in `site/_`.",
|
|
168
|
+
"- Hidden route files start with `.` or `-`.",
|
|
169
|
+
"- Colocated `index.skin` and `index.js` attach automatically.",
|
|
170
|
+
"- Any other file under `site/pages` (images, fonts, …) copies to `dist/` at its own path."
|
|
171
|
+
].join("\n")
|
|
172
|
+
);
|
|
145
173
|
return { root };
|
|
146
174
|
}
|
|
147
175
|
|
|
@@ -159,7 +187,6 @@ function writeNew(root, file, content) {
|
|
|
159
187
|
fs.writeFileSync(target, `${content}\n`);
|
|
160
188
|
}
|
|
161
189
|
|
|
162
|
-
|
|
163
190
|
/**
|
|
164
191
|
* Derive a safe default npm package name from the scaffold target directory.
|
|
165
192
|
* @param {string} root Absolute target directory.
|
package/src/skin.js
CHANGED
|
@@ -14,7 +14,8 @@ const aliases = new Map([
|
|
|
14
14
|
* @returns {string}
|
|
15
15
|
*/
|
|
16
16
|
function resolveProp(prop, rest) {
|
|
17
|
-
if (prop === "font" && (/^[\d.]/.test(rest[0] || "") || rest.join(" ").includes("/")))
|
|
17
|
+
if (prop === "font" && (/^[\d.]/.test(rest[0] || "") || rest.join(" ").includes("/")))
|
|
18
|
+
return "font";
|
|
18
19
|
return aliases.get(prop) || prop;
|
|
19
20
|
}
|
|
20
21
|
|
package/site/_/og.png
DELETED
|
Binary file
|