diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 91abdae6d..6b2f6ba07 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -207,7 +207,7 @@ jobs: # Run tests - name: Build packages - run: pnpm run compile + run: pnpm run build - name: End-to-End Tests ${{ matrix.framework }} run: pnpm run --filter ${{ matrix.framework }} build && pnpm --filter ${{ matrix.framework }} tests diff --git a/e2e/react/.graphqlrc.yaml b/e2e/react/.graphqlrc.yaml new file mode 100644 index 000000000..1f581f856 --- /dev/null +++ b/e2e/react/.graphqlrc.yaml @@ -0,0 +1,9 @@ +projects: + default: + schema: + - ./$houdini/graphql/schema.graphql + documents: + - '**/*.gql' + - '**/*.jsx' + - '**/*.tsx' + - ./$houdini/graphql/documents.gql diff --git a/e2e/react/package.json b/e2e/react/package.json index 1c231d6ef..c33c3da82 100644 --- a/e2e/react/package.json +++ b/e2e/react/package.json @@ -4,7 +4,7 @@ "version": "0.0.0", "type": "module", "scripts": { - "build:": "cd ../../ && ((run build && cd -) || (cd - && exit 1))", + "build:": "cd ../../ && ((pnpm run build && cd -) || (cd - && exit 1))", "build:dev": "pnpm build: && pnpm dev", "build:web": "pnpm build: && pnpm web", "build:test": "pnpm build: && pnpm test", diff --git a/e2e/react/src/api/+schema.ts b/e2e/react/src/api/+schema.ts index 2eb073e6d..1fbaa4490 100644 --- a/e2e/react/src/api/+schema.ts +++ b/e2e/react/src/api/+schema.ts @@ -1,95 +1,6 @@ import { makeExecutableSchema } from '@graphql-tools/schema' -const typeDefs = /* GraphQL */ ` - type Query { - welcome: String! - links(delay: Int): [Link!]! - sponsors: [Sponsor!]! - giveMeAnError: String - } - - type Mutation { - hello(name: String!): String! - } - - type Link { - name: String - url: String - } - - type Sponsor { - login: String! - name: String! - avatarUrl: String! - websiteUrl: String - tiersTitle: String! - } -` - -const resolvers = { - Query: { - welcome: () => 'Welcome to Houdini 🎩', - links: async (_: any, args: { delay?: number }) => { - if (args.delay) { - await new Promise((resolve) => setTimeout(resolve, args.delay)) - } - return [ - { name: 'GitHub', url: 'https://github.com/HoudiniGraphql/houdini' }, - { name: 'Documentation', url: 'https://houdinigraphql.com/' }, - { name: 'Discord', url: 'https://discord.gg/Gd8vfvxpsD' }, - ] - }, - sponsors: async () => { - const res = await fetch( - 'https://raw.githubusercontent.com/HoudiniGraphql/sponsors/main/generated/sponsors.json' - ) - const jsonData = await res.json() - - function getTier(value: number) { - if (value >= 1500) { - return 'Wizard' - } - if (value >= 500) { - return 'Mage' - } - if (value >= 25) { - return "Magician's Apprentice" - } - if (value >= 10) { - return 'Supportive Muggle' - } - return 'Past Sponsors' - } - - return jsonData.map( - (c: { - sponsor: { - login: string - name: string - avatarUrl: string - websiteUrl: string - } - monthlyDollars: number - }) => { - return { - login: c.sponsor.login, - name: c.sponsor.name, - avatarUrl: c.sponsor.avatarUrl, - websiteUrl: c.sponsor.websiteUrl, - tiersTitle: getTier(c.monthlyDollars), - } - } - ) - }, - giveMeAnError: () => { - throw new Error(`Yes, I'm an error!`) - }, - }, - Mutation: { - hello: (_: any, args: { name: string }) => { - return `👋 Hey, hello ${args.name}! ` - }, - }, -} +import { resolvers } from './resolvers' +import { typeDefs } from './typeDefs' export default makeExecutableSchema({ typeDefs, resolvers }) diff --git a/e2e/react/src/api/dico.ts b/e2e/react/src/api/dico.ts new file mode 100644 index 000000000..3f5a55006 --- /dev/null +++ b/e2e/react/src/api/dico.ts @@ -0,0 +1 @@ +export const dico = { HELLO: `👋 Hey, hello` } diff --git a/e2e/react/src/api/extra.ts b/e2e/react/src/api/extra.ts new file mode 100644 index 000000000..d1ffe8e41 --- /dev/null +++ b/e2e/react/src/api/extra.ts @@ -0,0 +1,5 @@ +export const extra = /* GraphQL */ ` + extend type Query { + welcomeTooEveryone: String! + } +` diff --git a/e2e/react/src/api/resolvers.ts b/e2e/react/src/api/resolvers.ts new file mode 100644 index 000000000..7c17aed3d --- /dev/null +++ b/e2e/react/src/api/resolvers.ts @@ -0,0 +1,67 @@ +import { dico } from './dico' + +export const resolvers = { + Query: { + welcome: () => 'Welcome to Houdini 🎩', + links: async (_: any, args: { delay?: number }) => { + if (args.delay) { + await new Promise((resolve) => setTimeout(resolve, args.delay)) + } + return [ + { name: 'GitHub', url: 'https://github.com/HoudiniGraphql/houdini' }, + { name: 'Documentation', url: 'https://houdinigraphql.com/' }, + { name: 'Discord', url: 'https://discord.gg/Gd8vfvxpsD' }, + ] + }, + sponsors: async () => { + const res = await fetch( + 'https://raw.githubusercontent.com/HoudiniGraphql/sponsors/main/generated/sponsors.json' + ) + const jsonData = await res.json() + + function getTier(value: number) { + if (value >= 1500) { + return 'Wizard' + } + if (value >= 500) { + return 'Mage' + } + if (value >= 25) { + return "Magician's Apprentice" + } + if (value >= 10) { + return 'Supportive Muggle' + } + return 'Past Sponsors' + } + + return jsonData.map( + (c: { + sponsor: { + login: string + name: string + avatarUrl: string + websiteUrl: string + } + monthlyDollars: number + }) => { + return { + login: c.sponsor.login, + name: c.sponsor.name, + avatarUrl: c.sponsor.avatarUrl, + websiteUrl: c.sponsor.websiteUrl, + tiersTitle: getTier(c.monthlyDollars), + } + } + ) + }, + giveMeAnError: () => { + throw new Error(`Yes, I'm an error!`) + }, + }, + Mutation: { + hello: (_: any, args: { name: string }) => { + return `${dico.HELLO} ${args.name}!` + }, + }, +} diff --git a/e2e/react/src/api/typeDefs.ts b/e2e/react/src/api/typeDefs.ts new file mode 100644 index 000000000..c5888515e --- /dev/null +++ b/e2e/react/src/api/typeDefs.ts @@ -0,0 +1,25 @@ +export const typeDefs = /* GraphQL */ ` + type Query { + welcome: String! + links(delay: Int): [Link!]! + sponsors: [Sponsor!]! + giveMeAnError: String + } + + type Mutation { + hello(name: String!): String! + } + + type Link { + name: String + url: String + } + + type Sponsor { + login: String! + name: String! + avatarUrl: String! + websiteUrl: String + tiersTitle: String! + } +` diff --git a/packages/houdini-react/src/plugin/index.ts b/packages/houdini-react/src/plugin/index.ts index 74f1e6c44..e5574f7c8 100644 --- a/packages/houdini-react/src/plugin/index.ts +++ b/packages/houdini-react/src/plugin/index.ts @@ -1,12 +1,12 @@ import { - type ArtifactKinds, - type Document, - type Config, - type Plugin, ArtifactKind, plugin, fragmentKey, load_manifest, + type ArtifactKinds, + type Document, + type Config, + type Plugin, type ProjectManifest, } from 'houdini' import path from 'node:path' diff --git a/packages/houdini-react/src/plugin/vite.tsx b/packages/houdini-react/src/plugin/vite.tsx index d76d3448c..8c2a28c9f 100644 --- a/packages/houdini-react/src/plugin/vite.tsx +++ b/packages/houdini-react/src/plugin/vite.tsx @@ -1,9 +1,9 @@ import { PluginHooks, - path, fs, - load_manifest, isSecondaryBuild, + load_manifest, + path, type ProjectManifest, type RouterManifest, routerConventions, diff --git a/packages/houdini/src/codegen/generators/definitions/index.ts b/packages/houdini/src/codegen/generators/definitions/index.ts index 3892ca6a1..0ef7f3c14 100644 --- a/packages/houdini/src/codegen/generators/definitions/index.ts +++ b/packages/houdini/src/codegen/generators/definitions/index.ts @@ -1,3 +1,5 @@ +import * as graphql from 'graphql' + import type { Config } from '../../../lib' import { fs } from '../../../lib' import enums from './enums' @@ -5,7 +7,10 @@ import enums from './enums' // schemaGenerator updates the schema file to contain all of the generated export default async function schemaGenerator(config: Config) { await Promise.all([ - fs.writeFile(config.definitionsSchemaPath, config.newSchema), + fs.writeFile( + config.definitionsSchemaPath, + config.localSchema ? graphql.printSchema(config.schema) : config.newSchema + ), fs.writeFile(config.definitionsDocumentsPath, config.newDocuments), enums(config), ]) diff --git a/packages/houdini/src/lib/router/server.ts b/packages/houdini/src/lib/router/server.ts index e032b628c..988d84bd4 100644 --- a/packages/houdini/src/lib/router/server.ts +++ b/packages/houdini/src/lib/router/server.ts @@ -2,7 +2,7 @@ import type * as graphql from 'graphql' import path from 'node:path' import type { Config } from '../config' -import { type ConfigFile, localApiEndpoint } from '../types' +import { localApiEndpoint, type ConfigFile } from '../types' export function isSecondaryBuild() { return process.env.HOUDINI_SECONDARY_BUILD && process.env.HOUDINI_SECONDARY_BUILD !== 'false' @@ -26,6 +26,8 @@ export async function buildLocalSchema(config: Config): Promise { process.env.HOUDINI_SECONDARY_BUILD = 'true' + const schema = path.join(config.localApiDir, '+schema') + // build the schema somewhere we can import from await build({ logLevel: 'silent', @@ -33,7 +35,7 @@ export async function buildLocalSchema(config: Config): Promise { outDir: path.join(config.rootDir, 'temp'), rollupOptions: { input: { - schema: path.join(config.localApiDir, '+schema'), + schema, }, output: { entryFileNames: 'assets/[name].js', @@ -41,7 +43,9 @@ export async function buildLocalSchema(config: Config): Promise { }, ssr: true, lib: { - entry: path.join(config.localApiDir, '+schema'), + entry: { + schema, + }, formats: ['es'], }, }, @@ -55,7 +59,7 @@ export async function loadLocalSchema(config: Config): Promise c.id)) + } + if (depOfSchema.includes(module.id)) { + depOfSchema.push(...module.importedIdResolutions.map((c) => c.id)) + } + }, + async closeBundle() { + ref.list = [ + ...new Set( + depOfSchema.filter((c) => !c.includes('node_modules') && c !== 'graphql') + ), + ] + depOfSchema = [] + }, + } +}