another progress marker
This commit is contained in:
parent
694432ad97
commit
f854abe9dd
|
@ -64,28 +64,38 @@
|
||||||
"lint": "eslint --cache --cache-location ./node_modules/.cache/eslint ."
|
"lint": "eslint --cache --cache-location ./node_modules/.cache/eslint ."
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"astro": "^4.2.1",
|
"astro": "^4.2.1"
|
||||||
"zod": "^3.22.4"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"devDependencies": {
|
||||||
"@matthiesenxyz/astro-ghostcms-theme-default": "workspace:*",
|
|
||||||
"@astrojs/check": "^0.3.4",
|
"@astrojs/check": "^0.3.4",
|
||||||
"@astrojs/rss": "^4.0.2",
|
"@ts-ghost/core-api": "*",
|
||||||
"@astrojs/sitemap": "^3.0.5",
|
"@ts-ghost/tsconfig": "*",
|
||||||
|
"@types/node": "^20.11.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
||||||
"@typescript-eslint/parser": "^6.19.0",
|
"@typescript-eslint/parser": "^6.19.0",
|
||||||
"@types/node": "^20.11.5",
|
|
||||||
"astro-robots-txt": "^1.0.0",
|
|
||||||
"axios": "^1.6.5",
|
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-astro": "^0.31.3",
|
"eslint-plugin-astro": "^0.31.3",
|
||||||
|
"jiti": "^1.21.0",
|
||||||
"prettier": "^3.2.4",
|
"prettier": "^3.2.4",
|
||||||
"prettier-plugin-astro": "^0.13.0",
|
"prettier-plugin-astro": "^0.13.0",
|
||||||
"sass": "^1.70.0",
|
"tsup": "^8.0.0",
|
||||||
"tiny-invariant": "^1.3.1",
|
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^4.5.2",
|
"vite": "^4.5.2",
|
||||||
|
"vite-tsconfig-paths": "^4.2.2",
|
||||||
|
"vitest": "^1.1.0",
|
||||||
|
"vitest-fetch-mock": "^0.2.2",
|
||||||
|
"zod": "^3.22.4",
|
||||||
"zod-validation-error": "^3.0.0"
|
"zod-validation-error": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@matthiesenxyz/astro-ghostcms-theme-default": "workspace:*",
|
||||||
|
"@astrojs/rss": "^4.0.2",
|
||||||
|
"@astrojs/sitemap": "^3.0.5",
|
||||||
|
"@ts-ghost/core-api": "^5.1.2",
|
||||||
|
"astro-robots-txt": "^1.0.0",
|
||||||
|
"axios": "^1.6.5",
|
||||||
|
"sass": "^1.70.0",
|
||||||
|
"tiny-invariant": "^1.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
import type { Page, Post } from "./index";
|
||||||
|
import { TSGhostContentAPI } from "./content-api";
|
||||||
|
|
||||||
|
// LOAD ENVIRONMENT VARIABLES
|
||||||
|
import { loadEnv } from 'vite';
|
||||||
|
|
||||||
|
const {CONTENT_API_KEY, CONTENT_API_URL} = loadEnv(
|
||||||
|
'all',
|
||||||
|
process.cwd(),
|
||||||
|
'CONTENT_'
|
||||||
|
);
|
||||||
|
|
||||||
|
let ghostApiKey = CONTENT_API_KEY;
|
||||||
|
let ghostUrl = CONTENT_API_URL;
|
||||||
|
|
||||||
|
// SETUP API
|
||||||
|
const version = "v5.0";
|
||||||
|
|
||||||
|
export const getGhostAuthors = async () => {
|
||||||
|
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||||
|
const results = await api.authors
|
||||||
|
.browse()
|
||||||
|
.include({
|
||||||
|
"count.posts": true,
|
||||||
|
})
|
||||||
|
.fetch();
|
||||||
|
if (!results.success) {
|
||||||
|
throw new Error(results.errors.map((e) => e.message).join(", "));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
authors: results.data,
|
||||||
|
meta: results.meta,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPosts = async () => {
|
||||||
|
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||||
|
const results = await api.posts
|
||||||
|
.browse()
|
||||||
|
.include({
|
||||||
|
authors: true,
|
||||||
|
tags: true,
|
||||||
|
})
|
||||||
|
.fetch();
|
||||||
|
if (!results.success) {
|
||||||
|
throw new Error(results.errors.map((e) => e.message).join(", "));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
posts: results.data,
|
||||||
|
meta: results.meta,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAllPosts = async () => {
|
||||||
|
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||||
|
const posts: Post[] = [];
|
||||||
|
let cursor = await api.posts
|
||||||
|
.browse()
|
||||||
|
.include({
|
||||||
|
authors: true,
|
||||||
|
tags: true,
|
||||||
|
})
|
||||||
|
.paginate();
|
||||||
|
if (cursor.current.success) posts.push(...cursor.current.data);
|
||||||
|
while (cursor.next) {
|
||||||
|
cursor = await cursor.next.paginate();
|
||||||
|
if (cursor.current.success) posts.push(...cursor.current.data);
|
||||||
|
}
|
||||||
|
return posts;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAllPages = async () => {
|
||||||
|
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||||
|
const pages: Page[] = [];
|
||||||
|
let cursor = await api.pages
|
||||||
|
.browse()
|
||||||
|
.include({
|
||||||
|
authors: true,
|
||||||
|
tags: true,
|
||||||
|
})
|
||||||
|
.paginate();
|
||||||
|
if (cursor.current.success) pages.push(...cursor.current.data);
|
||||||
|
while (cursor.next) {
|
||||||
|
cursor = await cursor.next.paginate();
|
||||||
|
if (cursor.current.success) pages.push(...cursor.current.data);
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSettings = async () => {
|
||||||
|
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||||
|
const res = await api.settings.fetch();
|
||||||
|
if (res.success) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
export type NonNullable<T> = T extends null | undefined ? never : T;
|
||||||
|
|
||||||
|
export type Settings = NonNullable<Awaited<ReturnType<typeof getSettings>>>;
|
||||||
|
|
||||||
|
export const getAllTags = async () => {
|
||||||
|
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||||
|
const results = await api.tags
|
||||||
|
.browse()
|
||||||
|
.include({
|
||||||
|
"count.posts": true,
|
||||||
|
})
|
||||||
|
.fetch();
|
||||||
|
if (!results.success) {
|
||||||
|
throw new Error(results.errors.map((e) => e.message).join(", "));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
tags: results.data,
|
||||||
|
meta: results.meta,
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,94 @@
|
||||||
|
import {
|
||||||
|
APIComposer, BasicFetcher, contentAPICredentialsSchema,
|
||||||
|
HTTPClient, slugOrIdSchema,
|
||||||
|
} from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
import {
|
||||||
|
authorsIncludeSchema, authorsSchema, pagesIncludeSchema,
|
||||||
|
pagesSchema, postsIncludeSchema, postsSchema,
|
||||||
|
settingsSchema, tagsIncludeSchema, tagsSchema,
|
||||||
|
tiersIncludeSchema, tiersSchema
|
||||||
|
} from "./schemas";
|
||||||
|
|
||||||
|
export type { ContentAPICredentials, APIVersions } from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
export enum BrowseEndpointType {
|
||||||
|
authors = "authors",
|
||||||
|
tiers = "tiers",
|
||||||
|
posts = "posts",
|
||||||
|
pages = "pages",
|
||||||
|
tags = "tags",
|
||||||
|
settings = "settings",
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TSGhostContentAPI<Version extends `v5.${string}` = any> {
|
||||||
|
private httpClient: HTTPClient;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected readonly url: string,
|
||||||
|
protected readonly key: string,
|
||||||
|
protected readonly version: Version
|
||||||
|
) {
|
||||||
|
const apiCredentials = contentAPICredentialsSchema.parse({
|
||||||
|
key,
|
||||||
|
version,
|
||||||
|
url,
|
||||||
|
});
|
||||||
|
this.httpClient = new HTTPClient({
|
||||||
|
...apiCredentials,
|
||||||
|
endpoint: "content",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get authors() {
|
||||||
|
return new APIComposer(
|
||||||
|
"authors",
|
||||||
|
{
|
||||||
|
schema: authorsSchema,
|
||||||
|
identitySchema: slugOrIdSchema,
|
||||||
|
include: authorsIncludeSchema,
|
||||||
|
},
|
||||||
|
this.httpClient
|
||||||
|
).access(["read", "browse"]);
|
||||||
|
}
|
||||||
|
get tiers() {
|
||||||
|
return new APIComposer(
|
||||||
|
"tiers",
|
||||||
|
{ schema: tiersSchema, identitySchema: slugOrIdSchema, include: tiersIncludeSchema },
|
||||||
|
this.httpClient
|
||||||
|
).access(["browse", "read"]);
|
||||||
|
}
|
||||||
|
get posts() {
|
||||||
|
return new APIComposer(
|
||||||
|
"posts",
|
||||||
|
{
|
||||||
|
schema: postsSchema,
|
||||||
|
identitySchema: slugOrIdSchema,
|
||||||
|
include: postsIncludeSchema,
|
||||||
|
},
|
||||||
|
this.httpClient
|
||||||
|
).access(["browse", "read"]);
|
||||||
|
}
|
||||||
|
get pages() {
|
||||||
|
return new APIComposer(
|
||||||
|
"pages",
|
||||||
|
{
|
||||||
|
schema: pagesSchema,
|
||||||
|
identitySchema: slugOrIdSchema,
|
||||||
|
include: pagesIncludeSchema,
|
||||||
|
},
|
||||||
|
this.httpClient
|
||||||
|
).access(["browse", "read"]);
|
||||||
|
}
|
||||||
|
get tags() {
|
||||||
|
return new APIComposer(
|
||||||
|
"tags",
|
||||||
|
{ schema: tagsSchema, identitySchema: slugOrIdSchema, include: tagsIncludeSchema },
|
||||||
|
this.httpClient
|
||||||
|
).access(["browse", "read"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
get settings() {
|
||||||
|
return new BasicFetcher("settings", { output: settingsSchema }, this.httpClient);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,4 @@
|
||||||
// FUNCTION EXPORTS
|
export * from './content-api';
|
||||||
export {
|
export * from './schemas';
|
||||||
getGhostPosts, getGhostRecentPosts, getGhostFeaturedPosts,
|
|
||||||
getGhostPostbySlug, getGhostPostsbyTag, getGhostTags,
|
|
||||||
getGhostTagbySlug, getGhostAuthors, getGhostPages,
|
|
||||||
getGhostPage, getGhostSettings
|
|
||||||
} from './functions';
|
|
||||||
|
|
||||||
// TYPE EXPORTS
|
export type { InferFetcherDataShape, InferResponseDataShape, BrowseParams } from "@ts-ghost/core-api";
|
||||||
export type {
|
|
||||||
PostOrPage, ArrayOrValue, Author,
|
|
||||||
Authors, BrowseFunction, CodeInjection,
|
|
||||||
Excerpt, Facebook, FieldParam,
|
|
||||||
FilterParam, FormatParam, GhostAPI,
|
|
||||||
GhostContentAPIOptions, GhostData, GhostError,
|
|
||||||
Identification, IncludeParam, LimitParam,
|
|
||||||
Metadata, Nullable, OrderParam,
|
|
||||||
PageParam, Pagination, Params,
|
|
||||||
PostsOrPages, ReadFunction, Settings,
|
|
||||||
SettingsResponse, SocialMedia, Tag,
|
|
||||||
TagVisibility, Tags, Twitter
|
|
||||||
} from './tryghost-content-api.d';
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import { ghostIdentitySchema, ghostMetadataSchema, ghostMetaSchema } from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
export const authorsSchema = z.object({
|
||||||
|
...ghostIdentitySchema.shape,
|
||||||
|
...ghostMetadataSchema.shape,
|
||||||
|
name: z.string(),
|
||||||
|
profile_image: z.string().nullable(),
|
||||||
|
cover_image: z.string().nullable(),
|
||||||
|
bio: z.string().nullable(),
|
||||||
|
website: z.string().nullable(),
|
||||||
|
location: z.string().nullable(),
|
||||||
|
facebook: z.string().nullable(),
|
||||||
|
twitter: z.string().nullable(),
|
||||||
|
count: z
|
||||||
|
.object({
|
||||||
|
posts: z.number(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
url: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Author = z.infer<typeof authorsSchema>;
|
||||||
|
|
||||||
|
export const ghostFetchAuthorsSchema = z.object({
|
||||||
|
meta: ghostMetaSchema,
|
||||||
|
authors: z.array(authorsSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const authorsIncludeSchema = z.object({
|
||||||
|
"count.posts": z.literal(true).optional(),
|
||||||
|
});
|
||||||
|
export type AuthorsIncludeSchema = z.infer<typeof authorsIncludeSchema>;
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./socials";
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Transformed to TypeScript, original Code by Ghost Foundation, License:
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
// Copyright (c) 2013-2022 Ghost Foundation
|
||||||
|
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
export const twitter = (username: string) => {
|
||||||
|
// Creates the canonical twitter URL without the '@'
|
||||||
|
return "https://twitter.com/" + username.replace(/^@/, "");
|
||||||
|
};
|
||||||
|
|
||||||
|
export const facebook = (username: string) => {
|
||||||
|
// Handles a starting slash, this shouldn't happen, but just in case
|
||||||
|
return "https://www.facebook.com/" + username.replace(/^\//, "");
|
||||||
|
};
|
|
@ -0,0 +1,7 @@
|
||||||
|
export * from './authors';
|
||||||
|
export * from './helpers';
|
||||||
|
export * from './pages';
|
||||||
|
export * from './posts';
|
||||||
|
export * from './settings';
|
||||||
|
export * from './tags';
|
||||||
|
export * from './tiers';
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import {
|
||||||
|
ghostCodeInjectionSchema,
|
||||||
|
ghostIdentitySchema,
|
||||||
|
ghostMetadataSchema,
|
||||||
|
ghostSocialMediaSchema,
|
||||||
|
ghostVisibilitySchema,
|
||||||
|
} from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
import { authorsSchema } from "./authors";
|
||||||
|
import { tagsSchema } from "./tags";
|
||||||
|
|
||||||
|
const postsAuthorSchema = authorsSchema.extend({
|
||||||
|
url: z.string().nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const pagesSchema = z.object({
|
||||||
|
...ghostIdentitySchema.shape,
|
||||||
|
...ghostMetadataSchema.shape,
|
||||||
|
title: z.string(),
|
||||||
|
html: z.string().catch(""),
|
||||||
|
plaintext: z.string().nullish(),
|
||||||
|
comment_id: z.string().nullable(),
|
||||||
|
feature_image: z.string().nullable(),
|
||||||
|
feature_image_alt: z.string().nullable(),
|
||||||
|
feature_image_caption: z.string().nullable(),
|
||||||
|
featured: z.boolean(),
|
||||||
|
custom_excerpt: z.string().nullable(),
|
||||||
|
...ghostCodeInjectionSchema.shape,
|
||||||
|
...ghostSocialMediaSchema.shape,
|
||||||
|
visibility: ghostVisibilitySchema,
|
||||||
|
custom_template: z.string().nullable(),
|
||||||
|
canonical_url: z.string().nullable(),
|
||||||
|
authors: z.array(postsAuthorSchema).optional(),
|
||||||
|
tags: z.array(tagsSchema).optional(),
|
||||||
|
primary_author: postsAuthorSchema.nullish(),
|
||||||
|
primary_tag: tagsSchema.nullish(),
|
||||||
|
url: z.string(),
|
||||||
|
excerpt: z.string().catch(""),
|
||||||
|
reading_time: z.number().optional().default(0),
|
||||||
|
created_at: z.string(),
|
||||||
|
updated_at: z.string(),
|
||||||
|
published_at: z.string(),
|
||||||
|
access: z.boolean(),
|
||||||
|
comments: z.boolean(),
|
||||||
|
email_subject: z.string().nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Page = z.infer<typeof pagesSchema>;
|
||||||
|
|
||||||
|
export const pagesIncludeSchema = z.object({
|
||||||
|
authors: z.literal(true).optional(),
|
||||||
|
tags: z.literal(true).optional(),
|
||||||
|
});
|
||||||
|
export type PagesIncludeSchema = z.infer<typeof pagesIncludeSchema>;
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import {
|
||||||
|
ghostCodeInjectionSchema,
|
||||||
|
ghostIdentitySchema,
|
||||||
|
ghostMetadataSchema,
|
||||||
|
ghostSocialMediaSchema,
|
||||||
|
ghostVisibilitySchema,
|
||||||
|
} from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
import { authorsSchema } from "./authors";
|
||||||
|
import { tagsSchema } from "./tags";
|
||||||
|
|
||||||
|
const postsAuthorSchema = authorsSchema.extend({
|
||||||
|
url: z.string().nullish(),
|
||||||
|
});
|
||||||
|
export const postsSchema = z.object({
|
||||||
|
...ghostIdentitySchema.shape,
|
||||||
|
...ghostMetadataSchema.shape,
|
||||||
|
title: z.string(),
|
||||||
|
html: z.string().catch(""),
|
||||||
|
plaintext: z.string().nullish(),
|
||||||
|
comment_id: z.string().nullable(),
|
||||||
|
feature_image: z.string().nullable(),
|
||||||
|
feature_image_alt: z.string().nullable(),
|
||||||
|
feature_image_caption: z.string().nullable(),
|
||||||
|
featured: z.boolean(),
|
||||||
|
custom_excerpt: z.string().nullable(),
|
||||||
|
...ghostCodeInjectionSchema.shape,
|
||||||
|
...ghostSocialMediaSchema.shape,
|
||||||
|
visibility: ghostVisibilitySchema,
|
||||||
|
custom_template: z.string().nullable(),
|
||||||
|
canonical_url: z.string().nullable(),
|
||||||
|
authors: z.array(postsAuthorSchema).optional(),
|
||||||
|
tags: z.array(tagsSchema).optional(),
|
||||||
|
primary_author: postsAuthorSchema.nullish(),
|
||||||
|
primary_tag: tagsSchema.nullish(),
|
||||||
|
url: z.string(),
|
||||||
|
excerpt: z.string().catch(""),
|
||||||
|
reading_time: z.number().optional().default(0),
|
||||||
|
created_at: z.string(),
|
||||||
|
updated_at: z.string().nullish(),
|
||||||
|
published_at: z.string().nullish(),
|
||||||
|
access: z.boolean(),
|
||||||
|
comments: z.boolean(),
|
||||||
|
email_subject: z.string().nullish(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Post = z.infer<typeof postsSchema>;
|
||||||
|
|
||||||
|
export const postsIncludeSchema = z.object({
|
||||||
|
authors: z.literal(true).optional(),
|
||||||
|
tags: z.literal(true).optional(),
|
||||||
|
});
|
||||||
|
export type PostsIncludeSchema = z.infer<typeof postsIncludeSchema>;
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const settingsSchema = z.object({
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
logo: z.string().nullable(),
|
||||||
|
icon: z.string().nullable(),
|
||||||
|
accent_color: z.string().nullable(),
|
||||||
|
cover_image: z.string().nullable(),
|
||||||
|
facebook: z.string().nullable(),
|
||||||
|
twitter: z.string().nullable(),
|
||||||
|
lang: z.string(),
|
||||||
|
timezone: z.string(),
|
||||||
|
codeinjection_head: z.string().nullable(),
|
||||||
|
codeinjection_foot: z.string().nullable(),
|
||||||
|
navigation: z.array(
|
||||||
|
z.object({
|
||||||
|
label: z.string(),
|
||||||
|
url: z.string(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
secondary_navigation: z.array(
|
||||||
|
z.object({
|
||||||
|
label: z.string(),
|
||||||
|
url: z.string(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
meta_title: z.string().nullable(),
|
||||||
|
meta_description: z.string().nullable(),
|
||||||
|
og_image: z.string().nullable(),
|
||||||
|
og_title: z.string().nullable(),
|
||||||
|
og_description: z.string().nullable(),
|
||||||
|
twitter_image: z.string().nullable(),
|
||||||
|
twitter_title: z.string().nullable(),
|
||||||
|
twitter_description: z.string().nullable(),
|
||||||
|
members_support_address: z.string(),
|
||||||
|
url: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Settings = z.infer<typeof settingsSchema>;
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import {
|
||||||
|
ghostCodeInjectionSchema,
|
||||||
|
ghostIdentitySchema,
|
||||||
|
ghostMetadataSchema,
|
||||||
|
ghostSocialMediaSchema,
|
||||||
|
ghostVisibilitySchema,
|
||||||
|
} from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
export const tagsSchema = z.object({
|
||||||
|
...ghostIdentitySchema.shape,
|
||||||
|
...ghostMetadataSchema.shape,
|
||||||
|
...ghostCodeInjectionSchema.shape,
|
||||||
|
...ghostSocialMediaSchema.shape,
|
||||||
|
name: z.string(),
|
||||||
|
description: z.string().nullable(),
|
||||||
|
feature_image: z.string().nullable(),
|
||||||
|
visibility: ghostVisibilitySchema,
|
||||||
|
canonical_url: z.string().nullable(),
|
||||||
|
accent_color: z.string().nullable(),
|
||||||
|
url: z.string(),
|
||||||
|
count: z
|
||||||
|
.object({
|
||||||
|
posts: z.number(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Tag = z.infer<typeof tagsSchema>;
|
||||||
|
|
||||||
|
export const tagsIncludeSchema = z.object({
|
||||||
|
"count.posts": z.literal(true).optional(),
|
||||||
|
});
|
||||||
|
export type TagsIncludeSchema = z.infer<typeof tagsIncludeSchema>;
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import { ghostIdentitySchema, ghostVisibilitySchema } from "@ts-ghost/core-api";
|
||||||
|
|
||||||
|
export const tiersSchema = z.object({
|
||||||
|
...ghostIdentitySchema.shape,
|
||||||
|
name: z.string(),
|
||||||
|
description: z.string().nullable(),
|
||||||
|
active: z.boolean(),
|
||||||
|
type: z.union([z.literal("free"), z.literal("paid")]),
|
||||||
|
welcome_page_url: z.string().nullable(),
|
||||||
|
created_at: z.string(),
|
||||||
|
updated_at: z.string().nullable(),
|
||||||
|
stripe_prices: z
|
||||||
|
.array(z.number())
|
||||||
|
.optional()
|
||||||
|
.transform((v) => (v?.length ? v : [])),
|
||||||
|
monthly_price: z
|
||||||
|
.number()
|
||||||
|
.nullable()
|
||||||
|
.optional()
|
||||||
|
.transform((v) => (v ? v : null)),
|
||||||
|
yearly_price: z
|
||||||
|
.number()
|
||||||
|
.nullable()
|
||||||
|
.optional()
|
||||||
|
.transform((v) => (v ? v : null)),
|
||||||
|
benefits: z.array(z.string()),
|
||||||
|
visibility: ghostVisibilitySchema,
|
||||||
|
currency: z.string().nullish(),
|
||||||
|
trial_days: z.number().default(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Tier = z.infer<typeof tiersSchema>;
|
||||||
|
|
||||||
|
export const tiersIncludeSchema = z.object({
|
||||||
|
monthly_price: z.literal(true).optional(),
|
||||||
|
yearly_price: z.literal(true).optional(),
|
||||||
|
benefits: z.literal(true).optional(),
|
||||||
|
});
|
||||||
|
export type TiersIncludeSchema = z.infer<typeof tiersIncludeSchema>;
|
|
@ -0,0 +1,22 @@
|
||||||
|
// FUNCTION EXPORTS
|
||||||
|
export {
|
||||||
|
getGhostPosts, getGhostRecentPosts, getGhostFeaturedPosts,
|
||||||
|
getGhostPostbySlug, getGhostPostsbyTag, getGhostTags,
|
||||||
|
getGhostTagbySlug, getGhostAuthors, getGhostPages,
|
||||||
|
getGhostPage, getGhostSettings
|
||||||
|
} from './functions';
|
||||||
|
|
||||||
|
// TYPE EXPORTS
|
||||||
|
export type {
|
||||||
|
PostOrPage, ArrayOrValue, Author,
|
||||||
|
Authors, BrowseFunction, CodeInjection,
|
||||||
|
Excerpt, Facebook, FieldParam,
|
||||||
|
FilterParam, FormatParam, GhostAPI,
|
||||||
|
GhostContentAPIOptions, GhostData, GhostError,
|
||||||
|
Identification, IncludeParam, LimitParam,
|
||||||
|
Metadata, Nullable, OrderParam,
|
||||||
|
PageParam, Pagination, Params,
|
||||||
|
PostsOrPages, ReadFunction, Settings,
|
||||||
|
SettingsResponse, SocialMedia, Tag,
|
||||||
|
TagVisibility, Tags, Twitter
|
||||||
|
} from './tryghost-content-api';
|
|
@ -1,5 +1,5 @@
|
||||||
import rss from "@astrojs/rss";
|
import rss from "@astrojs/rss";
|
||||||
import { getGhostPosts, getGhostSettings } from '../api';
|
import { getGhostPosts, getGhostSettings } from '../api_old';
|
||||||
import invariant from "tiny-invariant";
|
import invariant from "tiny-invariant";
|
||||||
|
|
||||||
export async function GET(context) {
|
export async function GET(context) {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"display": "Default",
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": false,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"inlineSources": false,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"preserveWatchOutput": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "**/*/lib", "**/*/dist"]
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"display": "Node 16",
|
||||||
|
"extends": "./base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ES2021", "ESNext", "DOM"],
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "ES2021",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"name": "@ts-ghost/tsconfig",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"display": "React Library",
|
||||||
|
"extends": "./base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ES2015"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"target": "ES6",
|
||||||
|
"jsx": "react-jsx"
|
||||||
|
}
|
||||||
|
}
|
1043
pnpm-lock.yaml
1043
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue