Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/components/content/examples/ReleaseExample.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<GithubRelease v-slot="{ release }" :query="{ tag: 'v0.0.1' }">
{{ release.name }}
</GithubRelease>
</template>
37 changes: 36 additions & 1 deletion docs/content/3.components.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ This component is useful if you want to display last release of the repository.

::

::props{of="GithubContributors"}
::props{of="GithubLastRelease"}
::

::source-link
Expand All @@ -149,6 +149,41 @@ source: "packages/github/src/runtime/components/GithubLastRelease.ts"

---

## `<GithubRelease />`

This component is useful if you want to display release fetched by tag.

::code-group

::code-block{label="Preview"}
::div{class="max-h-[300px] pb-8"}
::release-example
::
::
::

```vue [Code]
<template>
<GithubRelease v-slot="{ release }" :query={ tag: 'v1.0.0'}>
<ProseH1>{{ release.name }}</ProseH1>
<ContentRenderer :value="release" />
</GithubRelease>
</template>
```

::

::props{of="GithubRelease"}
::

::source-link
---
source: "packages/github/src/runtime/components/GithubRelease.ts"
---
::

---

## `<GithubReleases />`

This component is useful if you want to display all the releases of the repository.
Expand Down
4 changes: 3 additions & 1 deletion docs/content/4.composables.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const {
fetchRepository,
// Fetch repository releases
fetchReleases,
// Fetch repository release by tag
fetchRelease,
// Fetch repository last release
fetchLastRelease,
// Fetch repository contributors
Expand All @@ -21,7 +23,7 @@ const {
fetchFileContributors,
// Fetch a readme file
fetchReadme
} = useDocus()
} = useGithub()
```

These helpers makes it easy to use the Github API with `useAsyncData`.
Expand Down
27 changes: 3 additions & 24 deletions docs/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
app: {
},
extends: [
'../node_modules/@nuxt-themes/docus'
],
Expand All @@ -16,28 +18,5 @@ export default defineNuxtConfig({
prefix: '',
global: true
}
],
tailwindcss: {
config: {
theme: {
extend: {
colors: {
primary: {
DEFAULT: '#4183C4',
50: '#CDDEF0',
100: '#BED4EB',
200: '#9EC0E1',
300: '#7FACD7',
400: '#6097CE',
500: '#4183C4',
600: '#31679C',
700: '#234B72',
800: '#162F47',
900: '#09121C'
}
}
}
}
}
}
]
})
2 changes: 1 addition & 1 deletion docs/theme.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineTheme } from '@nuxt-themes/kit'
import { defineTheme } from '@nuxt-themes/config'

export default defineTheme(
{
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@nuxt/test-utils": "^3.0.0-rc.6",
"@nuxtjs/eslint-config-typescript": "latest",
"eslint": "latest",
"nuxt": "npm:nuxt3@latest",
"nuxt": "3.0.0-rc.6",
"release-it": "^15.1.3",
"standard-version": "^9.5.0",
"vitest": "^0.18.1"
Expand Down
4 changes: 4 additions & 0 deletions playground/components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const nav = [
name: 'Releases',
path: '/releases'
},
{
name: 'Release by tag',
path: '/release'
},
{
name: 'Last Release',
path: '/last-release'
Expand Down
12 changes: 9 additions & 3 deletions playground/pages/last-release.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<script setup lang="ts">
const { owner, repo } = useRuntimeConfig().github
const qOwner = ref('nuxt-community')
const qRepo = ref('supabase-module')
</script>

<template>
<div>
<GithubLastRelease v-slot="{ release }">
Fetch last release from config: {{ owner }} / {{ repo }}
<GithubLastRelease v-slot="{ release, refresh }" :query="{ owner: qOwner, repo: qRepo }">
Fetch last release from query:
<input v-model="qOwner" style="margin-left: 1rem;" type="text"> /
<input v-model="qRepo" type="text">
<button style="margin-left: 1rem;" @click="refresh">
Search
</button>
<div v-if="release">
<ProseH2 :id="release.name || '#'">
Last Release: {{ release.name }}
Expand Down
44 changes: 44 additions & 0 deletions playground/pages/release.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<script setup lang="ts">
const qOwner = ref('nuxt-community')
const qRepo = ref('supabase-module')
const tag = ref('v0.1.18')
</script>

<template>
<div>
<GithubRelease v-slot="{ release, refresh }" :query="{ owner: qOwner, repo: qRepo, tag }">
Fetch last release from query:
<div>
Owner: <input v-model="qOwner" type="text">
</div>
<div>
Repo: <input v-model="qRepo" type="text">
</div>
<div>
Tag: <input v-model="tag" type="text">
</div>
<button @click="refresh">
Search
</button>
<div v-if="release">
<ProseH2 :id="release.name || '#'">
Release: {{ release.name }}
</ProseH2>

<p>Version: {{ release.v }}</p>

<p>URL: {{ release.url }}</p>

<p>Zipball: {{ release.zipall }}</p>

<p>Tarball: {{ release.tarball }}</p>

<p>Prerelease: {{ release.prerelease }}</p>

<p>Reactions: {{ release.reactions }}</p>

<p>Author: {{ release.author }}</p>
</div>
</GithubRelease>
</div>
</template>
15 changes: 5 additions & 10 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,6 @@ export default defineNuxtModule<ModuleOptions>({

// Setup releases API
if (options.releases) {
// Last release (pre-render friendly)
//
// Have to use `last-release` instead of `release/last` otherwise pre-rendering will throw
// an error as the cached file will try to overwrite `/releases` one.
nitroConfig.handlers.push({
route: '/api/_github/last-release',
handler: resolveModule('./server/api/releases/last', { paths: runtimeDir })
})
nitroConfig.prerender.routes.push('/api/_github/last-release')

// Releases list
nitroConfig.handlers.push({
route: '/api/_github/releases',
Expand All @@ -163,6 +153,11 @@ export default defineNuxtModule<ModuleOptions>({
filePath: resolveModule('./components/GithubLastRelease', { paths: runtimeDir }),
global: true
})
addComponent({
name: 'GithubRelease',
filePath: resolveModule('./components/GithubRelease', { paths: runtimeDir }),
global: true
})
}

// Setup contributors API
Expand Down
6 changes: 5 additions & 1 deletion src/runtime/components/GithubLastRelease.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export default defineComponent({
async setup (props) {
const { fetchLastRelease } = useGithub()

const { data: release, refresh, pending } = await useAsyncData(`github-last-release-${hash(props.query)}`, () => fetchLastRelease(props.query))
const {
data: release,
refresh,
pending
} = await useAsyncData(`github-last-release-${hash(props.query)}`, () => fetchLastRelease(props.query))

return {
release,
Expand Down
38 changes: 38 additions & 0 deletions src/runtime/components/GithubRelease.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { defineComponent, useSlots, PropType } from 'vue'
import { hash } from 'ohash'
import { useGithub } from '../composables/useGithub'
import { GithubReleaseQuery } from '../types'
// @ts-ignore
import { useAsyncData } from '#imports'

export default defineComponent({
props: {
query: {
type: Object as PropType<GithubReleaseQuery>,
required: false,
default: () => ({})
}
},
async setup (props) {
const { fetchRelease } = useGithub()

if (!props.query.tag) { return }

const {
data: release,
refresh,
pending
} = await useAsyncData(`github-release-${hash(props.query)}`, () => fetchRelease(props.query))

return {
release,
refresh,
pending
}
},
render ({ release, refresh, pending }) {
const slots = useSlots()

return slots?.default?.({ release, refresh, pending })
}
})
18 changes: 12 additions & 6 deletions src/runtime/composables/useGithub.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import { withQuery, QueryObject } from 'ufo'
import type { ParsedContent } from '@nuxt/content/dist/runtime/types'
import type { GithubRepositoryOptions, GithubContributorsQuery, GithubReleasesQuery, GithubRepository, GithubRawRelease, GithubRawContributors } from '../types'
import type { GithubRepositoryOptions, GithubContributorsQuery, GithubReleasesQuery, GithubRepository, GithubRawRelease, GithubRawContributor, GithubReleaseQuery } from '../types'
export const useGithub = () => {
const fetchRepository = (query: GithubRepositoryOptions): Promise<GithubRepository> => {
const url = withQuery('/api/_github/repository', query as QueryObject)
return $fetch(url, { responseType: 'json' })
}

const fetchLastRelease = (query: GithubRepositoryOptions): Promise<GithubRepository> => {
const url = withQuery('/api/_github/last-release', query as QueryObject)
const fetchRelease = (query: GithubReleaseQuery): Promise<GithubRawRelease> => {
const url = withQuery('/api/_github/releases', query as QueryObject)
return $fetch(url, { responseType: 'json' })
}

const fetchLastRelease = (query: GithubRepositoryOptions): Promise<GithubRawRelease> => {
const url = withQuery('/api/_github/releases', { ...query, last: 'true' } as QueryObject)
return $fetch(url, { responseType: 'json' })
}

const fetchReleases = (query: GithubReleasesQuery): Promise<GithubRawRelease> => {
const fetchReleases = (query: GithubReleasesQuery): Promise<GithubRawRelease[]> => {
const url = withQuery('/api/_github/releases', query as QueryObject)
return $fetch(url, { responseType: 'json' })
}

const fetchContributors = (query: GithubContributorsQuery): Promise<GithubRawContributors> => {
const fetchContributors = (query: GithubContributorsQuery): Promise<GithubRawContributor[]> => {
const url = withQuery('/api/_github/contributors', query as QueryObject)
return $fetch(url, { responseType: 'json' })
}

const fetchFileContributors = (query: GithubContributorsQuery): Promise<GithubRawContributors> => {
const fetchFileContributors = (query: GithubContributorsQuery): Promise<GithubRawContributor[]> => {
const url = withQuery('/api/_github/contributors/file', query as QueryObject)
return $fetch(url, { responseType: 'json' })
}
Expand All @@ -35,6 +40,7 @@ export const useGithub = () => {
return {
fetchRepository,
fetchReleases,
fetchRelease,
fetchLastRelease,
fetchContributors,
fetchFileContributors,
Expand Down
12 changes: 7 additions & 5 deletions src/runtime/server/api/releases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,21 @@ export default handler(
if (!githubConfig.owner || !githubConfig.repo || !githubConfig.api) { return [] }

// Fetches releases from GitHub
let releases = (await fetchReleases(query, githubConfig)) as GithubRawRelease[]
let releases = (await fetchReleases(query, githubConfig)) as (GithubRawRelease | GithubRawRelease[])

if (!releases) { return }

// Parse release notes when `parse` option is enabled and `@nuxt/content` is installed.
if (moduleConfig.parseContents) {
releases = await Promise.all(releases.map(release => parseRelease(release, githubConfig)))
if (Array.isArray(releases)) {
releases = await Promise.all(releases.map(release => parseRelease(release, githubConfig)))
} else {
return await parseRelease(releases, githubConfig)
}
}

// Sort DESC by release version or date
releases = (releases || []).sort((a, b) => (a.v !== b.v ? b.v - a.v : a.date - b.date))

return releases
return (releases as GithubRawRelease[] || []).sort((a, b) => (a.v !== b.v ? b.v - a.v : a.date - b.date)).filter(Boolean)
},
{
maxAge: 60 // cache for one minute
Expand Down
Loading