@ewanc26/svelte-standard-site 0.2.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 (160) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +108 -0
  3. package/dist/__tests__/content.test.d.ts +4 -0
  4. package/dist/__tests__/content.test.js +128 -0
  5. package/dist/client.d.ts +71 -0
  6. package/dist/client.js +307 -0
  7. package/dist/components/Comments.svelte +277 -0
  8. package/dist/components/Comments.svelte.d.ts +17 -0
  9. package/dist/components/DocumentCard.svelte +95 -0
  10. package/dist/components/DocumentCard.svelte.d.ts +11 -0
  11. package/dist/components/PublicationCard.svelte +54 -0
  12. package/dist/components/PublicationCard.svelte.d.ts +9 -0
  13. package/dist/components/StandardSiteLayout.svelte +102 -0
  14. package/dist/components/StandardSiteLayout.svelte.d.ts +18 -0
  15. package/dist/components/ThemeToggle.svelte +55 -0
  16. package/dist/components/ThemeToggle.svelte.d.ts +6 -0
  17. package/dist/components/common/DateDisplay.svelte +38 -0
  18. package/dist/components/common/DateDisplay.svelte.d.ts +11 -0
  19. package/dist/components/common/TagList.svelte +31 -0
  20. package/dist/components/common/TagList.svelte.d.ts +8 -0
  21. package/dist/components/common/ThemedCard.svelte +65 -0
  22. package/dist/components/common/ThemedCard.svelte.d.ts +11 -0
  23. package/dist/components/common/ThemedContainer.svelte +55 -0
  24. package/dist/components/common/ThemedContainer.svelte.d.ts +11 -0
  25. package/dist/components/common/ThemedText.svelte +75 -0
  26. package/dist/components/common/ThemedText.svelte.d.ts +11 -0
  27. package/dist/components/document/BlockRenderer.svelte +67 -0
  28. package/dist/components/document/BlockRenderer.svelte.d.ts +9 -0
  29. package/dist/components/document/CanvasRenderer.svelte +41 -0
  30. package/dist/components/document/CanvasRenderer.svelte.d.ts +22 -0
  31. package/dist/components/document/DocumentRenderer.svelte +68 -0
  32. package/dist/components/document/DocumentRenderer.svelte.d.ts +17 -0
  33. package/dist/components/document/InlineMath.svelte +41 -0
  34. package/dist/components/document/InlineMath.svelte.d.ts +7 -0
  35. package/dist/components/document/LeafletContentRenderer.svelte +64 -0
  36. package/dist/components/document/LeafletContentRenderer.svelte.d.ts +36 -0
  37. package/dist/components/document/LinearDocumentRenderer.svelte +45 -0
  38. package/dist/components/document/LinearDocumentRenderer.svelte.d.ts +18 -0
  39. package/dist/components/document/MarkdownRenderer.svelte +62 -0
  40. package/dist/components/document/MarkdownRenderer.svelte.d.ts +10 -0
  41. package/dist/components/document/RichText.svelte +272 -0
  42. package/dist/components/document/RichText.svelte.d.ts +18 -0
  43. package/dist/components/document/blocks/BlockquoteBlock.svelte +29 -0
  44. package/dist/components/document/blocks/BlockquoteBlock.svelte.d.ts +10 -0
  45. package/dist/components/document/blocks/BskyPostBlock.svelte +202 -0
  46. package/dist/components/document/blocks/BskyPostBlock.svelte.d.ts +13 -0
  47. package/dist/components/document/blocks/ButtonBlock.svelte +24 -0
  48. package/dist/components/document/blocks/ButtonBlock.svelte.d.ts +10 -0
  49. package/dist/components/document/blocks/CodeBlock.svelte +68 -0
  50. package/dist/components/document/blocks/CodeBlock.svelte.d.ts +12 -0
  51. package/dist/components/document/blocks/HeaderBlock.svelte +56 -0
  52. package/dist/components/document/blocks/HeaderBlock.svelte.d.ts +11 -0
  53. package/dist/components/document/blocks/HorizontalRuleBlock.svelte +14 -0
  54. package/dist/components/document/blocks/HorizontalRuleBlock.svelte.d.ts +6 -0
  55. package/dist/components/document/blocks/IframeBlock.svelte +32 -0
  56. package/dist/components/document/blocks/IframeBlock.svelte.d.ts +10 -0
  57. package/dist/components/document/blocks/ImageBlock.svelte +55 -0
  58. package/dist/components/document/blocks/ImageBlock.svelte.d.ts +25 -0
  59. package/dist/components/document/blocks/MathBlock.svelte +34 -0
  60. package/dist/components/document/blocks/MathBlock.svelte.d.ts +10 -0
  61. package/dist/components/document/blocks/PageBlock.svelte +66 -0
  62. package/dist/components/document/blocks/PageBlock.svelte.d.ts +10 -0
  63. package/dist/components/document/blocks/PollBlock.svelte +122 -0
  64. package/dist/components/document/blocks/PollBlock.svelte.d.ts +27 -0
  65. package/dist/components/document/blocks/TextBlock.svelte +26 -0
  66. package/dist/components/document/blocks/TextBlock.svelte.d.ts +11 -0
  67. package/dist/components/document/blocks/UnorderedListBlock.svelte +71 -0
  68. package/dist/components/document/blocks/UnorderedListBlock.svelte.d.ts +9 -0
  69. package/dist/components/document/blocks/WebsiteBlock.svelte +81 -0
  70. package/dist/components/document/blocks/WebsiteBlock.svelte.d.ts +21 -0
  71. package/dist/components/index.d.ts +11 -0
  72. package/dist/components/index.js +13 -0
  73. package/dist/config/env.d.ts +11 -0
  74. package/dist/config/env.js +26 -0
  75. package/dist/index.d.ts +20 -0
  76. package/dist/index.js +23 -0
  77. package/dist/publisher.d.ts +193 -0
  78. package/dist/publisher.js +349 -0
  79. package/dist/schemas.d.ts +626 -0
  80. package/dist/schemas.js +113 -0
  81. package/dist/stores/index.d.ts +1 -0
  82. package/dist/stores/index.js +1 -0
  83. package/dist/stores/theme.d.ts +11 -0
  84. package/dist/stores/theme.js +67 -0
  85. package/dist/styles/base.css +188 -0
  86. package/dist/styles/themes.css +5 -0
  87. package/dist/types.d.ts +106 -0
  88. package/dist/types.js +4 -0
  89. package/dist/utils/agents.d.ts +35 -0
  90. package/dist/utils/agents.js +96 -0
  91. package/dist/utils/at-uri.d.ts +50 -0
  92. package/dist/utils/at-uri.js +71 -0
  93. package/dist/utils/cache.d.ts +14 -0
  94. package/dist/utils/cache.js +33 -0
  95. package/dist/utils/comments.d.ts +61 -0
  96. package/dist/utils/comments.js +159 -0
  97. package/dist/utils/content.d.ts +94 -0
  98. package/dist/utils/content.js +178 -0
  99. package/dist/utils/document.d.ts +23 -0
  100. package/dist/utils/document.js +33 -0
  101. package/dist/utils/theme-helpers.d.ts +34 -0
  102. package/dist/utils/theme-helpers.js +63 -0
  103. package/dist/utils/theme.d.ts +18 -0
  104. package/dist/utils/theme.js +24 -0
  105. package/dist/utils/verification.d.ts +129 -0
  106. package/dist/utils/verification.js +157 -0
  107. package/package.json +139 -0
  108. package/src/lib/__tests__/content.test.ts +155 -0
  109. package/src/lib/client.ts +368 -0
  110. package/src/lib/components/Comments.svelte +277 -0
  111. package/src/lib/components/DocumentCard.svelte +95 -0
  112. package/src/lib/components/PublicationCard.svelte +54 -0
  113. package/src/lib/components/StandardSiteLayout.svelte +102 -0
  114. package/src/lib/components/ThemeToggle.svelte +55 -0
  115. package/src/lib/components/common/DateDisplay.svelte +38 -0
  116. package/src/lib/components/common/TagList.svelte +31 -0
  117. package/src/lib/components/common/ThemedCard.svelte +65 -0
  118. package/src/lib/components/common/ThemedContainer.svelte +55 -0
  119. package/src/lib/components/common/ThemedText.svelte +75 -0
  120. package/src/lib/components/document/BlockRenderer.svelte +67 -0
  121. package/src/lib/components/document/CanvasRenderer.svelte +41 -0
  122. package/src/lib/components/document/DocumentRenderer.svelte +68 -0
  123. package/src/lib/components/document/InlineMath.svelte +41 -0
  124. package/src/lib/components/document/LeafletContentRenderer.svelte +64 -0
  125. package/src/lib/components/document/LinearDocumentRenderer.svelte +45 -0
  126. package/src/lib/components/document/MarkdownRenderer.svelte +62 -0
  127. package/src/lib/components/document/RichText.svelte +272 -0
  128. package/src/lib/components/document/blocks/BlockquoteBlock.svelte +29 -0
  129. package/src/lib/components/document/blocks/BskyPostBlock.svelte +202 -0
  130. package/src/lib/components/document/blocks/ButtonBlock.svelte +24 -0
  131. package/src/lib/components/document/blocks/CodeBlock.svelte +68 -0
  132. package/src/lib/components/document/blocks/HeaderBlock.svelte +56 -0
  133. package/src/lib/components/document/blocks/HorizontalRuleBlock.svelte +14 -0
  134. package/src/lib/components/document/blocks/IframeBlock.svelte +32 -0
  135. package/src/lib/components/document/blocks/ImageBlock.svelte +55 -0
  136. package/src/lib/components/document/blocks/MathBlock.svelte +34 -0
  137. package/src/lib/components/document/blocks/PageBlock.svelte +66 -0
  138. package/src/lib/components/document/blocks/PollBlock.svelte +122 -0
  139. package/src/lib/components/document/blocks/TextBlock.svelte +26 -0
  140. package/src/lib/components/document/blocks/UnorderedListBlock.svelte +71 -0
  141. package/src/lib/components/document/blocks/WebsiteBlock.svelte +81 -0
  142. package/src/lib/components/index.ts +15 -0
  143. package/src/lib/config/env.ts +31 -0
  144. package/src/lib/index.ts +104 -0
  145. package/src/lib/publisher.ts +489 -0
  146. package/src/lib/schemas.ts +137 -0
  147. package/src/lib/stores/index.ts +1 -0
  148. package/src/lib/stores/theme.ts +80 -0
  149. package/src/lib/styles/base.css +188 -0
  150. package/src/lib/styles/themes.css +5 -0
  151. package/src/lib/types.ts +116 -0
  152. package/src/lib/utils/agents.ts +124 -0
  153. package/src/lib/utils/at-uri.ts +89 -0
  154. package/src/lib/utils/cache.ts +46 -0
  155. package/src/lib/utils/comments.ts +217 -0
  156. package/src/lib/utils/content.ts +234 -0
  157. package/src/lib/utils/document.ts +41 -0
  158. package/src/lib/utils/theme-helpers.ts +87 -0
  159. package/src/lib/utils/theme.ts +33 -0
  160. package/src/lib/utils/verification.ts +180 -0
@@ -0,0 +1,34 @@
1
+ import type { BasicTheme } from '../types.js';
2
+ /**
3
+ * Generate color-mix CSS for theme colors with transparency
4
+ */
5
+ export declare function mixThemeColor(variable: string, opacity: number, fallback?: string): string;
6
+ /**
7
+ * Get theme-aware color styles for text
8
+ */
9
+ export declare function getThemedTextColor(hasTheme: boolean, opacity?: number): {
10
+ color?: string;
11
+ };
12
+ /**
13
+ * Get theme-aware background color
14
+ */
15
+ export declare function getThemedBackground(hasTheme: boolean, opacity?: number): {
16
+ backgroundColor?: string;
17
+ };
18
+ /**
19
+ * Get theme-aware border color
20
+ */
21
+ export declare function getThemedBorder(hasTheme: boolean, opacity?: number): {
22
+ borderColor?: string;
23
+ };
24
+ /**
25
+ * Get theme-aware accent color
26
+ */
27
+ export declare function getThemedAccent(hasTheme: boolean, opacity?: number): {
28
+ color?: string;
29
+ backgroundColor?: string;
30
+ };
31
+ /**
32
+ * Convert BasicTheme to CSS custom properties
33
+ */
34
+ export declare function themeToCssVars(theme?: BasicTheme): Record<string, string>;
@@ -0,0 +1,63 @@
1
+ import { rgbToCSS } from './theme.js';
2
+ /**
3
+ * Generate color-mix CSS for theme colors with transparency
4
+ */
5
+ export function mixThemeColor(variable, opacity, fallback = 'transparent') {
6
+ return `color-mix(in srgb, var(${variable}) ${opacity}%, ${fallback})`;
7
+ }
8
+ /**
9
+ * Get theme-aware color styles for text
10
+ */
11
+ export function getThemedTextColor(hasTheme, opacity = 100) {
12
+ if (!hasTheme)
13
+ return {};
14
+ return opacity === 100
15
+ ? { color: 'var(--theme-foreground)' }
16
+ : { color: mixThemeColor('--theme-foreground', opacity) };
17
+ }
18
+ /**
19
+ * Get theme-aware background color
20
+ */
21
+ export function getThemedBackground(hasTheme, opacity) {
22
+ if (!hasTheme)
23
+ return {};
24
+ if (opacity === undefined) {
25
+ return { backgroundColor: 'var(--theme-background)' };
26
+ }
27
+ return { backgroundColor: mixThemeColor('--theme-background', opacity) };
28
+ }
29
+ /**
30
+ * Get theme-aware border color
31
+ */
32
+ export function getThemedBorder(hasTheme, opacity = 20) {
33
+ if (!hasTheme)
34
+ return {};
35
+ return { borderColor: mixThemeColor('--theme-foreground', opacity) };
36
+ }
37
+ /**
38
+ * Get theme-aware accent color
39
+ */
40
+ export function getThemedAccent(hasTheme, opacity) {
41
+ if (!hasTheme)
42
+ return {};
43
+ if (opacity === undefined) {
44
+ return { color: 'var(--theme-accent)' };
45
+ }
46
+ return {
47
+ backgroundColor: mixThemeColor('--theme-accent', opacity),
48
+ color: 'var(--theme-accent)'
49
+ };
50
+ }
51
+ /**
52
+ * Convert BasicTheme to CSS custom properties
53
+ */
54
+ export function themeToCssVars(theme) {
55
+ if (!theme)
56
+ return {};
57
+ return {
58
+ '--theme-background': rgbToCSS(theme.background),
59
+ '--theme-foreground': rgbToCSS(theme.foreground),
60
+ '--theme-accent': rgbToCSS(theme.accent),
61
+ '--theme-accent-foreground': rgbToCSS(theme.accentForeground)
62
+ };
63
+ }
@@ -0,0 +1,18 @@
1
+ import type { RGBColor } from '../types.js';
2
+ /**
3
+ * Convert RGB color object to CSS rgb() string
4
+ */
5
+ export declare function rgbToCSS(color: RGBColor): string;
6
+ /**
7
+ * Convert RGB color object to hex string
8
+ */
9
+ export declare function rgbToHex(color: RGBColor): string;
10
+ /**
11
+ * Get theme CSS variables from BasicTheme
12
+ */
13
+ export declare function getThemeVars(theme: {
14
+ background: RGBColor;
15
+ foreground: RGBColor;
16
+ accent: RGBColor;
17
+ accentForeground: RGBColor;
18
+ }): Record<string, string>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Convert RGB color object to CSS rgb() string
3
+ */
4
+ export function rgbToCSS(color) {
5
+ return `rgb(${color.r}, ${color.g}, ${color.b})`;
6
+ }
7
+ /**
8
+ * Convert RGB color object to hex string
9
+ */
10
+ export function rgbToHex(color) {
11
+ const toHex = (n) => n.toString(16).padStart(2, '0');
12
+ return `#${toHex(color.r)}${toHex(color.g)}${toHex(color.b)}`;
13
+ }
14
+ /**
15
+ * Get theme CSS variables from BasicTheme
16
+ */
17
+ export function getThemeVars(theme) {
18
+ return {
19
+ '--theme-background': rgbToCSS(theme.background),
20
+ '--theme-foreground': rgbToCSS(theme.foreground),
21
+ '--theme-accent': rgbToCSS(theme.accent),
22
+ '--theme-accent-foreground': rgbToCSS(theme.accentForeground)
23
+ };
24
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Verification utilities for proving content ownership
3
+ *
4
+ * Creates `.well-known` endpoints and `<link>` tags to verify that
5
+ * you own the content published to ATProto.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // SvelteKit endpoint: src/routes/.well-known/site.standard.publication/+server.ts
10
+ * import { generatePublicationWellKnown } from 'svelte-standard-site/verification';
11
+ * import { text } from '@sveltejs/kit';
12
+ *
13
+ * export function GET() {
14
+ * return text(
15
+ * generatePublicationWellKnown({
16
+ * did: 'did:plc:xxx',
17
+ * publicationRkey: '3abc123xyz',
18
+ * })
19
+ * );
20
+ * }
21
+ * ```
22
+ */
23
+ /**
24
+ * Parse an AT-URI to extract its components
25
+ */
26
+ export declare function parseAtUri(uri: string): {
27
+ did: string;
28
+ collection: string;
29
+ rkey: string;
30
+ } | null;
31
+ /**
32
+ * Build an AT-URI for a document
33
+ */
34
+ export declare function getDocumentAtUri(did: string, rkey: string): string;
35
+ /**
36
+ * Build an AT-URI for a publication
37
+ */
38
+ export declare function getPublicationAtUri(did: string, rkey: string): string;
39
+ /**
40
+ * Generate content for /.well-known/site.standard.publication endpoint
41
+ *
42
+ * This endpoint proves you own your publication record on ATProto.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * // src/routes/.well-known/site.standard.publication/+server.ts
47
+ * import { generatePublicationWellKnown } from 'svelte-standard-site/verification';
48
+ * import { text } from '@sveltejs/kit';
49
+ *
50
+ * export function GET() {
51
+ * return text(
52
+ * generatePublicationWellKnown({
53
+ * did: 'did:plc:xxx',
54
+ * publicationRkey: '3abc123xyz',
55
+ * })
56
+ * );
57
+ * }
58
+ * ```
59
+ */
60
+ export declare function generatePublicationWellKnown(options: {
61
+ did: string;
62
+ publicationRkey: string;
63
+ }): string;
64
+ /**
65
+ * Generate a <link> tag for document verification
66
+ *
67
+ * Add this to your document's <head> to verify ownership.
68
+ *
69
+ * @example
70
+ * ```svelte
71
+ * <svelte:head>
72
+ * {@html generateDocumentLinkTag({
73
+ * did: 'did:plc:xxx',
74
+ * documentRkey: '3xyz789abc',
75
+ * })}
76
+ * </svelte:head>
77
+ * ```
78
+ */
79
+ export declare function generateDocumentLinkTag(options: {
80
+ did: string;
81
+ documentRkey: string;
82
+ }): string;
83
+ /**
84
+ * Generate a <link> tag for publication verification
85
+ *
86
+ * Add this to your site's <head> to verify publication ownership.
87
+ *
88
+ * @example
89
+ * ```svelte
90
+ * <svelte:head>
91
+ * {@html generatePublicationLinkTag({
92
+ * did: 'did:plc:xxx',
93
+ * publicationRkey: '3abc123xyz',
94
+ * })}
95
+ * </svelte:head>
96
+ * ```
97
+ */
98
+ export declare function generatePublicationLinkTag(options: {
99
+ did: string;
100
+ publicationRkey: string;
101
+ }): string;
102
+ /**
103
+ * Verify that a well-known endpoint returns the expected AT-URI
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const isValid = await verifyPublicationWellKnown(
108
+ * 'https://yourblog.com',
109
+ * 'did:plc:xxx',
110
+ * '3abc123xyz'
111
+ * );
112
+ * ```
113
+ */
114
+ export declare function verifyPublicationWellKnown(siteUrl: string, did: string, publicationRkey: string): Promise<boolean>;
115
+ /**
116
+ * Extract AT-URI from a <link> tag in HTML
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * const html = '<link rel="site.standard.document" href="at://did:plc:xxx/site.standard.document/3xyz">';
121
+ * const uri = extractDocumentLinkFromHtml(html);
122
+ * // => 'at://did:plc:xxx/site.standard.document/3xyz'
123
+ * ```
124
+ */
125
+ export declare function extractDocumentLinkFromHtml(html: string): string | null;
126
+ /**
127
+ * Extract publication AT-URI from a <link> tag in HTML
128
+ */
129
+ export declare function extractPublicationLinkFromHtml(html: string): string | null;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Verification utilities for proving content ownership
3
+ *
4
+ * Creates `.well-known` endpoints and `<link>` tags to verify that
5
+ * you own the content published to ATProto.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // SvelteKit endpoint: src/routes/.well-known/site.standard.publication/+server.ts
10
+ * import { generatePublicationWellKnown } from 'svelte-standard-site/verification';
11
+ * import { text } from '@sveltejs/kit';
12
+ *
13
+ * export function GET() {
14
+ * return text(
15
+ * generatePublicationWellKnown({
16
+ * did: 'did:plc:xxx',
17
+ * publicationRkey: '3abc123xyz',
18
+ * })
19
+ * );
20
+ * }
21
+ * ```
22
+ */
23
+ /**
24
+ * Parse an AT-URI to extract its components
25
+ */
26
+ export function parseAtUri(uri) {
27
+ const match = uri.match(/^at:\/\/([^/]+)\/([^/]+)\/(.+)$/);
28
+ if (!match)
29
+ return null;
30
+ return {
31
+ did: match[1],
32
+ collection: match[2],
33
+ rkey: match[3]
34
+ };
35
+ }
36
+ /**
37
+ * Build an AT-URI for a document
38
+ */
39
+ export function getDocumentAtUri(did, rkey) {
40
+ return `at://${did}/site.standard.document/${rkey}`;
41
+ }
42
+ /**
43
+ * Build an AT-URI for a publication
44
+ */
45
+ export function getPublicationAtUri(did, rkey) {
46
+ return `at://${did}/site.standard.publication/${rkey}`;
47
+ }
48
+ /**
49
+ * Generate content for /.well-known/site.standard.publication endpoint
50
+ *
51
+ * This endpoint proves you own your publication record on ATProto.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * // src/routes/.well-known/site.standard.publication/+server.ts
56
+ * import { generatePublicationWellKnown } from 'svelte-standard-site/verification';
57
+ * import { text } from '@sveltejs/kit';
58
+ *
59
+ * export function GET() {
60
+ * return text(
61
+ * generatePublicationWellKnown({
62
+ * did: 'did:plc:xxx',
63
+ * publicationRkey: '3abc123xyz',
64
+ * })
65
+ * );
66
+ * }
67
+ * ```
68
+ */
69
+ export function generatePublicationWellKnown(options) {
70
+ return getPublicationAtUri(options.did, options.publicationRkey);
71
+ }
72
+ /**
73
+ * Generate a <link> tag for document verification
74
+ *
75
+ * Add this to your document's <head> to verify ownership.
76
+ *
77
+ * @example
78
+ * ```svelte
79
+ * <svelte:head>
80
+ * {@html generateDocumentLinkTag({
81
+ * did: 'did:plc:xxx',
82
+ * documentRkey: '3xyz789abc',
83
+ * })}
84
+ * </svelte:head>
85
+ * ```
86
+ */
87
+ export function generateDocumentLinkTag(options) {
88
+ const atUri = getDocumentAtUri(options.did, options.documentRkey);
89
+ return `<link rel="site.standard.document" href="${atUri}">`;
90
+ }
91
+ /**
92
+ * Generate a <link> tag for publication verification
93
+ *
94
+ * Add this to your site's <head> to verify publication ownership.
95
+ *
96
+ * @example
97
+ * ```svelte
98
+ * <svelte:head>
99
+ * {@html generatePublicationLinkTag({
100
+ * did: 'did:plc:xxx',
101
+ * publicationRkey: '3abc123xyz',
102
+ * })}
103
+ * </svelte:head>
104
+ * ```
105
+ */
106
+ export function generatePublicationLinkTag(options) {
107
+ const atUri = getPublicationAtUri(options.did, options.publicationRkey);
108
+ return `<link rel="site.standard.publication" href="${atUri}">`;
109
+ }
110
+ /**
111
+ * Verify that a well-known endpoint returns the expected AT-URI
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const isValid = await verifyPublicationWellKnown(
116
+ * 'https://yourblog.com',
117
+ * 'did:plc:xxx',
118
+ * '3abc123xyz'
119
+ * );
120
+ * ```
121
+ */
122
+ export async function verifyPublicationWellKnown(siteUrl, did, publicationRkey) {
123
+ try {
124
+ const cleanUrl = siteUrl.replace(/\/$/, '');
125
+ const response = await fetch(`${cleanUrl}/.well-known/site.standard.publication`);
126
+ if (!response.ok)
127
+ return false;
128
+ const content = await response.text();
129
+ const expectedUri = getPublicationAtUri(did, publicationRkey);
130
+ return content.trim() === expectedUri;
131
+ }
132
+ catch (error) {
133
+ console.error('Failed to verify publication well-known:', error);
134
+ return false;
135
+ }
136
+ }
137
+ /**
138
+ * Extract AT-URI from a <link> tag in HTML
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * const html = '<link rel="site.standard.document" href="at://did:plc:xxx/site.standard.document/3xyz">';
143
+ * const uri = extractDocumentLinkFromHtml(html);
144
+ * // => 'at://did:plc:xxx/site.standard.document/3xyz'
145
+ * ```
146
+ */
147
+ export function extractDocumentLinkFromHtml(html) {
148
+ const match = html.match(/<link\s+rel="site\.standard\.document"\s+href="(at:\/\/[^"]+)"\s*\/?>/i);
149
+ return match ? match[1] : null;
150
+ }
151
+ /**
152
+ * Extract publication AT-URI from a <link> tag in HTML
153
+ */
154
+ export function extractPublicationLinkFromHtml(html) {
155
+ const match = html.match(/<link\s+rel="site\.standard\.publication"\s+href="(at:\/\/[^"]+)"\s*\/?>/i);
156
+ return match ? match[1] : null;
157
+ }
package/package.json ADDED
@@ -0,0 +1,139 @@
1
+ {
2
+ "name": "@ewanc26/svelte-standard-site",
3
+ "version": "0.2.0",
4
+ "description": "SvelteKit library for reading and writing AT Protocol longform content via site.standard.* records — with a complete design system, federated comments, publishing tools, and content verification.",
5
+ "license": "AGPL-3.0-only",
6
+ "author": {
7
+ "name": "Ewan Croft",
8
+ "url": "https://github.com/ewanc26"
9
+ },
10
+ "type": "module",
11
+ "svelte": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "svelte": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./publisher": {
20
+ "types": "./dist/publisher.d.ts",
21
+ "default": "./dist/publisher.js"
22
+ },
23
+ "./content": {
24
+ "types": "./dist/utils/content.d.ts",
25
+ "default": "./dist/utils/content.js"
26
+ },
27
+ "./comments": {
28
+ "types": "./dist/utils/comments.d.ts",
29
+ "default": "./dist/utils/comments.js"
30
+ },
31
+ "./verification": {
32
+ "types": "./dist/utils/verification.d.ts",
33
+ "default": "./dist/utils/verification.js"
34
+ },
35
+ "./schemas": {
36
+ "types": "./dist/schemas.d.ts",
37
+ "default": "./dist/schemas.js"
38
+ },
39
+ "./config/env": {
40
+ "types": "./dist/config/env.d.ts",
41
+ "default": "./dist/config/env.js"
42
+ },
43
+ "./styles/base.css": {
44
+ "default": "./dist/styles/base.css"
45
+ },
46
+ "./styles/themes.css": {
47
+ "default": "./dist/styles/themes.css"
48
+ }
49
+ },
50
+ "files": [
51
+ "dist",
52
+ "src/lib",
53
+ "README.md"
54
+ ],
55
+ "sideEffects": [
56
+ "**/*.css"
57
+ ],
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "peerDependencies": {
62
+ "@sveltejs/kit": "^2.0.0",
63
+ "svelte": "^5.0.0"
64
+ },
65
+ "dependencies": {
66
+ "@atproto/api": "^0.18.16",
67
+ "@lucide/svelte": "^0.562.0",
68
+ "katex": "^0.16.27",
69
+ "rehype-slug": "^6.0.0",
70
+ "rehype-stringify": "^10.0.1",
71
+ "remark-gfm": "^4.0.1",
72
+ "remark-parse": "^11.0.0",
73
+ "remark-rehype": "^11.1.2",
74
+ "shiki": "^3.21.0",
75
+ "unified": "^11.0.5",
76
+ "zod": "^3.24.0",
77
+ "@ewanc26/atproto": "0.2.0",
78
+ "@ewanc26/tid": "1.1.0",
79
+ "@ewanc26/utils": "0.1.0"
80
+ },
81
+ "devDependencies": {
82
+ "@sveltejs/adapter-auto": "^7.0.0",
83
+ "@sveltejs/kit": "^2.49.1",
84
+ "@sveltejs/package": "^2.5.7",
85
+ "@sveltejs/vite-plugin-svelte": "^6.2.1",
86
+ "@tailwindcss/typography": "^0.5.19",
87
+ "@tailwindcss/vite": "^4.1.17",
88
+ "@types/node": "^22.0.0",
89
+ "prettier": "^3.7.4",
90
+ "prettier-plugin-svelte": "^3.4.0",
91
+ "prettier-plugin-tailwindcss": "^0.7.2",
92
+ "publint": "^0.3.15",
93
+ "svelte": "^5.45.6",
94
+ "svelte-check": "^4.3.4",
95
+ "tailwindcss": "^4.1.17",
96
+ "typescript": "^5.9.3",
97
+ "vite": "^7.2.6",
98
+ "vitest": "^4.0.16"
99
+ },
100
+ "keywords": [
101
+ "svelte",
102
+ "sveltekit",
103
+ "atproto",
104
+ "at-protocol",
105
+ "bluesky",
106
+ "site-standard",
107
+ "blog",
108
+ "cms",
109
+ "design-system",
110
+ "components",
111
+ "dark-mode",
112
+ "light-mode",
113
+ "theme",
114
+ "publishing",
115
+ "federation",
116
+ "comments"
117
+ ],
118
+ "repository": {
119
+ "type": "git",
120
+ "url": "git+https://github.com/ewanc26/pkgs.git",
121
+ "directory": "packages/svelte-standard-site"
122
+ },
123
+ "homepage": "https://github.com/ewanc26/pkgs/tree/main/packages/svelte-standard-site",
124
+ "bugs": {
125
+ "url": "https://github.com/ewanc26/pkgs/issues"
126
+ },
127
+ "scripts": {
128
+ "build": "svelte-kit sync && svelte-package -i src/lib -o dist && publint",
129
+ "dev": "svelte-kit sync && svelte-package -i src/lib -o dist --watch",
130
+ "dev:app": "vite dev",
131
+ "preview": "vite preview",
132
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
133
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
134
+ "test": "vitest run",
135
+ "test:watch": "vitest",
136
+ "format": "prettier --write .",
137
+ "lint": "prettier --check ."
138
+ }
139
+ }