ferst-core 0.7.2 → 0.7.4

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.
Files changed (37) hide show
  1. package/components/BlockRenderer.astro +6 -0
  2. package/components/Pagination.astro +51 -0
  3. package/components/blocks/Heading.astro +47 -46
  4. package/components/blocks/Prose.astro +10 -2
  5. package/components/blocks/Quote.astro +40 -38
  6. package/components/recipes/Accordion.astro +91 -84
  7. package/components/recipes/Document.astro +152 -0
  8. package/components/recipes/FeatureCards.astro +112 -111
  9. package/components/recipes/Hero.astro +52 -4
  10. package/components/recipes/LinkRow.astro +91 -0
  11. package/components/recipes/MediaCards.astro +213 -212
  12. package/components/recipes/Notice.astro +90 -89
  13. package/components/recipes/Stats.astro +152 -145
  14. package/components/recipes/Table.astro +98 -97
  15. package/components/recipes/Tabs.astro +134 -133
  16. package/components/recipes/Tiles.astro +4 -2
  17. package/components/recipes/Timetable.astro +189 -0
  18. package/components/recipes/Video.astro +177 -157
  19. package/content/blocks.ts +65 -1
  20. package/content/cookies.ts +10 -0
  21. package/examples/primitives.ts +2 -0
  22. package/examples/recipes.ts +5 -0
  23. package/integration.mjs +83 -64
  24. package/layouts/Base.astro +481 -475
  25. package/lib/documents.ts +68 -62
  26. package/lib/embed-consent.ts +78 -73
  27. package/lib/inline-markdown.ts +6 -0
  28. package/lib/links.ts +12 -0
  29. package/lib/paginate.ts +23 -0
  30. package/lib/posts.ts +20 -2
  31. package/lib/timetable.ts +27 -0
  32. package/lib/video.ts +101 -75
  33. package/package.json +1 -1
  34. package/routes/cookie-policy.astro +27 -0
  35. package/routes/posts/index.astro +36 -31
  36. package/routes/posts/page/[page].astro +36 -0
  37. package/routes/posts/tag/[...tag].astro +41 -37
package/integration.mjs CHANGED
@@ -1,64 +1,83 @@
1
- /**
2
- * ferst() — the Astro integration that makes a client site's ROUTING package-owned.
3
- *
4
- * A thin client adds `integrations: [ferst()]` to astro.config.mjs and carries
5
- * ZERO page files: the page catch-all (which also owns the home page), the
6
- * calendar route and the blog routes are injected from ferst-core. A routing fix
7
- * then ships as a package bump + rebuild — the same channel component fixes travel
8
- * through — instead of being hand-copied into every client repo.
9
- *
10
- * Irreducible caveat (Astro 5): content collections must be defined in the CONSUMER,
11
- * so the one-line `src/content/config.ts` re-export stays. "Zero page files" is
12
- * reachable; "zero files" is not. Explicit client `.astro` routes still win over
13
- * these injected ones, so a one-off hand-built page is always possible.
14
- *
15
- * The blog routes (posts index / individual post / tag pages) inject as a set:
16
- * the listing components (NewsList, PostsFilter) now live in core, so `/posts`,
17
- * `/posts/[...slug]` and `/posts/tag/[...tag]` all ship from the package. Turn
18
- * the whole capability off with `blog: false` (then a client wanting posts hand-
19
- * builds its own routes over `ferst-core/lib/posts`).
20
- *
21
- * @param {object} [options]
22
- * @param {boolean} [options.calendar=true] Inject the `/calendar` route.
23
- * @param {boolean} [options.blog=true] Inject the blog routes (`/posts`,
24
- * `/posts/[...slug]`, `/posts/tag/[...tag]`).
25
- * @returns {import('astro').AstroIntegration}
26
- */
27
- export default function ferst(options = {}) {
28
- const { calendar = true, blog = true } = options;
29
- return {
30
- name: 'ferst',
31
- hooks: {
32
- 'astro:config:setup': ({ injectRoute }) => {
33
- // Pages + home: the reserved `index` entry renders at `/`, every other
34
- // `pages` entry at its own slug (see lib/pages.ts `getSiteRoutes`).
35
- injectRoute({
36
- pattern: '/[...slug]',
37
- entrypoint: 'ferst-core/routes/[...slug].astro',
38
- });
39
- if (calendar) {
40
- injectRoute({
41
- pattern: '/calendar',
42
- entrypoint: 'ferst-core/routes/calendar/index.astro',
43
- });
44
- }
45
- if (blog) {
46
- // The posts capability: index, individual post, and tag pages. Reads
47
- // the `posts`/`tags`/`postsSettings` collections (content/collections.ts).
48
- injectRoute({
49
- pattern: '/posts',
50
- entrypoint: 'ferst-core/routes/posts/index.astro',
51
- });
52
- injectRoute({
53
- pattern: '/posts/[...slug]',
54
- entrypoint: 'ferst-core/routes/posts/[...slug].astro',
55
- });
56
- injectRoute({
57
- pattern: '/posts/tag/[...tag]',
58
- entrypoint: 'ferst-core/routes/posts/tag/[...tag].astro',
59
- });
60
- }
61
- },
62
- },
63
- };
64
- }
1
+ /**
2
+ * ferst() — the Astro integration that makes a client site's ROUTING package-owned.
3
+ *
4
+ * A thin client adds `integrations: [ferst()]` to astro.config.mjs and carries
5
+ * ZERO page files: the page catch-all (which also owns the home page), the
6
+ * calendar route and the blog routes are injected from ferst-core. A routing fix
7
+ * then ships as a package bump + rebuild — the same channel component fixes travel
8
+ * through — instead of being hand-copied into every client repo.
9
+ *
10
+ * Irreducible caveat (Astro 5): content collections must be defined in the CONSUMER,
11
+ * so the one-line `src/content/config.ts` re-export stays. "Zero page files" is
12
+ * reachable; "zero files" is not. Explicit client `.astro` routes still win over
13
+ * these injected ones, so a one-off hand-built page is always possible.
14
+ *
15
+ * The blog routes (posts index / individual post / tag pages) inject as a set:
16
+ * the listing components (NewsList, PostsFilter) now live in core, so `/posts`,
17
+ * `/posts/[...slug]` and `/posts/tag/[...tag]` all ship from the package. Turn
18
+ * the whole capability off with `blog: false` (then a client wanting posts hand-
19
+ * builds its own routes over `ferst-core/lib/posts`).
20
+ *
21
+ * @param {object} [options]
22
+ * @param {boolean} [options.calendar=true] Inject the `/calendar` route.
23
+ * @param {boolean} [options.blog=true] Inject the blog routes (`/posts`,
24
+ * `/posts/[...slug]`, `/posts/tag/[...tag]`).
25
+ * @param {boolean} [options.cookiePolicy=true] Inject `/cookie-policy` (the page the cookie
26
+ * banner links to), generated from the blocks the site uses. Skipped automatically when
27
+ * the site has its own `src/pages/cookie-policy.astro`.
28
+ * @returns {import('astro').AstroIntegration}
29
+ */
30
+ import { existsSync } from 'node:fs';
31
+
32
+ export default function ferst(options = {}) {
33
+ const { calendar = true, blog = true, cookiePolicy = true } = options;
34
+ return {
35
+ name: 'ferst',
36
+ hooks: {
37
+ 'astro:config:setup': ({ injectRoute, config }) => {
38
+ // Pages + home: the reserved `index` entry renders at `/`, every other
39
+ // `pages` entry at its own slug (see lib/pages.ts `getSiteRoutes`).
40
+ injectRoute({
41
+ pattern: '/[...slug]',
42
+ entrypoint: 'ferst-core/routes/[...slug].astro',
43
+ });
44
+ if (calendar) {
45
+ injectRoute({
46
+ pattern: '/calendar',
47
+ entrypoint: 'ferst-core/routes/calendar/index.astro',
48
+ });
49
+ }
50
+ if (blog) {
51
+ // The posts capability: index, individual post, and tag pages. Reads
52
+ // the `posts`/`tags`/`postsSettings` collections (content/collections.ts).
53
+ injectRoute({
54
+ pattern: '/posts',
55
+ entrypoint: 'ferst-core/routes/posts/index.astro',
56
+ });
57
+ injectRoute({
58
+ pattern: '/posts/[...slug]',
59
+ entrypoint: 'ferst-core/routes/posts/[...slug].astro',
60
+ });
61
+ injectRoute({
62
+ pattern: '/posts/tag/[...tag]',
63
+ entrypoint: 'ferst-core/routes/posts/tag/[...tag].astro',
64
+ });
65
+ // Index pages 2+ (page 1 is /posts; tag pages paginate inside their own route).
66
+ injectRoute({
67
+ pattern: '/posts/page/[page]',
68
+ entrypoint: 'ferst-core/routes/posts/page/[page].astro',
69
+ });
70
+ }
71
+ // The cookie banner links here on every page, so it must always resolve. A site's
72
+ // own hand-built page wins (Astro would otherwise see two routes for one path).
73
+ const bespoke = config?.root && existsSync(new URL('src/pages/cookie-policy.astro', config.root));
74
+ if (cookiePolicy && !bespoke) {
75
+ injectRoute({
76
+ pattern: '/cookie-policy',
77
+ entrypoint: 'ferst-core/routes/cookie-policy.astro',
78
+ });
79
+ }
80
+ },
81
+ },
82
+ };
83
+ }