@ts-ghost/core-api
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -37,6 +37,18 @@ "use strict"; | ||
ReadFetcher: () => ReadFetcher, | ||
adminAPICredentialsSchema: () => adminAPICredentialsSchema, | ||
adminAPIEndpointsSchema: () => adminAPIEndpointsSchema, | ||
apiVersionsSchema: () => apiVersionsSchema, | ||
baseAuthorsSchema: () => baseAuthorsSchema, | ||
baseEmailSchema: () => baseEmailSchema, | ||
baseMembersSchema: () => baseMembersSchema, | ||
baseNewsletterSchema: () => baseNewsletterSchema, | ||
baseOffersSchema: () => baseOffersSchema, | ||
basePagesSchema: () => basePagesSchema, | ||
basePostsSchema: () => basePostsSchema, | ||
baseSettingsSchema: () => baseSettingsSchema, | ||
baseSiteSchema: () => baseSiteSchema, | ||
baseTagsSchema: () => baseTagsSchema, | ||
baseTiersSchema: () => baseTiersSchema, | ||
browseParamsSchema: () => browseParamsSchema, | ||
contentAPICredentialsSchema: () => contentAPICredentialsSchema, | ||
contentAPIEndpointsSchema: () => contentAPIEndpointsSchema, | ||
ghostCodeInjectionSchema: () => ghostCodeInjectionSchema, | ||
@@ -58,3 +70,6 @@ ghostExcerptSchema: () => ghostExcerptSchema, | ||
// src/schemas.ts | ||
// src/schemas/authors.ts | ||
var import_zod2 = require("zod"); | ||
// src/schemas/shared.ts | ||
var import_zod = require("zod"); | ||
@@ -130,61 +145,414 @@ var ghostIdentitySchema = import_zod.z.object({ | ||
]); | ||
var contentAPIEndpointsSchema = import_zod.z.union([ | ||
import_zod.z.literal("authors"), | ||
import_zod.z.literal("tiers"), | ||
import_zod.z.literal("posts"), | ||
import_zod.z.literal("pages"), | ||
import_zod.z.literal("tags"), | ||
import_zod.z.literal("settings") | ||
]); | ||
var apiVersionsSchema = import_zod.z.enum(["v5.0", "v2", "v3", "v4", "canary"]).default("v5.0"); | ||
var contentAPICredentialsSchema = import_zod.z.discriminatedUnion("endpoint", [ | ||
var contentAPICredentialsSchema = import_zod.z.discriminatedUnion("resource", [ | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("authors"), | ||
resource: import_zod.z.literal("authors"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("tiers"), | ||
resource: import_zod.z.literal("tiers"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("pages"), | ||
resource: import_zod.z.literal("pages"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("posts"), | ||
resource: import_zod.z.literal("posts"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("tags"), | ||
resource: import_zod.z.literal("tags"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("settings"), | ||
resource: import_zod.z.literal("settings"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}) | ||
]); | ||
var adminAPIEndpointsSchema = import_zod.z.union([import_zod.z.literal("posts"), import_zod.z.literal("pages")]); | ||
var adminAPICredentialsSchema = import_zod.z.discriminatedUnion("resource", [ | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("pages"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}), | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("posts"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}), | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("members"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}), | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("site"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}) | ||
]); | ||
// src/schemas/authors.ts | ||
var baseAuthorsSchema = import_zod2.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
name: import_zod2.z.string(), | ||
profile_image: import_zod2.z.string().nullable(), | ||
cover_image: import_zod2.z.string().nullable(), | ||
bio: import_zod2.z.string().nullable(), | ||
website: import_zod2.z.string().nullable(), | ||
location: import_zod2.z.string().nullable(), | ||
facebook: import_zod2.z.string().nullable(), | ||
twitter: import_zod2.z.string().nullable(), | ||
count: import_zod2.z.object({ | ||
posts: import_zod2.z.number() | ||
}).optional(), | ||
url: import_zod2.z.string() | ||
}); | ||
// src/schemas/pages.ts | ||
var import_zod4 = require("zod"); | ||
// src/schemas/tags.ts | ||
var import_zod3 = require("zod"); | ||
var baseTagsSchema = import_zod3.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
...ghostCodeInjectionSchema.shape, | ||
...ghostSocialMediaSchema.shape, | ||
name: import_zod3.z.string(), | ||
description: import_zod3.z.string().nullable(), | ||
feature_image: import_zod3.z.string().nullable(), | ||
visibility: ghostVisibilitySchema, | ||
canonical_url: import_zod3.z.string().nullable(), | ||
accent_color: import_zod3.z.string().nullable(), | ||
url: import_zod3.z.string(), | ||
created_at: import_zod3.z.string().nullish(), | ||
updated_at: import_zod3.z.string().nullish(), | ||
count: import_zod3.z.object({ | ||
posts: import_zod3.z.number() | ||
}).optional() | ||
}); | ||
// src/schemas/pages.ts | ||
var postsAuthorSchema = baseAuthorsSchema.extend({ | ||
url: import_zod4.z.string().nullish() | ||
}); | ||
var basePagesSchema = import_zod4.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
title: import_zod4.z.string(), | ||
html: import_zod4.z.string().nullish(), | ||
plaintext: import_zod4.z.string().nullish(), | ||
comment_id: import_zod4.z.string().nullable(), | ||
feature_image: import_zod4.z.string().nullable(), | ||
feature_image_alt: import_zod4.z.string().nullable(), | ||
feature_image_caption: import_zod4.z.string().nullable(), | ||
featured: import_zod4.z.boolean(), | ||
custom_excerpt: import_zod4.z.string().nullable(), | ||
...ghostCodeInjectionSchema.shape, | ||
...ghostSocialMediaSchema.shape, | ||
visibility: ghostVisibilitySchema, | ||
custom_template: import_zod4.z.string().nullable(), | ||
canonical_url: import_zod4.z.string().nullable(), | ||
authors: import_zod4.z.array(postsAuthorSchema).optional(), | ||
tags: import_zod4.z.array(baseTagsSchema).optional(), | ||
primary_author: postsAuthorSchema.nullish(), | ||
primary_tag: baseTagsSchema.nullish(), | ||
url: import_zod4.z.string(), | ||
excerpt: import_zod4.z.string(), | ||
reading_time: import_zod4.z.number().optional().default(0), | ||
created_at: import_zod4.z.string(), | ||
updated_at: import_zod4.z.string(), | ||
published_at: import_zod4.z.string(), | ||
email_subject: import_zod4.z.string().nullish(), | ||
is_page: import_zod4.z.boolean().default(true) | ||
}); | ||
// src/schemas/posts.ts | ||
var import_zod5 = require("zod"); | ||
var postsAuthorSchema2 = baseAuthorsSchema.extend({ | ||
url: import_zod5.z.string().nullish() | ||
}); | ||
var basePostsSchema = import_zod5.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
title: import_zod5.z.string(), | ||
html: import_zod5.z.string().nullish(), | ||
plaintext: import_zod5.z.string().nullish(), | ||
comment_id: import_zod5.z.string().nullable(), | ||
feature_image: import_zod5.z.string().nullable(), | ||
feature_image_alt: import_zod5.z.string().nullable(), | ||
feature_image_caption: import_zod5.z.string().nullable(), | ||
featured: import_zod5.z.boolean(), | ||
custom_excerpt: import_zod5.z.string().nullable(), | ||
...ghostCodeInjectionSchema.shape, | ||
...ghostSocialMediaSchema.shape, | ||
visibility: ghostVisibilitySchema, | ||
custom_template: import_zod5.z.string().nullable(), | ||
canonical_url: import_zod5.z.string().nullable(), | ||
authors: import_zod5.z.array(postsAuthorSchema2).optional(), | ||
tags: import_zod5.z.array(baseTagsSchema).optional(), | ||
primary_author: postsAuthorSchema2.nullish(), | ||
primary_tag: baseTagsSchema.nullish(), | ||
url: import_zod5.z.string(), | ||
excerpt: import_zod5.z.string(), | ||
reading_time: import_zod5.z.number().optional().default(0), | ||
created_at: import_zod5.z.string(), | ||
updated_at: import_zod5.z.string(), | ||
published_at: import_zod5.z.string(), | ||
email_subject: import_zod5.z.string().nullish(), | ||
is_page: import_zod5.z.boolean().default(false) | ||
}); | ||
// src/schemas/settings.ts | ||
var import_zod6 = require("zod"); | ||
var baseSettingsSchema = import_zod6.z.object({ | ||
title: import_zod6.z.string(), | ||
description: import_zod6.z.string(), | ||
logo: import_zod6.z.string().nullable(), | ||
icon: import_zod6.z.string().nullable(), | ||
accent_color: import_zod6.z.string().nullable(), | ||
cover_image: import_zod6.z.string().nullable(), | ||
facebook: import_zod6.z.string().nullable(), | ||
twitter: import_zod6.z.string().nullable(), | ||
lang: import_zod6.z.string(), | ||
timezone: import_zod6.z.string(), | ||
codeinjection_head: import_zod6.z.string().nullable(), | ||
codeinjection_foot: import_zod6.z.string().nullable(), | ||
navigation: import_zod6.z.array( | ||
import_zod6.z.object({ | ||
label: import_zod6.z.string(), | ||
url: import_zod6.z.string() | ||
}) | ||
), | ||
secondary_navigation: import_zod6.z.array( | ||
import_zod6.z.object({ | ||
label: import_zod6.z.string(), | ||
url: import_zod6.z.string() | ||
}) | ||
), | ||
meta_title: import_zod6.z.string().nullable(), | ||
meta_description: import_zod6.z.string().nullable(), | ||
og_image: import_zod6.z.string().nullable(), | ||
og_title: import_zod6.z.string().nullable(), | ||
og_description: import_zod6.z.string().nullable(), | ||
twitter_image: import_zod6.z.string().nullable(), | ||
twitter_title: import_zod6.z.string().nullable(), | ||
twitter_description: import_zod6.z.string().nullable(), | ||
members_support_address: import_zod6.z.string(), | ||
url: import_zod6.z.string() | ||
}); | ||
// src/schemas/tiers.ts | ||
var import_zod7 = require("zod"); | ||
var baseTiersSchema = import_zod7.z.object({ | ||
...ghostIdentitySchema.shape, | ||
name: import_zod7.z.string(), | ||
description: import_zod7.z.string().nullable(), | ||
active: import_zod7.z.boolean(), | ||
type: import_zod7.z.union([import_zod7.z.literal("free"), import_zod7.z.literal("paid")]), | ||
welcome_page_url: import_zod7.z.string().nullable(), | ||
created_at: import_zod7.z.string(), | ||
updated_at: import_zod7.z.string().nullable(), | ||
stripe_prices: import_zod7.z.array(import_zod7.z.number()).optional().transform((v) => v?.length ? v : []), | ||
monthly_price: import_zod7.z.number().nullable().optional().transform((v) => v ? v : null), | ||
yearly_price: import_zod7.z.number().nullable().optional().transform((v) => v ? v : null), | ||
benefits: import_zod7.z.array(import_zod7.z.string()).nullish(), | ||
visibility: ghostVisibilitySchema, | ||
currency: import_zod7.z.string().nullish(), | ||
trial_days: import_zod7.z.number().default(0) | ||
}); | ||
// src/schemas/email.ts | ||
var import_zod8 = require("zod"); | ||
var baseEmailSchema = import_zod8.z.object({ | ||
id: import_zod8.z.string(), | ||
uuid: import_zod8.z.string(), | ||
status: import_zod8.z.string(), | ||
recipient_filter: import_zod8.z.string(), | ||
error: import_zod8.z.string().nullish(), | ||
error_data: import_zod8.z.any().nullable(), | ||
email_count: import_zod8.z.number(), | ||
delivered_count: import_zod8.z.number(), | ||
opened_count: import_zod8.z.number(), | ||
failed_count: import_zod8.z.number(), | ||
subject: import_zod8.z.string(), | ||
from: import_zod8.z.string(), | ||
reply_to: import_zod8.z.string(), | ||
html: import_zod8.z.string(), | ||
plaintext: import_zod8.z.string(), | ||
track_opens: import_zod8.z.boolean(), | ||
submitted_at: import_zod8.z.string(), | ||
created_at: import_zod8.z.string(), | ||
updated_at: import_zod8.z.string() | ||
}); | ||
// src/schemas/offers.ts | ||
var import_zod9 = require("zod"); | ||
var baseOffersSchema = import_zod9.z.object({ | ||
id: import_zod9.z.string(), | ||
name: import_zod9.z.string({ description: "Internal name for an offer, must be unique" }), | ||
code: import_zod9.z.string({ description: "Shortcode for the offer, for example: https://yoursite.com/black-friday" }), | ||
display_title: import_zod9.z.string({ description: "Name displayed in the offer window" }), | ||
display_description: import_zod9.z.string({ description: "Text displayed in the offer window" }), | ||
type: import_zod9.z.union([import_zod9.z.literal("percent"), import_zod9.z.literal("fixed")]), | ||
cadence: import_zod9.z.union([import_zod9.z.literal("month"), import_zod9.z.literal("year")]), | ||
amount: import_zod9.z.number({ | ||
description: `Offer discount amount, as a percentage or fixed value as set in type. | ||
Amount is always denoted by the smallest currency unit | ||
(e.g., 100 cents instead of $1.00 in USD)` | ||
}), | ||
duration: import_zod9.z.union([import_zod9.z.literal("once"), import_zod9.z.literal("forever"), import_zod9.z.literal("repeating")], { | ||
description: "once/forever/repeating. repeating duration is only available when cadence is month" | ||
}), | ||
duration_in_months: import_zod9.z.number({ description: "Number of months offer should be repeated when duration is repeating" }).nullable(), | ||
currency_restriction: import_zod9.z.boolean({ | ||
description: "Denotes whether the offer `currency` is restricted. If so, changing the currency invalidates the offer" | ||
}), | ||
currency: import_zod9.z.string({ description: "fixed type offers only - specifies tier's currency as three letter ISO currency code" }).nullable(), | ||
status: import_zod9.z.union([import_zod9.z.literal("active"), import_zod9.z.literal("archived")], { | ||
description: "active or archived - denotes if the offer is active or archived" | ||
}), | ||
redemption_count: import_zod9.z.number({ description: "Number of times the offer has been redeemed" }), | ||
tier: import_zod9.z.object( | ||
{ | ||
id: import_zod9.z.string(), | ||
name: import_zod9.z.string() | ||
}, | ||
{ description: "Tier on which offer is applied" } | ||
) | ||
}); | ||
// src/schemas/members.ts | ||
var import_zod11 = require("zod"); | ||
// src/schemas/newsletter.ts | ||
var import_zod10 = require("zod"); | ||
var baseNewsletterSchema = import_zod10.z.object({ | ||
...ghostIdentitySchema.shape, | ||
name: import_zod10.z.string({ description: "Public name for the newsletter" }), | ||
description: import_zod10.z.string({ description: "(nullable) Public description of the newsletter" }).nullish(), | ||
sender_name: import_zod10.z.string({ description: "(nullable) The sender name of the emails" }).nullish(), | ||
sender_email: import_zod10.z.string({ description: "(nullable) The email from which to send emails. Requires validation." }).nullish(), | ||
sender_reply_to: import_zod10.z.string({ | ||
description: "The reply-to email address for sent emails. Can be either newsletter (= use sender_email) or support (use support email from Portal settings)." | ||
}), | ||
status: import_zod10.z.union([import_zod10.z.literal("active"), import_zod10.z.literal("archived")], { | ||
description: "active or archived - denotes if the newsletter is active or archived" | ||
}), | ||
visibility: import_zod10.z.union([import_zod10.z.literal("public"), import_zod10.z.literal("members")]), | ||
subscribe_on_signup: import_zod10.z.boolean({ | ||
description: "true/false. Whether members should automatically subscribe to this newsletter on signup" | ||
}), | ||
sort_order: import_zod10.z.number({ description: "The order in which newsletters are displayed in the Portal" }), | ||
header_image: import_zod10.z.string({ description: "(nullable) Path to an image to show at the top of emails. Recommended size 1200x600" }).nullish(), | ||
show_header_icon: import_zod10.z.boolean({ description: "true/false. Show the site icon in emails" }), | ||
show_header_title: import_zod10.z.boolean({ description: "true/false. Show the site name in emails" }), | ||
title_font_category: import_zod10.z.union([import_zod10.z.literal("serif"), import_zod10.z.literal("sans_serif")], { | ||
description: "Title font style. Either serif or sans_serif" | ||
}), | ||
title_alignment: import_zod10.z.string().nullish(), | ||
show_feature_image: import_zod10.z.boolean({ description: "true/false. Show the post's feature image in emails" }), | ||
body_font_category: import_zod10.z.union([import_zod10.z.literal("serif"), import_zod10.z.literal("sans_serif")], { | ||
description: "Body font style. Either serif or sans_serif" | ||
}), | ||
footer_content: import_zod10.z.string({ | ||
description: "(nullable) Extra information or legal text to show in the footer of emails. Should contain valid HTML." | ||
}).nullish(), | ||
show_badge: import_zod10.z.boolean({ | ||
description: "true/false. Show you\u2019re a part of the indie publishing movement by adding a small Ghost badge in the footer" | ||
}), | ||
created_at: import_zod10.z.string(), | ||
updated_at: import_zod10.z.string().nullish(), | ||
show_header_name: import_zod10.z.boolean({ description: "true/false. Show the newsletter name in emails" }), | ||
uuid: import_zod10.z.string() | ||
}); | ||
// src/schemas/members.ts | ||
var baseMembersSchema = import_zod11.z.object({ | ||
id: import_zod11.z.string(), | ||
email: import_zod11.z.string({ description: "The email address of the member" }), | ||
name: import_zod11.z.string({ description: "The name of the member" }), | ||
note: import_zod11.z.string({ description: "(nullable) A note about the member" }).nullish(), | ||
geolocation: import_zod11.z.string({ description: "(nullable) The geolocation of the member" }).nullish(), | ||
created_at: import_zod11.z.string({ description: "The date and time the member was created" }), | ||
updated_at: import_zod11.z.string({ description: "(nullable) The date and time the member was last updated" }).nullish(), | ||
labels: import_zod11.z.array( | ||
import_zod11.z.object({ | ||
id: import_zod11.z.string({ description: "The ID of the label" }), | ||
name: import_zod11.z.string({ description: "The name of the label" }), | ||
slug: import_zod11.z.string({ description: "The slug of the label" }), | ||
created_at: import_zod11.z.string({ description: "The date and time the label was created" }), | ||
updated_at: import_zod11.z.string({ description: "(nullable) The date and time the label was last updated" }).nullish() | ||
}), | ||
{ description: "The labels associated with the member" } | ||
), | ||
subscriptions: import_zod11.z.array(import_zod11.z.string({ description: "The subscriptions associated with the member" })), | ||
avatar_image: import_zod11.z.string({ description: "The URL of the member's avatar image" }), | ||
email_count: import_zod11.z.number({ description: "The number of emails sent to the member" }), | ||
email_opened_count: import_zod11.z.number({ description: "The number of emails opened by the member" }), | ||
email_open_rate: import_zod11.z.number({ description: "(nullable) The open rate of the member" }).nullish(), | ||
status: import_zod11.z.string({ description: "The status of the member" }), | ||
last_seen_at: import_zod11.z.string({ description: "(nullable) The date and time the member was last seen" }).nullish(), | ||
newsletters: import_zod11.z.array(baseNewsletterSchema) | ||
}); | ||
// src/schemas/site.ts | ||
var import_zod12 = require("zod"); | ||
var baseSiteSchema = import_zod12.z.object({ | ||
title: import_zod12.z.string(), | ||
description: import_zod12.z.string(), | ||
logo: import_zod12.z.string().nullable(), | ||
version: import_zod12.z.string(), | ||
url: import_zod12.z.string() | ||
}); | ||
// src/query-builder/browse-params.ts | ||
var import_zod2 = require("zod"); | ||
var browseParamsSchema = import_zod2.z.object({ | ||
order: import_zod2.z.string().optional(), | ||
limit: import_zod2.z.number().refine((n) => n && n > 0 && n <= 15, { | ||
var import_zod13 = require("zod"); | ||
var browseParamsSchema = import_zod13.z.object({ | ||
order: import_zod13.z.string().optional(), | ||
limit: import_zod13.z.number().refine((n) => n && n > 0 && n <= 15, { | ||
message: "Limit must be between 1 and 15" | ||
}).optional(), | ||
page: import_zod2.z.number().refine((n) => n && n >= 1, { | ||
page: import_zod13.z.number().refine((n) => n && n >= 1, { | ||
message: "Page must be greater than 1" | ||
}).optional(), | ||
filter: import_zod2.z.string().optional() | ||
filter: import_zod13.z.string().optional() | ||
}); | ||
@@ -194,4 +562,4 @@ var parseBrowseParams = (args, schema) => { | ||
const augmentedSchema = browseParamsSchema.merge( | ||
import_zod2.z.object({ | ||
order: import_zod2.z.string().superRefine((val, ctx) => { | ||
import_zod13.z.object({ | ||
order: import_zod13.z.string().superRefine((val, ctx) => { | ||
const orderPredicates = val.split(","); | ||
@@ -202,3 +570,3 @@ for (const orderPredicate of orderPredicates) { | ||
ctx.addIssue({ | ||
code: import_zod2.z.ZodIssueCode.custom, | ||
code: import_zod13.z.ZodIssueCode.custom, | ||
message: `Field "${field}" is not a valid field`, | ||
@@ -210,3 +578,3 @@ fatal: true | ||
ctx.addIssue({ | ||
code: import_zod2.z.ZodIssueCode.custom, | ||
code: import_zod13.z.ZodIssueCode.custom, | ||
message: "Order direction must be ASC or DESC", | ||
@@ -218,3 +586,3 @@ fatal: true | ||
}).optional(), | ||
filter: import_zod2.z.string().superRefine((val, ctx) => { | ||
filter: import_zod13.z.string().superRefine((val, ctx) => { | ||
const filterPredicates = val.split(/[+(,]+/); | ||
@@ -225,3 +593,3 @@ for (const filterPredicate of filterPredicates) { | ||
ctx.addIssue({ | ||
code: import_zod2.z.ZodIssueCode.custom, | ||
code: import_zod13.z.ZodIssueCode.custom, | ||
message: `Field "${field}" is not a valid field`, | ||
@@ -244,4 +612,46 @@ fatal: true | ||
// src/fetchers/browse-fetcher.ts | ||
var import_zod14 = require("zod"); | ||
// src/fetchers/helpers.ts | ||
var import_cross_fetch = __toESM(require("cross-fetch")); | ||
var import_zod3 = require("zod"); | ||
var import_jsonwebtoken = __toESM(require("jsonwebtoken")); | ||
function getJWT(key) { | ||
const [id, secret] = key.split(":"); | ||
return import_jsonwebtoken.default.sign({}, Buffer.from(secret, "hex"), { | ||
keyid: id, | ||
algorithm: "HS256", | ||
expiresIn: "5m", | ||
audience: "/admin/" | ||
}); | ||
} | ||
async function _fetch(URL2, api) { | ||
if (URL2 === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
const headers = { | ||
"Content-Type": "application/json", | ||
"Accept-Version": api.version | ||
}; | ||
if (api.endpoint === "admin") { | ||
headers["Authorization"] = `Ghost ${getJWT(api.key)}`; | ||
} | ||
try { | ||
result = await (await (0, import_cross_fetch.default)(URL2.toString(), { | ||
headers | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
// src/fetchers/browse-fetcher.ts | ||
var BrowseFetcher = class { | ||
@@ -256,7 +666,72 @@ constructor(config, _params = { browseParams: {}, include: [], fields: {} }, _api) { | ||
this._buildUrlParams(); | ||
this._endpoint = _api.endpoint; | ||
this._resource = _api.resource; | ||
} | ||
getEndpoint() { | ||
return this._endpoint; | ||
/** | ||
* Lets you choose output format for the content of Post and Pages resources | ||
* The choices are html, mobiledoc or plaintext. It will transform the output of the fetcher to a new shape | ||
* with the selected formats required. | ||
* | ||
* @param formats html, mobiledoc or plaintext | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
formats(formats) { | ||
const params = { | ||
...this._params, | ||
formats: Object.keys(formats) | ||
}; | ||
return new BrowseFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(formats), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you include special keys into the Ghost API Query to retrieve complimentary info | ||
* The available keys are defined by the Resource include schema, will not care about unknown keys. | ||
* Returns a new Fetcher with an Output shape modified with the include keys required. | ||
* | ||
* @param include Include specific keys from the include shape | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
include(include) { | ||
const params = { | ||
...this._params, | ||
include: Object.keys(include) | ||
}; | ||
return new BrowseFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(include), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you strip the output to only the specified keys of your choice that are in the config Schema | ||
* Will not care about unknown keys and return a new Fetcher with an Output shape with only the selected keys. | ||
* | ||
* @param fields Any keys from the resource Schema | ||
* @returns A new Fetcher with the fixed output shape having only the selected Fields | ||
*/ | ||
fields(fields) { | ||
const newOutput = this.config.output.pick(fields); | ||
return new BrowseFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: newOutput, | ||
include: this.config.include | ||
}, | ||
this._params, | ||
this._api | ||
); | ||
} | ||
getResource() { | ||
return this._resource; | ||
} | ||
getParams() { | ||
@@ -274,9 +749,18 @@ return this._params; | ||
} | ||
getFormats() { | ||
return this._params?.formats || []; | ||
} | ||
_buildUrlParams() { | ||
const inputKeys = this.config.schema.keyof().options; | ||
const outputKeys = this.config.output.keyof().options; | ||
this._urlParams = { | ||
key: this._api.key, | ||
...this._urlBrowseParams() | ||
}; | ||
if (this._api.endpoint === "content") { | ||
this._urlParams = { | ||
key: this._api.key, | ||
...this._urlBrowseParams() | ||
}; | ||
} else { | ||
this._urlParams = { | ||
...this._urlBrowseParams() | ||
}; | ||
} | ||
if (inputKeys.length !== outputKeys.length && outputKeys.length > 0) { | ||
@@ -288,4 +772,7 @@ this._urlParams.fields = outputKeys.join(","); | ||
} | ||
if (this._params.formats && this._params.formats.length > 0) { | ||
this._urlParams.formats = this._params.formats.join(","); | ||
} | ||
const url = new URL(this._api.url); | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/`; | ||
for (const [key, value] of Object.entries(this._urlParams)) { | ||
@@ -313,14 +800,14 @@ url.searchParams.append(key, value); | ||
_getResultSchema() { | ||
return import_zod3.z.discriminatedUnion("status", [ | ||
import_zod3.z.object({ | ||
status: import_zod3.z.literal("success"), | ||
return import_zod14.z.discriminatedUnion("status", [ | ||
import_zod14.z.object({ | ||
status: import_zod14.z.literal("success"), | ||
meta: ghostMetaSchema, | ||
data: import_zod3.z.array(this.config.output) | ||
data: import_zod14.z.array(this.config.output) | ||
}), | ||
import_zod3.z.object({ | ||
status: import_zod3.z.literal("error"), | ||
errors: import_zod3.z.array( | ||
import_zod3.z.object({ | ||
type: import_zod3.z.string(), | ||
message: import_zod3.z.string() | ||
import_zod14.z.object({ | ||
status: import_zod14.z.literal("error"), | ||
errors: import_zod14.z.array( | ||
import_zod14.z.object({ | ||
type: import_zod14.z.string(), | ||
message: import_zod14.z.string() | ||
}) | ||
@@ -333,3 +820,3 @@ ) | ||
const resultSchema = this._getResultSchema(); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -343,3 +830,3 @@ if (result.errors) { | ||
meta: result.meta, | ||
data: result[this._endpoint] | ||
data: result[this._resource] | ||
}; | ||
@@ -358,3 +845,3 @@ } | ||
const resultSchema = this._getResultSchema(); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -368,3 +855,3 @@ if (result.errors) { | ||
meta: result.meta, | ||
data: result[this._endpoint] | ||
data: result[this._resource] | ||
}; | ||
@@ -392,31 +879,6 @@ } | ||
} | ||
async _fetch() { | ||
if (this._URL === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
try { | ||
result = await (await (0, import_cross_fetch.default)(this._URL.toString(), { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept-Version": this._api.version | ||
} | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
}; | ||
// src/fetchers/read-fetcher.ts | ||
var import_cross_fetch2 = __toESM(require("cross-fetch")); | ||
var import_zod4 = require("zod"); | ||
var import_zod15 = require("zod"); | ||
var ReadFetcher = class { | ||
@@ -431,7 +893,72 @@ constructor(config, _params, _api) { | ||
this._buildUrlParams(); | ||
this._endpoint = _api.endpoint; | ||
this._resource = _api.resource; | ||
} | ||
getEndpoint() { | ||
return this._endpoint; | ||
/** | ||
* Lets you choose output format for the content of Post and Pages resources | ||
* The choices are html, mobiledoc or plaintext. It will transform the output of the fetcher to a new shape | ||
* with the selected formats required. | ||
* | ||
* @param formats html, mobiledoc or plaintext | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
formats(formats) { | ||
const params = { | ||
...this._params, | ||
formats: Object.keys(formats) | ||
}; | ||
return new ReadFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(formats), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you include special keys into the Ghost API Query to retrieve complimentary info | ||
* The available keys are defined by the Resource include schema, will not care about unknown keys. | ||
* Returns a new Fetcher with an Output shape modified with the include keys required. | ||
* | ||
* @param include Include specific keys from the include shape | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
include(include) { | ||
const params = { | ||
...this._params, | ||
include: Object.keys(include) | ||
}; | ||
return new ReadFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(include), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you strip the output to only the specified keys of your choice that are in the config Schema | ||
* Will not care about unknown keys and return a new Fetcher with an Output shape with only the selected keys. | ||
* | ||
* @param fields Any keys from the resource Schema | ||
* @returns A new Fetcher with the fixed output shape having only the selected Fields | ||
*/ | ||
fields(fields) { | ||
const newOutput = this.config.output.pick(fields); | ||
return new ReadFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: newOutput, | ||
include: this.config.include | ||
}, | ||
this._params, | ||
this._api | ||
); | ||
} | ||
getResource() { | ||
return this._resource; | ||
} | ||
getParams() { | ||
@@ -452,5 +979,7 @@ return this._params; | ||
const outputKeys = this.config.output.keyof().options; | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
if (this._api.endpoint === "content") { | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
} | ||
if (inputKeys.length !== outputKeys.length && outputKeys.length > 0) { | ||
@@ -462,7 +991,10 @@ this._urlParams.fields = outputKeys.join(","); | ||
} | ||
if (this._params.formats && this._params.formats.length > 0) { | ||
this._urlParams.formats = this._params.formats.join(","); | ||
} | ||
const url = new URL(this._api.url); | ||
if (this._params.identity.id) { | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/${this._params.identity.id}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/${this._params.identity.id}/`; | ||
} else if (this._params.identity.slug) { | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/slug/${this._params.identity.slug}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/slug/${this._params.identity.slug}/`; | ||
} else { | ||
@@ -477,13 +1009,13 @@ throw new Error("Identity is not defined"); | ||
async fetch() { | ||
const res = import_zod4.z.discriminatedUnion("status", [ | ||
import_zod4.z.object({ | ||
status: import_zod4.z.literal("success"), | ||
const res = import_zod15.z.discriminatedUnion("status", [ | ||
import_zod15.z.object({ | ||
status: import_zod15.z.literal("success"), | ||
data: this.config.output | ||
}), | ||
import_zod4.z.object({ | ||
status: import_zod4.z.literal("error"), | ||
errors: import_zod4.z.array( | ||
import_zod4.z.object({ | ||
type: import_zod4.z.string(), | ||
message: import_zod4.z.string() | ||
import_zod15.z.object({ | ||
status: import_zod15.z.literal("error"), | ||
errors: import_zod15.z.array( | ||
import_zod15.z.object({ | ||
type: import_zod15.z.string(), | ||
message: import_zod15.z.string() | ||
}) | ||
@@ -493,3 +1025,3 @@ ) | ||
]); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -502,3 +1034,3 @@ if (result.errors) { | ||
status: "success", | ||
data: result[this._endpoint][0] | ||
data: result[this._resource][0] | ||
}; | ||
@@ -508,26 +1040,2 @@ } | ||
} | ||
async _fetch() { | ||
if (this._URL === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
try { | ||
result = await (await (0, import_cross_fetch2.default)(this._URL.toString(), { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept-Version": this._api.version | ||
} | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
}; | ||
@@ -563,3 +1071,4 @@ | ||
include: includeFields, | ||
fields: options?.output?.fields || void 0 | ||
fields: options?.output?.fields || void 0, | ||
formats: this.config.formats && options?.output?.formats ? this.config.formats.parse(options.output.formats) : void 0 | ||
}, | ||
@@ -591,3 +1100,4 @@ this._api | ||
include: includeFields, | ||
fields: options?.output?.fields || void 0 | ||
fields: options?.output?.fields || void 0, | ||
formats: this.config.formats && options?.output?.formats ? this.config.formats.parse(options.output.formats) : void 0 | ||
}, | ||
@@ -600,4 +1110,3 @@ this._api | ||
// src/fetchers/basic-fetcher.ts | ||
var import_cross_fetch3 = __toESM(require("cross-fetch")); | ||
var import_zod5 = require("zod"); | ||
var import_zod16 = require("zod"); | ||
var BasicFetcher = class { | ||
@@ -610,6 +1119,6 @@ constructor(config, _api) { | ||
this._buildUrl(); | ||
this._endpoint = _api.endpoint; | ||
this._resource = _api.resource; | ||
} | ||
getEndpoint() { | ||
return this._endpoint; | ||
getResource() { | ||
return this._resource; | ||
} | ||
@@ -623,7 +1132,9 @@ getOutputFields() { | ||
_buildUrl() { | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
if (this._api.endpoint === "content") { | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
} | ||
const url = new URL(this._api.url); | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/`; | ||
for (const [key, value] of Object.entries(this._urlParams)) { | ||
@@ -635,13 +1146,13 @@ url.searchParams.append(key, value); | ||
async fetch() { | ||
const res = import_zod5.z.discriminatedUnion("status", [ | ||
import_zod5.z.object({ | ||
status: import_zod5.z.literal("success"), | ||
const res = import_zod16.z.discriminatedUnion("status", [ | ||
import_zod16.z.object({ | ||
status: import_zod16.z.literal("success"), | ||
data: this.config.output | ||
}), | ||
import_zod5.z.object({ | ||
status: import_zod5.z.literal("error"), | ||
errors: import_zod5.z.array( | ||
import_zod5.z.object({ | ||
type: import_zod5.z.string(), | ||
message: import_zod5.z.string() | ||
import_zod16.z.object({ | ||
status: import_zod16.z.literal("error"), | ||
errors: import_zod16.z.array( | ||
import_zod16.z.object({ | ||
type: import_zod16.z.string(), | ||
message: import_zod16.z.string() | ||
}) | ||
@@ -651,3 +1162,3 @@ ) | ||
]); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -660,3 +1171,3 @@ if (result.errors) { | ||
status: "success", | ||
data: result[this._endpoint] | ||
data: result[this._resource] | ||
}; | ||
@@ -666,26 +1177,2 @@ } | ||
} | ||
async _fetch() { | ||
if (this._URL === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
try { | ||
result = await (await (0, import_cross_fetch3.default)(this._URL.toString(), { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept-Version": this._api.version | ||
} | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
}; | ||
@@ -698,6 +1185,18 @@ // Annotate the CommonJS export names for ESM import in node: | ||
ReadFetcher, | ||
adminAPICredentialsSchema, | ||
adminAPIEndpointsSchema, | ||
apiVersionsSchema, | ||
baseAuthorsSchema, | ||
baseEmailSchema, | ||
baseMembersSchema, | ||
baseNewsletterSchema, | ||
baseOffersSchema, | ||
basePagesSchema, | ||
basePostsSchema, | ||
baseSettingsSchema, | ||
baseSiteSchema, | ||
baseTagsSchema, | ||
baseTiersSchema, | ||
browseParamsSchema, | ||
contentAPICredentialsSchema, | ||
contentAPIEndpointsSchema, | ||
ghostCodeInjectionSchema, | ||
@@ -704,0 +1203,0 @@ ghostExcerptSchema, |
@@ -37,6 +37,18 @@ "use strict"; | ||
ReadFetcher: () => ReadFetcher, | ||
adminAPICredentialsSchema: () => adminAPICredentialsSchema, | ||
adminAPIEndpointsSchema: () => adminAPIEndpointsSchema, | ||
apiVersionsSchema: () => apiVersionsSchema, | ||
baseAuthorsSchema: () => baseAuthorsSchema, | ||
baseEmailSchema: () => baseEmailSchema, | ||
baseMembersSchema: () => baseMembersSchema, | ||
baseNewsletterSchema: () => baseNewsletterSchema, | ||
baseOffersSchema: () => baseOffersSchema, | ||
basePagesSchema: () => basePagesSchema, | ||
basePostsSchema: () => basePostsSchema, | ||
baseSettingsSchema: () => baseSettingsSchema, | ||
baseSiteSchema: () => baseSiteSchema, | ||
baseTagsSchema: () => baseTagsSchema, | ||
baseTiersSchema: () => baseTiersSchema, | ||
browseParamsSchema: () => browseParamsSchema, | ||
contentAPICredentialsSchema: () => contentAPICredentialsSchema, | ||
contentAPIEndpointsSchema: () => contentAPIEndpointsSchema, | ||
ghostCodeInjectionSchema: () => ghostCodeInjectionSchema, | ||
@@ -58,3 +70,6 @@ ghostExcerptSchema: () => ghostExcerptSchema, | ||
// src/schemas.ts | ||
// src/schemas/authors.ts | ||
var import_zod2 = require("zod"); | ||
// src/schemas/shared.ts | ||
var import_zod = require("zod"); | ||
@@ -130,61 +145,414 @@ var ghostIdentitySchema = import_zod.z.object({ | ||
]); | ||
var contentAPIEndpointsSchema = import_zod.z.union([ | ||
import_zod.z.literal("authors"), | ||
import_zod.z.literal("tiers"), | ||
import_zod.z.literal("posts"), | ||
import_zod.z.literal("pages"), | ||
import_zod.z.literal("tags"), | ||
import_zod.z.literal("settings") | ||
]); | ||
var apiVersionsSchema = import_zod.z.enum(["v5.0", "v2", "v3", "v4", "canary"]).default("v5.0"); | ||
var contentAPICredentialsSchema = import_zod.z.discriminatedUnion("endpoint", [ | ||
var contentAPICredentialsSchema = import_zod.z.discriminatedUnion("resource", [ | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("authors"), | ||
resource: import_zod.z.literal("authors"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("tiers"), | ||
resource: import_zod.z.literal("tiers"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("pages"), | ||
resource: import_zod.z.literal("pages"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("posts"), | ||
resource: import_zod.z.literal("posts"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("tags"), | ||
resource: import_zod.z.literal("tags"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}), | ||
import_zod.z.object({ | ||
endpoint: import_zod.z.literal("settings"), | ||
resource: import_zod.z.literal("settings"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{26}/, { message: "'key' must have 26 hex characters" }), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url() | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("content") | ||
}) | ||
]); | ||
var adminAPIEndpointsSchema = import_zod.z.union([import_zod.z.literal("posts"), import_zod.z.literal("pages")]); | ||
var adminAPICredentialsSchema = import_zod.z.discriminatedUnion("resource", [ | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("pages"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}), | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("posts"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}), | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("members"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}), | ||
import_zod.z.object({ | ||
resource: import_zod.z.literal("site"), | ||
key: import_zod.z.string().regex(/[0-9a-f]{24}:[0-9a-f]{64}/, { | ||
message: "'key' must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters" | ||
}), | ||
version: apiVersionsSchema, | ||
url: import_zod.z.string().url(), | ||
endpoint: import_zod.z.literal("admin") | ||
}) | ||
]); | ||
// src/schemas/authors.ts | ||
var baseAuthorsSchema = import_zod2.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
name: import_zod2.z.string(), | ||
profile_image: import_zod2.z.string().nullable(), | ||
cover_image: import_zod2.z.string().nullable(), | ||
bio: import_zod2.z.string().nullable(), | ||
website: import_zod2.z.string().nullable(), | ||
location: import_zod2.z.string().nullable(), | ||
facebook: import_zod2.z.string().nullable(), | ||
twitter: import_zod2.z.string().nullable(), | ||
count: import_zod2.z.object({ | ||
posts: import_zod2.z.number() | ||
}).optional(), | ||
url: import_zod2.z.string() | ||
}); | ||
// src/schemas/pages.ts | ||
var import_zod4 = require("zod"); | ||
// src/schemas/tags.ts | ||
var import_zod3 = require("zod"); | ||
var baseTagsSchema = import_zod3.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
...ghostCodeInjectionSchema.shape, | ||
...ghostSocialMediaSchema.shape, | ||
name: import_zod3.z.string(), | ||
description: import_zod3.z.string().nullable(), | ||
feature_image: import_zod3.z.string().nullable(), | ||
visibility: ghostVisibilitySchema, | ||
canonical_url: import_zod3.z.string().nullable(), | ||
accent_color: import_zod3.z.string().nullable(), | ||
url: import_zod3.z.string(), | ||
created_at: import_zod3.z.string().nullish(), | ||
updated_at: import_zod3.z.string().nullish(), | ||
count: import_zod3.z.object({ | ||
posts: import_zod3.z.number() | ||
}).optional() | ||
}); | ||
// src/schemas/pages.ts | ||
var postsAuthorSchema = baseAuthorsSchema.extend({ | ||
url: import_zod4.z.string().nullish() | ||
}); | ||
var basePagesSchema = import_zod4.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
title: import_zod4.z.string(), | ||
html: import_zod4.z.string().nullish(), | ||
plaintext: import_zod4.z.string().nullish(), | ||
comment_id: import_zod4.z.string().nullable(), | ||
feature_image: import_zod4.z.string().nullable(), | ||
feature_image_alt: import_zod4.z.string().nullable(), | ||
feature_image_caption: import_zod4.z.string().nullable(), | ||
featured: import_zod4.z.boolean(), | ||
custom_excerpt: import_zod4.z.string().nullable(), | ||
...ghostCodeInjectionSchema.shape, | ||
...ghostSocialMediaSchema.shape, | ||
visibility: ghostVisibilitySchema, | ||
custom_template: import_zod4.z.string().nullable(), | ||
canonical_url: import_zod4.z.string().nullable(), | ||
authors: import_zod4.z.array(postsAuthorSchema).optional(), | ||
tags: import_zod4.z.array(baseTagsSchema).optional(), | ||
primary_author: postsAuthorSchema.nullish(), | ||
primary_tag: baseTagsSchema.nullish(), | ||
url: import_zod4.z.string(), | ||
excerpt: import_zod4.z.string(), | ||
reading_time: import_zod4.z.number().optional().default(0), | ||
created_at: import_zod4.z.string(), | ||
updated_at: import_zod4.z.string(), | ||
published_at: import_zod4.z.string(), | ||
email_subject: import_zod4.z.string().nullish(), | ||
is_page: import_zod4.z.boolean().default(true) | ||
}); | ||
// src/schemas/posts.ts | ||
var import_zod5 = require("zod"); | ||
var postsAuthorSchema2 = baseAuthorsSchema.extend({ | ||
url: import_zod5.z.string().nullish() | ||
}); | ||
var basePostsSchema = import_zod5.z.object({ | ||
...ghostIdentitySchema.shape, | ||
...ghostMetadataSchema.shape, | ||
title: import_zod5.z.string(), | ||
html: import_zod5.z.string().nullish(), | ||
plaintext: import_zod5.z.string().nullish(), | ||
comment_id: import_zod5.z.string().nullable(), | ||
feature_image: import_zod5.z.string().nullable(), | ||
feature_image_alt: import_zod5.z.string().nullable(), | ||
feature_image_caption: import_zod5.z.string().nullable(), | ||
featured: import_zod5.z.boolean(), | ||
custom_excerpt: import_zod5.z.string().nullable(), | ||
...ghostCodeInjectionSchema.shape, | ||
...ghostSocialMediaSchema.shape, | ||
visibility: ghostVisibilitySchema, | ||
custom_template: import_zod5.z.string().nullable(), | ||
canonical_url: import_zod5.z.string().nullable(), | ||
authors: import_zod5.z.array(postsAuthorSchema2).optional(), | ||
tags: import_zod5.z.array(baseTagsSchema).optional(), | ||
primary_author: postsAuthorSchema2.nullish(), | ||
primary_tag: baseTagsSchema.nullish(), | ||
url: import_zod5.z.string(), | ||
excerpt: import_zod5.z.string(), | ||
reading_time: import_zod5.z.number().optional().default(0), | ||
created_at: import_zod5.z.string(), | ||
updated_at: import_zod5.z.string(), | ||
published_at: import_zod5.z.string(), | ||
email_subject: import_zod5.z.string().nullish(), | ||
is_page: import_zod5.z.boolean().default(false) | ||
}); | ||
// src/schemas/settings.ts | ||
var import_zod6 = require("zod"); | ||
var baseSettingsSchema = import_zod6.z.object({ | ||
title: import_zod6.z.string(), | ||
description: import_zod6.z.string(), | ||
logo: import_zod6.z.string().nullable(), | ||
icon: import_zod6.z.string().nullable(), | ||
accent_color: import_zod6.z.string().nullable(), | ||
cover_image: import_zod6.z.string().nullable(), | ||
facebook: import_zod6.z.string().nullable(), | ||
twitter: import_zod6.z.string().nullable(), | ||
lang: import_zod6.z.string(), | ||
timezone: import_zod6.z.string(), | ||
codeinjection_head: import_zod6.z.string().nullable(), | ||
codeinjection_foot: import_zod6.z.string().nullable(), | ||
navigation: import_zod6.z.array( | ||
import_zod6.z.object({ | ||
label: import_zod6.z.string(), | ||
url: import_zod6.z.string() | ||
}) | ||
), | ||
secondary_navigation: import_zod6.z.array( | ||
import_zod6.z.object({ | ||
label: import_zod6.z.string(), | ||
url: import_zod6.z.string() | ||
}) | ||
), | ||
meta_title: import_zod6.z.string().nullable(), | ||
meta_description: import_zod6.z.string().nullable(), | ||
og_image: import_zod6.z.string().nullable(), | ||
og_title: import_zod6.z.string().nullable(), | ||
og_description: import_zod6.z.string().nullable(), | ||
twitter_image: import_zod6.z.string().nullable(), | ||
twitter_title: import_zod6.z.string().nullable(), | ||
twitter_description: import_zod6.z.string().nullable(), | ||
members_support_address: import_zod6.z.string(), | ||
url: import_zod6.z.string() | ||
}); | ||
// src/schemas/tiers.ts | ||
var import_zod7 = require("zod"); | ||
var baseTiersSchema = import_zod7.z.object({ | ||
...ghostIdentitySchema.shape, | ||
name: import_zod7.z.string(), | ||
description: import_zod7.z.string().nullable(), | ||
active: import_zod7.z.boolean(), | ||
type: import_zod7.z.union([import_zod7.z.literal("free"), import_zod7.z.literal("paid")]), | ||
welcome_page_url: import_zod7.z.string().nullable(), | ||
created_at: import_zod7.z.string(), | ||
updated_at: import_zod7.z.string().nullable(), | ||
stripe_prices: import_zod7.z.array(import_zod7.z.number()).optional().transform((v) => v?.length ? v : []), | ||
monthly_price: import_zod7.z.number().nullable().optional().transform((v) => v ? v : null), | ||
yearly_price: import_zod7.z.number().nullable().optional().transform((v) => v ? v : null), | ||
benefits: import_zod7.z.array(import_zod7.z.string()).nullish(), | ||
visibility: ghostVisibilitySchema, | ||
currency: import_zod7.z.string().nullish(), | ||
trial_days: import_zod7.z.number().default(0) | ||
}); | ||
// src/schemas/email.ts | ||
var import_zod8 = require("zod"); | ||
var baseEmailSchema = import_zod8.z.object({ | ||
id: import_zod8.z.string(), | ||
uuid: import_zod8.z.string(), | ||
status: import_zod8.z.string(), | ||
recipient_filter: import_zod8.z.string(), | ||
error: import_zod8.z.string().nullish(), | ||
error_data: import_zod8.z.any().nullable(), | ||
email_count: import_zod8.z.number(), | ||
delivered_count: import_zod8.z.number(), | ||
opened_count: import_zod8.z.number(), | ||
failed_count: import_zod8.z.number(), | ||
subject: import_zod8.z.string(), | ||
from: import_zod8.z.string(), | ||
reply_to: import_zod8.z.string(), | ||
html: import_zod8.z.string(), | ||
plaintext: import_zod8.z.string(), | ||
track_opens: import_zod8.z.boolean(), | ||
submitted_at: import_zod8.z.string(), | ||
created_at: import_zod8.z.string(), | ||
updated_at: import_zod8.z.string() | ||
}); | ||
// src/schemas/offers.ts | ||
var import_zod9 = require("zod"); | ||
var baseOffersSchema = import_zod9.z.object({ | ||
id: import_zod9.z.string(), | ||
name: import_zod9.z.string({ description: "Internal name for an offer, must be unique" }), | ||
code: import_zod9.z.string({ description: "Shortcode for the offer, for example: https://yoursite.com/black-friday" }), | ||
display_title: import_zod9.z.string({ description: "Name displayed in the offer window" }), | ||
display_description: import_zod9.z.string({ description: "Text displayed in the offer window" }), | ||
type: import_zod9.z.union([import_zod9.z.literal("percent"), import_zod9.z.literal("fixed")]), | ||
cadence: import_zod9.z.union([import_zod9.z.literal("month"), import_zod9.z.literal("year")]), | ||
amount: import_zod9.z.number({ | ||
description: `Offer discount amount, as a percentage or fixed value as set in type. | ||
Amount is always denoted by the smallest currency unit | ||
(e.g., 100 cents instead of $1.00 in USD)` | ||
}), | ||
duration: import_zod9.z.union([import_zod9.z.literal("once"), import_zod9.z.literal("forever"), import_zod9.z.literal("repeating")], { | ||
description: "once/forever/repeating. repeating duration is only available when cadence is month" | ||
}), | ||
duration_in_months: import_zod9.z.number({ description: "Number of months offer should be repeated when duration is repeating" }).nullable(), | ||
currency_restriction: import_zod9.z.boolean({ | ||
description: "Denotes whether the offer `currency` is restricted. If so, changing the currency invalidates the offer" | ||
}), | ||
currency: import_zod9.z.string({ description: "fixed type offers only - specifies tier's currency as three letter ISO currency code" }).nullable(), | ||
status: import_zod9.z.union([import_zod9.z.literal("active"), import_zod9.z.literal("archived")], { | ||
description: "active or archived - denotes if the offer is active or archived" | ||
}), | ||
redemption_count: import_zod9.z.number({ description: "Number of times the offer has been redeemed" }), | ||
tier: import_zod9.z.object( | ||
{ | ||
id: import_zod9.z.string(), | ||
name: import_zod9.z.string() | ||
}, | ||
{ description: "Tier on which offer is applied" } | ||
) | ||
}); | ||
// src/schemas/members.ts | ||
var import_zod11 = require("zod"); | ||
// src/schemas/newsletter.ts | ||
var import_zod10 = require("zod"); | ||
var baseNewsletterSchema = import_zod10.z.object({ | ||
...ghostIdentitySchema.shape, | ||
name: import_zod10.z.string({ description: "Public name for the newsletter" }), | ||
description: import_zod10.z.string({ description: "(nullable) Public description of the newsletter" }).nullish(), | ||
sender_name: import_zod10.z.string({ description: "(nullable) The sender name of the emails" }).nullish(), | ||
sender_email: import_zod10.z.string({ description: "(nullable) The email from which to send emails. Requires validation." }).nullish(), | ||
sender_reply_to: import_zod10.z.string({ | ||
description: "The reply-to email address for sent emails. Can be either newsletter (= use sender_email) or support (use support email from Portal settings)." | ||
}), | ||
status: import_zod10.z.union([import_zod10.z.literal("active"), import_zod10.z.literal("archived")], { | ||
description: "active or archived - denotes if the newsletter is active or archived" | ||
}), | ||
visibility: import_zod10.z.union([import_zod10.z.literal("public"), import_zod10.z.literal("members")]), | ||
subscribe_on_signup: import_zod10.z.boolean({ | ||
description: "true/false. Whether members should automatically subscribe to this newsletter on signup" | ||
}), | ||
sort_order: import_zod10.z.number({ description: "The order in which newsletters are displayed in the Portal" }), | ||
header_image: import_zod10.z.string({ description: "(nullable) Path to an image to show at the top of emails. Recommended size 1200x600" }).nullish(), | ||
show_header_icon: import_zod10.z.boolean({ description: "true/false. Show the site icon in emails" }), | ||
show_header_title: import_zod10.z.boolean({ description: "true/false. Show the site name in emails" }), | ||
title_font_category: import_zod10.z.union([import_zod10.z.literal("serif"), import_zod10.z.literal("sans_serif")], { | ||
description: "Title font style. Either serif or sans_serif" | ||
}), | ||
title_alignment: import_zod10.z.string().nullish(), | ||
show_feature_image: import_zod10.z.boolean({ description: "true/false. Show the post's feature image in emails" }), | ||
body_font_category: import_zod10.z.union([import_zod10.z.literal("serif"), import_zod10.z.literal("sans_serif")], { | ||
description: "Body font style. Either serif or sans_serif" | ||
}), | ||
footer_content: import_zod10.z.string({ | ||
description: "(nullable) Extra information or legal text to show in the footer of emails. Should contain valid HTML." | ||
}).nullish(), | ||
show_badge: import_zod10.z.boolean({ | ||
description: "true/false. Show you\u2019re a part of the indie publishing movement by adding a small Ghost badge in the footer" | ||
}), | ||
created_at: import_zod10.z.string(), | ||
updated_at: import_zod10.z.string().nullish(), | ||
show_header_name: import_zod10.z.boolean({ description: "true/false. Show the newsletter name in emails" }), | ||
uuid: import_zod10.z.string() | ||
}); | ||
// src/schemas/members.ts | ||
var baseMembersSchema = import_zod11.z.object({ | ||
id: import_zod11.z.string(), | ||
email: import_zod11.z.string({ description: "The email address of the member" }), | ||
name: import_zod11.z.string({ description: "The name of the member" }), | ||
note: import_zod11.z.string({ description: "(nullable) A note about the member" }).nullish(), | ||
geolocation: import_zod11.z.string({ description: "(nullable) The geolocation of the member" }).nullish(), | ||
created_at: import_zod11.z.string({ description: "The date and time the member was created" }), | ||
updated_at: import_zod11.z.string({ description: "(nullable) The date and time the member was last updated" }).nullish(), | ||
labels: import_zod11.z.array( | ||
import_zod11.z.object({ | ||
id: import_zod11.z.string({ description: "The ID of the label" }), | ||
name: import_zod11.z.string({ description: "The name of the label" }), | ||
slug: import_zod11.z.string({ description: "The slug of the label" }), | ||
created_at: import_zod11.z.string({ description: "The date and time the label was created" }), | ||
updated_at: import_zod11.z.string({ description: "(nullable) The date and time the label was last updated" }).nullish() | ||
}), | ||
{ description: "The labels associated with the member" } | ||
), | ||
subscriptions: import_zod11.z.array(import_zod11.z.string({ description: "The subscriptions associated with the member" })), | ||
avatar_image: import_zod11.z.string({ description: "The URL of the member's avatar image" }), | ||
email_count: import_zod11.z.number({ description: "The number of emails sent to the member" }), | ||
email_opened_count: import_zod11.z.number({ description: "The number of emails opened by the member" }), | ||
email_open_rate: import_zod11.z.number({ description: "(nullable) The open rate of the member" }).nullish(), | ||
status: import_zod11.z.string({ description: "The status of the member" }), | ||
last_seen_at: import_zod11.z.string({ description: "(nullable) The date and time the member was last seen" }).nullish(), | ||
newsletters: import_zod11.z.array(baseNewsletterSchema) | ||
}); | ||
// src/schemas/site.ts | ||
var import_zod12 = require("zod"); | ||
var baseSiteSchema = import_zod12.z.object({ | ||
title: import_zod12.z.string(), | ||
description: import_zod12.z.string(), | ||
logo: import_zod12.z.string().nullable(), | ||
version: import_zod12.z.string(), | ||
url: import_zod12.z.string() | ||
}); | ||
// src/query-builder/browse-params.ts | ||
var import_zod2 = require("zod"); | ||
var browseParamsSchema = import_zod2.z.object({ | ||
order: import_zod2.z.string().optional(), | ||
limit: import_zod2.z.number().refine((n) => n && n > 0 && n <= 15, { | ||
var import_zod13 = require("zod"); | ||
var browseParamsSchema = import_zod13.z.object({ | ||
order: import_zod13.z.string().optional(), | ||
limit: import_zod13.z.number().refine((n) => n && n > 0 && n <= 15, { | ||
message: "Limit must be between 1 and 15" | ||
}).optional(), | ||
page: import_zod2.z.number().refine((n) => n && n >= 1, { | ||
page: import_zod13.z.number().refine((n) => n && n >= 1, { | ||
message: "Page must be greater than 1" | ||
}).optional(), | ||
filter: import_zod2.z.string().optional() | ||
filter: import_zod13.z.string().optional() | ||
}); | ||
@@ -194,4 +562,4 @@ var parseBrowseParams = (args, schema) => { | ||
const augmentedSchema = browseParamsSchema.merge( | ||
import_zod2.z.object({ | ||
order: import_zod2.z.string().superRefine((val, ctx) => { | ||
import_zod13.z.object({ | ||
order: import_zod13.z.string().superRefine((val, ctx) => { | ||
const orderPredicates = val.split(","); | ||
@@ -202,3 +570,3 @@ for (const orderPredicate of orderPredicates) { | ||
ctx.addIssue({ | ||
code: import_zod2.z.ZodIssueCode.custom, | ||
code: import_zod13.z.ZodIssueCode.custom, | ||
message: `Field "${field}" is not a valid field`, | ||
@@ -210,3 +578,3 @@ fatal: true | ||
ctx.addIssue({ | ||
code: import_zod2.z.ZodIssueCode.custom, | ||
code: import_zod13.z.ZodIssueCode.custom, | ||
message: "Order direction must be ASC or DESC", | ||
@@ -218,3 +586,3 @@ fatal: true | ||
}).optional(), | ||
filter: import_zod2.z.string().superRefine((val, ctx) => { | ||
filter: import_zod13.z.string().superRefine((val, ctx) => { | ||
const filterPredicates = val.split(/[+(,]+/); | ||
@@ -225,3 +593,3 @@ for (const filterPredicate of filterPredicates) { | ||
ctx.addIssue({ | ||
code: import_zod2.z.ZodIssueCode.custom, | ||
code: import_zod13.z.ZodIssueCode.custom, | ||
message: `Field "${field}" is not a valid field`, | ||
@@ -244,4 +612,46 @@ fatal: true | ||
// src/fetchers/browse-fetcher.ts | ||
var import_zod14 = require("zod"); | ||
// src/fetchers/helpers.ts | ||
var import_cross_fetch = __toESM(require("cross-fetch")); | ||
var import_zod3 = require("zod"); | ||
var import_jsonwebtoken = __toESM(require("jsonwebtoken")); | ||
function getJWT(key) { | ||
const [id, secret] = key.split(":"); | ||
return import_jsonwebtoken.default.sign({}, Buffer.from(secret, "hex"), { | ||
keyid: id, | ||
algorithm: "HS256", | ||
expiresIn: "5m", | ||
audience: "/admin/" | ||
}); | ||
} | ||
async function _fetch(URL2, api) { | ||
if (URL2 === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
const headers = { | ||
"Content-Type": "application/json", | ||
"Accept-Version": api.version | ||
}; | ||
if (api.endpoint === "admin") { | ||
headers["Authorization"] = `Ghost ${getJWT(api.key)}`; | ||
} | ||
try { | ||
result = await (await (0, import_cross_fetch.default)(URL2.toString(), { | ||
headers | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
// src/fetchers/browse-fetcher.ts | ||
var BrowseFetcher = class { | ||
@@ -256,7 +666,72 @@ constructor(config, _params = { browseParams: {}, include: [], fields: {} }, _api) { | ||
this._buildUrlParams(); | ||
this._endpoint = _api.endpoint; | ||
this._resource = _api.resource; | ||
} | ||
getEndpoint() { | ||
return this._endpoint; | ||
/** | ||
* Lets you choose output format for the content of Post and Pages resources | ||
* The choices are html, mobiledoc or plaintext. It will transform the output of the fetcher to a new shape | ||
* with the selected formats required. | ||
* | ||
* @param formats html, mobiledoc or plaintext | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
formats(formats) { | ||
const params = { | ||
...this._params, | ||
formats: Object.keys(formats) | ||
}; | ||
return new BrowseFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(formats), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you include special keys into the Ghost API Query to retrieve complimentary info | ||
* The available keys are defined by the Resource include schema, will not care about unknown keys. | ||
* Returns a new Fetcher with an Output shape modified with the include keys required. | ||
* | ||
* @param include Include specific keys from the include shape | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
include(include) { | ||
const params = { | ||
...this._params, | ||
include: Object.keys(include) | ||
}; | ||
return new BrowseFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(include), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you strip the output to only the specified keys of your choice that are in the config Schema | ||
* Will not care about unknown keys and return a new Fetcher with an Output shape with only the selected keys. | ||
* | ||
* @param fields Any keys from the resource Schema | ||
* @returns A new Fetcher with the fixed output shape having only the selected Fields | ||
*/ | ||
fields(fields) { | ||
const newOutput = this.config.output.pick(fields); | ||
return new BrowseFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: newOutput, | ||
include: this.config.include | ||
}, | ||
this._params, | ||
this._api | ||
); | ||
} | ||
getResource() { | ||
return this._resource; | ||
} | ||
getParams() { | ||
@@ -274,9 +749,18 @@ return this._params; | ||
} | ||
getFormats() { | ||
return this._params?.formats || []; | ||
} | ||
_buildUrlParams() { | ||
const inputKeys = this.config.schema.keyof().options; | ||
const outputKeys = this.config.output.keyof().options; | ||
this._urlParams = { | ||
key: this._api.key, | ||
...this._urlBrowseParams() | ||
}; | ||
if (this._api.endpoint === "content") { | ||
this._urlParams = { | ||
key: this._api.key, | ||
...this._urlBrowseParams() | ||
}; | ||
} else { | ||
this._urlParams = { | ||
...this._urlBrowseParams() | ||
}; | ||
} | ||
if (inputKeys.length !== outputKeys.length && outputKeys.length > 0) { | ||
@@ -288,4 +772,7 @@ this._urlParams.fields = outputKeys.join(","); | ||
} | ||
if (this._params.formats && this._params.formats.length > 0) { | ||
this._urlParams.formats = this._params.formats.join(","); | ||
} | ||
const url = new URL(this._api.url); | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/`; | ||
for (const [key, value] of Object.entries(this._urlParams)) { | ||
@@ -313,14 +800,14 @@ url.searchParams.append(key, value); | ||
_getResultSchema() { | ||
return import_zod3.z.discriminatedUnion("status", [ | ||
import_zod3.z.object({ | ||
status: import_zod3.z.literal("success"), | ||
return import_zod14.z.discriminatedUnion("status", [ | ||
import_zod14.z.object({ | ||
status: import_zod14.z.literal("success"), | ||
meta: ghostMetaSchema, | ||
data: import_zod3.z.array(this.config.output) | ||
data: import_zod14.z.array(this.config.output) | ||
}), | ||
import_zod3.z.object({ | ||
status: import_zod3.z.literal("error"), | ||
errors: import_zod3.z.array( | ||
import_zod3.z.object({ | ||
type: import_zod3.z.string(), | ||
message: import_zod3.z.string() | ||
import_zod14.z.object({ | ||
status: import_zod14.z.literal("error"), | ||
errors: import_zod14.z.array( | ||
import_zod14.z.object({ | ||
type: import_zod14.z.string(), | ||
message: import_zod14.z.string() | ||
}) | ||
@@ -333,3 +820,3 @@ ) | ||
const resultSchema = this._getResultSchema(); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -343,3 +830,3 @@ if (result.errors) { | ||
meta: result.meta, | ||
data: result[this._endpoint] | ||
data: result[this._resource] | ||
}; | ||
@@ -358,3 +845,3 @@ } | ||
const resultSchema = this._getResultSchema(); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -368,3 +855,3 @@ if (result.errors) { | ||
meta: result.meta, | ||
data: result[this._endpoint] | ||
data: result[this._resource] | ||
}; | ||
@@ -392,31 +879,6 @@ } | ||
} | ||
async _fetch() { | ||
if (this._URL === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
try { | ||
result = await (await (0, import_cross_fetch.default)(this._URL.toString(), { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept-Version": this._api.version | ||
} | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
}; | ||
// src/fetchers/read-fetcher.ts | ||
var import_cross_fetch2 = __toESM(require("cross-fetch")); | ||
var import_zod4 = require("zod"); | ||
var import_zod15 = require("zod"); | ||
var ReadFetcher = class { | ||
@@ -431,7 +893,72 @@ constructor(config, _params, _api) { | ||
this._buildUrlParams(); | ||
this._endpoint = _api.endpoint; | ||
this._resource = _api.resource; | ||
} | ||
getEndpoint() { | ||
return this._endpoint; | ||
/** | ||
* Lets you choose output format for the content of Post and Pages resources | ||
* The choices are html, mobiledoc or plaintext. It will transform the output of the fetcher to a new shape | ||
* with the selected formats required. | ||
* | ||
* @param formats html, mobiledoc or plaintext | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
formats(formats) { | ||
const params = { | ||
...this._params, | ||
formats: Object.keys(formats) | ||
}; | ||
return new ReadFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(formats), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you include special keys into the Ghost API Query to retrieve complimentary info | ||
* The available keys are defined by the Resource include schema, will not care about unknown keys. | ||
* Returns a new Fetcher with an Output shape modified with the include keys required. | ||
* | ||
* @param include Include specific keys from the include shape | ||
* @returns A new Fetcher with the fixed output shape and the formats specified | ||
*/ | ||
include(include) { | ||
const params = { | ||
...this._params, | ||
include: Object.keys(include) | ||
}; | ||
return new ReadFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: this.config.output.required(include), | ||
include: this.config.include | ||
}, | ||
params, | ||
this._api | ||
); | ||
} | ||
/** | ||
* Let's you strip the output to only the specified keys of your choice that are in the config Schema | ||
* Will not care about unknown keys and return a new Fetcher with an Output shape with only the selected keys. | ||
* | ||
* @param fields Any keys from the resource Schema | ||
* @returns A new Fetcher with the fixed output shape having only the selected Fields | ||
*/ | ||
fields(fields) { | ||
const newOutput = this.config.output.pick(fields); | ||
return new ReadFetcher( | ||
{ | ||
schema: this.config.schema, | ||
output: newOutput, | ||
include: this.config.include | ||
}, | ||
this._params, | ||
this._api | ||
); | ||
} | ||
getResource() { | ||
return this._resource; | ||
} | ||
getParams() { | ||
@@ -452,5 +979,7 @@ return this._params; | ||
const outputKeys = this.config.output.keyof().options; | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
if (this._api.endpoint === "content") { | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
} | ||
if (inputKeys.length !== outputKeys.length && outputKeys.length > 0) { | ||
@@ -462,7 +991,10 @@ this._urlParams.fields = outputKeys.join(","); | ||
} | ||
if (this._params.formats && this._params.formats.length > 0) { | ||
this._urlParams.formats = this._params.formats.join(","); | ||
} | ||
const url = new URL(this._api.url); | ||
if (this._params.identity.id) { | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/${this._params.identity.id}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/${this._params.identity.id}/`; | ||
} else if (this._params.identity.slug) { | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/slug/${this._params.identity.slug}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/slug/${this._params.identity.slug}/`; | ||
} else { | ||
@@ -477,13 +1009,13 @@ throw new Error("Identity is not defined"); | ||
async fetch() { | ||
const res = import_zod4.z.discriminatedUnion("status", [ | ||
import_zod4.z.object({ | ||
status: import_zod4.z.literal("success"), | ||
const res = import_zod15.z.discriminatedUnion("status", [ | ||
import_zod15.z.object({ | ||
status: import_zod15.z.literal("success"), | ||
data: this.config.output | ||
}), | ||
import_zod4.z.object({ | ||
status: import_zod4.z.literal("error"), | ||
errors: import_zod4.z.array( | ||
import_zod4.z.object({ | ||
type: import_zod4.z.string(), | ||
message: import_zod4.z.string() | ||
import_zod15.z.object({ | ||
status: import_zod15.z.literal("error"), | ||
errors: import_zod15.z.array( | ||
import_zod15.z.object({ | ||
type: import_zod15.z.string(), | ||
message: import_zod15.z.string() | ||
}) | ||
@@ -493,3 +1025,3 @@ ) | ||
]); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -502,3 +1034,3 @@ if (result.errors) { | ||
status: "success", | ||
data: result[this._endpoint][0] | ||
data: result[this._resource][0] | ||
}; | ||
@@ -508,26 +1040,2 @@ } | ||
} | ||
async _fetch() { | ||
if (this._URL === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
try { | ||
result = await (await (0, import_cross_fetch2.default)(this._URL.toString(), { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept-Version": this._api.version | ||
} | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
}; | ||
@@ -563,3 +1071,4 @@ | ||
include: includeFields, | ||
fields: options?.output?.fields || void 0 | ||
fields: options?.output?.fields || void 0, | ||
formats: this.config.formats && options?.output?.formats ? this.config.formats.parse(options.output.formats) : void 0 | ||
}, | ||
@@ -591,3 +1100,4 @@ this._api | ||
include: includeFields, | ||
fields: options?.output?.fields || void 0 | ||
fields: options?.output?.fields || void 0, | ||
formats: this.config.formats && options?.output?.formats ? this.config.formats.parse(options.output.formats) : void 0 | ||
}, | ||
@@ -600,4 +1110,3 @@ this._api | ||
// src/fetchers/basic-fetcher.ts | ||
var import_cross_fetch3 = __toESM(require("cross-fetch")); | ||
var import_zod5 = require("zod"); | ||
var import_zod16 = require("zod"); | ||
var BasicFetcher = class { | ||
@@ -610,6 +1119,6 @@ constructor(config, _api) { | ||
this._buildUrl(); | ||
this._endpoint = _api.endpoint; | ||
this._resource = _api.resource; | ||
} | ||
getEndpoint() { | ||
return this._endpoint; | ||
getResource() { | ||
return this._resource; | ||
} | ||
@@ -623,7 +1132,9 @@ getOutputFields() { | ||
_buildUrl() { | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
if (this._api.endpoint === "content") { | ||
this._urlParams = { | ||
key: this._api.key | ||
}; | ||
} | ||
const url = new URL(this._api.url); | ||
url.pathname = `/ghost/api/content/${this._api.endpoint}/`; | ||
url.pathname = `/ghost/api/${this._api.endpoint}/${this._api.resource}/`; | ||
for (const [key, value] of Object.entries(this._urlParams)) { | ||
@@ -635,13 +1146,13 @@ url.searchParams.append(key, value); | ||
async fetch() { | ||
const res = import_zod5.z.discriminatedUnion("status", [ | ||
import_zod5.z.object({ | ||
status: import_zod5.z.literal("success"), | ||
const res = import_zod16.z.discriminatedUnion("status", [ | ||
import_zod16.z.object({ | ||
status: import_zod16.z.literal("success"), | ||
data: this.config.output | ||
}), | ||
import_zod5.z.object({ | ||
status: import_zod5.z.literal("error"), | ||
errors: import_zod5.z.array( | ||
import_zod5.z.object({ | ||
type: import_zod5.z.string(), | ||
message: import_zod5.z.string() | ||
import_zod16.z.object({ | ||
status: import_zod16.z.literal("error"), | ||
errors: import_zod16.z.array( | ||
import_zod16.z.object({ | ||
type: import_zod16.z.string(), | ||
message: import_zod16.z.string() | ||
}) | ||
@@ -651,3 +1162,3 @@ ) | ||
]); | ||
const result = await this._fetch(); | ||
const result = await _fetch(this._URL, this._api); | ||
let data = {}; | ||
@@ -660,3 +1171,3 @@ if (result.errors) { | ||
status: "success", | ||
data: result[this._endpoint] | ||
data: result[this._resource] | ||
}; | ||
@@ -666,26 +1177,2 @@ } | ||
} | ||
async _fetch() { | ||
if (this._URL === void 0) | ||
throw new Error("URL is undefined"); | ||
let result = void 0; | ||
try { | ||
result = await (await (0, import_cross_fetch3.default)(this._URL.toString(), { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept-Version": this._api.version | ||
} | ||
})).json(); | ||
} catch (e) { | ||
return { | ||
status: "error", | ||
errors: [ | ||
{ | ||
type: "FetchError", | ||
message: e.toString() | ||
} | ||
] | ||
}; | ||
} | ||
return result; | ||
} | ||
}; | ||
@@ -698,6 +1185,18 @@ // Annotate the CommonJS export names for ESM import in node: | ||
ReadFetcher, | ||
adminAPICredentialsSchema, | ||
adminAPIEndpointsSchema, | ||
apiVersionsSchema, | ||
baseAuthorsSchema, | ||
baseEmailSchema, | ||
baseMembersSchema, | ||
baseNewsletterSchema, | ||
baseOffersSchema, | ||
basePagesSchema, | ||
basePostsSchema, | ||
baseSettingsSchema, | ||
baseSiteSchema, | ||
baseTagsSchema, | ||
baseTiersSchema, | ||
browseParamsSchema, | ||
contentAPICredentialsSchema, | ||
contentAPIEndpointsSchema, | ||
ghostCodeInjectionSchema, | ||
@@ -704,0 +1203,0 @@ ghostExcerptSchema, |
@@ -12,3 +12,3 @@ { | ||
}, | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"main": "./dist/index.js", | ||
@@ -22,3 +22,4 @@ "module": "./dist/index.mjs", | ||
"@ts-ghost/tsconfig": "*", | ||
"@types/node": "^18.14.1", | ||
"@types/jsonwebtoken": "^9.0.1", | ||
"@types/node": "^18.15.2", | ||
"eslint-config-vite": "*", | ||
@@ -30,3 +31,3 @@ "ts-toolbelt": "^9.6.0", | ||
"vite-tsconfig-paths": "^4.0.5", | ||
"vitest": "^0.29.1", | ||
"vitest": "^0.29.2", | ||
"vitest-fetch-mock": "^0.2.2" | ||
@@ -36,3 +37,4 @@ }, | ||
"cross-fetch": "^3.1.5", | ||
"zod": "^3.20.6" | ||
"jsonwebtoken": "^9.0.0", | ||
"zod": "^3.21.4" | ||
}, | ||
@@ -39,0 +41,0 @@ "publishConfig": { |
@@ -47,3 +47,3 @@ <br/> | ||
version: "v5.0", | ||
endpoint: "posts", | ||
resource: "posts", | ||
}; | ||
@@ -58,3 +58,3 @@ | ||
// the "include" schema is used to validate the "include" parameters of the API call | ||
// it is specific to the Ghost API endpoint from resource to resource. | ||
// it is specific to the Ghost API resource from resource to resource. | ||
// The format is always { 'name_of_the_field': true } | ||
@@ -82,3 +82,3 @@ const simplifiedIncludeSchema = z.object({ | ||
import { z } from "zod"; | ||
const api: ContentAPICredentials = { url: "https://ghost.org", key: "7d2d15d7338526d43c2fadc47c", version: "v5.0", endpoint: "posts",}; | ||
const api: ContentAPICredentials = { url: "https://ghost.org", key: "7d2d15d7338526d43c2fadc47c", version: "v5.0", resource: "posts",}; | ||
@@ -209,3 +209,3 @@ const simplifiedSchema = z.object({ | ||
### `include` | ||
The `include` key lets you include some additionnal data that the Ghost API doesn't give you by default. This `include` key is specific to each endpoint and is defined in the `Schema` of the endpoint. You will have to let TypeScript guide you to know what you can include. | ||
The `include` key lets you include some additionnal data that the Ghost API doesn't give you by default. This `include` key is specific to each resource and is defined in the `Schema` of the resource. You will have to let TypeScript guide you to know what you can include. | ||
@@ -212,0 +212,0 @@ ```typescript |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
383375
5956
3
11
+ Addedjsonwebtoken@^9.0.0
+ Addedbuffer-equal-constant-time@1.0.1(transitive)
+ Addedecdsa-sig-formatter@1.0.11(transitive)
+ Addedjsonwebtoken@9.0.2(transitive)
+ Addedjwa@1.4.1(transitive)
+ Addedjws@3.2.2(transitive)
+ Addedlodash.includes@4.3.0(transitive)
+ Addedlodash.isboolean@3.0.3(transitive)
+ Addedlodash.isinteger@4.0.4(transitive)
+ Addedlodash.isnumber@3.0.3(transitive)
+ Addedlodash.isplainobject@4.0.6(transitive)
+ Addedlodash.isstring@4.0.1(transitive)
+ Addedlodash.once@4.1.1(transitive)
+ Addedms@2.1.3(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsemver@7.7.1(transitive)
Updatedzod@^3.21.4