Skip to content

Commit

Permalink
Fix queries & mutations to work with trailing slash config (patch) (#…
Browse files Browse the repository at this point in the history
…2392)

* Added trailingslash support for API endpoints.

* Accidentally RM'd actual condition it was meant to be based upon.

* simplify integration test

Co-authored-by: Brandon Bayer <[email protected]>
  • Loading branch information
timbooker and flybayer authored May 28, 2021
1 parent 3dcc885 commit ada67b5
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface BlitzConfig extends Record<string, unknown> {
isomorphicResolverImports?: boolean
reactRoot?: boolean
}
trailingSlash?: boolean
cli?: {
clearConsoleOnBlitzDev?: boolean
httpProxy?: string
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/blitz-data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {isClient} from "./utils"
export type BlitzRuntimeData = {
suspenseEnabled: boolean
sessionCookiePrefix: string
trailingSlash: boolean
}

export function _getBlitzRuntimeData(): BlitzRuntimeData {
Expand All @@ -17,6 +18,7 @@ export function _getBlitzRuntimeData(): BlitzRuntimeData {
return {
sessionCookiePrefix: cookiePrefix || "blitz",
suspenseEnabled: config.experimental?.reactRoot !== false,
trailingSlash: config.trailingSlash !== undefined ? config.trailingSlash : false,
}
}

Expand Down
15 changes: 13 additions & 2 deletions packages/core/src/rpc-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {deserialize, serialize} from "superjson"
import {SuperJSONResult} from "superjson/dist/types"
import {getAntiCSRFToken} from "./auth/auth-client"
import {publicDataStore} from "./auth/public-data-store"
import {getBlitzRuntimeData} from "./blitz-data"
import {
HEADER_CSRF,
HEADER_CSRF_ERROR,
Expand Down Expand Up @@ -161,8 +162,18 @@ executeRpcCall.warm = (apiUrl: string) => {
return window.fetch(addBasePath(apiUrl), {method: "HEAD"})
}

const getApiUrlFromResolverFilePath = (resolverFilePath: string) =>
resolverFilePath.replace(/^app\/_resolvers/, "/api")
const ensureTrailingSlash = (url: string) => {
const lastChar = url.substr(-1)
if (lastChar !== "/") {
url = url + "/"
}
return url
}

const getApiUrlFromResolverFilePath = (resolverFilePath: string) => {
const url = resolverFilePath.replace(/^app\/_resolvers/, "/api")
return getBlitzRuntimeData().trailingSlash ? ensureTrailingSlash(url) : url
}

type IsomorphicEnhancedResolverOptions = {
warmApiEndpoints?: boolean
Expand Down
3 changes: 3 additions & 0 deletions test/integration/trailing-slash/app/queries/getBasic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function getBasic() {
return "basic-result"
}
4 changes: 4 additions & 0 deletions test/integration/trailing-slash/app/queries/getIncremented.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let count = 0
export default async function getBasic() {
return count++
}
30 changes: 30 additions & 0 deletions test/integration/trailing-slash/app/queries/getPaginated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {paginate, resolver} from "blitz"

const dataset = Array.from(Array(100).keys())

type Args = {
skip: number
take: number
where?: {value: {gte: number}}
}

export default resolver.pipe(async ({skip = 0, take = 100, where}: Args) => {
const {items, hasMore, nextPage, count} = await paginate({
skip,
take,
count: async () => dataset.length,
query: async (paginateArgs) =>
dataset
.filter((i) => {
if (!where) return true
return i >= where.value.gte
})
.slice(paginateArgs.skip, paginateArgs.skip + paginateArgs.take),
})
return {
items,
hasMore,
nextPage,
count,
}
})
4 changes: 4 additions & 0 deletions test/integration/trailing-slash/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
presets: ["blitz/babel"],
plugins: [],
}
3 changes: 3 additions & 0 deletions test/integration/trailing-slash/blitz.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
trailingSlash: true,
}
11 changes: 11 additions & 0 deletions test/integration/trailing-slash/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {AppProps} from "blitz"
import {ReactQueryDevtools} from "react-query/devtools"

export default function App({Component, pageProps}: AppProps) {
return (
<>
<Component {...pageProps} />
<ReactQueryDevtools />
</>
)
}
23 changes: 23 additions & 0 deletions test/integration/trailing-slash/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {BlitzScript, Document, DocumentHead, Html, Main} from "blitz"

class MyDocument extends Document {
// Only uncomment if you need to customize this behaviour
// static async getInitialProps(ctx: DocumentContext) {
// const initialProps = await Document.getInitialProps(ctx)
// return {...initialProps}
// }

render() {
return (
<Html lang="en">
<DocumentHead />
<body>
<Main />
<BlitzScript />
</body>
</Html>
)
}
}

export default MyDocument
20 changes: 20 additions & 0 deletions test/integration/trailing-slash/pages/use-query.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import getBasic from "app/queries/getBasic"
import {useQuery} from "blitz"
import {Suspense} from "react"

function Content() {
const [result] = useQuery(getBasic, undefined)
return <div id="content">{result}</div>
}

function Page() {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<Content />
</Suspense>
</div>
)
}

export default Page
32 changes: 32 additions & 0 deletions test/integration/trailing-slash/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-env jest */
import {findPort, killApp, launchApp, renderViaHTTP} from "lib/blitz-test-utils"
import webdriver from "lib/next-webdriver"
import {join} from "path"

const context: any = {}
jest.setTimeout(1000 * 60 * 5)

describe("Queries", () => {
beforeAll(async () => {
context.appPort = await findPort()
context.server = await launchApp(join(__dirname, "../"), context.appPort, {
env: {__NEXT_TEST_WITH_DEVTOOL: 1},
})

const prerender = ["/use-query"]
await Promise.all(prerender.map((route) => renderViaHTTP(context.appPort, route)))
})
afterAll(() => killApp(context.server))

describe("useQuery", () => {
it("should render query result", async () => {
const browser = await webdriver(context.appPort, "/use-query")
let text = await browser.elementByCss("#page").text()
expect(text).toMatch(/Loading/)
await browser.waitForElementByCss("#content")
text = await browser.elementByCss("#content").text()
expect(text).toMatch(/basic-result/)
if (browser) await browser.close()
})
})
})
25 changes: 25 additions & 0 deletions test/integration/trailing-slash/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": "./",
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo",
"paths": {
"lib/*": ["../../lib/*"]
}
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

0 comments on commit ada67b5

Please sign in to comment.