@leadertechie/personal-site-kit 0.1.0-alpha.8 → 0.1.0-alpha.9

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 (93) hide show
  1. package/dist/api/content-utils.d.ts +27 -0
  2. package/dist/api/content-utils.d.ts.map +1 -0
  3. package/dist/api/handlers/content-api.d.ts +0 -1
  4. package/dist/api/handlers/content-api.d.ts.map +1 -1
  5. package/dist/api.js +2 -2
  6. package/dist/chunks/{index-CYd_Pe2U.js → index-CnSEOZse.js} +81 -121
  7. package/dist/chunks/{template-D1uGvdWZ.js → template-DWcsZW22.js} +1 -1
  8. package/dist/chunks/{website-api-FLejlWxJ.js → website-api-BEYGOsT3.js} +90 -131
  9. package/dist/index.js +3 -3
  10. package/dist/shared.js +1 -1
  11. package/dist/ui/admin/index.d.ts +8 -0
  12. package/dist/ui/admin/index.d.ts.map +1 -1
  13. package/dist/ui.js +1 -1
  14. package/package.json +4 -4
  15. package/src/api/__tests__/info.test.ts +0 -44
  16. package/src/api/__tests__/utils.test.ts +0 -78
  17. package/src/api/handlers/about-me.ts +0 -109
  18. package/src/api/handlers/auth-handler.ts +0 -204
  19. package/src/api/handlers/auth.ts +0 -157
  20. package/src/api/handlers/content-api.ts +0 -268
  21. package/src/api/handlers/content.ts +0 -139
  22. package/src/api/handlers/home.ts +0 -79
  23. package/src/api/handlers/info.ts +0 -12
  24. package/src/api/handlers/logo.ts +0 -55
  25. package/src/api/handlers/static-details.ts +0 -48
  26. package/src/api/index.ts +0 -9
  27. package/src/api/utils.ts +0 -16
  28. package/src/api/website-api.ts +0 -142
  29. package/src/index.ts +0 -4
  30. package/src/prerender/__tests__/page-content.test.ts +0 -44
  31. package/src/prerender/__tests__/template.test.ts +0 -54
  32. package/src/prerender/data-fetcher.ts +0 -93
  33. package/src/prerender/index.ts +0 -7
  34. package/src/prerender/page-content.ts +0 -266
  35. package/src/prerender/page-generators/about.ts +0 -38
  36. package/src/prerender/page-generators/base.ts +0 -77
  37. package/src/prerender/page-generators/blog-detail.ts +0 -35
  38. package/src/prerender/page-generators/blogs-list.ts +0 -43
  39. package/src/prerender/page-generators/home.ts +0 -54
  40. package/src/prerender/page-generators/index.ts +0 -8
  41. package/src/prerender/page-generators/not-found.ts +0 -36
  42. package/src/prerender/page-generators/stories-list.ts +0 -43
  43. package/src/prerender/page-generators/story-detail.ts +0 -35
  44. package/src/prerender/prerender.ts +0 -25
  45. package/src/prerender/template.ts +0 -65
  46. package/src/prerender/website-prerender.ts +0 -152
  47. package/src/shared/config/api.ts +0 -16
  48. package/src/shared/config/index.ts +0 -43
  49. package/src/shared/config/types.ts +0 -16
  50. package/src/shared/core/__tests__/theme-toggle.test.ts +0 -204
  51. package/src/shared/core/site-store.ts +0 -38
  52. package/src/shared/core/theme-toggle.ts +0 -118
  53. package/src/shared/index.ts +0 -17
  54. package/src/shared/interfaces/ifooter-link.ts +0 -4
  55. package/src/shared/interfaces/iroute.ts +0 -4
  56. package/src/shared/models/theme-variables.css +0 -25
  57. package/src/shared/page-content.ts +0 -210
  58. package/src/shared/router.ts +0 -250
  59. package/src/shared/runtime.ts +0 -11
  60. package/src/shared/template.ts +0 -35
  61. package/src/shared/website-ui.ts +0 -92
  62. package/src/styles/markdown.css +0 -129
  63. package/src/ui/about-me/api.ts +0 -12
  64. package/src/ui/about-me/index.ts +0 -121
  65. package/src/ui/about-me/styles.ts +0 -85
  66. package/src/ui/admin/api.ts +0 -93
  67. package/src/ui/admin/components/AboutMeSection.ts +0 -47
  68. package/src/ui/admin/components/AdminSection.ts +0 -134
  69. package/src/ui/admin/components/BlogsSection.ts +0 -62
  70. package/src/ui/admin/components/HomeSection.ts +0 -47
  71. package/src/ui/admin/components/ImagesSection.ts +0 -54
  72. package/src/ui/admin/components/LoginForm.ts +0 -116
  73. package/src/ui/admin/components/LogoSection.ts +0 -51
  74. package/src/ui/admin/components/ProfileSection.ts +0 -47
  75. package/src/ui/admin/components/StaticSection.ts +0 -67
  76. package/src/ui/admin/components/StoriesSection.ts +0 -62
  77. package/src/ui/admin/components/index.ts +0 -10
  78. package/src/ui/admin/index.ts +0 -413
  79. package/src/ui/admin/styles.ts +0 -270
  80. package/src/ui/admin/types.ts +0 -26
  81. package/src/ui/banner/index.ts +0 -38
  82. package/src/ui/banner/styles.ts +0 -95
  83. package/src/ui/blog-viewer/__tests__/blogviewer.test.ts +0 -7
  84. package/src/ui/blog-viewer/index.ts +0 -127
  85. package/src/ui/blog-viewer/styles.ts +0 -23
  86. package/src/ui/footer/index.ts +0 -37
  87. package/src/ui/footer/styles.ts +0 -50
  88. package/src/ui/index.ts +0 -13
  89. package/src/ui/story-viewer/__tests__/storyviewer.test.ts +0 -7
  90. package/src/ui/story-viewer/index.ts +0 -123
  91. package/src/ui/story-viewer/styles.ts +0 -54
  92. /package/{src/shared → dist}/styles/markdown.css +0 -0
  93. /package/{src → dist}/styles/theme.css +0 -0
@@ -0,0 +1,27 @@
1
+ export interface ContentMetadata {
2
+ slug: string;
3
+ title: string;
4
+ description: string;
5
+ summary?: string;
6
+ date: string;
7
+ imageUrl?: string;
8
+ tags?: string[];
9
+ author?: string;
10
+ }
11
+ export interface BlogPost extends ContentMetadata {
12
+ content: string;
13
+ }
14
+ export interface StoryPost extends ContentMetadata {
15
+ content: string;
16
+ }
17
+ export declare function getCachedOrFetch<T>(key: string, fetchFn: () => Promise<T>): Promise<T>;
18
+ export declare function clearContentCache(prefix?: string): void;
19
+ export declare function parseFrontmatter(content: string): {
20
+ metadata: ContentMetadata;
21
+ content: string;
22
+ };
23
+ export declare function checkContentBucket(env: any): Response | null;
24
+ export declare function fetchContentItem(bucket: any, type: 'blogs' | 'stories', slug: string): Promise<BlogPost | StoryPost>;
25
+ export declare function fetchContentList(bucket: any, type: 'blogs' | 'stories', latest?: number): Promise<ContentMetadata[]>;
26
+ export declare function searchContent(bucket: any, query: string): Promise<(BlogPost | StoryPost)[]>;
27
+ //# sourceMappingURL=content-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-utils.d.ts","sourceRoot":"","sources":["../../src/api/content-utils.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAS,SAAQ,eAAe;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAU,SAAQ,eAAe;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAStF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAUvD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA6BhG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,GAAG,IAAI,CAK5D;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAqB1H;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAiB1H;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CA2BjG"}
@@ -1,5 +1,4 @@
1
1
  export declare function handleBlogs(env?: any, slug?: string, latest?: number): Promise<Response>;
2
2
  export declare function handleStories(env?: any, slug?: string, latest?: number): Promise<Response>;
3
3
  export declare function handleSearch(env?: any, query?: string): Promise<Response>;
4
- export declare function clearContentCache(): void;
5
4
  //# sourceMappingURL=content-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-api.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/content-api.ts"],"names":[],"mappings":"AA8EA,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgE9F;AAED,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8DhG;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuD/E;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
1
+ {"version":3,"file":"content-api.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/content-api.ts"],"names":[],"mappings":"AAcA,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmB9F;AAED,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmBhG;AAED,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkB/E"}
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { W as WebsiteAPI } from "./chunks/website-api-FLejlWxJ.js";
2
- import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-FLejlWxJ.js";
1
+ import { W as WebsiteAPI } from "./chunks/website-api-BEYGOsT3.js";
2
+ import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-BEYGOsT3.js";
3
3
  const defaultAPI = new WebsiteAPI();
4
4
  export {
5
5
  A as AUTH_KV,
@@ -1802,6 +1802,87 @@ class AdminPortal extends (_a$4 = LitElement, _isAuthenticated_dec = [state()],
1802
1802
  handleStatusMessage(message) {
1803
1803
  this.statusMessage = message;
1804
1804
  }
1805
+ renderHomeSection() {
1806
+ return html`
1807
+ <admin-home-section
1808
+ .contentList=${this.contentList}
1809
+ .onUpload=${this.handleUpload.bind(this)}
1810
+ .onDelete=${this.handleDelete.bind(this)}
1811
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1812
+ ></admin-home-section>
1813
+ `;
1814
+ }
1815
+ renderProfileSection() {
1816
+ return html`
1817
+ <admin-profile-section
1818
+ .contentList=${this.contentList}
1819
+ .onUpload=${this.handleUpload.bind(this)}
1820
+ .onDelete=${this.handleDelete.bind(this)}
1821
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1822
+ ></admin-profile-section>
1823
+ `;
1824
+ }
1825
+ renderAboutMeSection() {
1826
+ return html`
1827
+ <admin-about-me-section
1828
+ .contentList=${this.contentList}
1829
+ .onUpload=${this.handleUpload.bind(this)}
1830
+ .onDelete=${this.handleDelete.bind(this)}
1831
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1832
+ ></admin-about-me-section>
1833
+ `;
1834
+ }
1835
+ renderBlogsSection() {
1836
+ return html`
1837
+ <admin-blogs-section
1838
+ .contentList=${this.contentList}
1839
+ .onUpload=${this.handleUpload.bind(this)}
1840
+ .onDelete=${this.handleDelete.bind(this)}
1841
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1842
+ ></admin-blogs-section>
1843
+ `;
1844
+ }
1845
+ renderStoriesSection() {
1846
+ return html`
1847
+ <admin-stories-section
1848
+ .contentList=${this.contentList}
1849
+ .onUpload=${this.handleUpload.bind(this)}
1850
+ .onDelete=${this.handleDelete.bind(this)}
1851
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1852
+ ></admin-stories-section>
1853
+ `;
1854
+ }
1855
+ renderImagesSection() {
1856
+ return html`
1857
+ <admin-images-section
1858
+ .contentList=${this.contentList}
1859
+ .onUpload=${this.handleUpload.bind(this)}
1860
+ .onDelete=${this.handleDelete.bind(this)}
1861
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1862
+ ></admin-images-section>
1863
+ `;
1864
+ }
1865
+ renderLogoSection() {
1866
+ return html`
1867
+ <admin-logo-section
1868
+ .contentList=${this.contentList}
1869
+ .onUpload=${this.handleUpload.bind(this)}
1870
+ .onDelete=${this.handleDelete.bind(this)}
1871
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1872
+ ></admin-logo-section>
1873
+ `;
1874
+ }
1875
+ renderStaticSection() {
1876
+ return html`
1877
+ <admin-static-section
1878
+ .contentList=${this.contentList}
1879
+ .staticDetails=${this.staticDetails}
1880
+ .onUpload=${this.handleUpload.bind(this)}
1881
+ .onDelete=${this.handleDelete.bind(this)}
1882
+ .onStatusMessage=${this.handleStatusMessage.bind(this)}
1883
+ ></admin-static-section>
1884
+ `;
1885
+ }
1805
1886
  renderLoginForm() {
1806
1887
  return html`
1807
1888
  <admin-login-form
@@ -1866,127 +1947,6 @@ class AdminPortal extends (_a$4 = LitElement, _isAuthenticated_dec = [state()],
1866
1947
  </div>
1867
1948
  ` : ""}
1868
1949
 
1869
- ${this.activeSection === "home" ? html`
1870
- <admin-home-section
1871
- .contentList=${this.contentList}
1872
- .onUpload=${this.handleUpload.bind(this)}
1873
- .onDelete=${this.handleDelete.bind(this)}
1874
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1875
- ></admin-home-section>
1876
- ` : ""}
1877
-
1878
- ${this.activeSection === "profile" ? html`
1879
- <admin-profile-section
1880
- .contentList=${this.contentList}
1881
- .onUpload=${this.handleUpload.bind(this)}
1882
- .onDelete=${this.handleDelete.bind(this)}
1883
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1884
- ></admin-profile-section>
1885
- ` : ""}
1886
-
1887
- ${this.activeSection === "aboutme" ? html`
1888
- <admin-about-me-section
1889
- .contentList=${this.contentList}
1890
- .onUpload=${this.handleUpload.bind(this)}
1891
- .onDelete=${this.handleDelete.bind(this)}
1892
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1893
- ></admin-about-me-section>
1894
- ` : ""}
1895
-
1896
- ${this.activeSection === "blogs" ? html`
1897
- <admin-blogs-section
1898
- .contentList=${this.contentList}
1899
- .onUpload=${this.handleUpload.bind(this)}
1900
- .onDelete=${this.handleDelete.bind(this)}
1901
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1902
- ></admin-blogs-section>
1903
- ` : ""}
1904
-
1905
- ${this.activeSection === "stories" ? html`
1906
- <admin-stories-section
1907
- .contentList=${this.contentList}
1908
- .onUpload=${this.handleUpload.bind(this)}
1909
- .onDelete=${this.handleDelete.bind(this)}
1910
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1911
- ></admin-stories-section>
1912
- ` : ""}
1913
-
1914
- ${this.activeSection === "images" ? html`
1915
- <admin-images-section
1916
- .contentList=${this.contentList}
1917
- .onUpload=${this.handleUpload.bind(this)}
1918
- .onDelete=${this.handleDelete.bind(this)}
1919
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1920
- ></admin-images-section>
1921
- ` : ""}
1922
-
1923
- ${this.activeSection === "logo" ? html`
1924
- <admin-logo-section
1925
- .contentList=${this.contentList}
1926
- .onUpload=${this.handleUpload.bind(this)}
1927
- .onDelete=${this.handleDelete.bind(this)}
1928
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1929
- ></admin-logo-section>
1930
- ` : ""}
1931
-
1932
- ${this.activeSection === "static" ? html`
1933
- <admin-static-section
1934
- .contentList=${this.contentList}
1935
- .staticDetails=${this.staticDetails}
1936
- .onUpload=${this.handleUpload.bind(this)}
1937
- .onDelete=${this.handleDelete.bind(this)}
1938
- .onStatusMessage=${this.handleStatusMessage.bind(this)}
1939
- ></admin-static-section>
1940
- ` : ""}
1941
- </div>
1942
- `;
1943
- }
1944
- render() {
1945
- if (this.isLoading) {
1946
- return html`<div class="container"><div class="loading">Loading...</div></div>`;
1947
- }
1948
- if (!this.isSetup) {
1949
- return this.renderLoginForm();
1950
- }
1951
- if (!this.isAuthenticated) {
1952
- return this.renderLogin();
1953
- }
1954
- return html`
1955
- <div class="container">
1956
- <div class="header">
1957
- <h1>Content Manager</h1>
1958
- <button class="btn-secondary" @click=${() => this.handleLogout()}>Logout</button>
1959
- <button class="btn-secondary" @click=${() => this.handleClearCache()}>Clear Cache</button>
1960
- </div>
1961
-
1962
- <div class="nav-tabs">
1963
- <button class="nav-tab ${this.activeSection === "home" ? "active" : ""}"
1964
- @click=${() => this.activeSection = "home"}>Home</button>
1965
- <button class="nav-tab ${this.activeSection === "profile" ? "active" : ""}"
1966
- @click=${() => this.activeSection = "profile"}>Profile</button>
1967
- <button class="nav-tab ${this.activeSection === "aboutme" ? "active" : ""}"
1968
- @click=${() => this.activeSection = "aboutme"}>About Me</button>
1969
- <button class="nav-tab ${this.activeSection === "blogs" ? "active" : ""}"
1970
- @click=${() => this.activeSection = "blogs"}>Blogs</button>
1971
- <button class="nav-tab ${this.activeSection === "stories" ? "active" : ""}"
1972
- @click=${() => this.activeSection = "stories"}>Stories</button>
1973
- <button class="nav-tab ${this.activeSection === "images" ? "active" : ""}"
1974
- @click=${() => this.activeSection = "images"}>Images</button>
1975
- <button class="nav-tab ${this.activeSection === "logo" ? "active" : ""}"
1976
- @click=${() => this.activeSection = "logo"}>Logo</button>
1977
- <button class="nav-tab ${this.activeSection === "static" ? "active" : ""}"
1978
- @click=${() => {
1979
- this.activeSection = "static";
1980
- this.fetchStaticDetails();
1981
- }}>Site Settings</button>
1982
- </div>
1983
-
1984
- ${this.statusMessage ? html`
1985
- <div class="status-message ${this.statusMessage.includes("successful") || this.statusMessage.includes("cleared") ? "success" : this.statusMessage.includes("failed") || this.statusMessage.includes("Error") ? "error" : ""}">
1986
- ${this.statusMessage}
1987
- </div>
1988
- ` : ""}
1989
-
1990
1950
  ${this.activeSection === "home" ? this.renderHomeSection() : ""}
1991
1951
  ${this.activeSection === "profile" ? this.renderProfileSection() : ""}
1992
1952
  ${this.activeSection === "aboutme" ? this.renderAboutMeSection() : ""}
@@ -2,7 +2,7 @@ import { MarkdownPipeline } from "@leadertechie/md2html";
2
2
  const __vite_import_meta_env__ = {};
3
3
  const DEFAULT_INFRA = {
4
4
  baseUrl: typeof window !== "undefined" ? window.location.origin : "http://localhost:5173",
5
- apiUrl: typeof window !== "undefined" && (window.__VITE_API_URL__ || __vite_import_meta_env__?.VITE_API_URL) || "http://localhost:8788"
5
+ apiUrl: typeof window !== "undefined" && (window.__VITE_API_URL__ || __vite_import_meta_env__?.VITE_API_URL) || (typeof window !== "undefined" ? window.location.origin : "http://localhost:8787")
6
6
  };
7
7
  const DEFAULT_STATIC = {
8
8
  siteTitle: "My Personal Website",
@@ -532,14 +532,15 @@ async function handleLogout(request, env) {
532
532
  }
533
533
  const contentCache = /* @__PURE__ */ new Map();
534
534
  const CACHE_TTL = 5 * 60 * 1e3;
535
- async function getCachedOrFetch(key, fetchFn) {
535
+ function getCachedOrFetch(key, fetchFn) {
536
536
  const cached = contentCache.get(key);
537
537
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
538
- return cached.data;
538
+ return Promise.resolve(cached.data);
539
539
  }
540
- const data = await fetchFn();
541
- contentCache.set(key, { data, timestamp: Date.now() });
542
- return data;
540
+ return fetchFn().then((data) => {
541
+ contentCache.set(key, { data, timestamp: Date.now() });
542
+ return data;
543
+ });
543
544
  }
544
545
  function parseFrontmatter(content) {
545
546
  const lines = content.split("\n");
@@ -569,159 +570,117 @@ function parseFrontmatter(content) {
569
570
  content: lines.slice(contentStart).join("\n").trim()
570
571
  };
571
572
  }
573
+ function checkContentBucket(env) {
574
+ if (!env?.CONTENT_BUCKET) {
575
+ return createErrorResponse("Content bucket not configured", 500);
576
+ }
577
+ return null;
578
+ }
579
+ async function fetchContentItem(bucket, type, slug) {
580
+ const mdObj = await bucket.get(`${type}/${slug}.md`);
581
+ const jsonObj = await bucket.get(`${type}/${slug}.json`);
582
+ if (!mdObj && !jsonObj) throw new Error(`${type.slice(0, -1)} not found`);
583
+ let metadata = {};
584
+ if (jsonObj) {
585
+ metadata = await jsonObj.json();
586
+ }
587
+ let content = "";
588
+ if (mdObj) {
589
+ const text = await mdObj.text();
590
+ const parsed = parseFrontmatter(text);
591
+ content = parsed.content;
592
+ metadata = { ...parsed.metadata, ...metadata };
593
+ }
594
+ return { ...metadata, slug, content };
595
+ }
596
+ async function fetchContentList(bucket, type, latest) {
597
+ const list = await bucket.list({ prefix: `${type}/` });
598
+ const items = [];
599
+ for (const item of list.objects) {
600
+ if (item.key.endsWith(".json")) {
601
+ const obj = await bucket.get(item.key);
602
+ if (obj) {
603
+ const metadata = await obj.json();
604
+ const slug = item.key.replace(`${type}/`, "").replace(".json", "");
605
+ items.push({ ...metadata, slug });
606
+ }
607
+ }
608
+ }
609
+ const sorted = items.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
610
+ return latest ? sorted.slice(0, latest) : sorted;
611
+ }
612
+ async function searchContent(bucket, query) {
613
+ const q = query.toLowerCase();
614
+ const results = [];
615
+ const [blogsList, storiesList] = await Promise.all([
616
+ bucket.list({ prefix: "blogs/" }),
617
+ bucket.list({ prefix: "stories/" })
618
+ ]);
619
+ for (const item of [...blogsList.objects, ...storiesList.objects]) {
620
+ if (item.key.endsWith(".md")) {
621
+ const obj = await bucket.get(item.key);
622
+ if (obj) {
623
+ const text = await obj.text();
624
+ const { metadata } = parseFrontmatter(text);
625
+ const matchTitle = metadata.title?.toLowerCase().includes(q);
626
+ const matchDesc = metadata.description?.toLowerCase().includes(q);
627
+ const matchTags = metadata.tags?.some((t) => t.toLowerCase().includes(q));
628
+ if (matchTitle || matchDesc || matchTags) {
629
+ results.push(metadata);
630
+ }
631
+ }
632
+ }
633
+ }
634
+ return results;
635
+ }
572
636
  async function handleBlogs(env, slug, latest) {
637
+ const bucketCheck = checkContentBucket(env);
638
+ if (bucketCheck) return bucketCheck;
573
639
  try {
574
- if (!env?.CONTENT_BUCKET) {
575
- return new Response(JSON.stringify({ error: "Content bucket not configured" }), {
576
- status: 500,
577
- headers: { "Content-Type": "application/json" }
578
- });
579
- }
580
640
  const cacheKey = slug ? `blog-${slug}` : `blogs-list-${latest || "all"}`;
581
641
  const result = await getCachedOrFetch(cacheKey, async () => {
582
642
  if (slug) {
583
- const mdObj = await env.CONTENT_BUCKET.get(`blogs/${slug}.md`);
584
- const jsonObj = await env.CONTENT_BUCKET.get(`blogs/${slug}.json`);
585
- if (!mdObj && !jsonObj) throw new Error("Blog not found");
586
- let metadata = {};
587
- if (jsonObj) {
588
- metadata = await jsonObj.json();
589
- }
590
- let content = "";
591
- if (mdObj) {
592
- const text = await mdObj.text();
593
- const parsed = parseFrontmatter(text);
594
- content = parsed.content;
595
- metadata = { ...parsed.metadata, ...metadata };
596
- }
597
- return { ...metadata, slug, content };
643
+ return await fetchContentItem(env.CONTENT_BUCKET, "blogs", slug);
598
644
  }
599
- const list = await env.CONTENT_BUCKET.list({ prefix: "blogs/" });
600
- const blogs = [];
601
- for (const item of list.objects) {
602
- if (item.key.endsWith(".json")) {
603
- const obj = await env.CONTENT_BUCKET.get(item.key);
604
- if (obj) {
605
- const metadata = await obj.json();
606
- const slug2 = item.key.replace("blogs/", "").replace(".json", "");
607
- blogs.push({ ...metadata, slug: slug2 });
608
- }
609
- }
610
- }
611
- const sorted = blogs.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
612
- return latest ? sorted.slice(0, latest) : sorted;
613
- });
614
- return new Response(JSON.stringify(result), {
615
- headers: { "Content-Type": "application/json" }
645
+ return await fetchContentList(env.CONTENT_BUCKET, "blogs", latest);
616
646
  });
647
+ return createJSONResponse(result);
617
648
  } catch (error) {
618
649
  console.error("Error serving blogs:", error);
619
- return new Response(JSON.stringify({ error: "Blog not found" }), {
620
- status: 404,
621
- headers: { "Content-Type": "application/json" }
622
- });
650
+ return createErrorResponse("Blog not found", 404);
623
651
  }
624
652
  }
625
653
  async function handleStories(env, slug, latest) {
654
+ const bucketCheck = checkContentBucket(env);
655
+ if (bucketCheck) return bucketCheck;
626
656
  try {
627
- if (!env?.CONTENT_BUCKET) {
628
- return new Response(JSON.stringify({ error: "Content bucket not configured" }), {
629
- status: 500,
630
- headers: { "Content-Type": "application/json" }
631
- });
632
- }
633
657
  const cacheKey = slug ? `story-${slug}` : `stories-list-${latest || "all"}`;
634
658
  const result = await getCachedOrFetch(cacheKey, async () => {
635
659
  if (slug) {
636
- const mdObj = await env.CONTENT_BUCKET.get(`stories/${slug}.md`);
637
- const jsonObj = await env.CONTENT_BUCKET.get(`stories/${slug}.json`);
638
- if (!mdObj && !jsonObj) throw new Error("Story not found");
639
- let metadata = {};
640
- if (jsonObj) {
641
- metadata = await jsonObj.json();
642
- }
643
- let content = "";
644
- if (mdObj) {
645
- const text = await mdObj.text();
646
- const parsed = parseFrontmatter(text);
647
- content = parsed.content;
648
- metadata = { ...parsed.metadata, ...metadata };
649
- }
650
- return { ...metadata, slug, content };
660
+ return await fetchContentItem(env.CONTENT_BUCKET, "stories", slug);
651
661
  }
652
- const list = await env.CONTENT_BUCKET.list({ prefix: "stories/" });
653
- const stories = [];
654
- for (const item of list.objects) {
655
- if (item.key.endsWith(".json")) {
656
- const obj = await env.CONTENT_BUCKET.get(item.key);
657
- if (obj) {
658
- const metadata = await obj.json();
659
- const slug2 = item.key.replace("stories/", "").replace(".json", "");
660
- stories.push({ ...metadata, slug: slug2 });
661
- }
662
- }
663
- }
664
- const sorted = stories.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
665
- return latest ? sorted.slice(0, latest) : sorted;
666
- });
667
- return new Response(JSON.stringify(result), {
668
- headers: { "Content-Type": "application/json" }
662
+ return await fetchContentList(env.CONTENT_BUCKET, "stories", latest);
669
663
  });
664
+ return createJSONResponse(result);
670
665
  } catch (error) {
671
666
  console.error("Error serving stories:", error);
672
- return new Response(JSON.stringify({ error: "Story not found" }), {
673
- status: 404,
674
- headers: { "Content-Type": "application/json" }
675
- });
667
+ return createErrorResponse("Story not found", 404);
676
668
  }
677
669
  }
678
670
  async function handleSearch(env, query) {
671
+ const bucketCheck = checkContentBucket(env);
672
+ if (bucketCheck) return bucketCheck;
673
+ if (!query) {
674
+ return createErrorResponse("Search query required", 400);
675
+ }
679
676
  try {
680
- if (!env?.CONTENT_BUCKET) {
681
- return new Response(JSON.stringify({ error: "Content bucket not configured" }), {
682
- status: 500,
683
- headers: { "Content-Type": "application/json" }
684
- });
685
- }
686
- if (!query) {
687
- return new Response(JSON.stringify({ error: "Search query required" }), {
688
- status: 400,
689
- headers: { "Content-Type": "application/json" }
690
- });
691
- }
692
677
  const searchResults = await getCachedOrFetch(`search-${query}`, async () => {
693
- const q = query.toLowerCase();
694
- const results = [];
695
- const [blogsList, storiesList] = await Promise.all([
696
- env.CONTENT_BUCKET.list({ prefix: "blogs/" }),
697
- env.CONTENT_BUCKET.list({ prefix: "stories/" })
698
- ]);
699
- for (const item of [...blogsList.objects, ...storiesList.objects]) {
700
- if (item.key.endsWith(".md")) {
701
- const obj = await env.CONTENT_BUCKET.get(item.key);
702
- if (obj) {
703
- const text = await obj.text();
704
- const { metadata } = parseFrontmatter(text);
705
- const matchTitle = metadata.title?.toLowerCase().includes(q);
706
- const matchDesc = metadata.description?.toLowerCase().includes(q);
707
- const matchTags = metadata.tags?.some((t) => t.toLowerCase().includes(q));
708
- if (matchTitle || matchDesc || matchTags) {
709
- results.push(metadata);
710
- }
711
- }
712
- }
713
- }
714
- return results;
715
- });
716
- return new Response(JSON.stringify(searchResults), {
717
- headers: { "Content-Type": "application/json" }
678
+ return await searchContent(env.CONTENT_BUCKET, query);
718
679
  });
680
+ return createJSONResponse(searchResults);
719
681
  } catch (error) {
720
682
  console.error("Error serving search:", error);
721
- return new Response(JSON.stringify({ error: "Search failed" }), {
722
- status: 500,
723
- headers: { "Content-Type": "application/json" }
724
- });
683
+ return createErrorResponse("Search failed", 500);
725
684
  }
726
685
  }
727
686
  const PLACEHOLDER_LOGO = `<svg width="600" height="320" viewBox="0 0 600 320" xmlns="http://www.w3.org/2000/svg">
@@ -790,7 +749,7 @@ async function handleStaticDetails(env, method, body) {
790
749
  });
791
750
  }
792
751
  if (!method || method === "GET") {
793
- const staticDetails = await env.CONTENT_BUCKET.get("staticdetails.json");
752
+ const staticDetails = await env.CONTENT_BUCKET.get("static-details.json");
794
753
  if (staticDetails) {
795
754
  const data = await staticDetails.json();
796
755
  return new Response(JSON.stringify({ ...DEFAULT_STATIC_DETAILS, ...data }), {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { A, B, M, R, W, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-FLejlWxJ.js";
1
+ import { A, B, M, R, W, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-BEYGOsT3.js";
2
2
  import { WebsitePrerender } from "./prerender.js";
3
- import { A as A2, a as a2, b as b2, c as c2, d as d2, e as e2, f, g as g2, h as h2, i, B as B2, F, M as M2, j, S, k } from "./chunks/index-CYd_Pe2U.js";
4
- import { R as R2, S as S2, T, W as W2, b as b3, c as c3, g as g3, a as a3, i as i2, r as r2 } from "./chunks/template-D1uGvdWZ.js";
3
+ import { A as A2, a as a2, b as b2, c as c2, d as d2, e as e2, f, g as g2, h as h2, i, B as B2, F, M as M2, j, S, k } from "./chunks/index-CnSEOZse.js";
4
+ import { R as R2, S as S2, T, W as W2, b as b3, c as c3, g as g3, a as a3, i as i2, r as r2 } from "./chunks/template-DWcsZW22.js";
5
5
  export {
6
6
  A as AUTH_KV,
7
7
  A2 as AdminAboutMeSection,
package/dist/shared.js CHANGED
@@ -1,4 +1,4 @@
1
- import { R, S, T, W, b, c, g, a, i, r } from "./chunks/template-D1uGvdWZ.js";
1
+ import { R, S, T, W, b, c, g, a, i, r } from "./chunks/template-DWcsZW22.js";
2
2
  export {
3
3
  R as Router,
4
4
  S as SiteStore,
@@ -27,6 +27,14 @@ export declare class AdminPortal extends LitElement {
27
27
  handleClearCache(): Promise<void>;
28
28
  handleDelete(key: string): Promise<void>;
29
29
  private handleStatusMessage;
30
+ private renderHomeSection;
31
+ private renderProfileSection;
32
+ private renderAboutMeSection;
33
+ private renderBlogsSection;
34
+ private renderStoriesSection;
35
+ private renderImagesSection;
36
+ private renderLogoSection;
37
+ private renderStaticSection;
30
38
  renderLoginForm(): import('lit-html').TemplateResult<1>;
31
39
  renderLogin(): import('lit-html').TemplateResult<1>;
32
40
  render(): import('lit-html').TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAK5C,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EACnB,CAAC;AAEF,qBACa,WAAY,SAAQ,UAAU;IACzC,MAAM,CAAC,MAAM,0BAAe;IAG5B,QAAQ,CAAC,eAAe,UAAS;IAGjC,QAAQ,CAAC,OAAO,UAAS;IAGzB,QAAQ,CAAC,SAAS,UAAQ;IAG1B,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,CAAM;IAGzC,QAAQ,CAAC,aAAa,SAAM;IAG5B,QAAQ,CAAC,aAAa,SAAa;IAGnC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAM;IAG3C,QAAQ,CAAC,UAAU,SAAM;IAEzB,OAAO,CAAC,UAAU,CAAkB;;IAQpC,OAAO,CAAC,gBAAgB;IAIlB,iBAAiB;IAMjB,eAAe;IAcf,YAAY;IASZ,WAAW,CAAC,CAAC,EAAE,WAAW;IAkB1B,WAAW,CAAC,CAAC,EAAE,WAAW;IAkC1B,YAAY;IAQZ,YAAY;IAQZ,kBAAkB;IAMlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;IAWpC,gBAAgB;IAUhB,YAAY,CAAC,GAAG,EAAE,MAAM;IAS9B,OAAO,CAAC,mBAAmB;IAI3B,eAAe;IAUf,WAAW;IAUX,MAAM;CAsLP;AAED,eAAO,MAAM,WAAW,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAK5C,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EACnB,CAAC;AAEF,qBACa,WAAY,SAAQ,UAAU;IACzC,MAAM,CAAC,MAAM,0BAAe;IAG5B,QAAQ,CAAC,eAAe,UAAS;IAGjC,QAAQ,CAAC,OAAO,UAAS;IAGzB,QAAQ,CAAC,SAAS,UAAQ;IAG1B,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,CAAM;IAGzC,QAAQ,CAAC,aAAa,SAAM;IAG5B,QAAQ,CAAC,aAAa,SAAa;IAGnC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAM;IAG3C,QAAQ,CAAC,UAAU,SAAM;IAEzB,OAAO,CAAC,UAAU,CAAkB;;IAQpC,OAAO,CAAC,gBAAgB;IAIlB,iBAAiB;IAMjB,eAAe;IAcf,YAAY;IASZ,WAAW,CAAC,CAAC,EAAE,WAAW;IAkB1B,WAAW,CAAC,CAAC,EAAE,WAAW;IAkC1B,YAAY;IAQZ,YAAY;IAQZ,kBAAkB;IAMlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;IAWpC,gBAAgB;IAUhB,YAAY,CAAC,GAAG,EAAE,MAAM;IAS9B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,mBAAmB;IAY3B,eAAe;IAUf,WAAW;IAUX,MAAM;CAyDP;AAED,eAAO,MAAM,WAAW,OAAO,CAAC"}
package/dist/ui.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A, a, b, c, d, e, f, g, h, i, B, F, M, j, S, k } from "./chunks/index-CYd_Pe2U.js";
1
+ import { A, a, b, c, d, e, f, g, h, i, B, F, M, j, S, k } from "./chunks/index-CnSEOZse.js";
2
2
  export {
3
3
  A as AdminAboutMeSection,
4
4
  a as AdminBlogsSection,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leadertechie/personal-site-kit",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "type": "module",
5
5
  "description": "A high-performance personal website engine for Cloudflare Workers and R2",
6
6
  "repository": {
@@ -11,7 +11,6 @@
11
11
  "license": "MIT",
12
12
  "files": [
13
13
  "dist",
14
- "src",
15
14
  "README.md",
16
15
  "public"
17
16
  ],
@@ -36,10 +35,11 @@
36
35
  "types": "./dist/prerender.d.ts",
37
36
  "import": "./dist/prerender.js"
38
37
  },
39
- "./styles/*": "./src/styles/*"
38
+ "./styles/*": "./dist/styles/*"
40
39
  },
41
40
  "scripts": {
42
- "build": "vite build",
41
+ "build": "vite build && npm run postbuild",
42
+ "postbuild": "cp -r src/styles dist/",
43
43
  "test": "vitest run"
44
44
  },
45
45
  "dependencies": {