Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A small set of bug fixes #1415

Merged
merged 11 commits into from
Jan 17, 2025
5 changes: 5 additions & 0 deletions .changeset/big-queens-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini-svelte': patch
---

Fix issue with sessions when load function was declared to be the result of a function (or a direct value)
5 changes: 5 additions & 0 deletions .changeset/clean-weeks-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini': patch
---

Include pageInfo in default pagination fields
5 changes: 5 additions & 0 deletions .changeset/grumpy-comics-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini-adapter-static': patch
---

Fix bug when shell was defined as tsx
5 changes: 5 additions & 0 deletions .changeset/lazy-seas-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini': patch
---

Fix issue when multiple operations targetting the same list are found in a mutation
5 changes: 5 additions & 0 deletions .changeset/lemon-clouds-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini-react': patch
---

Fix bug when url encoded route parameters contain url encodings
8 changes: 8 additions & 0 deletions .changeset/mighty-trains-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'houdini-adapter-auto': minor
'houdini-adapter-cloudflare': minor
'houdini-adapter-node': minor
'houdini-adapter-static': minor
---

Version bump to align with rest of packages
4 changes: 4 additions & 0 deletions e2e/_api/graphql.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export const typeDefs = /* GraphQL */ `
union UnionAorB = A | B

type Query {
book(title: String!): Book
hello: String
aOrB: [UnionAorB!]!
avgYearsBirthDate: Float!
Expand Down Expand Up @@ -429,6 +430,9 @@ export const resolvers = {

return toRet
},
book: (_, args) => {
return dataBooks.find((book) => book.title === args.title)
},
usersList: (_, args) => {
return [...getUserSnapshot(args.snapshot)].splice(args.offset || 0, args.limit)
},
Expand Down
3 changes: 2 additions & 1 deletion e2e/_api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ input UserNameFilter {
union UnionAorB = A | B

type Query {
book(title: String!): Book
hello: String
aOrB: [UnionAorB!]!
avgYearsBirthDate: Float!
Expand All @@ -110,7 +111,7 @@ type Query {
before: String
first: Int
last: Int
delay: Int
delay: Int
snapshot: String!
): UserConnection!
usersList(limit: Int = 4, offset: Int, snapshot: String!): [User!]!
Expand Down
2 changes: 1 addition & 1 deletion e2e/react/src/routes/route_params/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { routes } from '~/utils/routes'
import { sleep } from '~/utils/sleep'
import { expect_to_be, goto } from '~/utils/testsHelper'

test('Component fields with correct argument value', async ({ page }) => {
test('Route params', async ({ page }) => {
await goto(page, routes.route_params)

// be default we see user 1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
query RouteParamsWithSpace($title: String!) {
book(title: $title) {
title
}
}
16 changes: 16 additions & 0 deletions e2e/react/src/routes/route_params_with_space/[title]/+page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useRoute } from '$houdini'

import type { PageProps } from './$types'

export default function ({ RouteParamsWithSpace }: PageProps) {
const route = useRoute<PageProps>()

const { book } = RouteParamsWithSpace
return (
<div>
<div id="result">
{route.params.title}: {book?.title}
</div>
</div>
)
}
10 changes: 10 additions & 0 deletions e2e/react/src/routes/route_params_with_space/[title]/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { test } from '@playwright/test'
import { routes } from '~/utils/routes'
import { expect_to_be, goto } from '~/utils/testsHelper'

test('Route params with space', async ({ page }) => {
await goto(page, routes.route_params_with_space)

// be default we see user 1
await expect_to_be(page, 'Callimachus Pinakes:Callimachus Pinakes')
})
1 change: 1 addition & 0 deletions e2e/react/src/utils/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const routes = {
componentFields_simple: '/component_fields/simple',
componentFields_arguments: '/component_fields/arguments',
route_params: '/route_params/1',
route_params_with_space: '/route_params_with_space/Callimachus%20Pinakes',
handle_1: '/handle/1',
handle_2: '/handle/2',
pagination_query_backwards: '/pagination/query/connection-backwards',
Expand Down
3 changes: 2 additions & 1 deletion packages/adapter-static/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ adapter.pre = async ({ config, outDir, conventions }) => {
},
lib: {
entry: {
shell: conventions.router_index_path(config),
// the shell could be defined as tsx or jsx so just strip the extension
shell: conventions.router_index_path(config).replace('.jsx', ''),
},
formats: ['es'],
},
Expand Down
51 changes: 46 additions & 5 deletions packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,21 +309,16 @@ test('augments load function in root layout load', async function () {
const result = await test_transform_js(
'src/routes/+layout.js',
`
import { browser } from '$app/environment';

export const load = async ({ url }) => {
console.log('routes/+layout.js start');
if (!browser) return;

console.log('this should only run in the browser');
};

`
)

expect(result).toMatchInlineSnapshot(`
import { browser } from "$app/environment";

export const load = async event => {
let {
url
Expand All @@ -345,3 +340,49 @@ test('augments load function in root layout load', async function () {
};
`)
})

test('call expression assignment for load function', async function () {
const result = await test_transform_js(
'src/routes/+layout.js',
`

export const load = someFn()
`
)

expect(result).toMatchInlineSnapshot(`
export const load = event => {
const result = houdini__intermediate__load__(event);

return {
...event.data,
...result
};
};

const houdini__intermediate__load__ = someFn();
`)
})

test('value assignment for load function', async function () {
const result = await test_transform_js(
'src/routes/+layout.js',
`

export const load = someFn
`
)

expect(result).toMatchInlineSnapshot(`
export const load = event => {
const result = houdini__intermediate__load__(event);

return {
...event.data,
...result
};
};

const houdini__intermediate__load__ = someFn;
`)
})
51 changes: 47 additions & 4 deletions packages/houdini-svelte/src/plugin/transforms/kit/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ type ReturnStatement = recast.types.namedTypes.ReturnStatement
type BlockStatement = recast.types.namedTypes.BlockStatement
type Identifier = recast.types.namedTypes.Identifier
type ObjectExpression = recast.types.namedTypes.ObjectExpression
type CallExpression = recast.types.namedTypes.CallExpression
type VariableDeclaration = recast.types.namedTypes.VariableDeclaration
type VariableDeclarator = recast.types.namedTypes.VariableDeclarator

export default function (page: SvelteTransformPage) {
if (is_root_layout_server(page.config, page.filepath)) {
Expand Down Expand Up @@ -96,8 +99,9 @@ function modify_load(
cb: (body: BlockStatement, event_id: Identifier) => BlockStatement
) {
// before we do anything, we need to find the load function
let load_fn = find_exported_fn(page.script.body, 'load')
let exported = find_exported_fn(page.script.body, 'load')
let event_id = AST.identifier('event')
let load_fn = exported?.declaration || null

// lets get a reference to the body of the function
let body: BlockStatement = AST.blockStatement([])
Expand All @@ -108,7 +112,7 @@ function modify_load(
body = AST.blockStatement([AST.returnStatement(load_fn.body)])
load_fn.body = body
}
} else if (load_fn) {
} else if (load_fn && 'body' in load_fn) {
body = load_fn.body
}

Expand All @@ -127,8 +131,47 @@ function modify_load(
)
body = load_fn.body
}
// there is a load function, we need the event
else {
// the load function could be not an actual function but just an expression like an identifier or callexpression
// in which case we need to replace the declared value to be a function that passes event on and adds what we want
else if (load_fn.type === 'CallExpression' || load_fn.type === 'Identifier') {
const exportStatement = exported?.export

// this should never be true since we know load_fn exists but let's make typescript happy
if (!exportStatement) {
return
}

// add a global variable with the intermediate value
const intermediateID = AST.identifier('houdini__intermediate__load__')
page.script.body.push(
AST.variableDeclaration('const', [AST.variableDeclarator(intermediateID, load_fn)])
)

// build up a function that does the right thing
const newLoad = AST.arrowFunctionExpression(
[AST.identifier('event')],
AST.blockStatement([
AST.variableDeclaration('const', [
AST.variableDeclarator(
AST.identifier('result'),
AST.callExpression(intermediateID, [AST.identifier('event')])
),
]),
AST.returnStatement(AST.identifier('result')),
])
)

// and change the declared value to be an arrow function that invokes the required function
// NOTE: we need the semi-colon here so we don't treat the above definition as a function
;(
(exportStatement.declaration as VariableDeclaration)!
.declarations[0] as VariableDeclarator
).init = newLoad

load_fn = newLoad
body = newLoad.body as BlockStatement
// there is a load function, we need the event
} else {
// if there are no identifiers, we need to add one
if (load_fn.params.length === 0) {
load_fn.params.push(event_id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ test('paginate over unions', async function () {
export default {
"name": "TestQuery",
"kind": "HoudiniQuery",
"hash": "1d660603f2610ac59b38fd74f0b429f0c9c2cec3c64459cb222e7e26c7905e66",
"hash": "08460eca65b13b6651de34501d9c49719964dca434698bf0c4929d4aaf6e64e0",

"refetch": {
"path": ["entitiesByCursor"],
Expand All @@ -665,6 +665,12 @@ test('paginate over unions', async function () {
__typename
}
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
edges {
cursor
node {
Expand Down Expand Up @@ -4749,7 +4755,7 @@ describe('mutation artifacts', function () {
export default {
"name": "TestQuery",
"kind": "HoudiniQuery",
"hash": "6fe0aeaa708161553cd04645834b38c4ce625fce10c46056efcff9a97988d358",
"hash": "cd372a6df411857b10dc498b89090295f82ba66e2988f1c80e01c501bffe9236",

"refetch": {
"path": ["usersByCursor"],
Expand All @@ -4770,6 +4776,12 @@ describe('mutation artifacts', function () {
id
}
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
edges {
cursor
node {
Expand Down Expand Up @@ -5001,7 +5013,7 @@ describe('mutation artifacts', function () {
export default {
"name": "TestQuery",
"kind": "HoudiniQuery",
"hash": "6fe0aeaa708161553cd04645834b38c4ce625fce10c46056efcff9a97988d358",
"hash": "cd372a6df411857b10dc498b89090295f82ba66e2988f1c80e01c501bffe9236",

"refetch": {
"path": ["usersByCursor"],
Expand All @@ -5022,6 +5034,12 @@ describe('mutation artifacts', function () {
id
}
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
edges {
cursor
node {
Expand Down
Loading
Loading