Skip to content

Commit

Permalink
use TypeScript for Next.js example
Browse files Browse the repository at this point in the history
  • Loading branch information
brillout committed Oct 22, 2022
1 parent 047c15f commit f68221c
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 18 deletions.
10 changes: 10 additions & 0 deletions examples/next/TelefuncContext.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'telefunc'
import type { User } from './auth/getUser'

declare module 'telefunc' {
namespace Telefunc {
interface Context {
user: null | User
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
export { getUser }
export type { User }

function getUser(req) {
type User = {
id: number,
name: string
}

function getUser(_req: unknown): User {
// Fake implementation. A real implementation would, for example, use `req.headers.cookie` to retrieve the logged-in user.
return {
id: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Todo } from '../database/Todo'

export { onNewTodo }

async function onNewTodo({ text }) {
async function onNewTodo({ text }: { text: string }) {
const { user } = getContext()
if (!user) {
throw Abort()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useState } from 'react'
import { onNewTodo } from './TodoList.telefunc.js'

export { TodoList }

function TodoList({ todoItemsInitial }) {
import React, { useState } from 'react'
import { onNewTodo } from './TodoList.telefunc'

function TodoList({ todoItemsInitial }: { todoItemsInitial: { text: string }[] }) {
const [todoItems, setTodoItems] = useState(todoItemsInitial)
const [text, setText] = useState('')
return (
Expand Down
18 changes: 16 additions & 2 deletions examples/next/database/Todo.js → examples/next/database/Todo.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
export { Todo }
export type { TodoItem }

const Todo = {
findMany,
createNew
}

type TodoItem = {
text: string
authorId: number
}

const database = (global.database = global.database || {
todoItems: [
{ text: 'Buy milk', authorId: 0 },
{ text: 'Buy strawberries', authorId: 0 }
]
})

function findMany({ authorId }) {
function findMany({ authorId }: { authorId: number }) {
return database.todoItems.filter((todoItem) => todoItem.authorId === authorId)
}

function createNew({ text, authorId }) {
function createNew({ text, authorId }: { text: string; authorId: number }) {
database.todoItems.push({ text, authorId })
}

declare global {
var database:
| undefined
| {
todoItems: TodoItem[]
}
}
1 change: 0 additions & 1 deletion examples/next/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
Expand Down
8 changes: 5 additions & 3 deletions examples/next/pages/_app.jsx → examples/next/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
export default MyApp

import { telefuncConfig } from 'telefunc/client'
import type { AppProps } from 'next/app'
import React from 'react'

const isBrowser = typeof window !== 'undefined'
if (isBrowser) {
telefuncConfig.telefuncUrl = '/api/_telefunc'
}

function MyApp({ Component, pageProps }) {
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}

export default MyApp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { getUser } from '../../auth/getUser'
import { telefunc, telefuncConfig, provideTelefuncContext } from 'telefunc'
import type { NextApiRequest, NextApiResponse } from 'next'
import assert from 'assert'

telefuncConfig.telefuncUrl = '/api/_telefunc'

export default async function (req, res) {
export default async function telefuncMiddleware (req: NextApiRequest, res: NextApiResponse) {
const user = getUser(req)
provideTelefuncContext({ user })
const { url, method, body } = req
assert(url && method && typeof body === 'string')
const httpRequest = { url, method, body }
const httpResponse = await telefunc(httpRequest)
res.status(httpResponse.statusCode).send(httpResponse.body)
Expand Down
18 changes: 13 additions & 5 deletions examples/next/pages/index.jsx → examples/next/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { getUser } from '../auth/getUser'
export default Page
export { getServerSideProps }

import { getUser, type User } from '../auth/getUser'
import { TodoList } from '../components/TodoList'
import { Todo } from '../database/Todo'
import { Todo, type TodoItem } from '../database/Todo'
import React from 'react'
import { GetServerSideProps } from 'next'

export default Page
type Props = {
user: User
todoItemsInitial: TodoItem[]
}

function Page(props) {
function Page(props: Props) {
const title = `${props.user.name}'s to-do list`
return (
<>
Expand All @@ -14,7 +22,7 @@ function Page(props) {
)
}

export async function getServerSideProps(context) {
const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const user = getUser(context.req)
const todoItems = Todo.findMany({ authorId: user.id })
return {
Expand Down
30 changes: 30 additions & 0 deletions examples/next/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"strict": true,
"module": "ES2020",
"moduleResolution": "Node",
"target": "ES2017",
"lib": [
"DOM",
"DOM.Iterable",
"ESNext"
],
"jsx": "preserve",
"skipLibCheck": true,
"esModuleInterop": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}

0 comments on commit f68221c

Please sign in to comment.