@inblog/cli 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,584 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/sdk/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthorsEndpoint: () => AuthorsEndpoint,
24
+ BlogsEndpoint: () => BlogsEndpoint,
25
+ FormResponsesEndpoint: () => FormResponsesEndpoint,
26
+ FormsEndpoint: () => FormsEndpoint,
27
+ InblogApiError: () => InblogApiError,
28
+ InblogClient: () => InblogClient,
29
+ PostsEndpoint: () => PostsEndpoint,
30
+ RedirectsEndpoint: () => RedirectsEndpoint,
31
+ TagsEndpoint: () => TagsEndpoint,
32
+ deserialize: () => deserialize,
33
+ extractMeta: () => extractMeta,
34
+ flattenResource: () => flattenResource,
35
+ serialize: () => serialize
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/sdk/deserialize.ts
40
+ function resolveRelationship(rel, included) {
41
+ if (!rel.data) return null;
42
+ if (Array.isArray(rel.data)) {
43
+ return rel.data.map((ref2) => {
44
+ const found2 = included.find((r) => r.type === ref2.type && r.id === ref2.id);
45
+ return found2 ? flattenResource(found2, included) : { id: ref2.id, type: ref2.type };
46
+ });
47
+ }
48
+ const ref = rel.data;
49
+ const found = included.find((r) => r.type === ref.type && r.id === ref.id);
50
+ return found ? flattenResource(found, included) : { id: ref.id, type: ref.type };
51
+ }
52
+ function flattenResource(resource, included = []) {
53
+ const result = {
54
+ id: resource.id,
55
+ ...resource.attributes
56
+ };
57
+ if (resource.relationships) {
58
+ for (const [key, rel] of Object.entries(resource.relationships)) {
59
+ result[key] = resolveRelationship(rel, included);
60
+ }
61
+ }
62
+ return result;
63
+ }
64
+ function deserialize(response) {
65
+ const included = response.included ?? [];
66
+ if (Array.isArray(response.data)) {
67
+ return response.data.map((r) => flattenResource(r, included));
68
+ }
69
+ return flattenResource(response.data, included);
70
+ }
71
+ function extractMeta(response) {
72
+ return {
73
+ total: response.meta?.total,
74
+ page: response.meta?.page,
75
+ limit: response.meta?.limit,
76
+ hasNext: !!response.links?.next
77
+ };
78
+ }
79
+
80
+ // src/sdk/serialize.ts
81
+ function serialize(type, attributes, id) {
82
+ const resource = {
83
+ type,
84
+ attributes
85
+ };
86
+ if (id !== void 0) {
87
+ resource.id = id;
88
+ }
89
+ return { data: resource };
90
+ }
91
+
92
+ // src/sdk/client.ts
93
+ var InblogApiError = class extends Error {
94
+ status;
95
+ code;
96
+ title;
97
+ detail;
98
+ constructor(status, code, title, detail) {
99
+ super(detail || title);
100
+ this.name = "InblogApiError";
101
+ this.status = status;
102
+ this.code = code;
103
+ this.title = title;
104
+ this.detail = detail;
105
+ }
106
+ };
107
+ var InblogClient = class {
108
+ apiKey;
109
+ accessToken;
110
+ baseUrl;
111
+ blogId;
112
+ blogSubdomain;
113
+ tokenRefresher;
114
+ constructor(options) {
115
+ this.apiKey = options.apiKey;
116
+ this.accessToken = options.accessToken;
117
+ this.baseUrl = (options.baseUrl ?? "https://inblog.ai").replace(/\/$/, "");
118
+ this.blogId = options.blogId;
119
+ this.blogSubdomain = options.blogSubdomain;
120
+ if (!this.apiKey && !this.accessToken) {
121
+ throw new Error("Either apiKey or accessToken must be provided");
122
+ }
123
+ }
124
+ setTokenRefresher(fn) {
125
+ this.tokenRefresher = fn;
126
+ }
127
+ async readHeaders() {
128
+ const token = await this.resolveToken();
129
+ const headers = {
130
+ Authorization: `Bearer ${token}`,
131
+ Accept: "application/vnd.api+json"
132
+ };
133
+ if (this.accessToken && this.blogId) {
134
+ headers["X-Blog-Id"] = String(this.blogId);
135
+ }
136
+ return headers;
137
+ }
138
+ async writeHeaders() {
139
+ const token = await this.resolveToken();
140
+ const headers = {
141
+ Authorization: `Bearer ${token}`,
142
+ "Content-Type": "application/vnd.api+json",
143
+ Accept: "application/vnd.api+json"
144
+ };
145
+ if (this.accessToken && this.blogId) {
146
+ headers["X-Blog-Id"] = String(this.blogId);
147
+ }
148
+ return headers;
149
+ }
150
+ async resolveToken() {
151
+ if (this.apiKey) return this.apiKey;
152
+ if (this.tokenRefresher) {
153
+ const refreshed = await this.tokenRefresher();
154
+ if (refreshed) {
155
+ this.accessToken = refreshed;
156
+ return refreshed;
157
+ }
158
+ }
159
+ if (this.accessToken) return this.accessToken;
160
+ throw new Error("No valid authentication token available");
161
+ }
162
+ buildUrl(path, params) {
163
+ const url = new URL(`/api${path}`, this.baseUrl);
164
+ if (params) {
165
+ for (const [key, value] of Object.entries(params)) {
166
+ if (value === void 0 || value === null) continue;
167
+ if (typeof value === "object" && !Array.isArray(value)) {
168
+ for (const [subKey, subValue] of Object.entries(value)) {
169
+ if (subValue !== void 0 && subValue !== null) {
170
+ url.searchParams.set(`${key}[${subKey}]`, String(subValue));
171
+ }
172
+ }
173
+ } else {
174
+ url.searchParams.set(key, String(value));
175
+ }
176
+ }
177
+ }
178
+ return url.toString();
179
+ }
180
+ async handleResponse(response) {
181
+ const text = await response.text();
182
+ let body;
183
+ try {
184
+ body = text ? JSON.parse(text) : null;
185
+ } catch {
186
+ throw new InblogApiError(response.status, "PARSE_ERROR", "Failed to parse API response");
187
+ }
188
+ if (!response.ok) {
189
+ if (body?.errors?.[0]) {
190
+ const err = body.errors[0];
191
+ throw new InblogApiError(
192
+ parseInt(err.status, 10) || response.status,
193
+ err.code || "UNKNOWN_ERROR",
194
+ err.title || "API Error",
195
+ err.detail
196
+ );
197
+ }
198
+ throw new InblogApiError(response.status, "UNKNOWN_ERROR", `HTTP ${response.status}`);
199
+ }
200
+ return body;
201
+ }
202
+ async get(path, params) {
203
+ const url = this.buildUrl(path, params);
204
+ const response = await fetch(url, { method: "GET", headers: await this.readHeaders() });
205
+ const json = await this.handleResponse(response);
206
+ return {
207
+ data: deserialize(json),
208
+ meta: extractMeta(json)
209
+ };
210
+ }
211
+ async list(path, params) {
212
+ const url = this.buildUrl(path, params);
213
+ const response = await fetch(url, { method: "GET", headers: await this.readHeaders() });
214
+ const json = await this.handleResponse(response);
215
+ return {
216
+ data: deserialize(json),
217
+ meta: extractMeta(json)
218
+ };
219
+ }
220
+ async create(path, type, attributes, params) {
221
+ const url = this.buildUrl(path, params);
222
+ const body = serialize(type, attributes);
223
+ const response = await fetch(url, {
224
+ method: "POST",
225
+ headers: await this.writeHeaders(),
226
+ body: JSON.stringify(body)
227
+ });
228
+ const json = await this.handleResponse(response);
229
+ return {
230
+ data: deserialize(json),
231
+ meta: extractMeta(json)
232
+ };
233
+ }
234
+ async update(path, type, id, attributes) {
235
+ const url = this.buildUrl(path);
236
+ const body = serialize(type, attributes, id);
237
+ const response = await fetch(url, {
238
+ method: "PATCH",
239
+ headers: await this.writeHeaders(),
240
+ body: JSON.stringify(body)
241
+ });
242
+ const json = await this.handleResponse(response);
243
+ return {
244
+ data: deserialize(json),
245
+ meta: extractMeta(json)
246
+ };
247
+ }
248
+ async delete(path) {
249
+ const url = this.buildUrl(path);
250
+ const response = await fetch(url, { method: "DELETE", headers: await this.readHeaders() });
251
+ if (!response.ok) {
252
+ await this.handleResponse(response);
253
+ }
254
+ }
255
+ async post(path, body) {
256
+ const url = this.buildUrl(path);
257
+ const response = await fetch(url, {
258
+ method: "POST",
259
+ headers: await this.writeHeaders(),
260
+ body: body ? JSON.stringify(body) : void 0
261
+ });
262
+ const json = await this.handleResponse(response);
263
+ return {
264
+ data: deserialize(json),
265
+ meta: extractMeta(json)
266
+ };
267
+ }
268
+ async patch(path, body) {
269
+ const url = this.buildUrl(path);
270
+ const response = await fetch(url, {
271
+ method: "PATCH",
272
+ headers: await this.writeHeaders(),
273
+ body: body ? JSON.stringify(body) : void 0
274
+ });
275
+ const json = await this.handleResponse(response);
276
+ return {
277
+ data: deserialize(json),
278
+ meta: extractMeta(json)
279
+ };
280
+ }
281
+ /**
282
+ * Raw GET — for non-JSON:API endpoints that return plain JSON.
283
+ */
284
+ async rawGet(path, params) {
285
+ const url = this.buildUrl(path, params);
286
+ const response = await fetch(url, { method: "GET", headers: await this.readHeaders() });
287
+ return this.handleRawResponse(response);
288
+ }
289
+ /**
290
+ * Raw POST — for non-JSON:API endpoints.
291
+ */
292
+ async rawPost(path, body) {
293
+ const url = this.buildUrl(path);
294
+ const headers = await this.readHeaders();
295
+ headers["Content-Type"] = "application/json";
296
+ const response = await fetch(url, {
297
+ method: "POST",
298
+ headers,
299
+ body: body ? JSON.stringify(body) : void 0
300
+ });
301
+ return this.handleRawResponse(response);
302
+ }
303
+ /**
304
+ * Raw PATCH — for non-JSON:API endpoints.
305
+ */
306
+ async rawPatch(path, body) {
307
+ const url = this.buildUrl(path);
308
+ const headers = await this.readHeaders();
309
+ headers["Content-Type"] = "application/json";
310
+ const response = await fetch(url, {
311
+ method: "PATCH",
312
+ headers,
313
+ body: body ? JSON.stringify(body) : void 0
314
+ });
315
+ return this.handleRawResponse(response);
316
+ }
317
+ /**
318
+ * Raw DELETE — for non-JSON:API endpoints.
319
+ */
320
+ async rawDelete(path) {
321
+ const url = this.buildUrl(path);
322
+ const response = await fetch(url, { method: "DELETE", headers: await this.readHeaders() });
323
+ if (response.status === 204) return { success: true };
324
+ return this.handleRawResponse(response);
325
+ }
326
+ async handleRawResponse(response) {
327
+ const text = await response.text();
328
+ let body;
329
+ try {
330
+ body = text ? JSON.parse(text) : null;
331
+ } catch {
332
+ if (!response.ok) {
333
+ throw new InblogApiError(response.status, "PARSE_ERROR", "Failed to parse API response");
334
+ }
335
+ return text;
336
+ }
337
+ if (!response.ok) {
338
+ if (body?.errors?.[0]) {
339
+ const err = body.errors[0];
340
+ throw new InblogApiError(
341
+ parseInt(err.status, 10) || response.status,
342
+ err.code || "UNKNOWN_ERROR",
343
+ err.title || "API Error",
344
+ err.detail
345
+ );
346
+ }
347
+ throw new InblogApiError(response.status, "UNKNOWN_ERROR", body?.message || `HTTP ${response.status}`);
348
+ }
349
+ return body;
350
+ }
351
+ };
352
+
353
+ // src/sdk/endpoints/posts.ts
354
+ var PostsEndpoint = class {
355
+ constructor(client) {
356
+ this.client = client;
357
+ }
358
+ async list(options = {}) {
359
+ const params = {};
360
+ if (options.page) params.page = options.page;
361
+ if (options.limit) params.limit = options.limit;
362
+ if (options.sort) params.sort = options.sort;
363
+ if (options.order) params.order = options.order;
364
+ if (options.include?.length) params.include = options.include.join(",");
365
+ if (options.filter) params.filter = options.filter;
366
+ return this.client.list("/v1/posts", params);
367
+ }
368
+ async get(id, include) {
369
+ const params = {};
370
+ if (include?.length) params.include = include.join(",");
371
+ return this.client.get(`/v1/posts/${id}`, params);
372
+ }
373
+ async create(input) {
374
+ const { tag_ids, author_ids, ...attributes } = input;
375
+ const attrs = { ...attributes };
376
+ if (tag_ids) attrs.tag_ids = tag_ids;
377
+ if (author_ids) attrs.author_ids = author_ids;
378
+ return this.client.create("/v1/posts", "posts", attrs, {
379
+ include: "tags,authors"
380
+ });
381
+ }
382
+ async update(id, input) {
383
+ return this.client.update(`/v1/posts/${id}`, "posts", id, input);
384
+ }
385
+ async delete(id) {
386
+ return this.client.delete(`/v1/posts/${id}`);
387
+ }
388
+ async publish(id) {
389
+ return this.client.post(`/v1/posts/${id}/publish`);
390
+ }
391
+ async unpublish(id) {
392
+ return this.client.post(`/v1/posts/${id}/unpublish`);
393
+ }
394
+ async schedule(id, scheduledAt) {
395
+ return this.client.post(`/v1/posts/${id}/schedule`, {
396
+ data: { type: "posts", attributes: { published_at: scheduledAt } }
397
+ });
398
+ }
399
+ // ── Relationship management ──
400
+ async listTags(postId) {
401
+ return this.client.list(`/v1/posts/${postId}/tags`);
402
+ }
403
+ async addTags(postId, tagIds) {
404
+ return this.client.post(`/v1/posts/${postId}/tags`, {
405
+ data: tagIds.map((id) => ({ id }))
406
+ });
407
+ }
408
+ async removeTag(postId, tagId) {
409
+ return this.client.delete(`/v1/posts/${postId}/tags/${tagId}`);
410
+ }
411
+ async listAuthors(postId) {
412
+ return this.client.list(`/v1/posts/${postId}/authors`);
413
+ }
414
+ async addAuthors(postId, authorIds) {
415
+ return this.client.post(`/v1/posts/${postId}/authors`, {
416
+ data: authorIds.map((id) => ({ id }))
417
+ });
418
+ }
419
+ async removeAuthor(postId, authorId) {
420
+ return this.client.delete(`/v1/posts/${postId}/authors/${authorId}`);
421
+ }
422
+ };
423
+
424
+ // src/sdk/endpoints/tags.ts
425
+ var TagsEndpoint = class {
426
+ constructor(client) {
427
+ this.client = client;
428
+ }
429
+ async list(options = {}) {
430
+ const params = {};
431
+ if (options.include?.length) params.include = options.include.join(",");
432
+ return this.client.list("/v1/tags", params);
433
+ }
434
+ async get(id) {
435
+ return this.client.get(`/v1/tags/${id}`);
436
+ }
437
+ async create(input) {
438
+ return this.client.create("/v1/tags", "tags", input);
439
+ }
440
+ async update(id, input) {
441
+ return this.client.update(`/v1/tags/${id}`, "tags", id, input);
442
+ }
443
+ async delete(id) {
444
+ return this.client.delete(`/v1/tags/${id}`);
445
+ }
446
+ };
447
+
448
+ // src/sdk/endpoints/authors.ts
449
+ var AuthorsEndpoint = class {
450
+ constructor(client) {
451
+ this.client = client;
452
+ }
453
+ async list(options = {}) {
454
+ const params = {};
455
+ if (options.page) params.page = options.page;
456
+ if (options.limit) params.limit = options.limit;
457
+ if (options.include?.length) params.include = options.include.join(",");
458
+ return this.client.list("/v1/authors", params);
459
+ }
460
+ async get(id) {
461
+ return this.client.get(`/v1/authors/${id}`);
462
+ }
463
+ async update(id, input) {
464
+ return this.client.update(
465
+ `/v1/authors/${id}`,
466
+ "authors",
467
+ id,
468
+ input
469
+ );
470
+ }
471
+ };
472
+
473
+ // src/sdk/endpoints/blogs.ts
474
+ var BlogsEndpoint = class {
475
+ constructor(client) {
476
+ this.client = client;
477
+ }
478
+ async me() {
479
+ return this.client.get("/v1/blogs/me");
480
+ }
481
+ async update(subdomain, input) {
482
+ return this.client.update(
483
+ `/v1/blogs/${subdomain}`,
484
+ "blogs",
485
+ subdomain,
486
+ input
487
+ );
488
+ }
489
+ // Domain management (plain JSON endpoints, not JSON:API)
490
+ async domainConnect(domain) {
491
+ return this.client.rawPost("/v1/blogs/domain", { custom_domain: domain });
492
+ }
493
+ async domainStatus() {
494
+ return this.client.rawGet("/v1/blogs/domain");
495
+ }
496
+ async domainDisconnect() {
497
+ return this.client.rawDelete("/v1/blogs/domain");
498
+ }
499
+ // Custom UI / Banner (plain JSON endpoints)
500
+ async getCustomUi() {
501
+ return this.client.rawGet("/v1/blogs/custom-ui");
502
+ }
503
+ async updateCustomUi(input) {
504
+ return this.client.rawPatch("/v1/blogs/custom-ui", input);
505
+ }
506
+ };
507
+
508
+ // src/sdk/endpoints/redirects.ts
509
+ var RedirectsEndpoint = class {
510
+ constructor(client) {
511
+ this.client = client;
512
+ }
513
+ async list(options = {}) {
514
+ const params = {};
515
+ if (options.page) params.page = options.page;
516
+ if (options.limit) params.limit = options.limit;
517
+ return this.client.list("/v1/redirects", params);
518
+ }
519
+ async get(id) {
520
+ return this.client.get(`/v1/redirects/${id}`);
521
+ }
522
+ async create(input) {
523
+ return this.client.create("/v1/redirects", "redirects", input);
524
+ }
525
+ async update(id, input) {
526
+ return this.client.update(
527
+ `/v1/redirects/${id}`,
528
+ "redirects",
529
+ id,
530
+ input
531
+ );
532
+ }
533
+ async delete(id) {
534
+ return this.client.delete(`/v1/redirects/${id}`);
535
+ }
536
+ };
537
+
538
+ // src/sdk/endpoints/forms.ts
539
+ var FormsEndpoint = class {
540
+ constructor(client) {
541
+ this.client = client;
542
+ }
543
+ async list(options = {}) {
544
+ const params = {};
545
+ if (options.page) params.page = options.page;
546
+ if (options.limit) params.limit = options.limit;
547
+ return this.client.list("/v1/forms", params);
548
+ }
549
+ async get(id) {
550
+ return this.client.get(`/v1/forms/${id}`);
551
+ }
552
+ };
553
+ var FormResponsesEndpoint = class {
554
+ constructor(client) {
555
+ this.client = client;
556
+ }
557
+ async list(options = {}) {
558
+ const params = {};
559
+ if (options.page) params.page = options.page;
560
+ if (options.limit) params.limit = options.limit;
561
+ if (options.filter) params.filter = options.filter;
562
+ return this.client.list("/v1/form-responses", params);
563
+ }
564
+ async get(id) {
565
+ return this.client.get(`/v1/form-responses/${id}`);
566
+ }
567
+ };
568
+ // Annotate the CommonJS export names for ESM import in node:
569
+ 0 && (module.exports = {
570
+ AuthorsEndpoint,
571
+ BlogsEndpoint,
572
+ FormResponsesEndpoint,
573
+ FormsEndpoint,
574
+ InblogApiError,
575
+ InblogClient,
576
+ PostsEndpoint,
577
+ RedirectsEndpoint,
578
+ TagsEndpoint,
579
+ deserialize,
580
+ extractMeta,
581
+ flattenResource,
582
+ serialize
583
+ });
584
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/sdk/index.ts","../../src/sdk/deserialize.ts","../../src/sdk/serialize.ts","../../src/sdk/client.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"],"sourcesContent":["export { InblogClient, InblogApiError, type ClientOptions } from './client.js';\nexport { PostsEndpoint } from './endpoints/posts.js';\nexport { TagsEndpoint } from './endpoints/tags.js';\nexport { AuthorsEndpoint } from './endpoints/authors.js';\nexport { BlogsEndpoint } from './endpoints/blogs.js';\nexport { RedirectsEndpoint } from './endpoints/redirects.js';\nexport { FormsEndpoint, FormResponsesEndpoint } from './endpoints/forms.js';\nexport { deserialize, flattenResource, extractMeta } from './deserialize.js';\nexport { serialize } from './serialize.js';\nexport type * from './types.js';\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 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(subdomain: string, input: BlogUpdateInput) {\n return this.client.update<Blog>(\n `/v1/blogs/${subdomain}`,\n 'blogs',\n subdomain,\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"],"mappings":"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","names":["ref","found"]}