Skip to content

Commit

Permalink
Merge pull request #1 from Applelo/dev
Browse files Browse the repository at this point in the history
Version 1.1.0
  • Loading branch information
Applelo authored Jun 1, 2024
2 parents a7af4f9 + 5d10cfa commit f0a79ec
Show file tree
Hide file tree
Showing 26 changed files with 351 additions and 111 deletions.
96 changes: 54 additions & 42 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,41 @@ import type { FormError } from '#ui/types'
const state = reactive<SchemaOptions>({
url: undefined,
headerName: undefined,
headerValue: undefined,
headers: [],
})
const hasHeader = ref(false)
const rawSchema = ref('')
const errorSchema = ref<Error | null>(null)
const loading = ref(false)
function validate(state: any): FormError[] {
const errors = []
if (!state.url)
errors.push({ path: 'url', message: 'Required' })
if (hasHeader.value) {
if (!state.headerName)
errors.push({ path: 'headerName', message: 'Required' })
// if (hasHeader.value) {
// if (!state.headerName)
// errors.push({ path: 'headerName', message: 'Required' })
if (!state.headerValue)
errors.push({ path: 'headerValue', message: 'Required' })
}
// if (!state.headerValue)
// errors.push({ path: 'headerValue', message: 'Required' })
// }
return errors
}
async function onSubmit() {
rawSchema.value = ''
loading.value = true
const { data } = await useAsyncData(() => getSchema(state))
const { data, error } = await useAsyncData(() => getSchema(state))
errorSchema.value = error.value
if (!data.value)
return loading.value = false
rawSchema.value = data.value
loading.value = false
}
const headerValuePlaceholder = computed(
() => (Math.random() + 1).toString(36).substring(2),
)
useHead({
htmlAttrs: {
lang: 'en',
Expand All @@ -50,8 +46,7 @@ useHead({
</script>

<template>
<Title>Get GraphQL Schema</Title>
<Meta name="description" content="Get your GraphQL schema easily" />
<AppHead />

<main class="bg-gray-900">
<div class="max-w-5xl mx-auto min-h-screen px-4 py-8 flex flex-col">
Expand All @@ -73,38 +68,55 @@ useHead({
/>
</UFormGroup>

<UCheckbox v-model="hasHeader" class="mb-2">
<template #label>
<span class="text-white">
Set an header
</span>
</template>
</UCheckbox>
<div v-if="hasHeader" class="relative">
<div class="grid sm:grid-cols-2 gap-3">
<UFormGroup name="headerName">
<UInput
v-model="state.headerName"
aria-label="Header name"
placeholder="Authorization"
/>
</UFormGroup>
<UFormGroup name="headerValue">
<UInput
v-model="state.headerValue"
aria-label="Header value"
:placeholder="headerValuePlaceholder"
/>
</UFormGroup>
</div>
<div v-for="item, index in state.headers" :key="index" class="flex gap-3 mb-2">
<UFormGroup name="headerName" class="grow">
<UInput
v-model="item[0]"
aria-label="Header name"
placeholder="Key"
/>
</UFormGroup>
<UFormGroup name="headerValue" class="grow">
<UInput
v-model="item[1]"
aria-label="Header value"
placeholder="Value"
/>
</UFormGroup>
<UButton
icon="i-heroicons-minus"
color="white"
square
variant="solid"
aria-label="Remove"
@click="state.headers.splice(index, 1)"
/>
</div>
<UButton :loading="loading" block type="submit" class="mt-4">

<UButton
icon="i-heroicons-plus"
color="white"
variant="solid"
@click="state.headers.push(['', ''])"
>
Add Header
</UButton>

<UButton :loading="loading" block type="submit" class="mt-5">
Get my schema
</UButton>
</UForm>

<UAlert
v-if="errorSchema"
class="mt-12 mb-8"
color="primary"
variant="solid"
title="Error"
:description="errorSchema.message"
/>
<LazyResult
v-if="rawSchema || loading"
v-else-if="rawSchema || loading"
:loading="loading"
:raw-schema="rawSchema"
/>
Expand Down
Binary file modified bun.lockb
Binary file not shown.
11 changes: 11 additions & 0 deletions components/AppHead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<Title>Get GraphQL Schema</Title>
<Meta name="description" content="Get your GraphQL schema easily" />
<Link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
<Link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
<Link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
<Link rel="manifest" href="/favicons/site.webmanifest" />
<Link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#f76fc9" />
<Meta name="msapplication-TileColor" content="#111827" />
<Meta name="theme-color" content="#111827" />
</template>
8 changes: 1 addition & 7 deletions components/Footer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<footer class="mt-auto">
<footer class="mt-auto pt-8">
<UDivider class="mb-2">
<ULink to="https://github.com/Applelo/get-graphql-schema">
<span class="sr-only">
Expand Down Expand Up @@ -42,12 +42,6 @@
</ULink>
by Nuxt Team
</li>
<li>
<ULink to="https://github.com/antfu/shikiji" class="text-primary">
Shikiji
</ULink>
by antfu
</li>
</ul>
</div>
</template>
Expand Down
File renamed without changes.
96 changes: 58 additions & 38 deletions components/Result.vue
Original file line number Diff line number Diff line change
@@ -1,68 +1,88 @@
<script lang="ts" setup>
import type { HighlighterCore } from 'shikiji/core'
const props = defineProps<{
rawSchema: string
loading: boolean
}>()
const toast = useToast()
let shiki: HighlighterCore
const { copy, isSupported: copySupport } = useClipboard()
const body = computed(() => {
return {
schema: props.rawSchema,
}
})
const selected = ref(0)
const { data: rawTs, execute: executeGqlToTs } = await useFetch('/api/gql-to-ts', {
method: 'POST',
body,
immediate: false,
server: false,
watch: false,
})
async function getShiki() {
const shikiji = await import('shikiji/core')
const shikijiWasm = await import('shikiji/wasm')
const items = [{
label: 'Schema',
}, {
label: 'Typescript',
}]
shiki = await shikiji.getHighlighterCore({
themes: [
import('shikiji/themes/dracula.mjs'),
],
langs: [
import('shikiji/langs/typescript.mjs'),
import('shikiji/langs/graphql.mjs'),
],
loadWasm: shikijiWasm.getWasmInlined,
})
}
const toast = useToast()
const { copy, isSupported: copySupport } = useClipboard()
function schemaToClipboard() {
copy(props.rawSchema)
toast.add({ title: 'Copied', description: 'The schema is in your clipboard!' })
function codeToClipboard() {
if (selected.value === 0) {
copy(props.rawSchema)
toast.add({
title: 'Copied',
description: 'The schema is in your clipboard!',
})
}
else if (selected.value === 1 && rawTs.value) {
copy(rawTs.value)
toast.add({
title: 'Copied',
description: 'The TypeScript code is in your clipboard!',
})
}
}
const htmlSchema = computed(
() => shiki.codeToHtml(
props.rawSchema,
{
lang: 'graphql',
theme: 'dracula',
},
),
)
onMounted(() => {
getShiki()
watch(selected, async () => {
if (selected.value !== 1 || rawTs.value)
return
await executeGqlToTs()
})
</script>

<template>
<UCard class="mt-12 mb-8">
<template v-if="rawSchema" #header>
<div class="flex justify-end">
<div class="flex justify-between items-start gap-4">
<UTabs v-model="selected" :items="items" />
<UTooltip text="Copy to your clipboard">
<UButton
v-if="copySupport"
color="gray"
square
icon="i-heroicons-clipboard-document"
@click="schemaToClipboard"
@click="codeToClipboard"
/>
</UTooltip>
</div>
</template>
<div v-if="rawSchema" class="overflow-auto max-h-screen" v-html="htmlSchema" />
<div v-else class="text-center flex align-center justify-center">
<LazyShiki
v-if="rawSchema && selected === 0"
lang="graphql"
class="max-h-screen overflow-auto"
:code="rawSchema"
/>
<LazyShiki
v-else-if="rawTs && selected === 1"
class="max-h-screen overflow-auto"
lang="ts"
:code="rawTs"
/>
<div
v-else
class="text-center flex align-center justify-center"
>
Loading...
</div>
</UCard>
Expand Down
14 changes: 10 additions & 4 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,18 @@ export default defineNuxtConfig({
'@nuxt/ui',
'@vueuse/nuxt',
'nuxt-simple-robots',
'nuxt-shiki',
],
shiki: {
defaultTheme: 'dracula',
bundledThemes: ['dracula'],
bundledLangs: ['typescript', 'graphql'],
},
nitro: {
preset: 'vercel-edge',
preset: 'vercel',
experimental: {
wasm: true,
},
},
ui: {
icons: [
Expand All @@ -16,7 +25,4 @@ export default defineNuxtConfig({
colorMode: {
preference: 'dark',
},
experimental: {
componentIslands: true,
},
})
28 changes: 19 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"type": "module",
"version": "1.1.0",
"private": true,
"scripts": {
"build": "nuxt build",
Expand All @@ -11,17 +12,26 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
"@iconify-json/simple-icons": "^1.1.80",
"@nuxt/ui": "^2.11.0",
"@vueuse/core": "^10.6.1",
"@vueuse/nuxt": "^10.6.1",
"@graphql-codegen/core": "^4.0.2",
"@graphql-codegen/typescript": "^4.0.7",
"@graphql-codegen/typescript-operations": "^4.2.1",
"@iconify-json/simple-icons": "^1.1.103",
"@nuxt/ui": "^2.16.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@vueuse/core": "^10.10.0",
"@vueuse/nuxt": "^10.10.0",
"graphql": "^16.8.1",
"nuxt-simple-robots": "^3.1.9",
"shikiji": "^0.7.4"
"nuxt": "^3.11.2",
"nuxt-shiki": "^0.3.0",
"nuxt-simple-robots": "4.0.0-rc.17"
},
"devDependencies": {
"@antfu/eslint-config": "^2.1.0",
"eslint": "^8.54.0",
"nuxt": "^3.8.2"
"@antfu/eslint-config": "^2.19.1",
"eslint": "^9.3.0"
},
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
Loading

0 comments on commit f0a79ec

Please sign in to comment.