Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"vite": "6.3.6",
"whatwg-url": "14.0.0",
"supports-hyperlinks": "3.1.0",
"@graphql-tools/utils": "10.7.2",
"@graphql-tools/utils": "10.8.0",
"@shopify/cli-hydrogen>@shopify/cli-kit": "link:./packages/cli-kit",
"@shopify/cli-hydrogen>@shopify/plugin-cloudflare": "link:./packages/plugin-cloudflare",
"nanoid": "3.3.8"
Expand Down
1 change: 1 addition & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
]
},
"dependencies": {
"@graphql-codegen/cli": "5.0.4",
"@graphql-typed-document-node/core": "3.2.0",
"@luckycatfactory/esbuild-graphql-loader": "3.8.1",
"@oclif/core": "4.5.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/commands/app/function/typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class FunctionTypegen extends AppUnlinkedCommand {

const ourFunction = await chooseFunction(app, flags.path)

await buildGraphqlTypes(ourFunction, {stdout: process.stdout, stderr: process.stderr, app})
await buildGraphqlTypes(ourFunction)
renderSuccess({headline: 'GraphQL types generated successfully.'})

return {app}
Expand Down
35 changes: 29 additions & 6 deletions packages/app/src/cli/services/function/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import {testApp, testFunctionExtension} from '../../models/app/app.test-data.js'
import {beforeEach, describe, expect, test, vi} from 'vitest'
import {exec} from '@shopify/cli-kit/node/system'
import {dirname, joinPath} from '@shopify/cli-kit/node/path'
import {inTemporaryDirectory, mkdir, readFileSync, writeFile, removeFile} from '@shopify/cli-kit/node/fs'
import {inTemporaryDirectory, mkdir, readFile, readFileSync, writeFile, removeFile} from '@shopify/cli-kit/node/fs'
import {build as esBuild} from 'esbuild'
import {generate} from '@graphql-codegen/cli'

vi.mock('@shopify/cli-kit/node/fs')
vi.mock('@shopify/cli-kit/node/system')
Expand All @@ -36,6 +37,9 @@ vi.mock('esbuild', async () => {
build: vi.fn(),
}
})
vi.mock('@graphql-codegen/cli', () => ({
generate: vi.fn().mockResolvedValue(undefined),
}))

let stdout: any
let stderr: any
Expand Down Expand Up @@ -73,15 +77,34 @@ describe('buildGraphqlTypes', () => {
// Given
const ourFunction = await testFunctionExtension({entryPath: 'src/index.js'})

// Mock the package.json
const packageJson = {
codegen: {
schema: 'schema.graphql',
documents: 'src/*.graphql',
generates: {
'./generated/api.ts': {
plugins: ['typescript'],
},
},
},
}
vi.mocked(readFile).mockImplementation(async (path: string) => {
if (path === joinPath(ourFunction.directory, 'package.json')) {
return JSON.stringify(packageJson) as any
}
return JSON.stringify({}) as any
})

// When
const got = buildGraphqlTypes(ourFunction, {stdout, stderr, signal, app})
const got = buildGraphqlTypes(ourFunction)

// Then
await expect(got).resolves.toBeUndefined()
expect(exec).toHaveBeenCalledWith('npm', ['exec', '--', 'graphql-code-generator', '--config', 'package.json'], {
expect(readFile).toHaveBeenCalledWith(joinPath(ourFunction.directory, 'package.json'))
expect(vi.mocked(generate)).toHaveBeenCalledWith({
cwd: ourFunction.directory,
stderr,
signal,
...packageJson.codegen,
})
})

Expand All @@ -91,7 +114,7 @@ describe('buildGraphqlTypes', () => {
ourFunction.entrySourceFilePath = 'src/main.rs'

// When
const got = buildGraphqlTypes(ourFunction, {stdout, stderr, signal, app})
const got = buildGraphqlTypes(ourFunction)

// Then
await expect(got).rejects.toThrow(/GraphQL types can only be built for JavaScript functions/)
Expand Down
22 changes: 13 additions & 9 deletions packages/app/src/cli/services/function/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {renderTasks} from '@shopify/cli-kit/node/ui'
import {pickBy} from '@shopify/cli-kit/common/object'
import {runWithTimer} from '@shopify/cli-kit/node/metadata'
import {AbortError} from '@shopify/cli-kit/node/error'
import {generate} from '@graphql-codegen/cli'
import {Writable} from 'stream'

export const PREFERRED_FUNCTION_NPM_PACKAGE_MAJOR_VERSION = '2'
Expand Down Expand Up @@ -79,7 +80,7 @@ async function buildJSFunctionWithoutTasks(
if (!options.signal?.aborted) {
options.stdout.write(`Building function ${fun.localIdentifier}...`)
options.stdout.write(`Building GraphQL types...\n`)
await buildGraphqlTypes(fun, options)
await buildGraphqlTypes(fun)
}
if (!options.signal?.aborted) {
options.stdout.write(`Bundling JS function...\n`)
Expand All @@ -104,7 +105,7 @@ async function buildJSFunctionWithTasks(
{
title: 'Building GraphQL types',
task: async () => {
await buildGraphqlTypes(fun, options)
await buildGraphqlTypes(fun)
},
},
{
Expand All @@ -122,19 +123,22 @@ async function buildJSFunctionWithTasks(
])
}

export async function buildGraphqlTypes(
fun: {directory: string; isJavaScript: boolean},
options: JSFunctionBuildOptions,
) {
export async function buildGraphqlTypes(fun: {directory: string; isJavaScript: boolean}) {
if (!fun.isJavaScript) {
throw new Error('GraphQL types can only be built for JavaScript functions')
}

return runWithTimer('cmd_all_timing_network_ms')(async () => {
return exec('npm', ['exec', '--', 'graphql-code-generator', '--config', 'package.json'], {
const packageJsonPath = joinPath(fun.directory, 'package.json')
const packageJson = JSON.parse(await readFile(packageJsonPath))

if (!packageJson.codegen) {
throw new AbortError('No `codegen` config found in package.json')
}

return generate({
...packageJson.codegen,
cwd: fun.directory,
stderr: options.stderr,
signal: options.signal,
})
})
}
Expand Down
23 changes: 22 additions & 1 deletion packages/app/src/cli/services/generate/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ import {joinPath, dirname} from '@shopify/cli-kit/node/path'
import {slugify} from '@shopify/cli-kit/common/string'

vi.mock('../../models/app/validation/multi-cli-warning.js')
vi.mock('../function/build.js', async () => {
const actual: any = await vi.importActual('../function/build.js')
return {
...actual,
buildGraphqlTypes: vi.fn().mockResolvedValue(undefined),
}
})
vi.mock('@shopify/cli-kit/node/node-package-manager', async () => {
const actual: any = await vi.importActual('@shopify/cli-kit/node/node-package-manager')
return {
Expand Down Expand Up @@ -361,7 +368,7 @@ describe('initialize a extension', async () => {
await file.mkdir(joinPath(destination, 'src'))
await file.writeFile(joinPath(destination, 'src', 'index'), '')
})
const buildGraphqlTypesSpy = vi.spyOn(functionBuild, 'buildGraphqlTypes').mockResolvedValue()
const buildGraphqlTypesSpy = vi.spyOn(functionBuild, 'buildGraphqlTypes').mockResolvedValue(undefined)

// When
const extensionDir = await createFromTemplate({
Expand Down Expand Up @@ -409,6 +416,20 @@ describe('initialize a extension', async () => {
await file.mkdir(joinPath(destination, 'src'))
await file.writeFile(joinPath(destination, 'src', 'index'), '')
await file.writeFile(joinPath(destination, 'src', 'run.graphql'), '')
await file.writeFile(
joinPath(destination, 'package.json'),
JSON.stringify({
codegen: {
schema: 'schema.graphql',
documents: 'src/*.graphql',
generates: {
'./generated/api.ts': {
plugins: ['typescript'],
},
},
},
}),
)
})

// When
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/services/generate/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ async function functionExtensionInit({
taskList.push({
title: `Building GraphQL types`,
task: async () => {
await buildGraphqlTypes({directory, isJavaScript: true}, {stdout: process.stdout, stderr: process.stderr, app})
await buildGraphqlTypes({directory, isJavaScript: true})
},
})
}
Expand Down
Loading