@aureuma/svelta 0.0.1 → 0.1.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.
Files changed (83) hide show
  1. package/package.json +34 -2
  2. package/packages/blogkit/CHANGELOG.md +12 -0
  3. package/packages/blogkit/dist/index.d.ts +1 -1
  4. package/packages/blogkit/dist/server/blog.d.ts +68 -1
  5. package/packages/blogkit/dist/server/blog.js +248 -0
  6. package/packages/blogkit/dist/server/index.d.ts +1 -1
  7. package/packages/blogkit/dist/server/index.js +1 -1
  8. package/packages/blogkit/dist/types/blog.d.ts +10 -0
  9. package/.changeset/README.md +0 -8
  10. package/.changeset/config.json +0 -14
  11. package/.changeset/publish-blogkit.md +0 -5
  12. package/.github/workflows/release.yml +0 -65
  13. package/docs/mintlify-blog-study.md +0 -697
  14. package/packages/blogkit/package.json +0 -66
  15. package/packages/blogkit/src/lib/components/blog/Avatar.svelte +0 -15
  16. package/packages/blogkit/src/lib/components/blog/BackLink.svelte +0 -23
  17. package/packages/blogkit/src/lib/components/blog/BlogCard.svelte +0 -37
  18. package/packages/blogkit/src/lib/components/blog/BlogHeroCard.svelte +0 -36
  19. package/packages/blogkit/src/lib/components/blog/Container.svelte +0 -8
  20. package/packages/blogkit/src/lib/components/blog/ImageLightbox.svelte +0 -58
  21. package/packages/blogkit/src/lib/components/blog/MorePosts.svelte +0 -15
  22. package/packages/blogkit/src/lib/components/blog/ShareButtons.svelte +0 -113
  23. package/packages/blogkit/src/lib/components/blog/SummaryCard.svelte +0 -11
  24. package/packages/blogkit/src/lib/components/blog/TagTabs.svelte +0 -32
  25. package/packages/blogkit/src/lib/index.ts +0 -15
  26. package/packages/blogkit/src/lib/server/blog.ts +0 -264
  27. package/packages/blogkit/src/lib/server/index.ts +0 -2
  28. package/packages/blogkit/src/lib/theme/ThemeSwitcher.svelte +0 -34
  29. package/packages/blogkit/src/lib/theme/index.ts +0 -3
  30. package/packages/blogkit/src/lib/theme/store.ts +0 -64
  31. package/packages/blogkit/src/lib/types/blog.ts +0 -36
  32. package/packages/blogkit/svelte.config.js +0 -8
  33. package/packages/blogkit/tsconfig.json +0 -5
  34. package/playwright.config.ts +0 -24
  35. package/postcss.config.cjs +0 -6
  36. package/src/app.css +0 -146
  37. package/src/app.d.ts +0 -13
  38. package/src/app.html +0 -26
  39. package/src/content/blog/ai-summary-cards-with-frontmatter.md +0 -32
  40. package/src/content/blog/announcing-svelta-blog.md +0 -19
  41. package/src/content/blog/best-practices-ship-with-checklists.md +0 -26
  42. package/src/content/blog/building-a-mintlify-inspired-blog.md +0 -49
  43. package/src/content/blog/design-tokens-that-scale.md +0 -47
  44. package/src/content/blog/for-founders-why-speed-matters.md +0 -23
  45. package/src/content/blog/infinite-scroll-with-intersection-observer.md +0 -37
  46. package/src/content/blog/markdown-kitchen-sink.md +0 -101
  47. package/src/content/blog/markdown-pipeline-mdsvex-shiki.md +0 -39
  48. package/src/content/blog/rss-feeds-that-actually-work.md +0 -25
  49. package/src/content/blog/tag-tabs-and-mobile-fade-masks.md +0 -25
  50. package/src/lib/assets/favicon.svg +0 -1
  51. package/src/lib/components/site/SiteFooter.svelte +0 -24
  52. package/src/lib/components/site/SiteHeader.svelte +0 -36
  53. package/src/lib/content/authors.ts +0 -28
  54. package/src/lib/index.ts +0 -1
  55. package/src/lib/server/blog.ts +0 -22
  56. package/src/lib/server/rss.ts +0 -58
  57. package/src/lib/server/seo.ts +0 -31
  58. package/src/lib/stores/theme.ts +0 -10
  59. package/src/lib/types/blog.ts +0 -1
  60. package/src/routes/+layout.svelte +0 -31
  61. package/src/routes/+page.svelte +0 -44
  62. package/src/routes/blog/+page.server.ts +0 -28
  63. package/src/routes/blog/+page.svelte +0 -122
  64. package/src/routes/blog/[slug]/+page.server.ts +0 -39
  65. package/src/routes/blog/[slug]/+page.svelte +0 -118
  66. package/src/routes/blog/posts.json/+server.ts +0 -32
  67. package/src/routes/feed.xml/+server.ts +0 -21
  68. package/static/blog/authors/alex.svg +0 -13
  69. package/static/blog/authors/maria.svg +0 -13
  70. package/static/blog/authors/shawn.svg +0 -13
  71. package/static/blog/covers/ai-summary.svg +0 -38
  72. package/static/blog/covers/design-tokens.svg +0 -37
  73. package/static/blog/covers/infinite-scroll.svg +0 -38
  74. package/static/blog/covers/kitchen-sink.svg +0 -36
  75. package/static/blog/covers/markdown-pipeline.svg +0 -41
  76. package/static/blog/covers/mintlify-style.svg +0 -35
  77. package/static/blog/covers/rss.svg +0 -34
  78. package/static/robots.txt +0 -3
  79. package/svelte.config.js +0 -70
  80. package/tailwind.config.cjs +0 -133
  81. package/tests/blog.spec.ts +0 -63
  82. package/tsconfig.json +0 -21
  83. package/vite.config.ts +0 -14
package/package.json CHANGED
@@ -1,8 +1,37 @@
1
1
  {
2
2
  "name": "@aureuma/svelta",
3
3
  "private": false,
4
- "version": "0.0.1",
4
+ "version": "0.1.0",
5
5
  "type": "module",
6
+ "files": [
7
+ "packages/blogkit/dist",
8
+ "packages/blogkit/README.md",
9
+ "packages/blogkit/CHANGELOG.md",
10
+ "LICENSE",
11
+ "README.md"
12
+ ],
13
+ "exports": {
14
+ ".": {
15
+ "types": "./packages/blogkit/dist/index.d.ts",
16
+ "svelte": "./packages/blogkit/dist/index.js",
17
+ "default": "./packages/blogkit/dist/index.js"
18
+ },
19
+ "./server": {
20
+ "types": "./packages/blogkit/dist/server/index.d.ts",
21
+ "default": "./packages/blogkit/dist/server/index.js"
22
+ },
23
+ "./theme": {
24
+ "types": "./packages/blogkit/dist/theme/index.d.ts",
25
+ "svelte": "./packages/blogkit/dist/theme/index.js",
26
+ "default": "./packages/blogkit/dist/theme/index.js"
27
+ }
28
+ },
29
+ "types": "./packages/blogkit/dist/index.d.ts",
30
+ "main": "./packages/blogkit/dist/index.js",
31
+ "svelte": "./packages/blogkit/dist/index.js",
32
+ "peerDependencies": {
33
+ "svelte": "^4.0.0 || ^5.0.0"
34
+ },
6
35
  "workspaces": [
7
36
  "packages/*"
8
37
  ],
@@ -18,7 +47,8 @@
18
47
  "test": "npm run check && npm run test:e2e",
19
48
  "changeset": "changeset",
20
49
  "version-packages": "changeset version",
21
- "release": "changeset publish"
50
+ "release": "changeset publish",
51
+ "prepack": "npm -w @aureuma/blogkit run build"
22
52
  },
23
53
  "devDependencies": {
24
54
  "@changesets/changelog-github": "^0.5.2",
@@ -47,9 +77,11 @@
47
77
  "vite": "^7.3.1"
48
78
  },
49
79
  "dependencies": {
80
+ "esm-env": "^1.2.2",
50
81
  "@fontsource/geist-mono": "^5.2.7",
51
82
  "@fontsource/inter": "^5.2.8",
52
83
  "gray-matter": "^4.0.3",
84
+ "marked": "^12.0.2",
53
85
  "reading-time": "^1.5.0",
54
86
  "zod": "^4.3.6"
55
87
  },
@@ -4,3 +4,15 @@ All notable changes to this package will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [0.1.0] - 2026-02-22
8
+ ### Added
9
+ - Added `createRawBlog` support for raw markdown module sources.
10
+ - Added Viva frontmatter and author parser helpers:
11
+ - `parseVivaBlogFrontmatter`
12
+ - `parseVivaAuthorFrontmatter`
13
+ - `parseMarkdownAuthorMap`
14
+ - `parseVivaAuthorProfiles`
15
+ - Added exported Viva-focused types for frontmatter and author profiles.
16
+
17
+ ### Changed
18
+ - Expanded `@aureuma/svelta/server` exports to support Viva app migration without custom blog parsing code.
@@ -8,4 +8,4 @@ export { default as MorePosts } from './components/blog/MorePosts.svelte';
8
8
  export { default as ShareButtons } from './components/blog/ShareButtons.svelte';
9
9
  export { default as SummaryCard } from './components/blog/SummaryCard.svelte';
10
10
  export { default as TagTabs } from './components/blog/TagTabs.svelte';
11
- export type { BlogAuthor, BlogCategory, BlogPost, BlogPostFull } from './types/blog';
11
+ export type { BlogAuthor, BlogCategory, BlogPost, BlogPostFull, BlogPostWithContent, BlogTag } from './types/blog';
@@ -1,4 +1,4 @@
1
- import type { BlogAuthor, BlogCategory, BlogPost, BlogPostFull } from '../types/blog';
1
+ import type { BlogAuthor, BlogCategory, BlogPost, BlogPostFull, BlogPostWithContent, BlogTag } from '../types/blog';
2
2
  import { z } from 'zod';
3
3
  declare const frontmatterSchema: z.ZodObject<{
4
4
  title: z.ZodString;
@@ -29,6 +29,54 @@ export type BlogCreateConfig = {
29
29
  categoryOrder?: string[];
30
30
  mapFrontmatter?: BlogFrontmatterAdapter;
31
31
  };
32
+ export type MarkdownRenderer = (markdown: string) => string | Promise<string>;
33
+ export type RawBlogCreateConfig = {
34
+ rawModules: Record<string, () => Promise<string>>;
35
+ getAuthor: (id: string) => BlogAuthor;
36
+ categoryOrder?: string[];
37
+ mapFrontmatter?: BlogFrontmatterAdapter;
38
+ renderMarkdown?: MarkdownRenderer;
39
+ };
40
+ export type VivaImageAsset = {
41
+ url: string;
42
+ alt: string;
43
+ width: number;
44
+ height: number;
45
+ credit: string;
46
+ source: string;
47
+ };
48
+ export type VivaSeoFields = {
49
+ title: string;
50
+ description: string;
51
+ keywords: string[];
52
+ };
53
+ export type VivaBlogFrontmatter = {
54
+ title: string;
55
+ description: string;
56
+ slug: string;
57
+ publishedAt: string;
58
+ updatedAt: string;
59
+ author: string;
60
+ tags: string[];
61
+ canonical: string;
62
+ ogImage: VivaImageAsset;
63
+ draft: boolean;
64
+ seo: VivaSeoFields;
65
+ };
66
+ export type VivaAuthorFrontmatter = {
67
+ name: string;
68
+ slug: string;
69
+ role: string;
70
+ bio: string;
71
+ interests: string[];
72
+ canonical: string;
73
+ avatar: VivaImageAsset;
74
+ seo: VivaSeoFields;
75
+ };
76
+ export type VivaAuthorProfile = VivaAuthorFrontmatter & {
77
+ html: string;
78
+ raw: string;
79
+ };
32
80
  export declare function createBlog(config: BlogCreateConfig): {
33
81
  getAllPosts: () => Promise<BlogPost[]>;
34
82
  getAllPostsFull: () => Promise<BlogPostFull[]>;
@@ -36,4 +84,23 @@ export declare function createBlog(config: BlogCreateConfig): {
36
84
  getCategories: () => Promise<BlogCategory[]>;
37
85
  pickHero: (posts?: BlogPost[]) => Promise<BlogPost>;
38
86
  };
87
+ export declare function parseVivaBlogFrontmatter(data: unknown): VivaBlogFrontmatter;
88
+ export declare function parseVivaAuthorFrontmatter(data: unknown): VivaAuthorFrontmatter;
89
+ export declare function parseMarkdownAuthorMap(rawModules: Record<string, string>, fallbackAvatar?: string): Map<string, BlogAuthor>;
90
+ export declare function parseVivaAuthorProfiles(rawModules: Record<string, string>, renderMarkdown?: MarkdownRenderer): Promise<VivaAuthorProfile[]>;
91
+ export declare function createRawBlog(config: RawBlogCreateConfig): {
92
+ getAllPosts: () => Promise<BlogPost[]>;
93
+ getAllPostsWithContent: () => Promise<BlogPostWithContent[]>;
94
+ getPostBySlug: (slug: string) => Promise<BlogPostWithContent | null>;
95
+ getCategories: () => Promise<BlogCategory[]>;
96
+ pickHero: (posts?: BlogPost[]) => Promise<BlogPost>;
97
+ getAllTags: () => Promise<BlogTag[]>;
98
+ getPostsByTag: (tagSlug: string) => Promise<BlogPostWithContent[]>;
99
+ getPostsByAuthor: (authorId: string) => Promise<BlogPostWithContent[]>;
100
+ getAdjacentPosts: (slug: string) => Promise<{
101
+ previous: BlogPostWithContent | null;
102
+ next: BlogPostWithContent | null;
103
+ }>;
104
+ getRelatedPosts: (slug: string, limit?: number) => Promise<BlogPostWithContent[]>;
105
+ };
39
106
  export {};
@@ -1,5 +1,6 @@
1
1
  import { DEV } from 'esm-env';
2
2
  import matter from 'gray-matter';
3
+ import { marked } from 'marked';
3
4
  import readingTime from 'reading-time';
4
5
  import { z } from 'zod';
5
6
  const frontmatterSchema = z.object({
@@ -23,6 +24,46 @@ const DEFAULT_CATEGORY_ORDER = [
23
24
  'design',
24
25
  'best-practices'
25
26
  ];
27
+ const vivaImageAssetSchema = z.object({
28
+ url: z.string(),
29
+ alt: z.string(),
30
+ width: z.number(),
31
+ height: z.number(),
32
+ credit: z.string(),
33
+ source: z.string()
34
+ });
35
+ const vivaSeoFieldsSchema = z.object({
36
+ title: z.string(),
37
+ description: z.string(),
38
+ keywords: z.array(z.string())
39
+ });
40
+ const vivaDateField = z
41
+ .union([z.string(), z.date()])
42
+ .transform((value) => (value instanceof Date ? value.toISOString() : value));
43
+ const vivaBlogFrontmatterSchema = z.object({
44
+ title: z.string(),
45
+ description: z.string(),
46
+ slug: z.string(),
47
+ publishedAt: vivaDateField,
48
+ updatedAt: vivaDateField,
49
+ author: z.string(),
50
+ tags: z.array(z.string()),
51
+ canonical: z.string(),
52
+ ogImage: vivaImageAssetSchema,
53
+ draft: z.boolean().optional().default(false),
54
+ seo: vivaSeoFieldsSchema
55
+ });
56
+ const vivaAuthorFrontmatterSchema = z.object({
57
+ name: z.string(),
58
+ slug: z.string(),
59
+ role: z.string(),
60
+ bio: z.string(),
61
+ interests: z.array(z.string()),
62
+ canonical: z.string(),
63
+ avatar: vivaImageAssetSchema,
64
+ seo: vivaSeoFieldsSchema
65
+ });
66
+ const frontmatterOnlySchema = /^---\s*[\r\n]+([\s\S]*?)\r?\n---\s*[\r\n]+/;
26
67
  function slugify(input) {
27
68
  return input
28
69
  .toLowerCase()
@@ -220,3 +261,210 @@ export function createBlog(config) {
220
261
  }
221
262
  return { getAllPosts, getAllPostsFull, getPostBySlug, getCategories, pickHero };
222
263
  }
264
+ export function parseVivaBlogFrontmatter(data) {
265
+ return vivaBlogFrontmatterSchema.parse(data);
266
+ }
267
+ export function parseVivaAuthorFrontmatter(data) {
268
+ return vivaAuthorFrontmatterSchema.parse(data);
269
+ }
270
+ function extractFrontmatter(raw) {
271
+ const match = raw.match(frontmatterOnlySchema);
272
+ if (!match)
273
+ return {};
274
+ return matter(raw).data;
275
+ }
276
+ export function parseMarkdownAuthorMap(rawModules, fallbackAvatar = '/favicon.ico') {
277
+ const map = new Map();
278
+ for (const [path, raw] of Object.entries(rawModules)) {
279
+ const defaultSlug = path.split('/').pop()?.replace(/\.md(?:\?.*)?$/, '') || '';
280
+ const data = extractFrontmatter(raw);
281
+ const record = (typeof data === 'object' && data ? data : {});
282
+ const id = typeof record.slug === 'string' && record.slug.length > 0 ? record.slug : defaultSlug;
283
+ if (!id)
284
+ continue;
285
+ const name = typeof record.name === 'string' && record.name.length > 0 ? record.name : id;
286
+ const title = typeof record.role === 'string' && record.role.length > 0 ? record.role : 'Contributor';
287
+ const avatarRecord = record.avatar && typeof record.avatar === 'object'
288
+ ? record.avatar
289
+ : null;
290
+ const avatar = avatarRecord && typeof avatarRecord.url === 'string' ? avatarRecord.url : fallbackAvatar;
291
+ map.set(id, { id, name, title, avatar });
292
+ }
293
+ return map;
294
+ }
295
+ export async function parseVivaAuthorProfiles(rawModules, renderMarkdown = defaultRenderMarkdown) {
296
+ const profiles = [];
297
+ for (const [path, raw] of Object.entries(rawModules)) {
298
+ const { data, content } = matter(raw);
299
+ const parsed = parseVivaAuthorFrontmatter(data);
300
+ const html = await renderMarkdown(content);
301
+ profiles.push({
302
+ ...parsed,
303
+ html,
304
+ raw: content
305
+ });
306
+ }
307
+ profiles.sort((a, b) => a.name.localeCompare(b.name));
308
+ return profiles;
309
+ }
310
+ const defaultRenderMarkdown = (markdown) => String(marked.parse(markdown));
311
+ function toBlogTag(name) {
312
+ return {
313
+ name,
314
+ slug: slugify(name)
315
+ };
316
+ }
317
+ export function createRawBlog(config) {
318
+ const categoryOrder = config.categoryOrder ?? DEFAULT_CATEGORY_ORDER;
319
+ const renderMarkdown = config.renderMarkdown ?? defaultRenderMarkdown;
320
+ let cachedContentIndex = null;
321
+ async function buildContentIndex() {
322
+ if (!DEV && cachedContentIndex)
323
+ return cachedContentIndex;
324
+ const posts = [];
325
+ const paths = Object.keys(config.rawModules).sort();
326
+ for (const path of paths) {
327
+ const file = path.split('/').pop();
328
+ const slug = file?.replace(/\.md(?:\?.*)?$/, '');
329
+ if (!slug)
330
+ continue;
331
+ const rawFn = config.rawModules[path];
332
+ if (!rawFn)
333
+ continue;
334
+ const raw = await rawFn();
335
+ const { data, content } = matter(raw);
336
+ const metadata = config.mapFrontmatter
337
+ ? config.mapFrontmatter({ data, content, slug, path })
338
+ : frontmatterSchema.parse(data);
339
+ if (metadata.draft)
340
+ continue;
341
+ const dateObj = parseISODate(metadata.date);
342
+ const rt = minutesToLabels(readingTime(content).minutes);
343
+ const category = normalizeCategory(metadata.category);
344
+ const excerpt = metadata.excerpt?.trim() || excerptFromContent(content);
345
+ const rendered = await renderMarkdown(content);
346
+ posts.push({
347
+ slug,
348
+ title: metadata.title.trim(),
349
+ excerpt,
350
+ category,
351
+ tags: metadata.tags ?? [],
352
+ author: config.getAuthor(metadata.author),
353
+ authorId: metadata.author,
354
+ date: metadata.date,
355
+ dateLong: fmtLong.format(dateObj),
356
+ dateShort: fmtShort.format(dateObj),
357
+ readingMinutes: rt.minutes,
358
+ readingTimeShort: rt.short,
359
+ readingTimeLong: rt.long,
360
+ cover: metadata.cover,
361
+ summaryAI: metadata.summaryAI,
362
+ featured: Boolean(metadata.featured),
363
+ html: rendered,
364
+ raw: content,
365
+ frontmatter: typeof data === 'object' && data ? data : {}
366
+ });
367
+ }
368
+ posts.sort((a, b) => parseISODate(b.date).getTime() - parseISODate(a.date).getTime());
369
+ if (!DEV)
370
+ cachedContentIndex = posts;
371
+ return posts;
372
+ }
373
+ function stripContent(post) {
374
+ const { html: _html, raw: _raw, authorId: _authorId, frontmatter: _frontmatter, ...meta } = post;
375
+ return meta;
376
+ }
377
+ async function getAllPosts() {
378
+ const posts = await buildContentIndex();
379
+ return posts.map(stripContent);
380
+ }
381
+ async function getAllPostsWithContent() {
382
+ return buildContentIndex();
383
+ }
384
+ async function getPostBySlug(slug) {
385
+ const posts = await buildContentIndex();
386
+ return posts.find((p) => p.slug === slug) ?? null;
387
+ }
388
+ async function getCategories() {
389
+ const posts = await getAllPosts();
390
+ const map = new Map();
391
+ for (const p of posts)
392
+ map.set(p.category.slug, p.category.label);
393
+ return Array.from(map.entries())
394
+ .map(([slug, label]) => ({ slug, label }))
395
+ .sort((a, b) => {
396
+ const ai = categoryOrder.indexOf(a.slug);
397
+ const bi = categoryOrder.indexOf(b.slug);
398
+ if (ai === -1 && bi === -1)
399
+ return a.label.localeCompare(b.label);
400
+ if (ai === -1)
401
+ return 1;
402
+ if (bi === -1)
403
+ return -1;
404
+ return ai - bi;
405
+ });
406
+ }
407
+ async function pickHero(posts) {
408
+ const list = posts ?? (await getAllPosts());
409
+ const featured = list.filter((p) => p.featured);
410
+ return (featured[0] ?? list[0]);
411
+ }
412
+ async function getAllTags() {
413
+ const posts = await buildContentIndex();
414
+ const map = new Map();
415
+ for (const post of posts) {
416
+ for (const tagName of post.tags) {
417
+ const tag = toBlogTag(tagName);
418
+ map.set(tag.slug, tag);
419
+ }
420
+ }
421
+ return Array.from(map.values()).sort((a, b) => a.name.localeCompare(b.name));
422
+ }
423
+ async function getPostsByTag(tagSlug) {
424
+ const posts = await buildContentIndex();
425
+ return posts.filter((post) => post.tags.some((tagName) => slugify(tagName) === tagSlug));
426
+ }
427
+ async function getPostsByAuthor(authorId) {
428
+ const posts = await buildContentIndex();
429
+ return posts.filter((post) => post.authorId === authorId);
430
+ }
431
+ async function getAdjacentPosts(slug) {
432
+ const posts = await buildContentIndex();
433
+ const index = posts.findIndex((post) => post.slug === slug);
434
+ if (index === -1)
435
+ return { previous: null, next: null };
436
+ return {
437
+ previous: posts[index + 1] ?? null,
438
+ next: posts[index - 1] ?? null
439
+ };
440
+ }
441
+ async function getRelatedPosts(slug, limit = 3) {
442
+ const posts = await buildContentIndex();
443
+ const current = posts.find((post) => post.slug === slug);
444
+ if (!current)
445
+ return [];
446
+ const tagSet = new Set(current.tags.map((tag) => slugify(tag)));
447
+ return posts
448
+ .filter((post) => post.slug !== slug)
449
+ .map((post) => {
450
+ const overlap = post.tags.filter((tag) => tagSet.has(slugify(tag))).length;
451
+ return { post, overlap };
452
+ })
453
+ .filter((entry) => entry.overlap > 0)
454
+ .sort((a, b) => b.overlap - a.overlap)
455
+ .slice(0, limit)
456
+ .map((entry) => entry.post);
457
+ }
458
+ return {
459
+ getAllPosts,
460
+ getAllPostsWithContent,
461
+ getPostBySlug,
462
+ getCategories,
463
+ pickHero,
464
+ getAllTags,
465
+ getPostsByTag,
466
+ getPostsByAuthor,
467
+ getAdjacentPosts,
468
+ getRelatedPosts
469
+ };
470
+ }
@@ -1 +1 @@
1
- export { createBlog, type BlogCreateConfig } from './blog';
1
+ export { createBlog, createRawBlog, parseMarkdownAuthorMap, parseVivaAuthorFrontmatter, parseVivaAuthorProfiles, parseVivaBlogFrontmatter, type BlogCreateConfig, type RawBlogCreateConfig, type MarkdownRenderer, type VivaAuthorFrontmatter, type VivaAuthorProfile, type VivaBlogFrontmatter, type VivaImageAsset, type VivaSeoFields } from './blog';
@@ -1 +1 @@
1
- export { createBlog } from './blog';
1
+ export { createBlog, createRawBlog, parseMarkdownAuthorMap, parseVivaAuthorFrontmatter, parseVivaAuthorProfiles, parseVivaBlogFrontmatter } from './blog';
@@ -29,3 +29,13 @@ export type BlogPost = {
29
29
  export type BlogPostFull = BlogPost & {
30
30
  component: ComponentType;
31
31
  };
32
+ export type BlogTag = {
33
+ name: string;
34
+ slug: string;
35
+ };
36
+ export type BlogPostWithContent = BlogPost & {
37
+ html: string;
38
+ raw: string;
39
+ authorId: string;
40
+ frontmatter: Record<string, unknown>;
41
+ };
@@ -1,8 +0,0 @@
1
- # Changesets
2
-
3
- Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
- with multi-package repos, or single-package repos to help you version and publish your code. You can
5
- find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
-
7
- We have a quick list of common questions to get you started engaging with this project in
8
- [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -1,14 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
3
- "changelog": [
4
- "@changesets/changelog-github",
5
- { "repo": "Aureuma/svelta" }
6
- ],
7
- "commit": false,
8
- "fixed": [],
9
- "linked": [],
10
- "access": "public",
11
- "baseBranch": "main",
12
- "updateInternalDependencies": "patch",
13
- "ignore": []
14
- }
@@ -1,5 +0,0 @@
1
- ---
2
- "@aureuma/blogkit": patch
3
- ---
4
-
5
- Prepare @aureuma/blogkit for the first public npm release.
@@ -1,65 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- branches: [main]
6
-
7
- permissions:
8
- contents: write
9
- pull-requests: write
10
-
11
- jobs:
12
- release:
13
- runs-on: ubuntu-latest
14
- steps:
15
- - name: Checkout
16
- uses: actions/checkout@v4
17
-
18
- - name: Setup Node
19
- uses: actions/setup-node@v4
20
- with:
21
- node-version: 20
22
- cache: npm
23
- registry-url: https://registry.npmjs.org
24
-
25
- - name: Install
26
- run: npm ci
27
-
28
- - name: Create Release PR or Publish
29
- id: changesets
30
- uses: changesets/action@v1
31
- with:
32
- publish: npm run release
33
- env:
34
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36
-
37
- - name: Tag Published Package
38
- if: steps.changesets.outputs.published == 'true'
39
- id: tag
40
- run: |
41
- TAG="$(node - <<'NODE'
42
- const pkgs = JSON.parse(process.env.PUBLISHED_PACKAGES || '[]');
43
- const blogkit = pkgs.find((p) => p.name && p.name.includes('blogkit'));
44
- if (!blogkit) process.exit(0);
45
- process.stdout.write(`${blogkit.name}@${blogkit.version}`);
46
- NODE
47
- )"
48
-
49
- if [ -z "$TAG" ]; then
50
- echo "No published blogkit package found; skipping tag."
51
- exit 0
52
- fi
53
-
54
- echo "tag=$TAG" >> "$GITHUB_OUTPUT"
55
- git tag "$TAG"
56
- git push origin "$TAG"
57
- env:
58
- PUBLISHED_PACKAGES: ${{ steps.changesets.outputs.publishedPackages }}
59
-
60
- - name: GitHub Release
61
- if: steps.changesets.outputs.published == 'true' && steps.tag.outputs.tag != ''
62
- uses: softprops/action-gh-release@v2
63
- with:
64
- tag_name: ${{ steps.tag.outputs.tag }}
65
- generate_release_notes: true