From 5de87101ee678eb8f21c6192470d63081359782e Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Thu, 16 Jan 2025 23:23:42 -0800 Subject: [PATCH 01/11] fix bug when url parameters enclude url encodings --- .changeset/lemon-clouds-taste.md | 5 +++++ e2e/_api/graphql.mjs | 4 ++++ e2e/_api/schema.graphql | 3 ++- e2e/react/src/routes/route_params/test.ts | 2 +- .../route_params_with_space/[title]/+page.gql | 5 +++++ .../route_params_with_space/[title]/+page.tsx | 16 ++++++++++++++++ .../route_params_with_space/[title]/test.ts | 10 ++++++++++ e2e/react/src/utils/routes.ts | 1 + .../houdini/src/runtime/router/match.test.ts | 11 +++++++++++ packages/houdini/src/runtime/router/match.ts | 2 +- 10 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 .changeset/lemon-clouds-taste.md create mode 100644 e2e/react/src/routes/route_params_with_space/[title]/+page.gql create mode 100644 e2e/react/src/routes/route_params_with_space/[title]/+page.tsx create mode 100644 e2e/react/src/routes/route_params_with_space/[title]/test.ts diff --git a/.changeset/lemon-clouds-taste.md b/.changeset/lemon-clouds-taste.md new file mode 100644 index 0000000000..9090497a30 --- /dev/null +++ b/.changeset/lemon-clouds-taste.md @@ -0,0 +1,5 @@ +--- +'houdini-react': patch +--- + +Fix bug when url encoded route parameters contain url encodings diff --git a/e2e/_api/graphql.mjs b/e2e/_api/graphql.mjs index 48d7c0b8b8..5bb1567ea7 100644 --- a/e2e/_api/graphql.mjs +++ b/e2e/_api/graphql.mjs @@ -112,6 +112,7 @@ export const typeDefs = /* GraphQL */ ` union UnionAorB = A | B type Query { + book(title: String!): Book hello: String aOrB: [UnionAorB!]! avgYearsBirthDate: Float! @@ -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) }, diff --git a/e2e/_api/schema.graphql b/e2e/_api/schema.graphql index 67a5974c3c..82ad18459c 100644 --- a/e2e/_api/schema.graphql +++ b/e2e/_api/schema.graphql @@ -100,6 +100,7 @@ input UserNameFilter { union UnionAorB = A | B type Query { + book(title: String!): Book hello: String aOrB: [UnionAorB!]! avgYearsBirthDate: Float! @@ -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!]! diff --git a/e2e/react/src/routes/route_params/test.ts b/e2e/react/src/routes/route_params/test.ts index d08bdd80b9..5659fe11d7 100644 --- a/e2e/react/src/routes/route_params/test.ts +++ b/e2e/react/src/routes/route_params/test.ts @@ -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 diff --git a/e2e/react/src/routes/route_params_with_space/[title]/+page.gql b/e2e/react/src/routes/route_params_with_space/[title]/+page.gql new file mode 100644 index 0000000000..8f50f46c9f --- /dev/null +++ b/e2e/react/src/routes/route_params_with_space/[title]/+page.gql @@ -0,0 +1,5 @@ +query RouteParamsWithSpace($title: String!) { + book(title: $title) { + title + } +} diff --git a/e2e/react/src/routes/route_params_with_space/[title]/+page.tsx b/e2e/react/src/routes/route_params_with_space/[title]/+page.tsx new file mode 100644 index 0000000000..2ea17789d3 --- /dev/null +++ b/e2e/react/src/routes/route_params_with_space/[title]/+page.tsx @@ -0,0 +1,16 @@ +import { useRoute } from '$houdini' + +import type { PageProps } from './$types' + +export default function ({ RouteParamsWithSpace }: PageProps) { + const route = useRoute() + + const { book } = RouteParamsWithSpace + return ( +
+
+ {route.params.title}: {book?.title} +
+
+ ) +} diff --git a/e2e/react/src/routes/route_params_with_space/[title]/test.ts b/e2e/react/src/routes/route_params_with_space/[title]/test.ts new file mode 100644 index 0000000000..c6312f781d --- /dev/null +++ b/e2e/react/src/routes/route_params_with_space/[title]/test.ts @@ -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) + + // be default we see user 1 + await expect_to_be(page, 'Callimachus Pinakes:Callimachus Pinakes') +}) diff --git a/e2e/react/src/utils/routes.ts b/e2e/react/src/utils/routes.ts index e1c114eec8..6302bbf86e 100644 --- a/e2e/react/src/utils/routes.ts +++ b/e2e/react/src/utils/routes.ts @@ -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', diff --git a/packages/houdini/src/runtime/router/match.test.ts b/packages/houdini/src/runtime/router/match.test.ts index b7a54592fa..dd29075ad3 100644 --- a/packages/houdini/src/runtime/router/match.test.ts +++ b/packages/houdini/src/runtime/router/match.test.ts @@ -26,6 +26,17 @@ describe('route_params', () => { layout: null, }, }, + { + name: 'Parameter with space', + pattern: '/user/[id]', + url: '/user/4%202', + expected: { + variables: { + id: '4 2', + }, + layout: null, + }, + }, { name: 'Route with a single required parameter (missing)', pattern: '/user/[id]', diff --git a/packages/houdini/src/runtime/router/match.ts b/packages/houdini/src/runtime/router/match.ts index 7445642d8b..87eccc2030 100644 --- a/packages/houdini/src/runtime/router/match.ts +++ b/packages/houdini/src/runtime/router/match.ts @@ -219,7 +219,7 @@ export function exec(match: RegExpMatchArray, params: RouteParam[]) { // an optional or rest parameter if (param.rest) result[param.name] = '' } else { - result[param.name] = value + result[param.name] = decodeURIComponent(value) } } From 2e3eef18741202b5ca7fee490ab468ea6aacee36 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 00:03:51 -0800 Subject: [PATCH 02/11] fix issue when multiple operations targetting the same list are in a mutation --- .changeset/lazy-seas-kick.md | 5 + packages/houdini/src/runtime/cache/cache.ts | 48 ++++- packages/houdini/src/runtime/cache/lists.ts | 21 +- .../src/runtime/cache/tests/list.test.ts | 180 ++++++++++++++++++ 4 files changed, 248 insertions(+), 6 deletions(-) create mode 100644 .changeset/lazy-seas-kick.md diff --git a/.changeset/lazy-seas-kick.md b/.changeset/lazy-seas-kick.md new file mode 100644 index 0000000000..040a50ebd5 --- /dev/null +++ b/.changeset/lazy-seas-kick.md @@ -0,0 +1,5 @@ +--- +'houdini': patch +--- + +Fix issue when multiple operations targetting the same list are found in a mutation diff --git a/packages/houdini/src/runtime/cache/cache.ts b/packages/houdini/src/runtime/cache/cache.ts index 581314933b..86b2767e0f 100644 --- a/packages/houdini/src/runtime/cache/cache.ts +++ b/packages/houdini/src/runtime/cache/cache.ts @@ -131,8 +131,13 @@ export class Cache { } // return the list handler to mutate a named list in the cache - list(name: string, parentID?: string, allLists?: boolean): ListCollection { - const handler = this._internal_unstable.lists.get(name, parentID, allLists) + list( + name: string, + parentID?: string, + allLists?: boolean, + skipMatches?: Set + ): ListCollection { + const handler = this._internal_unstable.lists.get(name, parentID, allLists, skipMatches) if (!handler) { throw new Error( `Cannot find list with name: ${name}${ @@ -846,6 +851,12 @@ class CacheInternal { } } + // there could be multiple operations that refer to the same field entry in the cache + // which would result in duplicate data. this is a useful pattern to ensure that the required + // fields are included for both lists so we want to support it. we need to track the operation targets + // we've already processed so we don't duplicate work + const processedOperations = new Set() + // handle any operations relative to this node for (const operation of operations || []) { // turn the ID into something we can use @@ -883,7 +894,12 @@ class CacheInternal { operation.list ) { this.cache - .list(operation.list, parentID, operation.target === 'all') + .list( + operation.list, + parentID, + operation.target === 'all', + processedOperations + ) .when(operation.when) .addToList( fieldSelection, @@ -902,7 +918,12 @@ class CacheInternal { operation.list ) { this.cache - .list(operation.list, parentID, operation.target === 'all') + .list( + operation.list, + parentID, + operation.target === 'all', + processedOperations + ) .when(operation.when) .toggleElement({ selection: fieldSelection, @@ -921,7 +942,12 @@ class CacheInternal { operation.list ) { this.cache - .list(operation.list, parentID, operation.target === 'all') + .list( + operation.list, + parentID, + operation.target === 'all', + processedOperations + ) .when(operation.when) .remove(target, variables, layer) } @@ -942,6 +968,18 @@ class CacheInternal { this.cache.delete(targetID, layer) } } + + if (operation.list) { + // figure out the field referenced by the list + const matchingLists = this.cache.list( + operation.list, + parentID, + operation.target === 'all' + ) + for (const list of matchingLists.lists) { + processedOperations.add(list.fieldRef) + } + } } } diff --git a/packages/houdini/src/runtime/cache/lists.ts b/packages/houdini/src/runtime/cache/lists.ts index a06c2f0cfa..528ce93a13 100644 --- a/packages/houdini/src/runtime/cache/lists.ts +++ b/packages/houdini/src/runtime/cache/lists.ts @@ -18,7 +18,22 @@ export class ListManager { private listsByField: Map> = new Map() - get(listName: string, id?: string, allLists?: boolean) { + get(listName: string, id?: string, allLists?: boolean, skipMatches?: Set) { + // get the list collection + const lists = this.getLists(listName, id, allLists) + if (!lists) { + return null + } + + // if we were given a set of matches to skip, we should do that now + if (skipMatches) { + return new ListCollection(lists.lists.filter((list) => !skipMatches.has(list.fieldRef))) + } else { + return lists + } + } + + getLists(listName: string, id?: string, allLists?: boolean) { const matches = this.lists.get(listName) // if we don't have a list by that name, we're done @@ -197,6 +212,10 @@ export class List { this.abstract = abstract } + get fieldRef() { + return `${this.recordID}.${this.key}` + } + // looks for the collection of all of the lists in the cache that satisfies a when // condition when(when?: ListWhen): ListCollection { diff --git a/packages/houdini/src/runtime/cache/tests/list.test.ts b/packages/houdini/src/runtime/cache/tests/list.test.ts index 296b872d8e..d97a94cff6 100644 --- a/packages/houdini/src/runtime/cache/tests/list.test.ts +++ b/packages/houdini/src/runtime/cache/tests/list.test.ts @@ -5438,3 +5438,183 @@ test('inserting in list at a specific layer affects just that layer', function ( ]) expect(layer.links['User:1']).not.toBeDefined() }) + +test("two operations referencing the same list don't commit twice", function () { + // instantiate a cache + const cache = new Cache(config) + + // create a list we will add to + cache.write({ + selection: { + fields: { + viewer: { + type: 'User', + visible: true, + keyRaw: 'viewer', + selection: { + fields: { + id: { + type: 'ID', + visible: true, + keyRaw: 'id', + }, + }, + }, + }, + }, + }, + data: { + viewer: { + id: '1', + }, + }, + }) + + // subscribe to the data to register the list + cache.subscribe( + { + rootType: 'User', + selection: { + fields: { + friends: { + type: 'User', + visible: true, + keyRaw: 'friends', + list: { + name: 'All_Users', + connection: false, + type: 'User', + }, + selection: { + fields: { + id: { + type: 'ID', + visible: true, + keyRaw: 'id', + }, + firstName: { + type: 'String', + visible: true, + keyRaw: 'firstName', + }, + }, + }, + }, + }, + }, + parentID: cache._internal_unstable.id('User', '1')!, + set: vi.fn(), + }, + {} + ) + + // subscribe to the data to register the list + cache.subscribe( + { + rootType: 'User', + selection: { + fields: { + friends: { + type: 'User', + visible: true, + keyRaw: 'friends', + list: { + name: 'Other_Users', + connection: false, + type: 'User', + }, + selection: { + fields: { + id: { + type: 'ID', + visible: true, + keyRaw: 'id', + }, + firstName: { + type: 'String', + visible: true, + keyRaw: 'firstName', + }, + }, + }, + }, + }, + }, + parentID: cache._internal_unstable.id('User', '1')!, + set: vi.fn(), + }, + {} + ) + + // write some data with 2 operations + cache.write({ + selection: { + fields: { + newUser: { + type: 'User', + visible: true, + keyRaw: 'newUser', + operations: [ + { + action: 'insert', + list: 'All_Users', + }, + { + action: 'insert', + list: 'Other_Users', + }, + ], + selection: { + fields: { + id: { + type: 'ID', + visible: true, + keyRaw: 'id', + }, + }, + }, + }, + }, + }, + data: { + newUser: { + id: '2', + }, + }, + }) + + const result = cache.read({ + selection: { + fields: { + friends: { + type: 'User', + visible: true, + keyRaw: 'friends', + list: { + name: 'Other_Users', + connection: false, + type: 'User', + }, + selection: { + fields: { + id: { + type: 'ID', + visible: true, + keyRaw: 'id', + }, + }, + }, + }, + }, + }, + parent: cache._internal_unstable.id('User', '1')!, + }) + + expect(result.data).toEqual({ + friends: [ + { + id: '2', + }, + ], + }) +}) From e5c3150401efc362061118c6b8748901cc852110 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 00:12:25 -0800 Subject: [PATCH 03/11] include pageInfo in default cursor query fields --- .changeset/clean-weeks-fry.md | 5 +++ .../src/codegen/transforms/paginate.ts | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .changeset/clean-weeks-fry.md diff --git a/.changeset/clean-weeks-fry.md b/.changeset/clean-weeks-fry.md new file mode 100644 index 0000000000..29a661076b --- /dev/null +++ b/.changeset/clean-weeks-fry.md @@ -0,0 +1,5 @@ +--- +'houdini': patch +--- + +Include pageInfo in default pagination fields diff --git a/packages/houdini/src/codegen/transforms/paginate.ts b/packages/houdini/src/codegen/transforms/paginate.ts index f4e4ba91fe..a211384aea 100644 --- a/packages/houdini/src/codegen/transforms/paginate.ts +++ b/packages/houdini/src/codegen/transforms/paginate.ts @@ -746,6 +746,46 @@ function objectNode([type, defaultValue]: [ } export const pageInfoSelection = [ + { + kind: graphql.Kind.FIELD, + name: { + kind: graphql.Kind.NAME, + value: 'pageInfo', + }, + selectionSet: { + kind: graphql.Kind.SELECTION_SET, + selections: [ + { + kind: graphql.Kind.FIELD, + name: { + kind: graphql.Kind.NAME, + value: 'hasPreviousPage', + }, + }, + { + kind: graphql.Kind.FIELD, + name: { + kind: graphql.Kind.NAME, + value: 'hasNextPage', + }, + }, + { + kind: graphql.Kind.FIELD, + name: { + kind: graphql.Kind.NAME, + value: 'startCursor', + }, + }, + { + kind: graphql.Kind.FIELD, + name: { + kind: graphql.Kind.NAME, + value: 'endCursor', + }, + }, + ], + }, + }, { kind: graphql.Kind.FIELD, name: { From d7e55b2e059f54cb71a356ee832e2ec62632af05 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 00:20:14 -0800 Subject: [PATCH 04/11] update snapshots --- .../artifacts/tests/artifacts.test.ts | 24 +++- .../artifacts/tests/pagination.test.ts | 32 ++++- .../artifacts/tests/selection.test.ts | 8 +- .../src/codegen/transforms/lists.test.ts | 12 ++ .../src/codegen/transforms/paginate.test.ts | 134 +++++++++++++++++- 5 files changed, 198 insertions(+), 12 deletions(-) diff --git a/packages/houdini/src/codegen/generators/artifacts/tests/artifacts.test.ts b/packages/houdini/src/codegen/generators/artifacts/tests/artifacts.test.ts index fbe8fdf579..6cf81bec1c 100644 --- a/packages/houdini/src/codegen/generators/artifacts/tests/artifacts.test.ts +++ b/packages/houdini/src/codegen/generators/artifacts/tests/artifacts.test.ts @@ -641,7 +641,7 @@ test('paginate over unions', async function () { export default { "name": "TestQuery", "kind": "HoudiniQuery", - "hash": "1d660603f2610ac59b38fd74f0b429f0c9c2cec3c64459cb222e7e26c7905e66", + "hash": "08460eca65b13b6651de34501d9c49719964dca434698bf0c4929d4aaf6e64e0", "refetch": { "path": ["entitiesByCursor"], @@ -665,6 +665,12 @@ test('paginate over unions', async function () { __typename } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -4749,7 +4755,7 @@ describe('mutation artifacts', function () { export default { "name": "TestQuery", "kind": "HoudiniQuery", - "hash": "6fe0aeaa708161553cd04645834b38c4ce625fce10c46056efcff9a97988d358", + "hash": "cd372a6df411857b10dc498b89090295f82ba66e2988f1c80e01c501bffe9236", "refetch": { "path": ["usersByCursor"], @@ -4770,6 +4776,12 @@ describe('mutation artifacts', function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -5001,7 +5013,7 @@ describe('mutation artifacts', function () { export default { "name": "TestQuery", "kind": "HoudiniQuery", - "hash": "6fe0aeaa708161553cd04645834b38c4ce625fce10c46056efcff9a97988d358", + "hash": "cd372a6df411857b10dc498b89090295f82ba66e2988f1c80e01c501bffe9236", "refetch": { "path": ["usersByCursor"], @@ -5022,6 +5034,12 @@ describe('mutation artifacts', function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { diff --git a/packages/houdini/src/codegen/generators/artifacts/tests/pagination.test.ts b/packages/houdini/src/codegen/generators/artifacts/tests/pagination.test.ts index 86ff7be5d0..a3ffe14d0b 100644 --- a/packages/houdini/src/codegen/generators/artifacts/tests/pagination.test.ts +++ b/packages/houdini/src/codegen/generators/artifacts/tests/pagination.test.ts @@ -30,7 +30,7 @@ test('pagination arguments stripped from key', async function () { export default { "name": "PaginatedFragment", "kind": "HoudiniFragment", - "hash": "fd66badc676c41d3a2449afc85e1901f9fc1580e030c7658acff1ce4fb1b4d3f", + "hash": "ed9498ccbdc4d5a35b7fb6d1280ee254731c880e2484b4b34f8c462fb34c7985", "refetch": { "path": ["friendsByCursor"], @@ -56,6 +56,12 @@ test('pagination arguments stripped from key', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -238,7 +244,7 @@ test('pagination arguments stays in key as it s a SinglePage Mode', async functi export default { "name": "PaginatedFragment", "kind": "HoudiniFragment", - "hash": "fd66badc676c41d3a2449afc85e1901f9fc1580e030c7658acff1ce4fb1b4d3f", + "hash": "ed9498ccbdc4d5a35b7fb6d1280ee254731c880e2484b4b34f8c462fb34c7985", "refetch": { "path": ["friendsByCursor"], @@ -264,6 +270,12 @@ test('pagination arguments stays in key as it s a SinglePage Mode', async functi id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -567,7 +579,7 @@ test('cursor as scalar gets the right pagination query argument types', async fu export default { "name": "ScalarPagination", "kind": "HoudiniQuery", - "hash": "52d1832ab8d47b638e7f73bf90390ffd2e3a41ec194f0cc821ebe51ad792d771", + "hash": "bc8472e5f0b3987b33e8a9301e9d98033f6f8de399a96d73b5b5fbc35c3514a6", "refetch": { "path": ["user", "friendsByCursorScalar"], @@ -601,6 +613,12 @@ test('cursor as scalar gets the right pagination query argument types', async fu id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -855,7 +873,7 @@ test("sibling aliases don't get marked", async function () { export default { "name": "PaginatedFragment", "kind": "HoudiniFragment", - "hash": "5efa295fd82f7f78f41f944f345fbea76fbf5c5988ecfed7e0ac3ae757423f5b", + "hash": "4f933c65c6e551abd45d58d0136695d84e20e62b793f75cebb936091bfdfd2a5", "refetch": { "path": ["friendsByCursor"], @@ -888,6 +906,12 @@ test("sibling aliases don't get marked", async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { diff --git a/packages/houdini/src/codegen/generators/artifacts/tests/selection.test.ts b/packages/houdini/src/codegen/generators/artifacts/tests/selection.test.ts index 4dc46ba5b8..fde1eae47f 100644 --- a/packages/houdini/src/codegen/generators/artifacts/tests/selection.test.ts +++ b/packages/houdini/src/codegen/generators/artifacts/tests/selection.test.ts @@ -271,7 +271,7 @@ test('fragments in lists', async function () { export default { "name": "TestQuery", "kind": "HoudiniQuery", - "hash": "91b23604b402b84e2d83099ca8afc0953ce7e9abdad65e7ea3fb20ba5893e4ce", + "hash": "701b45dea27a1c86d40dc4ad9db1e3e1c16be62af21f8b31c784749ddcc4217a", "raw": \`query TestQuery { usersByCursor { @@ -281,6 +281,12 @@ test('fragments in lists', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { diff --git a/packages/houdini/src/codegen/transforms/lists.test.ts b/packages/houdini/src/codegen/transforms/lists.test.ts index c240b80c6b..800ee1fc36 100644 --- a/packages/houdini/src/codegen/transforms/lists.test.ts +++ b/packages/houdini/src/codegen/transforms/lists.test.ts @@ -325,6 +325,12 @@ test('connections marked with list directive get cursor information', async func } } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -433,6 +439,12 @@ test('list flags connections', async function () { } } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { diff --git a/packages/houdini/src/codegen/transforms/paginate.test.ts b/packages/houdini/src/codegen/transforms/paginate.test.ts index e296578a86..00d15b1544 100644 --- a/packages/houdini/src/codegen/transforms/paginate.test.ts +++ b/packages/houdini/src/codegen/transforms/paginate.test.ts @@ -33,6 +33,12 @@ test('adds pagination info to full', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -161,6 +167,12 @@ test('paginate adds forwards cursor args to the full cursor fragment', async fun id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -209,6 +221,12 @@ test('paginate adds backwards cursor args to the full cursor fragment', async fu id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -257,6 +275,12 @@ test('paginate adds forwards cursor args to the fragment', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -305,6 +329,12 @@ test('paginate adds backwards cursor args to the fragment', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -369,6 +399,12 @@ test('adds required fragment args to pagination query', async function () { name } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -419,6 +455,12 @@ test('sets before with default value', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -471,6 +513,12 @@ test('embeds pagination query as a separate document', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -515,7 +563,7 @@ test('embeds node pagination query as a separate document', async function () { export default { "name": "UserFriends_Pagination_Query", "kind": "HoudiniQuery", - "hash": "21597bdb8e302eee972c328a43fcf8e2f95bfbefa428ee4ecfe1cb06e2b23a36", + "hash": "30767cc439cd988fba3fa4aed967f50c4a399802943d1648d6ef844e404e4195", "refetch": { "path": ["friendsByForwardsCursor"], @@ -543,6 +591,12 @@ test('embeds node pagination query as a separate document', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -799,7 +853,7 @@ test('embeds custom pagination query as a separate document', async function () export default { "name": "UserGhost_Pagination_Query", "kind": "HoudiniQuery", - "hash": "8c2b9403592ff399ab2b2033a5244a7f3ff8f887edd6fd514b8ca67aa97b038a", + "hash": "ed7cb843392ec40cc41958b5447504a23d6816c3d2b0372dd3c8087ed7e4fe28", "refetch": { "path": ["friendsConnection"], @@ -829,6 +883,12 @@ test('embeds custom pagination query as a separate document', async function () aka } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1068,6 +1128,12 @@ test('query with forwards cursor paginate', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1117,6 +1183,12 @@ test('suppress pagination dedupe', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1164,6 +1236,12 @@ test('query with custom first args', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1211,6 +1289,12 @@ test('query with backwards cursor paginate', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1285,6 +1369,12 @@ test('query with backwards cursor on full paginate', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1332,6 +1422,12 @@ test('query with forwards cursor on full paginate', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1379,6 +1475,12 @@ test("don't generate unsupported directions", async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1426,6 +1528,12 @@ test("forwards cursor paginated query doesn't overlap variables", async function id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1473,6 +1581,12 @@ test("backwards cursor paginated query doesn't overlap variables", async functio id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1655,7 +1769,7 @@ test('generated query has same refetch spec', async function () { export default { "name": "UserFriends_Pagination_Query", "kind": "HoudiniQuery", - "hash": "cbb05d7edec775450f7062e8daa0637bd08190d89de5ff600ec2e091cbe02952", + "hash": "63ad0e8780be98430b6e2272df8bc6b3b4d8d78baa4f616d2ac5a6beb45bcb7e", "refetch": { "path": ["usersByCursor"], @@ -1680,6 +1794,12 @@ test('generated query has same refetch spec', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { @@ -1969,7 +2089,7 @@ test('default defaultPaginateMode to SinglePage', async function () { export default { "name": "UserFriends", "kind": "HoudiniFragment", - "hash": "b20e0ad5f66a7bc7454144f370b46c9000dbf9b73df620c693ca7a9bcc965842", + "hash": "1edf81feb135cb2a595dcaf31e1e559b2e2f0038db41d30f9d9f1bb9f0607ddc", "refetch": { "path": ["usersByCursor"], @@ -1989,6 +2109,12 @@ test('default defaultPaginateMode to SinglePage', async function () { id } } + pageInfo { + hasPreviousPage + hasNextPage + startCursor + endCursor + } edges { cursor node { From ccb1a1abdd7fe76c28bf8c63bd9c6197374f216e Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 00:32:15 -0800 Subject: [PATCH 05/11] fix test route --- e2e/react/src/routes/route_params_with_space/[title]/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/react/src/routes/route_params_with_space/[title]/test.ts b/e2e/react/src/routes/route_params_with_space/[title]/test.ts index c6312f781d..169aee0fc7 100644 --- a/e2e/react/src/routes/route_params_with_space/[title]/test.ts +++ b/e2e/react/src/routes/route_params_with_space/[title]/test.ts @@ -3,7 +3,7 @@ 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) + await goto(page, routes.route_params_with_space) // be default we see user 1 await expect_to_be(page, 'Callimachus Pinakes:Callimachus Pinakes') From 16c507e3d652b465eb42d1983da1a45ee8720e2b Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 10:25:25 -0800 Subject: [PATCH 06/11] Fix issue with sessions when load function was declared to be the result of a function (or a direct value) --- .changeset/big-queens-shop.md | 5 ++ .../src/plugin/transforms/kit/session.test.ts | 51 +++++++++++++++++-- .../src/plugin/transforms/kit/session.ts | 41 +++++++++++++-- packages/houdini/src/vite/ast.ts | 19 ++++--- 4 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 .changeset/big-queens-shop.md diff --git a/.changeset/big-queens-shop.md b/.changeset/big-queens-shop.md new file mode 100644 index 0000000000..5a6d105a82 --- /dev/null +++ b/.changeset/big-queens-shop.md @@ -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) diff --git a/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts b/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts index ab9c07205c..207ae28356 100644 --- a/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts +++ b/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts @@ -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 @@ -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; + `) +}) \ No newline at end of file diff --git a/packages/houdini-svelte/src/plugin/transforms/kit/session.ts b/packages/houdini-svelte/src/plugin/transforms/kit/session.ts index 1fd9239c71..07a016232e 100644 --- a/packages/houdini-svelte/src/plugin/transforms/kit/session.ts +++ b/packages/houdini-svelte/src/plugin/transforms/kit/session.ts @@ -4,6 +4,7 @@ import * as recast from 'recast' import { is_root_layout_script, is_root_layout_server } from '../../kit' import type { SvelteTransformPage } from '../types' +import { VariableDeclarationKind } from 'ast-types/lib/gen/kinds' const AST = recast.types.builders @@ -11,6 +12,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)) { @@ -96,8 +100,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([]) @@ -108,7 +113,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 } @@ -127,8 +132,36 @@ function modify_load( ) body = load_fn.body } + // 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")) + ])) + + load_fn = newLoad + body = newLoad.body as BlockStatement + + // and change the declared value to be an arrow function that invokes the required function + ((exportStatement.declaration as VariableDeclaration)!.declarations[0] as VariableDeclarator).init = newLoad // there is a load function, we need the event - else { + } else { // if there are no identifiers, we need to add one if (load_fn.params.length === 0) { load_fn.params.push(event_id) @@ -159,6 +192,6 @@ function modify_load( } } - // modify the body + // modify the body load_fn.body = cb(body, event_id) } diff --git a/packages/houdini/src/vite/ast.ts b/packages/houdini/src/vite/ast.ts index 0ac7fb38cd..1c2c0721cf 100644 --- a/packages/houdini/src/vite/ast.ts +++ b/packages/houdini/src/vite/ast.ts @@ -1,4 +1,4 @@ -import type * as recast from 'recast' +import * as recast from 'recast' type Statement = recast.types.namedTypes.Statement type Program = recast.types.namedTypes.Program @@ -8,6 +8,9 @@ type VariableDeclaration = recast.types.namedTypes.VariableDeclaration type Identifier = recast.types.namedTypes.Identifier type ArrowFunctionExpression = recast.types.namedTypes.ArrowFunctionExpression type FunctionExpression = recast.types.namedTypes.FunctionExpression +type CallExpression = recast.types.namedTypes.CallExpression + +const AST = recast.types.builders export function find_insert_index(script: Program) { let insert_index = script.body.findIndex((statement) => { @@ -25,19 +28,18 @@ export function find_insert_index(script: Program) { export function find_exported_fn( body: Statement[], name: string -): FunctionDeclaration | FunctionExpression | ArrowFunctionExpression | null { +): {declaration: FunctionDeclaration | FunctionExpression | ArrowFunctionExpression | null | Identifier | CallExpression, export: ExportNamedDeclaration} | null { for (const statement of body) { if (statement.type !== 'ExportNamedDeclaration') { continue } - const exportDeclaration = statement as ExportNamedDeclaration // if the exported thing is a function it could be what we're looking for if (exportDeclaration.declaration?.type === 'FunctionDeclaration') { const value = exportDeclaration.declaration as FunctionDeclaration if (value.id?.name === name) { - return exportDeclaration.declaration + return {declaration: exportDeclaration.declaration, export: exportDeclaration} } } @@ -78,7 +80,12 @@ export function find_exported_fn( } if (init.type === 'FunctionExpression' || init.type === 'ArrowFunctionExpression') { - return init + return {declaration: init, export: exportDeclaration} + } + + // if the initialized value is the result of a function, or a constant + if (init.type === 'Identifier' || init.type === 'CallExpression') { + return {declaration: init, export: exportDeclaration} } } // it wasn't something we care about, move along @@ -107,7 +114,7 @@ export function find_exported_fn( return null } - return exported.declaration as FunctionDeclaration + return {declaration: exported.declaration as FunctionDeclaration, export: exported} } export function find_exported_id(program: Program, name: string) { From 030f443a1b44509505efb63eaba883abc2ee3111 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 12:26:14 -0800 Subject: [PATCH 07/11] formatting --- .../src/plugin/transforms/kit/session.test.ts | 6 +-- .../src/plugin/transforms/kit/session.ts | 43 ++++++++++++------- packages/houdini/src/vite/ast.ts | 21 ++++++--- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts b/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts index 207ae28356..341bdbb2b8 100644 --- a/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts +++ b/packages/houdini-svelte/src/plugin/transforms/kit/session.test.ts @@ -341,7 +341,7 @@ test('augments load function in root layout load', async function () { `) }) -test("call expression assignment for load function", async function () { +test('call expression assignment for load function', async function () { const result = await test_transform_js( 'src/routes/+layout.js', ` @@ -364,7 +364,7 @@ test("call expression assignment for load function", async function () { `) }) -test("value assignment for load function", async function () { +test('value assignment for load function', async function () { const result = await test_transform_js( 'src/routes/+layout.js', ` @@ -385,4 +385,4 @@ test("value assignment for load function", async function () { const houdini__intermediate__load__ = someFn; `) -}) \ No newline at end of file +}) diff --git a/packages/houdini-svelte/src/plugin/transforms/kit/session.ts b/packages/houdini-svelte/src/plugin/transforms/kit/session.ts index 07a016232e..a7427caf8b 100644 --- a/packages/houdini-svelte/src/plugin/transforms/kit/session.ts +++ b/packages/houdini-svelte/src/plugin/transforms/kit/session.ts @@ -1,10 +1,10 @@ +import { VariableDeclarationKind } from 'ast-types/lib/gen/kinds' import { walk } from 'estree-walker' import { find_exported_fn, find_insert_index, ensure_imports } from 'houdini/vite' import * as recast from 'recast' import { is_root_layout_script, is_root_layout_server } from '../../kit' import type { SvelteTransformPage } from '../types' -import { VariableDeclarationKind } from 'ast-types/lib/gen/kinds' const AST = recast.types.builders @@ -134,33 +134,44 @@ function modify_load( } // 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") { + 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} + if (!exportStatement) { + return + } // add a global variable with the intermediate value - const intermediateID = AST.identifier("houdini__intermediate__load__") + 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")) - ])) + 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 - - // and change the declared value to be an arrow function that invokes the required function - ((exportStatement.declaration as VariableDeclaration)!.declarations[0] as VariableDeclarator).init = newLoad - // there is a load function, we need the event + // 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) { @@ -192,6 +203,6 @@ function modify_load( } } - // modify the body + // modify the body load_fn.body = cb(body, event_id) } diff --git a/packages/houdini/src/vite/ast.ts b/packages/houdini/src/vite/ast.ts index 1c2c0721cf..6d0f03c3fa 100644 --- a/packages/houdini/src/vite/ast.ts +++ b/packages/houdini/src/vite/ast.ts @@ -28,7 +28,16 @@ export function find_insert_index(script: Program) { export function find_exported_fn( body: Statement[], name: string -): {declaration: FunctionDeclaration | FunctionExpression | ArrowFunctionExpression | null | Identifier | CallExpression, export: ExportNamedDeclaration} | null { +): { + declaration: + | FunctionDeclaration + | FunctionExpression + | ArrowFunctionExpression + | null + | Identifier + | CallExpression + export: ExportNamedDeclaration +} | null { for (const statement of body) { if (statement.type !== 'ExportNamedDeclaration') { continue @@ -39,7 +48,7 @@ export function find_exported_fn( if (exportDeclaration.declaration?.type === 'FunctionDeclaration') { const value = exportDeclaration.declaration as FunctionDeclaration if (value.id?.name === name) { - return {declaration: exportDeclaration.declaration, export: exportDeclaration} + return { declaration: exportDeclaration.declaration, export: exportDeclaration } } } @@ -80,12 +89,12 @@ export function find_exported_fn( } if (init.type === 'FunctionExpression' || init.type === 'ArrowFunctionExpression') { - return {declaration: init, export: exportDeclaration} + return { declaration: init, export: exportDeclaration } } - + // if the initialized value is the result of a function, or a constant if (init.type === 'Identifier' || init.type === 'CallExpression') { - return {declaration: init, export: exportDeclaration} + return { declaration: init, export: exportDeclaration } } } // it wasn't something we care about, move along @@ -114,7 +123,7 @@ export function find_exported_fn( return null } - return {declaration: exported.declaration as FunctionDeclaration, export: exported} + return { declaration: exported.declaration as FunctionDeclaration, export: exported } } export function find_exported_id(program: Program, name: string) { From 3f04729dec8cbe6d2215a77929bdf49b9c98ae45 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 12:36:13 -0800 Subject: [PATCH 08/11] unused import --- packages/houdini-svelte/src/plugin/transforms/kit/session.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/houdini-svelte/src/plugin/transforms/kit/session.ts b/packages/houdini-svelte/src/plugin/transforms/kit/session.ts index a7427caf8b..386a0382b0 100644 --- a/packages/houdini-svelte/src/plugin/transforms/kit/session.ts +++ b/packages/houdini-svelte/src/plugin/transforms/kit/session.ts @@ -1,4 +1,3 @@ -import { VariableDeclarationKind } from 'ast-types/lib/gen/kinds' import { walk } from 'estree-walker' import { find_exported_fn, find_insert_index, ensure_imports } from 'houdini/vite' import * as recast from 'recast' From d60ca72992625966fdafc2dcda763bebb9184d43 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 13:54:40 -0800 Subject: [PATCH 09/11] bump adapter version to align with rest of packages --- .changeset/mighty-trains-switch.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/mighty-trains-switch.md diff --git a/.changeset/mighty-trains-switch.md b/.changeset/mighty-trains-switch.md new file mode 100644 index 0000000000..f6f97ff2b2 --- /dev/null +++ b/.changeset/mighty-trains-switch.md @@ -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 From ea0ef2931db3fbf118a4f3fa78caac143fc7ed3f Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 14:01:35 -0800 Subject: [PATCH 10/11] fix bug building when shell is defined as .tsx --- .changeset/grumpy-comics-talk.md | 5 +++++ packages/adapter-static/src/index.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changeset/grumpy-comics-talk.md diff --git a/.changeset/grumpy-comics-talk.md b/.changeset/grumpy-comics-talk.md new file mode 100644 index 0000000000..98944b8866 --- /dev/null +++ b/.changeset/grumpy-comics-talk.md @@ -0,0 +1,5 @@ +--- +'houdini-adapter-static': patch +--- + +Fix bug when shell was defined as tsx diff --git a/packages/adapter-static/src/index.ts b/packages/adapter-static/src/index.ts index babbffc27e..c2c6fefe08 100644 --- a/packages/adapter-static/src/index.ts +++ b/packages/adapter-static/src/index.ts @@ -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'], }, From a65d606c9e889ec9a3fac4a58bfdc2bb935e15d6 Mon Sep 17 00:00:00 2001 From: Alec Aivazis Date: Fri, 17 Jan 2025 14:51:48 -0800 Subject: [PATCH 11/11] formatting --- packages/adapter-static/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adapter-static/src/index.ts b/packages/adapter-static/src/index.ts index c2c6fefe08..319d82e0aa 100644 --- a/packages/adapter-static/src/index.ts +++ b/packages/adapter-static/src/index.ts @@ -55,7 +55,7 @@ adapter.pre = async ({ config, outDir, conventions }) => { lib: { entry: { // the shell could be defined as tsx or jsx so just strip the extension - shell: conventions.router_index_path(config).replace(".jsx", ""), + shell: conventions.router_index_path(config).replace('.jsx', ''), }, formats: ['es'], },