Compare commits
118 Commits
@matthiese
...
main
Author | SHA1 | Date |
---|---|---|
Adam Matthiesen | ca3e595401 | |
Adam Matthiesen | fa276f9d64 | |
Adam Matthiesen | 5166bdc11f | |
github-actions[bot] | acf9a1def4 | |
dependabot[bot] | f82035b813 | |
dependabot[bot] | a6b2b28843 | |
Adam Matthiesen | c3b8872706 | |
github-actions[bot] | 13d6b551b8 | |
create-issue-branch[bot] | f097c6a18b | |
github-actions[bot] | ec50145786 | |
create-issue-branch[bot] | b0218e182b | |
Adam Matthiesen | 8074b66935 | |
Adam Matthiesen | c57ff7d370 | |
Adam Matthiesen | 2854ad8a33 | |
Adam Matthiesen | cfc6c88a8f | |
github-actions[bot] | e532e1471e | |
create-issue-branch[bot] | b685e6617d | |
dependabot[bot] | 62829e268a | |
Adam Matthiesen | 6f1139f038 | |
github-actions[bot] | f1ee69c8b7 | |
create-issue-branch[bot] | 4c1002a733 | |
github-actions[bot] | 10bcac444b | |
create-issue-branch[bot] | a02c78b323 | |
github-actions[bot] | 6fee8bab1d | |
Adam Matthiesen | 209e99b8c7 | |
github-actions[bot] | b0ebb96783 | |
create-issue-branch[bot] | 746fcc5858 | |
github-actions[bot] | 110c5a973a | |
create-issue-branch[bot] | 205738c288 | |
Adam Matthiesen | fa93f54b68 | |
github-actions[bot] | 81095d78b5 | |
create-issue-branch[bot] | 27241192af | |
Adam Matthiesen | b606fac02d | |
Adam Matthiesen | 827be67b2d | |
Adam Matthiesen | 5709e8706e | |
Adam Matthiesen | 18f99e9b58 | |
Adam Matthiesen | f57800a911 | |
Adam Matthiesen | 08561b74ca | |
Adam Matthiesen | 78c0a72040 | |
Adam Matthiesen | 487d6e49fd | |
Adam Matthiesen | 20a12344a1 | |
Adam Matthiesen | dc7147421e | |
github-actions[bot] | 7babbf79dd | |
Adam Matthiesen | 20ba7b1bd2 | |
Adam Matthiesen | 3396cf4249 | |
github-actions[bot] | f921005a60 | |
dependabot[bot] | 79e7a279e0 | |
Adam Matthiesen | f7ef16ff66 | |
Adam Matthiesen | cee0255bb3 | |
dependabot[bot] | 409946a5d3 | |
Adam Matthiesen | 4a5e508cfb | |
Adam Matthiesen | c1db889879 | |
github-actions[bot] | 5b94b30316 | |
Adam Matthiesen | 62159744bc | |
Adam Matthiesen | b6ba6fedc1 | |
Adam Matthiesen | 5e73f12070 | |
Adam Matthiesen | c896e50468 | |
Adam Matthiesen | 70c366e0b8 | |
Adam Matthiesen | edad9da91f | |
Adam Matthiesen | f078ebc063 | |
Adam Matthiesen | 70b6fd2d16 | |
Adam Matthiesen | f7816e69a6 | |
Adam Matthiesen | 363c22bf36 | |
Adam Matthiesen | 9ec2a61782 | |
Adam Matthiesen | 9f6f137155 | |
Adam Matthiesen | b1d7a044cf | |
Adam Matthiesen | bc3ec6d653 | |
Adam Matthiesen | 01ad923e30 | |
Adam Matthiesen | b50e8882cc | |
Adam Matthiesen | 30ad4ac355 | |
Adam Matthiesen | 33d8d1782a | |
Adam Matthiesen | e73131984b | |
Adam Matthiesen | 24a7b3144b | |
Adam Matthiesen | 0441bc0fad | |
Adam Matthiesen | 28d9c9e5c4 | |
Adam Matthiesen | 546bd3fe10 | |
Adam Matthiesen | ee0d5b5147 | |
Adam Matthiesen | f881e4f2a6 | |
Adam Matthiesen | c077205215 | |
Adam Matthiesen | 621bafbd61 | |
Adam Matthiesen | 5cfea0a0a7 | |
Adam Matthiesen | e3080d763c | |
Adam Matthiesen | 6f78923d92 | |
Adam Matthiesen | 5b4c3e3268 | |
Adam Matthiesen | e0372288ed | |
Adam Matthiesen | aea8305ac0 | |
Adam Matthiesen | 41b0ce75d3 | |
Adam Matthiesen | 5f1f157152 | |
Adam Matthiesen | 3a9ee8aa0b | |
Adam Matthiesen | 03c1de5591 | |
Adam Matthiesen | 1350532de4 | |
Adam Matthiesen | 078b1c4088 | |
Adam Matthiesen | eebcd36583 | |
Adam Matthiesen | 4288cbe1ac | |
Adam Matthiesen | 302af0f7b6 | |
Adam Matthiesen | 65f3f2b019 | |
Adam Matthiesen | 017e641afd | |
Adam Matthiesen | 657cfe7568 | |
Adam Matthiesen | 5f7ac8e4a6 | |
Adam Matthiesen | 3192714355 | |
Adam Matthiesen | 2901524b8a | |
Adam Matthiesen | 557120f6e6 | |
Adam Matthiesen | fd21ee8df5 | |
Adam Matthiesen | 8db7190be8 | |
Adam Matthiesen | 8e276d533d | |
github-actions[bot] | a9a0222c59 | |
Adam Matthiesen | 127bcd22c9 | |
Adam Matthiesen | cb979d5b0f | |
Adam Matthiesen | e99553f413 | |
Adam Matthiesen | 271ad759a8 | |
github-actions[bot] | d8463fb696 | |
Adam Matthiesen | 40d6454fee | |
Adam Matthiesen | 32bab4e4c6 | |
Adam Matthiesen | e2438684f7 | |
Adam Matthiesen | 94b71b11d0 | |
Adam Matthiesen | 62f917ac8c | |
Adam Matthiesen | 5560722bd8 | |
Adam Matthiesen | ebd45257f6 |
|
@ -7,5 +7,5 @@
|
|||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": ["playground","starlight-playground"]
|
||||
"ignore": ["astro-playground", "starlight-playground"]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
name: New Chore
|
||||
about: Used to create a new Chore for a needed task
|
||||
title: "Chore: [NAME]"
|
||||
labels: chore
|
||||
---
|
||||
|
||||
**Is your chore related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1,38 @@
|
|||
branchName: 'issue-${issue.number}-${issue.title[0,32]}'
|
||||
gitReplaceChars: '/<>'
|
||||
autoLinkIssue: true
|
||||
openDraftPR: true
|
||||
prSkipCI: true
|
||||
copyIssueDescriptionToPR: true
|
||||
copyIssueLabelsToPR: true
|
||||
copyIssueAssigneeToPR: true
|
||||
copyIssueProjectsToPR: true
|
||||
copyIssueMilestoneToPR: true
|
||||
conventionalPrTitles: true
|
||||
conventionalLabels:
|
||||
fix:
|
||||
bug: '🐛'
|
||||
dependencies: '⬆️'
|
||||
security: '🔒'
|
||||
feat:
|
||||
enhancement: '✨'
|
||||
new-stuff: '🚀'
|
||||
build:
|
||||
build: '🔧'
|
||||
chore:
|
||||
chore: '♻️'
|
||||
ci:
|
||||
ci: '👷'
|
||||
docs:
|
||||
documentation: '📝'
|
||||
style:
|
||||
style: '💎'
|
||||
refactor:
|
||||
refactor: '♻️'
|
||||
perf:
|
||||
performance: '⚡️'
|
||||
test:
|
||||
test: '✅'
|
||||
breaking:
|
||||
breaking-change: '💥'
|
||||
breaking change: '💥'
|
|
@ -1,8 +1,7 @@
|
|||
name: "Changesets: Build Changesets for Dependabot"
|
||||
|
||||
#on: pull_request
|
||||
on:
|
||||
workflow_dispatch:
|
||||
on: pull_request
|
||||
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
|
|
@ -3,6 +3,9 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
env:
|
||||
CI: true
|
||||
jobs:
|
||||
|
@ -17,19 +20,19 @@ jobs:
|
|||
- name: setup node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
- name: install pnpm
|
||||
run: npm i pnpm@latest -g
|
||||
- name: Setup npmrc
|
||||
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
|
||||
- name: install dependencies
|
||||
run: pnpm install
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
- name: create and publish versions
|
||||
uses: matthiesenxyz/changeset-action@v1
|
||||
uses: matthiesenxyz/changeset@v1
|
||||
with:
|
||||
version: pnpm ci:version
|
||||
commit: "chore: update versions"
|
||||
title: "chore: update versions"
|
||||
title: "👷 [ci]: Ready for Release"
|
||||
publish: pnpm ci:publish
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACTION_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
name: Write coauthors to a pull request
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
generate-coauthors:
|
||||
name: Generate Coauthor
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: kevinzunigacuellar/coauthor-action@v0.1.2
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: jauderho/git-repo-sync@63782025e80e84c48b25a1ee6bb9a22a3bd570d3
|
||||
- uses: MatthiesenXYZ/git-sync-action@v1.1
|
||||
with:
|
||||
# Such as https://github.com/wangchucheng/git-repo-sync.git
|
||||
target-url: ${{ secrets.GITLAB_URL }}
|
||||
|
|
|
@ -11,6 +11,7 @@ Don't like GitHub, and prefer GitLab? This Repo is Auto Cloned to Gitlab! Check
|
|||
- [Default Theme](https://demo.astro-ghostcms.xyz) - ( [Github Repo](https://github.com/MatthiesenXYZ/demo-astroghostcms-themedefault) )
|
||||
- [Catppuccin Theme](https://catppuccindark-demo.astro-ghostcms.xyz/) - ( [Github Repo](https://github.com/MatthiesenXYZ/demo-astroghostcms-catppuccin) )
|
||||
- [Brutal by Elian Theme](https://brutal-demo.astro-ghostcms.xyz) - ( [Github Repo](https://github.com/MatthiesenXYZ/demo-astroghostcms-brutalbyelian) )
|
||||
- [Starlight GhostCMS](https://starlightdemo.astro-ghostcms.xyz/) - ( [Github Repo](https://github.com/MatthiesenXYZ/demo-starlightghostcms) )
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
@ -29,16 +30,16 @@ This repo is structured as a `pnpm` monorepo. All of our packages can be found
|
|||
|
||||
In this Repo you will find the Following:
|
||||
|
||||
- `playground`: Development and Testing
|
||||
- `playgrounds/`:
|
||||
- [`astro-playground`](./playgrounds/astro-playground/): Playground for Astro-GhostCMS development and testing.
|
||||
- [`starlight-playground`](./playgrounds/starlight-playground/): Playground of Starlight-GhostCMS development and testing.
|
||||
- `packages/`:
|
||||
- [`create-astro-ghostcms`](./packages/create-astro-ghostcms/): CLI Utility to quickly deploy new Astro-GhostCMS projects.
|
||||
- [`astro-ghostcms`](./packages/astro-ghostcms/): The main Integration!
|
||||
- [`astro-ghostcms-rendercontent`](./packages/astro-ghostcms-rendercontent/): Allows rendering of remote GhostCMS HTML with Custom Astro Components
|
||||
- [`astro-ghostcms-theme-default`](./packages/astro-ghostcms-theme-default/): The Default theme in integration mode.
|
||||
- [`astro-ghostcms-catppuccin`](./packages/astro-ghostcms-catppuccin/): A dark theme made with Catppuccin and TailwindCSS for Astro-GhostCMS Integration Mode.
|
||||
- [`astro-ghostcms-brutalbyelian`](./packages/astro-ghostcms-brutalbyelian/): [ElianCodes](https://www.elian.codes/) Brutal theme modified to work with Astro-GhostCMS
|
||||
- [`starlight-ghostcms`](./packages/starlight-ghostcms/) A [Starlight Plugin](https://starlight.astro.build/resources/plugins/) to integrate your GhostCMS into your documentation website
|
||||
- `tsconfig`: *LOCAL* Development package for `@ts-ghost/core-api`.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
26
package.json
26
package.json
|
@ -6,26 +6,26 @@
|
|||
"node": ">=18.19.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "pnpm --filter playground dev",
|
||||
"astro:dev": "pnpm --filter astro-playground dev",
|
||||
"starlight:dev": "pnpm --filter starlight-playground dev",
|
||||
"lint": "biome check .",
|
||||
"lint:fix": "biome check --apply .",
|
||||
"ci:version": "pnpm changeset version",
|
||||
"ci:publish": "pnpm changeset publish",
|
||||
"ci:test:api": "pnpm --filter astro-ghostcms test:ci",
|
||||
"test:api": "pnpm --filter astro-ghostcms test",
|
||||
"test:api:watch": "pnpm --filter astro-ghostcms test:watch",
|
||||
"test:api:coverage": "pnpm --filter astro-ghostcms test:coverage",
|
||||
"test:create": "pnpm --filter create-astro-ghostcms test",
|
||||
"test:slg": "pnpm --filter starlight-ghostcms test",
|
||||
"test:slg:watch": "pnpm --filter starlight-ghostcms test:watch",
|
||||
"test:slg:coverage": "pnpm --filter starlight-ghostcms test:coverage"
|
||||
"ci:test:integration": "pnpm --filter astro-ghostcms test:ci",
|
||||
"test:integration": "pnpm --filter astro-ghostcms test",
|
||||
"test:integration:watch": "pnpm --filter astro-ghostcms test:watch",
|
||||
"test:integration:coverage": "pnpm --filter astro-ghostcms test:coverage",
|
||||
"test:create-utility": "pnpm --filter create-astro-ghostcms test",
|
||||
"test:starlight": "pnpm --filter starlight-ghostcms test",
|
||||
"test:starlight:watch": "pnpm --filter starlight-ghostcms test:watch",
|
||||
"test:starlight:coverage": "pnpm --filter starlight-ghostcms test:coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.5.3",
|
||||
"@biomejs/biome": "1.6.1",
|
||||
"@changesets/cli": "^2.27.1",
|
||||
"vitest": "^1.3.0",
|
||||
"vitest-fetch-mock": "^0.2.2",
|
||||
"@vitest/ui": "1.3.0"
|
||||
"@vitest/ui": "^1.4.0",
|
||||
"vitest": "^1.4.0",
|
||||
"vitest-fetch-mock": "^0.2.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,83 @@
|
|||
# @matthiesenxyz/astro-ghostcms-brutalbyelian
|
||||
|
||||
## 0.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f82035b: Bump dependencies:
|
||||
|
||||
- astro-integration-kit from to
|
||||
- @unocss/astro from to
|
||||
- @unocss/reset from to
|
||||
- astro-font from to
|
||||
- unocss from to
|
||||
- sass from to
|
||||
- @matthiesenxyz/astro-gists from to
|
||||
- vite-tsconfig-paths from to
|
||||
- astro from to
|
||||
|
||||
- Updated dependencies [f82035b]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.5
|
||||
|
||||
## 0.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f097c6a: Adds a toggleswitch to allow users to disable astro-remote usage for rendering ghost-content
|
||||
- Updated dependencies [f097c6a]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.4
|
||||
|
||||
## 0.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b0218e1: fix:
|
||||
|
||||
- Removed CodeSlot Component that sometimes would break with some <pre> components
|
||||
- Will be adding at a latter time a custom component to replace this, but at this time this is now fixed.
|
||||
|
||||
## 0.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4c1002a: fix getAllTags bug for themes and bump other packages deps
|
||||
- Updated dependencies [4c1002a]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.2
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 746fcc5: Fix html rendering to allow custom components
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2724119: Migrate from `astro-ghostcms-rendercontent` to `astro-remote` for internal processing of GhostCMS HTML. no user changes required.
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f921005: Bump dependencies:
|
||||
|
||||
- vite from to
|
||||
- @eliancodes/brutal-ui from to
|
||||
- typescript from to
|
||||
- ultrahtml from to
|
||||
- @fontsource-variable/inter from to
|
||||
- astro-seo from to
|
||||
- astro from to
|
||||
- sass from to
|
||||
- @astrojs/starlight from to
|
||||
- sharp from to
|
||||
|
||||
- Updated dependencies [f921005]
|
||||
- Updated dependencies [f921005]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.1
|
||||
- @matthiesenxyz/astro-ghostcms-rendercontent@0.0.8
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms-brutalbyelian",
|
||||
"description": "ElianCodes Brutal theme modified to work with Astro-GhostCMS",
|
||||
"version": "0.0.11",
|
||||
"version": "0.0.18",
|
||||
"homepage": "https://astro-ghostcms.xyz/",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
@ -42,29 +42,27 @@
|
|||
},
|
||||
"scripts": {},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.2.0"
|
||||
"@matthiesenxyz/astro-ghostcms": ">=3.3.5",
|
||||
"astro": ">=4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/parser": "^7.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"@typescript-eslint/parser": "^7.2.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-astro": "^0.31.4",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"prettier-plugin-astro": "^0.13.0",
|
||||
"prettier": "^3.2.5",
|
||||
"@matthiesenxyz/astro-ghostcms": "workspace:*",
|
||||
"@matthiesenxyz/astro-ghostcms-rendercontent": "workspace:*"
|
||||
"prettier": "^3.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eliancodes/brutal-ui": "^0.2.6",
|
||||
"@iconify-json/logos": "^1.1.41",
|
||||
"@iconify-json/uil": "^1.1.8",
|
||||
"@matthiesenxyz/astro-ghostcms": "^3.2.9",
|
||||
"@matthiesenxyz/astro-ghostcms-rendercontent": "^0.0.7",
|
||||
"@unocss/astro": "^0.58.5",
|
||||
"@unocss/reset": "^0.58.5",
|
||||
"unocss": "^0.58.5",
|
||||
"@eliancodes/brutal-ui": "^0.2.3",
|
||||
"astro-font": "^0.0.77",
|
||||
"typescript": "^5.3.3",
|
||||
"ultrahtml": "^1.5.2"
|
||||
"@unocss/astro": "^0.58.6",
|
||||
"@unocss/reset": "^0.58.6",
|
||||
"astro-font": "^0.0.78",
|
||||
"astro-remote": "0.3.2",
|
||||
"typescript": "^5.4.2",
|
||||
"ultrahtml": "^1.5.3",
|
||||
"unocss": "^0.58.6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
---
|
||||
import { getGhostImgPath } from "../../utils";
|
||||
import type { Settings } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import { Markup } from 'astro-remote';
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const useRemote = config.ThemeProvider.astroRemote.enable;
|
||||
|
||||
export type Props = {
|
||||
image: string;
|
||||
alt?: string;
|
||||
|
@ -22,5 +27,8 @@ const { image, alt, caption = "", settings, transitionName } = Astro.props as Pr
|
|||
alt={alt}
|
||||
transition:name={transitionName}
|
||||
/>
|
||||
{caption && <figcaption class="text-ctp-overlay2"><Fragment set:html={caption}></figcaption>}
|
||||
{caption && (
|
||||
<figcaption class="text-ctp-overlay2">
|
||||
{useRemote ? <Markup content={caption} /> : <Fragment set:html={caption} />}
|
||||
</figcaption>)}
|
||||
</figure>
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
---
|
||||
import { Code } from "astro/components"
|
||||
import { parse } from "ultrahtml"
|
||||
import { querySelector } from "ultrahtml/selector"
|
||||
|
||||
const html = await Astro.slots.render("default")
|
||||
const ast = await parse(html)
|
||||
const codetag = querySelector(ast,'code')
|
||||
const { children } = codetag
|
||||
const code = children[0].value
|
||||
---
|
||||
<Code code={code} lang={"sh"} theme={"monokai"}/>
|
|
@ -4,6 +4,5 @@ export { default as H3 } from "./H3.astro";
|
|||
export { default as H4 } from "./H4.astro";
|
||||
export { default as H5 } from "./H5.astro";
|
||||
export { default as H6 } from "./H6.astro";
|
||||
export { default as CodeSlot } from "./CodeSlot.astro";
|
||||
export { default as Paragraph } from "./Paragraph.astro";
|
||||
export { default as astrocard } from "./astrocard.astro";
|
||||
|
|
|
@ -4,9 +4,12 @@ import { getAllPosts, getAllPages, getSettings, invariant } from "@matthiesenxyz
|
|||
import type { InferGetStaticPropsType } from "astro";
|
||||
import RecentBlogPosts from "../components/generic/RecentBlogPosts.astro";
|
||||
import BlogPostHeader from "../components/blog/BlogPostHeader.astro";
|
||||
import { GhostRender } from "@matthiesenxyz/astro-ghostcms-rendercontent";
|
||||
import { Markup } from 'astro-remote';
|
||||
import * as C from "../components/ghostrender";
|
||||
import { Card } from "@eliancodes/brutal-ui";
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const useRemote = config.ThemeProvider.astroRemote.enable;
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
||||
|
@ -30,8 +33,12 @@ invariant(settings, "Settings are required");
|
|||
|
||||
<div class="my-5"/>
|
||||
<div id="ghost">
|
||||
<GhostRender
|
||||
{useRemote ? <Markup
|
||||
content={post.html}
|
||||
sanitize={{
|
||||
allowComponents: true,
|
||||
allowElements: ['a', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img', 'figure', 'figcaption', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'em', 'strong', 'del', 'hr', 'br', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'div', 'span', 'script', 'astrocard'],
|
||||
}}
|
||||
components={{
|
||||
h1: C.H1,
|
||||
h2: C.H2,
|
||||
|
@ -39,11 +46,10 @@ invariant(settings, "Settings are required");
|
|||
h4: C.H4,
|
||||
h5: C.H5,
|
||||
h6: C.H6,
|
||||
pre: C.CodeSlot,
|
||||
p: C.Paragraph,
|
||||
astrocard: C.astrocard,
|
||||
}}
|
||||
/>
|
||||
/> : <Fragment set:html={post.html} />}
|
||||
</div>
|
||||
|
||||
</article>
|
||||
|
|
|
@ -8,7 +8,7 @@ import { getAllPosts, getAllTags, getSettings, invariant } from "@matthiesenxyz/
|
|||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getAllPosts();
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
|
||||
return tags.map((tag) => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import Layout from '../layouts/Default.astro';
|
||||
import { getAllTags, getSettings, invariant } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import TagSummaryCard from '../components/generic/TagSummaryCard.astro';
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
invariant(settings, 'Settings not found');
|
||||
const title = settings.title;
|
||||
|
|
|
@ -1,5 +1,62 @@
|
|||
# @matthiesenxyz/astro-ghostcms-catppuccin
|
||||
|
||||
## 0.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f097c6a: Adds a toggleswitch to allow users to disable astro-remote usage for rendering ghost-content
|
||||
- Updated dependencies [f097c6a]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.4
|
||||
|
||||
## 0.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b0218e1: fix:
|
||||
|
||||
- Removed CodeSlot Component that sometimes would break with some <pre> components
|
||||
- Will be adding at a latter time a custom component to replace this, but at this time this is now fixed.
|
||||
|
||||
## 0.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4c1002a: fix getAllTags bug for themes and bump other packages deps
|
||||
- Updated dependencies [4c1002a]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.2
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 746fcc5: Fix html rendering to allow custom components
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2724119: Migrate to `astro-remote` for internal processing of GhostCMS HTML. No user changes required.
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f921005: Bump dependencies:
|
||||
|
||||
- vite from to
|
||||
- @eliancodes/brutal-ui from to
|
||||
- typescript from to
|
||||
- ultrahtml from to
|
||||
- @fontsource-variable/inter from to
|
||||
- astro-seo from to
|
||||
- astro from to
|
||||
- sass from to
|
||||
- @astrojs/starlight from to
|
||||
- sharp from to
|
||||
|
||||
- Updated dependencies [f921005]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.1
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms-catppuccin",
|
||||
"description": "A dark theme made with Catppuccin and TailwindCSS for Astro-GhostCMS",
|
||||
"version": "0.0.8",
|
||||
"version": "0.0.14",
|
||||
"homepage": "https://astro-ghostcms.xyz/",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
@ -50,7 +50,8 @@
|
|||
},
|
||||
"scripts": {},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.2.1"
|
||||
"@matthiesenxyz/astro-ghostcms": ">=3.3.5",
|
||||
"astro": ">=4.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@matthiesenxyz/astro-ghostcms": "workspace:*"
|
||||
|
@ -58,11 +59,13 @@
|
|||
"dependencies": {
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@catppuccin/tailwindcss": "0.1.6",
|
||||
"@fontsource-variable/inter": "^5.0.16",
|
||||
"@matthiesenxyz/astro-ghostcms": "^3.2.9",
|
||||
"@fontsource-variable/inter": "^5.0.17",
|
||||
"@matthiesenxyz/astro-ghostcms": "^3.3.5",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"astro-navbar": "^2.3.1",
|
||||
"astro-seo": "^0.8.2"
|
||||
"astro-remote": "^0.3.2",
|
||||
"astro-seo": "^0.8.3",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"ultrahtml": "1.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@ import type { Settings, Post } from "@matthiesenxyz/astro-ghostcms/api";
|
|||
import FeatureImage from "./FeatureImage.astro";
|
||||
import AuthorList from "./AuthorList.astro";
|
||||
import { formatDate } from "../utils";
|
||||
import { Markup } from 'astro-remote';
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const useRemote = config.ThemeProvider.astroRemote.enable;
|
||||
|
||||
export type Props = {
|
||||
posts: Post[];
|
||||
settings: Settings;
|
||||
|
@ -59,7 +64,15 @@ const latestFeatured = posts[0]
|
|||
</div>
|
||||
<div class="divider my-4"/>
|
||||
<section id="ghostimport" class="text-ctp-subtext1">
|
||||
{latestFeatured && <Fragment set:html={latestFeatured.html} />}
|
||||
|
||||
|
||||
{useRemote ? (latestFeatured && <Markup
|
||||
content={latestFeatured.html}
|
||||
sanitize={{
|
||||
allowComponents: true,
|
||||
allowElements: ['a', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img', 'figure', 'figcaption', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'em', 'strong', 'del', 'hr', 'br', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'div', 'span', 'script', 'astrocard'],
|
||||
}}
|
||||
/>) : (latestFeatured && <Fragment set:html={latestFeatured.html} />) }
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
import PostHero from "../components/PostHero.astro";
|
||||
import PostFooter from "../components/PostFooter.astro";
|
||||
import { getFeaturedPosts, invariant, type Post, type Settings } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import { Markup } from 'astro-remote';
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const useRemote = config.ThemeProvider.astroRemote.enable;
|
||||
|
||||
export type Props = {
|
||||
post: Post;
|
||||
settings: Settings;
|
||||
|
@ -14,10 +19,10 @@ async function getPostsSet(){
|
|||
const featuredPosts = await getFeaturedPosts();
|
||||
const fposts = posts;
|
||||
if(featuredPosts.posts.length === 0){ return fposts }
|
||||
else {
|
||||
const featured = featuredPosts.posts[0]
|
||||
return fposts.filter((p: Post)=>p.id !== featured.id)
|
||||
}
|
||||
|
||||
const featured = featuredPosts.posts[0]
|
||||
return fposts.filter((p: Post)=>p.id !== featured.id)
|
||||
|
||||
}
|
||||
|
||||
const mPosts = await getPostsSet()
|
||||
|
@ -27,7 +32,15 @@ invariant(settings, "Settings not found");
|
|||
|
||||
<PostHero post={post} settings={settings} />
|
||||
<div id="ghostimport" class="mt-4 text-ctp-subtext1">
|
||||
<Fragment set:html={post.html} />
|
||||
{useRemote ? (
|
||||
<Markup
|
||||
content={post.html}
|
||||
sanitize={{
|
||||
allowComponents: true,
|
||||
allowElements: ['a', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img', 'figure', 'figcaption', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'em', 'strong', 'del', 'hr', 'br', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'div', 'span', 'script', 'astrocard'],
|
||||
}}
|
||||
/>
|
||||
) : <Fragment set:html={post.html} /> }
|
||||
</div>
|
||||
<PostFooter post={post} settings={settings} posts={mPosts} />
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import PostPreview from '../../components/PostPreview.astro';
|
|||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getAllPosts();
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
|
||||
return tags.map((tag) => {
|
||||
|
|
|
@ -6,7 +6,7 @@ import { getAllTags, getSettings, invariant } from "@matthiesenxyz/astro-ghostcm
|
|||
|
||||
let title = "All Tags";
|
||||
let description = "All the tags used so far...";
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
invariant(settings, 'Settings not found');
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
# @matthiesenxyz/astro-ghostcms-rendercontent
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1f850db: Bump dependencies:
|
||||
|
||||
- astro from to
|
||||
- vite from to
|
||||
- astro-seo from to
|
||||
- sass from to
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3a5aea9: Updated Tests and Linted packages
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 455ad3f: Bump astro from 4.0.0 to 4.3.7
|
||||
- 12be739: Depencency updates
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix License File
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Initialization of changeset cli
|
|
@ -1,33 +0,0 @@
|
|||
# Astro GhostCMS Content API HTML Processor
|
||||
|
||||
Render remote GhostCMS HTML in Astro with full control over the output.
|
||||
|
||||
Powered by [`ultrahtml`](https://github.com/natemoo-re/ultrahtml).
|
||||
|
||||
## Rendering Remote Content
|
||||
|
||||
The most basic function of `astro-ghostcms-rendercontent` is to convert a string of HTML to Astro friendly HTML. Use the `GhostRender` component.
|
||||
|
||||
```astro
|
||||
---
|
||||
import { GhostRender } from "@matthiesenxyz/astro-ghostcms-rendercontent";
|
||||
---
|
||||
|
||||
<GhostRender content={post.html} />
|
||||
```
|
||||
|
||||
### Customization
|
||||
|
||||
`GhostRender` allows full control over the rendering of output. The `components` option allows you to replace a standard HTML element with a custom component.
|
||||
|
||||
```astro
|
||||
---
|
||||
import { GhostRender } from "@matthiesenxyz/astro-ghostcms-rendercontent";
|
||||
import Title from '../components/Title.astro';
|
||||
---
|
||||
|
||||
<!-- Render <h1> as custom <Title> component -->
|
||||
<GhostRender content={post.html} components={{ h1: Title }} />
|
||||
```
|
||||
|
||||
For examples on how to setup custom components check [examples](./examples/)
|
|
@ -1,12 +0,0 @@
|
|||
---
|
||||
import { Code } from "astro/components"
|
||||
import { parse } from "ultrahtml"
|
||||
import { querySelector } from "ultrahtml/selector"
|
||||
|
||||
const html = await Astro.slots.render("default")
|
||||
const ast = await parse(html)
|
||||
const codetag = querySelector(ast,'code')
|
||||
const { children } = codetag
|
||||
const code = children[0].value
|
||||
---
|
||||
<Code code={code} lang={"sh"} theme={"monokai"}/>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
<h1 class="righteous">
|
||||
<slot />
|
||||
</h1>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
<h2 class="righteous">
|
||||
<slot />
|
||||
</h2>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
<h3 class="righteous">
|
||||
<slot />
|
||||
</h3>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
<h4 class="righteous">
|
||||
<slot />
|
||||
</h4>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
<h5 class="righteous">
|
||||
<slot />
|
||||
</h5>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
---
|
||||
<h6 class="righteous">
|
||||
<slot />
|
||||
</h6>
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
---
|
||||
<p class="my-5"><slot /></p>
|
||||
|
||||
<style is:inline>
|
||||
#ghost p a {
|
||||
color: rgb(0, 123, 247);
|
||||
}
|
||||
#ghost ul li a {
|
||||
color: rgb(0, 123, 247);
|
||||
}
|
||||
#ghost ul li {
|
||||
padding-top: 0.5rem;
|
||||
margin-left: 2rem;
|
||||
list-style: circle;
|
||||
}
|
||||
#ghost ul {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
|
@ -1,8 +0,0 @@
|
|||
export { default as H1 } from "./H1.astro";
|
||||
export { default as H2 } from "./H2.astro";
|
||||
export { default as H3 } from "./H3.astro";
|
||||
export { default as H4 } from "./H4.astro";
|
||||
export { default as H5 } from "./H5.astro";
|
||||
export { default as H6 } from "./H6.astro";
|
||||
export { default as CodeSlot } from "./CodeSlot.astro";
|
||||
export { default as Paragraph } from "./Paragraph.astro";
|
|
@ -1 +0,0 @@
|
|||
export { default as GhostRender } from "./lib/GhostRender.astro";
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
import { createComponentProxy, html } from './utils';
|
||||
|
||||
export interface Props {
|
||||
content?: string;
|
||||
components?: Record<string, any>;
|
||||
}
|
||||
|
||||
const input = Astro.props.content ?? await Astro.slots.render('default');
|
||||
if (!input) {
|
||||
throw new Error('Unable to render <GhostRender> without a content prop or children')
|
||||
}
|
||||
// @ts-ignore
|
||||
const components = createComponentProxy($$result, Astro.props.components);
|
||||
const content = await html(input, { components });
|
||||
---
|
||||
|
||||
<Fragment set:html={content} />
|
|
@ -1 +0,0 @@
|
|||
/// <reference types="astro/client" />
|
|
@ -1,59 +0,0 @@
|
|||
import { jsx as h } from "astro/jsx-runtime";
|
||||
import { renderJSX } from "astro/runtime/server/jsx";
|
||||
import * as entities from "entities";
|
||||
import { transform } from "ultrahtml";
|
||||
import { __unsafeHTML } from "ultrahtml";
|
||||
import swap from "ultrahtml/transformers/swap";
|
||||
|
||||
export function createComponentProxy(
|
||||
result,
|
||||
_components: Record<string, any> = {},
|
||||
) {
|
||||
const components = {};
|
||||
for (const [key, value] of Object.entries(_components)) {
|
||||
if (typeof value === "string") {
|
||||
components[key] = value;
|
||||
} else {
|
||||
components[key] = async (props, children) => {
|
||||
if (key === "CodeBlock" || key === "CodeSpan") {
|
||||
props.code = entities.decode(JSON.parse(`"${props.code}"`));
|
||||
}
|
||||
const output = await renderJSX(
|
||||
result,
|
||||
h(value, { ...props, "set:html": children.value }),
|
||||
);
|
||||
return __unsafeHTML(output);
|
||||
};
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
function getIndent(ln: string): string {
|
||||
if (ln.trim() === ln) return "";
|
||||
return ln.slice(0, ln.length - ln.trim().length);
|
||||
}
|
||||
|
||||
export function dedent(str: string): string {
|
||||
const lns = str.replace(/^[\r\n]+/, "").split("\n");
|
||||
let indent = getIndent(lns[0]);
|
||||
if (indent.length === 0 && lns.length > 1) {
|
||||
indent = getIndent(lns[1]);
|
||||
}
|
||||
return lns
|
||||
.map((ln) => (ln.startsWith(indent) ? ln.slice(indent.length) : ln))
|
||||
.map((ln, i, { length }) => (i === length - 1 ? ln.trim() : ln))
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
export interface HTMLOptions {
|
||||
// biome-ignore lint/complexity/noBannedTypes: <explanation>
|
||||
components?: {};
|
||||
}
|
||||
|
||||
export async function html(
|
||||
input: string,
|
||||
opts: HTMLOptions = {},
|
||||
): Promise<string> {
|
||||
return transform(dedent(input), [swap(opts.components)]);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms-rendercontent",
|
||||
"type": "module",
|
||||
"version": "0.0.7",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/MatthiesenXYZ/astro-ghostcms.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/MatthiesenXYZ/astro-ghostcms/issues",
|
||||
"email": "issues@astro-ghostcms.xyz"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"homepage": "https://astro-ghostcms.xyz",
|
||||
"files": [
|
||||
"examples",
|
||||
"lib",
|
||||
"index.ts",
|
||||
"CHANGELOG.md"
|
||||
],
|
||||
"types": "./index.ts",
|
||||
"exports": {
|
||||
".": "./index.ts",
|
||||
"./lib/*": "./lib/*",
|
||||
"./examples/*": "./examples/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"keywords": [
|
||||
"astro-ghostcms"
|
||||
],
|
||||
"author": {
|
||||
"email": "adam@matthiesen.xyz",
|
||||
"name": "Adam Matthiesen - MatthiesenXYZ",
|
||||
"url": "https://matthiesen.xyz"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"entities": "^4.5.0",
|
||||
"ultrahtml": "^1.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "4.4.0"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,81 @@
|
|||
# @matthiesenxyz/astro-ghostcms-theme-default
|
||||
|
||||
## 0.1.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f82035b: Bump dependencies:
|
||||
|
||||
- astro-integration-kit from to
|
||||
- @unocss/astro from to
|
||||
- @unocss/reset from to
|
||||
- astro-font from to
|
||||
- unocss from to
|
||||
- sass from to
|
||||
- @matthiesenxyz/astro-gists from to
|
||||
- vite-tsconfig-paths from to
|
||||
- astro from to
|
||||
|
||||
- Updated dependencies [f82035b]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.5
|
||||
|
||||
## 0.1.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f097c6a: Adds a toggleswitch to allow users to disable astro-remote usage for rendering ghost-content
|
||||
- Updated dependencies [f097c6a]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.4
|
||||
|
||||
## 0.1.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b0218e1: fix:
|
||||
|
||||
- Removed CodeSlot Component that sometimes would break with some <pre> components
|
||||
- Will be adding at a latter time a custom component to replace this, but at this time this is now fixed.
|
||||
|
||||
## 0.1.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4c1002a: fix getAllTags bug for themes and bump other packages deps
|
||||
- Updated dependencies [4c1002a]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.2
|
||||
|
||||
## 0.1.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 746fcc5: Fix html rendering to allow custom components
|
||||
|
||||
## 0.1.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2724119: Migrate to `astro-remote` for internal processing of GhostCMS HTML. No user changes required.
|
||||
|
||||
## 0.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f921005: Bump dependencies:
|
||||
|
||||
- vite from to
|
||||
- @eliancodes/brutal-ui from to
|
||||
- typescript from to
|
||||
- ultrahtml from to
|
||||
- @fontsource-variable/inter from to
|
||||
- astro-seo from to
|
||||
- astro from to
|
||||
- sass from to
|
||||
- @astrojs/starlight from to
|
||||
- sharp from to
|
||||
|
||||
- Updated dependencies [f921005]
|
||||
- @matthiesenxyz/astro-ghostcms@3.3.1
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms-theme-default",
|
||||
"description": "Default Theme for astro-ghostcms",
|
||||
"version": "0.1.13",
|
||||
"version": "0.1.20",
|
||||
"homepage": "https://astro-ghostcms.xyz/",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
@ -43,15 +43,17 @@
|
|||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"@matthiesenxyz/astro-ghostcms": "*",
|
||||
"@astrojs/check": "^0.5.4",
|
||||
"typescript": "^5.3.3"
|
||||
"@astrojs/check": "^0.5.9",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.2.1"
|
||||
"@matthiesenxyz/astro-ghostcms": ">=3.3.5",
|
||||
"astro": ">=4.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matthiesenxyz/astro-ghostcms": "^3.2.9",
|
||||
"astro-font": "^0.0.77",
|
||||
"sass": "^1.71.0"
|
||||
"astro-font": "^0.0.78",
|
||||
"astro-remote": "^0.3.2",
|
||||
"sass": "^1.72.0",
|
||||
"ultrahtml": "^1.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
---
|
||||
import FeatureImage from "../components/FeatureImage.astro";
|
||||
import type { Settings, Page } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import { Markup } from 'astro-remote';
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const useRemote = config.ThemeProvider.astroRemote.enable;
|
||||
|
||||
export type Props = {
|
||||
page: Page;
|
||||
settings: Settings;
|
||||
|
@ -24,7 +29,15 @@ const { page, settings, pageClass } = Astro.props as Props;
|
|||
|
||||
<section class="gh-content gh-canvas">
|
||||
<h1 class="article-title">{page.title}</h1>
|
||||
<Fragment set:html={page.html} />
|
||||
{useRemote ? (
|
||||
<Markup
|
||||
content={page.html}
|
||||
sanitize={{
|
||||
allowComponents: true,
|
||||
allowElements: ['a', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img', 'figure', 'figcaption', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'em', 'strong', 'del', 'hr', 'br', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'div', 'span', 'script', 'astrocard'],
|
||||
}}
|
||||
/>
|
||||
) : <Fragment set:html={page.html} /> }
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
import PostHero from "../components/PostHero.astro";
|
||||
import PostFooter from "../components/PostFooter.astro";
|
||||
import {invariant, type Post, type Settings } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import { Markup } from 'astro-remote';
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const useRemote = config.ThemeProvider.astroRemote.enable;
|
||||
|
||||
export type Props = {
|
||||
post: Post;
|
||||
settings: Settings;
|
||||
|
@ -16,7 +21,15 @@ invariant(settings, "Settings not found");
|
|||
<article class={`article post ${postClass}`}>
|
||||
<PostHero post={post} settings={settings} />
|
||||
<section class="gh-content gh-canvas">
|
||||
<Fragment set:html={post.html} />
|
||||
{useRemote ? (
|
||||
<Markup
|
||||
content={post.html}
|
||||
sanitize={{
|
||||
allowComponents: true,
|
||||
allowElements: ['a', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img', 'figure', 'figcaption', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'em', 'strong', 'del', 'hr', 'br', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'div', 'span', 'script', 'astrocard'],
|
||||
}}
|
||||
/>
|
||||
) : <Fragment set:html={post.html} /> }
|
||||
</section>
|
||||
</article>
|
||||
<PostFooter post={post} settings={settings} posts={posts} />
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
import type { InferGetStaticParamsType, InferGetStaticPropsType } from 'astro';
|
||||
import DefaultPageLayout from "../../layouts/default.astro";
|
||||
import PostPreview from "../../components/PostPreview.astro";
|
||||
import { getAllPosts, getAllTags, getSettings, invariant } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import type { InferGetStaticParamsType, InferGetStaticPropsType } from 'astro';
|
||||
import PostPreview from "../../components/PostPreview.astro";
|
||||
import DefaultPageLayout from "../../layouts/default.astro";
|
||||
import { getGhostImgPath } from "../../utils";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getAllPosts();
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
|
||||
return tags.map((tag) => {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
import DefaultPageLayout from "../layouts/default.astro";
|
||||
import { getAllTags, getSettings, invariant } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import TagCard from "../components/TagCard.astro";
|
||||
import { getSettings, getAllTags, invariant } from "@matthiesenxyz/astro-ghostcms/api";
|
||||
import DefaultPageLayout from "../layouts/default.astro";
|
||||
|
||||
|
||||
let title = "All Tags";
|
||||
let description = "All the tags used so far...";
|
||||
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings not found");
|
||||
---
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
CONTENT_API_KEY=a33da3965a3a9fb2c6b3f63b48
|
||||
CONTENT_API_URL=https://ghostdemo.matthiesen.xyz
|
|
@ -1,5 +1,82 @@
|
|||
# @matthiesenxyz/astro-ghostcms
|
||||
|
||||
## 3.3.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f82035b: Bump dependencies:
|
||||
|
||||
- astro-integration-kit from to
|
||||
- @unocss/astro from to
|
||||
- @unocss/reset from to
|
||||
- astro-font from to
|
||||
- unocss from to
|
||||
- sass from to
|
||||
- @matthiesenxyz/astro-gists from to
|
||||
- vite-tsconfig-paths from to
|
||||
- astro from to
|
||||
|
||||
- Updated dependencies [f82035b]
|
||||
- @matthiesenxyz/astro-ghostcms-theme-default@0.1.20
|
||||
|
||||
## 3.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f097c6a: Adds a toggleswitch to allow users to disable astro-remote usage for rendering ghost-content
|
||||
- Updated dependencies [f097c6a]
|
||||
- @matthiesenxyz/astro-ghostcms-theme-default@0.1.19
|
||||
|
||||
## 3.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b685e66: Update Deps
|
||||
|
||||
## 3.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4c1002a: fix getAllTags bug for themes and bump other packages deps
|
||||
- Updated dependencies [4c1002a]
|
||||
- @matthiesenxyz/astro-ghostcms-theme-default@0.1.17
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f921005: Bump dependencies:
|
||||
|
||||
- vite from to
|
||||
- @eliancodes/brutal-ui from to
|
||||
- typescript from to
|
||||
- ultrahtml from to
|
||||
- @fontsource-variable/inter from to
|
||||
- astro-seo from to
|
||||
- astro from to
|
||||
- sass from to
|
||||
- @astrojs/starlight from to
|
||||
- sharp from to
|
||||
|
||||
- Updated dependencies [f921005]
|
||||
- @matthiesenxyz/astro-ghostcms-theme-default@0.1.14
|
||||
|
||||
## 3.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- eebcd36: This is a HUGE internal update, Our integration is now built on [`Astro-Integration-Kit`](https://github.com/florian-lefebvre/astro-integration-kit) to give better control over the entire `Astro-GhostCMS` Eco-System.
|
||||
|
||||
# Breaking Changes:
|
||||
|
||||
- NEW USER CONFIG! Some of the options have changed! Please check the Readme for a current version of the available options!
|
||||
- Thats it! Some how even though this is almost an entire rebuild, There is no other USER breaking changes aside from the new more advanced config!
|
||||
|
||||
# Updates:
|
||||
|
||||
- Moved from `@ts-ghost/core-api` to `@ts-ghost/content-api` as it provides the same functions as the standard core-api but pre-wrapped with a nice `HTTPClientFactory` instead of `HTTPClient`.
|
||||
- Updated a ton of Dependencies that Dependabot was reporting as needed updated.
|
||||
|
||||
## 3.2.9
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -59,7 +59,34 @@ import GhostCMS from '@matthiesenxyz/astro-ghostcms';
|
|||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: "https://YOUR-DOMAIN-HERE.com"
|
||||
integrations: [GhostCMS()],
|
||||
integrations: [
|
||||
GhostCMS({
|
||||
// Config Options
|
||||
ghostURL: "http://example.com", // Recommended to set here, Can also set in .env as CONTENT_API_URL
|
||||
ThemeProvider: { // Allows you to pass config options to our ThemeProvider if enabled.
|
||||
disableThemeProvider: false, // OPTIONAL - Default False
|
||||
theme: "@matthiesenxyz/astro-ghostcms-theme-default", // OPTIONAL - Default Theme shown.
|
||||
astroRemote: {
|
||||
enable: true // OPTIONAL - Default True, Allows the user to switch to standard <Fragment> html rendering if they are having issues with Astro-remote
|
||||
}
|
||||
};
|
||||
disableDefault404: false, // Allows the user to disable the default `/404 page, to be able to create their own under `/src/pages/404.astro`.
|
||||
enableRSSFeed: true, // Allows the user to Enable or disable RSS Feed Generation. Default: true
|
||||
enableOGImages: true, // Allows the user to Enable or disable OG Image Generation. Default: true
|
||||
verbose: false, // Show the full Log output from All parts of Astro-GhostCMS
|
||||
Integrations: {
|
||||
// This allows user config passthrough from Astro-GhostCMS to the Included Integrations
|
||||
robotsTxt: {
|
||||
// OPTIONAL
|
||||
// ADVANCED USAGE - https://www.npmjs.com/package/astro-robots-txt#configuration
|
||||
},
|
||||
sitemap: {
|
||||
// OPTIONAL
|
||||
// ADVANCED USAGE - https://docs.astro.build/en/guides/integrations-guide/sitemap
|
||||
},
|
||||
},
|
||||
})
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -113,4 +140,3 @@ For more information and to see the docs please check our website: [Astro-GhostC
|
|||
# Foot Notes & Credits
|
||||
|
||||
[^1]: Ghost.org, Ghost.io, Ghost are all trademarks of [The Ghost Foundation](https://ghost.org/). This project is Open Source and not directly related to or provided by The Ghost Foundation and is intended to help create a easier method to utilize their provided JavaScript tools to link a Headless GhostCMS install in to your Astro project.
|
||||
|
||||
|
|
|
@ -1,359 +0,0 @@
|
|||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import type { AstroIntegration } from "astro";
|
||||
import type { SafeParseError, SafeParseSuccess } from "astro/zod";
|
||||
import fse from "fs-extra";
|
||||
import { loadEnv } from "vite";
|
||||
import ghostRobots from "./src/integrations/robots-txt";
|
||||
import ghostSitemap from "./src/integrations/sitemap";
|
||||
import { UserConfigSchema } from "./src/schemas";
|
||||
import { addVirtualImport } from "./src/utils/add-virtual-import";
|
||||
import latestVersion from "./src/utils/latestVersion.js";
|
||||
import { fromZodError } from "./src/utils/zod-validation/fromZodError.js";
|
||||
import type { UserConfig } from "./types";
|
||||
|
||||
/** INTERNAL CONSTANTS */
|
||||
const IC = {
|
||||
/** INTERNAL PACKAGE NAME */
|
||||
PKG: "@matthiesenxyz/astro-ghostcms",
|
||||
/** INTERNAL PACKAGE NAME (THEME) */
|
||||
DT: "@matthiesenxyz/astro-ghostcms-theme-default",
|
||||
/** INTERNAL STRING */
|
||||
CHECK_ENV: "Checking for Environment Variables...",
|
||||
/** SET ENV GRABBER MODE */
|
||||
MODE: "all",
|
||||
/** SET ENV GRABBER PREFIXES */
|
||||
PREFIXES: "CONTENT_API",
|
||||
/** INTERNAL STRING */
|
||||
KEY_MISSING: "CONTENT_API_KEY Missing from .env/environment variables",
|
||||
/** INTERNAL STRING */
|
||||
URL_MISSING:
|
||||
"CONTENT_API_URL Missing from .env/environment variables or ghostURL under the integration settings in `astro.config.mjs`",
|
||||
/** INTERNAL STRING */
|
||||
IT: "Injecting Theme: ",
|
||||
/** INTERNAL STRING */
|
||||
IDR: "Injecting Default Routes...",
|
||||
/** INTERNAL STRING */
|
||||
ITR: "Injecting Default Theme Routes...",
|
||||
/** INTERNAL STRING */
|
||||
IRD: "Route Injection Disabled - Skipping...",
|
||||
/** INTERNAL STRING */
|
||||
IIR: "Injecting Integration Route: ",
|
||||
/** INTERNAL STRING */
|
||||
II: "Injecting Integration: ",
|
||||
/** INTERNAL STRING */
|
||||
AIbU: "Already Imported by User: ",
|
||||
/** INTERNAL STRING */
|
||||
CF: "Checking for ",
|
||||
/** INTERNAL STRING */
|
||||
CONFSETUPDONE: "Step Complete",
|
||||
/** INTERNAL STRING */
|
||||
F0FR: "Inject `/404` Route",
|
||||
/** INTERNAL STRING */
|
||||
RSS: "Injecting `/rss.xml` Route and `@astrojs/rss` Integration",
|
||||
/** INTERNAL STRING */
|
||||
NOURL:
|
||||
"No Ghost URL defined in User Config: Falling back to environment variables.",
|
||||
/** INTERNAL STRING */
|
||||
id404: "404 Injection Disabled",
|
||||
/** INTERNAL STRING */
|
||||
idRSS: "RSS Injection Disabled",
|
||||
/** INTERNAL STRING */
|
||||
satori_e: "Injecting Satori-OpenGraph Generator",
|
||||
/** INTERNAL STRING */
|
||||
satori_d: "Satori Injection disabled",
|
||||
};
|
||||
|
||||
/** CONTENT API ENVIRONMENT VARIABLES */
|
||||
const ENV = loadEnv(IC.MODE, process.cwd(), IC.PREFIXES);
|
||||
|
||||
/** Astro-GhostCMS Integration
|
||||
* @ For more information and to see the docs check
|
||||
* @see https://astro-ghostcms.xyz
|
||||
*/
|
||||
export default function GhostCMS(options: UserConfig): AstroIntegration {
|
||||
return {
|
||||
name: "astro-ghostcms",
|
||||
hooks: {
|
||||
"astro:config:setup": async ({
|
||||
injectRoute,
|
||||
config,
|
||||
updateConfig,
|
||||
logger,
|
||||
}) => {
|
||||
// DEFINE LOGGERS
|
||||
const logConfigCheck = logger.fork("astro-ghostcms/config:check");
|
||||
const logConfigSetup = logger.fork("astro-ghostcms/config:setup");
|
||||
|
||||
// CHECK USER CONFIG AND MAKE AVAILBLE TO INTEGRATIONS
|
||||
logConfigCheck.info("Checking Config...");
|
||||
const GhostUserConfig = UserConfigSchema.safeParse(
|
||||
options || {},
|
||||
) as SafeParseSuccess<UserConfig>;
|
||||
if (!GhostUserConfig.success) {
|
||||
const validationError = fromZodError(
|
||||
(GhostUserConfig as unknown as SafeParseError<UserConfig>).error,
|
||||
);
|
||||
logConfigCheck.error(`Config Error - ${validationError}`);
|
||||
throw Error("");
|
||||
}
|
||||
const GhostConfig = GhostUserConfig.data;
|
||||
const GCD = {
|
||||
theme: GhostConfig.theme,
|
||||
dRI: GhostConfig.disableRouteInjection,
|
||||
dCO: GhostConfig.disableConsoleOutput,
|
||||
SM: GhostConfig.sitemap,
|
||||
RTXT: GhostConfig.robotstxt,
|
||||
gSite: GhostConfig.ghostURL,
|
||||
dRSS: GhostConfig.disableRSS,
|
||||
d404: GhostConfig.disable404,
|
||||
dOG: GhostConfig.disableSatoriOG,
|
||||
};
|
||||
|
||||
// Check For ENV Variables
|
||||
if (!GCD.dCO) {
|
||||
logConfigCheck.info(IC.CHECK_ENV);
|
||||
}
|
||||
if (ENV.CONTENT_API_KEY === undefined) {
|
||||
logConfigCheck.error(IC.KEY_MISSING);
|
||||
throw IC.KEY_MISSING;
|
||||
}
|
||||
if (GCD.gSite === undefined) {
|
||||
logConfigCheck.warn(IC.NOURL);
|
||||
if (ENV.CONTENT_API_URL === undefined) {
|
||||
logConfigCheck.error(IC.URL_MISSING);
|
||||
throw IC.URL_MISSING;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GCD.dRI) {
|
||||
// THEME SELECTOR
|
||||
if (GCD.theme === IC.DT) {
|
||||
if (!GCD.dCO) {
|
||||
logConfigCheck.info(IC.IT + IC.DT);
|
||||
}
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigCheck.info(IC.IT + GCD.theme);
|
||||
}
|
||||
}
|
||||
// INJECT ROUTES
|
||||
//// DEFAULT PROGRAM ROUTES
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.IDR);
|
||||
}
|
||||
if (!GCD.d404) {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.F0FR);
|
||||
}
|
||||
injectRoute({
|
||||
pattern: "/404",
|
||||
entrypoint: `${IC.PKG}/404.astro`,
|
||||
});
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.id404);
|
||||
}
|
||||
}
|
||||
|
||||
if (!GCD.dRSS) {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.RSS);
|
||||
}
|
||||
injectRoute({
|
||||
pattern: "/rss-style.xsl",
|
||||
entrypoint: `${IC.PKG}/rss-style.xsl.ts`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/rss.xml",
|
||||
entrypoint: `${IC.PKG}/rss.xml.ts`,
|
||||
});
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.idRSS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!GCD.dOG) {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.satori_e);
|
||||
}
|
||||
injectRoute({
|
||||
pattern: "/open-graph/[slug].png",
|
||||
entrypoint: `${IC.PKG}/open-graph/[slug].png.ts`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/open-graph/index.png",
|
||||
entrypoint: `${IC.PKG}/open-graph/index.png.ts`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/open-graph/authors.png",
|
||||
entrypoint: `${IC.PKG}/open-graph/authors.png.ts`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/open-graph/author/[slug].png",
|
||||
entrypoint: `${IC.PKG}/open-graph/author/[slug].png.ts`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/open-graph/tags.png",
|
||||
entrypoint: `${IC.PKG}/open-graph/tags.png.ts`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/open-graph/tag/[slug].png",
|
||||
entrypoint: `${IC.PKG}/open-graph/tag/[slug].png.ts`,
|
||||
});
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.satori_d);
|
||||
}
|
||||
}
|
||||
|
||||
// THEME ROUTES
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.ITR);
|
||||
}
|
||||
|
||||
injectRoute({
|
||||
pattern: "/",
|
||||
entrypoint: `${GCD.theme}/index.astro`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/[slug]",
|
||||
entrypoint: `${GCD.theme}/[slug].astro`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/tags",
|
||||
entrypoint: `${GCD.theme}/tags.astro`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/authors",
|
||||
entrypoint: `${GCD.theme}/authors.astro`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/tag/[slug]",
|
||||
entrypoint: `${GCD.theme}/tag/[slug].astro`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/author/[slug]",
|
||||
entrypoint: `${GCD.theme}/author/[slug].astro`,
|
||||
});
|
||||
injectRoute({
|
||||
pattern: "/archives/[...page]",
|
||||
entrypoint: `${GCD.theme}/archives/[...page].astro`,
|
||||
});
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(IC.IRD);
|
||||
}
|
||||
}
|
||||
|
||||
// IMPORT INTEGRATIONS & INTEGRATION ROUTES
|
||||
const integrations = [...config.integrations];
|
||||
|
||||
// IMPORT INTEGRATION: @ASTROJS/SITEMAP
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(`${IC.CF}@astrojs/sitemap`);
|
||||
}
|
||||
if (!integrations.find(({ name }) => name === "@astrojs/sitemap")) {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(`${IC.II}@astrojs/sitemap`);
|
||||
}
|
||||
integrations.push(ghostSitemap(GCD.SM));
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(`${IC.AIbU}@astrojs/sitemap`);
|
||||
}
|
||||
}
|
||||
|
||||
// IMPORT INTEGRATION: ASTRO-ROBOTS-TXT
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(`${IC.CF}astro-robots-txt`);
|
||||
}
|
||||
if (!integrations.find(({ name }) => name === "astro-robots-txt")) {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(`${IC.II}astro-robots-txt`);
|
||||
}
|
||||
integrations.push(ghostRobots(GCD.RTXT));
|
||||
} else {
|
||||
if (!GCD.dCO) {
|
||||
logConfigSetup.info(`${IC.AIbU}astro-robots-txt`);
|
||||
}
|
||||
}
|
||||
|
||||
// FINAL STEP TO KEEP INTEGRATION LIVE
|
||||
try {
|
||||
updateConfig({
|
||||
// UPDATE ASTRO CONFIG WITH INTEGRATED INTEGRATIONS
|
||||
integrations: [ghostSitemap(GCD.SM), ghostRobots(GCD.RTXT)],
|
||||
vite: {
|
||||
optimizeDeps: { exclude: ["@resvg/resvg-js"] },
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
logConfigSetup.error(e as string);
|
||||
throw e;
|
||||
}
|
||||
|
||||
addVirtualImport({
|
||||
name: "virtual:@matthiesenxyz/astro-ghostcms/config",
|
||||
content: `export default ${JSON.stringify(GhostUserConfig.data)}`,
|
||||
updateConfig,
|
||||
});
|
||||
},
|
||||
"astro:config:done": async ({ logger }) => {
|
||||
// Config Done
|
||||
const logConfigDone = logger.fork("astro-ghostcms/config:done");
|
||||
const pJSON = await fse.readJson(
|
||||
path.resolve(fileURLToPath(import.meta.url), "..", "package.json"),
|
||||
);
|
||||
const pkgVer = pJSON.version;
|
||||
logConfigDone.info(`Config Done. Current Version: v${pkgVer}`);
|
||||
},
|
||||
"astro:server:setup": async ({ logger }) => {
|
||||
// Dev Server Start
|
||||
const logServerSetup = logger.fork("astro-ghostcms/server:setup");
|
||||
const logCurrentVersion = logger.fork("astro-ghostcms/current-version");
|
||||
const logNpmVersion = logger.fork("astro-ghostcms/npm-pub-version");
|
||||
const logCheck = logger.fork("astro-ghostcms/check");
|
||||
const pJSON = await fse.readJson(
|
||||
path.resolve(fileURLToPath(import.meta.url), "..", "package.json"),
|
||||
);
|
||||
const pkgVer = pJSON.version;
|
||||
const npmVER = await latestVersion(IC.PKG);
|
||||
if (pkgVer !== npmVER) {
|
||||
logCurrentVersion.warn(`Current Installed Version is v${pkgVer}`);
|
||||
logNpmVersion.warn(`Latest Published Version is v${npmVER}`);
|
||||
logCheck.warn("Please consider updating.");
|
||||
}
|
||||
logServerSetup.info(
|
||||
"Setting up Astro-GhostCMS server for Development!",
|
||||
);
|
||||
},
|
||||
"astro:server:start": async ({ logger }) => {
|
||||
// Server Start
|
||||
const logServerStart = logger.fork("astro-ghostcms/server:start");
|
||||
logServerStart.info("Astro-GhostCMS Integration Ready!");
|
||||
},
|
||||
"astro:build:done": async ({ logger }) => {
|
||||
// Build Done
|
||||
const logBuildDone = logger.fork("astro-ghostcms/build:done");
|
||||
const logCurrentVersion = logger.fork("astro-ghostcms/current-version");
|
||||
const logNpmVersion = logger.fork("astro-ghostcms/npm-pub-version");
|
||||
const logCheck = logger.fork("astro-ghostcms/check");
|
||||
const pJSON = await fse.readJson(
|
||||
path.resolve(fileURLToPath(import.meta.url), "..", "package.json"),
|
||||
);
|
||||
const pkgVer = pJSON.version;
|
||||
const npmVER = await latestVersion(IC.PKG);
|
||||
if (pkgVer !== npmVER) {
|
||||
logCurrentVersion.warn(`Current Installed Version is v${pkgVer}`);
|
||||
logNpmVersion.warn(`Latest Published Version is v${npmVER}`);
|
||||
logCheck.warn("Please consider updating.");
|
||||
}
|
||||
logBuildDone.info(
|
||||
`Build Complete, Integration Now ready for Production. Astro-GhostCMS v${pkgVer}`,
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms",
|
||||
"description": "Astro GhostCMS integration to allow easier importing of GhostCMS Content",
|
||||
"version": "3.2.9",
|
||||
"version": "3.3.5",
|
||||
"homepage": "https://astro-ghostcms.xyz/",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
@ -36,36 +36,16 @@
|
|||
"url": "https://github.com/MatthiesenXYZ/astro-ghostcms/issues",
|
||||
"email": "issues@astro-ghostcms.xyz"
|
||||
},
|
||||
"main": "index.ts",
|
||||
"types": "types.d.ts",
|
||||
"files": [
|
||||
"src",
|
||||
".env.demo",
|
||||
"index.ts",
|
||||
"tsconfig.json",
|
||||
"types.d.ts"
|
||||
"CHANGELOG.md",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"exports": {
|
||||
".": "./index.ts",
|
||||
"./api": {
|
||||
"types": "./src/api/index.ts",
|
||||
"default": "./src/api/index.ts"
|
||||
},
|
||||
"./api-core": "./src/api/content-api/index.ts",
|
||||
"./config": {
|
||||
"types": "./src/integrations/virtual.d.ts",
|
||||
"default": "./src/integrations/virtual-config.ts"
|
||||
},
|
||||
"./satoriOG": "./src/integrations/satori.ts",
|
||||
"./404.astro": "./src/default-routes/404/404.astro",
|
||||
"./rss.xml.ts": "./src/default-routes/rss.xml.ts",
|
||||
"./rss-style.xsl.ts": "./src/default-routes/rss-style.xsl.ts",
|
||||
"./open-graph/index.png.ts": "./src/default-routes/open-graph/index.png.ts",
|
||||
"./open-graph/authors.png.ts": "./src/default-routes/open-graph/authors.png.ts",
|
||||
"./open-graph/tags.png.ts": "./src/default-routes/open-graph/tags.png.ts",
|
||||
"./open-graph/[slug].png.ts": "./src/default-routes/open-graph/[slug].png.ts",
|
||||
"./open-graph/author/[slug].png.ts": "./src/default-routes/open-graph/author/[slug].png.ts",
|
||||
"./open-graph/tag/[slug].png.ts": "./src/default-routes/open-graph/tag/[slug].png.ts"
|
||||
".": "./src/index.ts",
|
||||
"./api": "./src/api/index.ts",
|
||||
"./satoriOG": "./src/integrations/satoriog/satori.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
|
@ -73,39 +53,32 @@
|
|||
"test:coverage": "vitest run --coverage",
|
||||
"test:ci": "vitest run --coverage.enabled --coverage.reporter='text-summary'"
|
||||
},
|
||||
"enginesStrict": {
|
||||
"node": ">=18.19.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": ">=4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.5.4",
|
||||
"@ts-ghost/core-api": "*",
|
||||
"@ts-ghost/tsconfig": "*",
|
||||
"@matthiesenxyz/astro-ghostcms-theme-default": "*",
|
||||
"@matthiesenxyz/astro-ghostcms-catppuccin": "*",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/node": "^20.11.19",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.1",
|
||||
"@typescript-eslint/parser": "^7.0.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-astro": "^0.31.4",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-astro": "^0.13.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vitest": "^1.3.0",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/node": "^20.11.28",
|
||||
"vitest": "^1.4.0",
|
||||
"vitest-fetch-mock": "^0.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matthiesenxyz/astro-ghostcms-theme-default": "^0.1.13",
|
||||
"@astrojs/rss": "^4.0.5",
|
||||
"@astrojs/sitemap": "^3.0.5",
|
||||
"@astrojs/sitemap": "^3.1.1",
|
||||
"@matthiesenxyz/astro-ghostcms-theme-default": "^0.1.20",
|
||||
"@resvg/resvg-js": "^2.6.0",
|
||||
"@ts-ghost/core-api": "^5.1.2",
|
||||
"astro": "^4.4.0",
|
||||
"@ts-ghost/core-api": "^6.0.0",
|
||||
"@ts-ghost/content-api": "^4.0.12",
|
||||
"astro-integration-kit": "^0.6.0",
|
||||
"astro-robots-txt": "^1.0.0",
|
||||
"fs-extra": "^11.1.0",
|
||||
"package-json": "9.0.0",
|
||||
"satori": "^0.10.11",
|
||||
"fs-extra": "^11.2.0",
|
||||
"package-json": "^10.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"satori": "^0.10.13",
|
||||
"satori-html": "^0.3.2",
|
||||
"vite": "^5.1.3",
|
||||
"vite-tsconfig-paths": "^4.2.2",
|
||||
"zod": "^3.22.4"
|
||||
"vite": "^5.1.6"
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
import {
|
||||
APIComposer,
|
||||
BasicFetcher,
|
||||
HTTPClient,
|
||||
contentAPICredentialsSchema,
|
||||
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 default class TS_API<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,8 +0,0 @@
|
|||
export { default as TS_API } from "./content-api";
|
||||
export * from "./schemas";
|
||||
|
||||
export type {
|
||||
InferFetcherDataShape,
|
||||
InferResponseDataShape,
|
||||
BrowseParams,
|
||||
} from "@ts-ghost/core-api";
|
|
@ -1 +0,0 @@
|
|||
export * from "./authors";
|
|
@ -1 +0,0 @@
|
|||
export * from "./socials";
|
|
@ -1 +0,0 @@
|
|||
export * from "./pages";
|
|
@ -1 +0,0 @@
|
|||
export * from "./posts";
|
|
@ -1 +0,0 @@
|
|||
export * from "./settings";
|
|
@ -1 +0,0 @@
|
|||
export * from "./tags";
|
|
@ -1 +0,0 @@
|
|||
export * from "./tiers";
|
|
@ -1,11 +1,15 @@
|
|||
import { assert, beforeEach, describe, expect, test } from "vitest";
|
||||
|
||||
import TS_API from "./content-api";
|
||||
import { TSGhostContentAPI } from "@ts-ghost/content-api";
|
||||
|
||||
describe("content-api", () => {
|
||||
let api: TS_API;
|
||||
let api: TSGhostContentAPI;
|
||||
beforeEach(() => {
|
||||
api = new TS_API("https://ghost.org", "59d4bf56c73c04a18c867dc3ba", "v5.0");
|
||||
api = new TSGhostContentAPI(
|
||||
"https://ghost.org",
|
||||
"59d4bf56c73c04a18c867dc3ba",
|
||||
"v5.0",
|
||||
);
|
||||
});
|
||||
|
||||
test("content-api", () => {
|
||||
|
@ -14,21 +18,25 @@ describe("content-api", () => {
|
|||
|
||||
test("content-api shouldn't instantiate with an incorrect url", () => {
|
||||
assert.throws(() => {
|
||||
const api = new TS_API("ghost.org", "59d4bf56c73c04a18c867dc3ba", "v5.0");
|
||||
const api = new TSGhostContentAPI(
|
||||
"ghost.org",
|
||||
"59d4bf56c73c04a18c867dc3ba",
|
||||
"v5.0",
|
||||
);
|
||||
api.settings;
|
||||
});
|
||||
});
|
||||
|
||||
test("content-api shouldn't instantiate with an incorrect key", () => {
|
||||
assert.throws(() => {
|
||||
const api = new TS_API("https://ghost.org", "a", "v5.0");
|
||||
const api = new TSGhostContentAPI("https://ghost.org", "a", "v5.0");
|
||||
api.settings;
|
||||
});
|
||||
});
|
||||
|
||||
test("content-api shouldn't instantiate with an incorrect version", () => {
|
||||
assert.throws(() => {
|
||||
const api = new TS_API(
|
||||
const api = new TSGhostContentAPI(
|
||||
"https://ghost.org",
|
||||
"1efedd9db174adee2d23d982:4b74dca0219bad629852191af326a45037346c2231240e0f7aec1f9371cc14e8",
|
||||
// @ts-expect-error
|
|
@ -1,23 +1,24 @@
|
|||
import { TS_API } from "./content-api";
|
||||
import type { Page, Post } from "./content-api/schemas";
|
||||
import { TSGhostContentAPI } from "@ts-ghost/content-api";
|
||||
import type { Page, Post, Tag } from "../schemas/api";
|
||||
|
||||
// LOAD ENVIRONMENT VARIABLES
|
||||
import { loadEnv } from "vite";
|
||||
|
||||
import config from "../integrations/virtual-config";
|
||||
|
||||
const CONF_URL = config.ghostURL;
|
||||
|
||||
const { CONTENT_API_KEY, CONTENT_API_URL } = loadEnv(
|
||||
"all",
|
||||
process.cwd(),
|
||||
"CONTENT_",
|
||||
);
|
||||
|
||||
const ghostApiKey = CONTENT_API_KEY;
|
||||
const ghostUrl = CONF_URL ? CONF_URL : CONTENT_API_URL;
|
||||
// LOAD CONFIG
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
const CONF_URL = config.ghostURL;
|
||||
|
||||
// SETUP GHOST API
|
||||
const ghostApiKey = CONTENT_API_KEY || "";
|
||||
const ghostUrl = CONF_URL || CONTENT_API_URL || "";
|
||||
const version = "v5.0";
|
||||
const api = new TS_API(ghostUrl, ghostApiKey, version);
|
||||
const api = new TSGhostContentAPI(ghostUrl, ghostApiKey, version);
|
||||
|
||||
export const getAllAuthors = async () => {
|
||||
const results = await api.authors
|
||||
|
@ -93,17 +94,20 @@ export const getSettings = async () => {
|
|||
};
|
||||
|
||||
export const getAllTags = async () => {
|
||||
const results = await api.tags
|
||||
.browse()
|
||||
const tags: Tag[] = [];
|
||||
let cursor = await api.tags
|
||||
.browse({
|
||||
limit: 'all'
|
||||
})
|
||||
.include({ "count.posts": true })
|
||||
.fetch();
|
||||
if (!results.success) {
|
||||
throw new Error(results.errors.map((e) => e.message).join(", "));
|
||||
.paginate();
|
||||
|
||||
if (cursor.current.success) tags.push(...cursor.current.data);
|
||||
while (cursor.next) {
|
||||
cursor = await cursor.next.paginate();
|
||||
if (cursor.current.success) tags.push(...cursor.current.data);
|
||||
}
|
||||
return {
|
||||
tags: results.data,
|
||||
meta: results.meta,
|
||||
};
|
||||
return tags;
|
||||
};
|
||||
|
||||
export const getFeaturedPosts = async () => {
|
|
@ -1,3 +1,3 @@
|
|||
export * from "./api-functions";
|
||||
export * from "./content-api/schemas";
|
||||
export * from "./ghostAPI";
|
||||
export * from "./invariant";
|
||||
export * from "../schemas/api/index";
|
||||
|
|
|
@ -20,7 +20,6 @@ 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.
|
||||
*/
|
||||
const tinyinvariant = "merged";
|
||||
const isProduction: boolean = process.env.NODE_ENV === "production";
|
||||
const prefix: string = "Invariant failed";
|
||||
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
import fse from "fs-extra";
|
||||
import { createResolver, defineIntegration } from "astro-integration-kit";
|
||||
import { corePlugins } from "astro-integration-kit/plugins";
|
||||
import { AstroError } from "astro/errors";
|
||||
import type { AstroIntegration } from "astro";
|
||||
import c from "picocolors";
|
||||
import { loadEnv } from "vite";
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
import robotsTxt from "astro-robots-txt";
|
||||
|
||||
// Internal Imports
|
||||
import { GhostUserConfigSchema } from "./schemas/userconfig";
|
||||
import ghostRSS from "./integrations/rssfeed";
|
||||
import ghostOGImages from "./integrations/satoriog";
|
||||
import ghostThemeProvider from "./integrations/themeprovider";
|
||||
import latestVersion from "./utils/latestVersion";
|
||||
|
||||
// Load environment variables
|
||||
const ENV = loadEnv("all", process.cwd(), "CONTENT_API");
|
||||
|
||||
/** Astro-GhostCMS Integration
|
||||
* @description This integration allows you to use GhostCMS as a headless CMS for your Astro project
|
||||
* @see https://astro-ghostcms.xyz for the most up-to-date documentation!
|
||||
*/
|
||||
export default defineIntegration({
|
||||
name: "@matthiesenxyz/astro-ghostcms",
|
||||
optionsSchema: GhostUserConfigSchema,
|
||||
plugins: [...corePlugins],
|
||||
setup({ options, name }) {
|
||||
const { resolve } = createResolver(import.meta.url);
|
||||
|
||||
return {
|
||||
"astro:config:setup": ({
|
||||
watchIntegration,
|
||||
hasIntegration,
|
||||
addIntegration,
|
||||
addVirtualImports,
|
||||
injectRoute,
|
||||
logger,
|
||||
}) => {
|
||||
// Set up verbose logging
|
||||
const verbose = options.verbose;
|
||||
|
||||
// Configure Loggers
|
||||
const GhostLogger = logger.fork(c.bold(c.blue("👻 Astro-GhostCMS")));
|
||||
|
||||
const loggerTagged = (message: string) => {
|
||||
return logger.fork(`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(message)}`)
|
||||
}
|
||||
|
||||
// Configure ENV Logger
|
||||
const GhostENVLogger = loggerTagged("ENV Check");
|
||||
|
||||
// Configure Integration Loggers & verbose logging
|
||||
const GhostIntegrationLogger = loggerTagged("Integrations");
|
||||
|
||||
// Configure Route Logger & verbose logging
|
||||
const GhostRouteLogger = loggerTagged("Router");
|
||||
|
||||
// Log Info Helper
|
||||
const intLogInfo = (message:string) => {
|
||||
if (verbose) {
|
||||
GhostIntegrationLogger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
// Log Route Info Helper
|
||||
const routeLogInfo = (message:string) => {
|
||||
if (verbose) {
|
||||
GhostRouteLogger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
// Local Integration Helper
|
||||
const localIntegration = (enabled: boolean, name: string, integration: AstroIntegration) => {
|
||||
if (enabled) {
|
||||
addIntegration(integration);
|
||||
} else {
|
||||
intLogInfo(c.gray(`${name} integration is disabled`));
|
||||
}
|
||||
}
|
||||
|
||||
// Check External Integration Helper
|
||||
const checkIntegration = (name: string, integration: AstroIntegration) => {
|
||||
if (!hasIntegration(name)) {
|
||||
intLogInfo(c.bold(c.magenta(`Adding ${c.blue(name)} integration`)));
|
||||
addIntegration(integration);
|
||||
} else {
|
||||
intLogInfo(c.gray(`${name} integration already exists, skipping...`));
|
||||
}
|
||||
}
|
||||
|
||||
// Inject Route Helper
|
||||
const routeHelper = (routename: string, enabled: boolean, pattern: string, entrypoint: string) => {
|
||||
if (enabled) {
|
||||
routeLogInfo(c.bold(c.cyan(`Setting up ${routename} route`)));
|
||||
injectRoute({
|
||||
pattern: pattern,
|
||||
entrypoint: resolve(`./routes${entrypoint}`),
|
||||
prerender: true,
|
||||
});
|
||||
} else {
|
||||
routeLogInfo(c.gray(`${routename} route is disabled, Skipping...`));
|
||||
}
|
||||
}
|
||||
|
||||
// Setup Watch Integration for Hot Reload during DEV
|
||||
watchIntegration(resolve());
|
||||
GhostLogger.info("Initializing @matthiesenxyz/astro-ghostcms...");
|
||||
|
||||
|
||||
// Check for GhostCMS environment variables
|
||||
GhostENVLogger.info(
|
||||
c.bold(
|
||||
c.yellow(
|
||||
"Checking for GhostCMS environment variables & user configuration",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Check for GhostCMS API Key
|
||||
if (ENV.CONTENT_API_KEY === undefined) {
|
||||
GhostENVLogger.error(
|
||||
c.bgRed(
|
||||
c.bold(
|
||||
c.white("CONTENT_API_KEY is not set in environment variables"),
|
||||
),
|
||||
),
|
||||
);
|
||||
throw new AstroError(
|
||||
`${name} CONTENT_API_KEY is not set in environment variables`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check for GhostCMS URL
|
||||
if (options.ghostURL === undefined) {
|
||||
GhostENVLogger.warn(
|
||||
c.bgYellow(
|
||||
c.bold(
|
||||
c.black(
|
||||
"ghostURL is not set in user configuration falling back to environment variable",
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (ENV.CONTENT_API_URL === undefined) {
|
||||
GhostENVLogger.error(
|
||||
c.bgRed(
|
||||
c.bold(
|
||||
c.white(
|
||||
"CONTENT_API_URL is not set in environment variables",
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
throw new AstroError(
|
||||
`${name} CONTENT_API_URL is not set in environment variables`,
|
||||
);
|
||||
}
|
||||
}
|
||||
GhostENVLogger.info(
|
||||
c.bold(c.green("GhostCMS environment variables are set")),
|
||||
);
|
||||
|
||||
// Set up Astro-GhostCMS Integrations
|
||||
GhostIntegrationLogger.info(
|
||||
c.bold(c.magenta("Configuring Enabled Integrations")),
|
||||
);
|
||||
|
||||
// Setup GhostCMS Theme Provider
|
||||
localIntegration(
|
||||
!options.ThemeProvider.disableThemeProvider,
|
||||
"Theme Provider",
|
||||
ghostThemeProvider({
|
||||
theme: options.ThemeProvider.theme,
|
||||
verbose,
|
||||
})
|
||||
);
|
||||
|
||||
// Setup GhostCMS OG Image Provider
|
||||
localIntegration(
|
||||
options.enableOGImages,
|
||||
"Satori OG Images",
|
||||
ghostOGImages({ verbose })
|
||||
);
|
||||
|
||||
// Setup GhostCMS RSS Feed Provider
|
||||
localIntegration(
|
||||
options.enableRSSFeed,
|
||||
"RSS Feed",
|
||||
ghostRSS({ verbose })
|
||||
);
|
||||
|
||||
// Setup @astrojs/sitemap Integration
|
||||
checkIntegration(
|
||||
"@astrojs/sitemap",
|
||||
sitemap(options.Integrations.sitemap)
|
||||
);
|
||||
|
||||
// Setup astro-robots-txt Integration
|
||||
checkIntegration(
|
||||
"astro-robots-txt",
|
||||
robotsTxt(options.Integrations.robotsTxt)
|
||||
);
|
||||
|
||||
// Setup Default 404 Page
|
||||
routeHelper(
|
||||
"Default 404 Page",
|
||||
!options.disableDefault404,
|
||||
"/404",
|
||||
"/404.astro"
|
||||
);
|
||||
|
||||
// Add virtual imports for user configuration
|
||||
addVirtualImports({
|
||||
"virtual:@matthiesenxyz/astro-ghostcms/config": `export default ${JSON.stringify(
|
||||
options,
|
||||
)}`,
|
||||
});
|
||||
|
||||
},
|
||||
"astro:config:done": ({ logger }) => {
|
||||
// Configure Loggers
|
||||
const GhostLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.green(
|
||||
"CONFIG",
|
||||
)}`,
|
||||
);
|
||||
|
||||
// Log Configuration Complete
|
||||
GhostLogger.info(
|
||||
c.bold(c.green("Integration Setup & Configuration Complete")),
|
||||
);
|
||||
},
|
||||
"astro:server:start": async ({ logger }) => {
|
||||
const loggerTagged = (message: string) => {
|
||||
return logger.fork(`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.green(message)}`)
|
||||
}
|
||||
// Configure Loggers
|
||||
const GhostLogger = loggerTagged("DEV");
|
||||
|
||||
const GhostUpdateLogger = loggerTagged("VERSION CHECK");
|
||||
|
||||
// Start the DEV server
|
||||
GhostLogger.info(
|
||||
c.bold(c.magenta("Running Astro-GhostCMS in Deveopment mode 🚀")),
|
||||
);
|
||||
|
||||
// Check for updates
|
||||
|
||||
// Get the latest version of Astro-GhostCMS
|
||||
const currentNPMVersion = await latestVersion(
|
||||
"@matthiesenxyz/astro-ghostcms",
|
||||
);
|
||||
|
||||
// Get the local version of Astro-GhostCMS
|
||||
const packageJson = await fse.readJson(resolve("../package.json"));
|
||||
const localVersion = packageJson.version;
|
||||
|
||||
// Log the version check
|
||||
if (currentNPMVersion !== localVersion) {
|
||||
GhostUpdateLogger.warn(
|
||||
`\n${c.bgYellow(
|
||||
c.bold(
|
||||
c.black(
|
||||
" There is a new version of Astro-GhostCMS available! ",
|
||||
),
|
||||
),
|
||||
)}\n${
|
||||
c.bold(c.white(" Current Installed Version: ")) +
|
||||
c.bold(c.red(`${localVersion} `))
|
||||
} \n ${c.bold(c.white("New Available Version: "))} ${c.green(
|
||||
currentNPMVersion,
|
||||
)} \n ${c.bold(
|
||||
c.white(
|
||||
"Please consider updating to the latest version by running: ",
|
||||
),
|
||||
)} ${c.bold(
|
||||
c.green("npm i @matthiesenxyz/astro-ghostcms@latest"),
|
||||
)} \n`,
|
||||
);
|
||||
} else {
|
||||
GhostUpdateLogger.info(
|
||||
c.bold(c.green(`Astro-GhostCMS is up to date! v${localVersion}`)),
|
||||
);
|
||||
}
|
||||
},
|
||||
"astro:build:done": ({ logger }) => {
|
||||
// Configure Loggers
|
||||
const GhostLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.bold(
|
||||
c.green("BUILD"),
|
||||
)}`,
|
||||
);
|
||||
|
||||
// Log Build Complete
|
||||
GhostLogger.info(
|
||||
c.bold(c.magenta("Running Astro-GhostCMS in Production mode 🚀")),
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
import astroGhostCMS from "./astro-ghostcms";
|
||||
|
||||
export default astroGhostCMS;
|
|
@ -1,28 +0,0 @@
|
|||
import robotsTxt, { type RobotsTxtOptions } from "astro-robots-txt";
|
||||
import type { UserConfig } from "../schemas";
|
||||
|
||||
export function getRobotsTxtConfig(
|
||||
opts: UserConfig["robotstxt"],
|
||||
): RobotsTxtOptions {
|
||||
const robotsConfig: RobotsTxtOptions = {};
|
||||
if (opts?.host) {
|
||||
robotsConfig.host = opts.host;
|
||||
}
|
||||
if (opts?.policy) {
|
||||
robotsConfig.policy = opts.policy;
|
||||
}
|
||||
if (opts?.sitemap) {
|
||||
robotsConfig.sitemap = opts.sitemap;
|
||||
}
|
||||
if (opts?.sitemapBaseFileName) {
|
||||
robotsConfig.sitemapBaseFileName = opts.sitemapBaseFileName;
|
||||
}
|
||||
return robotsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapped version of the `astro-robots-txt` integration for GhostCMS.
|
||||
*/
|
||||
export default function ghostRobots(opts: UserConfig["robotstxt"]) {
|
||||
return robotsTxt(getRobotsTxtConfig(opts));
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { createResolver, defineIntegration } from "astro-integration-kit";
|
||||
import { corePlugins } from "astro-integration-kit/plugins";
|
||||
import { z } from "astro/zod";
|
||||
import c from "picocolors";
|
||||
|
||||
export default defineIntegration({
|
||||
name: "@matthiesenxyz/astro-ghostcms-rss",
|
||||
optionsSchema: z.object({
|
||||
verbose: z.coerce.boolean().optional(),
|
||||
}),
|
||||
plugins: [...corePlugins],
|
||||
setup({ options }) {
|
||||
const { resolve } = createResolver(import.meta.url);
|
||||
|
||||
return {
|
||||
"astro:config:setup": ({ watchIntegration, injectRoute, logger }) => {
|
||||
watchIntegration(resolve());
|
||||
const RSSLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(
|
||||
"RSSGenerator",
|
||||
)}`,
|
||||
);
|
||||
|
||||
RSSLogger.info(c.bold(c.magenta("RSS Feed Enabled. Setting up...")));
|
||||
|
||||
injectRoute({
|
||||
pattern: "/rss-style.xsl",
|
||||
entrypoint: resolve("./routes/rss-style.xsl.ts"),
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/rss.xml",
|
||||
entrypoint: resolve("./routes/rss.xml.ts"),
|
||||
});
|
||||
},
|
||||
"astro:config:done": ({ logger }) => {
|
||||
const RSSLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(
|
||||
"RSSGenerator",
|
||||
)}`,
|
||||
);
|
||||
const verboseLogsInfo = (message:string) => {
|
||||
if (options.verbose) {
|
||||
RSSLogger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
verboseLogsInfo(c.bold(c.green("RSS Feed Setup Complete")));
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
import astroGhostcmsRSS from "./astro-ghostcms-rss";
|
||||
|
||||
export default astroGhostcmsRSS;
|
|
@ -1,6 +1,6 @@
|
|||
import rss from "@astrojs/rss";
|
||||
import type { APIContext } from "astro";
|
||||
import { getAllPosts, getSettings, invariant } from "../api";
|
||||
import { getAllPosts, getSettings, invariant } from "../../../api";
|
||||
|
||||
const posts = await getAllPosts();
|
||||
const settings = await getSettings();
|
|
@ -0,0 +1,84 @@
|
|||
import { createResolver, defineIntegration } from "astro-integration-kit";
|
||||
import { corePlugins } from "astro-integration-kit/plugins";
|
||||
import { z } from "astro/zod";
|
||||
import c from "picocolors";
|
||||
|
||||
export default defineIntegration({
|
||||
name: "@matthiesenxyz/astro-ghostcms-satoriog",
|
||||
optionsSchema: z.object({
|
||||
verbose: z.coerce.boolean().optional(),
|
||||
}),
|
||||
plugins: [...corePlugins],
|
||||
setup({ options }) {
|
||||
const { resolve } = createResolver(import.meta.url);
|
||||
|
||||
return {
|
||||
"astro:config:setup": ({
|
||||
watchIntegration,
|
||||
updateConfig,
|
||||
injectRoute,
|
||||
logger,
|
||||
}) => {
|
||||
watchIntegration(resolve());
|
||||
|
||||
const SatoriLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(
|
||||
"SatoriOG",
|
||||
)}`,
|
||||
);
|
||||
|
||||
SatoriLogger.info(
|
||||
c.bold(c.magenta("OG Image Integration Enabled. Setting up...")),
|
||||
);
|
||||
|
||||
injectRoute({
|
||||
pattern: "/open-graph/[slug].png",
|
||||
entrypoint: resolve("./routes/[slug].png.ts"),
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/open-graph/index.png",
|
||||
entrypoint: resolve("./routes/index.png.ts"),
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/open-graph/authors.png",
|
||||
entrypoint: resolve("./routes/authors.png.ts"),
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/open-graph/author/[slug].png",
|
||||
entrypoint: resolve("./routes/author/[slug].png.ts"),
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/open-graph/tags.png",
|
||||
entrypoint: resolve("./routes/tags.png.ts"),
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/open-graph/tag/[slug].png",
|
||||
entrypoint: resolve("./routes/tag/[slug].png.ts"),
|
||||
});
|
||||
|
||||
updateConfig({
|
||||
vite: { optimizeDeps: { exclude: ["@resvg/resvg-js"] } },
|
||||
});
|
||||
},
|
||||
"astro:config:done": ({ logger }) => {
|
||||
const SatoriLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(
|
||||
"SatoriOG",
|
||||
)}`,
|
||||
);
|
||||
const verboseLogsInfo = (message:string) => {
|
||||
if (options.verbose) {
|
||||
SatoriLogger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
verboseLogsInfo(c.bold(c.green("OG Image Integration Setup Complete")));
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
import astroGhostcmsSatoriog from "./astro-ghostcms-satoriog";
|
||||
|
||||
export default astroGhostcmsSatoriog;
|
|
@ -5,13 +5,8 @@ import type {
|
|||
InferGetStaticPropsType,
|
||||
} from "astro";
|
||||
import { html } from "satori-html";
|
||||
import {
|
||||
getAllPages,
|
||||
getAllPosts,
|
||||
getSettings,
|
||||
invariant,
|
||||
} from "../../api/index.js";
|
||||
import satoriOG from "../../integrations/satori.js";
|
||||
import { getAllPages, getAllPosts, getSettings, invariant } from "../../../api";
|
||||
import satoriOG from "../satori";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
|
@ -10,8 +10,8 @@ import {
|
|||
getAllPosts,
|
||||
getSettings,
|
||||
invariant,
|
||||
} from "../../../api/index.js";
|
||||
import satoriOG from "../../../integrations/satori.js";
|
||||
} from "../../../../api";
|
||||
import satoriOG from "../../satori";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
|
@ -5,13 +5,8 @@ import type {
|
|||
InferGetStaticPropsType,
|
||||
} from "astro";
|
||||
import { html } from "satori-html";
|
||||
import {
|
||||
getAllPages,
|
||||
getAllPosts,
|
||||
getSettings,
|
||||
invariant,
|
||||
} from "../../api/index.js";
|
||||
import satoriOG from "../../integrations/satori.js";
|
||||
import { getAllPages, getAllPosts, getSettings, invariant } from "../../../api";
|
||||
import satoriOG from "../satori";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
|
@ -5,13 +5,8 @@ import type {
|
|||
InferGetStaticPropsType,
|
||||
} from "astro";
|
||||
import { html } from "satori-html";
|
||||
import {
|
||||
getAllPages,
|
||||
getAllPosts,
|
||||
getSettings,
|
||||
invariant,
|
||||
} from "../../api/index.js";
|
||||
import satoriOG from "../../integrations/satori.js";
|
||||
import { getAllPages, getAllPosts, getSettings, invariant } from "../../../api";
|
||||
import satoriOG from "../satori";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
|
@ -10,13 +10,13 @@ import {
|
|||
getAllTags,
|
||||
getSettings,
|
||||
invariant,
|
||||
} from "../../../api/index.js";
|
||||
import satoriOG from "../../../integrations/satori.js";
|
||||
} from "../../../../api";
|
||||
import satoriOG from "../../satori";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const posts = await getAllPosts();
|
||||
const { tags } = await getAllTags();
|
||||
const tags = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
|
|
@ -5,13 +5,8 @@ import type {
|
|||
InferGetStaticPropsType,
|
||||
} from "astro";
|
||||
import { html } from "satori-html";
|
||||
import {
|
||||
getAllPages,
|
||||
getAllPosts,
|
||||
getSettings,
|
||||
invariant,
|
||||
} from "../../api/index.js";
|
||||
import satoriOG from "../../integrations/satori.js";
|
||||
import { getAllPages, getAllPosts, getSettings, invariant } from "../../../api";
|
||||
import satoriOG from "../satori";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
|
@ -5,7 +5,7 @@ import type {
|
|||
ToImageOptions,
|
||||
ToResponseOptions,
|
||||
ToSvgOptions,
|
||||
} from "../../types.js";
|
||||
} from "./types";
|
||||
|
||||
const satoriOG = ({ width, height, template }: SatoriAstroOGOptions) => {
|
||||
return {
|
|
@ -1,24 +1,5 @@
|
|||
import type { Resvg } from "@resvg/resvg-js";
|
||||
import type satori from "satori";
|
||||
|
||||
export type { UserConfig, GhostUserConfig } from "./src/schemas";
|
||||
|
||||
export type {
|
||||
Author,
|
||||
AuthorsIncludeSchema,
|
||||
Page,
|
||||
PagesIncludeSchema,
|
||||
Post,
|
||||
PostsIncludeSchema,
|
||||
Settings,
|
||||
Tag,
|
||||
TagsIncludeSchema,
|
||||
Tier,
|
||||
TiersIncludeSchema,
|
||||
} from "./src/api/index.ts";
|
||||
|
||||
export type { ContentAPICredentials, APIVersions } from "@ts-ghost/core-api";
|
||||
|
||||
type SatoriParameters = Parameters<typeof satori>;
|
||||
type SatoriOptions = SatoriParameters[1];
|
||||
type ResvgOptions = NonNullable<ConstructorParameters<typeof Resvg>[1]>;
|
|
@ -1,38 +0,0 @@
|
|||
import sitemap, { type SitemapOptions } from "@astrojs/sitemap";
|
||||
import type { UserConfig } from "../schemas";
|
||||
|
||||
export function getSitemapConfig(opts: UserConfig["sitemap"]): SitemapOptions {
|
||||
const sitemapConfig: SitemapOptions = {};
|
||||
if (opts?.filter) {
|
||||
sitemapConfig.filter = opts.filter;
|
||||
}
|
||||
if (opts?.changefreq) {
|
||||
sitemapConfig.changefreq = opts.changefreq;
|
||||
}
|
||||
if (opts?.entryLimit) {
|
||||
sitemapConfig.entryLimit = opts.entryLimit;
|
||||
}
|
||||
if (opts?.customPages) {
|
||||
sitemapConfig.customPages = opts.customPages;
|
||||
}
|
||||
if (opts?.i18n) {
|
||||
sitemapConfig.i18n = opts.i18n;
|
||||
}
|
||||
if (opts?.lastmod) {
|
||||
sitemapConfig.lastmod = opts.lastmod;
|
||||
}
|
||||
if (opts?.priority) {
|
||||
sitemapConfig.priority = opts.priority;
|
||||
}
|
||||
if (opts?.serialize) {
|
||||
sitemapConfig.serialize = opts.serialize;
|
||||
}
|
||||
return sitemapConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapped version of the `@astrojs/sitemap` integration for GhostCMS.
|
||||
*/
|
||||
export default function ghostSitemap(opts: UserConfig["sitemap"]) {
|
||||
return sitemap(getSitemapConfig(opts));
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
import { createResolver, defineIntegration } from "astro-integration-kit";
|
||||
import { corePlugins } from "astro-integration-kit/plugins";
|
||||
import { z } from "astro/zod";
|
||||
import c from "picocolors";
|
||||
|
||||
export default defineIntegration({
|
||||
name: "@matthiesenxyz/astro-ghostcms-themeprovider",
|
||||
optionsSchema: z.object({
|
||||
theme: z.string(),
|
||||
verbose: z.coerce.boolean().optional(),
|
||||
}),
|
||||
plugins: [...corePlugins],
|
||||
setup({ options }) {
|
||||
const { resolve } = createResolver(import.meta.url);
|
||||
|
||||
const DEFAULT_THEME = "@matthiesenxyz/astro-ghostcms-theme-default";
|
||||
|
||||
return {
|
||||
"astro:config:setup": ({ watchIntegration, injectRoute, logger }) => {
|
||||
watchIntegration(resolve());
|
||||
|
||||
const themeLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(
|
||||
"Theme Provider",
|
||||
)}`,
|
||||
);
|
||||
const verboseLogsInfo = (message:string) => {
|
||||
if (options.verbose) {
|
||||
themeLogger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
themeLogger.info(
|
||||
c.bold(c.magenta("Theme Provider enabled. Setting up...")),
|
||||
);
|
||||
|
||||
|
||||
if (options.theme === DEFAULT_THEME) {
|
||||
verboseLogsInfo(
|
||||
c.blue("No theme is set, injecting default theme"),
|
||||
);
|
||||
} else {
|
||||
verboseLogsInfo(`${c.bold(c.cyan("Injecting Theme:"))} ${c.bold(c.underline(c.magenta(options.theme)))}`);
|
||||
}
|
||||
|
||||
|
||||
injectRoute({
|
||||
pattern: "/",
|
||||
entrypoint: `${options.theme}/index.astro`,
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/[slug]",
|
||||
entrypoint: `${options.theme}/[slug].astro`,
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/tags",
|
||||
entrypoint: `${options.theme}/tags.astro`,
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/authors",
|
||||
entrypoint: `${options.theme}/authors.astro`,
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/tag/[slug]",
|
||||
entrypoint: `${options.theme}/tag/[slug].astro`,
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/author/[slug]",
|
||||
entrypoint: `${options.theme}/author/[slug].astro`,
|
||||
});
|
||||
|
||||
injectRoute({
|
||||
pattern: "/archives/[...page]",
|
||||
entrypoint: `${options.theme}/archives/[...page].astro`,
|
||||
});
|
||||
},
|
||||
"astro:config:done": ({ logger }) => {
|
||||
const themeLogger = logger.fork(
|
||||
`${c.bold(c.blue("👻 Astro-GhostCMS"))}${c.gray("/")}${c.blue(
|
||||
"Theme Provider",
|
||||
)}`,
|
||||
);
|
||||
const verboseLogsInfo = (message:string) => {
|
||||
if (options.verbose) {
|
||||
themeLogger.info(message);
|
||||
}
|
||||
};
|
||||
|
||||
verboseLogsInfo(c.bold(c.green("Provider Setup Complete")));
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
import astroGhostcmsThemeProvider from "./astro-ghostcms-themeprovider";
|
||||
|
||||
export default astroGhostcmsThemeProvider;
|
|
@ -1,6 +0,0 @@
|
|||
import type { GhostUserConfig } from "../schemas";
|
||||
import config from "virtual:@matthiesenxyz/astro-ghostcms/config";
|
||||
|
||||
const UserConfig = config as GhostUserConfig;
|
||||
|
||||
export default UserConfig;
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import './404.css';
|
||||
import { getSettings, invariant } from '../../api';
|
||||
import { getSettings, invariant } from '../api';
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings not found");
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import createFetchMock from "vitest-fetch-mock";
|
||||
|
||||
import TS_API from "../../content-api";
|
||||
import { TSGhostContentAPI } from "@ts-ghost/content-api";
|
||||
|
||||
const fetchMocker = createFetchMock(vi);
|
||||
|
||||
|
@ -9,7 +9,7 @@ describe("authors api .browse() Args Type-safety", () => {
|
|||
const url = process.env.VITE_GHOST_URL || "https://my-ghost-blog.com";
|
||||
const key =
|
||||
process.env.VITE_GHOST_CONTENT_API_KEY || "59d4bf56c73c04a18c867dc3ba";
|
||||
const api = new TS_API(url, key, "v5.0");
|
||||
const api = new TSGhostContentAPI(url, key, "v5.0");
|
||||
test(".browse() params shouldnt accept invalid params", () => {
|
||||
// @ts-expect-error - shouldnt accept invalid params
|
||||
const browse = api.authors.browse({ pp: 2 });
|
||||
|
@ -95,10 +95,10 @@ describe("authors api .browse() Args Type-safety", () => {
|
|||
});
|
||||
|
||||
describe("authors resource mocked", () => {
|
||||
let api: TS_API;
|
||||
let api: TSGhostContentAPI;
|
||||
|
||||
beforeEach(() => {
|
||||
api = new TS_API(
|
||||
api = new TSGhostContentAPI(
|
||||
"https://my-ghost-blog.com",
|
||||
"59d4bf56c73c04a18c867dc3ba",
|
||||
"v5.0",
|
|
@ -1,7 +1,7 @@
|
|||
export * from "./authors";
|
||||
export * from "./helpers";
|
||||
export * from "./pages";
|
||||
export * from "./posts";
|
||||
export * from "./settings";
|
||||
export * from "./socials";
|
||||
export * from "./tags";
|
||||
export * from "./tiers";
|
|
@ -7,8 +7,8 @@ import {
|
|||
} from "@ts-ghost/core-api";
|
||||
import { z } from "astro/zod";
|
||||
|
||||
import { authorsSchema } from "../authors";
|
||||
import { tagsSchema } from "../tags";
|
||||
import { authorsSchema } from "./authors";
|
||||
import { tagsSchema } from "./tags";
|
||||
|
||||
const postsAuthorSchema = authorsSchema.extend({
|
||||
url: z.string().nullish(),
|
|
@ -1,14 +1,14 @@
|
|||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import TS_API from "../../content-api";
|
||||
import type { Post } from "./posts";
|
||||
import { TSGhostContentAPI } from "@ts-ghost/content-api";
|
||||
import type { Post } from "./index";
|
||||
|
||||
const url = process.env.VITE_GHOST_URL || "https://my-ghost-blog.com";
|
||||
const key =
|
||||
process.env.VITE_GHOST_CONTENT_API_KEY || "59d4bf56c73c04a18c867dc3ba";
|
||||
|
||||
describe("posts api .browse() Args Type-safety", () => {
|
||||
const api = new TS_API(url, key, "v5.0");
|
||||
const api = new TSGhostContentAPI(url, key, "v5.0");
|
||||
test(".browse() params shouldnt accept invalid params", () => {
|
||||
// @ts-expect-error - shouldnt accept invalid params
|
||||
const browse = api.posts.browse({ pp: 2 });
|
||||
|
@ -21,8 +21,7 @@ describe("posts api .browse() Args Type-safety", () => {
|
|||
foo: true,
|
||||
} satisfies { [k in keyof Post]?: true | undefined };
|
||||
|
||||
// biome-ignore lint/style/useConst: <explanation>
|
||||
let test = api.posts
|
||||
const test = api.posts
|
||||
.browse()
|
||||
// @ts-expect-error - shouldnt accept invalid params
|
||||
.fields(outputFields);
|
||||
|
@ -45,8 +44,7 @@ describe("posts api .browse() Args Type-safety", () => {
|
|||
title: true,
|
||||
} satisfies { [k in keyof Post]?: true | undefined };
|
||||
|
||||
// biome-ignore lint/style/useConst: <explanation>
|
||||
let test = api.posts.browse().fields(outputFields);
|
||||
const test = api.posts.browse().fields(outputFields);
|
||||
expect(test.getOutputFields()).toEqual(["slug", "title"]);
|
||||
|
||||
// @ts-expect-error - shouldnt accept invalid params
|
|
@ -7,8 +7,8 @@ import {
|
|||
} from "@ts-ghost/core-api";
|
||||
import { z } from "astro/zod";
|
||||
|
||||
import { authorsSchema } from "../authors";
|
||||
import { tagsSchema } from "../tags";
|
||||
import { authorsSchema } from "./authors";
|
||||
import { tagsSchema } from "./tags";
|
||||
|
||||
const postsAuthorSchema = authorsSchema.extend({
|
||||
url: z.string().nullish(),
|
|
@ -0,0 +1,39 @@
|
|||
import { beforeEach, describe, expect, test } from "vitest";
|
||||
|
||||
import { TSGhostContentAPI } from "@ts-ghost/content-api";
|
||||
|
||||
const url = process.env.VITE_GHOST_URL || "https://my-ghost-blog.com";
|
||||
const key =
|
||||
process.env.VITE_GHOST_CONTENT_API_KEY || "59d4bf56c73c04a18c867dc3ba";
|
||||
|
||||
describe("settings integration tests browse", () => {
|
||||
let api: TSGhostContentAPI;
|
||||
beforeEach(() => {
|
||||
api = new TSGhostContentAPI(url, key, "v5.0");
|
||||
});
|
||||
test("settings.fetch()", async () => {
|
||||
const result = await api.settings.fetch();
|
||||
expect(result).not.toBeUndefined();
|
||||
expect(result).not.toBeNull();
|
||||
if (!result.success) {
|
||||
expect(result.errors).toBeDefined();
|
||||
expect(result.errors).toHaveLength(1);
|
||||
} else {
|
||||
expect(result.data).toBeDefined();
|
||||
const settings = result.data;
|
||||
expect(settings).toBeDefined();
|
||||
expect(settings.title).toBe("Astro Starter");
|
||||
expect(settings.description).toBe("Thoughts, stories and ideas.");
|
||||
expect(settings.logo).toBeNull();
|
||||
expect(settings.cover_image).toBe(
|
||||
"https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
||||
);
|
||||
expect(settings.icon).toBeNull();
|
||||
expect(settings.lang).toBe("en");
|
||||
expect(settings.timezone).toBe("Etc/UTC");
|
||||
expect(settings.codeinjection_head).toBeNull();
|
||||
expect(settings.codeinjection_foot).toBeNull();
|
||||
expect(settings.members_support_address).toBe("noreply");
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
export * from "./robots";
|
||||
export * from "./sitemap";
|
||||
export * from "./userconfig";
|
|
@ -1,37 +0,0 @@
|
|||
import { z } from "astro/zod";
|
||||
|
||||
const RobotsPolicySchema = z.object({
|
||||
/** You must provide a name of the automatic client (search engine crawler).
|
||||
* Wildcards are allowed.
|
||||
*/
|
||||
userAgent: z.string(),
|
||||
/** Allowed paths for crawling */
|
||||
allow: z.string().optional(),
|
||||
/** Disallowed paths for crawling */
|
||||
disallow: z.string().optional(),
|
||||
/** Indicates that the page's URL contains parameters that should be ignored during crawling.
|
||||
* Maximum string length is limited to 500.
|
||||
*/
|
||||
cleanParam: z.string().optional(),
|
||||
/** Minimum interval (in secs) for the crawler to wait after loading one page, before starting other */
|
||||
crawlDelay: z.number().optional(),
|
||||
});
|
||||
|
||||
export const RobotsTxtSchema = z.object({
|
||||
/** @example host: true
|
||||
* // Automatically resolve using the site option from Astro config
|
||||
* @example host: 'example.com'
|
||||
*/
|
||||
host: z.string().optional(),
|
||||
/** @example sitemap: "https://example.com/sitemap-0.xml"
|
||||
* @example sitemap: ['https://example.com/sitemap-0.xml','https://example.com/sitemap-1.xml']
|
||||
* @example sitemap: false - If you want to get the robots.txt file without the Sitemap: ... entry, set the sitemap parameter to false.
|
||||
*/
|
||||
sitemap: z.union([z.string(), z.string().array(), z.boolean()]).optional(),
|
||||
/** astrojs/sitemap and astro-robots-txt integrations have the sitemap-index.xml as their primary output. That is why the default value of sitemapBaseFileName is set to sitemap-index.
|
||||
* @example sitemapBaseFileName: 'custom-sitemap'
|
||||
*/
|
||||
sitemapBaseFileName: z.string().optional(),
|
||||
/** SET POLICY RULES */
|
||||
policy: RobotsPolicySchema.array().optional(),
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
import { z } from "astro/zod";
|
||||
|
||||
const localeKeySchema = z.string().min(1);
|
||||
enum EnumChangefreq {
|
||||
DAILY = "daily",
|
||||
MONTHLY = "monthly",
|
||||
ALWAYS = "always",
|
||||
HOURLY = "hourly",
|
||||
WEEKLY = "weekly",
|
||||
YEARLY = "yearly",
|
||||
NEVER = "never",
|
||||
}
|
||||
export const SitemapSchema = z.object({
|
||||
filter: z.function().args(z.string()).returns(z.boolean()).optional(),
|
||||
customPages: z.string().url().array().optional(),
|
||||
i18n: z
|
||||
.object({
|
||||
defaultLocale: localeKeySchema,
|
||||
locales: z.record(
|
||||
localeKeySchema,
|
||||
z
|
||||
.string()
|
||||
.min(2)
|
||||
.regex(/^[a-zA-Z\-]+$/gm, {
|
||||
message: "Only English alphabet symbols and hyphen allowed",
|
||||
}),
|
||||
),
|
||||
})
|
||||
.refine((val) => !val || val.locales[val.defaultLocale], {
|
||||
message: "`defaultLocale` must exist in `locales` keys",
|
||||
})
|
||||
.optional(),
|
||||
entryLimit: z.number().nonnegative().optional(),
|
||||
serialize: z.function().args(z.any()).returns(z.any()).optional(),
|
||||
changefreq: z.nativeEnum(EnumChangefreq).optional(),
|
||||
lastmod: z.date().optional(),
|
||||
priority: z.number().min(0).max(1).optional(),
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue