@by-association-only/graphql-app-config
v1.5.0
Published
BAO's Shopify App helpers
Readme
@by-association-only/graphql-app-config
GraphQL codegen configuration for Shopify apps. One getConfig() call in graphql.config.js wires up schema introspection, base types, and typed operations for the Admin and Storefront APIs.
Install
bun add -D @by-association-only/graphql-app-config @graphql-codegen/cli graphqlSingle API (Admin)
// graphql.config.js
import { getConfig } from '@by-association-only/graphql-app-config'
export default getConfig({
apiVersion: '2026-07',
documents: ['./src/**/*.{ts,tsx}'],
outputDir: './src/types',
})Running graphql-codegen produces, in outputDir:
| File | Purpose |
|------|---------|
| admin-{version}.schema.json | Cached introspected schema (generated once) |
| admin.types.ts | Base schema types |
| admin.generated.ts | Typed operations for your documents |
Admin consumers bind the generated operations to the client by wrapping the interface extension themselves via preset.extendInterfaceExtension — see test/fixtures/cli-app/graphql.config.js for a complete working example (it is exercised by the test suite with the real graphql-codegen CLI).
Admin and Storefront side by side
Pass an array — each entry keeps its own documents glob, API version, and output files, generated in one graphql-codegen run with no cross-contamination:
import { ApiType, getConfig } from '@by-association-only/graphql-app-config'
export default getConfig([
{
apiVersion: '2026-07',
documents: ['./src/**/*.{ts,tsx}'],
outputDir: './src/types',
},
{
apiType: ApiType.Storefront,
apiVersion: '2026-01',
documents: ['./src/storefront/**/*.{ts,tsx}'],
outputDir: './src/types',
},
])This adds storefront-{version}.schema.json, storefront.types.ts, and storefront.generated.ts alongside the admin files.
Unlike Admin, the storefront output augments @by-association-only/shopify-graphql-client out of the box — no extendInterfaceExtension needed. Import the generated file once and storefront calls are typed, @inContext included:
import { createStorefrontClient } from '@by-association-only/shopify-graphql-client'
import './types/storefront.generated'
const client = createStorefrontClient({
apiVersion: '2026-01',
privateAccessToken: env.STOREFRONT_PRIVATE_TOKEN,
shop: 'example.myshopify.com',
})
const response = await client.request(ProductsQuery, {
variables: { country: CountryCode.Gb, language: LanguageCode.En },
})How multi-API mode composes
The codegen CLI only reads the default graphql-config project, and merges any project-level documents/schema into every generates target. So in array mode:
- all generates targets live on the default project, each carrying its own
documentsandschema; - the default project itself carries neither;
- per-API projects (
admin,storefront) exposedocuments+schemafor IDE tooling only.
Single-object calls keep the exact shape previous versions produced.
Scalars
Shopify's DateTime and URL scalars map to string by default, so fields like Metaobject.createdAt, Metaobject.updatedAt and Image.url infer as string rather than unknown. The defaults apply to every generated API (Admin, Storefront, Customer); scalars absent from a schema are ignored.
Pass scalars to add or override mappings. Explicit entries win over the defaults, and other Shopify scalars keep their existing behaviour:
export default getConfig({
apiVersion: '2026-07',
documents: ['./src/**/*.{ts,tsx}'],
outputDir: './src/types',
scalars: {
// override a default
DateTime: 'Date',
// add your own
Decimal: 'number',
},
})A string maps both the input and output positions; pass { input, output } to target them independently.
Extensions
Directories under ./extensions/ containing a schema.graphql are added as their own graphql-config projects automatically.
