-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from AElfProject/release/v0.1.6
feat: 🎸 request all in one
- Loading branch information
Showing
12 changed files
with
511 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
"extends": [ | ||
"next/core-web-vitals", | ||
"plugin:@tanstack/eslint-plugin-query/recommended" | ||
] | ||
} |
30 changes: 30 additions & 0 deletions
30
lib/generator/templates/src/app/demos/api-all-in-one/apollo-client.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { ApolloClient, InMemoryCache, gql } from "@apollo/client"; | ||
import {IBaseRequestOptions} from '@/app/demos/api-all-in-one/fetch-data'; | ||
|
||
export interface IApolloRequestOptions extends IBaseRequestOptions { | ||
apolloConfig?: any; | ||
query?: any; | ||
} | ||
|
||
interface IApolloClientOptions { | ||
uri: any; | ||
cache: any; | ||
} | ||
export const createApolloClient = (options: IApolloClientOptions) => { | ||
return new ApolloClient({ | ||
// uri: "https://countries.trevorblades.com", | ||
// cache: new InMemoryCache(), | ||
uri: options.uri || "https://countries.trevorblades.com", | ||
cache: options.cache || new InMemoryCache(), | ||
}); | ||
}; | ||
|
||
export const queryCountries = gql` | ||
query Countries { | ||
countries { | ||
code | ||
name | ||
emoji | ||
} | ||
} | ||
`; |
85 changes: 85 additions & 0 deletions
85
lib/generator/templates/src/app/demos/api-all-in-one/fetch-data.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import {createApolloClient, IApolloRequestOptions} from '@/app/demos/api-all-in-one/apollo-client'; | ||
import {fetchData} from '@/app/demos/api-all-in-one/fetch'; | ||
import { ApolloClient, gql } from "@apollo/client"; | ||
import { io, Socket } from 'socket.io-client'; | ||
import {ISocketRequestOptions} from '@/app/demos/api-all-in-one/socket-io'; | ||
|
||
export interface IBaseRequestOptions { | ||
method?: string; | ||
headers?: Record<string, string>; | ||
body?: Record<string, any>; | ||
} | ||
|
||
export interface IRequestOptions extends ISocketRequestOptions, IApolloRequestOptions {} | ||
|
||
export const defaultHeaders = { | ||
'Content-Type': 'application/json', | ||
}; | ||
|
||
export class RequestAllInOne { | ||
private readonly headers: Record<string, string>; | ||
private readonly apolloConfig: any; | ||
private readonly apolloClient: ApolloClient<any> | undefined; // TCacheShape | ||
private readonly socketClient: Socket | undefined; | ||
private options: Partial<IRequestOptions>; | ||
constructor(options: Partial<IRequestOptions>) { | ||
this.options = options || {}; | ||
this.headers = options.headers || defaultHeaders; | ||
|
||
if (options.socketPath) { | ||
this.socketClient = io({ | ||
path: options.socketPath | ||
}); | ||
} | ||
if (options.apolloConfig) { | ||
this.apolloConfig = options.apolloConfig; | ||
this.apolloClient = createApolloClient(this.apolloConfig); | ||
} | ||
} | ||
|
||
async get(url: string) { | ||
return fetchData(url, { headers: this.headers }); | ||
} | ||
|
||
async post(url: string, options: IBaseRequestOptions = {}) { | ||
return fetchData(url, { | ||
method: 'POST', | ||
headers: { | ||
...this.headers, | ||
...options.headers, | ||
}, | ||
body: options.body | ||
}); | ||
} | ||
|
||
async gql(url: string, options: IApolloRequestOptions = {}) { | ||
if (!this.apolloClient) { | ||
throw Error('No apollo client found') | ||
} | ||
const { data } = await this.apolloClient.query({ | ||
query: gql`${options.query}`, | ||
}); | ||
|
||
return data; | ||
} | ||
|
||
socket(url: string, options: ISocketRequestOptions) { | ||
let socketClient = this.socketClient; | ||
if (this.options.socketPath !== url || !socketClient) { | ||
socketClient = io({ | ||
path: options.socketPath | ||
}); | ||
} | ||
if (options.type === 'on') { | ||
socketClient.on(options.event, (response: any) => { | ||
console.log(options.event, response); | ||
options.callback && options.callback(response); | ||
}); | ||
} else { | ||
socketClient.emit(options.event, options.value, (response: any) => { | ||
console.log(response); | ||
options.callback && options.callback(response); | ||
}); | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
lib/generator/templates/src/app/demos/api-all-in-one/fetch.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { IBaseRequestOptions } from '@/app/demos/api-all-in-one/fetch-data'; | ||
|
||
export const fetchData = async (url: string, options: IBaseRequestOptions = {}) => { | ||
|
||
const { method = 'GET', headers = {}, body } = options; | ||
|
||
const fetchOptions: any = { | ||
method, | ||
headers, | ||
}; | ||
|
||
if (body) { | ||
fetchOptions.body = JSON.stringify(body); | ||
} | ||
|
||
const response = await fetch(url, fetchOptions); | ||
|
||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
|
||
return response.json(); | ||
} |
95 changes: 95 additions & 0 deletions
95
lib/generator/templates/src/app/demos/api-all-in-one/fetch/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
'use client'; | ||
import {RequestAllInOne} from '@/app/demos/api-all-in-one/fetch-data'; | ||
import {useEffect, useState} from 'react'; | ||
|
||
const client = new RequestAllInOne({}); | ||
|
||
export default function Fetch() { | ||
const [data, setData] = useState<any>(); | ||
|
||
useEffect(() => { | ||
const fetchData = async () => { | ||
const response = await client.get('https://api.github.com/repos/TanStack/query'); | ||
setData(response); | ||
}; | ||
fetchData(); | ||
}, []); | ||
|
||
if (!data) { | ||
return <>No data</>; | ||
} | ||
|
||
return <> | ||
<div> | ||
<div> Fetch Only </div> | ||
<h1>{data.full_name}</h1> | ||
<p>{data.description}</p> | ||
<strong>👀 {data.subscribers_count}</strong>{' '} | ||
<strong>✨ {data.stargazers_count}</strong>{' '} | ||
<strong>🍴 {data.forks_count}</strong> | ||
{/*<div>{isFetching ? 'Updating...' : ''}</div>*/} | ||
</div> | ||
</>; | ||
} | ||
|
||
// function Example() { | ||
// const { isPending, error, data, isFetching } = useQuery({ | ||
// queryKey: ['repoData'], | ||
// queryFn: async () => { | ||
// const response = await fetch( | ||
// 'https://api.github.com/repos/TanStack/query', | ||
// ) | ||
// return await response.json() | ||
// }, | ||
// }) | ||
// | ||
// if (isPending) return 'Loading...' | ||
// | ||
// if (error) return 'An error has occurred: ' + error.message | ||
// | ||
// return ( | ||
// <div> | ||
// <h1>{data.full_name}</h1> | ||
// <p>{data.description}</p> | ||
// <strong>👀 {data.subscribers_count}</strong>{' '} | ||
// <strong>✨ {data.stargazers_count}</strong>{' '} | ||
// <strong>🍴 {data.forks_count}</strong> | ||
// <div>{isFetching ? 'Updating...' : ''}</div> | ||
// </div> | ||
// ) | ||
// } | ||
|
||
// | ||
// function Todos() { | ||
// // Access the client | ||
// const queryClient = useQueryClient() | ||
// | ||
// // Queries | ||
// const query = useQuery({ queryKey: ['todos'], queryFn: getTodos }) | ||
// | ||
// // Mutations | ||
// const mutation = useMutation({ | ||
// mutationFn: postTodo, | ||
// onSuccess: () => { | ||
// // Invalidate and refetch | ||
// queryClient.invalidateQueries({ queryKey: ['todos'] }) | ||
// }, | ||
// }) | ||
// | ||
// return ( | ||
// <div> | ||
// <ul>{query.data?.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul> | ||
// | ||
// <button | ||
// onClick={() => { | ||
// mutation.mutate({ | ||
// id: Date.now(), | ||
// title: 'Do Laundry', | ||
// }) | ||
// }} | ||
// > | ||
// Add Todo | ||
// </button> | ||
// </div> | ||
// ) | ||
// } |
40 changes: 40 additions & 0 deletions
40
lib/generator/templates/src/app/demos/api-all-in-one/graphql/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
'use client'; | ||
import {RequestAllInOne} from '@/app/demos/api-all-in-one/fetch-data'; | ||
import {useEffect, useState} from 'react'; | ||
import {queryCountries} from '@/app/demos/graphql/apollo-client'; | ||
import {InMemoryCache} from '@apollo/client'; | ||
|
||
const client = new RequestAllInOne({ apolloConfig: { | ||
uri: "https://countries.trevorblades.com", | ||
cache: new InMemoryCache(), | ||
}}); | ||
|
||
export default function Fetch() { | ||
const [data, setData] = useState<any>(); | ||
|
||
useEffect(() => { | ||
const fetchData = async () => { | ||
const response = await client.gql('https://countries.trevorblades.com', { | ||
query: queryCountries | ||
}); | ||
const countries = response.countries.slice(0, 4); | ||
setData(countries); | ||
}; | ||
fetchData(); | ||
}, []); | ||
|
||
if (!data) { | ||
return <>No data</>; | ||
} | ||
|
||
return <div> | ||
{data.map((country: any) => ( | ||
<div key={country.code}> | ||
<h3>{country.name}</h3> | ||
<p> | ||
{country.code} - {country.emoji} | ||
</p> | ||
</div> | ||
))} | ||
</div> | ||
} |
21 changes: 21 additions & 0 deletions
21
lib/generator/templates/src/app/demos/api-all-in-one/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Menu } from 'antd'; | ||
import Link from 'next/link'; | ||
import type { MenuProps } from 'antd'; | ||
|
||
type MenuItem = Required<MenuProps>['items'][number]; | ||
|
||
const items: MenuItem[] = [ | ||
{ key: '1', label: <Link href="/demos/api-all-in-one/fetch">Fetch</Link> }, | ||
{ key: '2', label: <Link href="/demos/api-all-in-one/graphql">Graphql</Link> }, | ||
{ key: '3', label: <Link href="/demos/api-all-in-one/socket">Socket</Link> }, | ||
]; | ||
export default function APIAllInOneLayout({ | ||
children, // will be a page or nested layout | ||
}: { | ||
children: React.ReactNode | ||
}) { | ||
return <> | ||
<Menu mode="horizontal" items={items} /> | ||
<div>{children}</div> | ||
</>; | ||
} |
83 changes: 83 additions & 0 deletions
83
lib/generator/templates/src/app/demos/api-all-in-one/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
'use client'; | ||
// useQuery use client only | ||
// Todo: server side integration. | ||
import { | ||
useQuery, | ||
QueryClient, | ||
QueryClientProvider, | ||
} from '@tanstack/react-query'; | ||
|
||
// Create a client | ||
const queryClient = new QueryClient() | ||
|
||
export default function APIAllInOne() { | ||
return <> | ||
<QueryClientProvider client={queryClient}> | ||
<p>api all in one.</p> | ||
{/*<Todos />*/} | ||
<Example /> | ||
</QueryClientProvider> | ||
</>; | ||
} | ||
|
||
function Example() { | ||
const { isPending, error, data, isFetching } = useQuery({ | ||
queryKey: ['repoData'], | ||
queryFn: async () => { | ||
const response = await fetch( | ||
'https://api.github.com/repos/TanStack/query', | ||
) | ||
return await response.json() | ||
}, | ||
}) | ||
|
||
if (isPending) return 'Loading...' | ||
|
||
if (error) return 'An error has occurred: ' + error.message | ||
|
||
return ( | ||
<div> | ||
<h1>{data.full_name}</h1> | ||
<p>{data.description}</p> | ||
<strong>👀 {data.subscribers_count}</strong>{' '} | ||
<strong>✨ {data.stargazers_count}</strong>{' '} | ||
<strong>🍴 {data.forks_count}</strong> | ||
<div>{isFetching ? 'Updating...' : ''}</div> | ||
</div> | ||
) | ||
} | ||
|
||
// | ||
// function Todos() { | ||
// // Access the client | ||
// const queryClient = useQueryClient() | ||
// | ||
// // Queries | ||
// const query = useQuery({ queryKey: ['todos'], queryFn: getTodos }) | ||
// | ||
// // Mutations | ||
// const mutation = useMutation({ | ||
// mutationFn: postTodo, | ||
// onSuccess: () => { | ||
// // Invalidate and refetch | ||
// queryClient.invalidateQueries({ queryKey: ['todos'] }) | ||
// }, | ||
// }) | ||
// | ||
// return ( | ||
// <div> | ||
// <ul>{query.data?.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul> | ||
// | ||
// <button | ||
// onClick={() => { | ||
// mutation.mutate({ | ||
// id: Date.now(), | ||
// title: 'Do Laundry', | ||
// }) | ||
// }} | ||
// > | ||
// Add Todo | ||
// </button> | ||
// </div> | ||
// ) | ||
// } |
Oops, something went wrong.