vowel 0.1.4 → 0.1.6

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.js CHANGED
@@ -21,7 +21,7 @@ const binDirName = path.dirname(binFilePath);
21
21
  const homeDir = process.cwd();
22
22
 
23
23
  const spawnArgs = ['./server.js', '--directory', homeDir];
24
- if (args.build) spawnArgs.push('--build');
24
+ if (args._.includes('build')) spawnArgs.push('--build');
25
25
 
26
26
  if (!args.verbose) {
27
27
  filterConsole(['jsconfig', 'vite', 'Vite', 'tsconfig', `--host`]);
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🃏
3
+ ---
4
+
5
+ # Cards
6
+
7
+ Create eye-catching content with no fuss. (Like this.)
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 👩‍🎤
3
+ ---
4
+
5
+ # Live editing
6
+
7
+ See updates live as you save.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🙃
3
+ ---
4
+
5
+ # Emoji favicons
6
+
7
+ Use any emoji you want for your website's icon.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🧮
3
+ ---
4
+
5
+ # Frontmatter
6
+
7
+ Display dates, lists, nested properties, links, and images in your frontmatter.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🍱
3
+ ---
4
+
5
+ # Blog
6
+
7
+ Write one line to list your blog posts.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🚏
3
+ ---
4
+
5
+ # Navigation
6
+
7
+ Structure your content with smart nav menus.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🤿
3
+ ---
4
+
5
+ # Rich link previews
6
+
7
+ Create rich links with titles and images.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🤖
3
+ ---
4
+
5
+ # Robots
6
+
7
+ Take control of your robots.txt.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 📡
3
+ ---
4
+
5
+ # RSS
6
+
7
+ Deliver your content to RSS readers with an Atom feed.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🗺️
3
+ ---
4
+
5
+ # Sitemap
6
+
7
+ Submit your website to search engines with a sitemap that lists all of your pages.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🏎️
3
+ ---
4
+
5
+ # Speed
6
+
7
+ Get a blazing-fast, Svelte-rendered website.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🏛️
3
+ ---
4
+
5
+ # Static generation
6
+
7
+ Load pages quickly with plain HTML.
@@ -0,0 +1,7 @@
1
+ ---
2
+ icon: 🔖
3
+ ---
4
+
5
+ # Taxonomies
6
+
7
+ Go beyond tags to create authors and categories.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: File structure
3
- breadcrumb: File structure
3
+ breadcrumb: Files
4
4
  description: Organize your files.
5
5
  ---
6
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  title: Folder settings
3
+ breadcrumb: Folders
3
4
  description: Configure your project.
4
5
  ---
5
6
 
@@ -0,0 +1,13 @@
1
+ # Items
2
+
3
+ With Vowel, you can create reusable pieces of content and embed them throughout your website.
4
+
5
+ To create one, prefix a file or folder with a `$`, such as `$faqs`. The file or folder will not produce a page, but the content can be displayed on other pages, like so:
6
+
7
+ ```md
8
+ Here are answers to common questions:
9
+
10
+ /$faqs?count=10
11
+ ```
12
+
13
+ This also allows richer content, as the item will be displayed with frontmatter.
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: Run, Build, and Deploy
2
+ title: Deploy
3
3
  description: Get going.
4
4
  ---
5
5
 
package/content/home.md CHANGED
@@ -26,49 +26,7 @@ Vowel is created by Sam Littlefair. If you have questions or comments, [reach ou
26
26
 
27
27
  # Features
28
28
 
29
- ## Sitemap 🗺️
30
-
31
- Submit your website to search engines with a sitemap that lists all of your pages.
32
-
33
- ## RSS 📡
34
-
35
- Deliver your content to RSS readers with an Atom feed that lists your full posts in reverse-chronology.
36
-
37
- ## Speed ⚡️
38
-
39
- Get a blazing-fast, Svelte-rendered website.
40
-
41
- ## Static generation 🗿
42
-
43
- Load pages quickly with plain HTML.
44
-
45
- ## Copyright 🔒
46
-
47
- Display an up-to-date copyright in the footer of your website.
48
-
49
- ## Rich link previews 🔗
50
-
51
- Create rich links with titles and images, both internally and externally.
52
-
53
- ## Navigation 🚏
54
-
55
- Structure your content with a header, nav, sitemap, and breadcrumbs.
56
-
57
- ## Emoji favicon 🙃
58
-
59
- Use any emoji you want for your website's icon.
60
-
61
- ## Custom taxonomies 🖇️
62
-
63
- Go beyond tags to create authors and categories.
64
-
65
- ## Advanced frontmatter 🧮
66
-
67
- Display dates, lists, nested properties, links, and images in your frontmatter.
68
-
69
- ## Live editing 👩‍🎤
70
-
71
- See updates live as you save.
29
+ /$features?count=20
72
30
 
73
31
  # Try it
74
32
 
@@ -0,0 +1,5 @@
1
+ {
2
+ "cleanUrls": true,
3
+ "outputDirectory": ".output",
4
+ "buildCommand": null
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vowel",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "bin": "./bin.js",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
package/server.js CHANGED
@@ -57,8 +57,10 @@ async function buildProject() {
57
57
  }
58
58
 
59
59
  const jsonData = JSON.stringify(vercelDefaults, null, 2);
60
- await writeFile(vercelConfigPath, jsonData, 'utf-8');
61
- await writeFile(join($home[0], '.output', 'vercel.json'), jsonData, 'utf-8');
60
+
61
+ const path = join($home, 'vercel.json');
62
+ await writeFile(path, jsonData, 'utf-8');
63
+ // await writeFile(vercelConfigPath, jsonData, 'utf-8');
62
64
  console.log('Build completed successfully.');
63
65
  } catch (err) {
64
66
  console.error('Build failed:', err);
@@ -352,7 +352,7 @@
352
352
  padding-right: 0;
353
353
  }
354
354
 
355
- :where(pre, blockquote, dl, figure, table, p, ul, ol, form, article):not(:last-child) {
355
+ :where(pre, blockquote, dl, figure, table, p, ul, ol, form, article, section):not(:last-child) {
356
356
  margin-bottom: 2.5rem;
357
357
  }
358
358
 
@@ -365,10 +365,14 @@
365
365
 
366
366
  /* Header */
367
367
 
368
+ header {
369
+ margin-top: 4rem;
370
+ }
371
+
368
372
  nav.top-bar {
369
373
  border: 1px solid var(--border-color);
370
374
  padding: 6px 10px;
371
- margin-inline: -10px;
375
+ margin-inline: -3px;
372
376
  border-radius: 5px;
373
377
  display: flex;
374
378
  column-gap: 2rem;
@@ -422,6 +426,10 @@
422
426
  cursor: default;
423
427
  }
424
428
 
429
+ header .breadcrumbs > a:only-child {
430
+ display: none;
431
+ }
432
+
425
433
  header .breadcrumbs {
426
434
  margin-block: 4rem 1rem;
427
435
  }
@@ -455,5 +463,55 @@
455
463
  .page.home > main > h1 {
456
464
  display: none;
457
465
  }
466
+
467
+ .page.home .content p:first-child {
468
+ font-size: 1.2em;
469
+ }
470
+
471
+ section[class*='$'] {
472
+ display: grid;
473
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
474
+ grid-auto-rows: auto;
475
+ grid-gap: 2rem;
476
+
477
+ & article {
478
+ margin: 0;
479
+ }
480
+ }
481
+
482
+ article.item {
483
+ display: grid;
484
+ flex-direction: column;
485
+ grid-template-areas:
486
+ 'title icon'
487
+ 'description description';
488
+ align-content: start;
489
+ }
490
+
491
+ article.item h1 {
492
+ grid-area: title;
493
+ font-size: 1.6rem;
494
+ }
495
+
496
+ article.item dl.icon {
497
+ grid-area: icon;
498
+ font-size: 1.5em;
499
+ }
500
+
501
+ article.item dl.icon dd {
502
+ text-align: right;
503
+ }
504
+
505
+ article.item .description {
506
+ grid-area: description;
507
+ }
508
+
509
+ article.item dt {
510
+ display: none;
511
+ }
512
+
513
+ article.item dl.icon {
514
+ order: -1;
515
+ }
458
516
  }
459
517
  </style>
@@ -1,4 +1,4 @@
1
- const pathRegex = /^\/[\/\w\d=-_\.\?&-]*$/;
1
+ const pathRegex = /^\/[\/\$\w\d=-_\.\?&-]*$/;
2
2
 
3
3
  export function getFolderAndCount(node) {
4
4
  if (
@@ -7,7 +7,7 @@
7
7
  function filterFolder(folder) {
8
8
  const filteredFolder = {};
9
9
  for (let key in folder) {
10
- if (!folder[key]['$']?.date) {
10
+ if (!folder[key]['$']?.date && !key.startsWith('$')) {
11
11
  filteredFolder[key] = folder[key];
12
12
  }
13
13
  }
@@ -19,7 +19,7 @@
19
19
 
20
20
  {#if Object.keys(evergreen).some((key) => key !== '$' && key !== '_')}
21
21
  <nav class="top-bar">
22
- {#if !child && evergreen['$']?.url !== '/'}
22
+ {#if !child}
23
23
  <a aria-current={isActiveLink(segments)} href={evergreen['$']?.url}
24
24
  >{getFolderLabel(evergreen)}</a
25
25
  >
@@ -22,7 +22,7 @@
22
22
 
23
23
  <!-- Title -->
24
24
  {#if title}
25
- {#if link}
25
+ {#if link && page.url}
26
26
  <h1>
27
27
  <a href={page.url}>
28
28
  {page.imputedProperties.title || title || page.imputedProperties?.fileName}
@@ -19,13 +19,13 @@
19
19
  </li>
20
20
  {/if}
21
21
  {#each Object.keys(section) as key}
22
- {#if Object.keys(section[key]).length === 1 && section[key].$ && !section[key].$.date}
22
+ {#if Object.keys(section[key]).length === 1 && section[key].$ && !section[key].$.date && !key.startsWith('$')}
23
23
  <li class={key}>
24
24
  <a aria-current={isActiveLink(segments, key)} href={section[key].$.url}>
25
25
  {getFileLabel(section[key]['$'], true) || getFolderLabel(section[key], true)}
26
26
  </a>
27
27
  </li>
28
- {:else if section[key].$ && !section[key].$.date}
28
+ {:else if section[key].$ && !section[key].$.date && !key.startsWith('$')}
29
29
  <li class={key}>
30
30
  <a aria-current={isActiveLink(segments, key)} href={section[key].$.url}>
31
31
  {getFileLabel(section[key]['$']) || getFolderLabel(section[key])}
@@ -1,4 +1,5 @@
1
1
  export default function createPageClass(url, type = 'page') {
2
+ if (!url) return 'item';
2
3
  if (url === '/') return 'page home';
3
4
  return type + url.split('/').join(' ');
4
5
  }
@@ -17,30 +17,32 @@ function traverseFolder(folder, root = false, property = '.') {
17
17
  let pages = [];
18
18
 
19
19
  for (let key in folder) {
20
- if (key === '$') {
21
- if (!root) {
22
- if (propertyKey) {
23
- if (
24
- folder[key].hasOwnProperty(propertyKey) &&
25
- folder[key][propertyKey] === propertyValue
26
- ) {
20
+ if (!key.startsWith('$') || key.length === 1) {
21
+ if (key === '$') {
22
+ if (!root) {
23
+ if (propertyKey) {
24
+ if (
25
+ folder[key].hasOwnProperty(propertyKey) &&
26
+ folder[key][propertyKey] === propertyValue
27
+ ) {
28
+ pages.push(folder[key]);
29
+ }
30
+ } else {
27
31
  pages.push(folder[key]);
28
32
  }
29
- } else {
30
- pages.push(folder[key]);
31
33
  }
32
- }
33
- // if (
34
- // !root &&
35
- // folder[key].$?.hasOwnProperty(propertyKey) &&
36
- // folder[key][propertyKey] === propertyValue
37
- // )
38
- // pages.push(folder[key]);
39
- } else if (key !== '_') {
40
- const child = folder[key];
34
+ // if (
35
+ // !root &&
36
+ // folder[key].$?.hasOwnProperty(propertyKey) &&
37
+ // folder[key][propertyKey] === propertyValue
38
+ // )
39
+ // pages.push(folder[key]);
40
+ } else if (key !== '_') {
41
+ const child = folder[key];
41
42
 
42
- // @ts-ignore
43
- pages.push(...traverseFolder(child, false, property));
43
+ // @ts-ignore
44
+ pages.push(...traverseFolder(child, false, property));
45
+ }
44
46
  }
45
47
  }
46
48
 
@@ -90,7 +90,7 @@ function DefaultDirectory(path) {
90
90
  * @param {import('./loadCache').Cache} cache
91
91
  * @returns {Promise<Directory>}
92
92
  */
93
- async function readFolder(folderPath, parents, cache) {
93
+ async function readFolder(folderPath, parents, cache, hidden) {
94
94
  function filterFiles(file) {
95
95
  if (file.name.startsWith('.')) return false;
96
96
  if (file.name.startsWith('README')) return false;
@@ -105,7 +105,9 @@ async function readFolder(folderPath, parents, cache) {
105
105
 
106
106
  console.log(`filesfound:${files.length}`);
107
107
 
108
- const promises = files.map(async (file) => await readFile(file, parents, cache, folderPath));
108
+ const promises = files.map(
109
+ async (file) => await readFile(file, parents, cache, folderPath, hidden)
110
+ );
109
111
 
110
112
  const folder = (await Promise.all(promises)).reduce((acc, obj) => ({ ...acc, ...obj }), {});
111
113
 
@@ -123,13 +125,15 @@ async function readFolder(folderPath, parents, cache) {
123
125
  return folder;
124
126
  }
125
127
 
126
- async function readFile(file, parents, cache, folderPath) {
128
+ async function readFile(file, parents, cache, folderPath, hidden) {
127
129
  const route = path.parse(file.name).name;
128
130
  const url = buildURL(parents, route);
129
131
  const filePath = path.join(folderPath, file.name);
130
132
 
131
133
  const extension = path.extname(file.name);
132
134
 
135
+ const hide = file.name.startsWith('$') || hidden;
136
+
133
137
  if (file.isFile() && extension === '.md') {
134
138
  const startLoad = performance.now();
135
139
  const shortPath = parents + '/' + file.name;
@@ -150,13 +154,15 @@ async function readFile(file, parents, cache, folderPath) {
150
154
  }
151
155
  };
152
156
  }
157
+
153
158
  return {
154
159
  [route]: {
155
160
  $: {
156
161
  ...frontmatter,
157
162
  imputedProperties,
158
163
  ast,
159
- url
164
+ // url,
165
+ url: hide ? false : url
160
166
  }
161
167
  }
162
168
  };
@@ -173,7 +179,7 @@ async function readFile(file, parents, cache, folderPath) {
173
179
  const shortPath = parents + '/' + file.name;
174
180
 
175
181
  const startLoad = performance.now();
176
- const folder = await readFolder(path.join(folderPath, file.name), url, cache);
182
+ const folder = await readFolder(path.join(folderPath, file.name), url, cache, hide);
177
183
 
178
184
  const loadTime = (performance.now() - startLoad).toFixed(2);
179
185
  // console.log(`📁 ${shortPath} (${loadTime}ms)`);