@inblog/cli 0.2.3 → 0.2.5

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.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # @inblog/cli
2
+
3
+ Command-line tool for managing [inblog.ai](https://inblog.ai) blog content. Create, publish, and manage blog posts, tags, authors, images, and more from your terminal.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @inblog/cli
9
+ ```
10
+
11
+ Requires Node.js 18+.
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ # Authenticate with your API key
17
+ inblog auth login
18
+
19
+ # Check current blog
20
+ inblog auth status
21
+
22
+ # List posts
23
+ inblog posts list
24
+
25
+ # Create and publish a post
26
+ inblog posts create --title "My Post" --slug "my-post" --content-file ./content.html
27
+ inblog posts publish <id>
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ ### Authentication
33
+
34
+ ```bash
35
+ inblog auth login # Login with API key
36
+ inblog auth whoami # Show current user/blog
37
+ inblog auth status # Check auth status
38
+ inblog auth logout # Remove saved credentials
39
+ ```
40
+
41
+ ### Blog Management
42
+
43
+ ```bash
44
+ inblog blogs me # Current blog info
45
+ inblog blogs list # List accessible blogs (OAuth)
46
+ inblog blogs switch [id] # Switch active blog
47
+ inblog blogs update # Update blog settings
48
+ ```
49
+
50
+ **Blog settings:**
51
+
52
+ ```bash
53
+ inblog blogs update --title "Blog Name" --description "About" --language ko
54
+ inblog blogs update --logo ./logo.png --favicon ./favicon.ico --og-image ./og.jpg
55
+ inblog blogs update --ga-id G-XXXXXXXXXX
56
+ ```
57
+
58
+ **Custom domain:**
59
+
60
+ ```bash
61
+ inblog blogs domain connect blog.example.com # Connect + DNS guide
62
+ inblog blogs domain status # Check verification
63
+ inblog blogs domain disconnect # Disconnect
64
+ ```
65
+
66
+ **Banner:**
67
+
68
+ ```bash
69
+ inblog blogs banner get
70
+ inblog blogs banner set --image ./banner.png --title "Title" --subtext "Subtitle"
71
+ inblog blogs banner remove
72
+ ```
73
+
74
+ ### Posts
75
+
76
+ ```bash
77
+ inblog posts list # List all posts
78
+ inblog posts list --published # Published only
79
+ inblog posts list --draft # Drafts only
80
+ inblog posts get <id> # Post details
81
+
82
+ inblog posts create \
83
+ --title "Title" \
84
+ --slug "url-slug" \
85
+ --image ./cover.jpg \
86
+ --content-file ./content.html
87
+
88
+ inblog posts update <id> --title "New Title" --image ./new-cover.jpg
89
+ inblog posts delete <id>
90
+
91
+ inblog posts publish <id> # Publish immediately
92
+ inblog posts unpublish <id> # Unpublish
93
+ inblog posts schedule <id> --at "2026-03-15T09:00:00+09:00"
94
+ ```
95
+
96
+ **Tags & Authors on posts:**
97
+
98
+ ```bash
99
+ inblog posts add-tags <id> --tag-ids 1,2,3
100
+ inblog posts remove-tag <postId> <tagId>
101
+ inblog posts add-authors <id> --author-ids uuid1,uuid2
102
+ inblog posts remove-author <postId> <authorId>
103
+ ```
104
+
105
+ ### Images
106
+
107
+ ```bash
108
+ # Upload images to CDN
109
+ inblog images upload ./photo1.jpg ./photo2.png
110
+ inblog images upload ./cover.jpg -b featured_image --json
111
+ ```
112
+
113
+ Local image files used with `--image` or `--content-file` are automatically uploaded to the CDN.
114
+
115
+ ### Tags
116
+
117
+ ```bash
118
+ inblog tags list
119
+ inblog tags create --name "Tag Name" --slug "tag-slug"
120
+ inblog tags update <id> --name "New Name"
121
+ inblog tags delete <id>
122
+ ```
123
+
124
+ ### Authors
125
+
126
+ ```bash
127
+ inblog authors list
128
+ inblog authors get <id>
129
+ inblog authors update <id> --name "Name" --avatar-url "https://..."
130
+ ```
131
+
132
+ ### Redirects
133
+
134
+ ```bash
135
+ inblog redirects list
136
+ inblog redirects create --from "/old" --to "/new" --type 308
137
+ inblog redirects update <id> --to "/newer"
138
+ inblog redirects delete <id>
139
+ ```
140
+
141
+ ### Forms
142
+
143
+ ```bash
144
+ inblog forms list
145
+ inblog forms get <id>
146
+ inblog form-responses list --form-id <id>
147
+ ```
148
+
149
+ ### Search Console
150
+
151
+ ```bash
152
+ inblog search-console connect # OAuth connect
153
+ inblog search-console status # Connection status
154
+ inblog search-console keywords --sort clicks --limit 20
155
+ inblog search-console pages --sort clicks --limit 20
156
+ ```
157
+
158
+ ### Analytics
159
+
160
+ ```bash
161
+ inblog analytics traffic --interval day # Blog traffic
162
+ inblog analytics posts --sort visits --limit 20 --include title
163
+ inblog analytics sources --limit 20 # Traffic sources
164
+ inblog analytics post <id> --interval day # Single post traffic
165
+ inblog analytics post <id> --sources # Single post sources
166
+ ```
167
+
168
+ ## Global Options
169
+
170
+ | Option | Description |
171
+ |--------|-------------|
172
+ | `--json` | Output as JSON |
173
+ | `--base-url <url>` | Custom API base URL |
174
+ | `--no-color` | Disable colored output |
175
+ | `--api-key <key>` | Use specific API key |
176
+
177
+ ## Image Handling
178
+
179
+ The CLI automatically handles image uploads:
180
+
181
+ - `--image ./cover.jpg` on `posts create/update` uploads the file to CDN
182
+ - `--content-file` scans HTML for local file paths and base64 data URIs, uploads them, and replaces with CDN URLs
183
+ - `--logo`, `--favicon`, `--og-image` on `blogs update` accept local files
184
+ - `inblog images upload` for standalone CDN uploads
185
+
186
+ **Note:** Do not embed base64 images directly in `content_html` API calls (causes 413 errors). Use `--content-file` or upload first with `inblog images upload`.
187
+
188
+ ## API Key
189
+
190
+ Get your API key from [inblog.ai dashboard](https://inblog.ai) > Settings > API Keys. Requires a Team plan or higher.
191
+
192
+ ## AI Skills
193
+
194
+ For AI-assisted blog management (Claude Code, Cursor, GitHub Copilot), install the companion package:
195
+
196
+ ```bash
197
+ npx @inblog/ai-skills
198
+ ```
199
+
200
+ ## License
201
+
202
+ MIT
@@ -1684,6 +1684,7 @@ function registerAuthorsCommands(program2) {
1684
1684
 
1685
1685
  // src/commands/blogs.ts
1686
1686
  var import_prompts2 = require("@inquirer/prompts");
1687
+ var import_open2 = __toESM(require("open"));
1687
1688
 
1688
1689
  // src/utils/domain.ts
1689
1690
  var import_promises = __toESM(require("dns/promises"));
@@ -1832,6 +1833,20 @@ function registerBlogsCommands(program2) {
1832
1833
  handleError(error, json);
1833
1834
  }
1834
1835
  });
1836
+ blogs.command("create").description("Create a new blog (opens inblog.ai in your browser)").action(async function() {
1837
+ const json = isJsonMode(this);
1838
+ try {
1839
+ const url = "https://inblog.ai/dashboard/create?utm_source=cli";
1840
+ if (json) {
1841
+ printJson({ url });
1842
+ } else {
1843
+ printSuccess("Opening inblog.ai to create a new blog...");
1844
+ await (0, import_open2.default)(url);
1845
+ }
1846
+ } catch (error) {
1847
+ handleError(error, json);
1848
+ }
1849
+ });
1835
1850
  blogs.command("list").description("List all blogs you have access to (OAuth only)").action(async function() {
1836
1851
  const json = isJsonMode(this);
1837
1852
  try {
@@ -2418,7 +2433,7 @@ function registerConfigCommands(program2) {
2418
2433
  }
2419
2434
 
2420
2435
  // src/commands/search-console.ts
2421
- var import_open2 = __toESM(require("open"));
2436
+ var import_open3 = __toESM(require("open"));
2422
2437
  function registerSearchConsoleCommands(program2) {
2423
2438
  const sc = program2.command("search-console").description("Google Search Console integration");
2424
2439
  sc.command("connect").description("Connect Google Search Console via OAuth").action(async function() {
@@ -2447,7 +2462,7 @@ function registerSearchConsoleCommands(program2) {
2447
2462
  throw new Error("Failed to retrieve OAuth URL from server.");
2448
2463
  }
2449
2464
  console.log("Opening browser for Google Search Console authorization...");
2450
- await (0, import_open2.default)(url);
2465
+ await (0, import_open3.default)(url);
2451
2466
  console.log("Waiting for authorization...");
2452
2467
  const { code } = await serverPromise;
2453
2468
  await searchConsole.connect(code, redirectUri);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/inblog.ts","../../src/commands/auth.ts","../../src/utils/config.ts","../../src/utils/output.ts","../../src/sdk/deserialize.ts","../../src/sdk/serialize.ts","../../src/sdk/client.ts","../../src/utils/token-store.ts","../../src/utils/token-refresh.ts","../../src/utils/errors.ts","../../src/sdk/endpoints/posts.ts","../../src/sdk/endpoints/tags.ts","../../src/sdk/endpoints/authors.ts","../../src/sdk/endpoints/blogs.ts","../../src/sdk/endpoints/redirects.ts","../../src/sdk/endpoints/forms.ts","../../src/sdk/endpoints/search-console.ts","../../src/sdk/endpoints/analytics.ts","../../src/utils/client-factory.ts","../../src/utils/pkce.ts","../../src/utils/callback-server.ts","../../src/commands/posts.ts","../../src/utils/upload.ts","../../src/commands/tags.ts","../../src/commands/authors.ts","../../src/commands/blogs.ts","../../src/utils/domain.ts","../../src/commands/redirects.ts","../../src/commands/forms.ts","../../src/commands/config.ts","../../src/commands/search-console.ts","../../src/commands/analytics.ts","../../src/commands/images.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerAuthCommands } from '../src/commands/auth.js';\nimport { registerPostsCommands } from '../src/commands/posts.js';\nimport { registerTagsCommands } from '../src/commands/tags.js';\nimport { registerAuthorsCommands } from '../src/commands/authors.js';\nimport { registerBlogsCommands } from '../src/commands/blogs.js';\nimport { registerRedirectsCommands } from '../src/commands/redirects.js';\nimport { registerFormsCommands, registerFormResponsesCommands } from '../src/commands/forms.js';\nimport { registerConfigCommands } from '../src/commands/config.js';\nimport { registerSearchConsoleCommands } from '../src/commands/search-console.js';\nimport { registerAnalyticsCommands } from '../src/commands/analytics.js';\nimport { registerImagesCommands } from '../src/commands/images.js';\n\n\nconst program = new Command();\n\nprogram\n .name('inblog')\n .description('CLI for managing inblog.ai blog content (posts, tags, authors, redirects, forms)')\n .version('0.2.0')\n .option('--json', 'Output as JSON (for programmatic use)')\n .option('--base-url <url>', 'API base URL')\n .option('--no-color', 'Disable colored output');\n\nregisterAuthCommands(program);\nregisterPostsCommands(program);\nregisterTagsCommands(program);\nregisterAuthorsCommands(program);\nregisterBlogsCommands(program);\nregisterRedirectsCommands(program);\nregisterFormsCommands(program);\nregisterFormResponsesCommands(program);\nregisterConfigCommands(program);\nregisterSearchConsoleCommands(program);\nregisterAnalyticsCommands(program);\nregisterImagesCommands(program);\nprogram.parse();\n","import { Command } from 'commander';\nimport { select } from '@inquirer/prompts';\nimport open from 'open';\nimport { readConfig } from '../utils/config.js';\nimport { printJson, printSuccess, printDetail, printWarning } from '../utils/output.js';\nimport { isJsonMode } from '../utils/client-factory.js';\nimport { handleError } from '../utils/errors.js';\nimport { generateCodeVerifier, generateCodeChallenge } from '../utils/pkce.js';\nimport { startCallbackServer } from '../utils/callback-server.js';\nimport { writeSession, readSession, clearSession } from '../utils/token-store.js';\nimport { exchangeCodeForTokens, SUPABASE_URL } from '../utils/token-refresh.js';\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command('auth').description('Manage authentication');\n\n auth\n .command('login')\n .description('Log in with your Google account')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n if (json) {\n throw new Error('Interactive login is not available in --json mode.');\n }\n\n // Check if already logged in\n const existingSession = readSession();\n if (existingSession) {\n printWarning('Already logged in. Run `inblog auth logout` first to switch accounts.');\n return;\n }\n\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n\n // Start callback server\n const serverPromise = startCallbackServer();\n\n // Wait a tick for the server to start, then open browser\n await new Promise((r) => setTimeout(r, 100));\n\n const redirectUri = `http://127.0.0.1:54321/auth/callback`;\n const authUrl = new URL(`${SUPABASE_URL}/auth/v1/authorize`);\n authUrl.searchParams.set('provider', 'google');\n authUrl.searchParams.set('redirect_to', redirectUri);\n authUrl.searchParams.set('code_challenge', codeChallenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n\n console.log('Opening browser for login...');\n await open(authUrl.toString());\n console.log('Waiting for authentication...');\n\n // Wait for callback\n const { code } = await serverPromise;\n\n // Exchange code for tokens\n const tokens = await exchangeCodeForTokens(code, codeVerifier);\n\n // Fetch user's blogs to pick an active one\n const config = readConfig();\n const baseUrl = this.optsWithGlobals().baseUrl || config.baseUrl || 'https://inblog.ai';\n const response = await fetch(`${baseUrl}/api/v1/user/blogs`, {\n headers: {\n Authorization: `Bearer ${tokens.access_token}`,\n 'X-Blog-Id': '0',\n Accept: 'application/vnd.api+json',\n },\n });\n\n if (!response.ok) {\n writeSession({ tokens });\n printSuccess('Logged in successfully.');\n printWarning('Could not fetch blog list. Run `inblog blogs list` to select a blog.');\n return;\n }\n\n const blogsData: any = await response.json();\n const blogs = blogsData.data || [];\n\n if (blogs.length === 0) {\n writeSession({ tokens });\n printSuccess('Logged in, but you have no blogs yet.');\n return;\n }\n\n let activeBlogId: number;\n let activeBlogSubdomain: string;\n let activeBlogPlan: string | undefined;\n\n if (blogs.length === 1) {\n activeBlogId = parseInt(blogs[0].id, 10);\n activeBlogSubdomain = blogs[0].attributes.subdomain;\n activeBlogPlan = blogs[0].attributes.plan;\n } else {\n const choices = blogs.map((b: any) => ({\n name: `${b.attributes.title} (${b.attributes.subdomain}) [${b.attributes.permission}]`,\n value: { id: parseInt(b.id, 10), subdomain: b.attributes.subdomain },\n }));\n\n const selected = await select<{ id: number; subdomain: string }>({\n message: 'Select a blog to use:',\n choices,\n });\n\n activeBlogId = selected.id;\n activeBlogSubdomain = selected.subdomain;\n const selectedBlog = blogs.find((b: any) => parseInt(b.id, 10) === activeBlogId);\n activeBlogPlan = selectedBlog?.attributes.plan;\n }\n\n writeSession({\n tokens,\n activeBlogId,\n activeBlogSubdomain,\n activeBlogPlan,\n });\n\n printSuccess(`Logged in. Active blog: ${activeBlogSubdomain}`);\n\n if (activeBlogPlan !== 'team' && activeBlogPlan !== 'enterprise') {\n printWarning(`Blog \"${activeBlogSubdomain}\" is on the ${activeBlogPlan || 'free'} plan.`);\n printWarning(' CLI features require a Team plan or above.');\n printWarning(` Upgrade: https://inblog.ai/dashboard/${activeBlogSubdomain}/settings/billing`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n auth\n .command('logout')\n .description('Log out and clear stored session')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n if (json) {\n printJson({ success: true, message: 'Already logged out' });\n } else {\n printWarning('Already logged out.');\n }\n return;\n }\n\n clearSession();\n if (json) {\n printJson({ success: true, message: 'Logged out' });\n } else {\n printSuccess('Logged out.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n auth\n .command('status')\n .description('Show current login status')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n if (json) {\n printJson({ loggedIn: false });\n } else {\n console.log('Not logged in. Run `inblog auth login` to authenticate.');\n }\n return;\n }\n\n const expiresAt = new Date(session.tokens.expires_at * 1000).toISOString();\n\n if (json) {\n printJson({\n loggedIn: true,\n userId: session.tokens.user_id,\n activeBlogId: session.activeBlogId,\n activeBlogSubdomain: session.activeBlogSubdomain,\n tokenExpiresAt: expiresAt,\n });\n } else {\n printDetail([\n ['User ID', session.tokens.user_id],\n ['Active Blog', session.activeBlogSubdomain || '—'],\n ['Active Blog ID', session.activeBlogId || '—'],\n ['Token Expires', expiresAt],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\nexport interface InblogConfig {\n apiKey?: string;\n baseUrl?: string;\n defaultJson?: boolean;\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), '.config', 'inblog');\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');\nconst LOCAL_CONFIG_FILE = '.inblogrc.json';\n\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function getGlobalConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function getLocalConfigPath(): string | null {\n const localPath = path.resolve(LOCAL_CONFIG_FILE);\n return fs.existsSync(localPath) ? localPath : null;\n}\n\nexport function readGlobalConfig(): InblogConfig {\n if (!fs.existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function readLocalConfig(): InblogConfig {\n const localPath = path.resolve(LOCAL_CONFIG_FILE);\n if (!fs.existsSync(localPath)) return {};\n try {\n return JSON.parse(fs.readFileSync(localPath, 'utf-8'));\n } catch {\n return {};\n }\n}\n\n/**\n * Merged config: local overrides global.\n */\nexport function readConfig(): InblogConfig {\n const global = readGlobalConfig();\n const local = readLocalConfig();\n return { ...global, ...local };\n}\n\nexport function writeGlobalConfig(config: InblogConfig): void {\n ensureConfigDir();\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function setGlobalConfigValue(key: string, value: any): void {\n const config = readGlobalConfig();\n (config as any)[key] = value;\n writeGlobalConfig(config);\n}\n\nexport function deleteGlobalConfigValue(key: string): void {\n const config = readGlobalConfig();\n delete (config as any)[key];\n writeGlobalConfig(config);\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\n/**\n * Print JSON to stdout (for --json mode).\n */\nexport function printJson(data: any): void {\n process.stdout.write(JSON.stringify(data, null, 2) + '\\n');\n}\n\n/**\n * Print a styled table to stdout.\n */\nexport function printTable(\n headers: string[],\n rows: (string | number | null | undefined)[][],\n): void {\n const table = new Table({\n head: headers.map((h) => chalk.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n table.push(row.map((cell) => (cell == null ? chalk.dim('—') : String(cell))));\n }\n console.log(table.toString());\n}\n\n/**\n * Print a key-value detail view.\n */\nexport function printDetail(entries: [string, any][]): void {\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n for (const [key, value] of entries) {\n const label = chalk.cyan(key.padEnd(maxKeyLen));\n const val = value == null ? chalk.dim('—') : String(value);\n console.log(` ${label} ${val}`);\n }\n}\n\n/**\n * Print success message.\n */\nexport function printSuccess(message: string): void {\n console.log(chalk.green(message));\n}\n\n/**\n * Print warning message.\n */\nexport function printWarning(message: string): void {\n console.error(chalk.yellow(message));\n}\n\n/**\n * Print error message to stderr.\n */\nexport function printError(message: string): void {\n console.error(chalk.red(message));\n}\n\n/**\n * Truncate string for table display.\n */\nexport function truncate(str: string | null | undefined, maxLen: number = 50): string {\n if (!str) return '';\n return str.length > maxLen ? str.slice(0, maxLen - 1) + '…' : str;\n}\n","import type { JsonApiResource, JsonApiResponse } from './types.js';\n\n/**\n * Resolve included resources for a relationship.\n */\nfunction resolveRelationship(\n rel: { data: { type: string; id: string } | { type: string; id: string }[] | null },\n included: JsonApiResource[],\n): any {\n if (!rel.data) return null;\n\n if (Array.isArray(rel.data)) {\n return rel.data.map((ref) => {\n const found = included.find((r) => r.type === ref.type && r.id === ref.id);\n return found ? flattenResource(found, included) : { id: ref.id, type: ref.type };\n });\n }\n\n const ref = rel.data as { type: string; id: string };\n const found = included.find((r) => r.type === ref.type && r.id === ref.id);\n return found ? flattenResource(found, included) : { id: ref.id, type: ref.type };\n}\n\n/**\n * Flatten a JSON:API resource into a plain object.\n * Merges id + attributes + resolved relationships.\n */\nexport function flattenResource(\n resource: JsonApiResource,\n included: JsonApiResource[] = [],\n): Record<string, any> {\n const result: Record<string, any> = {\n id: resource.id,\n ...resource.attributes,\n };\n\n if (resource.relationships) {\n for (const [key, rel] of Object.entries(resource.relationships)) {\n result[key] = resolveRelationship(rel, included);\n }\n }\n\n return result;\n}\n\n/**\n * Deserialize a JSON:API response into flat object(s).\n */\nexport function deserialize<T = Record<string, any>>(\n response: JsonApiResponse<JsonApiResource>,\n): T;\nexport function deserialize<T = Record<string, any>>(\n response: JsonApiResponse<JsonApiResource[]>,\n): T[];\nexport function deserialize<T = Record<string, any>>(\n response: JsonApiResponse,\n): T | T[] {\n const included = response.included ?? [];\n\n if (Array.isArray(response.data)) {\n return response.data.map((r) => flattenResource(r, included)) as T[];\n }\n\n return flattenResource(response.data, included) as T;\n}\n\n/**\n * Extract pagination meta from a JSON:API response.\n */\nexport function extractMeta(response: JsonApiResponse): {\n total?: number;\n page?: number;\n limit?: number;\n hasNext: boolean;\n} {\n return {\n total: response.meta?.total,\n page: response.meta?.page,\n limit: response.meta?.limit,\n hasNext: !!response.links?.next,\n };\n}\n","/**\n * Build a JSON:API request body (simplified format).\n * The inblog API accepts both wrapped and unwrapped formats;\n * we use the simplified format: { type, attributes }.\n */\nexport function serialize(\n type: string,\n attributes: Record<string, any>,\n id?: string,\n): { data: { type: string; id?: string; attributes: Record<string, any> } } {\n const resource: { type: string; id?: string; attributes: Record<string, any> } = {\n type,\n attributes,\n };\n\n if (id !== undefined) {\n resource.id = id;\n }\n\n return { data: resource };\n}\n","import type { JsonApiResponse, JsonApiErrorResponse, JsonApiResource } from './types.js';\nimport { deserialize, extractMeta } from './deserialize.js';\nimport { serialize } from './serialize.js';\n\nexport class InblogApiError extends Error {\n status: number;\n code: string;\n title: string;\n detail?: string;\n\n constructor(status: number, code: string, title: string, detail?: string) {\n super(detail || title);\n this.name = 'InblogApiError';\n this.status = status;\n this.code = code;\n this.title = title;\n this.detail = detail;\n }\n}\n\nexport interface ClientOptions {\n apiKey?: string;\n accessToken?: string;\n baseUrl?: string;\n blogId?: number;\n blogSubdomain?: string;\n}\n\nexport class InblogClient {\n private apiKey?: string;\n private accessToken?: string;\n private baseUrl: string;\n private blogId?: number;\n private blogSubdomain?: string;\n private tokenRefresher?: () => Promise<string | null>;\n\n constructor(options: ClientOptions) {\n this.apiKey = options.apiKey;\n this.accessToken = options.accessToken;\n this.baseUrl = (options.baseUrl ?? 'https://inblog.ai').replace(/\\/$/, '');\n this.blogId = options.blogId;\n this.blogSubdomain = options.blogSubdomain;\n\n if (!this.apiKey && !this.accessToken) {\n throw new Error('Either apiKey or accessToken must be provided');\n }\n }\n\n setTokenRefresher(fn: () => Promise<string | null>): void {\n this.tokenRefresher = fn;\n }\n\n private async readHeaders(): Promise<Record<string, string>> {\n const token = await this.resolveToken();\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.api+json',\n };\n if (this.accessToken && this.blogId) {\n headers['X-Blog-Id'] = String(this.blogId);\n }\n return headers;\n }\n\n private async writeHeaders(): Promise<Record<string, string>> {\n const token = await this.resolveToken();\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/vnd.api+json',\n Accept: 'application/vnd.api+json',\n };\n if (this.accessToken && this.blogId) {\n headers['X-Blog-Id'] = String(this.blogId);\n }\n return headers;\n }\n\n private async resolveToken(): Promise<string> {\n if (this.apiKey) return this.apiKey;\n if (this.tokenRefresher) {\n const refreshed = await this.tokenRefresher();\n if (refreshed) {\n this.accessToken = refreshed;\n return refreshed;\n }\n }\n if (this.accessToken) return this.accessToken;\n throw new Error('No valid authentication token available');\n }\n\n private buildUrl(path: string, params?: Record<string, any>): string {\n const url = new URL(`/api${path}`, this.baseUrl);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle nested params like filter[slug]=xxx\n for (const [subKey, subValue] of Object.entries(value)) {\n if (subValue !== undefined && subValue !== null) {\n url.searchParams.set(`${key}[${subKey}]`, String(subValue));\n }\n }\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n private async handleResponse(response: Response): Promise<JsonApiResponse> {\n const text = await response.text();\n let body: any;\n\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n throw new InblogApiError(response.status, 'PARSE_ERROR', 'Failed to parse API response');\n }\n\n if (!response.ok) {\n if (body?.errors?.[0]) {\n const err = body.errors[0];\n throw new InblogApiError(\n parseInt(err.status, 10) || response.status,\n err.code || 'UNKNOWN_ERROR',\n err.title || 'API Error',\n err.detail,\n );\n }\n throw new InblogApiError(response.status, 'UNKNOWN_ERROR', `HTTP ${response.status}`);\n }\n\n return body;\n }\n\n async get<T = Record<string, any>>(\n path: string,\n params?: Record<string, any>,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path, params);\n const response = await fetch(url, { method: 'GET', headers: await this.readHeaders() });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async list<T = Record<string, any>>(\n path: string,\n params?: Record<string, any>,\n ): Promise<{ data: T[]; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path, params);\n const response = await fetch(url, { method: 'GET', headers: await this.readHeaders() });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource[]>),\n meta: extractMeta(json),\n };\n }\n\n async create<T = Record<string, any>>(\n path: string,\n type: string,\n attributes: Record<string, any>,\n params?: Record<string, any>,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path, params);\n const body = serialize(type, attributes);\n const response = await fetch(url, {\n method: 'POST',\n headers: await this.writeHeaders(),\n body: JSON.stringify(body),\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async update<T = Record<string, any>>(\n path: string,\n type: string,\n id: string,\n attributes: Record<string, any>,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path);\n const body = serialize(type, attributes, id);\n const response = await fetch(url, {\n method: 'PATCH',\n headers: await this.writeHeaders(),\n body: JSON.stringify(body),\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async delete(path: string): Promise<void> {\n const url = this.buildUrl(path);\n const response = await fetch(url, { method: 'DELETE', headers: await this.readHeaders() });\n if (!response.ok) {\n await this.handleResponse(response); // will throw\n }\n }\n\n async post<T = Record<string, any>>(\n path: string,\n body?: any,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path);\n const response = await fetch(url, {\n method: 'POST',\n headers: await this.writeHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async patch<T = Record<string, any>>(\n path: string,\n body?: any,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path);\n const response = await fetch(url, {\n method: 'PATCH',\n headers: await this.writeHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n /**\n * Raw GET — for non-JSON:API endpoints that return plain JSON.\n */\n async rawGet(path: string, params?: Record<string, any>): Promise<any> {\n const url = this.buildUrl(path, params);\n const response = await fetch(url, { method: 'GET', headers: await this.readHeaders() });\n return this.handleRawResponse(response);\n }\n\n /**\n * Raw POST — for non-JSON:API endpoints.\n */\n async rawPost(path: string, body?: any): Promise<any> {\n const url = this.buildUrl(path);\n const headers = await this.readHeaders();\n headers['Content-Type'] = 'application/json';\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n return this.handleRawResponse(response);\n }\n\n /**\n * Raw PATCH — for non-JSON:API endpoints.\n */\n async rawPatch(path: string, body?: any): Promise<any> {\n const url = this.buildUrl(path);\n const headers = await this.readHeaders();\n headers['Content-Type'] = 'application/json';\n const response = await fetch(url, {\n method: 'PATCH',\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n return this.handleRawResponse(response);\n }\n\n /**\n * Raw DELETE — for non-JSON:API endpoints.\n */\n async rawDelete(path: string): Promise<any> {\n const url = this.buildUrl(path);\n const response = await fetch(url, { method: 'DELETE', headers: await this.readHeaders() });\n if (response.status === 204) return { success: true };\n return this.handleRawResponse(response);\n }\n\n private async handleRawResponse(response: Response): Promise<any> {\n const text = await response.text();\n let body: any;\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n if (!response.ok) {\n throw new InblogApiError(response.status, 'PARSE_ERROR', 'Failed to parse API response');\n }\n return text;\n }\n if (!response.ok) {\n if (body?.errors?.[0]) {\n const err = body.errors[0];\n throw new InblogApiError(\n parseInt(err.status, 10) || response.status,\n err.code || 'UNKNOWN_ERROR',\n err.title || 'API Error',\n err.detail,\n );\n }\n throw new InblogApiError(response.status, 'UNKNOWN_ERROR', body?.message || `HTTP ${response.status}`);\n }\n return body;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\nconst CONFIG_DIR = path.join(os.homedir(), '.config', 'inblog');\nconst TOKENS_FILE = path.join(CONFIG_DIR, 'tokens.json');\n\nexport interface StoredTokens {\n access_token: string;\n refresh_token: string;\n expires_at: number;\n user_id: string;\n}\n\nexport interface StoredSession {\n tokens: StoredTokens;\n activeBlogId?: number;\n activeBlogSubdomain?: string;\n activeBlogPlan?: string;\n}\n\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function readSession(): StoredSession | null {\n if (!fs.existsSync(TOKENS_FILE)) return null;\n try {\n return JSON.parse(fs.readFileSync(TOKENS_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nexport function writeSession(session: StoredSession): void {\n ensureConfigDir();\n fs.writeFileSync(TOKENS_FILE, JSON.stringify(session, null, 2) + '\\n', {\n encoding: 'utf-8',\n mode: 0o600,\n });\n}\n\nexport function clearSession(): void {\n if (fs.existsSync(TOKENS_FILE)) {\n fs.unlinkSync(TOKENS_FILE);\n }\n}\n\nexport function setActiveBlog(blogId: number, subdomain: string, plan?: string): void {\n const session = readSession();\n if (!session) {\n throw new Error('Not logged in. Run `inblog auth login` first.');\n }\n session.activeBlogId = blogId;\n session.activeBlogSubdomain = subdomain;\n if (plan !== undefined) session.activeBlogPlan = plan;\n writeSession(session);\n}\n","import { readSession, writeSession, type StoredSession, type StoredTokens } from './token-store.js';\n\nconst SUPABASE_URL =\n process.env.INBLOG_SUPABASE_URL || 'https://fgobbnslcbjgothosvni.supabase.co';\nconst SUPABASE_ANON_KEY =\n process.env.INBLOG_SUPABASE_ANON_KEY ||\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZnb2JibnNsY2JqZ290aG9zdm5pIiwicm9sZSI6ImFub24iLCJpYXQiOjE2Nzc5OTc1MzYsImV4cCI6MTk5MzU3MzUzNn0.cFlx12_PLf42IHJseAxiYOw7MFiS2FOSRgbSZQNDiEo';\n\n// Refresh buffer: refresh 60 seconds before actual expiry\nconst REFRESH_BUFFER_SECONDS = 60;\n\nexport { SUPABASE_URL, SUPABASE_ANON_KEY };\n\nfunction isTokenExpiringSoon(session: StoredSession): boolean {\n const now = Math.floor(Date.now() / 1000);\n return session.tokens.expires_at - now < REFRESH_BUFFER_SECONDS;\n}\n\nasync function refreshTokens(refreshToken: string): Promise<StoredTokens> {\n const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=refresh_token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n apikey: SUPABASE_ANON_KEY,\n },\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n\n if (!response.ok) {\n throw new Error('Session expired. Run `inblog auth login` to re-authenticate.');\n }\n\n const data: any = await response.json();\n\n return {\n access_token: data.access_token,\n refresh_token: data.refresh_token,\n expires_at: Math.floor(Date.now() / 1000) + data.expires_in,\n user_id: data.user?.id || '',\n };\n}\n\n/**\n * Get a valid access token, refreshing if needed.\n * Returns null if no OAuth session exists.\n */\nexport async function getValidAccessToken(): Promise<string | null> {\n const session = readSession();\n if (!session) return null;\n\n if (!isTokenExpiringSoon(session)) {\n return session.tokens.access_token;\n }\n\n // Refresh the token\n const newTokens = await refreshTokens(session.tokens.refresh_token);\n session.tokens = newTokens;\n writeSession(session);\n\n return newTokens.access_token;\n}\n\n/**\n * Exchange authorization code for tokens using PKCE.\n */\nexport async function exchangeCodeForTokens(\n code: string,\n codeVerifier: string,\n): Promise<StoredTokens> {\n const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=pkce`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n apikey: SUPABASE_ANON_KEY,\n },\n body: JSON.stringify({\n auth_code: code,\n code_verifier: codeVerifier,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.text();\n throw new Error(`Token exchange failed: ${errorData}`);\n }\n\n const data: any = await response.json();\n\n return {\n access_token: data.access_token,\n refresh_token: data.refresh_token,\n expires_at: Math.floor(Date.now() / 1000) + data.expires_in,\n user_id: data.user?.id || '',\n };\n}\n","import { InblogApiError } from '../sdk/client.js';\nimport { printError, printJson } from './output.js';\nimport { readSession } from './token-store.js';\n\n/**\n * Check if active blog plan allows CLI usage (team or enterprise).\n * Exits with error if plan is insufficient.\n */\nexport function checkPlanOrExit(): void {\n const session = readSession();\n if (!session) return; // Not logged in — will fail at auth check anyway\n\n const plan = session.activeBlogPlan;\n if (plan === 'team' || plan === 'enterprise') return; // OK\n if (!plan) return; // No plan info cached — let the server decide\n\n printError(`CLI features require a Team plan or above. Current plan: ${plan}`);\n printError(`Upgrade: https://inblog.ai/dashboard/${session.activeBlogSubdomain || ''}/settings/billing`);\n process.exit(1);\n}\n\n/**\n * Handle errors in CLI commands.\n * In --json mode, outputs structured error JSON to stderr.\n * Otherwise prints human-friendly message.\n */\nexport function handleError(error: unknown, json: boolean = false): never {\n if (error instanceof InblogApiError) {\n if (json) {\n const errorObj = {\n error: true,\n status: error.status,\n code: error.code,\n title: error.title,\n detail: error.detail,\n };\n process.stderr.write(JSON.stringify(errorObj, null, 2) + '\\n');\n } else {\n printError(`API Error (${error.status}): ${error.title}`);\n if (error.detail) {\n printError(` ${error.detail}`);\n }\n if (error.code === 'SUBSCRIPTION_REQUIRED') {\n printError(' API access requires a paid plan. Upgrade at https://inblog.ai/dashboard/settings/billing');\n }\n }\n process.exit(2);\n }\n\n if (error instanceof Error) {\n if (json) {\n process.stderr.write(JSON.stringify({ error: true, message: error.message }, null, 2) + '\\n');\n } else {\n printError(error.message);\n }\n process.exit(1);\n }\n\n printError('An unexpected error occurred');\n process.exit(1);\n}\n\n/**\n * Wrap an async command handler with error handling.\n */\nexport function withErrorHandler(\n fn: (...args: any[]) => Promise<void>,\n getJson: (...args: any[]) => boolean,\n): (...args: any[]) => Promise<void> {\n return async (...args: any[]) => {\n try {\n await fn(...args);\n } catch (error) {\n handleError(error, getJson(...args));\n }\n };\n}\n","import type { InblogClient } from '../client.js';\nimport type {\n Post, Author, Tag, PostCreateInput, PostUpdateInput, PostListOptions,\n} from '../types.js';\n\nexport class PostsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: PostListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n if (options.sort) params.sort = options.sort;\n if (options.order) params.order = options.order;\n if (options.include?.length) params.include = options.include.join(',');\n if (options.filter) params.filter = options.filter;\n return this.client.list<Post>('/v1/posts', params);\n }\n\n async get(id: string, include?: string[]) {\n const params: Record<string, any> = {};\n if (include?.length) params.include = include.join(',');\n return this.client.get<Post>(`/v1/posts/${id}`, params);\n }\n\n async create(input: PostCreateInput) {\n const { tag_ids, author_ids, ...attributes } = input;\n const attrs: Record<string, any> = { ...attributes };\n if (tag_ids) attrs.tag_ids = tag_ids;\n if (author_ids) attrs.author_ids = author_ids;\n return this.client.create<Post>('/v1/posts', 'posts', attrs, {\n include: 'tags,authors',\n });\n }\n\n async update(id: string, input: PostUpdateInput) {\n return this.client.update<Post>(`/v1/posts/${id}`, 'posts', id, input as Record<string, any>);\n }\n\n async delete(id: string) {\n return this.client.delete(`/v1/posts/${id}`);\n }\n\n async publish(id: string) {\n return this.client.post<Post>(`/v1/posts/${id}/publish`);\n }\n\n async unpublish(id: string) {\n return this.client.post<Post>(`/v1/posts/${id}/unpublish`);\n }\n\n async schedule(id: string, scheduledAt: string) {\n return this.client.post<Post>(`/v1/posts/${id}/schedule`, {\n data: { type: 'posts', attributes: { published_at: scheduledAt } },\n });\n }\n\n // ── Relationship management ──\n\n async listTags(postId: string) {\n return this.client.list<Tag>(`/v1/posts/${postId}/tags`);\n }\n\n async addTags(postId: string, tagIds: number[]) {\n return this.client.post<Post>(`/v1/posts/${postId}/tags`, {\n data: tagIds.map((id) => ({ id })),\n });\n }\n\n async removeTag(postId: string, tagId: string) {\n return this.client.delete(`/v1/posts/${postId}/tags/${tagId}`);\n }\n\n async listAuthors(postId: string) {\n return this.client.list<Author>(`/v1/posts/${postId}/authors`);\n }\n\n async addAuthors(postId: string, authorIds: string[]) {\n return this.client.post<Post>(`/v1/posts/${postId}/authors`, {\n data: authorIds.map((id) => ({ id })),\n });\n }\n\n async removeAuthor(postId: string, authorId: string) {\n return this.client.delete(`/v1/posts/${postId}/authors/${authorId}`);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Tag, TagCreateInput, TagUpdateInput, TagListOptions } from '../types.js';\n\nexport class TagsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: TagListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.include?.length) params.include = options.include.join(',');\n return this.client.list<Tag>('/v1/tags', params);\n }\n\n async get(id: string) {\n return this.client.get<Tag>(`/v1/tags/${id}`);\n }\n\n async create(input: TagCreateInput) {\n return this.client.create<Tag>('/v1/tags', 'tags', input as Record<string, any>);\n }\n\n async update(id: string, input: TagUpdateInput) {\n return this.client.update<Tag>(`/v1/tags/${id}`, 'tags', id, input as Record<string, any>);\n }\n\n async delete(id: string) {\n return this.client.delete(`/v1/tags/${id}`);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Author, AuthorUpdateInput, AuthorListOptions } from '../types.js';\n\nexport class AuthorsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: AuthorListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n if (options.include?.length) params.include = options.include.join(',');\n return this.client.list<Author>('/v1/authors', params);\n }\n\n async get(id: string) {\n return this.client.get<Author>(`/v1/authors/${id}`);\n }\n\n async update(id: string, input: AuthorUpdateInput) {\n return this.client.update<Author>(\n `/v1/authors/${id}`,\n 'authors',\n id,\n input as Record<string, any>,\n );\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Blog, BlogUpdateInput } from '../types.js';\n\nexport class BlogsEndpoint {\n constructor(private client: InblogClient) {}\n\n async me() {\n return this.client.get<Blog>('/v1/blogs/me');\n }\n\n async update(input: BlogUpdateInput) {\n return this.client.update<Blog>(\n '/v1/blogs/me',\n 'blogs',\n 'me',\n input as Record<string, any>,\n );\n }\n\n // Domain management (plain JSON endpoints, not JSON:API)\n\n async domainConnect(domain: string) {\n return this.client.rawPost('/v1/blogs/domain', { custom_domain: domain });\n }\n\n async domainStatus() {\n return this.client.rawGet('/v1/blogs/domain');\n }\n\n async domainDisconnect() {\n return this.client.rawDelete('/v1/blogs/domain');\n }\n\n // Custom UI / Banner (plain JSON endpoints)\n\n async getCustomUi() {\n return this.client.rawGet('/v1/blogs/custom-ui');\n }\n\n async updateCustomUi(input: Record<string, any>) {\n return this.client.rawPatch('/v1/blogs/custom-ui', input);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Redirect, RedirectCreateInput, RedirectUpdateInput, RedirectListOptions } from '../types.js';\n\nexport class RedirectsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: RedirectListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n return this.client.list<Redirect>('/v1/redirects', params);\n }\n\n async get(id: string) {\n return this.client.get<Redirect>(`/v1/redirects/${id}`);\n }\n\n async create(input: RedirectCreateInput) {\n return this.client.create<Redirect>('/v1/redirects', 'redirects', input as Record<string, any>);\n }\n\n async update(id: string, input: RedirectUpdateInput) {\n return this.client.update<Redirect>(\n `/v1/redirects/${id}`,\n 'redirects',\n id,\n input as Record<string, any>,\n );\n }\n\n async delete(id: string) {\n return this.client.delete(`/v1/redirects/${id}`);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Form, FormResponse, FormListOptions, FormResponseListOptions } from '../types.js';\n\nexport class FormsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: FormListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n return this.client.list<Form>('/v1/forms', params);\n }\n\n async get(id: string) {\n return this.client.get<Form>(`/v1/forms/${id}`);\n }\n}\n\nexport class FormResponsesEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: FormResponseListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n if (options.filter) params.filter = options.filter;\n return this.client.list<FormResponse>('/v1/form-responses', params);\n }\n\n async get(id: string) {\n return this.client.get<FormResponse>(`/v1/form-responses/${id}`);\n }\n}\n","import type { InblogClient } from '../client.js';\n\nexport class SearchConsoleEndpoint {\n constructor(private client: InblogClient) {}\n\n async oauthUrl(redirectUri?: string) {\n const params: Record<string, string> = {};\n if (redirectUri) params.redirect_uri = redirectUri;\n return this.client.rawGet('/v1/blogs/search-console/oauth-url', params);\n }\n\n async connect(code: string, redirectUri: string) {\n return this.client.rawPost('/v1/blogs/search-console/connect', { code, redirect_uri: redirectUri });\n }\n\n async status() {\n return this.client.rawGet('/v1/blogs/search-console/status');\n }\n\n async disconnect() {\n return this.client.rawDelete('/v1/blogs/search-console/disconnect');\n }\n\n async keywords(options: { start_date?: string; end_date?: string; limit?: number; sort?: string; order?: string } = {}) {\n return this.client.rawGet('/v1/blogs/search-console/keywords', options);\n }\n\n async pages(options: { start_date?: string; end_date?: string; limit?: number; sort?: string; order?: string } = {}) {\n return this.client.rawGet('/v1/blogs/search-console/pages', options);\n }\n}\n","import type { InblogClient } from '../client.js';\n\nexport class AnalyticsEndpoint {\n constructor(private client: InblogClient) {}\n\n async traffic(options: { start_date?: string; end_date?: string; interval?: string; type?: string } = {}) {\n return this.client.rawGet('/v1/blogs/analytics/traffic', options);\n }\n\n async posts(options: { start_date?: string; end_date?: string; sort?: string; order?: string; limit?: number; include?: string } = {}) {\n return this.client.rawGet('/v1/blogs/analytics/posts', options);\n }\n\n async sources(options: { start_date?: string; end_date?: string; limit?: number } = {}) {\n return this.client.rawGet('/v1/blogs/analytics/sources', options);\n }\n\n async postTraffic(postId: number, options: { start_date?: string; end_date?: string; interval?: string } = {}) {\n return this.client.rawGet(`/v1/blogs/analytics/posts/${postId}`, options);\n }\n\n async postSources(postId: number, options: { start_date?: string; end_date?: string; limit?: number } = {}) {\n return this.client.rawGet(`/v1/blogs/analytics/posts/${postId}/sources`, options);\n }\n}\n","import { Command } from 'commander';\nimport { InblogClient } from '../sdk/client.js';\nimport { readConfig } from './config.js';\nimport { readSession } from './token-store.js';\nimport { getValidAccessToken } from './token-refresh.js';\nimport { checkPlanOrExit } from './errors.js';\nimport { PostsEndpoint } from '../sdk/endpoints/posts.js';\nimport { TagsEndpoint } from '../sdk/endpoints/tags.js';\nimport { AuthorsEndpoint } from '../sdk/endpoints/authors.js';\nimport { BlogsEndpoint } from '../sdk/endpoints/blogs.js';\nimport { RedirectsEndpoint } from '../sdk/endpoints/redirects.js';\nimport { FormsEndpoint, FormResponsesEndpoint } from '../sdk/endpoints/forms.js';\nimport { SearchConsoleEndpoint } from '../sdk/endpoints/search-console.js';\nimport { AnalyticsEndpoint } from '../sdk/endpoints/analytics.js';\n\nexport interface ClientContext {\n client: InblogClient;\n posts: PostsEndpoint;\n tags: TagsEndpoint;\n authors: AuthorsEndpoint;\n blogs: BlogsEndpoint;\n redirects: RedirectsEndpoint;\n forms: FormsEndpoint;\n formResponses: FormResponsesEndpoint;\n searchConsole: SearchConsoleEndpoint;\n analytics: AnalyticsEndpoint;\n}\n\n/**\n * Create SDK client from CLI global options.\n */\nexport function createClientFromCommand(cmd: Command): ClientContext {\n checkPlanOrExit();\n const opts = cmd.optsWithGlobals();\n const config = readConfig();\n const baseUrl = opts.baseUrl || config.baseUrl || 'https://inblog.ai';\n\n const session = readSession();\n if (!session) {\n throw new Error('Not logged in. Run `inblog auth login` to authenticate.');\n }\n\n if (!session.activeBlogId || !session.activeBlogSubdomain) {\n throw new Error(\n 'No active blog selected. Run `inblog blogs switch` to select a blog.',\n );\n }\n\n const client = new InblogClient({\n accessToken: session.tokens.access_token,\n baseUrl,\n blogId: session.activeBlogId,\n blogSubdomain: session.activeBlogSubdomain,\n });\n client.setTokenRefresher(getValidAccessToken);\n\n return {\n client,\n posts: new PostsEndpoint(client),\n tags: new TagsEndpoint(client),\n authors: new AuthorsEndpoint(client),\n blogs: new BlogsEndpoint(client),\n redirects: new RedirectsEndpoint(client),\n forms: new FormsEndpoint(client),\n formResponses: new FormResponsesEndpoint(client),\n searchConsole: new SearchConsoleEndpoint(client),\n analytics: new AnalyticsEndpoint(client),\n };\n}\n\n/**\n * Get global --json flag value from command hierarchy.\n */\nexport function isJsonMode(cmd: Command): boolean {\n return cmd.optsWithGlobals().json === true;\n}\n","import { randomBytes, createHash } from 'node:crypto';\n\nexport function generateCodeVerifier(): string {\n return randomBytes(32).toString('base64url');\n}\n\nexport function generateCodeChallenge(verifier: string): string {\n return createHash('sha256').update(verifier).digest('base64url');\n}\n\nexport function generateState(): string {\n return randomBytes(16).toString('hex');\n}\n","import { createServer, type Server } from 'node:http';\n\nconst SUCCESS_HTML = `<!DOCTYPE html><html><body style=\"font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0\"><div style=\"text-align:center\"><h1>Login successful!</h1><p>You can close this window and return to the terminal.</p></div></body></html>`;\n\nconst ERROR_HTML = `<!DOCTYPE html><html><body style=\"font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0\"><div style=\"text-align:center\"><h1>Login failed</h1><p>Please try again.</p></div></body></html>`;\n\n/**\n * Start a temporary HTTP server to receive the OAuth callback from Supabase.\n * Supabase handles CSRF protection via its own internal state,\n * so we only need to capture the authorization code.\n */\nexport function startCallbackServer(\n options: { port?: number; timeout?: number; callbackPath?: string } = {},\n): Promise<{ code: string; port: number }> {\n const { port = 54321, timeout = 300_000, callbackPath = '/auth/callback' } = options;\n\n return new Promise((resolve, reject) => {\n let server: Server;\n let timer: ReturnType<typeof setTimeout>;\n\n const cleanup = () => {\n clearTimeout(timer);\n server.close();\n };\n\n server = createServer((req, res) => {\n const url = new URL(req.url || '/', `http://127.0.0.1`);\n if (url.pathname !== callbackPath) {\n res.writeHead(404);\n res.end('Not found');\n return;\n }\n\n const code = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n const errorDescription = url.searchParams.get('error_description');\n\n if (error) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML);\n cleanup();\n reject(new Error(`OAuth error: ${errorDescription || error}`));\n return;\n }\n\n if (!code) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML);\n cleanup();\n reject(new Error('Missing authorization code in callback'));\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n cleanup();\n resolve({ code, port: actualPort });\n });\n\n let actualPort = port;\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Fallback: let OS assign a port\n server.listen(0, '127.0.0.1');\n } else {\n reject(err);\n }\n });\n\n server.on('listening', () => {\n const addr = server.address();\n if (addr && typeof addr === 'object') {\n actualPort = addr.port;\n }\n });\n\n server.listen(port, '127.0.0.1');\n\n timer = setTimeout(() => {\n cleanup();\n reject(new Error('Login timed out. Please try again.'));\n }, timeout);\n });\n}\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess, printWarning, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { resolveImageUrl, processContentImages } from '../utils/upload.js';\nimport type { PostCreateInput } from '../sdk/types.js';\nimport type { Post } from '../sdk/types.js';\n\nfunction formatPost(post: Post): [string, any][] {\n return [\n ['ID', post.id],\n ['Title', post.title],\n ['Slug', post.slug],\n ['Published', post.published ? 'Yes' : 'No'],\n ['Published At', post.published_at],\n ['Content Type', post.content_type],\n ['Description', post.description],\n ['Image', post.image?.url],\n ['Canonical URL', post.canonical_url],\n ['Meta Title', post.meta_title],\n ['Meta Description', post.meta_description],\n ['Tags', post.tags?.map((t) => t.name).join(', ')],\n ['Authors', post.authors?.map((a) => a.author_name).join(', ')],\n ];\n}\n\nexport function registerPostsCommands(program: Command): void {\n const posts = program.command('posts').description('CRUD, publish, schedule posts + manage tags/authors');\n\n posts\n .command('list')\n .description('List posts with pagination, filters, and sorting')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .option('-s, --sort <field>', 'Sort field (published_at, created_at, title)')\n .option('-o, --order <dir>', 'Sort order (asc, desc)')\n .option('--published', 'Only published posts')\n .option('--draft', 'Only draft posts')\n .option('--tag-id <id>', 'Filter by tag ID')\n .option('--author-id <id>', 'Filter by author ID')\n .option('--include <rels>', 'Include relationships (tags,authors)', 'tags,authors')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n\n const filter: Record<string, any> = {};\n if (opts.published) filter.published = true;\n if (opts.draft) filter.published = false;\n if (opts.tagId) filter.tag_id = parseInt(opts.tagId, 10);\n if (opts.authorId) filter.author_id = opts.authorId;\n\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n sort: opts.sort,\n order: opts.order,\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n include: opts.include ? opts.include.split(',') : undefined,\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Title', 'Slug', 'Published', 'Published At', 'Tags'],\n data.map((p) => [\n p.id,\n truncate(p.title, 40),\n truncate(p.slug, 30),\n p.published ? 'Yes' : 'No',\n p.published_at ? new Date(p.published_at).toLocaleDateString() : '—',\n p.tags?.map((t) => t.name).join(', ') ?? '',\n ]),\n );\n if (meta.total) {\n console.log(`\\nShowing page ${meta.page ?? 1} (${data.length} of ${meta.total} posts)`);\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('get <id>')\n .description('Get post details by ID (integer)')\n .option('--include <rels>', 'Include relationships', 'tags,authors')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id, opts.include?.split(','));\n\n if (json) {\n printJson(data);\n } else {\n printDetail(formatPost(data));\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('create')\n .description('Create post (draft by default, use --published to publish)')\n .requiredOption('-t, --title <title>', 'Post title')\n .option('-s, --slug <slug>', 'Post slug')\n .option('-d, --description <desc>', 'Post description')\n .option('--content <html>', 'HTML content')\n .option('--content-file <path>', 'Read HTML content from file')\n .option('--image <path-or-url>', 'Cover image (local file or URL)')\n .option('--notion-url <url>', 'Notion page URL')\n .option('--published', 'Publish immediately')\n .option('--tag-ids <ids>', 'Comma-separated tag IDs')\n .option('--author-ids <ids>', 'Comma-separated author IDs')\n .option('--canonical-url <url>', 'Canonical URL')\n .option('--meta-title <title>', 'Meta title')\n .option('--meta-description <desc>', 'Meta description')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n\n let contentHtml = opts.content;\n if (opts.contentFile) {\n contentHtml = fs.readFileSync(opts.contentFile, 'utf-8');\n }\n\n // Upload local/base64 images in content\n if (contentHtml) {\n const { html, uploadCount } = await processContentImages(contentHtml);\n contentHtml = html;\n if (uploadCount > 0 && !json) {\n printWarning(`Uploaded ${uploadCount} image(s) to CDN.`);\n }\n }\n\n const input: Record<string, any> = { title: opts.title };\n if (opts.slug) input.slug = opts.slug;\n if (opts.description) input.description = opts.description;\n if (contentHtml) input.content_html = contentHtml;\n if (opts.image) input.image = { url: await resolveImageUrl(opts.image, 'featured_image') };\n if (opts.notionUrl) input.notion_url = opts.notionUrl;\n if (opts.published) input.published = true;\n if (opts.canonicalUrl) input.canonical_url = opts.canonicalUrl;\n if (opts.metaTitle) input.meta_title = opts.metaTitle;\n if (opts.metaDescription) input.meta_description = opts.metaDescription;\n if (opts.tagIds) input.tag_ids = opts.tagIds.split(',').map(Number);\n if (opts.authorIds) input.author_ids = opts.authorIds.split(',');\n\n const { data } = await endpoint.create(input as PostCreateInput);\n\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post created: \"${data.title}\" (ID: ${data.id})`);\n printDetail(formatPost(data));\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('update <id>')\n .description('Update post fields (title, slug, content, SEO metadata)')\n .option('-t, --title <title>', 'Post title')\n .option('-s, --slug <slug>', 'Post slug')\n .option('-d, --description <desc>', 'Post description')\n .option('--content <html>', 'HTML content')\n .option('--content-file <path>', 'Read HTML content from file')\n .option('--image <path-or-url>', 'Cover image (local file or URL)')\n .option('--canonical-url <url>', 'Canonical URL')\n .option('--meta-title <title>', 'Meta title')\n .option('--meta-description <desc>', 'Meta description')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n\n let contentHtml = opts.content;\n if (opts.contentFile) {\n contentHtml = fs.readFileSync(opts.contentFile, 'utf-8');\n }\n\n // Upload local/base64 images in content\n if (contentHtml) {\n const { html, uploadCount } = await processContentImages(contentHtml);\n contentHtml = html;\n if (uploadCount > 0 && !json) {\n printWarning(`Uploaded ${uploadCount} image(s) to CDN.`);\n }\n }\n\n const input: Record<string, any> = {};\n if (opts.title) input.title = opts.title;\n if (opts.slug) input.slug = opts.slug;\n if (opts.description) input.description = opts.description;\n if (contentHtml) input.content_html = contentHtml;\n if (opts.image) input.image = { url: await resolveImageUrl(opts.image, 'featured_image') };\n if (opts.canonicalUrl !== undefined) input.canonical_url = opts.canonicalUrl || null;\n if (opts.metaTitle !== undefined) input.meta_title = opts.metaTitle || null;\n if (opts.metaDescription !== undefined) input.meta_description = opts.metaDescription || null;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post updated: \"${data.title}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('delete <id>')\n .description('Permanently delete a post')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n await endpoint.delete(id);\n if (json) {\n printJson({ success: true, id });\n } else {\n printSuccess(`Post ${id} deleted.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('publish <id>')\n .description('Set post as published (immediately visible)')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.publish(id);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post \"${data.title}\" published.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('unpublish <id>')\n .description('Revert published post to draft')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.unpublish(id);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post \"${data.title}\" unpublished.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('schedule <id>')\n .description('Schedule post for future publishing (ISO 8601 date)')\n .requiredOption('--at <iso-date>', 'ISO 8601 date for scheduled publish')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.schedule(id, opts.at);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post \"${data.title}\" scheduled for ${opts.at}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n // ── Relationship sub-commands ──\n\n posts\n .command('tags <id>')\n .description('List tags for a post')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.listTags(id);\n if (json) {\n printJson(data);\n } else {\n printTable(['ID', 'Name', 'Slug'], data.map((t) => [t.id, t.name, t.slug]));\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('add-tags <id>')\n .description('Add tags to a post')\n .requiredOption('--tag-ids <ids>', 'Comma-separated tag IDs')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const tagIds = opts.tagIds.split(',').map(Number);\n const { data } = await endpoint.addTags(id, tagIds);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Tags added to post ${id}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('remove-tag <postId> <tagId>')\n .description('Remove a tag from a post')\n .action(async function (this: Command, postId: string, tagId: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n await endpoint.removeTag(postId, tagId);\n if (json) {\n printJson({ success: true, postId, tagId });\n } else {\n printSuccess(`Tag ${tagId} removed from post ${postId}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('authors <id>')\n .description('List authors for a post')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.listAuthors(id);\n if (json) {\n printJson(data);\n } else {\n printTable(\n ['ID', 'Name', 'Avatar URL'],\n data.map((a) => [a.id, a.author_name, truncate(a.avatar_url, 40)]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('add-authors <id>')\n .description('Add authors to a post')\n .requiredOption('--author-ids <ids>', 'Comma-separated author IDs')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const authorIds = opts.authorIds.split(',');\n const { data } = await endpoint.addAuthors(id, authorIds);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Authors added to post ${id}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('remove-author <postId> <authorId>')\n .description('Remove an author from a post')\n .action(async function (this: Command, postId: string, authorId: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n await endpoint.removeAuthor(postId, authorId);\n if (json) {\n printJson({ success: true, postId, authorId });\n } else {\n printSuccess(`Author ${authorId} removed from post ${postId}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\nconst WORKER_URL = 'https://upload.inblog.dev/';\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\n\nconst MIME_TYPES: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n};\n\nexport type ImageBucket =\n | 'favicon'\n | 'featured_image'\n | 'logo'\n | 'avatar'\n | 'og_image'\n | 'banner'\n | 'post_image';\n\n/**\n * Checks if a string is a local file path (not a URL).\n */\nexport function isLocalPath(value: string): boolean {\n if (value.startsWith('http://') || value.startsWith('https://')) return false;\n return fs.existsSync(value);\n}\n\n/**\n * Uploads a local image file to inblog R2 storage via Worker.\n * Returns the public CDN URL.\n */\nexport async function uploadImage(filePath: string, bucket: ImageBucket): Promise<string> {\n const resolved = path.resolve(filePath);\n\n if (!fs.existsSync(resolved)) {\n throw new Error(`File not found: ${resolved}`);\n }\n\n const stat = fs.statSync(resolved);\n if (stat.size > MAX_FILE_SIZE) {\n throw new Error(`File size exceeds 10MB limit: ${(stat.size / 1024 / 1024).toFixed(1)}MB`);\n }\n\n const ext = path.extname(resolved).toLowerCase();\n const contentType = MIME_TYPES[ext] || 'application/octet-stream';\n\n const fileKey = `${bucket}/${new Date().toISOString()}-${randomUUID()}`;\n const body = fs.readFileSync(resolved);\n\n const response = await fetch(`${WORKER_URL}?fileKey=${fileKey}`, {\n method: 'POST',\n body,\n headers: { 'Content-Type': contentType },\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed: ${response.status} ${response.statusText}`);\n }\n\n const data: any = await response.json();\n return data.publicUrl;\n}\n\n/**\n * If the value is a local file path, uploads it and returns the URL.\n * If it's already a URL, returns it as-is.\n */\nexport async function resolveImageUrl(value: string, bucket: ImageBucket): Promise<string> {\n if (!isLocalPath(value)) return value;\n return uploadImage(value, bucket);\n}\n\n/**\n * Uploads a base64 data URI to R2 and returns the CDN URL.\n */\nasync function uploadBase64(dataUri: string, bucket: ImageBucket): Promise<string> {\n const match = dataUri.match(/^data:([^;]+);base64,(.+)$/s);\n if (!match) throw new Error('Invalid data URI');\n\n const contentType = match[1];\n const body = Buffer.from(match[2], 'base64');\n\n if (body.length > MAX_FILE_SIZE) {\n throw new Error(`Base64 image exceeds 10MB limit: ${(body.length / 1024 / 1024).toFixed(1)}MB`);\n }\n\n const fileKey = `${bucket}/${new Date().toISOString()}-${randomUUID()}`;\n\n const response = await fetch(`${WORKER_URL}?fileKey=${fileKey}`, {\n method: 'POST',\n body,\n headers: { 'Content-Type': contentType },\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed: ${response.status} ${response.statusText}`);\n }\n\n const data: any = await response.json();\n return data.publicUrl;\n}\n\n/**\n * Processes HTML content: finds local file paths and base64 data URIs in\n * img src attributes, uploads them to R2, and replaces with CDN URLs.\n * Returns the processed HTML with all images on CDN.\n */\nexport async function processContentImages(html: string): Promise<{ html: string; uploadCount: number }> {\n // Match src=\"...\" in img tags (data-type=\"imageBlock\" or regular img)\n const imgSrcRegex = /(<img\\s[^>]*\\bsrc=[\"'])([^\"']+)([\"'][^>]*>)/gi;\n const matches: { full: string; prefix: string; src: string; suffix: string; index: number }[] = [];\n\n let m: RegExpExecArray | null;\n while ((m = imgSrcRegex.exec(html)) !== null) {\n matches.push({ full: m[0], prefix: m[1], src: m[2], suffix: m[3], index: m.index });\n }\n\n if (matches.length === 0) return { html, uploadCount: 0 };\n\n let uploadCount = 0;\n const replacements: Map<string, string> = new Map();\n\n // Process uploads concurrently (max 5 at a time)\n const concurrency = 5;\n for (let i = 0; i < matches.length; i += concurrency) {\n const batch = matches.slice(i, i + concurrency);\n const results = await Promise.allSettled(\n batch.map(async ({ src }) => {\n // Skip already-uploaded CDN URLs\n if (src.startsWith('https://source.inblog.dev/') || src.startsWith('https://image.inblog.dev/')) {\n return null;\n }\n\n // Base64 data URI\n if (src.startsWith('data:image/')) {\n const url = await uploadBase64(src, 'post_image');\n return { src, url };\n }\n\n // Local file path\n if (isLocalPath(src)) {\n const url = await uploadImage(src, 'post_image');\n return { src, url };\n }\n\n return null;\n }),\n );\n\n for (const result of results) {\n if (result.status === 'fulfilled' && result.value) {\n replacements.set(result.value.src, result.value.url);\n uploadCount++;\n }\n }\n }\n\n // Apply replacements\n let processed = html;\n for (const [src, url] of replacements) {\n // Use split/join for replacement to avoid regex special char issues with base64\n processed = processed.split(src).join(url);\n }\n\n return { html: processed, uploadCount };\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport type { TagCreateInput } from '../sdk/types.js';\n\nexport function registerTagsCommands(program: Command): void {\n const tags = program.command('tags').description('CRUD tags (no pagination, sorted by priority)');\n\n tags\n .command('list')\n .description('List all tags (returns all, sorted by priority)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { tags: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.list();\n if (json) {\n printJson(data);\n } else {\n printTable(\n ['ID', 'Name', 'Slug', 'Priority'],\n data.map((t) => [t.id, t.name, t.slug, t.priority]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('get <id>')\n .description('Get a tag by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { tags: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Name', data.name],\n ['Slug', data.slug],\n ['Priority', data.priority],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('create')\n .description('Create a new tag')\n .requiredOption('-n, --name <name>', 'Tag name')\n .option('-s, --slug <slug>', 'Tag slug')\n .option('-p, --priority <number>', 'Tag priority')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { tags: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = { name: opts.name };\n if (opts.slug) input.slug = opts.slug;\n if (opts.priority !== undefined) input.priority = parseInt(opts.priority, 10);\n\n const { data } = await endpoint.create(input as TagCreateInput);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Tag created: \"${data.name}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('update <id>')\n .description('Update a tag')\n .option('-n, --name <name>', 'Tag name')\n .option('-s, --slug <slug>', 'Tag slug')\n .option('-p, --priority <number>', 'Tag priority')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { tags: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = {};\n if (opts.name) input.name = opts.name;\n if (opts.slug) input.slug = opts.slug;\n if (opts.priority !== undefined) input.priority = parseInt(opts.priority, 10);\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Tag updated: \"${data.name}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('delete <id>')\n .description('Delete a tag')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { tags: endpoint } = createClientFromCommand(this);\n await endpoint.delete(id);\n if (json) {\n printJson({ success: true, id });\n } else {\n printSuccess(`Tag ${id} deleted.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerAuthorsCommands(program: Command): void {\n const authors = program.command('authors').description('List, view, update authors (create not available)');\n\n authors\n .command('list')\n .description('List authors (only profiles with posts, UUID IDs)')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { authors: endpoint } = createClientFromCommand(this);\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Name', 'Avatar'],\n data.map((a) => [a.id, a.author_name, truncate(a.avatar_url, 40)]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n authors\n .command('get <id>')\n .description('Get an author by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { authors: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Name', data.author_name],\n ['Avatar URL', data.avatar_url],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n authors\n .command('update <id>')\n .description('Update an author')\n .option('-n, --name <name>', 'Author name')\n .option('--avatar-url <url>', 'Avatar URL')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { authors: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = {};\n if (opts.name) input.author_name = opts.name;\n if (opts.avatarUrl !== undefined) input.avatar_url = opts.avatarUrl || null;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Author updated: \"${data.author_name}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { select } from '@inquirer/prompts';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { readSession, setActiveBlog } from '../utils/token-store.js';\nimport { getValidAccessToken } from '../utils/token-refresh.js';\nimport { printJson, printDetail, printSuccess, printTable, printWarning } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { readConfig } from '../utils/config.js';\nimport { lookupNameservers, detectDnsProvider, getDnsProviderGuide, isSubdomain } from '../utils/domain.js';\nimport { resolveImageUrl } from '../utils/upload.js';\n\nexport function registerBlogsCommands(program: Command): void {\n const blogs = program.command('blogs').description('Manage blogs — list, switch, view, and update blog settings');\n\n blogs\n .command('me')\n .description('Show blog info (title, subdomain, plan, domain)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { blogs: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.me();\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Title', data.title],\n ['Subdomain', data.subdomain],\n ['Description', data.description],\n ['Plan', data.plan],\n ['Language', data.blog_language],\n ['Custom Domain', data.custom_domain],\n ['Domain Verified', data.custom_domain_verified],\n ['Logo', data.logo_url],\n ['Favicon', data.favicon],\n ['OG Image', data.og_image],\n ['GA ID', data.ga_measurement_id],\n ['Search Console', data.is_search_console_connected ? `Connected (${data.search_console_url})` : 'Not connected'],\n ['Created At', data.created_at],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('list')\n .description('List all blogs you have access to (OAuth only)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n throw new Error('OAuth session required. Run `inblog auth login` first.');\n }\n\n const accessToken = await getValidAccessToken();\n if (!accessToken) {\n throw new Error('Session expired. Run `inblog auth login` to re-authenticate.');\n }\n\n const config = readConfig();\n const baseUrl = this.optsWithGlobals().baseUrl || config.baseUrl || 'https://inblog.ai';\n\n const response = await fetch(`${baseUrl}/api/v1/user/blogs`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'X-Blog-Id': '0',\n Accept: 'application/vnd.api+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch blogs: HTTP ${response.status}`);\n }\n\n const blogsData: any = await response.json();\n const blogsList = blogsData.data || [];\n\n if (json) {\n printJson(blogsList.map((b: any) => ({\n id: parseInt(b.id, 10),\n ...b.attributes,\n })));\n return;\n }\n\n if (blogsList.length === 0) {\n printWarning('No blogs found.');\n return;\n }\n\n const activeBlogId = session.activeBlogId;\n\n printTable(\n ['', 'ID', 'Title', 'Subdomain', 'Permission', 'Plan'],\n blogsList.map((b: any) => {\n const id = parseInt(b.id, 10);\n const active = id === activeBlogId ? '*' : '';\n return [active, id, b.attributes.title, b.attributes.subdomain, b.attributes.permission, b.attributes.plan];\n }),\n );\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('switch [blog-id]')\n .description('Switch active blog (OAuth only)')\n .action(async function (this: Command, blogIdArg?: string) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n throw new Error('OAuth session required. Run `inblog auth login` first.');\n }\n\n const accessToken = await getValidAccessToken();\n if (!accessToken) {\n throw new Error('Session expired. Run `inblog auth login` to re-authenticate.');\n }\n\n const config = readConfig();\n const baseUrl = this.optsWithGlobals().baseUrl || config.baseUrl || 'https://inblog.ai';\n\n const response = await fetch(`${baseUrl}/api/v1/user/blogs`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'X-Blog-Id': '0',\n Accept: 'application/vnd.api+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch blogs: HTTP ${response.status}`);\n }\n\n const blogsData: any = await response.json();\n const blogsList = blogsData.data || [];\n\n if (blogsList.length === 0) {\n throw new Error('No blogs found for your account.');\n }\n\n let selectedBlogId: number;\n let selectedSubdomain: string;\n\n if (blogIdArg) {\n const target = blogsList.find((b: any) => b.id === blogIdArg || b.attributes.subdomain === blogIdArg);\n if (!target) {\n throw new Error(`Blog not found: ${blogIdArg}`);\n }\n selectedBlogId = parseInt(target.id, 10);\n selectedSubdomain = target.attributes.subdomain;\n } else {\n if (json) {\n throw new Error('Blog ID is required in --json mode. Usage: inblog blogs switch <blog-id>');\n }\n\n const choices = blogsList.map((b: any) => ({\n name: `${b.attributes.title} (${b.attributes.subdomain}) [${b.attributes.permission}]`,\n value: { id: parseInt(b.id, 10), subdomain: b.attributes.subdomain },\n }));\n\n const selected = await select<{ id: number; subdomain: string }>({\n message: 'Select a blog:',\n choices,\n });\n\n selectedBlogId = selected.id;\n selectedSubdomain = selected.subdomain;\n }\n\n const targetBlog = blogsList.find((b: any) => b.id === String(selectedBlogId));\n const activeBlogPlan = targetBlog?.attributes.plan;\n\n setActiveBlog(selectedBlogId, selectedSubdomain, activeBlogPlan);\n\n if (json) {\n printJson({ success: true, blogId: selectedBlogId, subdomain: selectedSubdomain });\n } else {\n printSuccess(`Switched to blog: ${selectedSubdomain}`);\n }\n\n if (activeBlogPlan !== 'team' && activeBlogPlan !== 'enterprise') {\n printWarning(`Blog \"${selectedSubdomain}\" is on the ${activeBlogPlan || 'free'} plan.`);\n printWarning(' CLI features require a Team plan or above.');\n printWarning(` Upgrade: https://inblog.ai/dashboard/${selectedSubdomain}/settings/billing`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('update')\n .description('Update blog title, description, language, or timezone')\n .option('-t, --title <title>', 'Blog title')\n .option('-d, --description <desc>', 'Blog description')\n .option('--language <lang>', 'Blog language')\n .option('--timezone-diff <hours>', 'Timezone offset in hours')\n .option('--logo <path-or-url>', 'Blog logo image (local file or URL)')\n .option('--favicon <path-or-url>', 'Blog favicon image (local file or URL)')\n .option('--og-image <path-or-url>', 'Blog OG image (local file or URL)')\n .option('--ga-id <id>', 'Google Analytics measurement ID')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const ctx = createClientFromCommand(this);\n\n const input: Record<string, any> = {};\n if (opts.title) input.title = opts.title;\n if (opts.description) input.description = opts.description;\n if (opts.language) input.blog_language = opts.language;\n if (opts.timezoneDiff !== undefined) input.timezone_diff = parseInt(opts.timezoneDiff, 10);\n if (opts.logo) input.logo = await resolveImageUrl(opts.logo, 'logo');\n if (opts.favicon) input.favicon = await resolveImageUrl(opts.favicon, 'favicon');\n if (opts.ogImage) input.og_image = await resolveImageUrl(opts.ogImage, 'og_image');\n if (opts.gaId) input.ga_measurement_id = opts.gaId;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await ctx.blogs.update(input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Blog updated: \"${data.title}\"`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n // ── Domain subcommands ──\n\n const domain = blogs.command('domain').description('Manage custom domain');\n\n domain\n .command('connect <domain>')\n .description('Connect a custom domain (with DNS provider detection)')\n .action(async function (this: Command, domainArg: string) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.domainConnect(domainArg);\n\n // NS lookup for provider detection\n const nameservers = await lookupNameservers(domainArg);\n const provider = detectDnsProvider(nameservers);\n const guide = provider ? getDnsProviderGuide(provider) : null;\n const isSub = isSubdomain(domainArg);\n\n if (json) {\n printJson({\n ...result,\n nameservers,\n dns_provider: provider,\n dns_provider_guide: guide,\n is_subdomain: isSub,\n });\n } else {\n printSuccess(`Custom domain requested: ${domainArg}`);\n\n // DNS provider info\n if (provider) {\n console.log(`\\n DNS Provider: ${provider}`);\n if (nameservers.length > 0) {\n console.log(` Nameservers: ${nameservers.join(', ')}`);\n }\n } else if (nameservers.length > 0) {\n console.log(`\\n Nameservers: ${nameservers.join(', ')}`);\n }\n\n // DNS records to set\n console.log('\\n DNS 설정:');\n if (isSub) {\n console.log(` → CNAME ${domainArg} → cname.inblog.ai`);\n } else {\n console.log(` → A ${domainArg} → 76.76.21.21`);\n }\n\n if (result.dns_records && result.dns_records.length > 0) {\n console.log('');\n printTable(\n ['Type', 'Name', 'Value'],\n result.dns_records.map((r: any) => [r.type, r.name, r.value]),\n );\n }\n\n // Provider-specific guide\n if (guide) {\n console.log(`\\n ${provider} DNS 설정 가이드: ${guide}`);\n }\n\n printWarning('\\nDNS 전파 후 `inblog blogs domain status`로 확인하세요.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n domain\n .command('status')\n .description('Check custom domain verification status')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.domainStatus();\n\n if (json) {\n printJson(result);\n } else {\n if (!result.custom_domain) {\n printWarning('No custom domain configured.');\n return;\n }\n printDetail([\n ['Domain', result.custom_domain],\n ['Verified', result.verified],\n ['SSL Status', result.ssl_status],\n ]);\n if (result.dns_records && result.dns_records.length > 0) {\n printTable(\n ['Type', 'Name', 'Value'],\n result.dns_records.map((r: any) => [r.type, r.name, r.value]),\n );\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n domain\n .command('disconnect')\n .description('Disconnect custom domain')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n await ctx.blogs.domainDisconnect();\n\n if (json) {\n printJson({ success: true });\n } else {\n printSuccess('Custom domain disconnected.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n // ── Banner subcommands ──\n\n const banner = blogs.command('banner').description('Manage blog banner settings');\n\n banner\n .command('get')\n .description('Show current banner settings')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.getCustomUi();\n\n if (json) {\n printJson(result);\n } else {\n printDetail([\n ['Banner Image', result.banner_url],\n ['Title', result.banner_title],\n ['Subtext', result.banner_subtext],\n ['Title Color', result.banner_title_color],\n ['Background Color', result.banner_bg_color],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n banner\n .command('set')\n .description('Update banner settings')\n .option('--image <path-or-url>', 'Banner image (local file or URL)')\n .option('--title <text>', 'Banner title text')\n .option('--subtext <text>', 'Banner subtext')\n .option('--title-color <hex>', 'Banner title color (hex)')\n .option('--bg-color <hex>', 'Banner background color (hex)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const input: Record<string, any> = {};\n if (opts.image) input.banner_url = await resolveImageUrl(opts.image, 'banner');\n if (opts.title) input.banner_title = opts.title;\n if (opts.subtext) input.banner_subtext = opts.subtext;\n if (opts.titleColor) input.banner_title_color = opts.titleColor;\n if (opts.bgColor) input.banner_bg_color = opts.bgColor;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option (--image, --title, --subtext, --title-color, --bg-color).');\n }\n\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.updateCustomUi(input);\n\n if (json) {\n printJson(result);\n } else {\n printSuccess('Banner updated.');\n printDetail([\n ['Banner Image', result.banner_url],\n ['Title', result.banner_title],\n ['Subtext', result.banner_subtext],\n ['Title Color', result.banner_title_color],\n ['Background Color', result.banner_bg_color],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n banner\n .command('remove')\n .description('Remove banner settings')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n await ctx.blogs.updateCustomUi({\n banner_url: null,\n banner_title: null,\n banner_subtext: null,\n });\n\n if (json) {\n printJson({ success: true });\n } else {\n printSuccess('Banner removed.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import dns from 'node:dns/promises';\n\nconst MULTI_PART_TLDS = [\n '.co.uk', '.co.kr', '.co.jp', '.co.nz', '.co.za', '.co.in', '.co.id',\n '.com.au', '.com.br', '.com.cn', '.com.mx', '.com.tw', '.com.sg',\n '.net.au', '.net.br', '.net.cn',\n '.org.uk', '.org.au', '.org.br',\n '.ac.uk', '.ac.kr', '.ac.jp',\n '.ne.jp', '.or.jp', '.or.kr',\n '.gov.uk', '.gov.au', '.gov.br',\n '.edu.au', '.edu.cn',\n];\n\nfunction getRootDomain(domain: string): string {\n const lower = domain.toLowerCase();\n const multiTld = MULTI_PART_TLDS.find((tld) => lower.endsWith(tld));\n if (multiTld) {\n const withoutTld = lower.slice(0, -multiTld.length);\n const parts = withoutTld.split('.').filter(Boolean);\n return parts[parts.length - 1] + multiTld;\n }\n const parts = lower.split('.');\n return parts.slice(-2).join('.');\n}\n\nexport function isSubdomain(domain: string): boolean {\n if (!domain) return false;\n const lower = domain.toLowerCase();\n const multiTld = MULTI_PART_TLDS.find((tld) => lower.endsWith(tld));\n if (multiTld) {\n const withoutTld = lower.slice(0, -multiTld.length);\n return withoutTld.includes('.');\n }\n return domain.split('.').length > 2;\n}\n\nexport async function lookupNameservers(domain: string): Promise<string[]> {\n const rootDomain = getRootDomain(domain);\n try {\n return await dns.resolveNs(rootDomain);\n } catch {\n return [];\n }\n}\n\nconst DNS_PROVIDER_MAP: [string[], string][] = [\n [['godaddy', 'domaincontrol'], 'GoDaddy'],\n [['namecheap', 'registrar-servers.com'], 'Namecheap'],\n [['cloudflare'], 'Cloudflare'],\n [['googledomains', 'google.com'], 'Google Domains'],\n [['awsdns', 'amazon'], 'AWS (Route 53)'],\n [['bluehost'], 'Bluehost'],\n [['siteground'], 'SiteGround'],\n [['hostgator'], 'HostGator'],\n [['dreamhost'], 'DreamHost'],\n [['name.com'], 'Name.com'],\n [['gandi'], 'Gandi'],\n [['gabia'], 'Gabia'],\n [['whois'], 'Whois'],\n [['cafe24'], 'Cafe24'],\n [['imweb'], 'Imweb'],\n [['xinnet'], 'Xinnet'],\n [['aliyun', 'alidns'], 'Aliyun'],\n [['dnspod', 'qcloud'], 'Tencent Cloud'],\n];\n\nexport function detectDnsProvider(nameservers: string[]): string | null {\n if (nameservers.length === 0) return null;\n const nsString = nameservers.join(',').toLowerCase();\n for (const [keywords, provider] of DNS_PROVIDER_MAP) {\n if (keywords.some((kw) => nsString.includes(kw))) return provider;\n }\n return null;\n}\n\nconst DNS_PROVIDER_GUIDES: Record<string, string> = {\n GoDaddy: 'https://www.godaddy.com/help/add-a-cname-record-19236',\n Namecheap: 'https://www.namecheap.com/support/knowledgebase/article.aspx/434/2237/how-do-i-set-up-host-records-for-a-domain/',\n Cloudflare: 'https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/',\n 'Google Domains': 'https://support.google.com/domains/answer/3290350',\n 'AWS (Route 53)': 'https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html',\n Bluehost: 'https://www.bluehost.com/help/article/dns-management-add-edit-or-delete-dns-entries',\n SiteGround: 'https://www.siteground.com/kb/how_to_manage_dns_records/',\n HostGator: 'https://www.hostgator.com/help/article/how-to-change-dns-zones-mx-cname-and-a-records',\n DreamHost: 'https://help.dreamhost.com/hc/en-us/articles/215413857-DreamHost-DNS-overview',\n 'Name.com': 'https://www.name.com/support/articles/205934458-Adding-a-CNAME-Record',\n Gandi: 'https://docs.gandi.net/en/domain_names/common_operations/dns_records.html',\n Gabia: 'https://customer.gabia.com/manual/dns/3041/3040',\n Whois: 'https://cs.whois.co.kr/manual/?p=view&page=1&number=435&keyfield=sub_cont&keyword=dns',\n Cafe24: 'https://help.cafe24.com/docs/domain/domain-hosting-external-service-connection/',\n Imweb: 'https://imweb.me/qna?mode=faq&q=71897',\n Xinnet: 'http://www.xinnet.com/service/cjwt/yuming/guanli/1485.html',\n Aliyun: 'https://www.alibabacloud.com/help/en/dns/user-guide/add-a-dns-record',\n 'Tencent Cloud': 'https://www.tencentcloud.com/document/product/302/3446',\n};\n\nexport function getDnsProviderGuide(provider: string): string | null {\n return DNS_PROVIDER_GUIDES[provider] || null;\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerRedirectsCommands(program: Command): void {\n const redirects = program.command('redirects').description('CRUD URL redirects (307 temporary, 308 permanent)');\n\n redirects\n .command('list')\n .description('List redirects')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '50')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { redirects: endpoint } = createClientFromCommand(this);\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'From', 'To', 'Type'],\n data.map((r) => [r.id, r.from_path, r.to_path, r.redirect_type]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('get <id>')\n .description('Get a redirect by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { redirects: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['From', data.from_path],\n ['To', data.to_path],\n ['Type', data.redirect_type],\n ['Created At', data.created_at],\n ['Updated At', data.updated_at],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('create')\n .description('Create a redirect (default: 308 permanent)')\n .requiredOption('--from <path>', 'Source path (auto-normalized with /)')\n .requiredOption('--to <path>', 'Destination path')\n .option('--type <type>', 'Redirect type (307 or 308)', '308')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { redirects: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.create({\n from_path: opts.from,\n to_path: opts.to,\n redirect_type: parseInt(opts.type, 10) as 307 | 308,\n });\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Redirect created: ${data.from_path} → ${data.to_path} (${data.redirect_type})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('update <id>')\n .description('Update a redirect')\n .option('--from <path>', 'Source path')\n .option('--to <path>', 'Destination path')\n .option('--type <type>', 'Redirect type (307 or 308)')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { redirects: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = {};\n if (opts.from) input.from_path = opts.from;\n if (opts.to) input.to_path = opts.to;\n if (opts.type) input.redirect_type = parseInt(opts.type, 10);\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Redirect updated: ${data.from_path} → ${data.to_path}`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('delete <id>')\n .description('Delete a redirect')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { redirects: endpoint } = createClientFromCommand(this);\n await endpoint.delete(id);\n if (json) {\n printJson({ success: true, id });\n } else {\n printSuccess(`Redirect ${id} deleted.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerFormsCommands(program: Command): void {\n const forms = program.command('forms').description('View lead-capture forms (read-only)');\n\n forms\n .command('list')\n .description('List forms')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { forms: endpoint } = createClientFromCommand(this);\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Title', 'Responses', 'Created At'],\n data.map((f) => [f.id, truncate(f.title, 40), f.response_count, f.created_at]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n forms\n .command('get <id>')\n .description('Get a form by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { forms: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Title', data.title],\n ['Magnet Type', data.magnet_type],\n ['Responses', data.response_count],\n ['Created At', data.created_at],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n\nexport function registerFormResponsesCommands(program: Command): void {\n const formResponses = program.command('form-responses').description('View form submission data (read-only)');\n\n formResponses\n .command('list')\n .description('List form responses')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .option('--form-id <id>', 'Filter by form ID')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { formResponses: endpoint } = createClientFromCommand(this);\n const filter: Record<string, any> = {};\n if (opts.formId) filter.form_id = opts.formId;\n\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Email', 'Country', 'Created At'],\n data.map((r) => [r.id, r.email, r.country, r.created_at]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n formResponses\n .command('get <id>')\n .description('Get a form response by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { formResponses: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Email', data.email],\n ['Country', data.country],\n ['City', data.city],\n ['Region', data.region],\n ['Language', data.language],\n ['Created At', data.created_at],\n ['Response', JSON.stringify(data.response)],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport {\n readGlobalConfig,\n getGlobalConfigPath,\n getLocalConfigPath,\n setGlobalConfigValue,\n deleteGlobalConfigValue,\n} from '../utils/config.js';\nimport { printJson, printDetail, printSuccess } from '../utils/output.js';\nimport { isJsonMode } from '../utils/client-factory.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerConfigCommands(program: Command): void {\n const config = program.command('config').description('Manage CLI config (~/.config/inblog/config.json)');\n\n config\n .command('list')\n .description('Show all configuration values')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const cfg = readGlobalConfig();\n if (json) {\n printJson(cfg);\n } else {\n const entries = Object.entries(cfg);\n if (entries.length === 0) {\n console.log('No configuration set.');\n } else {\n printDetail(\n entries.map(([k, v]) => [k, typeof v === 'object' ? JSON.stringify(v) : v]),\n );\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n config\n .command('get <key>')\n .description('Get a configuration value')\n .action(async function (this: Command, key: string) {\n const json = isJsonMode(this);\n try {\n const cfg = readGlobalConfig();\n const value = (cfg as any)[key];\n if (json) {\n printJson({ [key]: value ?? null });\n } else if (value === undefined) {\n console.log(`\"${key}\" is not set.`);\n } else {\n console.log(value);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n config\n .command('set <key> <value>')\n .description('Set a configuration value')\n .action(async function (this: Command, key: string, value: string) {\n const json = isJsonMode(this);\n try {\n // Parse booleans and numbers\n let parsed: any = value;\n if (value === 'true') parsed = true;\n else if (value === 'false') parsed = false;\n else if (!isNaN(Number(value)) && value !== '') parsed = Number(value);\n\n setGlobalConfigValue(key, parsed);\n if (json) {\n printJson({ [key]: parsed });\n } else {\n printSuccess(`Set ${key} = ${parsed}`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n config\n .command('path')\n .description('Show configuration file paths')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const globalPath = getGlobalConfigPath();\n const localPath = getLocalConfigPath();\n if (json) {\n printJson({ global: globalPath, local: localPath });\n } else {\n printDetail([\n ['Global', globalPath],\n ['Local', localPath ?? '(none)'],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport open from 'open';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess, printWarning } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { startCallbackServer } from '../utils/callback-server.js';\n\nexport function registerSearchConsoleCommands(program: Command): void {\n const sc = program\n .command('search-console')\n .description('Google Search Console integration');\n\n sc.command('connect')\n .description('Connect Google Search Console via OAuth')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n if (json) {\n throw new Error('Interactive OAuth flow is not available in --json mode.');\n }\n\n const { searchConsole } = createClientFromCommand(this);\n\n // Check if already connected\n const statusResult = await searchConsole.status();\n if (statusResult.connected) {\n printWarning('Search Console is already connected.');\n printDetail([\n ['Status', 'Connected'],\n ['Property', statusResult.property || '—'],\n ]);\n return;\n }\n\n const callbackPath = '/auth/gsc-callback';\n const serverPromise = startCallbackServer({ callbackPath });\n\n // Wait a tick for the server to start\n await new Promise((r) => setTimeout(r, 100));\n\n const redirectUri = `http://127.0.0.1:54321${callbackPath}`;\n const oauthResult = await searchConsole.oauthUrl(redirectUri);\n const url = oauthResult.url;\n\n if (!url) {\n throw new Error('Failed to retrieve OAuth URL from server.');\n }\n\n console.log('Opening browser for Google Search Console authorization...');\n await open(url);\n console.log('Waiting for authorization...');\n\n const { code } = await serverPromise;\n\n await searchConsole.connect(code, redirectUri);\n printSuccess('Google Search Console connected successfully.');\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('status')\n .description('Show Search Console connection status')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { searchConsole } = createClientFromCommand(this);\n const data = await searchConsole.status();\n\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['Connected', data.connected ? 'Yes' : 'No'],\n ['Property', data.property || '—'],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('disconnect')\n .description('Disconnect Google Search Console')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { searchConsole } = createClientFromCommand(this);\n await searchConsole.disconnect();\n\n if (json) {\n printJson({ success: true });\n } else {\n printSuccess('Google Search Console disconnected.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('keywords')\n .description('Show keyword performance data')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--sort <field>', 'Sort by: clicks, impressions, ctr, position', 'clicks')\n .option('--order <dir>', 'Sort order: asc, desc', 'desc')\n .option('-l, --limit <number>', 'Max results', '20')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { searchConsole } = createClientFromCommand(this);\n const data = await searchConsole.keywords({\n start_date: opts.startDate,\n end_date: opts.endDate,\n sort: opts.sort,\n order: opts.order,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.keywords || data.data || []).map((k: any) => [\n k.keyword || k.key,\n k.clicks,\n k.impressions,\n typeof k.ctr === 'number' ? `${(k.ctr * 100).toFixed(1)}%` : k.ctr,\n typeof k.position === 'number' ? k.position.toFixed(1) : k.position,\n ]);\n printTable(['Keyword', 'Clicks', 'Impressions', 'CTR', 'Position'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('pages')\n .description('Show page performance data')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--sort <field>', 'Sort by: clicks, impressions, ctr, position', 'clicks')\n .option('--order <dir>', 'Sort order: asc, desc', 'desc')\n .option('-l, --limit <number>', 'Max results', '20')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { searchConsole } = createClientFromCommand(this);\n const data = await searchConsole.pages({\n start_date: opts.startDate,\n end_date: opts.endDate,\n sort: opts.sort,\n order: opts.order,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.pages || data.data || []).map((p: any) => [\n p.page || p.key,\n p.clicks,\n p.impressions,\n typeof p.ctr === 'number' ? `${(p.ctr * 100).toFixed(1)}%` : p.ctr,\n typeof p.position === 'number' ? p.position.toFixed(1) : p.position,\n ]);\n printTable(['Page', 'Clicks', 'Impressions', 'CTR', 'Position'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerAnalyticsCommands(program: Command): void {\n const analytics = program\n .command('analytics')\n .description('Blog analytics: traffic, post metrics, referrer sources');\n\n analytics\n .command('traffic')\n .description('Show blog overall traffic')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--interval <interval>', 'Interval: day, hour', 'day')\n .option('--type <type>', 'Page type: all, home, post, category, author', 'all')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const data = await endpoint.traffic({\n start_date: opts.startDate,\n end_date: opts.endDate,\n interval: opts.interval,\n type: opts.type,\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.date || r.period,\n r.visits,\n r.clicks,\n r.organic,\n ]);\n printTable(['Date', 'Visits', 'Clicks', 'Organic'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n analytics\n .command('posts')\n .description('Show post-level metrics')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--sort <field>', 'Sort by: visits, clicks, organic, cvr', 'visits')\n .option('--order <dir>', 'Sort order: asc, desc', 'desc')\n .option('-l, --limit <number>', 'Max results', '20')\n .option('--include <fields>', 'Include extra fields (e.g. title)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const data = await endpoint.posts({\n start_date: opts.startDate,\n end_date: opts.endDate,\n sort: opts.sort,\n order: opts.order,\n limit: parseInt(opts.limit, 10),\n include: opts.include,\n });\n\n if (json) {\n printJson(data);\n } else {\n const hasTitle = opts.include?.includes('title');\n const headers = hasTitle\n ? ['Post ID', 'Title', 'Visits', 'Clicks', 'Organic', 'CVR']\n : ['Post ID', 'Visits', 'Clicks', 'Organic', 'CVR'];\n const rows = (data.data || []).map((r: any) => {\n const cvr = typeof r.cvr === 'number' ? `${(r.cvr * 100).toFixed(1)}%` : (r.cvr ?? '—');\n if (hasTitle) {\n return [r.post_id ?? r.id, truncate(r.title, 40), r.visits, r.clicks, r.organic, cvr];\n }\n return [r.post_id ?? r.id, r.visits, r.clicks, r.organic, cvr];\n });\n printTable(headers, rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n analytics\n .command('sources')\n .description('Show referrer sources')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('-l, --limit <number>', 'Max results', '20')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const data = await endpoint.sources({\n start_date: opts.startDate,\n end_date: opts.endDate,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.referrer || r.source,\n r.count ?? r.visits,\n ]);\n printTable(['Referrer', 'Count'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n analytics\n .command('post <id>')\n .description('Show traffic or sources for a single post')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--interval <interval>', 'Interval: day, hour', 'day')\n .option('--sources', 'Show referrer sources instead of traffic')\n .option('-l, --limit <number>', 'Max results (for --sources)', '20')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const postId = parseInt(id, 10);\n\n if (opts.sources) {\n const data = await endpoint.postSources(postId, {\n start_date: opts.startDate,\n end_date: opts.endDate,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.referrer || r.source,\n r.count ?? r.visits,\n ]);\n printTable(['Referrer', 'Count'], rows);\n }\n } else {\n const data = await endpoint.postTraffic(postId, {\n start_date: opts.startDate,\n end_date: opts.endDate,\n interval: opts.interval,\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.date || r.period,\n r.visits,\n r.clicks,\n r.organic,\n ]);\n printTable(['Date', 'Visits', 'Clicks', 'Organic'], rows);\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printSuccess } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { uploadImage, type ImageBucket } from '../utils/upload.js';\n\nconst VALID_BUCKETS: ImageBucket[] = ['post_image', 'featured_image', 'logo', 'favicon', 'og_image', 'banner', 'avatar'];\n\nexport function registerImagesCommands(program: Command): void {\n const images = program.command('images').description('Upload images to inblog CDN');\n\n images\n .command('upload <file...>')\n .description('Upload local image file(s) to inblog CDN')\n .option('-b, --bucket <type>', 'Image bucket (post_image, featured_image, logo, favicon, og_image, banner)', 'post_image')\n .action(async function (this: Command, files: string[]) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const bucket = opts.bucket as ImageBucket;\n if (!VALID_BUCKETS.includes(bucket)) {\n throw new Error(`Invalid bucket: ${bucket}. Valid: ${VALID_BUCKETS.join(', ')}`);\n }\n\n const results: { file: string; url: string }[] = [];\n for (const file of files) {\n const url = await uploadImage(file, bucket);\n results.push({ file, url });\n if (!json) {\n printSuccess(`${file} → ${url}`);\n }\n }\n\n if (json) {\n printJson(results);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n"],"mappings":"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","names":["Table","chalk","ref","found","path","fs","path","os","CONFIG_DIR","ensureConfigDir","resolve","program","open","fs","import_node_crypto","fs","path","program","program","program","import_prompts","parts","dns","program","program","program","program","import_open","program","open","program","program"]}
1
+ {"version":3,"sources":["../../bin/inblog.ts","../../src/commands/auth.ts","../../src/utils/config.ts","../../src/utils/output.ts","../../src/sdk/deserialize.ts","../../src/sdk/serialize.ts","../../src/sdk/client.ts","../../src/utils/token-store.ts","../../src/utils/token-refresh.ts","../../src/utils/errors.ts","../../src/sdk/endpoints/posts.ts","../../src/sdk/endpoints/tags.ts","../../src/sdk/endpoints/authors.ts","../../src/sdk/endpoints/blogs.ts","../../src/sdk/endpoints/redirects.ts","../../src/sdk/endpoints/forms.ts","../../src/sdk/endpoints/search-console.ts","../../src/sdk/endpoints/analytics.ts","../../src/utils/client-factory.ts","../../src/utils/pkce.ts","../../src/utils/callback-server.ts","../../src/commands/posts.ts","../../src/utils/upload.ts","../../src/commands/tags.ts","../../src/commands/authors.ts","../../src/commands/blogs.ts","../../src/utils/domain.ts","../../src/commands/redirects.ts","../../src/commands/forms.ts","../../src/commands/config.ts","../../src/commands/search-console.ts","../../src/commands/analytics.ts","../../src/commands/images.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerAuthCommands } from '../src/commands/auth.js';\nimport { registerPostsCommands } from '../src/commands/posts.js';\nimport { registerTagsCommands } from '../src/commands/tags.js';\nimport { registerAuthorsCommands } from '../src/commands/authors.js';\nimport { registerBlogsCommands } from '../src/commands/blogs.js';\nimport { registerRedirectsCommands } from '../src/commands/redirects.js';\nimport { registerFormsCommands, registerFormResponsesCommands } from '../src/commands/forms.js';\nimport { registerConfigCommands } from '../src/commands/config.js';\nimport { registerSearchConsoleCommands } from '../src/commands/search-console.js';\nimport { registerAnalyticsCommands } from '../src/commands/analytics.js';\nimport { registerImagesCommands } from '../src/commands/images.js';\n\n\nconst program = new Command();\n\nprogram\n .name('inblog')\n .description('CLI for managing inblog.ai blog content (posts, tags, authors, redirects, forms)')\n .version('0.2.0')\n .option('--json', 'Output as JSON (for programmatic use)')\n .option('--base-url <url>', 'API base URL')\n .option('--no-color', 'Disable colored output');\n\nregisterAuthCommands(program);\nregisterPostsCommands(program);\nregisterTagsCommands(program);\nregisterAuthorsCommands(program);\nregisterBlogsCommands(program);\nregisterRedirectsCommands(program);\nregisterFormsCommands(program);\nregisterFormResponsesCommands(program);\nregisterConfigCommands(program);\nregisterSearchConsoleCommands(program);\nregisterAnalyticsCommands(program);\nregisterImagesCommands(program);\nprogram.parse();\n","import { Command } from 'commander';\nimport { select } from '@inquirer/prompts';\nimport open from 'open';\nimport { readConfig } from '../utils/config.js';\nimport { printJson, printSuccess, printDetail, printWarning } from '../utils/output.js';\nimport { isJsonMode } from '../utils/client-factory.js';\nimport { handleError } from '../utils/errors.js';\nimport { generateCodeVerifier, generateCodeChallenge } from '../utils/pkce.js';\nimport { startCallbackServer } from '../utils/callback-server.js';\nimport { writeSession, readSession, clearSession } from '../utils/token-store.js';\nimport { exchangeCodeForTokens, SUPABASE_URL } from '../utils/token-refresh.js';\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command('auth').description('Manage authentication');\n\n auth\n .command('login')\n .description('Log in with your Google account')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n if (json) {\n throw new Error('Interactive login is not available in --json mode.');\n }\n\n // Check if already logged in\n const existingSession = readSession();\n if (existingSession) {\n printWarning('Already logged in. Run `inblog auth logout` first to switch accounts.');\n return;\n }\n\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n\n // Start callback server\n const serverPromise = startCallbackServer();\n\n // Wait a tick for the server to start, then open browser\n await new Promise((r) => setTimeout(r, 100));\n\n const redirectUri = `http://127.0.0.1:54321/auth/callback`;\n const authUrl = new URL(`${SUPABASE_URL}/auth/v1/authorize`);\n authUrl.searchParams.set('provider', 'google');\n authUrl.searchParams.set('redirect_to', redirectUri);\n authUrl.searchParams.set('code_challenge', codeChallenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n\n console.log('Opening browser for login...');\n await open(authUrl.toString());\n console.log('Waiting for authentication...');\n\n // Wait for callback\n const { code } = await serverPromise;\n\n // Exchange code for tokens\n const tokens = await exchangeCodeForTokens(code, codeVerifier);\n\n // Fetch user's blogs to pick an active one\n const config = readConfig();\n const baseUrl = this.optsWithGlobals().baseUrl || config.baseUrl || 'https://inblog.ai';\n const response = await fetch(`${baseUrl}/api/v1/user/blogs`, {\n headers: {\n Authorization: `Bearer ${tokens.access_token}`,\n 'X-Blog-Id': '0',\n Accept: 'application/vnd.api+json',\n },\n });\n\n if (!response.ok) {\n writeSession({ tokens });\n printSuccess('Logged in successfully.');\n printWarning('Could not fetch blog list. Run `inblog blogs list` to select a blog.');\n return;\n }\n\n const blogsData: any = await response.json();\n const blogs = blogsData.data || [];\n\n if (blogs.length === 0) {\n writeSession({ tokens });\n printSuccess('Logged in, but you have no blogs yet.');\n return;\n }\n\n let activeBlogId: number;\n let activeBlogSubdomain: string;\n let activeBlogPlan: string | undefined;\n\n if (blogs.length === 1) {\n activeBlogId = parseInt(blogs[0].id, 10);\n activeBlogSubdomain = blogs[0].attributes.subdomain;\n activeBlogPlan = blogs[0].attributes.plan;\n } else {\n const choices = blogs.map((b: any) => ({\n name: `${b.attributes.title} (${b.attributes.subdomain}) [${b.attributes.permission}]`,\n value: { id: parseInt(b.id, 10), subdomain: b.attributes.subdomain },\n }));\n\n const selected = await select<{ id: number; subdomain: string }>({\n message: 'Select a blog to use:',\n choices,\n });\n\n activeBlogId = selected.id;\n activeBlogSubdomain = selected.subdomain;\n const selectedBlog = blogs.find((b: any) => parseInt(b.id, 10) === activeBlogId);\n activeBlogPlan = selectedBlog?.attributes.plan;\n }\n\n writeSession({\n tokens,\n activeBlogId,\n activeBlogSubdomain,\n activeBlogPlan,\n });\n\n printSuccess(`Logged in. Active blog: ${activeBlogSubdomain}`);\n\n if (activeBlogPlan !== 'team' && activeBlogPlan !== 'enterprise') {\n printWarning(`Blog \"${activeBlogSubdomain}\" is on the ${activeBlogPlan || 'free'} plan.`);\n printWarning(' CLI features require a Team plan or above.');\n printWarning(` Upgrade: https://inblog.ai/dashboard/${activeBlogSubdomain}/settings/billing`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n auth\n .command('logout')\n .description('Log out and clear stored session')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n if (json) {\n printJson({ success: true, message: 'Already logged out' });\n } else {\n printWarning('Already logged out.');\n }\n return;\n }\n\n clearSession();\n if (json) {\n printJson({ success: true, message: 'Logged out' });\n } else {\n printSuccess('Logged out.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n auth\n .command('status')\n .description('Show current login status')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n if (json) {\n printJson({ loggedIn: false });\n } else {\n console.log('Not logged in. Run `inblog auth login` to authenticate.');\n }\n return;\n }\n\n const expiresAt = new Date(session.tokens.expires_at * 1000).toISOString();\n\n if (json) {\n printJson({\n loggedIn: true,\n userId: session.tokens.user_id,\n activeBlogId: session.activeBlogId,\n activeBlogSubdomain: session.activeBlogSubdomain,\n tokenExpiresAt: expiresAt,\n });\n } else {\n printDetail([\n ['User ID', session.tokens.user_id],\n ['Active Blog', session.activeBlogSubdomain || '—'],\n ['Active Blog ID', session.activeBlogId || '—'],\n ['Token Expires', expiresAt],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\nexport interface InblogConfig {\n apiKey?: string;\n baseUrl?: string;\n defaultJson?: boolean;\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), '.config', 'inblog');\nconst CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');\nconst LOCAL_CONFIG_FILE = '.inblogrc.json';\n\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function getGlobalConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function getLocalConfigPath(): string | null {\n const localPath = path.resolve(LOCAL_CONFIG_FILE);\n return fs.existsSync(localPath) ? localPath : null;\n}\n\nexport function readGlobalConfig(): InblogConfig {\n if (!fs.existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nexport function readLocalConfig(): InblogConfig {\n const localPath = path.resolve(LOCAL_CONFIG_FILE);\n if (!fs.existsSync(localPath)) return {};\n try {\n return JSON.parse(fs.readFileSync(localPath, 'utf-8'));\n } catch {\n return {};\n }\n}\n\n/**\n * Merged config: local overrides global.\n */\nexport function readConfig(): InblogConfig {\n const global = readGlobalConfig();\n const local = readLocalConfig();\n return { ...global, ...local };\n}\n\nexport function writeGlobalConfig(config: InblogConfig): void {\n ensureConfigDir();\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function setGlobalConfigValue(key: string, value: any): void {\n const config = readGlobalConfig();\n (config as any)[key] = value;\n writeGlobalConfig(config);\n}\n\nexport function deleteGlobalConfigValue(key: string): void {\n const config = readGlobalConfig();\n delete (config as any)[key];\n writeGlobalConfig(config);\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\n/**\n * Print JSON to stdout (for --json mode).\n */\nexport function printJson(data: any): void {\n process.stdout.write(JSON.stringify(data, null, 2) + '\\n');\n}\n\n/**\n * Print a styled table to stdout.\n */\nexport function printTable(\n headers: string[],\n rows: (string | number | null | undefined)[][],\n): void {\n const table = new Table({\n head: headers.map((h) => chalk.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n table.push(row.map((cell) => (cell == null ? chalk.dim('—') : String(cell))));\n }\n console.log(table.toString());\n}\n\n/**\n * Print a key-value detail view.\n */\nexport function printDetail(entries: [string, any][]): void {\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n for (const [key, value] of entries) {\n const label = chalk.cyan(key.padEnd(maxKeyLen));\n const val = value == null ? chalk.dim('—') : String(value);\n console.log(` ${label} ${val}`);\n }\n}\n\n/**\n * Print success message.\n */\nexport function printSuccess(message: string): void {\n console.log(chalk.green(message));\n}\n\n/**\n * Print warning message.\n */\nexport function printWarning(message: string): void {\n console.error(chalk.yellow(message));\n}\n\n/**\n * Print error message to stderr.\n */\nexport function printError(message: string): void {\n console.error(chalk.red(message));\n}\n\n/**\n * Truncate string for table display.\n */\nexport function truncate(str: string | null | undefined, maxLen: number = 50): string {\n if (!str) return '';\n return str.length > maxLen ? str.slice(0, maxLen - 1) + '…' : str;\n}\n","import type { JsonApiResource, JsonApiResponse } from './types.js';\n\n/**\n * Resolve included resources for a relationship.\n */\nfunction resolveRelationship(\n rel: { data: { type: string; id: string } | { type: string; id: string }[] | null },\n included: JsonApiResource[],\n): any {\n if (!rel.data) return null;\n\n if (Array.isArray(rel.data)) {\n return rel.data.map((ref) => {\n const found = included.find((r) => r.type === ref.type && r.id === ref.id);\n return found ? flattenResource(found, included) : { id: ref.id, type: ref.type };\n });\n }\n\n const ref = rel.data as { type: string; id: string };\n const found = included.find((r) => r.type === ref.type && r.id === ref.id);\n return found ? flattenResource(found, included) : { id: ref.id, type: ref.type };\n}\n\n/**\n * Flatten a JSON:API resource into a plain object.\n * Merges id + attributes + resolved relationships.\n */\nexport function flattenResource(\n resource: JsonApiResource,\n included: JsonApiResource[] = [],\n): Record<string, any> {\n const result: Record<string, any> = {\n id: resource.id,\n ...resource.attributes,\n };\n\n if (resource.relationships) {\n for (const [key, rel] of Object.entries(resource.relationships)) {\n result[key] = resolveRelationship(rel, included);\n }\n }\n\n return result;\n}\n\n/**\n * Deserialize a JSON:API response into flat object(s).\n */\nexport function deserialize<T = Record<string, any>>(\n response: JsonApiResponse<JsonApiResource>,\n): T;\nexport function deserialize<T = Record<string, any>>(\n response: JsonApiResponse<JsonApiResource[]>,\n): T[];\nexport function deserialize<T = Record<string, any>>(\n response: JsonApiResponse,\n): T | T[] {\n const included = response.included ?? [];\n\n if (Array.isArray(response.data)) {\n return response.data.map((r) => flattenResource(r, included)) as T[];\n }\n\n return flattenResource(response.data, included) as T;\n}\n\n/**\n * Extract pagination meta from a JSON:API response.\n */\nexport function extractMeta(response: JsonApiResponse): {\n total?: number;\n page?: number;\n limit?: number;\n hasNext: boolean;\n} {\n return {\n total: response.meta?.total,\n page: response.meta?.page,\n limit: response.meta?.limit,\n hasNext: !!response.links?.next,\n };\n}\n","/**\n * Build a JSON:API request body (simplified format).\n * The inblog API accepts both wrapped and unwrapped formats;\n * we use the simplified format: { type, attributes }.\n */\nexport function serialize(\n type: string,\n attributes: Record<string, any>,\n id?: string,\n): { data: { type: string; id?: string; attributes: Record<string, any> } } {\n const resource: { type: string; id?: string; attributes: Record<string, any> } = {\n type,\n attributes,\n };\n\n if (id !== undefined) {\n resource.id = id;\n }\n\n return { data: resource };\n}\n","import type { JsonApiResponse, JsonApiErrorResponse, JsonApiResource } from './types.js';\nimport { deserialize, extractMeta } from './deserialize.js';\nimport { serialize } from './serialize.js';\n\nexport class InblogApiError extends Error {\n status: number;\n code: string;\n title: string;\n detail?: string;\n\n constructor(status: number, code: string, title: string, detail?: string) {\n super(detail || title);\n this.name = 'InblogApiError';\n this.status = status;\n this.code = code;\n this.title = title;\n this.detail = detail;\n }\n}\n\nexport interface ClientOptions {\n apiKey?: string;\n accessToken?: string;\n baseUrl?: string;\n blogId?: number;\n blogSubdomain?: string;\n}\n\nexport class InblogClient {\n private apiKey?: string;\n private accessToken?: string;\n private baseUrl: string;\n private blogId?: number;\n private blogSubdomain?: string;\n private tokenRefresher?: () => Promise<string | null>;\n\n constructor(options: ClientOptions) {\n this.apiKey = options.apiKey;\n this.accessToken = options.accessToken;\n this.baseUrl = (options.baseUrl ?? 'https://inblog.ai').replace(/\\/$/, '');\n this.blogId = options.blogId;\n this.blogSubdomain = options.blogSubdomain;\n\n if (!this.apiKey && !this.accessToken) {\n throw new Error('Either apiKey or accessToken must be provided');\n }\n }\n\n setTokenRefresher(fn: () => Promise<string | null>): void {\n this.tokenRefresher = fn;\n }\n\n private async readHeaders(): Promise<Record<string, string>> {\n const token = await this.resolveToken();\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n Accept: 'application/vnd.api+json',\n };\n if (this.accessToken && this.blogId) {\n headers['X-Blog-Id'] = String(this.blogId);\n }\n return headers;\n }\n\n private async writeHeaders(): Promise<Record<string, string>> {\n const token = await this.resolveToken();\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/vnd.api+json',\n Accept: 'application/vnd.api+json',\n };\n if (this.accessToken && this.blogId) {\n headers['X-Blog-Id'] = String(this.blogId);\n }\n return headers;\n }\n\n private async resolveToken(): Promise<string> {\n if (this.apiKey) return this.apiKey;\n if (this.tokenRefresher) {\n const refreshed = await this.tokenRefresher();\n if (refreshed) {\n this.accessToken = refreshed;\n return refreshed;\n }\n }\n if (this.accessToken) return this.accessToken;\n throw new Error('No valid authentication token available');\n }\n\n private buildUrl(path: string, params?: Record<string, any>): string {\n const url = new URL(`/api${path}`, this.baseUrl);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Handle nested params like filter[slug]=xxx\n for (const [subKey, subValue] of Object.entries(value)) {\n if (subValue !== undefined && subValue !== null) {\n url.searchParams.set(`${key}[${subKey}]`, String(subValue));\n }\n }\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n private async handleResponse(response: Response): Promise<JsonApiResponse> {\n const text = await response.text();\n let body: any;\n\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n throw new InblogApiError(response.status, 'PARSE_ERROR', 'Failed to parse API response');\n }\n\n if (!response.ok) {\n if (body?.errors?.[0]) {\n const err = body.errors[0];\n throw new InblogApiError(\n parseInt(err.status, 10) || response.status,\n err.code || 'UNKNOWN_ERROR',\n err.title || 'API Error',\n err.detail,\n );\n }\n throw new InblogApiError(response.status, 'UNKNOWN_ERROR', `HTTP ${response.status}`);\n }\n\n return body;\n }\n\n async get<T = Record<string, any>>(\n path: string,\n params?: Record<string, any>,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path, params);\n const response = await fetch(url, { method: 'GET', headers: await this.readHeaders() });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async list<T = Record<string, any>>(\n path: string,\n params?: Record<string, any>,\n ): Promise<{ data: T[]; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path, params);\n const response = await fetch(url, { method: 'GET', headers: await this.readHeaders() });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource[]>),\n meta: extractMeta(json),\n };\n }\n\n async create<T = Record<string, any>>(\n path: string,\n type: string,\n attributes: Record<string, any>,\n params?: Record<string, any>,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path, params);\n const body = serialize(type, attributes);\n const response = await fetch(url, {\n method: 'POST',\n headers: await this.writeHeaders(),\n body: JSON.stringify(body),\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async update<T = Record<string, any>>(\n path: string,\n type: string,\n id: string,\n attributes: Record<string, any>,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path);\n const body = serialize(type, attributes, id);\n const response = await fetch(url, {\n method: 'PATCH',\n headers: await this.writeHeaders(),\n body: JSON.stringify(body),\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async delete(path: string): Promise<void> {\n const url = this.buildUrl(path);\n const response = await fetch(url, { method: 'DELETE', headers: await this.readHeaders() });\n if (!response.ok) {\n await this.handleResponse(response); // will throw\n }\n }\n\n async post<T = Record<string, any>>(\n path: string,\n body?: any,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path);\n const response = await fetch(url, {\n method: 'POST',\n headers: await this.writeHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n async patch<T = Record<string, any>>(\n path: string,\n body?: any,\n ): Promise<{ data: T; meta: ReturnType<typeof extractMeta> }> {\n const url = this.buildUrl(path);\n const response = await fetch(url, {\n method: 'PATCH',\n headers: await this.writeHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n const json = await this.handleResponse(response);\n return {\n data: deserialize<T>(json as JsonApiResponse<JsonApiResource>),\n meta: extractMeta(json),\n };\n }\n\n /**\n * Raw GET — for non-JSON:API endpoints that return plain JSON.\n */\n async rawGet(path: string, params?: Record<string, any>): Promise<any> {\n const url = this.buildUrl(path, params);\n const response = await fetch(url, { method: 'GET', headers: await this.readHeaders() });\n return this.handleRawResponse(response);\n }\n\n /**\n * Raw POST — for non-JSON:API endpoints.\n */\n async rawPost(path: string, body?: any): Promise<any> {\n const url = this.buildUrl(path);\n const headers = await this.readHeaders();\n headers['Content-Type'] = 'application/json';\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n return this.handleRawResponse(response);\n }\n\n /**\n * Raw PATCH — for non-JSON:API endpoints.\n */\n async rawPatch(path: string, body?: any): Promise<any> {\n const url = this.buildUrl(path);\n const headers = await this.readHeaders();\n headers['Content-Type'] = 'application/json';\n const response = await fetch(url, {\n method: 'PATCH',\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n return this.handleRawResponse(response);\n }\n\n /**\n * Raw DELETE — for non-JSON:API endpoints.\n */\n async rawDelete(path: string): Promise<any> {\n const url = this.buildUrl(path);\n const response = await fetch(url, { method: 'DELETE', headers: await this.readHeaders() });\n if (response.status === 204) return { success: true };\n return this.handleRawResponse(response);\n }\n\n private async handleRawResponse(response: Response): Promise<any> {\n const text = await response.text();\n let body: any;\n try {\n body = text ? JSON.parse(text) : null;\n } catch {\n if (!response.ok) {\n throw new InblogApiError(response.status, 'PARSE_ERROR', 'Failed to parse API response');\n }\n return text;\n }\n if (!response.ok) {\n if (body?.errors?.[0]) {\n const err = body.errors[0];\n throw new InblogApiError(\n parseInt(err.status, 10) || response.status,\n err.code || 'UNKNOWN_ERROR',\n err.title || 'API Error',\n err.detail,\n );\n }\n throw new InblogApiError(response.status, 'UNKNOWN_ERROR', body?.message || `HTTP ${response.status}`);\n }\n return body;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\nconst CONFIG_DIR = path.join(os.homedir(), '.config', 'inblog');\nconst TOKENS_FILE = path.join(CONFIG_DIR, 'tokens.json');\n\nexport interface StoredTokens {\n access_token: string;\n refresh_token: string;\n expires_at: number;\n user_id: string;\n}\n\nexport interface StoredSession {\n tokens: StoredTokens;\n activeBlogId?: number;\n activeBlogSubdomain?: string;\n activeBlogPlan?: string;\n}\n\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function readSession(): StoredSession | null {\n if (!fs.existsSync(TOKENS_FILE)) return null;\n try {\n return JSON.parse(fs.readFileSync(TOKENS_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nexport function writeSession(session: StoredSession): void {\n ensureConfigDir();\n fs.writeFileSync(TOKENS_FILE, JSON.stringify(session, null, 2) + '\\n', {\n encoding: 'utf-8',\n mode: 0o600,\n });\n}\n\nexport function clearSession(): void {\n if (fs.existsSync(TOKENS_FILE)) {\n fs.unlinkSync(TOKENS_FILE);\n }\n}\n\nexport function setActiveBlog(blogId: number, subdomain: string, plan?: string): void {\n const session = readSession();\n if (!session) {\n throw new Error('Not logged in. Run `inblog auth login` first.');\n }\n session.activeBlogId = blogId;\n session.activeBlogSubdomain = subdomain;\n if (plan !== undefined) session.activeBlogPlan = plan;\n writeSession(session);\n}\n","import { readSession, writeSession, type StoredSession, type StoredTokens } from './token-store.js';\n\nconst SUPABASE_URL =\n process.env.INBLOG_SUPABASE_URL || 'https://fgobbnslcbjgothosvni.supabase.co';\nconst SUPABASE_ANON_KEY =\n process.env.INBLOG_SUPABASE_ANON_KEY ||\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZnb2JibnNsY2JqZ290aG9zdm5pIiwicm9sZSI6ImFub24iLCJpYXQiOjE2Nzc5OTc1MzYsImV4cCI6MTk5MzU3MzUzNn0.cFlx12_PLf42IHJseAxiYOw7MFiS2FOSRgbSZQNDiEo';\n\n// Refresh buffer: refresh 60 seconds before actual expiry\nconst REFRESH_BUFFER_SECONDS = 60;\n\nexport { SUPABASE_URL, SUPABASE_ANON_KEY };\n\nfunction isTokenExpiringSoon(session: StoredSession): boolean {\n const now = Math.floor(Date.now() / 1000);\n return session.tokens.expires_at - now < REFRESH_BUFFER_SECONDS;\n}\n\nasync function refreshTokens(refreshToken: string): Promise<StoredTokens> {\n const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=refresh_token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n apikey: SUPABASE_ANON_KEY,\n },\n body: JSON.stringify({ refresh_token: refreshToken }),\n });\n\n if (!response.ok) {\n throw new Error('Session expired. Run `inblog auth login` to re-authenticate.');\n }\n\n const data: any = await response.json();\n\n return {\n access_token: data.access_token,\n refresh_token: data.refresh_token,\n expires_at: Math.floor(Date.now() / 1000) + data.expires_in,\n user_id: data.user?.id || '',\n };\n}\n\n/**\n * Get a valid access token, refreshing if needed.\n * Returns null if no OAuth session exists.\n */\nexport async function getValidAccessToken(): Promise<string | null> {\n const session = readSession();\n if (!session) return null;\n\n if (!isTokenExpiringSoon(session)) {\n return session.tokens.access_token;\n }\n\n // Refresh the token\n const newTokens = await refreshTokens(session.tokens.refresh_token);\n session.tokens = newTokens;\n writeSession(session);\n\n return newTokens.access_token;\n}\n\n/**\n * Exchange authorization code for tokens using PKCE.\n */\nexport async function exchangeCodeForTokens(\n code: string,\n codeVerifier: string,\n): Promise<StoredTokens> {\n const response = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=pkce`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n apikey: SUPABASE_ANON_KEY,\n },\n body: JSON.stringify({\n auth_code: code,\n code_verifier: codeVerifier,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.text();\n throw new Error(`Token exchange failed: ${errorData}`);\n }\n\n const data: any = await response.json();\n\n return {\n access_token: data.access_token,\n refresh_token: data.refresh_token,\n expires_at: Math.floor(Date.now() / 1000) + data.expires_in,\n user_id: data.user?.id || '',\n };\n}\n","import { InblogApiError } from '../sdk/client.js';\nimport { printError, printJson } from './output.js';\nimport { readSession } from './token-store.js';\n\n/**\n * Check if active blog plan allows CLI usage (team or enterprise).\n * Exits with error if plan is insufficient.\n */\nexport function checkPlanOrExit(): void {\n const session = readSession();\n if (!session) return; // Not logged in — will fail at auth check anyway\n\n const plan = session.activeBlogPlan;\n if (plan === 'team' || plan === 'enterprise') return; // OK\n if (!plan) return; // No plan info cached — let the server decide\n\n printError(`CLI features require a Team plan or above. Current plan: ${plan}`);\n printError(`Upgrade: https://inblog.ai/dashboard/${session.activeBlogSubdomain || ''}/settings/billing`);\n process.exit(1);\n}\n\n/**\n * Handle errors in CLI commands.\n * In --json mode, outputs structured error JSON to stderr.\n * Otherwise prints human-friendly message.\n */\nexport function handleError(error: unknown, json: boolean = false): never {\n if (error instanceof InblogApiError) {\n if (json) {\n const errorObj = {\n error: true,\n status: error.status,\n code: error.code,\n title: error.title,\n detail: error.detail,\n };\n process.stderr.write(JSON.stringify(errorObj, null, 2) + '\\n');\n } else {\n printError(`API Error (${error.status}): ${error.title}`);\n if (error.detail) {\n printError(` ${error.detail}`);\n }\n if (error.code === 'SUBSCRIPTION_REQUIRED') {\n printError(' API access requires a paid plan. Upgrade at https://inblog.ai/dashboard/settings/billing');\n }\n }\n process.exit(2);\n }\n\n if (error instanceof Error) {\n if (json) {\n process.stderr.write(JSON.stringify({ error: true, message: error.message }, null, 2) + '\\n');\n } else {\n printError(error.message);\n }\n process.exit(1);\n }\n\n printError('An unexpected error occurred');\n process.exit(1);\n}\n\n/**\n * Wrap an async command handler with error handling.\n */\nexport function withErrorHandler(\n fn: (...args: any[]) => Promise<void>,\n getJson: (...args: any[]) => boolean,\n): (...args: any[]) => Promise<void> {\n return async (...args: any[]) => {\n try {\n await fn(...args);\n } catch (error) {\n handleError(error, getJson(...args));\n }\n };\n}\n","import type { InblogClient } from '../client.js';\nimport type {\n Post, Author, Tag, PostCreateInput, PostUpdateInput, PostListOptions,\n} from '../types.js';\n\nexport class PostsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: PostListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n if (options.sort) params.sort = options.sort;\n if (options.order) params.order = options.order;\n if (options.include?.length) params.include = options.include.join(',');\n if (options.filter) params.filter = options.filter;\n return this.client.list<Post>('/v1/posts', params);\n }\n\n async get(id: string, include?: string[]) {\n const params: Record<string, any> = {};\n if (include?.length) params.include = include.join(',');\n return this.client.get<Post>(`/v1/posts/${id}`, params);\n }\n\n async create(input: PostCreateInput) {\n const { tag_ids, author_ids, ...attributes } = input;\n const attrs: Record<string, any> = { ...attributes };\n if (tag_ids) attrs.tag_ids = tag_ids;\n if (author_ids) attrs.author_ids = author_ids;\n return this.client.create<Post>('/v1/posts', 'posts', attrs, {\n include: 'tags,authors',\n });\n }\n\n async update(id: string, input: PostUpdateInput) {\n return this.client.update<Post>(`/v1/posts/${id}`, 'posts', id, input as Record<string, any>);\n }\n\n async delete(id: string) {\n return this.client.delete(`/v1/posts/${id}`);\n }\n\n async publish(id: string) {\n return this.client.post<Post>(`/v1/posts/${id}/publish`);\n }\n\n async unpublish(id: string) {\n return this.client.post<Post>(`/v1/posts/${id}/unpublish`);\n }\n\n async schedule(id: string, scheduledAt: string) {\n return this.client.post<Post>(`/v1/posts/${id}/schedule`, {\n data: { type: 'posts', attributes: { published_at: scheduledAt } },\n });\n }\n\n // ── Relationship management ──\n\n async listTags(postId: string) {\n return this.client.list<Tag>(`/v1/posts/${postId}/tags`);\n }\n\n async addTags(postId: string, tagIds: number[]) {\n return this.client.post<Post>(`/v1/posts/${postId}/tags`, {\n data: tagIds.map((id) => ({ id })),\n });\n }\n\n async removeTag(postId: string, tagId: string) {\n return this.client.delete(`/v1/posts/${postId}/tags/${tagId}`);\n }\n\n async listAuthors(postId: string) {\n return this.client.list<Author>(`/v1/posts/${postId}/authors`);\n }\n\n async addAuthors(postId: string, authorIds: string[]) {\n return this.client.post<Post>(`/v1/posts/${postId}/authors`, {\n data: authorIds.map((id) => ({ id })),\n });\n }\n\n async removeAuthor(postId: string, authorId: string) {\n return this.client.delete(`/v1/posts/${postId}/authors/${authorId}`);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Tag, TagCreateInput, TagUpdateInput, TagListOptions } from '../types.js';\n\nexport class TagsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: TagListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.include?.length) params.include = options.include.join(',');\n return this.client.list<Tag>('/v1/tags', params);\n }\n\n async get(id: string) {\n return this.client.get<Tag>(`/v1/tags/${id}`);\n }\n\n async create(input: TagCreateInput) {\n return this.client.create<Tag>('/v1/tags', 'tags', input as Record<string, any>);\n }\n\n async update(id: string, input: TagUpdateInput) {\n return this.client.update<Tag>(`/v1/tags/${id}`, 'tags', id, input as Record<string, any>);\n }\n\n async delete(id: string) {\n return this.client.delete(`/v1/tags/${id}`);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Author, AuthorUpdateInput, AuthorListOptions } from '../types.js';\n\nexport class AuthorsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: AuthorListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n if (options.include?.length) params.include = options.include.join(',');\n return this.client.list<Author>('/v1/authors', params);\n }\n\n async get(id: string) {\n return this.client.get<Author>(`/v1/authors/${id}`);\n }\n\n async update(id: string, input: AuthorUpdateInput) {\n return this.client.update<Author>(\n `/v1/authors/${id}`,\n 'authors',\n id,\n input as Record<string, any>,\n );\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Blog, BlogUpdateInput } from '../types.js';\n\nexport class BlogsEndpoint {\n constructor(private client: InblogClient) {}\n\n async me() {\n return this.client.get<Blog>('/v1/blogs/me');\n }\n\n async update(input: BlogUpdateInput) {\n return this.client.update<Blog>(\n '/v1/blogs/me',\n 'blogs',\n 'me',\n input as Record<string, any>,\n );\n }\n\n // Domain management (plain JSON endpoints, not JSON:API)\n\n async domainConnect(domain: string) {\n return this.client.rawPost('/v1/blogs/domain', { custom_domain: domain });\n }\n\n async domainStatus() {\n return this.client.rawGet('/v1/blogs/domain');\n }\n\n async domainDisconnect() {\n return this.client.rawDelete('/v1/blogs/domain');\n }\n\n // Custom UI / Banner (plain JSON endpoints)\n\n async getCustomUi() {\n return this.client.rawGet('/v1/blogs/custom-ui');\n }\n\n async updateCustomUi(input: Record<string, any>) {\n return this.client.rawPatch('/v1/blogs/custom-ui', input);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Redirect, RedirectCreateInput, RedirectUpdateInput, RedirectListOptions } from '../types.js';\n\nexport class RedirectsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: RedirectListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n return this.client.list<Redirect>('/v1/redirects', params);\n }\n\n async get(id: string) {\n return this.client.get<Redirect>(`/v1/redirects/${id}`);\n }\n\n async create(input: RedirectCreateInput) {\n return this.client.create<Redirect>('/v1/redirects', 'redirects', input as Record<string, any>);\n }\n\n async update(id: string, input: RedirectUpdateInput) {\n return this.client.update<Redirect>(\n `/v1/redirects/${id}`,\n 'redirects',\n id,\n input as Record<string, any>,\n );\n }\n\n async delete(id: string) {\n return this.client.delete(`/v1/redirects/${id}`);\n }\n}\n","import type { InblogClient } from '../client.js';\nimport type { Form, FormResponse, FormListOptions, FormResponseListOptions } from '../types.js';\n\nexport class FormsEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: FormListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n return this.client.list<Form>('/v1/forms', params);\n }\n\n async get(id: string) {\n return this.client.get<Form>(`/v1/forms/${id}`);\n }\n}\n\nexport class FormResponsesEndpoint {\n constructor(private client: InblogClient) {}\n\n async list(options: FormResponseListOptions = {}) {\n const params: Record<string, any> = {};\n if (options.page) params.page = options.page;\n if (options.limit) params.limit = options.limit;\n if (options.filter) params.filter = options.filter;\n return this.client.list<FormResponse>('/v1/form-responses', params);\n }\n\n async get(id: string) {\n return this.client.get<FormResponse>(`/v1/form-responses/${id}`);\n }\n}\n","import type { InblogClient } from '../client.js';\n\nexport class SearchConsoleEndpoint {\n constructor(private client: InblogClient) {}\n\n async oauthUrl(redirectUri?: string) {\n const params: Record<string, string> = {};\n if (redirectUri) params.redirect_uri = redirectUri;\n return this.client.rawGet('/v1/blogs/search-console/oauth-url', params);\n }\n\n async connect(code: string, redirectUri: string) {\n return this.client.rawPost('/v1/blogs/search-console/connect', { code, redirect_uri: redirectUri });\n }\n\n async status() {\n return this.client.rawGet('/v1/blogs/search-console/status');\n }\n\n async disconnect() {\n return this.client.rawDelete('/v1/blogs/search-console/disconnect');\n }\n\n async keywords(options: { start_date?: string; end_date?: string; limit?: number; sort?: string; order?: string } = {}) {\n return this.client.rawGet('/v1/blogs/search-console/keywords', options);\n }\n\n async pages(options: { start_date?: string; end_date?: string; limit?: number; sort?: string; order?: string } = {}) {\n return this.client.rawGet('/v1/blogs/search-console/pages', options);\n }\n}\n","import type { InblogClient } from '../client.js';\n\nexport class AnalyticsEndpoint {\n constructor(private client: InblogClient) {}\n\n async traffic(options: { start_date?: string; end_date?: string; interval?: string; type?: string } = {}) {\n return this.client.rawGet('/v1/blogs/analytics/traffic', options);\n }\n\n async posts(options: { start_date?: string; end_date?: string; sort?: string; order?: string; limit?: number; include?: string } = {}) {\n return this.client.rawGet('/v1/blogs/analytics/posts', options);\n }\n\n async sources(options: { start_date?: string; end_date?: string; limit?: number } = {}) {\n return this.client.rawGet('/v1/blogs/analytics/sources', options);\n }\n\n async postTraffic(postId: number, options: { start_date?: string; end_date?: string; interval?: string } = {}) {\n return this.client.rawGet(`/v1/blogs/analytics/posts/${postId}`, options);\n }\n\n async postSources(postId: number, options: { start_date?: string; end_date?: string; limit?: number } = {}) {\n return this.client.rawGet(`/v1/blogs/analytics/posts/${postId}/sources`, options);\n }\n}\n","import { Command } from 'commander';\nimport { InblogClient } from '../sdk/client.js';\nimport { readConfig } from './config.js';\nimport { readSession } from './token-store.js';\nimport { getValidAccessToken } from './token-refresh.js';\nimport { checkPlanOrExit } from './errors.js';\nimport { PostsEndpoint } from '../sdk/endpoints/posts.js';\nimport { TagsEndpoint } from '../sdk/endpoints/tags.js';\nimport { AuthorsEndpoint } from '../sdk/endpoints/authors.js';\nimport { BlogsEndpoint } from '../sdk/endpoints/blogs.js';\nimport { RedirectsEndpoint } from '../sdk/endpoints/redirects.js';\nimport { FormsEndpoint, FormResponsesEndpoint } from '../sdk/endpoints/forms.js';\nimport { SearchConsoleEndpoint } from '../sdk/endpoints/search-console.js';\nimport { AnalyticsEndpoint } from '../sdk/endpoints/analytics.js';\n\nexport interface ClientContext {\n client: InblogClient;\n posts: PostsEndpoint;\n tags: TagsEndpoint;\n authors: AuthorsEndpoint;\n blogs: BlogsEndpoint;\n redirects: RedirectsEndpoint;\n forms: FormsEndpoint;\n formResponses: FormResponsesEndpoint;\n searchConsole: SearchConsoleEndpoint;\n analytics: AnalyticsEndpoint;\n}\n\n/**\n * Create SDK client from CLI global options.\n */\nexport function createClientFromCommand(cmd: Command): ClientContext {\n checkPlanOrExit();\n const opts = cmd.optsWithGlobals();\n const config = readConfig();\n const baseUrl = opts.baseUrl || config.baseUrl || 'https://inblog.ai';\n\n const session = readSession();\n if (!session) {\n throw new Error('Not logged in. Run `inblog auth login` to authenticate.');\n }\n\n if (!session.activeBlogId || !session.activeBlogSubdomain) {\n throw new Error(\n 'No active blog selected. Run `inblog blogs switch` to select a blog.',\n );\n }\n\n const client = new InblogClient({\n accessToken: session.tokens.access_token,\n baseUrl,\n blogId: session.activeBlogId,\n blogSubdomain: session.activeBlogSubdomain,\n });\n client.setTokenRefresher(getValidAccessToken);\n\n return {\n client,\n posts: new PostsEndpoint(client),\n tags: new TagsEndpoint(client),\n authors: new AuthorsEndpoint(client),\n blogs: new BlogsEndpoint(client),\n redirects: new RedirectsEndpoint(client),\n forms: new FormsEndpoint(client),\n formResponses: new FormResponsesEndpoint(client),\n searchConsole: new SearchConsoleEndpoint(client),\n analytics: new AnalyticsEndpoint(client),\n };\n}\n\n/**\n * Get global --json flag value from command hierarchy.\n */\nexport function isJsonMode(cmd: Command): boolean {\n return cmd.optsWithGlobals().json === true;\n}\n","import { randomBytes, createHash } from 'node:crypto';\n\nexport function generateCodeVerifier(): string {\n return randomBytes(32).toString('base64url');\n}\n\nexport function generateCodeChallenge(verifier: string): string {\n return createHash('sha256').update(verifier).digest('base64url');\n}\n\nexport function generateState(): string {\n return randomBytes(16).toString('hex');\n}\n","import { createServer, type Server } from 'node:http';\n\nconst SUCCESS_HTML = `<!DOCTYPE html><html><body style=\"font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0\"><div style=\"text-align:center\"><h1>Login successful!</h1><p>You can close this window and return to the terminal.</p></div></body></html>`;\n\nconst ERROR_HTML = `<!DOCTYPE html><html><body style=\"font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0\"><div style=\"text-align:center\"><h1>Login failed</h1><p>Please try again.</p></div></body></html>`;\n\n/**\n * Start a temporary HTTP server to receive the OAuth callback from Supabase.\n * Supabase handles CSRF protection via its own internal state,\n * so we only need to capture the authorization code.\n */\nexport function startCallbackServer(\n options: { port?: number; timeout?: number; callbackPath?: string } = {},\n): Promise<{ code: string; port: number }> {\n const { port = 54321, timeout = 300_000, callbackPath = '/auth/callback' } = options;\n\n return new Promise((resolve, reject) => {\n let server: Server;\n let timer: ReturnType<typeof setTimeout>;\n\n const cleanup = () => {\n clearTimeout(timer);\n server.close();\n };\n\n server = createServer((req, res) => {\n const url = new URL(req.url || '/', `http://127.0.0.1`);\n if (url.pathname !== callbackPath) {\n res.writeHead(404);\n res.end('Not found');\n return;\n }\n\n const code = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n const errorDescription = url.searchParams.get('error_description');\n\n if (error) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML);\n cleanup();\n reject(new Error(`OAuth error: ${errorDescription || error}`));\n return;\n }\n\n if (!code) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML);\n cleanup();\n reject(new Error('Missing authorization code in callback'));\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n cleanup();\n resolve({ code, port: actualPort });\n });\n\n let actualPort = port;\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Fallback: let OS assign a port\n server.listen(0, '127.0.0.1');\n } else {\n reject(err);\n }\n });\n\n server.on('listening', () => {\n const addr = server.address();\n if (addr && typeof addr === 'object') {\n actualPort = addr.port;\n }\n });\n\n server.listen(port, '127.0.0.1');\n\n timer = setTimeout(() => {\n cleanup();\n reject(new Error('Login timed out. Please try again.'));\n }, timeout);\n });\n}\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess, printWarning, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { resolveImageUrl, processContentImages } from '../utils/upload.js';\nimport type { PostCreateInput } from '../sdk/types.js';\nimport type { Post } from '../sdk/types.js';\n\nfunction formatPost(post: Post): [string, any][] {\n return [\n ['ID', post.id],\n ['Title', post.title],\n ['Slug', post.slug],\n ['Published', post.published ? 'Yes' : 'No'],\n ['Published At', post.published_at],\n ['Content Type', post.content_type],\n ['Description', post.description],\n ['Image', post.image?.url],\n ['Canonical URL', post.canonical_url],\n ['Meta Title', post.meta_title],\n ['Meta Description', post.meta_description],\n ['Tags', post.tags?.map((t) => t.name).join(', ')],\n ['Authors', post.authors?.map((a) => a.author_name).join(', ')],\n ];\n}\n\nexport function registerPostsCommands(program: Command): void {\n const posts = program.command('posts').description('CRUD, publish, schedule posts + manage tags/authors');\n\n posts\n .command('list')\n .description('List posts with pagination, filters, and sorting')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .option('-s, --sort <field>', 'Sort field (published_at, created_at, title)')\n .option('-o, --order <dir>', 'Sort order (asc, desc)')\n .option('--published', 'Only published posts')\n .option('--draft', 'Only draft posts')\n .option('--tag-id <id>', 'Filter by tag ID')\n .option('--author-id <id>', 'Filter by author ID')\n .option('--include <rels>', 'Include relationships (tags,authors)', 'tags,authors')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n\n const filter: Record<string, any> = {};\n if (opts.published) filter.published = true;\n if (opts.draft) filter.published = false;\n if (opts.tagId) filter.tag_id = parseInt(opts.tagId, 10);\n if (opts.authorId) filter.author_id = opts.authorId;\n\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n sort: opts.sort,\n order: opts.order,\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n include: opts.include ? opts.include.split(',') : undefined,\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Title', 'Slug', 'Published', 'Published At', 'Tags'],\n data.map((p) => [\n p.id,\n truncate(p.title, 40),\n truncate(p.slug, 30),\n p.published ? 'Yes' : 'No',\n p.published_at ? new Date(p.published_at).toLocaleDateString() : '—',\n p.tags?.map((t) => t.name).join(', ') ?? '',\n ]),\n );\n if (meta.total) {\n console.log(`\\nShowing page ${meta.page ?? 1} (${data.length} of ${meta.total} posts)`);\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('get <id>')\n .description('Get post details by ID (integer)')\n .option('--include <rels>', 'Include relationships', 'tags,authors')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id, opts.include?.split(','));\n\n if (json) {\n printJson(data);\n } else {\n printDetail(formatPost(data));\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('create')\n .description('Create post (draft by default, use --published to publish)')\n .requiredOption('-t, --title <title>', 'Post title')\n .option('-s, --slug <slug>', 'Post slug')\n .option('-d, --description <desc>', 'Post description')\n .option('--content <html>', 'HTML content')\n .option('--content-file <path>', 'Read HTML content from file')\n .option('--image <path-or-url>', 'Cover image (local file or URL)')\n .option('--notion-url <url>', 'Notion page URL')\n .option('--published', 'Publish immediately')\n .option('--tag-ids <ids>', 'Comma-separated tag IDs')\n .option('--author-ids <ids>', 'Comma-separated author IDs')\n .option('--canonical-url <url>', 'Canonical URL')\n .option('--meta-title <title>', 'Meta title')\n .option('--meta-description <desc>', 'Meta description')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n\n let contentHtml = opts.content;\n if (opts.contentFile) {\n contentHtml = fs.readFileSync(opts.contentFile, 'utf-8');\n }\n\n // Upload local/base64 images in content\n if (contentHtml) {\n const { html, uploadCount } = await processContentImages(contentHtml);\n contentHtml = html;\n if (uploadCount > 0 && !json) {\n printWarning(`Uploaded ${uploadCount} image(s) to CDN.`);\n }\n }\n\n const input: Record<string, any> = { title: opts.title };\n if (opts.slug) input.slug = opts.slug;\n if (opts.description) input.description = opts.description;\n if (contentHtml) input.content_html = contentHtml;\n if (opts.image) input.image = { url: await resolveImageUrl(opts.image, 'featured_image') };\n if (opts.notionUrl) input.notion_url = opts.notionUrl;\n if (opts.published) input.published = true;\n if (opts.canonicalUrl) input.canonical_url = opts.canonicalUrl;\n if (opts.metaTitle) input.meta_title = opts.metaTitle;\n if (opts.metaDescription) input.meta_description = opts.metaDescription;\n if (opts.tagIds) input.tag_ids = opts.tagIds.split(',').map(Number);\n if (opts.authorIds) input.author_ids = opts.authorIds.split(',');\n\n const { data } = await endpoint.create(input as PostCreateInput);\n\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post created: \"${data.title}\" (ID: ${data.id})`);\n printDetail(formatPost(data));\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('update <id>')\n .description('Update post fields (title, slug, content, SEO metadata)')\n .option('-t, --title <title>', 'Post title')\n .option('-s, --slug <slug>', 'Post slug')\n .option('-d, --description <desc>', 'Post description')\n .option('--content <html>', 'HTML content')\n .option('--content-file <path>', 'Read HTML content from file')\n .option('--image <path-or-url>', 'Cover image (local file or URL)')\n .option('--canonical-url <url>', 'Canonical URL')\n .option('--meta-title <title>', 'Meta title')\n .option('--meta-description <desc>', 'Meta description')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n\n let contentHtml = opts.content;\n if (opts.contentFile) {\n contentHtml = fs.readFileSync(opts.contentFile, 'utf-8');\n }\n\n // Upload local/base64 images in content\n if (contentHtml) {\n const { html, uploadCount } = await processContentImages(contentHtml);\n contentHtml = html;\n if (uploadCount > 0 && !json) {\n printWarning(`Uploaded ${uploadCount} image(s) to CDN.`);\n }\n }\n\n const input: Record<string, any> = {};\n if (opts.title) input.title = opts.title;\n if (opts.slug) input.slug = opts.slug;\n if (opts.description) input.description = opts.description;\n if (contentHtml) input.content_html = contentHtml;\n if (opts.image) input.image = { url: await resolveImageUrl(opts.image, 'featured_image') };\n if (opts.canonicalUrl !== undefined) input.canonical_url = opts.canonicalUrl || null;\n if (opts.metaTitle !== undefined) input.meta_title = opts.metaTitle || null;\n if (opts.metaDescription !== undefined) input.meta_description = opts.metaDescription || null;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post updated: \"${data.title}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('delete <id>')\n .description('Permanently delete a post')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n await endpoint.delete(id);\n if (json) {\n printJson({ success: true, id });\n } else {\n printSuccess(`Post ${id} deleted.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('publish <id>')\n .description('Set post as published (immediately visible)')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.publish(id);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post \"${data.title}\" published.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('unpublish <id>')\n .description('Revert published post to draft')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.unpublish(id);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post \"${data.title}\" unpublished.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('schedule <id>')\n .description('Schedule post for future publishing (ISO 8601 date)')\n .requiredOption('--at <iso-date>', 'ISO 8601 date for scheduled publish')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.schedule(id, opts.at);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Post \"${data.title}\" scheduled for ${opts.at}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n // ── Relationship sub-commands ──\n\n posts\n .command('tags <id>')\n .description('List tags for a post')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.listTags(id);\n if (json) {\n printJson(data);\n } else {\n printTable(['ID', 'Name', 'Slug'], data.map((t) => [t.id, t.name, t.slug]));\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('add-tags <id>')\n .description('Add tags to a post')\n .requiredOption('--tag-ids <ids>', 'Comma-separated tag IDs')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const tagIds = opts.tagIds.split(',').map(Number);\n const { data } = await endpoint.addTags(id, tagIds);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Tags added to post ${id}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('remove-tag <postId> <tagId>')\n .description('Remove a tag from a post')\n .action(async function (this: Command, postId: string, tagId: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n await endpoint.removeTag(postId, tagId);\n if (json) {\n printJson({ success: true, postId, tagId });\n } else {\n printSuccess(`Tag ${tagId} removed from post ${postId}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('authors <id>')\n .description('List authors for a post')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.listAuthors(id);\n if (json) {\n printJson(data);\n } else {\n printTable(\n ['ID', 'Name', 'Avatar URL'],\n data.map((a) => [a.id, a.author_name, truncate(a.avatar_url, 40)]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('add-authors <id>')\n .description('Add authors to a post')\n .requiredOption('--author-ids <ids>', 'Comma-separated author IDs')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { posts: endpoint } = createClientFromCommand(this);\n const authorIds = opts.authorIds.split(',');\n const { data } = await endpoint.addAuthors(id, authorIds);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Authors added to post ${id}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n posts\n .command('remove-author <postId> <authorId>')\n .description('Remove an author from a post')\n .action(async function (this: Command, postId: string, authorId: string) {\n const json = isJsonMode(this);\n try {\n const { posts: endpoint } = createClientFromCommand(this);\n await endpoint.removeAuthor(postId, authorId);\n if (json) {\n printJson({ success: true, postId, authorId });\n } else {\n printSuccess(`Author ${authorId} removed from post ${postId}.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\nconst WORKER_URL = 'https://upload.inblog.dev/';\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\n\nconst MIME_TYPES: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n};\n\nexport type ImageBucket =\n | 'favicon'\n | 'featured_image'\n | 'logo'\n | 'avatar'\n | 'og_image'\n | 'banner'\n | 'post_image';\n\n/**\n * Checks if a string is a local file path (not a URL).\n */\nexport function isLocalPath(value: string): boolean {\n if (value.startsWith('http://') || value.startsWith('https://')) return false;\n return fs.existsSync(value);\n}\n\n/**\n * Uploads a local image file to inblog R2 storage via Worker.\n * Returns the public CDN URL.\n */\nexport async function uploadImage(filePath: string, bucket: ImageBucket): Promise<string> {\n const resolved = path.resolve(filePath);\n\n if (!fs.existsSync(resolved)) {\n throw new Error(`File not found: ${resolved}`);\n }\n\n const stat = fs.statSync(resolved);\n if (stat.size > MAX_FILE_SIZE) {\n throw new Error(`File size exceeds 10MB limit: ${(stat.size / 1024 / 1024).toFixed(1)}MB`);\n }\n\n const ext = path.extname(resolved).toLowerCase();\n const contentType = MIME_TYPES[ext] || 'application/octet-stream';\n\n const fileKey = `${bucket}/${new Date().toISOString()}-${randomUUID()}`;\n const body = fs.readFileSync(resolved);\n\n const response = await fetch(`${WORKER_URL}?fileKey=${fileKey}`, {\n method: 'POST',\n body,\n headers: { 'Content-Type': contentType },\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed: ${response.status} ${response.statusText}`);\n }\n\n const data: any = await response.json();\n return data.publicUrl;\n}\n\n/**\n * If the value is a local file path, uploads it and returns the URL.\n * If it's already a URL, returns it as-is.\n */\nexport async function resolveImageUrl(value: string, bucket: ImageBucket): Promise<string> {\n if (!isLocalPath(value)) return value;\n return uploadImage(value, bucket);\n}\n\n/**\n * Uploads a base64 data URI to R2 and returns the CDN URL.\n */\nasync function uploadBase64(dataUri: string, bucket: ImageBucket): Promise<string> {\n const match = dataUri.match(/^data:([^;]+);base64,(.+)$/s);\n if (!match) throw new Error('Invalid data URI');\n\n const contentType = match[1];\n const body = Buffer.from(match[2], 'base64');\n\n if (body.length > MAX_FILE_SIZE) {\n throw new Error(`Base64 image exceeds 10MB limit: ${(body.length / 1024 / 1024).toFixed(1)}MB`);\n }\n\n const fileKey = `${bucket}/${new Date().toISOString()}-${randomUUID()}`;\n\n const response = await fetch(`${WORKER_URL}?fileKey=${fileKey}`, {\n method: 'POST',\n body,\n headers: { 'Content-Type': contentType },\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed: ${response.status} ${response.statusText}`);\n }\n\n const data: any = await response.json();\n return data.publicUrl;\n}\n\n/**\n * Processes HTML content: finds local file paths and base64 data URIs in\n * img src attributes, uploads them to R2, and replaces with CDN URLs.\n * Returns the processed HTML with all images on CDN.\n */\nexport async function processContentImages(html: string): Promise<{ html: string; uploadCount: number }> {\n // Match src=\"...\" in img tags (data-type=\"imageBlock\" or regular img)\n const imgSrcRegex = /(<img\\s[^>]*\\bsrc=[\"'])([^\"']+)([\"'][^>]*>)/gi;\n const matches: { full: string; prefix: string; src: string; suffix: string; index: number }[] = [];\n\n let m: RegExpExecArray | null;\n while ((m = imgSrcRegex.exec(html)) !== null) {\n matches.push({ full: m[0], prefix: m[1], src: m[2], suffix: m[3], index: m.index });\n }\n\n if (matches.length === 0) return { html, uploadCount: 0 };\n\n let uploadCount = 0;\n const replacements: Map<string, string> = new Map();\n\n // Process uploads concurrently (max 5 at a time)\n const concurrency = 5;\n for (let i = 0; i < matches.length; i += concurrency) {\n const batch = matches.slice(i, i + concurrency);\n const results = await Promise.allSettled(\n batch.map(async ({ src }) => {\n // Skip already-uploaded CDN URLs\n if (src.startsWith('https://source.inblog.dev/') || src.startsWith('https://image.inblog.dev/')) {\n return null;\n }\n\n // Base64 data URI\n if (src.startsWith('data:image/')) {\n const url = await uploadBase64(src, 'post_image');\n return { src, url };\n }\n\n // Local file path\n if (isLocalPath(src)) {\n const url = await uploadImage(src, 'post_image');\n return { src, url };\n }\n\n return null;\n }),\n );\n\n for (const result of results) {\n if (result.status === 'fulfilled' && result.value) {\n replacements.set(result.value.src, result.value.url);\n uploadCount++;\n }\n }\n }\n\n // Apply replacements\n let processed = html;\n for (const [src, url] of replacements) {\n // Use split/join for replacement to avoid regex special char issues with base64\n processed = processed.split(src).join(url);\n }\n\n return { html: processed, uploadCount };\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport type { TagCreateInput } from '../sdk/types.js';\n\nexport function registerTagsCommands(program: Command): void {\n const tags = program.command('tags').description('CRUD tags (no pagination, sorted by priority)');\n\n tags\n .command('list')\n .description('List all tags (returns all, sorted by priority)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { tags: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.list();\n if (json) {\n printJson(data);\n } else {\n printTable(\n ['ID', 'Name', 'Slug', 'Priority'],\n data.map((t) => [t.id, t.name, t.slug, t.priority]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('get <id>')\n .description('Get a tag by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { tags: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Name', data.name],\n ['Slug', data.slug],\n ['Priority', data.priority],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('create')\n .description('Create a new tag')\n .requiredOption('-n, --name <name>', 'Tag name')\n .option('-s, --slug <slug>', 'Tag slug')\n .option('-p, --priority <number>', 'Tag priority')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { tags: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = { name: opts.name };\n if (opts.slug) input.slug = opts.slug;\n if (opts.priority !== undefined) input.priority = parseInt(opts.priority, 10);\n\n const { data } = await endpoint.create(input as TagCreateInput);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Tag created: \"${data.name}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('update <id>')\n .description('Update a tag')\n .option('-n, --name <name>', 'Tag name')\n .option('-s, --slug <slug>', 'Tag slug')\n .option('-p, --priority <number>', 'Tag priority')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { tags: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = {};\n if (opts.name) input.name = opts.name;\n if (opts.slug) input.slug = opts.slug;\n if (opts.priority !== undefined) input.priority = parseInt(opts.priority, 10);\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Tag updated: \"${data.name}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n tags\n .command('delete <id>')\n .description('Delete a tag')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { tags: endpoint } = createClientFromCommand(this);\n await endpoint.delete(id);\n if (json) {\n printJson({ success: true, id });\n } else {\n printSuccess(`Tag ${id} deleted.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerAuthorsCommands(program: Command): void {\n const authors = program.command('authors').description('List, view, update authors (create not available)');\n\n authors\n .command('list')\n .description('List authors (only profiles with posts, UUID IDs)')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { authors: endpoint } = createClientFromCommand(this);\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Name', 'Avatar'],\n data.map((a) => [a.id, a.author_name, truncate(a.avatar_url, 40)]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n authors\n .command('get <id>')\n .description('Get an author by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { authors: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Name', data.author_name],\n ['Avatar URL', data.avatar_url],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n authors\n .command('update <id>')\n .description('Update an author')\n .option('-n, --name <name>', 'Author name')\n .option('--avatar-url <url>', 'Avatar URL')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { authors: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = {};\n if (opts.name) input.author_name = opts.name;\n if (opts.avatarUrl !== undefined) input.avatar_url = opts.avatarUrl || null;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Author updated: \"${data.author_name}\" (ID: ${data.id})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { select } from '@inquirer/prompts';\nimport open from 'open';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { readSession, setActiveBlog } from '../utils/token-store.js';\nimport { getValidAccessToken } from '../utils/token-refresh.js';\nimport { printJson, printDetail, printSuccess, printTable, printWarning } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { readConfig } from '../utils/config.js';\nimport { lookupNameservers, detectDnsProvider, getDnsProviderGuide, isSubdomain } from '../utils/domain.js';\nimport { resolveImageUrl } from '../utils/upload.js';\n\nexport function registerBlogsCommands(program: Command): void {\n const blogs = program.command('blogs').description('Manage blogs — list, switch, view, and update blog settings');\n\n blogs\n .command('me')\n .description('Show blog info (title, subdomain, plan, domain)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { blogs: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.me();\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Title', data.title],\n ['Subdomain', data.subdomain],\n ['Description', data.description],\n ['Plan', data.plan],\n ['Language', data.blog_language],\n ['Custom Domain', data.custom_domain],\n ['Domain Verified', data.custom_domain_verified],\n ['Logo', data.logo_url],\n ['Favicon', data.favicon],\n ['OG Image', data.og_image],\n ['GA ID', data.ga_measurement_id],\n ['Search Console', data.is_search_console_connected ? `Connected (${data.search_console_url})` : 'Not connected'],\n ['Created At', data.created_at],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('create')\n .description('Create a new blog (opens inblog.ai in your browser)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const url = 'https://inblog.ai/dashboard/create?utm_source=cli';\n if (json) {\n printJson({ url });\n } else {\n printSuccess('Opening inblog.ai to create a new blog...');\n await open(url);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('list')\n .description('List all blogs you have access to (OAuth only)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n throw new Error('OAuth session required. Run `inblog auth login` first.');\n }\n\n const accessToken = await getValidAccessToken();\n if (!accessToken) {\n throw new Error('Session expired. Run `inblog auth login` to re-authenticate.');\n }\n\n const config = readConfig();\n const baseUrl = this.optsWithGlobals().baseUrl || config.baseUrl || 'https://inblog.ai';\n\n const response = await fetch(`${baseUrl}/api/v1/user/blogs`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'X-Blog-Id': '0',\n Accept: 'application/vnd.api+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch blogs: HTTP ${response.status}`);\n }\n\n const blogsData: any = await response.json();\n const blogsList = blogsData.data || [];\n\n if (json) {\n printJson(blogsList.map((b: any) => ({\n id: parseInt(b.id, 10),\n ...b.attributes,\n })));\n return;\n }\n\n if (blogsList.length === 0) {\n printWarning('No blogs found.');\n return;\n }\n\n const activeBlogId = session.activeBlogId;\n\n printTable(\n ['', 'ID', 'Title', 'Subdomain', 'Permission', 'Plan'],\n blogsList.map((b: any) => {\n const id = parseInt(b.id, 10);\n const active = id === activeBlogId ? '*' : '';\n return [active, id, b.attributes.title, b.attributes.subdomain, b.attributes.permission, b.attributes.plan];\n }),\n );\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('switch [blog-id]')\n .description('Switch active blog (OAuth only)')\n .action(async function (this: Command, blogIdArg?: string) {\n const json = isJsonMode(this);\n try {\n const session = readSession();\n if (!session) {\n throw new Error('OAuth session required. Run `inblog auth login` first.');\n }\n\n const accessToken = await getValidAccessToken();\n if (!accessToken) {\n throw new Error('Session expired. Run `inblog auth login` to re-authenticate.');\n }\n\n const config = readConfig();\n const baseUrl = this.optsWithGlobals().baseUrl || config.baseUrl || 'https://inblog.ai';\n\n const response = await fetch(`${baseUrl}/api/v1/user/blogs`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'X-Blog-Id': '0',\n Accept: 'application/vnd.api+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch blogs: HTTP ${response.status}`);\n }\n\n const blogsData: any = await response.json();\n const blogsList = blogsData.data || [];\n\n if (blogsList.length === 0) {\n throw new Error('No blogs found for your account.');\n }\n\n let selectedBlogId: number;\n let selectedSubdomain: string;\n\n if (blogIdArg) {\n const target = blogsList.find((b: any) => b.id === blogIdArg || b.attributes.subdomain === blogIdArg);\n if (!target) {\n throw new Error(`Blog not found: ${blogIdArg}`);\n }\n selectedBlogId = parseInt(target.id, 10);\n selectedSubdomain = target.attributes.subdomain;\n } else {\n if (json) {\n throw new Error('Blog ID is required in --json mode. Usage: inblog blogs switch <blog-id>');\n }\n\n const choices = blogsList.map((b: any) => ({\n name: `${b.attributes.title} (${b.attributes.subdomain}) [${b.attributes.permission}]`,\n value: { id: parseInt(b.id, 10), subdomain: b.attributes.subdomain },\n }));\n\n const selected = await select<{ id: number; subdomain: string }>({\n message: 'Select a blog:',\n choices,\n });\n\n selectedBlogId = selected.id;\n selectedSubdomain = selected.subdomain;\n }\n\n const targetBlog = blogsList.find((b: any) => b.id === String(selectedBlogId));\n const activeBlogPlan = targetBlog?.attributes.plan;\n\n setActiveBlog(selectedBlogId, selectedSubdomain, activeBlogPlan);\n\n if (json) {\n printJson({ success: true, blogId: selectedBlogId, subdomain: selectedSubdomain });\n } else {\n printSuccess(`Switched to blog: ${selectedSubdomain}`);\n }\n\n if (activeBlogPlan !== 'team' && activeBlogPlan !== 'enterprise') {\n printWarning(`Blog \"${selectedSubdomain}\" is on the ${activeBlogPlan || 'free'} plan.`);\n printWarning(' CLI features require a Team plan or above.');\n printWarning(` Upgrade: https://inblog.ai/dashboard/${selectedSubdomain}/settings/billing`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n blogs\n .command('update')\n .description('Update blog title, description, language, or timezone')\n .option('-t, --title <title>', 'Blog title')\n .option('-d, --description <desc>', 'Blog description')\n .option('--language <lang>', 'Blog language')\n .option('--timezone-diff <hours>', 'Timezone offset in hours')\n .option('--logo <path-or-url>', 'Blog logo image (local file or URL)')\n .option('--favicon <path-or-url>', 'Blog favicon image (local file or URL)')\n .option('--og-image <path-or-url>', 'Blog OG image (local file or URL)')\n .option('--ga-id <id>', 'Google Analytics measurement ID')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const ctx = createClientFromCommand(this);\n\n const input: Record<string, any> = {};\n if (opts.title) input.title = opts.title;\n if (opts.description) input.description = opts.description;\n if (opts.language) input.blog_language = opts.language;\n if (opts.timezoneDiff !== undefined) input.timezone_diff = parseInt(opts.timezoneDiff, 10);\n if (opts.logo) input.logo = await resolveImageUrl(opts.logo, 'logo');\n if (opts.favicon) input.favicon = await resolveImageUrl(opts.favicon, 'favicon');\n if (opts.ogImage) input.og_image = await resolveImageUrl(opts.ogImage, 'og_image');\n if (opts.gaId) input.ga_measurement_id = opts.gaId;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await ctx.blogs.update(input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Blog updated: \"${data.title}\"`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n // ── Domain subcommands ──\n\n const domain = blogs.command('domain').description('Manage custom domain');\n\n domain\n .command('connect <domain>')\n .description('Connect a custom domain (with DNS provider detection)')\n .action(async function (this: Command, domainArg: string) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.domainConnect(domainArg);\n\n // NS lookup for provider detection\n const nameservers = await lookupNameservers(domainArg);\n const provider = detectDnsProvider(nameservers);\n const guide = provider ? getDnsProviderGuide(provider) : null;\n const isSub = isSubdomain(domainArg);\n\n if (json) {\n printJson({\n ...result,\n nameservers,\n dns_provider: provider,\n dns_provider_guide: guide,\n is_subdomain: isSub,\n });\n } else {\n printSuccess(`Custom domain requested: ${domainArg}`);\n\n // DNS provider info\n if (provider) {\n console.log(`\\n DNS Provider: ${provider}`);\n if (nameservers.length > 0) {\n console.log(` Nameservers: ${nameservers.join(', ')}`);\n }\n } else if (nameservers.length > 0) {\n console.log(`\\n Nameservers: ${nameservers.join(', ')}`);\n }\n\n // DNS records to set\n console.log('\\n DNS 설정:');\n if (isSub) {\n console.log(` → CNAME ${domainArg} → cname.inblog.ai`);\n } else {\n console.log(` → A ${domainArg} → 76.76.21.21`);\n }\n\n if (result.dns_records && result.dns_records.length > 0) {\n console.log('');\n printTable(\n ['Type', 'Name', 'Value'],\n result.dns_records.map((r: any) => [r.type, r.name, r.value]),\n );\n }\n\n // Provider-specific guide\n if (guide) {\n console.log(`\\n ${provider} DNS 설정 가이드: ${guide}`);\n }\n\n printWarning('\\nDNS 전파 후 `inblog blogs domain status`로 확인하세요.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n domain\n .command('status')\n .description('Check custom domain verification status')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.domainStatus();\n\n if (json) {\n printJson(result);\n } else {\n if (!result.custom_domain) {\n printWarning('No custom domain configured.');\n return;\n }\n printDetail([\n ['Domain', result.custom_domain],\n ['Verified', result.verified],\n ['SSL Status', result.ssl_status],\n ]);\n if (result.dns_records && result.dns_records.length > 0) {\n printTable(\n ['Type', 'Name', 'Value'],\n result.dns_records.map((r: any) => [r.type, r.name, r.value]),\n );\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n domain\n .command('disconnect')\n .description('Disconnect custom domain')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n await ctx.blogs.domainDisconnect();\n\n if (json) {\n printJson({ success: true });\n } else {\n printSuccess('Custom domain disconnected.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n // ── Banner subcommands ──\n\n const banner = blogs.command('banner').description('Manage blog banner settings');\n\n banner\n .command('get')\n .description('Show current banner settings')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.getCustomUi();\n\n if (json) {\n printJson(result);\n } else {\n printDetail([\n ['Banner Image', result.banner_url],\n ['Title', result.banner_title],\n ['Subtext', result.banner_subtext],\n ['Title Color', result.banner_title_color],\n ['Background Color', result.banner_bg_color],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n banner\n .command('set')\n .description('Update banner settings')\n .option('--image <path-or-url>', 'Banner image (local file or URL)')\n .option('--title <text>', 'Banner title text')\n .option('--subtext <text>', 'Banner subtext')\n .option('--title-color <hex>', 'Banner title color (hex)')\n .option('--bg-color <hex>', 'Banner background color (hex)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const input: Record<string, any> = {};\n if (opts.image) input.banner_url = await resolveImageUrl(opts.image, 'banner');\n if (opts.title) input.banner_title = opts.title;\n if (opts.subtext) input.banner_subtext = opts.subtext;\n if (opts.titleColor) input.banner_title_color = opts.titleColor;\n if (opts.bgColor) input.banner_bg_color = opts.bgColor;\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option (--image, --title, --subtext, --title-color, --bg-color).');\n }\n\n const ctx = createClientFromCommand(this);\n const result = await ctx.blogs.updateCustomUi(input);\n\n if (json) {\n printJson(result);\n } else {\n printSuccess('Banner updated.');\n printDetail([\n ['Banner Image', result.banner_url],\n ['Title', result.banner_title],\n ['Subtext', result.banner_subtext],\n ['Title Color', result.banner_title_color],\n ['Background Color', result.banner_bg_color],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n banner\n .command('remove')\n .description('Remove banner settings')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const ctx = createClientFromCommand(this);\n await ctx.blogs.updateCustomUi({\n banner_url: null,\n banner_title: null,\n banner_subtext: null,\n });\n\n if (json) {\n printJson({ success: true });\n } else {\n printSuccess('Banner removed.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import dns from 'node:dns/promises';\n\nconst MULTI_PART_TLDS = [\n '.co.uk', '.co.kr', '.co.jp', '.co.nz', '.co.za', '.co.in', '.co.id',\n '.com.au', '.com.br', '.com.cn', '.com.mx', '.com.tw', '.com.sg',\n '.net.au', '.net.br', '.net.cn',\n '.org.uk', '.org.au', '.org.br',\n '.ac.uk', '.ac.kr', '.ac.jp',\n '.ne.jp', '.or.jp', '.or.kr',\n '.gov.uk', '.gov.au', '.gov.br',\n '.edu.au', '.edu.cn',\n];\n\nfunction getRootDomain(domain: string): string {\n const lower = domain.toLowerCase();\n const multiTld = MULTI_PART_TLDS.find((tld) => lower.endsWith(tld));\n if (multiTld) {\n const withoutTld = lower.slice(0, -multiTld.length);\n const parts = withoutTld.split('.').filter(Boolean);\n return parts[parts.length - 1] + multiTld;\n }\n const parts = lower.split('.');\n return parts.slice(-2).join('.');\n}\n\nexport function isSubdomain(domain: string): boolean {\n if (!domain) return false;\n const lower = domain.toLowerCase();\n const multiTld = MULTI_PART_TLDS.find((tld) => lower.endsWith(tld));\n if (multiTld) {\n const withoutTld = lower.slice(0, -multiTld.length);\n return withoutTld.includes('.');\n }\n return domain.split('.').length > 2;\n}\n\nexport async function lookupNameservers(domain: string): Promise<string[]> {\n const rootDomain = getRootDomain(domain);\n try {\n return await dns.resolveNs(rootDomain);\n } catch {\n return [];\n }\n}\n\nconst DNS_PROVIDER_MAP: [string[], string][] = [\n [['godaddy', 'domaincontrol'], 'GoDaddy'],\n [['namecheap', 'registrar-servers.com'], 'Namecheap'],\n [['cloudflare'], 'Cloudflare'],\n [['googledomains', 'google.com'], 'Google Domains'],\n [['awsdns', 'amazon'], 'AWS (Route 53)'],\n [['bluehost'], 'Bluehost'],\n [['siteground'], 'SiteGround'],\n [['hostgator'], 'HostGator'],\n [['dreamhost'], 'DreamHost'],\n [['name.com'], 'Name.com'],\n [['gandi'], 'Gandi'],\n [['gabia'], 'Gabia'],\n [['whois'], 'Whois'],\n [['cafe24'], 'Cafe24'],\n [['imweb'], 'Imweb'],\n [['xinnet'], 'Xinnet'],\n [['aliyun', 'alidns'], 'Aliyun'],\n [['dnspod', 'qcloud'], 'Tencent Cloud'],\n];\n\nexport function detectDnsProvider(nameservers: string[]): string | null {\n if (nameservers.length === 0) return null;\n const nsString = nameservers.join(',').toLowerCase();\n for (const [keywords, provider] of DNS_PROVIDER_MAP) {\n if (keywords.some((kw) => nsString.includes(kw))) return provider;\n }\n return null;\n}\n\nconst DNS_PROVIDER_GUIDES: Record<string, string> = {\n GoDaddy: 'https://www.godaddy.com/help/add-a-cname-record-19236',\n Namecheap: 'https://www.namecheap.com/support/knowledgebase/article.aspx/434/2237/how-do-i-set-up-host-records-for-a-domain/',\n Cloudflare: 'https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/',\n 'Google Domains': 'https://support.google.com/domains/answer/3290350',\n 'AWS (Route 53)': 'https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html',\n Bluehost: 'https://www.bluehost.com/help/article/dns-management-add-edit-or-delete-dns-entries',\n SiteGround: 'https://www.siteground.com/kb/how_to_manage_dns_records/',\n HostGator: 'https://www.hostgator.com/help/article/how-to-change-dns-zones-mx-cname-and-a-records',\n DreamHost: 'https://help.dreamhost.com/hc/en-us/articles/215413857-DreamHost-DNS-overview',\n 'Name.com': 'https://www.name.com/support/articles/205934458-Adding-a-CNAME-Record',\n Gandi: 'https://docs.gandi.net/en/domain_names/common_operations/dns_records.html',\n Gabia: 'https://customer.gabia.com/manual/dns/3041/3040',\n Whois: 'https://cs.whois.co.kr/manual/?p=view&page=1&number=435&keyfield=sub_cont&keyword=dns',\n Cafe24: 'https://help.cafe24.com/docs/domain/domain-hosting-external-service-connection/',\n Imweb: 'https://imweb.me/qna?mode=faq&q=71897',\n Xinnet: 'http://www.xinnet.com/service/cjwt/yuming/guanli/1485.html',\n Aliyun: 'https://www.alibabacloud.com/help/en/dns/user-guide/add-a-dns-record',\n 'Tencent Cloud': 'https://www.tencentcloud.com/document/product/302/3446',\n};\n\nexport function getDnsProviderGuide(provider: string): string | null {\n return DNS_PROVIDER_GUIDES[provider] || null;\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerRedirectsCommands(program: Command): void {\n const redirects = program.command('redirects').description('CRUD URL redirects (307 temporary, 308 permanent)');\n\n redirects\n .command('list')\n .description('List redirects')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '50')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { redirects: endpoint } = createClientFromCommand(this);\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'From', 'To', 'Type'],\n data.map((r) => [r.id, r.from_path, r.to_path, r.redirect_type]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('get <id>')\n .description('Get a redirect by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { redirects: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['From', data.from_path],\n ['To', data.to_path],\n ['Type', data.redirect_type],\n ['Created At', data.created_at],\n ['Updated At', data.updated_at],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('create')\n .description('Create a redirect (default: 308 permanent)')\n .requiredOption('--from <path>', 'Source path (auto-normalized with /)')\n .requiredOption('--to <path>', 'Destination path')\n .option('--type <type>', 'Redirect type (307 or 308)', '308')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { redirects: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.create({\n from_path: opts.from,\n to_path: opts.to,\n redirect_type: parseInt(opts.type, 10) as 307 | 308,\n });\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Redirect created: ${data.from_path} → ${data.to_path} (${data.redirect_type})`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('update <id>')\n .description('Update a redirect')\n .option('--from <path>', 'Source path')\n .option('--to <path>', 'Destination path')\n .option('--type <type>', 'Redirect type (307 or 308)')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { redirects: endpoint } = createClientFromCommand(this);\n const input: Record<string, any> = {};\n if (opts.from) input.from_path = opts.from;\n if (opts.to) input.to_path = opts.to;\n if (opts.type) input.redirect_type = parseInt(opts.type, 10);\n\n if (Object.keys(input).length === 0) {\n throw new Error('No fields to update. Provide at least one option.');\n }\n\n const { data } = await endpoint.update(id, input);\n if (json) {\n printJson(data);\n } else {\n printSuccess(`Redirect updated: ${data.from_path} → ${data.to_path}`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n redirects\n .command('delete <id>')\n .description('Delete a redirect')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { redirects: endpoint } = createClientFromCommand(this);\n await endpoint.delete(id);\n if (json) {\n printJson({ success: true, id });\n } else {\n printSuccess(`Redirect ${id} deleted.`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerFormsCommands(program: Command): void {\n const forms = program.command('forms').description('View lead-capture forms (read-only)');\n\n forms\n .command('list')\n .description('List forms')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { forms: endpoint } = createClientFromCommand(this);\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Title', 'Responses', 'Created At'],\n data.map((f) => [f.id, truncate(f.title, 40), f.response_count, f.created_at]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n forms\n .command('get <id>')\n .description('Get a form by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { forms: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Title', data.title],\n ['Magnet Type', data.magnet_type],\n ['Responses', data.response_count],\n ['Created At', data.created_at],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n\nexport function registerFormResponsesCommands(program: Command): void {\n const formResponses = program.command('form-responses').description('View form submission data (read-only)');\n\n formResponses\n .command('list')\n .description('List form responses')\n .option('-p, --page <number>', 'Page number', '1')\n .option('-l, --limit <number>', 'Items per page', '10')\n .option('--form-id <id>', 'Filter by form ID')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { formResponses: endpoint } = createClientFromCommand(this);\n const filter: Record<string, any> = {};\n if (opts.formId) filter.form_id = opts.formId;\n\n const { data, meta } = await endpoint.list({\n page: parseInt(opts.page, 10),\n limit: parseInt(opts.limit, 10),\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n });\n\n if (json) {\n printJson({ data, meta });\n } else {\n printTable(\n ['ID', 'Email', 'Country', 'Created At'],\n data.map((r) => [r.id, r.email, r.country, r.created_at]),\n );\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n formResponses\n .command('get <id>')\n .description('Get a form response by ID')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const { formResponses: endpoint } = createClientFromCommand(this);\n const { data } = await endpoint.get(id);\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['ID', data.id],\n ['Email', data.email],\n ['Country', data.country],\n ['City', data.city],\n ['Region', data.region],\n ['Language', data.language],\n ['Created At', data.created_at],\n ['Response', JSON.stringify(data.response)],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport {\n readGlobalConfig,\n getGlobalConfigPath,\n getLocalConfigPath,\n setGlobalConfigValue,\n deleteGlobalConfigValue,\n} from '../utils/config.js';\nimport { printJson, printDetail, printSuccess } from '../utils/output.js';\nimport { isJsonMode } from '../utils/client-factory.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerConfigCommands(program: Command): void {\n const config = program.command('config').description('Manage CLI config (~/.config/inblog/config.json)');\n\n config\n .command('list')\n .description('Show all configuration values')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const cfg = readGlobalConfig();\n if (json) {\n printJson(cfg);\n } else {\n const entries = Object.entries(cfg);\n if (entries.length === 0) {\n console.log('No configuration set.');\n } else {\n printDetail(\n entries.map(([k, v]) => [k, typeof v === 'object' ? JSON.stringify(v) : v]),\n );\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n config\n .command('get <key>')\n .description('Get a configuration value')\n .action(async function (this: Command, key: string) {\n const json = isJsonMode(this);\n try {\n const cfg = readGlobalConfig();\n const value = (cfg as any)[key];\n if (json) {\n printJson({ [key]: value ?? null });\n } else if (value === undefined) {\n console.log(`\"${key}\" is not set.`);\n } else {\n console.log(value);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n config\n .command('set <key> <value>')\n .description('Set a configuration value')\n .action(async function (this: Command, key: string, value: string) {\n const json = isJsonMode(this);\n try {\n // Parse booleans and numbers\n let parsed: any = value;\n if (value === 'true') parsed = true;\n else if (value === 'false') parsed = false;\n else if (!isNaN(Number(value)) && value !== '') parsed = Number(value);\n\n setGlobalConfigValue(key, parsed);\n if (json) {\n printJson({ [key]: parsed });\n } else {\n printSuccess(`Set ${key} = ${parsed}`);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n config\n .command('path')\n .description('Show configuration file paths')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const globalPath = getGlobalConfigPath();\n const localPath = getLocalConfigPath();\n if (json) {\n printJson({ global: globalPath, local: localPath });\n } else {\n printDetail([\n ['Global', globalPath],\n ['Local', localPath ?? '(none)'],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport open from 'open';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, printDetail, printSuccess, printWarning } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { startCallbackServer } from '../utils/callback-server.js';\n\nexport function registerSearchConsoleCommands(program: Command): void {\n const sc = program\n .command('search-console')\n .description('Google Search Console integration');\n\n sc.command('connect')\n .description('Connect Google Search Console via OAuth')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n if (json) {\n throw new Error('Interactive OAuth flow is not available in --json mode.');\n }\n\n const { searchConsole } = createClientFromCommand(this);\n\n // Check if already connected\n const statusResult = await searchConsole.status();\n if (statusResult.connected) {\n printWarning('Search Console is already connected.');\n printDetail([\n ['Status', 'Connected'],\n ['Property', statusResult.property || '—'],\n ]);\n return;\n }\n\n const callbackPath = '/auth/gsc-callback';\n const serverPromise = startCallbackServer({ callbackPath });\n\n // Wait a tick for the server to start\n await new Promise((r) => setTimeout(r, 100));\n\n const redirectUri = `http://127.0.0.1:54321${callbackPath}`;\n const oauthResult = await searchConsole.oauthUrl(redirectUri);\n const url = oauthResult.url;\n\n if (!url) {\n throw new Error('Failed to retrieve OAuth URL from server.');\n }\n\n console.log('Opening browser for Google Search Console authorization...');\n await open(url);\n console.log('Waiting for authorization...');\n\n const { code } = await serverPromise;\n\n await searchConsole.connect(code, redirectUri);\n printSuccess('Google Search Console connected successfully.');\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('status')\n .description('Show Search Console connection status')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { searchConsole } = createClientFromCommand(this);\n const data = await searchConsole.status();\n\n if (json) {\n printJson(data);\n } else {\n printDetail([\n ['Connected', data.connected ? 'Yes' : 'No'],\n ['Property', data.property || '—'],\n ]);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('disconnect')\n .description('Disconnect Google Search Console')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const { searchConsole } = createClientFromCommand(this);\n await searchConsole.disconnect();\n\n if (json) {\n printJson({ success: true });\n } else {\n printSuccess('Google Search Console disconnected.');\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('keywords')\n .description('Show keyword performance data')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--sort <field>', 'Sort by: clicks, impressions, ctr, position', 'clicks')\n .option('--order <dir>', 'Sort order: asc, desc', 'desc')\n .option('-l, --limit <number>', 'Max results', '20')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { searchConsole } = createClientFromCommand(this);\n const data = await searchConsole.keywords({\n start_date: opts.startDate,\n end_date: opts.endDate,\n sort: opts.sort,\n order: opts.order,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.keywords || data.data || []).map((k: any) => [\n k.keyword || k.key,\n k.clicks,\n k.impressions,\n typeof k.ctr === 'number' ? `${(k.ctr * 100).toFixed(1)}%` : k.ctr,\n typeof k.position === 'number' ? k.position.toFixed(1) : k.position,\n ]);\n printTable(['Keyword', 'Clicks', 'Impressions', 'CTR', 'Position'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n sc.command('pages')\n .description('Show page performance data')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--sort <field>', 'Sort by: clicks, impressions, ctr, position', 'clicks')\n .option('--order <dir>', 'Sort order: asc, desc', 'desc')\n .option('-l, --limit <number>', 'Max results', '20')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { searchConsole } = createClientFromCommand(this);\n const data = await searchConsole.pages({\n start_date: opts.startDate,\n end_date: opts.endDate,\n sort: opts.sort,\n order: opts.order,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.pages || data.data || []).map((p: any) => [\n p.page || p.key,\n p.clicks,\n p.impressions,\n typeof p.ctr === 'number' ? `${(p.ctr * 100).toFixed(1)}%` : p.ctr,\n typeof p.position === 'number' ? p.position.toFixed(1) : p.position,\n ]);\n printTable(['Page', 'Clicks', 'Impressions', 'CTR', 'Position'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { createClientFromCommand, isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printTable, truncate } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\n\nexport function registerAnalyticsCommands(program: Command): void {\n const analytics = program\n .command('analytics')\n .description('Blog analytics: traffic, post metrics, referrer sources');\n\n analytics\n .command('traffic')\n .description('Show blog overall traffic')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--interval <interval>', 'Interval: day, hour', 'day')\n .option('--type <type>', 'Page type: all, home, post, category, author', 'all')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const data = await endpoint.traffic({\n start_date: opts.startDate,\n end_date: opts.endDate,\n interval: opts.interval,\n type: opts.type,\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.date || r.period,\n r.visits,\n r.clicks,\n r.organic,\n ]);\n printTable(['Date', 'Visits', 'Clicks', 'Organic'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n analytics\n .command('posts')\n .description('Show post-level metrics')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--sort <field>', 'Sort by: visits, clicks, organic, cvr', 'visits')\n .option('--order <dir>', 'Sort order: asc, desc', 'desc')\n .option('-l, --limit <number>', 'Max results', '20')\n .option('--include <fields>', 'Include extra fields (e.g. title)')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const data = await endpoint.posts({\n start_date: opts.startDate,\n end_date: opts.endDate,\n sort: opts.sort,\n order: opts.order,\n limit: parseInt(opts.limit, 10),\n include: opts.include,\n });\n\n if (json) {\n printJson(data);\n } else {\n const hasTitle = opts.include?.includes('title');\n const headers = hasTitle\n ? ['Post ID', 'Title', 'Visits', 'Clicks', 'Organic', 'CVR']\n : ['Post ID', 'Visits', 'Clicks', 'Organic', 'CVR'];\n const rows = (data.data || []).map((r: any) => {\n const cvr = typeof r.cvr === 'number' ? `${(r.cvr * 100).toFixed(1)}%` : (r.cvr ?? '—');\n if (hasTitle) {\n return [r.post_id ?? r.id, truncate(r.title, 40), r.visits, r.clicks, r.organic, cvr];\n }\n return [r.post_id ?? r.id, r.visits, r.clicks, r.organic, cvr];\n });\n printTable(headers, rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n analytics\n .command('sources')\n .description('Show referrer sources')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('-l, --limit <number>', 'Max results', '20')\n .action(async function (this: Command) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const data = await endpoint.sources({\n start_date: opts.startDate,\n end_date: opts.endDate,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.referrer || r.source,\n r.count ?? r.visits,\n ]);\n printTable(['Referrer', 'Count'], rows);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n\n analytics\n .command('post <id>')\n .description('Show traffic or sources for a single post')\n .option('--start-date <date>', 'Start date (YYYY-MM-DD)')\n .option('--end-date <date>', 'End date (YYYY-MM-DD)')\n .option('--interval <interval>', 'Interval: day, hour', 'day')\n .option('--sources', 'Show referrer sources instead of traffic')\n .option('-l, --limit <number>', 'Max results (for --sources)', '20')\n .action(async function (this: Command, id: string) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const { analytics: endpoint } = createClientFromCommand(this);\n const postId = parseInt(id, 10);\n\n if (opts.sources) {\n const data = await endpoint.postSources(postId, {\n start_date: opts.startDate,\n end_date: opts.endDate,\n limit: parseInt(opts.limit, 10),\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.referrer || r.source,\n r.count ?? r.visits,\n ]);\n printTable(['Referrer', 'Count'], rows);\n }\n } else {\n const data = await endpoint.postTraffic(postId, {\n start_date: opts.startDate,\n end_date: opts.endDate,\n interval: opts.interval,\n });\n\n if (json) {\n printJson(data);\n } else {\n const rows = (data.data || []).map((r: any) => [\n r.date || r.period,\n r.visits,\n r.clicks,\n r.organic,\n ]);\n printTable(['Date', 'Visits', 'Clicks', 'Organic'], rows);\n }\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n","import { Command } from 'commander';\nimport { isJsonMode } from '../utils/client-factory.js';\nimport { printJson, printSuccess } from '../utils/output.js';\nimport { handleError } from '../utils/errors.js';\nimport { uploadImage, type ImageBucket } from '../utils/upload.js';\n\nconst VALID_BUCKETS: ImageBucket[] = ['post_image', 'featured_image', 'logo', 'favicon', 'og_image', 'banner', 'avatar'];\n\nexport function registerImagesCommands(program: Command): void {\n const images = program.command('images').description('Upload images to inblog CDN');\n\n images\n .command('upload <file...>')\n .description('Upload local image file(s) to inblog CDN')\n .option('-b, --bucket <type>', 'Image bucket (post_image, featured_image, logo, favicon, og_image, banner)', 'post_image')\n .action(async function (this: Command, files: string[]) {\n const json = isJsonMode(this);\n try {\n const opts = this.opts();\n const bucket = opts.bucket as ImageBucket;\n if (!VALID_BUCKETS.includes(bucket)) {\n throw new Error(`Invalid bucket: ${bucket}. Valid: ${VALID_BUCKETS.join(', ')}`);\n }\n\n const results: { file: string; url: string }[] = [];\n for (const file of files) {\n const url = await uploadImage(file, bucket);\n results.push({ file, url });\n if (!json) {\n printSuccess(`${file} → ${url}`);\n }\n }\n\n if (json) {\n printJson(results);\n }\n } catch (error) {\n handleError(error, json);\n }\n });\n}\n"],"mappings":"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","names":["Table","chalk","ref","found","path","fs","path","os","CONFIG_DIR","ensureConfigDir","resolve","program","open","fs","import_node_crypto","fs","path","program","program","program","import_prompts","import_open","parts","dns","program","open","program","program","program","import_open","program","open","program","program"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inblog/cli",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "CLI tool for managing inblog.ai content",
5
5
  "bin": {
6
6
  "inblog": "./dist/bin/inblog.js"