Skip to content

Commit

Permalink
feat(cli-utils): add experimental support for .svelte files (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Apr 22, 2024
1 parent 66b585c commit b67d40e
Show file tree
Hide file tree
Showing 38 changed files with 1,282 additions and 259 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-boats-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gql.tada/cli-utils": minor
---

Add experimental support for `.svelte` files for the `turbo`, `generate-persisted`, and `check` commands. (Note: `@0no-co/graphqlsp` does not yet have support for Svelte, Vue & Volar)
4 changes: 4 additions & 0 deletions examples/example-pokemon-svelte/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
27 changes: 27 additions & 0 deletions examples/example-pokemon-svelte/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>gql.tada: Pokemon API Example</title>
<style>
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
20 changes: 20 additions & 0 deletions examples/example-pokemon-svelte/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@gql.tada/example-pokemon-svelte",
"private": true,
"scripts": {
"start": "vite",
"check": "tsc"
},
"dependencies": {
"@urql/core": "^4.3.0",
"@urql/svelte": "^4.1.1",
"gql.tada": "^1.5.0",
"svelte": "^4.0.5"
},
"devDependencies": {
"@0no-co/graphqlsp": "^1.10.0",
"@sveltejs/vite-plugin-svelte": "^3.1.0",
"typescript": "^5.4.2",
"vite": "^5.1.6"
}
}
94 changes: 94 additions & 0 deletions examples/example-pokemon-svelte/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
### This file was generated by Nexus Schema
### Do not make changes to this file directly

"""
Move a Pokémon can perform with the associated damage and type.
"""
type Attack {
damage: Int
name: String
type: PokemonType
}

type AttacksConnection {
fast: [Attack]
special: [Attack]
}

"""
Requirement that prevents an evolution through regular means of levelling up.
"""
type EvolutionRequirement {
amount: Int
name: String
}

type Pokemon {
attacks: AttacksConnection
classification: String @deprecated(reason: "And this is the reason why")
evolutionRequirements: [EvolutionRequirement]
evolutions: [Pokemon]

"""
Likelihood of an attempt to catch a Pokémon to fail.
"""
fleeRate: Float
height: PokemonDimension
id: ID!

"""
Maximum combat power a Pokémon may achieve at max level.
"""
maxCP: Int

"""
Maximum health points a Pokémon may achieve at max level.
"""
maxHP: Int
name: String!
resistant: [PokemonType]
types: [PokemonType]
weaknesses: [PokemonType]
weight: PokemonDimension
}

type PokemonDimension {
maximum: String
minimum: String
}

"""
Elemental property associated with either a Pokémon or one of their moves.
"""
enum PokemonType {
Bug
Dark
Dragon
Electric
Fairy
Fighting
Fire
Flying
Ghost
Grass
Ground
Ice
Normal
Poison
Psychic
Rock
Steel
Water
}

type Query {
"""
Get a single Pokémon by its ID, a three character long identifier padded with zeroes
"""
pokemon(id: ID!): Pokemon

"""
List out all Pokémon, optionally in pages
"""
pokemons(limit: Int, skip: Int): [Pokemon]
}
11 changes: 11 additions & 0 deletions examples/example-pokemon-svelte/src/components/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import { Client, setContextClient, cacheExchange, fetchExchange } from "@urql/svelte";
import PokemonList from "./PokemonList.svelte";
setContextClient(new Client({
url: "https://trygql.formidable.dev/graphql/basic-pokedex",
exchanges: [cacheExchange, fetchExchange],
}));
</script>

<PokemonList />
26 changes: 26 additions & 0 deletions examples/example-pokemon-svelte/src/components/PokemonItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script context="module" lang="ts">
import type { FragmentOf } from "../graphql";
import { graphql, readFragment } from "../graphql";
import PokemonTypes, { pokemonTypesFragment } from "./PokemonTypes.svelte";
export const PokemonItemFragment = graphql(
`
fragment PokemonItem on Pokemon {
id
name
...PokemonTypes
}
`,
[pokemonTypesFragment]
);
</script>

<script lang="ts">
export let data: FragmentOf<typeof PokemonItemFragment> | null;
const pokemon = readFragment(PokemonItemFragment, data);
</script>

<li v-if="pokemon">
<p>{pokemon.name}</p>
<PokemonTypes data={pokemon} />
</li>
46 changes: 46 additions & 0 deletions examples/example-pokemon-svelte/src/components/PokemonList.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script context="module" lang="ts">
import { graphql } from "../graphql";
import PokemonItem, { PokemonItemFragment } from "./PokemonItem.svelte";
const PokemonsQuery = graphql(`
query Pokemons ($limit: Int = 10) {
pokemons(limit: $limit) {
id
...PokemonItem
}
}
`, [PokemonItemFragment]);
const PersistedQuery = graphql.persisted(
"sha256:fc073da8e9719deb51cdb258d7c35865708852c5ce9031a257588370d3cd42f3",
PokemonsQuery,
);
</script>

<script lang="ts">
import { getContextClient, queryStore } from "@urql/svelte";
$: result = queryStore({
client: getContextClient(),
query: PersistedQuery
});
</script>

<div>
{#if $result.fetching}
<h3>Loading...</h3>
{:else if $result.error}
<div>
<h3>Oh no!</h3>
<pre>{$result.error.message}</pre>
</div>
{:else if $result.data.pokemons}
<ul>
{#each $result.data.pokemons as pokemon}
<PokemonItem data={pokemon} />
{/each}
</ul>
{:else}
<h3>Your Pokedex is empty.</h3>
{/if}
</div>
26 changes: 26 additions & 0 deletions examples/example-pokemon-svelte/src/components/PokemonTypes.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script context="module" lang="ts">
import type { FragmentOf } from "../graphql";
import { graphql, readFragment } from "../graphql";
export const pokemonTypesFragment = graphql(`
fragment PokemonTypes on Pokemon {
types
}
`);
</script>

<script lang="ts">
export let data: FragmentOf<typeof PokemonTypesFragment> | null;
const pokemon = readFragment(pokemonTypesFragment, data);
</script>

{#if pokemon.types}
<div>
<h2>Types</h2>
<ul>
{#each pokemon.types as type}
<li>{type}</li>
{/each}
</ul>
</div>
{/if}
38 changes: 38 additions & 0 deletions examples/example-pokemon-svelte/src/graphql-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable */
/* prettier-ignore */

/** An IntrospectionQuery representation of your schema.
*
* @remarks
* This is an introspection of your schema saved as a file by GraphQLSP.
* It will automatically be used by `gql.tada` to infer the types of your GraphQL documents.
* If you need to reuse this data or update your `scalars`, update `tadaOutputLocation` to
* instead save to a .ts instead of a .d.ts file.
*/
export type introspection = {
query: 'Query';
mutation: never;
subscription: never;
types: {
'Attack': { kind: 'OBJECT'; name: 'Attack'; fields: { 'damage': { name: 'damage'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'type': { name: 'type'; type: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; } }; }; };
'AttacksConnection': { kind: 'OBJECT'; name: 'AttacksConnection'; fields: { 'fast': { name: 'fast'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Attack'; ofType: null; }; } }; 'special': { name: 'special'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Attack'; ofType: null; }; } }; }; };
'Boolean': unknown;
'EvolutionRequirement': { kind: 'OBJECT'; name: 'EvolutionRequirement'; fields: { 'amount': { name: 'amount'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
'Float': unknown;
'ID': unknown;
'Int': unknown;
'Pokemon': { kind: 'OBJECT'; name: 'Pokemon'; fields: { 'attacks': { name: 'attacks'; type: { kind: 'OBJECT'; name: 'AttacksConnection'; ofType: null; } }; 'classification': { name: 'classification'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'evolutionRequirements': { name: 'evolutionRequirements'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'EvolutionRequirement'; ofType: null; }; } }; 'evolutions': { name: 'evolutions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Pokemon'; ofType: null; }; } }; 'fleeRate': { name: 'fleeRate'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'height': { name: 'height'; type: { kind: 'OBJECT'; name: 'PokemonDimension'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'maxCP': { name: 'maxCP'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'maxHP': { name: 'maxHP'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'resistant': { name: 'resistant'; type: { kind: 'LIST'; name: never; ofType: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; }; } }; 'types': { name: 'types'; type: { kind: 'LIST'; name: never; ofType: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; }; } }; 'weaknesses': { name: 'weaknesses'; type: { kind: 'LIST'; name: never; ofType: { kind: 'ENUM'; name: 'PokemonType'; ofType: null; }; } }; 'weight': { name: 'weight'; type: { kind: 'OBJECT'; name: 'PokemonDimension'; ofType: null; } }; }; };
'PokemonDimension': { kind: 'OBJECT'; name: 'PokemonDimension'; fields: { 'maximum': { name: 'maximum'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'minimum': { name: 'minimum'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
'PokemonType': { name: 'PokemonType'; enumValues: 'Bug' | 'Dark' | 'Dragon' | 'Electric' | 'Fairy' | 'Fighting' | 'Fire' | 'Flying' | 'Ghost' | 'Grass' | 'Ground' | 'Ice' | 'Normal' | 'Poison' | 'Psychic' | 'Rock' | 'Steel' | 'Water'; };
'Query': { kind: 'OBJECT'; name: 'Query'; fields: { 'pokemon': { name: 'pokemon'; type: { kind: 'OBJECT'; name: 'Pokemon'; ofType: null; } }; 'pokemons': { name: 'pokemons'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Pokemon'; ofType: null; }; } }; }; };
'String': unknown;
};
};

import * as gqlTada from 'gql.tada';

declare module 'gql.tada' {
interface setupSchema {
introspection: introspection
}
}
9 changes: 9 additions & 0 deletions examples/example-pokemon-svelte/src/graphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { initGraphQLTada } from 'gql.tada';
import type { introspection } from './graphql-env.d.ts';

export const graphql = initGraphQLTada<{
introspection: introspection;
}>();

export type { FragmentOf, ResultOf, VariablesOf } from 'gql.tada';
export { readFragment } from 'gql.tada';
7 changes: 7 additions & 0 deletions examples/example-pokemon-svelte/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import App from './components/App.svelte';

var app = new App({
target: document.body,
});

export default app;
5 changes: 5 additions & 0 deletions examples/example-pokemon-svelte/svelte.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

export default {
preprocess: [vitePreprocess()]
};
19 changes: 19 additions & 0 deletions examples/example-pokemon-svelte/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"plugins": [
{
"name": "@0no-co/graphqlsp",
"schema": "./schema.graphql",
"tadaOutputLocation": "./src/graphql-env.d.ts"
}
],
"noEmit": true,
"jsx": "react-jsx",
"target": "es2016",
"moduleResolution": "node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"strict": true
}
}
6 changes: 6 additions & 0 deletions examples/example-pokemon-svelte/vite.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
plugins: [svelte()],
});
2 changes: 1 addition & 1 deletion examples/example-pokemon-vue/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
<script type="module" src="/src/index.ts"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ const pokemon = computed(() => readFragment(PokemonItemFragment, props.data));
<p>{{ pokemon.name }}</p>
<PokemonTypes :data="pokemon" />
</li>
</template>
</template>
Loading

0 comments on commit b67d40e

Please sign in to comment.