@begryp/blog-automation-admin 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/adapters/env-key-vault.d.ts +12 -0
  2. package/dist/adapters/env-key-vault.d.ts.map +1 -0
  3. package/dist/adapters/env-key-vault.js +46 -0
  4. package/dist/adapters/env-key-vault.js.map +1 -0
  5. package/dist/adapters/html.d.ts +18 -0
  6. package/dist/adapters/html.d.ts.map +1 -0
  7. package/dist/adapters/html.js +130 -0
  8. package/dist/adapters/html.js.map +1 -0
  9. package/dist/adapters/index.d.ts +5 -0
  10. package/dist/adapters/index.d.ts.map +1 -0
  11. package/dist/adapters/index.js +5 -0
  12. package/dist/adapters/index.js.map +1 -0
  13. package/dist/adapters/supabase-publisher.d.ts +30 -0
  14. package/dist/adapters/supabase-publisher.d.ts.map +1 -0
  15. package/dist/adapters/supabase-publisher.js +120 -0
  16. package/dist/adapters/supabase-publisher.js.map +1 -0
  17. package/dist/adapters/supabase-run-store.d.ts +15 -0
  18. package/dist/adapters/supabase-run-store.d.ts.map +1 -0
  19. package/dist/adapters/supabase-run-store.js +92 -0
  20. package/dist/adapters/supabase-run-store.js.map +1 -0
  21. package/dist/automation/index.d.ts +3 -0
  22. package/dist/automation/index.d.ts.map +1 -0
  23. package/dist/automation/index.js +3 -0
  24. package/dist/automation/index.js.map +1 -0
  25. package/dist/automation/runner.d.ts +45 -0
  26. package/dist/automation/runner.d.ts.map +1 -0
  27. package/dist/automation/runner.js +195 -0
  28. package/dist/automation/runner.js.map +1 -0
  29. package/dist/automation/types.d.ts +41 -0
  30. package/dist/automation/types.d.ts.map +1 -0
  31. package/dist/automation/types.js +12 -0
  32. package/dist/automation/types.js.map +1 -0
  33. package/dist/components/AutoGenerateBlogModal.d.ts +18 -0
  34. package/dist/components/AutoGenerateBlogModal.d.ts.map +1 -0
  35. package/dist/components/AutoGenerateBlogModal.js +99 -0
  36. package/dist/components/AutoGenerateBlogModal.js.map +1 -0
  37. package/dist/components/RichText.d.ts +9 -0
  38. package/dist/components/RichText.d.ts.map +1 -0
  39. package/dist/components/RichText.js +56 -0
  40. package/dist/components/RichText.js.map +1 -0
  41. package/dist/components/Shell.d.ts +18 -0
  42. package/dist/components/Shell.d.ts.map +1 -0
  43. package/dist/components/Shell.js +35 -0
  44. package/dist/components/Shell.js.map +1 -0
  45. package/dist/components/index.d.ts +4 -0
  46. package/dist/components/index.d.ts.map +1 -0
  47. package/dist/components/index.js +4 -0
  48. package/dist/components/index.js.map +1 -0
  49. package/dist/entities/index.d.ts +5 -0
  50. package/dist/entities/index.d.ts.map +1 -0
  51. package/dist/entities/index.js +5 -0
  52. package/dist/entities/index.js.map +1 -0
  53. package/dist/entities/registry.d.ts +10 -0
  54. package/dist/entities/registry.d.ts.map +1 -0
  55. package/dist/entities/registry.js +43 -0
  56. package/dist/entities/registry.js.map +1 -0
  57. package/dist/entities/schemas/blogs.d.ts +3 -0
  58. package/dist/entities/schemas/blogs.d.ts.map +1 -0
  59. package/dist/entities/schemas/blogs.js +110 -0
  60. package/dist/entities/schemas/blogs.js.map +1 -0
  61. package/dist/entities/schemas/enquiries.d.ts +3 -0
  62. package/dist/entities/schemas/enquiries.d.ts.map +1 -0
  63. package/dist/entities/schemas/enquiries.js +67 -0
  64. package/dist/entities/schemas/enquiries.js.map +1 -0
  65. package/dist/entities/types.d.ts +38 -0
  66. package/dist/entities/types.d.ts.map +1 -0
  67. package/dist/entities/types.js +2 -0
  68. package/dist/entities/types.js.map +1 -0
  69. package/dist/index.d.ts +10 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +10 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/theme/defaultTheme.d.ts +3 -0
  74. package/dist/theme/defaultTheme.d.ts.map +1 -0
  75. package/dist/theme/defaultTheme.js +22 -0
  76. package/dist/theme/defaultTheme.js.map +1 -0
  77. package/dist/theme/index.d.ts +4 -0
  78. package/dist/theme/index.d.ts.map +1 -0
  79. package/dist/theme/index.js +4 -0
  80. package/dist/theme/index.js.map +1 -0
  81. package/dist/theme/inject.d.ts +10 -0
  82. package/dist/theme/inject.d.ts.map +1 -0
  83. package/dist/theme/inject.js +46 -0
  84. package/dist/theme/inject.js.map +1 -0
  85. package/dist/theme/types.d.ts +30 -0
  86. package/dist/theme/types.d.ts.map +1 -0
  87. package/dist/theme/types.js +2 -0
  88. package/dist/theme/types.js.map +1 -0
  89. package/package.json +72 -4
  90. package/README.md +0 -3
@@ -0,0 +1,12 @@
1
+ import type { KeyVault } from "@begryp/blog-automation-core";
2
+ /**
3
+ * Resolves LLM API keys from environment variables.
4
+ * Checks provider-specific keys, client keys, and fallback keys.
5
+ */
6
+ export declare class EnvKeyVault implements KeyVault {
7
+ private readonly env;
8
+ constructor(customEnv?: Record<string, string | undefined>);
9
+ resolveKey(keyRef: string): Promise<string>;
10
+ resolveKeyForProvider(provider: string): Promise<string>;
11
+ }
12
+ //# sourceMappingURL=env-key-vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-key-vault.d.ts","sourceRoot":"","sources":["../../src/adapters/env-key-vault.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7D;;;GAGG;AACH,qBAAa,WAAY,YAAW,QAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqC;gBAE7C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAIpD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkB3C,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA8B/D"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Resolves LLM API keys from environment variables.
3
+ * Checks provider-specific keys, client keys, and fallback keys.
4
+ */
5
+ export class EnvKeyVault {
6
+ env;
7
+ constructor(customEnv) {
8
+ this.env = customEnv || (typeof process !== "undefined" ? process.env : {});
9
+ }
10
+ async resolveKey(keyRef) {
11
+ if (!keyRef)
12
+ return "";
13
+ // If keyRef starts with env:, extract variable name
14
+ if (keyRef.startsWith("env:")) {
15
+ const varName = keyRef.slice(4);
16
+ return this.env[varName] || "";
17
+ }
18
+ // Direct environment lookup
19
+ if (this.env[keyRef]) {
20
+ return this.env[keyRef];
21
+ }
22
+ // Common standard variable lookups
23
+ return this.resolveKeyForProvider("openai");
24
+ }
25
+ async resolveKeyForProvider(provider) {
26
+ const prov = provider.toLowerCase();
27
+ if (prov === "openai") {
28
+ return (this.env.SERVICE_OPENAI_API_KEY_CLIENT ||
29
+ this.env.OPENAI_API_KEY ||
30
+ this.env.OPENAI_KEY ||
31
+ "");
32
+ }
33
+ if (prov === "anthropic") {
34
+ return (this.env.ANTHROPIC_API_KEY ||
35
+ this.env.CLAUDE_API_KEY ||
36
+ "");
37
+ }
38
+ if (prov === "gemini" || prov === "google") {
39
+ return (this.env.GEMINI_API_KEY ||
40
+ this.env.GOOGLE_API_KEY ||
41
+ "");
42
+ }
43
+ return "";
44
+ }
45
+ }
46
+ //# sourceMappingURL=env-key-vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-key-vault.js","sourceRoot":"","sources":["../../src/adapters/env-key-vault.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACL,GAAG,CAAqC;IAEzD,YAAY,SAA8C;QACxD,IAAI,CAAC,GAAG,GAAG,SAAS,IAAI,CAAC,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,oDAAoD;QACpD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,CAAC;QAED,4BAA4B;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QAC3B,CAAC;QAED,mCAAmC;QACnC,OAAO,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,QAAgB;QAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAEpC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO,CACL,IAAI,CAAC,GAAG,CAAC,6BAA6B;gBACtC,IAAI,CAAC,GAAG,CAAC,cAAc;gBACvB,IAAI,CAAC,GAAG,CAAC,UAAU;gBACnB,EAAE,CACH,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,OAAO,CACL,IAAI,CAAC,GAAG,CAAC,iBAAiB;gBAC1B,IAAI,CAAC,GAAG,CAAC,cAAc;gBACvB,EAAE,CACH,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3C,OAAO,CACL,IAAI,CAAC,GAAG,CAAC,cAAc;gBACvB,IAAI,CAAC,GAAG,CAAC,cAAc;gBACvB,EAAE,CACH,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import type { DraftPost } from "@begryp/blog-automation-core";
2
+ /**
3
+ * Formats inline markdown tokens into clean HTML tags.
4
+ */
5
+ export declare function inlineFormat(text: string): string;
6
+ /**
7
+ * Converts markdown body into clean HTML markup for TipTap and browser rendering.
8
+ */
9
+ export declare function markdownToHtml(markdown: string): string;
10
+ /**
11
+ * Builds composite HTML from all draft sections, takeaways, FAQs, and citations.
12
+ */
13
+ export declare function buildFullHtml(draft: DraftPost): string;
14
+ /**
15
+ * Estimate reading time in minutes from words in draft sections.
16
+ */
17
+ export declare function calculateReadingTime(draft: DraftPost): number;
18
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/adapters/html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuEvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAgCtD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAI7D"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Formats inline markdown tokens into clean HTML tags.
3
+ */
4
+ export function inlineFormat(text) {
5
+ if (!text)
6
+ return "";
7
+ return text
8
+ // Bold & italic (order matters: triple first)
9
+ .replace(/\*\*\*(.*?)\*\*\*/g, "<strong><em>$1</em></strong>")
10
+ .replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
11
+ .replace(/_(.*?)_/g, "<em>$1</em>")
12
+ .replace(/\*(.*?)\*/g, "<em>$1</em>")
13
+ // Inline code
14
+ .replace(/`([^`]+)`/g, "<code>$1</code>")
15
+ // Links [text](url)
16
+ .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>');
17
+ }
18
+ /**
19
+ * Converts markdown body into clean HTML markup for TipTap and browser rendering.
20
+ */
21
+ export function markdownToHtml(markdown) {
22
+ if (!markdown)
23
+ return "";
24
+ // Normalize line endings
25
+ const normalized = markdown.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
26
+ // Split into blocks on blank lines
27
+ const rawBlocks = normalized.split(/\n{2,}/);
28
+ const htmlBlocks = [];
29
+ for (const block of rawBlocks) {
30
+ const trimmed = block.trim();
31
+ if (!trimmed)
32
+ continue;
33
+ // Headings
34
+ if (/^###\s+/.test(trimmed)) {
35
+ htmlBlocks.push(`<h4>${inlineFormat(trimmed.replace(/^###\s+/, ""))}</h4>`);
36
+ }
37
+ else if (/^##\s+/.test(trimmed)) {
38
+ htmlBlocks.push(`<h3>${inlineFormat(trimmed.replace(/^##\s+/, ""))}</h3>`);
39
+ }
40
+ else if (/^#\s+/.test(trimmed)) {
41
+ htmlBlocks.push(`<h3>${inlineFormat(trimmed.replace(/^#\s+/, ""))}</h3>`);
42
+ }
43
+ // Blockquote
44
+ else if (/^>\s+/.test(trimmed)) {
45
+ const quoteText = trimmed.replace(/^>\s+/gm, "");
46
+ htmlBlocks.push(`<blockquote><p>${inlineFormat(quoteText)}</p></blockquote>`);
47
+ }
48
+ // Unordered list
49
+ else if (/(?:^|\n)[-*]\s+\S/.test(trimmed)) {
50
+ const lines = trimmed.split("\n");
51
+ const listItems = [];
52
+ let preamble = "";
53
+ for (const line of lines) {
54
+ const stripped = line.trim();
55
+ if (/^[-*]\s+/.test(stripped)) {
56
+ listItems.push(`<li>${inlineFormat(stripped.replace(/^[-*]\s+/, ""))}</li>`);
57
+ }
58
+ else if (listItems.length === 0 && stripped) {
59
+ preamble += (preamble ? " " : "") + stripped;
60
+ }
61
+ }
62
+ if (preamble)
63
+ htmlBlocks.push(`<p>${inlineFormat(preamble)}</p>`);
64
+ if (listItems.length > 0)
65
+ htmlBlocks.push(`<ul>${listItems.join("")}</ul>`);
66
+ }
67
+ // Ordered list
68
+ else if (/(?:^|\n)\d+\.\s+\S/.test(trimmed)) {
69
+ const lines = trimmed.split("\n");
70
+ const listItems = [];
71
+ let preamble = "";
72
+ for (const line of lines) {
73
+ const stripped = line.trim();
74
+ if (/^\d+\.\s+/.test(stripped)) {
75
+ listItems.push(`<li>${inlineFormat(stripped.replace(/^\d+\.\s+/, ""))}</li>`);
76
+ }
77
+ else if (listItems.length === 0 && stripped) {
78
+ preamble += (preamble ? " " : "") + stripped;
79
+ }
80
+ }
81
+ if (preamble)
82
+ htmlBlocks.push(`<p>${inlineFormat(preamble)}</p>`);
83
+ if (listItems.length > 0)
84
+ htmlBlocks.push(`<ol>${listItems.join("")}</ol>`);
85
+ }
86
+ // Paragraph
87
+ else {
88
+ const para = trimmed.replace(/\n/g, " ");
89
+ htmlBlocks.push(`<p>${inlineFormat(para)}</p>`);
90
+ }
91
+ }
92
+ return htmlBlocks.join("\n");
93
+ }
94
+ /**
95
+ * Builds composite HTML from all draft sections, takeaways, FAQs, and citations.
96
+ */
97
+ export function buildFullHtml(draft) {
98
+ const parts = [];
99
+ for (const sec of draft.sections) {
100
+ parts.push(`<h3>${sec.heading}</h3>`);
101
+ if (sec.directAnswer) {
102
+ parts.push(`<blockquote><p><strong>Key takeaway:</strong> ${inlineFormat(sec.directAnswer)}</p></blockquote>`);
103
+ }
104
+ parts.push(markdownToHtml(sec.bodyMarkdown));
105
+ }
106
+ if (draft.faq && draft.faq.length > 0) {
107
+ parts.push(`<h3>Frequently Asked Questions</h3>`);
108
+ for (const item of draft.faq) {
109
+ parts.push(`<h4>${inlineFormat(item.question)}</h4>`);
110
+ parts.push(`<p>${inlineFormat(item.answer)}</p>`);
111
+ }
112
+ }
113
+ if (draft.sources && draft.sources.length > 0) {
114
+ parts.push(`<h4>References &amp; Standards</h4>`);
115
+ const list = draft.sources
116
+ .map((s) => `<li><a href="${s.url}" target="_blank" rel="noopener noreferrer">${inlineFormat(s.title)}</a>${s.claimReference ? ` — <em>${inlineFormat(s.claimReference)}</em>` : ""}</li>`)
117
+ .join("");
118
+ parts.push(`<ul>${list}</ul>`);
119
+ }
120
+ return parts.join("\n\n");
121
+ }
122
+ /**
123
+ * Estimate reading time in minutes from words in draft sections.
124
+ */
125
+ export function calculateReadingTime(draft) {
126
+ const text = draft.sections.map((s) => `${s.heading} ${s.bodyMarkdown}`).join(" ");
127
+ const wordCount = text.trim().split(/\s+/).filter(Boolean).length;
128
+ return Math.max(1, Math.ceil(wordCount / 200));
129
+ }
130
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/adapters/html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from "./html.js";
2
+ export * from "./env-key-vault.js";
3
+ export * from "./supabase-publisher.js";
4
+ export * from "./supabase-run-store.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from "./html.js";
2
+ export * from "./env-key-vault.js";
3
+ export * from "./supabase-publisher.js";
4
+ export * from "./supabase-run-store.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { DraftPost, PublishedCatalogItem, Publisher } from "@begryp/blog-automation-core";
2
+ export interface SupabasePublisherOptions {
3
+ /**
4
+ * Supabase client instance or factory function returning a Supabase client.
5
+ */
6
+ client: any | (() => any);
7
+ /**
8
+ * Database table name for blogs. Defaults to "blogs".
9
+ */
10
+ tableName?: string;
11
+ defaultAuthor?: string;
12
+ defaultAuthorTitle?: string;
13
+ revalidateFn?: (paths: string[]) => Promise<void> | void;
14
+ }
15
+ export declare class SupabasePublisher implements Publisher {
16
+ private readonly getClient;
17
+ private readonly tableName;
18
+ private readonly defaultAuthor;
19
+ private readonly defaultAuthorTitle;
20
+ private readonly revalidateFn?;
21
+ constructor(options: SupabasePublisherOptions);
22
+ getCatalog(_tenantId: string): Promise<PublishedCatalogItem[]>;
23
+ createDraft(draft: DraftPost, runId: string): Promise<string>;
24
+ publish(postId: string): Promise<void>;
25
+ schedule(postId: string, publishAt: string): Promise<void>;
26
+ updateSitemap(_tenantId: string): Promise<void>;
27
+ notifySearchEngines(_url: string): Promise<void>;
28
+ revalidate(paths: string[]): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=supabase-publisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-publisher.d.ts","sourceRoot":"","sources":["../../src/adapters/supabase-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAG/F,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED,qBAAa,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAA4C;gBAE9D,OAAO,EAAE,wBAAwB;IAQvC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAkB9D,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA+C7D,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBtC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAKjD"}
@@ -0,0 +1,120 @@
1
+ import { buildFullHtml, calculateReadingTime } from "./html.js";
2
+ export class SupabasePublisher {
3
+ getClient;
4
+ tableName;
5
+ defaultAuthor;
6
+ defaultAuthorTitle;
7
+ revalidateFn;
8
+ constructor(options) {
9
+ this.getClient = typeof options.client === "function" ? options.client : () => options.client;
10
+ this.tableName = options.tableName || "blogs";
11
+ this.defaultAuthor = options.defaultAuthor || "Editorial Team";
12
+ this.defaultAuthorTitle = options.defaultAuthorTitle || "Staff Author";
13
+ this.revalidateFn = options.revalidateFn;
14
+ }
15
+ async getCatalog(_tenantId) {
16
+ const supabase = this.getClient();
17
+ const { data, error } = await supabase
18
+ .from(this.tableName)
19
+ .select("slug, title, tags")
20
+ .eq("status", "published");
21
+ if (error || !data) {
22
+ return [];
23
+ }
24
+ return data.map((b) => ({
25
+ slug: b.slug,
26
+ title: b.title,
27
+ keywords: Array.isArray(b.tags) ? b.tags : []
28
+ }));
29
+ }
30
+ async createDraft(draft, runId) {
31
+ const supabase = this.getClient();
32
+ const htmlContent = buildFullHtml(draft);
33
+ const readingTime = calculateReadingTime(draft);
34
+ const row = {
35
+ slug: draft.slug,
36
+ title: draft.title,
37
+ summary: draft.summary,
38
+ content: htmlContent,
39
+ content_json: {
40
+ schemaVersion: draft.schemaVersion,
41
+ sections: draft.sections,
42
+ faq: draft.faq,
43
+ sources: draft.sources,
44
+ internalLinks: draft.internalLinks,
45
+ imageBriefs: draft.imageBriefs,
46
+ metaTitle: draft.metaTitle,
47
+ metaDescription: draft.metaDescription,
48
+ lastReviewed: draft.lastReviewed,
49
+ runId
50
+ },
51
+ category: draft.category || "General",
52
+ author: this.defaultAuthor,
53
+ author_title: this.defaultAuthorTitle,
54
+ reading_time_minutes: readingTime,
55
+ tags: draft.tags || [],
56
+ meta_title: draft.metaTitle,
57
+ meta_description: draft.metaDescription,
58
+ ai_disclosed: true,
59
+ status: "draft",
60
+ published_at: draft.publishAt || null
61
+ };
62
+ const { data, error } = await supabase
63
+ .from(this.tableName)
64
+ .upsert(row, { onConflict: "slug" })
65
+ .select("id")
66
+ .single();
67
+ if (error) {
68
+ throw new Error(`Failed to insert blog draft to Supabase: ${error.message}`);
69
+ }
70
+ return String(data?.id || draft.slug);
71
+ }
72
+ async publish(postId) {
73
+ const supabase = this.getClient();
74
+ const { data: current } = await supabase
75
+ .from(this.tableName)
76
+ .select("slug")
77
+ .eq("id", postId)
78
+ .maybeSingle();
79
+ const { error } = await supabase
80
+ .from(this.tableName)
81
+ .update({
82
+ status: "published",
83
+ published_at: new Date().toISOString()
84
+ })
85
+ .eq("id", postId);
86
+ if (error) {
87
+ throw new Error(`Failed to publish blog post ${postId}: ${error.message}`);
88
+ }
89
+ if (this.revalidateFn && current?.slug) {
90
+ await this.revalidateFn(["/blog", `/blog/${current.slug}`, "/"]);
91
+ }
92
+ }
93
+ async schedule(postId, publishAt) {
94
+ const supabase = this.getClient();
95
+ const { error } = await supabase
96
+ .from(this.tableName)
97
+ .update({
98
+ status: "scheduled",
99
+ published_at: publishAt
100
+ })
101
+ .eq("id", postId);
102
+ if (error) {
103
+ throw new Error(`Failed to schedule blog post ${postId}: ${error.message}`);
104
+ }
105
+ }
106
+ async updateSitemap(_tenantId) {
107
+ if (this.revalidateFn) {
108
+ await this.revalidateFn(["/sitemap.xml"]);
109
+ }
110
+ }
111
+ async notifySearchEngines(_url) {
112
+ // No-op by default or triggers IndexNow/Google Search Console webhook if configured
113
+ }
114
+ async revalidate(paths) {
115
+ if (this.revalidateFn) {
116
+ await this.revalidateFn(paths);
117
+ }
118
+ }
119
+ }
120
+ //# sourceMappingURL=supabase-publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-publisher.js","sourceRoot":"","sources":["../../src/adapters/supabase-publisher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { PipelineStage, Run, RunStore } from "@begryp/blog-automation-core";
2
+ export interface SupabaseRunStoreOptions {
3
+ client: any | (() => any);
4
+ tableName?: string;
5
+ }
6
+ export declare class SupabaseRunStore implements RunStore {
7
+ private readonly getClient;
8
+ private readonly tableName;
9
+ constructor(options: SupabaseRunStoreOptions);
10
+ getRun(id: string): Promise<Run | null>;
11
+ getRunByTenantAndTopic(tenantId: string, topicId: string): Promise<Run | null>;
12
+ saveRun(run: Run): Promise<void>;
13
+ saveCheckpoint(runId: string, stage: PipelineStage, payload: unknown): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=supabase-run-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-run-store.d.ts","sourceRoot":"","sources":["../../src/adapters/supabase-run-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEjF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,uBAAuB;IAKtC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAmCvC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAe9E,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBhC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAkB3F"}
@@ -0,0 +1,92 @@
1
+ export class SupabaseRunStore {
2
+ getClient;
3
+ tableName;
4
+ constructor(options) {
5
+ this.getClient = typeof options.client === "function" ? options.client : () => options.client;
6
+ this.tableName = options.tableName || "blog_automation_runs";
7
+ }
8
+ async getRun(id) {
9
+ const supabase = this.getClient();
10
+ const { data, error } = await supabase
11
+ .from(this.tableName)
12
+ .select("*")
13
+ .eq("id", id)
14
+ .maybeSingle();
15
+ if (error || !data)
16
+ return null;
17
+ const checkpoints = data.checkpoints || {};
18
+ const qaReport = data.qa_report;
19
+ return {
20
+ schemaVersion: 1,
21
+ id: data.id,
22
+ tenantId: data.tenant_id,
23
+ topicId: data.topic_id || "unknown",
24
+ status: (data.status === "success" ? "completed" : data.status),
25
+ currentStage: data.stage,
26
+ checkpoints: {
27
+ ...checkpoints,
28
+ ...(qaReport ? { qa: qaReport } : {})
29
+ },
30
+ provider: "openai",
31
+ model: "gpt-4o-mini",
32
+ promptVersion: "v1.0.0",
33
+ revisionCount: 0,
34
+ error: data.error_message || undefined,
35
+ startedAt: data.created_at,
36
+ finishedAt: data.status === "completed" || data.status === "failed" ? data.updated_at : undefined,
37
+ postRef: data.post_id || undefined
38
+ };
39
+ }
40
+ async getRunByTenantAndTopic(tenantId, topicId) {
41
+ const supabase = this.getClient();
42
+ const { data, error } = await supabase
43
+ .from(this.tableName)
44
+ .select("*")
45
+ .eq("tenant_id", tenantId)
46
+ .eq("topic_id", topicId)
47
+ .order("created_at", { ascending: false })
48
+ .limit(1)
49
+ .maybeSingle();
50
+ if (error || !data)
51
+ return null;
52
+ return this.getRun(data.id);
53
+ }
54
+ async saveRun(run) {
55
+ const supabase = this.getClient();
56
+ const statusMap = {
57
+ completed: "success",
58
+ failed: "failed",
59
+ running: "running",
60
+ pending: "pending",
61
+ "needs-review": "pending"
62
+ };
63
+ const row = {
64
+ id: run.id,
65
+ tenant_id: run.tenantId,
66
+ topic_id: run.topicId,
67
+ stage: run.currentStage,
68
+ status: statusMap[run.status] || "running",
69
+ checkpoints: run.checkpoints || {},
70
+ qa_report: run.checkpoints?.qa || null,
71
+ error_message: run.error || null,
72
+ updated_at: new Date().toISOString()
73
+ };
74
+ await supabase.from(this.tableName).upsert(row, { onConflict: "id" });
75
+ }
76
+ async saveCheckpoint(runId, stage, payload) {
77
+ const supabase = this.getClient();
78
+ const existing = await this.getRun(runId);
79
+ const checkpoints = existing?.checkpoints || {};
80
+ checkpoints[stage] = payload;
81
+ const updatePayload = {
82
+ stage: stage,
83
+ checkpoints,
84
+ updated_at: new Date().toISOString()
85
+ };
86
+ if (stage === "qa") {
87
+ updatePayload.qa_report = payload;
88
+ }
89
+ await supabase.from(this.tableName).update(updatePayload).eq("id", runId);
90
+ }
91
+ }
92
+ //# sourceMappingURL=supabase-run-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-run-store.js","sourceRoot":"","sources":["../../src/adapters/supabase-run-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export * from "./runner.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/automation/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export * from "./runner.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/automation/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { type TenantProfile } from "@begryp/blog-automation-core";
2
+ import { SupabasePublisher } from "../adapters/supabase-publisher.js";
3
+ import type { BlogAutomationSettings, GeneratedBlogDraft, RunBlogAutomationOptions, RunBlogAutomationResult } from "./types.js";
4
+ /**
5
+ * Normalizes time string (e.g. "09:00 AM" or "14:30") into 24-hour hours and minutes.
6
+ */
7
+ export declare function parsePublishTime(timeStr?: string): {
8
+ hours: number;
9
+ minutes: number;
10
+ };
11
+ /**
12
+ * Returns current date/time components localized to Africa/Nairobi (EAT, UTC+3).
13
+ */
14
+ export declare function getNairobiDateTime(now?: Date): {
15
+ year: string;
16
+ month: string;
17
+ day: string;
18
+ hour: number;
19
+ minute: number;
20
+ isoDay: number;
21
+ dayName: string;
22
+ localIsoDate: string;
23
+ };
24
+ /**
25
+ * Evaluates whether automation cycle should run right now under Nairobi EAT schedule.
26
+ */
27
+ export declare function isScheduleDue(settings: BlogAutomationSettings, now?: Date): {
28
+ due: boolean;
29
+ reason: string;
30
+ };
31
+ /**
32
+ * Instantly generates a complete blog draft from a given title and category.
33
+ */
34
+ export declare function generateInstantDraft(options: {
35
+ topicTitle: string;
36
+ category?: string;
37
+ tenant: TenantProfile;
38
+ apiKey?: string;
39
+ publisher?: SupabasePublisher;
40
+ }): Promise<GeneratedBlogDraft>;
41
+ /**
42
+ * Runs a full autonomous cycle with research, deduplication, drafting, and Supabase publishing.
43
+ */
44
+ export declare function runAutonomousCycle(options: RunBlogAutomationOptions): Promise<RunBlogAutomationResult>;
45
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/automation/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGtE,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAarF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,OAAa;;;;;;;;;EAkClD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,sBAAsB,EAChC,GAAG,OAAa,GACf;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAmClC;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiE9B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAyClC"}