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

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 (109) hide show
  1. package/dist/api/handlers/about-me.d.ts.map +1 -1
  2. package/dist/api/handlers/auth-handler.d.ts.map +1 -1
  3. package/dist/api/website-api.d.ts.map +1 -1
  4. package/dist/api.js +2 -2
  5. package/dist/chunks/index-CGvOrVf8.js +213 -0
  6. package/dist/chunks/{index-C3wLSCKU.js → index-CYd_Pe2U.js} +1353 -482
  7. package/dist/chunks/{template-MawmknFQ.js → template-D1uGvdWZ.js} +10 -8
  8. package/dist/chunks/{website-api-DI3muo2s.js → website-api-FLejlWxJ.js} +78 -41
  9. package/dist/index.js +19 -9
  10. package/dist/prerender/data-fetcher.d.ts +19 -0
  11. package/dist/prerender/data-fetcher.d.ts.map +1 -0
  12. package/dist/prerender/page-content.d.ts.map +1 -1
  13. package/dist/prerender/page-generators/about.d.ts +16 -0
  14. package/dist/prerender/page-generators/about.d.ts.map +1 -0
  15. package/dist/prerender/page-generators/base.d.ts +26 -0
  16. package/dist/prerender/page-generators/base.d.ts.map +1 -0
  17. package/dist/prerender/page-generators/blog-detail.d.ts +15 -0
  18. package/dist/prerender/page-generators/blog-detail.d.ts.map +1 -0
  19. package/dist/prerender/page-generators/blogs-list.d.ts +17 -0
  20. package/dist/prerender/page-generators/blogs-list.d.ts.map +1 -0
  21. package/dist/prerender/page-generators/home.d.ts +19 -0
  22. package/dist/prerender/page-generators/home.d.ts.map +1 -0
  23. package/dist/prerender/page-generators/index.d.ts +9 -0
  24. package/dist/prerender/page-generators/index.d.ts.map +1 -0
  25. package/dist/prerender/page-generators/not-found.d.ts +14 -0
  26. package/dist/prerender/page-generators/not-found.d.ts.map +1 -0
  27. package/dist/prerender/page-generators/stories-list.d.ts +17 -0
  28. package/dist/prerender/page-generators/stories-list.d.ts.map +1 -0
  29. package/dist/prerender/page-generators/story-detail.d.ts +15 -0
  30. package/dist/prerender/page-generators/story-detail.d.ts.map +1 -0
  31. package/dist/prerender.js +109 -102
  32. package/dist/shared/config/index.d.ts.map +1 -1
  33. package/dist/shared.js +1 -1
  34. package/dist/ui/about-me/index.d.ts +2 -10
  35. package/dist/ui/about-me/index.d.ts.map +1 -1
  36. package/dist/ui/admin/api.d.ts +16 -0
  37. package/dist/ui/admin/api.d.ts.map +1 -0
  38. package/dist/ui/admin/components/AboutMeSection.d.ts +7 -0
  39. package/dist/ui/admin/components/AboutMeSection.d.ts.map +1 -0
  40. package/dist/ui/admin/components/AdminSection.d.ts +13 -0
  41. package/dist/ui/admin/components/AdminSection.d.ts.map +1 -0
  42. package/dist/ui/admin/components/BlogsSection.d.ts +7 -0
  43. package/dist/ui/admin/components/BlogsSection.d.ts.map +1 -0
  44. package/dist/ui/admin/components/HomeSection.d.ts +7 -0
  45. package/dist/ui/admin/components/HomeSection.d.ts.map +1 -0
  46. package/dist/ui/admin/components/ImagesSection.d.ts +7 -0
  47. package/dist/ui/admin/components/ImagesSection.d.ts.map +1 -0
  48. package/dist/ui/admin/components/LoginForm.d.ts +9 -0
  49. package/dist/ui/admin/components/LoginForm.d.ts.map +1 -0
  50. package/dist/ui/admin/components/LogoSection.d.ts +7 -0
  51. package/dist/ui/admin/components/LogoSection.d.ts.map +1 -0
  52. package/dist/ui/admin/components/ProfileSection.d.ts +7 -0
  53. package/dist/ui/admin/components/ProfileSection.d.ts.map +1 -0
  54. package/dist/ui/admin/components/StaticSection.d.ts +13 -0
  55. package/dist/ui/admin/components/StaticSection.d.ts.map +1 -0
  56. package/dist/ui/admin/components/StoriesSection.d.ts +7 -0
  57. package/dist/ui/admin/components/StoriesSection.d.ts.map +1 -0
  58. package/dist/ui/admin/components/index.d.ts +11 -0
  59. package/dist/ui/admin/components/index.d.ts.map +1 -0
  60. package/dist/ui/admin/index.d.ts +10 -26
  61. package/dist/ui/admin/index.d.ts.map +1 -1
  62. package/dist/ui/admin/types.d.ts +24 -0
  63. package/dist/ui/admin/types.d.ts.map +1 -0
  64. package/dist/ui/blog-viewer/index.d.ts.map +1 -1
  65. package/dist/ui/index.d.ts.map +1 -1
  66. package/dist/ui/story-viewer/index.d.ts.map +1 -1
  67. package/dist/ui.js +14 -4
  68. package/package.json +1 -1
  69. package/src/api/handlers/about-me.ts +19 -9
  70. package/src/api/handlers/auth-handler.ts +41 -18
  71. package/src/api/handlers/content.ts +1 -1
  72. package/src/api/handlers/home.ts +2 -2
  73. package/src/api/website-api.ts +25 -13
  74. package/src/prerender/__tests__/page-content.test.ts +1 -11
  75. package/src/prerender/data-fetcher.ts +93 -0
  76. package/src/prerender/page-content.ts +109 -106
  77. package/src/prerender/page-generators/about.ts +38 -0
  78. package/src/prerender/page-generators/base.ts +77 -0
  79. package/src/prerender/page-generators/blog-detail.ts +35 -0
  80. package/src/prerender/page-generators/blogs-list.ts +43 -0
  81. package/src/prerender/page-generators/home.ts +54 -0
  82. package/src/prerender/page-generators/index.ts +8 -0
  83. package/src/prerender/page-generators/not-found.ts +36 -0
  84. package/src/prerender/page-generators/stories-list.ts +43 -0
  85. package/src/prerender/page-generators/story-detail.ts +35 -0
  86. package/src/shared/config/index.ts +4 -2
  87. package/src/shared/page-content.ts +1 -1
  88. package/src/shared/router.ts +5 -5
  89. package/src/ui/about-me/index.ts +23 -57
  90. package/src/ui/admin/api.ts +93 -0
  91. package/src/ui/admin/components/AboutMeSection.ts +47 -0
  92. package/src/ui/admin/components/AdminSection.ts +134 -0
  93. package/src/ui/admin/components/BlogsSection.ts +62 -0
  94. package/src/ui/admin/components/HomeSection.ts +47 -0
  95. package/src/ui/admin/components/ImagesSection.ts +54 -0
  96. package/src/ui/admin/components/LoginForm.ts +116 -0
  97. package/src/ui/admin/components/LogoSection.ts +51 -0
  98. package/src/ui/admin/components/ProfileSection.ts +47 -0
  99. package/src/ui/admin/components/StaticSection.ts +67 -0
  100. package/src/ui/admin/components/StoriesSection.ts +62 -0
  101. package/src/ui/admin/components/index.ts +10 -0
  102. package/src/ui/admin/index.ts +192 -434
  103. package/src/ui/admin/types.ts +26 -0
  104. package/src/ui/blog-viewer/index.ts +4 -1
  105. package/src/ui/index.ts +7 -0
  106. package/src/ui/story-viewer/index.ts +4 -1
  107. package/dist/ui/about-me/renderer.d.ts +0 -5
  108. package/dist/ui/about-me/renderer.d.ts.map +0 -1
  109. package/src/ui/about-me/renderer.ts +0 -7
@@ -1,7 +1,8 @@
1
1
  import { MarkdownPipeline } from "@leadertechie/md2html";
2
+ const __vite_import_meta_env__ = {};
2
3
  const DEFAULT_INFRA = {
3
4
  baseUrl: typeof window !== "undefined" ? window.location.origin : "http://localhost:5173",
4
- apiUrl: typeof window !== "undefined" && window.__VITE_API_URL__ || "http://localhost:8787"
5
+ apiUrl: typeof window !== "undefined" && (window.__VITE_API_URL__ || __vite_import_meta_env__?.VITE_API_URL) || "http://localhost:8788"
5
6
  };
6
7
  const DEFAULT_STATIC = {
7
8
  siteTitle: "My Personal Website",
@@ -14,7 +15,8 @@ const DEFAULT_STATIC = {
14
15
  let activeConfig = { ...DEFAULT_INFRA, ...DEFAULT_STATIC };
15
16
  async function initializeConfig(infra) {
16
17
  if (infra) {
17
- activeConfig = { ...activeConfig, ...infra };
18
+ if (infra.baseUrl) activeConfig.baseUrl = infra.baseUrl;
19
+ if (infra.apiUrl) activeConfig.apiUrl = infra.apiUrl;
18
20
  }
19
21
  try {
20
22
  const res = await fetch(`${activeConfig.apiUrl}/api/static`);
@@ -91,7 +93,7 @@ const generatePageContent = (pathname, routes, footerLinks, data) => {
91
93
  const footerTemplate = `
92
94
  <my-footer
93
95
  copyright="${copyright}"
94
- footerlinks='\${JSON.stringify(footerLinks)}'>
96
+ footerLinks='${JSON.stringify(footerLinks)}'>
95
97
  </my-footer>`;
96
98
  const renderContentGists = (items = [], title, type) => {
97
99
  const listHtml = items.length > 0 ? items.map((item) => `
@@ -230,10 +232,10 @@ class Router {
230
232
  return url;
231
233
  };
232
234
  this.footerLinks = [
233
- { text: "LinkedIn", link: normalizeUrl(config.linkedin) },
234
- { text: "GitHub", link: normalizeUrl(config.github) },
235
- { text: "Email", link: config.email ? `mailto:${config.email}` : "" }
236
- ].filter((link) => link.link !== "");
235
+ { text: "LinkedIn", link: normalizeUrl(config.linkedin) || "https://linkedin.com" },
236
+ { text: "GitHub", link: normalizeUrl(config.github) || "https://github.com" },
237
+ { text: "Email", link: config.email ? `mailto:${config.email}` : "mailto:hello@example.com" }
238
+ ];
237
239
  }
238
240
  init(appElementId = "app") {
239
241
  this.appElement = document.getElementById(appElementId);
@@ -425,7 +427,7 @@ class Router {
425
427
  <main class="container container-medium">
426
428
  <admin-portal></admin-portal>
427
429
  </main>
428
- <my-footer copyright="${this.copyright}" footerlinks='[]'></my-footer>
430
+ <my-footer copyright="${this.copyright}" footerLinks='[]'></my-footer>
429
431
  `;
430
432
  }
431
433
  }
@@ -52,20 +52,30 @@ async function handleAboutMe(env) {
52
52
  });
53
53
  }
54
54
  console.log("handleAboutMe: r2 created, fetching data");
55
- const [profileObj, astResult] = await Promise.all([
55
+ const [profileObj, rendered] = await Promise.all([
56
56
  r2.getObject("profile.json"),
57
- r2.getWithAST("about-me.md")
57
+ r2.getRendered("about-me.md")
58
58
  ]);
59
- console.log("handleAboutMe: profileObj =", !!profileObj, "astResult =", !!astResult);
60
- if (!profileObj || !astResult) {
61
- throw new Error("Content not found in R2");
59
+ if (!rendered) {
60
+ return new Response(JSON.stringify({ error: "About-me content not found. Please run seed." }), {
61
+ status: 404,
62
+ headers: { "Content-Type": "application/json" }
63
+ });
64
+ }
65
+ let profile = {
66
+ name: "Your Name",
67
+ title: "Professional",
68
+ experience: "Experienced",
69
+ profileImageUrl: ""
70
+ };
71
+ if (profileObj) {
72
+ profile = await profileObj.json();
62
73
  }
63
- const profile = await profileObj.json();
64
74
  console.log("handleAboutMe: profile loaded:", profile.name);
65
75
  const responseData = {
66
76
  profile,
67
- contentNodes: astResult.contentNodes,
68
- processedMarkdown: ""
77
+ contentNodes: [],
78
+ processedMarkdown: rendered.content
69
79
  };
70
80
  return new Response(JSON.stringify(responseData), {
71
81
  headers: { "Content-Type": "application/json" }
@@ -109,8 +119,8 @@ async function handleHome(env) {
109
119
  }
110
120
  const r2 = getLoader(env);
111
121
  const [astResult, renderedResult] = await Promise.all([
112
- r2.getWithAST("home.md"),
113
- r2.getRendered("home.md")
122
+ r2.getWithAST("pages/home.md"),
123
+ r2.getRendered("pages/home.md")
114
124
  ]);
115
125
  if (!astResult || !renderedResult) {
116
126
  return new Response(JSON.stringify({
@@ -281,7 +291,7 @@ async function handleContent(request, env, subpath) {
281
291
  }
282
292
  return createErrorResponse("Admin not configured. Use POST /auth/setup to configure.", 401);
283
293
  }
284
- const sessionToken = getSessionToken(request);
294
+ const sessionToken = getSessionToken(request) || request.headers.get("X-Session-Token");
285
295
  let isAuthenticated = false;
286
296
  if (sessionToken) {
287
297
  const session = await env.KV.get(`session:${sessionToken}`, "json");
@@ -359,17 +369,23 @@ async function handleWrite(request, bucket, subpath, env, method) {
359
369
  }
360
370
  return createErrorResponse("Method not allowed", 405);
361
371
  }
362
- function createSessionCookie(token, secure) {
372
+ function createSessionCookie(token, origin) {
363
373
  const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3).toUTCString();
364
- const SameSite = secure ? "Strict" : "Lax";
365
- return `session=${token}; HttpOnly; Secure; SameSite=${SameSite}; Path=/; Expires=${expires}`;
374
+ const isSecure = origin.startsWith("https://");
375
+ const hostname = new URL(origin).hostname;
376
+ const SameSite = isSecure ? "Strict" : "Lax";
377
+ let cookie = `session=${token}; HttpOnly; SameSite=${SameSite}; Path=/; Expires=${expires}`;
378
+ if (isSecure) {
379
+ cookie += "; Secure";
380
+ }
381
+ cookie += `; Domain=${hostname}`;
382
+ return cookie;
366
383
  }
367
384
  async function handleAuth(request, env, subpath) {
368
385
  request.method;
369
386
  const clientIP = getClientIP(request);
370
387
  const path = subpath.replace(/^\//, "").split("/")[0];
371
- const url = new URL(request.url);
372
- const isSecure = url.protocol === "https:";
388
+ const origin = request.headers.get("Origin") || new URL(request.url).origin;
373
389
  const rateCheck = await checkRateLimit(env, clientIP);
374
390
  if (!rateCheck.allowed) {
375
391
  return new Response(JSON.stringify({
@@ -385,44 +401,52 @@ async function handleAuth(request, env, subpath) {
385
401
  }
386
402
  switch (path) {
387
403
  case "setup":
388
- return handleSetup(request, env, clientIP, isSecure);
404
+ return handleSetup(request, env, clientIP, origin);
389
405
  case "status":
390
406
  return handleStatus(env);
391
407
  case "login":
392
- return handleLogin(request, env, clientIP, isSecure);
408
+ return handleLogin(request, env, clientIP, origin);
393
409
  case "logout":
394
410
  return handleLogout(request, env);
395
411
  default:
396
412
  return createErrorResponse("Not found", 404);
397
413
  }
398
414
  }
399
- async function handleSetup(request, env, clientIP, isSecure) {
415
+ async function handleSetup(request, env, clientIP, origin) {
416
+ console.log("handleSetup: starting setup, env.KV exists:", !!env.KV);
400
417
  if (request.method !== "POST") {
401
418
  return createErrorResponse("Method not allowed", 405);
402
419
  }
403
- const existing = await getAuthStore(env);
404
- if (existing) {
405
- return createErrorResponse("Admin already configured. Use /auth/login to login.", 400);
406
- }
407
420
  try {
421
+ const existing = await getAuthStore(env);
422
+ console.log("handleSetup: existing store check:", !!existing);
423
+ if (existing) {
424
+ return createErrorResponse("Admin already configured. Use /auth/login to login.", 400);
425
+ }
408
426
  const body = await request.json();
409
427
  const { username, password } = body;
428
+ console.log("handleSetup: body parsed, username:", username);
410
429
  if (!username || !password) {
411
430
  return createErrorResponse("Username and password required", 400);
412
431
  }
413
432
  if (username.length < 3 || password.length < 8) {
414
433
  return createErrorResponse("Username must be 3+ chars, password must be 8+ chars", 400);
415
434
  }
435
+ console.log("handleSetup: calling setupAuth");
416
436
  await setupAuth(env, username, password);
437
+ console.log("handleSetup: setupAuth successful");
417
438
  await clearRateLimit(env, clientIP);
418
439
  const token = crypto.randomUUID();
440
+ console.log("handleSetup: session token generated");
419
441
  await env.KV.put(`session:${token}`, JSON.stringify({
420
442
  createdAt: Date.now(),
421
443
  expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1e3
422
444
  }), { expirationTtl: 7 * 24 * 60 * 60 });
445
+ console.log("handleSetup: session stored in KV");
423
446
  const headers = {
424
447
  "Content-Type": "application/json",
425
- "Set-Cookie": createSessionCookie(token, isSecure)
448
+ "Set-Cookie": createSessionCookie(token, origin),
449
+ "X-Session-Token": token
426
450
  };
427
451
  return new Response(JSON.stringify({
428
452
  success: true,
@@ -432,7 +456,8 @@ async function handleSetup(request, env, clientIP, isSecure) {
432
456
  headers
433
457
  });
434
458
  } catch (e) {
435
- return createErrorResponse("Invalid request body", 400);
459
+ console.error("handleSetup: error occurred:", e);
460
+ return createErrorResponse("Internal server error: " + e.message, 500);
436
461
  }
437
462
  }
438
463
  async function handleStatus(env) {
@@ -442,7 +467,7 @@ async function handleStatus(env) {
442
467
  username: store?.username || null
443
468
  });
444
469
  }
445
- async function handleLogin(request, env, clientIP, isSecure) {
470
+ async function handleLogin(request, env, clientIP, origin) {
446
471
  if (request.method !== "POST") {
447
472
  return createErrorResponse("Method not allowed", 405);
448
473
  }
@@ -465,7 +490,8 @@ async function handleLogin(request, env, clientIP, isSecure) {
465
490
  }), { expirationTtl: 7 * 24 * 60 * 60 });
466
491
  const headers = {
467
492
  "Content-Type": "application/json",
468
- "Set-Cookie": createSessionCookie(token, isSecure)
493
+ "Set-Cookie": createSessionCookie(token, origin),
494
+ "X-Session-Token": token
469
495
  };
470
496
  return new Response(JSON.stringify({
471
497
  success: true,
@@ -486,16 +512,21 @@ async function handleLogout(request, env) {
486
512
  if (request.method !== "POST") {
487
513
  return createErrorResponse("Method not allowed", 405);
488
514
  }
515
+ const origin = request.headers.get("Origin") || new URL(request.url).origin;
489
516
  const cookieHeader = request.headers.get("Cookie");
490
517
  const sessionToken = cookieHeader?.split(";").find((c) => c.trim().startsWith("session="))?.split("=")[1];
491
518
  if (sessionToken) {
492
519
  await env.KV.delete(`session:${sessionToken}`);
493
520
  }
521
+ const hostname = new URL(origin).hostname;
522
+ const isSecure = origin.startsWith("https://");
523
+ const SameSite = isSecure ? "Strict" : "Lax";
524
+ const logoutCookie = `session=; HttpOnly; SameSite=${SameSite}; Path=/; Max-Age=0; Domain=${hostname}${isSecure ? "; Secure" : ""}`;
494
525
  return new Response(JSON.stringify({ success: true, message: "Logged out" }), {
495
526
  status: 200,
496
527
  headers: {
497
528
  "Content-Type": "application/json",
498
- "Set-Cookie": "session=; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=0"
529
+ "Set-Cookie": logoutCookie
499
530
  }
500
531
  });
501
532
  }
@@ -797,31 +828,35 @@ class WebsiteAPI {
797
828
  addCORSHeaders(response) {
798
829
  response.headers.set("Access-Control-Allow-Origin", "*");
799
830
  response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
800
- response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
831
+ response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Session-Token");
801
832
  return response;
802
833
  }
803
- addAdminCORSHeaders(response) {
804
- response.headers.set("Access-Control-Allow-Origin", "same-origin");
834
+ addAdminCORSHeaders(response, origin) {
835
+ const allowOrigin = origin && (origin.includes("localhost") || origin.includes("127.0.0.1")) ? origin : "same-origin";
836
+ response.headers.set("Access-Control-Allow-Origin", allowOrigin);
805
837
  response.headers.set("Access-Control-Allow-Credentials", "true");
806
838
  response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
807
- response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
839
+ response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Session-Token");
808
840
  return response;
809
841
  }
810
- handleCORS() {
842
+ handleCORS(origin) {
843
+ const allowOrigin = origin && (origin.includes("localhost") || origin.includes("127.0.0.1")) ? origin : "*";
811
844
  return new Response(null, {
812
845
  status: 200,
813
846
  headers: {
814
- "Access-Control-Allow-Origin": "*",
847
+ "Access-Control-Allow-Origin": allowOrigin,
815
848
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
816
- "Access-Control-Allow-Headers": "Content-Type, Authorization",
849
+ "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Session-Token",
850
+ "Access-Control-Allow-Credentials": "true",
817
851
  "Access-Control-Max-Age": "86400"
818
852
  }
819
853
  });
820
854
  }
821
855
  async fetch(request, env) {
822
856
  const url = new URL(request.url);
857
+ const origin = request.headers.get("Origin") || url.origin;
823
858
  if (request.method === "OPTIONS") {
824
- return this.handleCORS();
859
+ return this.handleCORS(origin);
825
860
  }
826
861
  const pathname = url.pathname;
827
862
  const route = pathname.replace(/^\/api\//, "").replace(/^\//, "").replace(/\/+$/, "");
@@ -832,7 +867,11 @@ class WebsiteAPI {
832
867
  try {
833
868
  if (route === "content" || route.startsWith("content/")) {
834
869
  const subpath = route.replace(/^content\/?/, "");
835
- return this.addAdminCORSHeaders(await handleContent(request, env, subpath));
870
+ return this.addAdminCORSHeaders(await handleContent(request, env, subpath), origin);
871
+ }
872
+ if (route === "auth" || route.startsWith("auth/")) {
873
+ const subpath = route.replace(/^auth\/?/, "");
874
+ return this.addAdminCORSHeaders(await handleAuth(request, env, subpath || "/"), origin);
836
875
  }
837
876
  switch (route) {
838
877
  case "info":
@@ -844,18 +883,16 @@ class WebsiteAPI {
844
883
  const sessionToken = cookieHeader?.split(";").find((c) => c.trim().startsWith("session="))?.split("=")[1];
845
884
  const session = sessionToken ? await env.KV.get(`session:${sessionToken}`, "json") : null;
846
885
  if (!session || session.expiresAt < Date.now()) {
847
- return this.addAdminCORSHeaders(createErrorResponse("Unauthorized", 401));
886
+ return this.addAdminCORSHeaders(createErrorResponse("Unauthorized", 401), origin);
848
887
  }
849
888
  clearContentCache();
850
- return this.addAdminCORSHeaders(new Response(JSON.stringify({ success: true, message: "Cache cleared" }), { status: 200 }));
889
+ return this.addAdminCORSHeaders(new Response(JSON.stringify({ success: true, message: "Cache cleared" }), { status: 200 }), origin);
851
890
  case "aboutme":
852
891
  return this.addCORSHeaders(await handleAboutMe(env));
853
892
  case "logo":
854
893
  return this.addCORSHeaders(await handleLogo(env));
855
894
  case "static":
856
895
  return this.addCORSHeaders(await handleStaticDetails(env));
857
- case "auth":
858
- return this.addAdminCORSHeaders(await handleAuth(request, env, "/auth"));
859
896
  case "blogs":
860
897
  return this.addCORSHeaders(await handleBlogs(env));
861
898
  case "blogs/latest":
package/dist/index.js CHANGED
@@ -1,16 +1,25 @@
1
- import { A, B, M, R, W, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-DI3muo2s.js";
1
+ import { A, B, M, R, W, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-FLejlWxJ.js";
2
2
  import { WebsitePrerender } from "./prerender.js";
3
- import { A as A2, B as B2, F, M as M2, a as a2, S } from "./chunks/index-C3wLSCKU.js";
4
- import { R as R2, S as S2, T, W as W2, b as b2, c as c2, g as g2, a as a3, i, r as r2 } from "./chunks/template-MawmknFQ.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";
5
5
  export {
6
6
  A as AUTH_KV,
7
- A2 as AdminPortal,
7
+ A2 as AdminAboutMeSection,
8
+ a2 as AdminBlogsSection,
9
+ b2 as AdminHomeSection,
10
+ c2 as AdminImagesSection,
11
+ d2 as AdminLoginForm,
12
+ e2 as AdminLogoSection,
13
+ f as AdminPortal,
14
+ g2 as AdminProfileSection,
15
+ h2 as AdminStaticSection,
16
+ i as AdminStoriesSection,
8
17
  B as BASE_DELAY_MS,
9
18
  B2 as BlogViewer,
10
19
  F as FooterComponent,
11
20
  M as MAX_ATTEMPTS,
12
21
  M2 as MyAboutme,
13
- a2 as MyBanner,
22
+ j as MyBanner,
14
23
  R as RATE_LIMIT_KV,
15
24
  R2 as Router,
16
25
  S2 as SiteStore,
@@ -19,18 +28,19 @@ export {
19
28
  W as WebsiteAPI,
20
29
  WebsitePrerender,
21
30
  W2 as WebsiteUI,
22
- b2 as bootstrap,
31
+ k as adminLoaded,
32
+ b3 as bootstrap,
23
33
  c as checkRateLimit,
24
34
  a as clearRateLimit,
25
- c2 as createHtmlTemplate,
26
- g2 as generatePageContent,
35
+ c3 as createHtmlTemplate,
36
+ g3 as generatePageContent,
27
37
  g as generateSalt,
28
38
  b as getAuthStore,
29
39
  d as getClientIP,
30
40
  a3 as getConfig,
31
41
  h as handleAuth,
32
42
  e as hashPassword,
33
- i as initializeConfig,
43
+ i2 as initializeConfig,
34
44
  r as recordFailedAttempt,
35
45
  r2 as renderMarkdown,
36
46
  s as setupAuth,
@@ -0,0 +1,19 @@
1
+ export interface Profile {
2
+ name: string;
3
+ title: string;
4
+ experience: string;
5
+ profileImageUrl: string;
6
+ }
7
+ export interface BlogMeta {
8
+ slug: string;
9
+ title: string;
10
+ summary: string;
11
+ tags: string[];
12
+ date: string;
13
+ }
14
+ export declare function fetchProfile(env: any): Promise<Profile | null>;
15
+ export declare function fetchAboutMe(env: any): Promise<string>;
16
+ export declare function fetchHome(env: any): Promise<string>;
17
+ export declare function fetchLatestBlogSummaries(env: any, count?: number): Promise<BlogMeta[]>;
18
+ export declare function fetchLatestStorySummaries(env: any, count?: number): Promise<BlogMeta[]>;
19
+ //# sourceMappingURL=data-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-fetcher.d.ts","sourceRoot":"","sources":["../../src/prerender/data-fetcher.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAeD,wBAAsB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAQpE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5D;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAOzD;AAED,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAgB/F;AAED,wBAAsB,yBAAyB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAgBhG"}
@@ -1 +1 @@
1
- {"version":3,"file":"page-content.d.ts","sourceRoot":"","sources":["../../src/prerender/page-content.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAuFD,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,EAChB,QAAQ,MAAM,EAAE,EAChB,aAAa,WAAW,EAAE,EAC1B,MAAM,GAAG,KACR,OAAO,CAAC,WAAW,CAkJrB,CAAC"}
1
+ {"version":3,"file":"page-content.d.ts","sourceRoot":"","sources":["../../src/prerender/page-content.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAuFD,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,EAChB,QAAQ,MAAM,EAAE,EAChB,aAAa,WAAW,EAAE,EAC1B,MAAM,GAAG,KACR,OAAO,CAAC,WAAW,CAqJrB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ import { Profile } from '../data-fetcher';
4
+ export interface AboutPageData {
5
+ routes: IRoute[];
6
+ footerLinks: IFooterLink[];
7
+ staticDetails: StaticDetails;
8
+ apiUrl: string;
9
+ baseUrl: string;
10
+ pathname: string;
11
+ profile: Profile | null;
12
+ }
13
+ export declare class AboutPageGenerator extends BasePageGenerator {
14
+ generate(data: AboutPageData): PageContent;
15
+ }
16
+ //# sourceMappingURL=about.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/about.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAED,qBAAa,kBAAmB,SAAQ,iBAAiB;IAChD,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,WAAW;CAsBlD"}
@@ -0,0 +1,26 @@
1
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
2
+ export interface StaticDetails {
3
+ siteTitle?: string;
4
+ copyright?: string;
5
+ linkedin?: string;
6
+ github?: string;
7
+ email?: string;
8
+ }
9
+ export interface BasePageData {
10
+ routes: IRoute[];
11
+ footerLinks: IFooterLink[];
12
+ staticDetails: StaticDetails;
13
+ apiUrl: string;
14
+ baseUrl: string;
15
+ pathname: string;
16
+ name?: string;
17
+ title?: string;
18
+ }
19
+ export declare class BasePageGenerator {
20
+ protected generateBanner(routes: IRoute[], siteTitle: string, logo: string): string;
21
+ protected generateFooter(footerLinks: IFooterLink[], copyright: string): string;
22
+ protected generateMeta(title: string, description: string, canonicalUrl: string): void;
23
+ protected wrapContent(banner: string, mainContent: string, footer: string): string;
24
+ generatePage(pathname: string, routes: IRoute[], footerLinks: IFooterLink[], staticDetails: StaticDetails, apiUrl: string, baseUrl: string, mainContent: string, title: string, description: string): PageContent;
25
+ }
26
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAiB;IAC5B,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAcnF,SAAS,CAAC,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAQ/E,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAItF,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAI3E,YAAY,CACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,WAAW,EAAE,WAAW,EAAE,EAC1B,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,WAAW;CAcf"}
@@ -0,0 +1,15 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ export interface BlogDetailPageData {
4
+ routes: IRoute[];
5
+ footerLinks: IFooterLink[];
6
+ staticDetails: StaticDetails;
7
+ apiUrl: string;
8
+ baseUrl: string;
9
+ pathname: string;
10
+ slug: string;
11
+ }
12
+ export declare class BlogDetailPageGenerator extends BasePageGenerator {
13
+ generate(data: BlogDetailPageData): PageContent;
14
+ }
15
+ //# sourceMappingURL=blog-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-detail.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/blog-detail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,uBAAwB,SAAQ,iBAAiB;IACrD,QAAQ,CAAC,IAAI,EAAE,kBAAkB,GAAG,WAAW;CAoBvD"}
@@ -0,0 +1,17 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ import { BlogMeta } from '../data-fetcher';
4
+ export interface BlogsListPageData {
5
+ routes: IRoute[];
6
+ footerLinks: IFooterLink[];
7
+ staticDetails: StaticDetails;
8
+ apiUrl: string;
9
+ baseUrl: string;
10
+ pathname: string;
11
+ latestBlogs: BlogMeta[];
12
+ name: string;
13
+ }
14
+ export declare class BlogsListPageGenerator extends BasePageGenerator {
15
+ generate(data: BlogsListPageData): PageContent;
16
+ }
17
+ //# sourceMappingURL=blogs-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blogs-list.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/blogs-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,sBAAuB,SAAQ,iBAAiB;IACpD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW;CA0BtD"}
@@ -0,0 +1,19 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ import { Profile, BlogMeta } from '../data-fetcher';
4
+ export interface HomePageData {
5
+ routes: IRoute[];
6
+ footerLinks: IFooterLink[];
7
+ staticDetails: StaticDetails;
8
+ apiUrl: string;
9
+ baseUrl: string;
10
+ pathname: string;
11
+ profile: Profile | null;
12
+ homeContent: string;
13
+ latestBlogs: BlogMeta[];
14
+ latestStories: BlogMeta[];
15
+ }
16
+ export declare class HomePageGenerator extends BasePageGenerator {
17
+ generate(data: HomePageData): PageContent;
18
+ }
19
+ //# sourceMappingURL=home.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/home.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,aAAa,EAAE,QAAQ,EAAE,CAAC;CAC3B;AAED,qBAAa,iBAAkB,SAAQ,iBAAiB;IAC/C,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW;CAmCjD"}
@@ -0,0 +1,9 @@
1
+ export * from './base';
2
+ export * from './home';
3
+ export * from './about';
4
+ export * from './blogs-list';
5
+ export * from './stories-list';
6
+ export * from './blog-detail';
7
+ export * from './story-detail';
8
+ export * from './not-found';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ export interface NotFoundPageData {
4
+ routes: IRoute[];
5
+ footerLinks: IFooterLink[];
6
+ staticDetails: StaticDetails;
7
+ apiUrl: string;
8
+ baseUrl: string;
9
+ pathname: string;
10
+ }
11
+ export declare class NotFoundPageGenerator extends BasePageGenerator {
12
+ generate(data: NotFoundPageData): PageContent;
13
+ }
14
+ //# sourceMappingURL=not-found.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-found.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/not-found.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;IACnD,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW;CAsBrD"}
@@ -0,0 +1,17 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ import { BlogMeta } from '../data-fetcher';
4
+ export interface StoriesListPageData {
5
+ routes: IRoute[];
6
+ footerLinks: IFooterLink[];
7
+ staticDetails: StaticDetails;
8
+ apiUrl: string;
9
+ baseUrl: string;
10
+ pathname: string;
11
+ latestStories: BlogMeta[];
12
+ name: string;
13
+ }
14
+ export declare class StoriesListPageGenerator extends BasePageGenerator {
15
+ generate(data: StoriesListPageData): PageContent;
16
+ }
17
+ //# sourceMappingURL=stories-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stories-list.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/stories-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,QAAQ,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,wBAAyB,SAAQ,iBAAiB;IACtD,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW;CA0BxD"}
@@ -0,0 +1,15 @@
1
+ import { BasePageGenerator, StaticDetails } from './base';
2
+ import { IRoute, IFooterLink, PageContent } from '../page-content';
3
+ export interface StoryDetailPageData {
4
+ routes: IRoute[];
5
+ footerLinks: IFooterLink[];
6
+ staticDetails: StaticDetails;
7
+ apiUrl: string;
8
+ baseUrl: string;
9
+ pathname: string;
10
+ slug: string;
11
+ }
12
+ export declare class StoryDetailPageGenerator extends BasePageGenerator {
13
+ generate(data: StoryDetailPageData): PageContent;
14
+ }
15
+ //# sourceMappingURL=story-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"story-detail.d.ts","sourceRoot":"","sources":["../../../src/prerender/page-generators/story-detail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,wBAAyB,SAAQ,iBAAiB;IACtD,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW;CAoBxD"}