Skip to content
Draft
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
4 changes: 4 additions & 0 deletions .github/workflows/deploy-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ env:
NUXT_SHOPIFY_CLIENTS_STOREFRONT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_STOREFRONT_API_VERSION }}
NUXT_SHOPIFY_CLIENTS_STOREFRONT_PUBLIC_ACCESS_TOKEN: ${{ secrets.NUXT_SHOPIFY_CLIENTS_STOREFRONT_PUBLIC_ACCESS_TOKEN }}

NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION }}
NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID }}
NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET }}

VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ env:
NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION }}
NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN }}

NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION }}
NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID }}
NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET }}

on:
release:
types: [published]
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ env:
NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION }}
NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN }}

NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION }}
NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID }}
NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET }}

on:
pull_request:
push:
Expand Down
125 changes: 124 additions & 1 deletion bun.lock

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"@graphql-codegen/import-types-preset",
"@graphql-codegen/introspection",
"@shopify/api-codegen-preset",
"@graphql-tools/graphql-tag-pluck"
"@graphql-tools/graphql-tag-pluck",
"@shopify/hydrogen"
]
},
"docs": {
Expand Down Expand Up @@ -75,6 +76,9 @@
],
"project": [
"**/*.{ts,vue}"
],
"ignoreDependencies": [
"@shopify/hydrogen"
]
},
"playgrounds/playground-v4-mock": {
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
"./storefront": {
"types": "./dist/clients/storefront.d.ts"
},
"./customer-account": {
"types": "./dist/clients/customer-account.d.ts"
},
"./admin": {
"types": "./dist/clients/admin.d.ts"
}
Expand All @@ -36,6 +39,9 @@
"storefront": [
"./dist/clients/storefront.d.ts"
],
"customer-account": [
"./dist/clients/customer-account.d.ts"
],
"admin": [
"./dist/clients/admin.d.ts"
]
Expand Down
2 changes: 1 addition & 1 deletion playgrounds/playground-v3/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default defineNuxtConfig({

serverDir: 'server/',

compatibilityDate: '2025-11-01',
compatibilityDate: '2026-03-15',

hooks: {
// Fix monorepo-specific tsconfig issue when running `nuxt prepare`
Expand Down
2 changes: 1 addition & 1 deletion playgrounds/playground-v4-mock/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default defineNuxtConfig({
},
},

compatibilityDate: '2025-11-01',
compatibilityDate: '2026-03-15',

shopify: {
clients: {
Expand Down
18 changes: 18 additions & 0 deletions playgrounds/playground-v4/app/pages/customer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
const customerAccount = useCustomerAccount()

const { data } = await customerAccount.request(`#graphql
query CustomerDetails {
customer {
...CustomerFields
}
}
${CUSTOMER_FRAGMENT}
`)
</script>

<template>
<div>
<pre>{{ data?.customer.firstName }}</pre>
</div>
</template>
7 changes: 7 additions & 0 deletions playgrounds/playground-v4/graphql/customer-account/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const CUSTOMER_FRAGMENT = `#graphql
fragment CustomerFields on Customer {
id
firstName
lastName
}
`
9 changes: 8 additions & 1 deletion playgrounds/playground-v4/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ export default defineNuxtConfig({
publicAccessToken: '',
},

customerAccount: {
apiVersion: '',
clientId: '',

autoImport: false,
},

admin: {
apiVersion: '',
accessToken: '',
Expand All @@ -34,5 +41,5 @@ export default defineNuxtConfig({
},
},

compatibilityDate: '2025-11-01',
compatibilityDate: '2026-03-15',
})
3 changes: 3 additions & 0 deletions playgrounds/playground-v4/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@
},
"dependencies": {
"nuxt": "^4.4.2"
},
"devDependencies": {
"@shopify/hydrogen": "^2026.1.2"
}
}
22 changes: 22 additions & 0 deletions src/clients/customer-account.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { ShopifyApiClient } from '../module'

export interface CustomerAccountQueries {
[key: string]: {
variables: any
return: any
}
[key: number | symbol]: never
}

export interface CustomerAccountMutations {
[key: string]: {
variables: any
return: any
}
[key: number | symbol]: never
}

export interface CustomerAccountOperations extends CustomerAccountQueries, CustomerAccountMutations {}

export type CustomerAccountApiClient = ShopifyApiClient<CustomerAccountOperations>
36 changes: 36 additions & 0 deletions src/runtime/composables/customer-account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { CustomerAccountApiClient, CustomerAccountOperations } from '@nuxtjs/shopify/customer-account'

import { useRuntimeConfig, useNuxtApp } from '#imports'
import { createClient } from '../utils/client'
import { createCustomerAccountConfig } from '../utils/clients/customer-account'
import useErrors from '../utils/errors'

export function useCustomerAccount(): CustomerAccountApiClient {
const { _shopify } = useRuntimeConfig().public

const config = createCustomerAccountConfig(_shopify)

const nuxtApp = useNuxtApp()

nuxtApp.hooks.callHook('customer-account:client:configure', { config })

const originalClient = createClient<CustomerAccountOperations>(config)

const request: CustomerAccountApiClient['request'] = async (operation, options) => {
nuxtApp.hooks.callHook('customer-account:client:request', { operation, options })

const response = await originalClient.request(operation, options)

if (response.errors) useErrors(nuxtApp.hooks, 'customer-account:client:errors', response.errors, _shopify?.errors?.throw ?? false)

nuxtApp.hooks.callHook('customer-account:client:response', { response, operation, options })

return response
}

const client = { ...originalClient, request } satisfies CustomerAccountApiClient

nuxtApp.hooks.callHook('customer-account:client:create', { client })

return client
}
37 changes: 37 additions & 0 deletions src/runtime/server/utils/customer-account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { CustomerAccountApiClient, CustomerAccountOperations } from '@nuxtjs/shopify/customer-account'

import { useNitroApp } from 'nitropack/runtime'
import { useRuntimeConfig } from '#imports'
import { createClient } from '../../utils/client'
import { createCustomerAccountConfig } from '../../utils/clients/customer-account'
import useErrors from '../../utils/errors'

export function useCustomerAccount(): CustomerAccountApiClient {
const { _shopify } = useRuntimeConfig()

const config = createCustomerAccountConfig(_shopify)

const nitroApp = useNitroApp()

nitroApp.hooks.callHook('customer-account:client:configure', { config })

const originalClient = createClient<CustomerAccountOperations>(config)

const request: CustomerAccountApiClient['request'] = async (operation, options) => {
nitroApp.hooks.callHook('customer-account:client:request', { operation, options })

const response = await originalClient.request(operation, options)

if (response.errors) useErrors(nitroApp.hooks, 'customer-account:client:errors', response.errors, _shopify?.errors?.throw ?? false)

nitroApp.hooks.callHook('customer-account:client:response', { response, operation, options })

return response
}

const client = { ...originalClient, request } satisfies CustomerAccountApiClient

nitroApp.hooks.callHook('customer-account:client:create', { client })

return client
}
49 changes: 49 additions & 0 deletions src/runtime/utils/clients/customer-account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type {
ShopifyApiClientConfig,
ShopifyConfig,
PublicShopifyConfig,
} from '../../../module'

import {
createApiUrl,
createStoreDomain,
} from '../client'

export const createCustomerAccountConfig = (config?: ShopifyConfig | PublicShopifyConfig): ShopifyApiClientConfig => {
if (!config?.clients?.customerAccount) {
throw new Error('Could not create customer account client')
}

const {
name,
logger,

clients: {
customerAccount: {
apiVersion,
headers,

clientId,
clientSecret,
},
},
} = config

if (!name || !clientId) {
throw new Error('Could not create customer account client')
}

const apiUrl = createApiUrl(createStoreDomain(name), apiVersion)

return {
storeDomain: createStoreDomain(name),
apiUrl,
apiVersion,
logger,
headers: {
...(clientId ? { 'Shopify-Storefront-Public-Token': clientId } : {}),
...(clientSecret ? { 'Shopify-Storefront-Private-Token': clientSecret } : {}),
...headers,
},
} satisfies ShopifyApiClientConfig
}
9 changes: 9 additions & 0 deletions src/schemas/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { z } from 'zod'

export enum ShopifyClientType {
Storefront = 'storefront',
CustomerAccount = 'customerAccount',
Admin = 'admin',
}

Expand Down Expand Up @@ -41,6 +42,13 @@ export const storefrontClientSchema = clientSchema.extend({
cache: clientCacheSchema.or(z.boolean()).optional(),
})

export const customerAccountClientSchema = clientSchema.extend({
clientId: z.string(),
clientSecret: z.string().optional(),
scope: z.array(z.string()).optional(),
redirectURL: z.string().optional(),
})

export const adminClientSchema = clientSchema.extend({
accessToken: z.string(),
})
Expand All @@ -53,6 +61,7 @@ export const moduleOptionsSchema = z.object({
clients: z.object({
[ShopifyClientType.Storefront]: storefrontClientSchema.optional(),
[ShopifyClientType.Admin]: adminClientSchema.optional(),
[ShopifyClientType.CustomerAccount]: customerAccountClientSchema.optional(),
}),

errors: z.object({
Expand Down
Loading