stack-site-builder 1.17.0 → 1.17.2
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
CHANGED
|
@@ -11,6 +11,35 @@ content schema, while a consuming site supplies only content, taxonomy data and
|
|
|
11
11
|
config. Sites track the theme with `pnpm up stack-site-builder`, so each release
|
|
12
12
|
here is a plain version bump they pull in.
|
|
13
13
|
|
|
14
|
+
## [1.17.2] - 2026-07-22
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Slide decks ignored the site's custom favicon** — DeckView owns its own
|
|
19
|
+
`<head>` (fullscreen layout) and still hardcoded `/favicon.svg`. Browser
|
|
20
|
+
icons are now resolved once in `lib/icons` and shared by BaseLayout and
|
|
21
|
+
DeckView, so `site.icons` applies everywhere (favicon, apple-touch,
|
|
22
|
+
manifest).
|
|
23
|
+
|
|
24
|
+
## [1.17.1] - 2026-07-22
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Mermaid never rendered on npm-consuming sites' dev server** — the loader
|
|
29
|
+
imported the package default (`mermaid.core.mjs`), whose bare CJS
|
|
30
|
+
dependencies (dayjs, …) are served without interop when the import chain
|
|
31
|
+
starts inside `node_modules`, killing the whole loader module with a
|
|
32
|
+
SyntaxError. It now imports the self-contained
|
|
33
|
+
`mermaid/dist/mermaid.esm.min.mjs` bundle, which loads identically in dev
|
|
34
|
+
and build. (The theme's own playground never hit this — its workspace
|
|
35
|
+
symlink resolves outside `node_modules`, so Vite prebundled mermaid.)
|
|
36
|
+
|
|
37
|
+
- **Course → slide-deck links matched nothing** — a course's `slides`
|
|
38
|
+
frontmatter lists locale-less deck slugs, but the detail page compared
|
|
39
|
+
them against raw collection ids (`ko/<deck>/index`), so the chips never
|
|
40
|
+
rendered and would have linked to the wrong path. Decks are now resolved
|
|
41
|
+
per locale via the slides helpers.
|
|
42
|
+
|
|
14
43
|
## [1.17.0] - 2026-07-22
|
|
15
44
|
|
|
16
45
|
### Changed
|
|
@@ -225,6 +254,8 @@ catalog sites from a thin content-only repository.
|
|
|
225
254
|
- **Standalone development setup** — a devcontainer and a minimal `playground/`
|
|
226
255
|
consuming site for developing and previewing the theme on its own.
|
|
227
256
|
|
|
257
|
+
[1.17.2]: https://github.com/CodeCompose7/stack-site-builder/compare/v1.17.1...v1.17.2
|
|
258
|
+
[1.17.1]: https://github.com/CodeCompose7/stack-site-builder/compare/v1.17.0...v1.17.1
|
|
228
259
|
[1.17.0]: https://github.com/CodeCompose7/stack-site-builder/compare/v1.16.0...v1.17.0
|
|
229
260
|
[1.16.0]: https://github.com/CodeCompose7/stack-site-builder/compare/v1.15.0...v1.16.0
|
|
230
261
|
[1.15.0]: https://github.com/CodeCompose7/stack-site-builder/compare/v1.14.0...v1.15.0
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stack-site-builder",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.17.
|
|
4
|
+
"version": "1.17.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "The engine behind the awesome-*-stack catalog sites: an Astro theme with the catalog/concepts/articles/slides/samples routes, components, styles and markdown pipeline. Sites provide content, taxonomy data and config.",
|
|
7
7
|
"repository": {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { render
|
|
2
|
+
import { render } from 'astro:content';
|
|
3
3
|
import { getRelativeLocaleUrl } from 'astro:i18n';
|
|
4
4
|
import { getCourses, courseSlugOf, type CourseEntry } from '../lib/courses';
|
|
5
|
+
import { getDecks, deckSlugOf } from '../lib/slides';
|
|
5
6
|
import { inlineMd } from '../lib/inline-md';
|
|
6
7
|
import { Image } from 'astro:assets';
|
|
7
8
|
import { useTranslations, type Lang } from '../i18n/ui';
|
|
@@ -33,14 +34,14 @@ const relatedCourses = data.related
|
|
|
33
34
|
.map((sl) => courseBySlug.get(sl))
|
|
34
35
|
.filter(Boolean) as CourseEntry[];
|
|
35
36
|
|
|
36
|
-
// Decks in the `slides` collection that belong to this course
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
)
|
|
43
|
-
|
|
37
|
+
// Decks in the `slides` collection that belong to this course, matched by
|
|
38
|
+
// their locale-less slug (what the frontmatter lists). Only linked when the
|
|
39
|
+
// slides section is enabled (otherwise its routes don't exist) and the slug
|
|
40
|
+
// actually resolves — a typo just drops the chip instead of a dead link.
|
|
41
|
+
const slideDecks =
|
|
42
|
+
sectionEnabled('slides') && data.slides.length > 0
|
|
43
|
+
? (await getDecks(lang)).filter((d) => data.slides.includes(deckSlugOf(d)))
|
|
44
|
+
: [];
|
|
44
45
|
|
|
45
46
|
// Breadcrumb: All courses › category › subcategory… (each segment linked).
|
|
46
47
|
const crumbs = [
|
|
@@ -84,7 +85,7 @@ const crumbs = [
|
|
|
84
85
|
</span>
|
|
85
86
|
{slideDecks.map((d) => (
|
|
86
87
|
<a
|
|
87
|
-
href={getRelativeLocaleUrl(lang, `slides/${d
|
|
88
|
+
href={getRelativeLocaleUrl(lang, `slides/${deckSlugOf(d)}/`)}
|
|
88
89
|
class="rounded-full border border-[var(--aas-border)] bg-[var(--aas-panel)] px-3 py-1 text-sm text-[var(--aas-text)] no-underline hover:bg-[var(--aas-tint)]"
|
|
89
90
|
>
|
|
90
91
|
{d.data.title}
|
|
@@ -6,6 +6,7 @@ import { render, type CollectionEntry } from 'astro:content';
|
|
|
6
6
|
import MermaidLoader from './MermaidLoader.astro';
|
|
7
7
|
import PrivateGate from './PrivateGate.astro';
|
|
8
8
|
import { useTranslations, type Lang } from '../i18n/ui';
|
|
9
|
+
import { siteIcons } from '../lib/icons';
|
|
9
10
|
|
|
10
11
|
// Renders a full-screen slide deck as a horizontal scroll-snap presentation.
|
|
11
12
|
// A page (src/pages/slides/[deck].astro and its ko/ sibling) picks the deck for
|
|
@@ -33,7 +34,9 @@ const priv = entry.data.private;
|
|
|
33
34
|
<title>{entry.data.title} — {site.name}</title>
|
|
34
35
|
<meta name="description" content={(priv ? entry.data.teaser : entry.data.description) ?? ''} />
|
|
35
36
|
{priv && <meta name="robots" content="noindex" />}
|
|
36
|
-
<link rel="icon" type
|
|
37
|
+
<link rel="icon" {...(siteIcons.faviconType ? { type: siteIcons.faviconType } : {})} href={`${base}${siteIcons.favicon}`} />
|
|
38
|
+
{siteIcons.appleTouch && <link rel="apple-touch-icon" href={`${base}${siteIcons.appleTouch}`} />}
|
|
39
|
+
{siteIcons.manifest && <link rel="manifest" href={`${base}${siteIcons.manifest}`} />}
|
|
37
40
|
{/* Follow the site's light/dark preference before first paint (same logic as
|
|
38
41
|
BaseLayout). The deck's visual theme is a separate CSS class, below. */}
|
|
39
42
|
<script is:inline>
|
|
@@ -5,7 +5,15 @@
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<script>
|
|
8
|
-
|
|
8
|
+
// The self-contained browser bundle, NOT the package default: the default
|
|
9
|
+
// entry (mermaid.core.mjs) keeps dayjs/d3 as bare CJS imports, which break
|
|
10
|
+
// with a "does not provide an export named 'default'" SyntaxError in a
|
|
11
|
+
// CONSUMING site's dev server — the theme lives in node_modules there, so
|
|
12
|
+
// Vite serves the import chain raw without CJS interop. The esm.min bundle
|
|
13
|
+
// inlines every dependency (relative-chunk imports only), so it loads the
|
|
14
|
+
// same in dev and build.
|
|
15
|
+
// @ts-expect-error — the bundled build ships no type mapping; same API.
|
|
16
|
+
import mermaid from 'mermaid/dist/mermaid.esm.min.mjs';
|
|
9
17
|
import { initOnReady } from '../lib/reinit';
|
|
10
18
|
|
|
11
19
|
// Read the live site palette so Mermaid matches the current theme exactly.
|
|
@@ -10,6 +10,7 @@ import { getNavPages, pageSlugOf } from '../lib/pages';
|
|
|
10
10
|
import { getNavProducts, getTopProducts, productSlugOf } from '../lib/products';
|
|
11
11
|
import { homeTemplate } from '../lib/home';
|
|
12
12
|
import { sectionEnabled, type SectionKey } from '../lib/sections';
|
|
13
|
+
import { siteIcons } from '../lib/icons';
|
|
13
14
|
|
|
14
15
|
interface Props {
|
|
15
16
|
title: string;
|
|
@@ -33,19 +34,6 @@ const container = wide ? 'max-w-[81rem]' : 'max-w-[75rem]';
|
|
|
33
34
|
const home = getRelativeLocaleUrl(lang, '');
|
|
34
35
|
const base = import.meta.env.BASE_URL;
|
|
35
36
|
|
|
36
|
-
// Site-configurable browser icons (`site.icons`). `favicon` may be any image
|
|
37
|
-
// the browser can render (SVG/PNG/ICO — public/ path); appleTouch/manifest
|
|
38
|
-
// links render only when declared. Defaults to the theme's /favicon.svg.
|
|
39
|
-
const icons =
|
|
40
|
-
(site as { icons?: { favicon?: string; appleTouch?: string; manifest?: string } }).icons ?? {};
|
|
41
|
-
const faviconHref = icons.favicon ?? '/favicon.svg';
|
|
42
|
-
const faviconType = faviconHref.endsWith('.svg')
|
|
43
|
-
? 'image/svg+xml'
|
|
44
|
-
: faviconHref.endsWith('.png')
|
|
45
|
-
? 'image/png'
|
|
46
|
-
: faviconHref.endsWith('.ico')
|
|
47
|
-
? 'image/x-icon'
|
|
48
|
-
: undefined;
|
|
49
37
|
const baseNoSlash = base.replace(/\/$/, '');
|
|
50
38
|
|
|
51
39
|
// Home URL per locale, for the language auto-detect redirect on the root home.
|
|
@@ -173,9 +161,9 @@ const navItems = allNavItems.filter((item) => !item.section || sectionEnabled(it
|
|
|
173
161
|
<title>{title}</title>
|
|
174
162
|
<meta name="description" content={description} />
|
|
175
163
|
{noindex && <meta name="robots" content="noindex" />}
|
|
176
|
-
<link rel="icon" {...(faviconType ? { type: faviconType } : {})} href={`${baseNoSlash}${
|
|
177
|
-
{
|
|
178
|
-
{
|
|
164
|
+
<link rel="icon" {...(siteIcons.faviconType ? { type: siteIcons.faviconType } : {})} href={`${baseNoSlash}${siteIcons.favicon}`} />
|
|
165
|
+
{siteIcons.appleTouch && <link rel="apple-touch-icon" href={`${baseNoSlash}${siteIcons.appleTouch}`} />}
|
|
166
|
+
{siteIcons.manifest && <link rel="manifest" href={`${baseNoSlash}${siteIcons.manifest}`} />}
|
|
179
167
|
{
|
|
180
168
|
sectionEnabled('articles') && (
|
|
181
169
|
<link
|
package/src/lib/icons.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { site } from '@aas-data/site';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The site's browser icons (`site.ts` `icons`), resolved once with the theme
|
|
5
|
+
* default. Shared by every layout that owns a `<head>` (BaseLayout, DeckView)
|
|
6
|
+
* so a site's custom favicon applies everywhere.
|
|
7
|
+
*/
|
|
8
|
+
export interface SiteIcons {
|
|
9
|
+
favicon: string;
|
|
10
|
+
faviconType?: string;
|
|
11
|
+
appleTouch?: string;
|
|
12
|
+
manifest?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const cfg =
|
|
16
|
+
(site as { icons?: { favicon?: string; appleTouch?: string; manifest?: string } }).icons ?? {};
|
|
17
|
+
const favicon = cfg.favicon ?? '/favicon.svg';
|
|
18
|
+
|
|
19
|
+
export const siteIcons: SiteIcons = {
|
|
20
|
+
favicon,
|
|
21
|
+
faviconType: favicon.endsWith('.svg')
|
|
22
|
+
? 'image/svg+xml'
|
|
23
|
+
: favicon.endsWith('.png')
|
|
24
|
+
? 'image/png'
|
|
25
|
+
: favicon.endsWith('.ico')
|
|
26
|
+
? 'image/x-icon'
|
|
27
|
+
: undefined,
|
|
28
|
+
appleTouch: cfg.appleTouch,
|
|
29
|
+
manifest: cfg.manifest,
|
|
30
|
+
};
|