{"_id":"@athleticgreens/customer-api-client","_rev":"5-5efd23b6a550f038de1c9964a7c7ac11","name":"@athleticgreens/customer-api-client","dist-tags":{"latest":"0.0.5"},"versions":{"0.0.1":{"name":"@athleticgreens/customer-api-client","version":"0.0.1","keywords":["shopify","node","graphql","Customer Account API"],"author":{"name":"Shopify"},"license":"MIT","_id":"@athleticgreens/customer-api-client@0.0.1","maintainers":[{"name":"sdornan","email":"sdornan@gmail.com"}],"homepage":"https://github.com/athletic-greens/shopify-app-js/tree/main/packages/api-clients/customer-api-client#readme","bugs":{"url":"https://github.com/athletic-greens/shopify-app-js/issues"},"dist":{"shasum":"09072c12450ef07247d3e9f20bbbb97e5c4a584d","tarball":"https://registry.npmjs.org/@athleticgreens/customer-api-client/-/customer-api-client-0.0.1.tgz","fileCount":46,"integrity":"sha512-mwoh6KOpyR5KNKXyDlS3ziOVevXp49K0uyngqZoErgS+xFDiwphHy/UM6RQFzuO9MLKCnwcjEsv1yO+IZqsaDw==","signatures":[{"sig":"MEYCIQDcT1HTBKWKL/yqsrNBCRI95fItG/52LJoDin0pkTsSzwIhAKaw0I9kl1WQEV8uaGSXFcSU9OFUEIPW4TtbkuYfQiLQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":384813},"jest":{"projects":[{"displayName":{"name":"test:browser","color":"blue"},"testEnvironment":"jsdom","testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)server(\\.|/)(test|spec))\\.[jt]sx?$"]},{"displayName":{"name":"test:server","color":"yellow"},"testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)browser(\\.|/)(test|spec))\\.[jt]sx?$"]}],"transform":{".*":"babel-jest"},"testPathIgnorePatterns":["\\.rollup\\.cache"]},"main":"./dist/umd/customer-api-client.min.js","types":"./dist/customer-api-client.d.ts","module":"./dist/index.mjs","browser":"./dist/umd/customer-api-client.min.js","exports":{".":{"import":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"module":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"default":"./dist/index.mjs","require":{"types":"./dist/ts/index.d.ts","default":"./dist/index.js"}}},"gitHead":"7ee73a7ca2f8f9d1900a8c9c909a93be16f98e58","scripts":{"tsc":"tsc","lint":"eslint .","test":"jest","build":"pnpm tsc -p ./tsconfig.build.json && pnpm rollup","clean":"rimraf dist/*","rollup":"rollup -c --bundleConfigAsCjs","release":"pnpm build && changeset publish","test:ci":"pnpm test","version":"changeset version","changeset":"changeset"},"_npmUser":{"name":"sdornan","email":"sdornan@gmail.com"},"repository":{"url":"git+https://github.com/athletic-greens/shopify-app-js.git","type":"git","directory":"packages/api-clients/customer-api-client"},"_npmVersion":"10.9.4","description":"Shopify Customer API Client - A lightweight JS client to interact with Shopify's Customer Account API","directories":{},"_nodeVersion":"22.21.0","dependencies":{"@shopify/graphql-client":"^1.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@babel/preset-env":"^7.28.6","rollup-plugin-dts":"^6.3.0","@shopify/babel-preset":"^25.0.2","jest-environment-jsdom":"^30.2.0"},"_npmOperationalInternal":{"tmp":"tmp/customer-api-client_0.0.1_1773960684476_0.7152211344522796","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@athleticgreens/customer-api-client","version":"0.0.2","keywords":["shopify","node","graphql","Customer Account API"],"author":{"name":"Shopify"},"license":"MIT","_id":"@athleticgreens/customer-api-client@0.0.2","maintainers":[{"name":"sdornan","email":"sdornan@gmail.com"}],"homepage":"https://github.com/athletic-greens/shopify-app-js/tree/main/packages/api-clients/customer-api-client#readme","bugs":{"url":"https://github.com/athletic-greens/shopify-app-js/issues"},"dist":{"shasum":"fcfe5bb477a320df44f9c4749ae0697075914e4f","tarball":"https://registry.npmjs.org/@athleticgreens/customer-api-client/-/customer-api-client-0.0.2.tgz","fileCount":46,"integrity":"sha512-i0h0wDQH3id/UExd1MiS8zveOfSNbaKxFVxTOoxAYP1HlY/pSp5PsrIAJcOHaeedtnY2FM5sb7vcGIE6wn1TxA==","signatures":[{"sig":"MEQCIBjy1KxNEOqaNcc3HtziRCSbUPsIZzZUziIEH3e76nuFAiBw+6cv7wDDxAZ/XuANl37E8JdMKnTlq9hstEpT04FMSQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":389253},"jest":{"projects":[{"displayName":{"name":"test:browser","color":"blue"},"testEnvironment":"jsdom","testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)server(\\.|/)(test|spec))\\.[jt]sx?$"]},{"displayName":{"name":"test:server","color":"yellow"},"testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)browser(\\.|/)(test|spec))\\.[jt]sx?$"]}],"transform":{".*":"babel-jest"},"testPathIgnorePatterns":["\\.rollup\\.cache"]},"main":"./dist/umd/customer-api-client.min.js","types":"./dist/customer-api-client.d.ts","module":"./dist/index.mjs","browser":"./dist/umd/customer-api-client.min.js","exports":{".":{"import":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"module":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"default":"./dist/index.mjs","require":{"types":"./dist/ts/index.d.ts","default":"./dist/index.js"}}},"gitHead":"7ee73a7ca2f8f9d1900a8c9c909a93be16f98e58","scripts":{"tsc":"tsc","lint":"eslint .","test":"jest","build":"pnpm tsc -p ./tsconfig.build.json && pnpm rollup","clean":"rimraf dist/*","rollup":"rollup -c --bundleConfigAsCjs","release":"pnpm build && changeset publish","test:ci":"pnpm test","version":"changeset version","changeset":"changeset"},"_npmUser":{"name":"sdornan","email":"sdornan@gmail.com"},"repository":{"url":"git+https://github.com/athletic-greens/shopify-app-js.git","type":"git","directory":"packages/api-clients/customer-api-client"},"_npmVersion":"10.9.4","description":"Shopify Customer API Client - A lightweight JS client to interact with Shopify's Customer Account API","directories":{},"_nodeVersion":"22.21.0","dependencies":{"@shopify/graphql-client":"^1.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@babel/preset-env":"^7.28.6","rollup-plugin-dts":"^6.3.0","@shopify/babel-preset":"^25.0.2","jest-environment-jsdom":"^30.2.0"},"_npmOperationalInternal":{"tmp":"tmp/customer-api-client_0.0.2_1773961306732_0.48932090197411426","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@athleticgreens/customer-api-client","version":"0.0.3","keywords":["shopify","node","graphql","Customer Account API"],"author":{"name":"Shopify"},"license":"MIT","_id":"@athleticgreens/customer-api-client@0.0.3","maintainers":[{"name":"sdornan","email":"sdornan@gmail.com"}],"homepage":"https://github.com/athletic-greens/shopify-app-js/tree/main/packages/api-clients/customer-api-client#readme","bugs":{"url":"https://github.com/athletic-greens/shopify-app-js/issues"},"dist":{"shasum":"3ef49ec6aa25ca220807a832c1fa7fafc558643f","tarball":"https://registry.npmjs.org/@athleticgreens/customer-api-client/-/customer-api-client-0.0.3.tgz","fileCount":46,"integrity":"sha512-aQn6sOabPt+bmy/+gX5OPdMX0rw9nMgz6q8pixcwJSe70qaid64S7qL5qfMldtY4bn3cKD1CYAgLIUYEiogfvA==","signatures":[{"sig":"MEUCIFHurLTMdB8CBCCUzu6M3RhcxmVtcUmr169zXmKxR3PvAiEA27VF1reXcpGnXfV4OT/EAgLdKAqU1x+7c5JtU4C1bHQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":394981},"jest":{"projects":[{"displayName":{"name":"test:browser","color":"blue"},"testEnvironment":"jsdom","testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)server(\\.|/)(test|spec))\\.[jt]sx?$"]},{"displayName":{"name":"test:server","color":"yellow"},"testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)browser(\\.|/)(test|spec))\\.[jt]sx?$"]}],"transform":{".*":"babel-jest"},"testPathIgnorePatterns":["\\.rollup\\.cache"]},"main":"./dist/umd/customer-api-client.min.js","types":"./dist/customer-api-client.d.ts","module":"./dist/index.mjs","browser":"./dist/umd/customer-api-client.min.js","exports":{".":{"import":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"module":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"default":"./dist/index.mjs","require":{"types":"./dist/ts/index.d.ts","default":"./dist/index.js"}}},"gitHead":"8f250b08df170c4780275238a0b73300f7287332","scripts":{"tsc":"tsc","lint":"eslint .","test":"jest","build":"pnpm tsc -p ./tsconfig.build.json && pnpm rollup","clean":"rimraf dist/*","rollup":"rollup -c --bundleConfigAsCjs","release":"pnpm build && changeset publish","test:ci":"pnpm test","version":"changeset version","changeset":"changeset"},"_npmUser":{"name":"sdornan","email":"sdornan@gmail.com"},"repository":{"url":"git+https://github.com/athletic-greens/shopify-app-js.git","type":"git","directory":"packages/api-clients/customer-api-client"},"_npmVersion":"11.12.1","description":"Shopify Customer API Client - A lightweight JS client to interact with Shopify's Customer Account API","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@shopify/graphql-client":"^1.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@babel/preset-env":"^7.28.6","rollup-plugin-dts":"^6.3.0","@shopify/babel-preset":"^25.0.2","jest-environment-jsdom":"^30.2.0"},"_npmOperationalInternal":{"tmp":"tmp/customer-api-client_0.0.3_1778358939319_0.05630178455525092","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@athleticgreens/customer-api-client","version":"0.0.4","keywords":["shopify","node","graphql","Customer Account API"],"author":{"name":"Shopify"},"license":"MIT","_id":"@athleticgreens/customer-api-client@0.0.4","maintainers":[{"name":"sdornan","email":"sdornan@gmail.com"}],"homepage":"https://github.com/athletic-greens/shopify-app-js/tree/main/packages/api-clients/customer-api-client#readme","bugs":{"url":"https://github.com/athletic-greens/shopify-app-js/issues"},"dist":{"shasum":"b248fde7651008ca10709c054bc6ac82741d49d4","tarball":"https://registry.npmjs.org/@athleticgreens/customer-api-client/-/customer-api-client-0.0.4.tgz","fileCount":46,"integrity":"sha512-KsOGd0XTwUwkA9S+dT02fzsCHigplvsFSZVX/YXRQV/g+3wDuSpAqMyw+US5k63SemaJ3OYBMts2Z0uR3lu1Lg==","signatures":[{"sig":"MEUCIQCt0Uo4u/E+BnjexqtZq7h21gCTn4Eyw/lA7l/7mSrMCAIgMZ0HkW3cRj7OyV0IQems04OwO/psFTtakmxaU5MvXYY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":412270},"jest":{"projects":[{"displayName":{"name":"test:browser","color":"blue"},"testEnvironment":"jsdom","testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)server(\\.|/)(test|spec))\\.[jt]sx?$"]},{"displayName":{"name":"test:server","color":"yellow"},"testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)browser(\\.|/)(test|spec))\\.[jt]sx?$"]}],"transform":{".*":"babel-jest"},"testPathIgnorePatterns":["\\.rollup\\.cache"]},"main":"./dist/umd/customer-api-client.min.js","types":"./dist/customer-api-client.d.ts","module":"./dist/index.mjs","browser":"./dist/umd/customer-api-client.min.js","exports":{".":{"import":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"module":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"default":"./dist/index.mjs","require":{"types":"./dist/ts/index.d.ts","default":"./dist/index.js"}}},"gitHead":"92f3596c860b0bc9cfc4034055b57817a7176ad3","scripts":{"tsc":"tsc","test":"jest","build":"pnpm tsc -p ./tsconfig.build.json && pnpm rollup","clean":"rimraf dist/*","rollup":"rollup -c --bundleConfigAsCjs","release":"pnpm build && changeset publish","test:ci":"pnpm test","version":"changeset version","changeset":"changeset"},"_npmUser":{"name":"sdornan","email":"sdornan@gmail.com"},"repository":{"url":"git+https://github.com/athletic-greens/shopify-app-js.git","type":"git","directory":"packages/api-clients/customer-api-client"},"_npmVersion":"11.17.0","description":"Shopify Customer API Client - A lightweight JS client to interact with Shopify's Customer Account API","directories":{},"_nodeVersion":"26.5.0","dependencies":{"@shopify/graphql-client":"^1.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@babel/preset-env":"^7.28.6","rollup-plugin-dts":"^6.3.0","@shopify/babel-preset":"^25.0.2","jest-environment-jsdom":"^30.2.0"},"_npmOperationalInternal":{"tmp":"tmp/customer-api-client_0.0.4_1785868537940_0.8193458085640439","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@athleticgreens/customer-api-client","version":"0.0.5","description":"Shopify Customer API Client - A lightweight JS client to interact with Shopify's Customer Account API","repository":{"type":"git","url":"git+https://github.com/athletic-greens/shopify-app-js.git","directory":"packages/api-clients/customer-api-client"},"author":{"name":"Shopify"},"license":"MIT","main":"./dist/umd/customer-api-client.min.js","browser":"./dist/umd/customer-api-client.min.js","module":"./dist/index.mjs","types":"./dist/customer-api-client.d.ts","exports":{".":{"module":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"import":{"types":"./dist/ts/index.d.ts","default":"./dist/index.mjs"},"require":{"types":"./dist/ts/index.d.ts","default":"./dist/index.js"},"default":"./dist/index.mjs"}},"scripts":{"lint":"eslint .","build":"pnpm tsc -p ./tsconfig.build.json && pnpm rollup","tsc":"tsc","test":"jest","test:ci":"pnpm test","rollup":"rollup -c --bundleConfigAsCjs","clean":"rimraf dist/*","changeset":"changeset","version":"changeset version","release":"pnpm build && changeset publish"},"jest":{"testPathIgnorePatterns":["\\.rollup\\.cache"],"projects":[{"displayName":{"name":"test:browser","color":"blue"},"testEnvironment":"jsdom","testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)server(\\.|/)(test|spec))\\.[jt]sx?$"]},{"displayName":{"name":"test:server","color":"yellow"},"testPathIgnorePatterns":["\\.rollup\\.cache","(/__tests__/.*|(\\.|/)browser(\\.|/)(test|spec))\\.[jt]sx?$"]}],"transform":{".*":"babel-jest"}},"publishConfig":{"access":"public"},"keywords":["shopify","node","graphql","Customer Account API"],"dependencies":{"@shopify/graphql-client":"^2.0.0"},"devDependencies":{"@babel/preset-env":"^7.28.6","@shopify/babel-preset":"^25.0.2","jest-environment-jsdom":"^30.2.0","rollup-plugin-dts":"^6.3.0"},"bugs":{"url":"https://github.com/athletic-greens/shopify-app-js/issues"},"homepage":"https://github.com/athletic-greens/shopify-app-js/tree/main/packages/api-clients/customer-api-client#readme","gitHead":"053c11ac3d30747238eed4b30fbaf5e6cad07ae1","_id":"@athleticgreens/customer-api-client@0.0.5","_nodeVersion":"26.7.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-D46l0Vcddg26Fno+QIOD7p3SDHD7J6yGtBmuLXsCiJ9jBf/y6Tgx/zuxpMVfpnVnlC6Bsen9xzv5hw09H3Zw9A==","shasum":"084caf328e87de3891d962474b274962bd288962","tarball":"https://registry.npmjs.org/@athleticgreens/customer-api-client/-/customer-api-client-0.0.5.tgz","fileCount":46,"unpackedSize":412187,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGVs2JcsKLTKRmDRrmx6PfvskkJ0lki8VDNzyIn83IQJAiEApoeeqSTKBZNhSyLfVQZ0rhihmA6avp4097HiIdonhBw="}]},"_npmUser":{"name":"sdornan","email":"sdornan@gmail.com"},"directories":{},"maintainers":[{"name":"sdornan","email":"sdornan@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/customer-api-client_0.0.5_1787670943828_0.8316623240696532"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-19T22:51:24.353Z","modified":"2026-08-25T15:15:44.119Z","0.0.1":"2026-03-19T22:51:24.652Z","0.0.2":"2026-03-19T23:01:46.962Z","0.0.3":"2026-05-09T20:35:39.475Z","0.0.4":"2026-08-04T18:35:38.086Z","0.0.5":"2026-08-25T15:15:43.951Z"},"bugs":{"url":"https://github.com/athletic-greens/shopify-app-js/issues"},"author":{"name":"Shopify"},"license":"MIT","homepage":"https://github.com/athletic-greens/shopify-app-js/tree/main/packages/api-clients/customer-api-client#readme","keywords":["shopify","node","graphql","Customer Account API"],"repository":{"type":"git","url":"git+https://github.com/athletic-greens/shopify-app-js.git","directory":"packages/api-clients/customer-api-client"},"description":"Shopify Customer API Client - A lightweight JS client to interact with Shopify's Customer Account API","maintainers":[{"name":"sdornan","email":"sdornan@gmail.com"}],"readme":"# Customer API Client\n\nThe Customer API Client manages OAuth authentication and provides methods to interact with the [Shopify Customer Account API](https://shopify.dev/docs/api/customer). It handles the complete PKCE OAuth flow and makes authenticated GraphQL requests on behalf of logged-in customers.\n\n## Getting started\n\nUsing your preferred package manager, install this package in a project:\n\n```sh\nyarn add @shopify/customer-api-client\n```\n\n```sh\nnpm install @shopify/customer-api-client --s\n```\n\n```sh\npnpm add @shopify/customer-api-client\n```\n\n### CDN\n\nThe UMD builds of each release version are available via the [`unpkg` CDN](https://unpkg.com/browse/@shopify/customer-api-client@latest/dist/umd/)\n\n```html\n<script src=\"https://unpkg.com/@shopify/customer-api-client@latest/dist/umd/customer-api-client.min.js\"></script>\n\n<script>\n  const client = ShopifyCustomerAPIClient.createCustomerApiClient({...});\n</script>\n```\n\n## Initialization\n\nThe client supports two OAuth client types:\n\n- **Public clients** (browser/mobile apps) — use PKCE for security. Do not provide `clientSecret`.\n- **Confidential clients** (server-side apps) — can securely store a `clientSecret`. Use Basic Auth on token requests; PKCE is omitted.\n\n### Public client (browser / mobile)\n\n```typescript\nimport {createCustomerApiClient} from '@shopify/customer-api-client';\n\nconst client = createCustomerApiClient({\n  storeDomain: 'your-shop-name.myshopify.com',\n  clientId: 'your-oauth-client-id',\n  redirectUri: 'https://your-app.example.com/auth/callback',\n});\n```\n\n### Confidential client (server-side)\n\n> [!WARNING]\n> `clientSecret` must never be exposed in a browser environment. Only use confidential clients in server-side code.\n\n```typescript\nimport {createCustomerApiClient} from '@shopify/customer-api-client';\n\nconst client = createCustomerApiClient({\n  storeDomain: 'your-shop-name.myshopify.com',\n  clientId: 'your-oauth-client-id',\n  clientSecret: 'your-oauth-client-secret',\n  redirectUri: 'https://your-app.example.com/auth/callback',\n});\n```\n\nThe client performs two discovery requests immediately on construction (they are not awaited until first use):\n\n- `GET https://{storeDomain}/.well-known/openid-configuration` — provides the OAuth endpoints (`authorization_endpoint`, `token_endpoint`, `end_session_endpoint`)\n- `GET https://{storeDomain}/.well-known/customer-account-api` — provides the GraphQL API URL (`graphql_api`)\n\n### `createCustomerApiClient()` parameters\n\n| Property        | Type                                                                    | Description                                                                                                                                                                             |\n| --------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| storeDomain     | `string`                                                                | The domain of the store. Can be the Shopify `myshopify.com` domain or a custom store domain.                                                                                            |\n| apiVersion?     | `string`                                                                | The default API version to use for all requests (e.g. `'2026-01'`). Can be overridden per request via `options.apiVersion`.                                                             |\n| clientId        | `string`                                                                | Your app's OAuth client ID.                                                                                                                                                             |\n| clientSecret?   | `string`                                                                | Your app's OAuth client secret. When provided, the client operates as a **confidential client**: token requests use `Authorization: Basic` instead of PKCE, and `code_challenge` is omitted from the authorization URL. **Never expose this value in a browser environment.** |\n| redirectUri     | `string`                                                                | The URI to redirect to after authorization. Must match one of the redirect URIs configured for your app.                                                                                |\n| clientName?     | `string`                                                                | Name of the client. Included in request headers as `X-SDK-Variant-Source`.                                                                                                             |\n| retries?        | `number`                                                                | The number of HTTP request retries if the request was abandoned or the server responded with a `Too Many Requests (429)` or `Service Unavailable (503)` response. Default value is `0`. |\n| customFetchApi? | `(url: string, init?: {method?: string, headers?: HeaderInit, body?: string}) => Promise<Response>` | A replacement `fetch` function used for all client network requests. By default, the client uses the global `fetch`.                                            |\n| logger?         | `(logContent: HTTPResponseLog \\| HTTPRetryLog) => void`                 | A logger function that accepts log content objects.                                                                                                                                     |\n\n## Client properties\n\n| Property            | Type                                                                                                                              | Description                                                                                                                             |\n| ------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |\n| config              | [`CustomerApiClientConfig`](#customerapiclientconfig-properties)                                                                  | Configuration for the client.                                                                                                           |\n| getHeaders          | `(headers?: Record<string, string>) => Record<string, string>`                                                                    | Returns Customer API specific headers. If additional `headers` are provided, they are merged into the returned headers object.           |\n| setTokens           | `(tokenSet: CustomerTokenSet) => void`                                                                                            | Stores a token set in the client. Call this to restore tokens after a page reload.                                                      |\n| getTokens           | `() => CustomerTokenSet \\| null`                                                                                                  | Returns the currently stored token set, or `null` if no tokens have been set.                                                           |\n| getAuthorizationUrl | `(params?: GetAuthorizationUrlParams) => Promise<GetAuthorizationUrlResult>`                                                      | Generates an authorization URL. For public clients, includes PKCE params and returns a `codeVerifier` to store. For confidential clients, PKCE is omitted and `codeVerifier` is `undefined`. |\n| exchangeCode        | `(params: ExchangeCodeParams) => Promise<CustomerTokenSet>`                                                                       | Exchanges an authorization code for a token set. Automatically calls `setTokens()` with the result. `codeVerifier` is required for public clients.                                    |\n| refreshToken        | `(params?: RefreshTokenParams) => Promise<CustomerTokenSet>`                                                                      | Refreshes the access token using a refresh token. Uses the stored refresh token if `params.refreshToken` is not provided. Calls `setTokens()` with the result. |\n| getLogoutUrl        | `(params?: {idToken?: string; postLogoutRedirectUri?: string}) => Promise<string>`                                                | Returns the end-session URL. Uses the stored `idToken` if `params.idToken` is not provided.                                             |\n| fetch               | `(operation: string, options?: CustomerRequestOptions) => Promise<Response>`                                                      | Fetches data from the Customer Account API. Uses the stored access token unless `options.customerAccessToken` is provided.              |\n| request             | `<TData>(operation: string, options?: CustomerRequestOptions) => Promise<ClientResponse<TData>>`                                  | Requests data from the Customer Account API and returns a normalized response object. Uses the stored access token unless `options.customerAccessToken` is provided. |\n\n## `CustomerApiClientConfig` properties\n\n| Name          | Type                       | Description                                                      |\n| ------------- | -------------------------- | ---------------------------------------------------------------- |\n| storeDomain   | `string`                   | The normalized store domain URL                                  |\n| apiVersion?   | `string`                   | The default API version set at initialization                    |\n| clientId      | `string`                   | The OAuth client ID                                              |\n| clientSecret? | `string`                   | The OAuth client secret (confidential clients only)              |\n| redirectUri   | `string`                   | The OAuth redirect URI                                           |\n| clientName?   | `string`                   | The provided client name                                         |\n| headers       | `Record<string, string>`   | The base headers generated by the client during initialization   |\n\n## `CustomerRequestOptions` properties\n\n| Name                  | Type                     | Description                                                                                                                                                                                                                                      |\n| --------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| customerAccessToken?  | `string`                 | An access token to use for this request. Overrides the stored token. If neither this option nor a stored token is available, the method throws an error.                                                                                          |\n| variables?            | `Record<string, any>`    | Variable values needed in the GraphQL operation.                                                                                                                                                                                                 |\n| apiVersion?           | `string`                 | Overrides the API version in the discovered GraphQL URL for this request (e.g. `'2024-10'`).                                                                                                                                                     |\n| headers?              | `Record<string, string>` | Custom headers to include in the API request.                                                                                                                                                                                                    |\n| retries?              | `number`                 | Alternative number of retries for the request. Retries only occur for requests that were abandoned or if the server responds with a `Too Many Request (429)` or `Service Unavailable (503)` response. Minimum value is `0` and maximum value is `3`. |\n\n## `CustomerTokenSet`\n\n| Name           | Type     | Description                                                 |\n| -------------- | -------- | ----------------------------------------------------------- |\n| accessToken    | `string` | The customer access token used to authenticate API requests |\n| refreshToken?  | `string` | Token used to obtain a new access token when it expires     |\n| expiresIn?     | `number` | Number of seconds until the access token expires            |\n| idToken?       | `string` | OpenID Connect ID token for the customer session            |\n\n## `GetAuthorizationUrlParams`\n\n| Name    | Type     | Description                                                                                  |\n| ------- | -------- | -------------------------------------------------------------------------------------------- |\n| scope?  | `string` | OAuth scopes to request. Defaults to `openid email customer-account-api:full` |\n| state?  | `string` | Random string to prevent CSRF attacks. Generated automatically if not provided.              |\n| nonce?  | `string` | Random string for replay attack prevention. Generated automatically if not provided.         |\n\n## `GetAuthorizationUrlResult`\n\n| Name          | Type               | Description                                                                                                        |\n| ------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------ |\n| url           | `string`           | The authorization URL to redirect the customer to                                                                  |\n| codeVerifier? | `string`           | The PKCE code verifier. Only present for public clients. Store this securely and pass it to `exchangeCode()`.      |\n| state         | `string`           | The state parameter used in the authorization request                                                              |\n| nonce         | `string`           | The nonce parameter used in the authorization request                                                              |\n\n## `ClientResponse<TData>`\n\n| Name        | Type                                | Description                                                                                                                                                                         |\n| ----------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| data?       | `TData \\| any`                      | Data returned from the Customer Account API. If `TData` was provided to the function, the return type is `TData`, else it returns type `any`.                                       |\n| errors?     | [`ResponseErrors`](#responseerrors) | Errors object that contains any API or network errors that occurred while fetching the data from the API. It does not include any `UserErrors`.                                     |\n| extensions? | `Record<string, any>`               | Additional information on the GraphQL response data and context.                                                                                                                    |\n\n## `ResponseErrors`\n\n| Name               | Type       | Description                                         |\n| ------------------ | ---------- | --------------------------------------------------- |\n| networkStatusCode? | `number`   | HTTP response status code                           |\n| message?           | `string`   | The provided error message                          |\n| graphQLErrors?     | `any[]`    | The GraphQL API errors returned by the server       |\n| response?          | `Response` | The raw response object from the network fetch call |\n\n## Usage examples\n\n### Complete OAuth PKCE flow\n\n```typescript\nimport {createCustomerApiClient} from '@shopify/customer-api-client';\n\nconst client = createCustomerApiClient({\n  storeDomain: 'your-shop-name.myshopify.com',\n  clientId: 'your-oauth-client-id',\n  redirectUri: 'https://your-app.example.com/auth/callback',\n});\n\n// Step 1: Generate the authorization URL and redirect the customer\nconst {url, codeVerifier, state, nonce} = await client.getAuthorizationUrl();\n\n// Store codeVerifier and state securely (e.g., in sessionStorage) before redirecting\nsessionStorage.setItem('codeVerifier', codeVerifier);\nsessionStorage.setItem('oauthState', state);\nwindow.location.href = url;\n\n// Step 2: On the callback page, exchange the authorization code for tokens\nconst urlParams = new URLSearchParams(window.location.search);\nconst code = urlParams.get('code');\nconst returnedState = urlParams.get('state');\n\nconst savedState = sessionStorage.getItem('oauthState');\nconst savedCodeVerifier = sessionStorage.getItem('codeVerifier');\n\nif (returnedState !== savedState) {\n  throw new Error('State mismatch — possible CSRF attack');\n}\n\nconst tokenSet = await client.exchangeCode({\n  code,\n  codeVerifier: savedCodeVerifier,\n});\n\n// Persist tokens for future page loads (e.g., localStorage, cookies)\nlocalStorage.setItem('customerTokens', JSON.stringify(tokenSet));\n```\n\n### Confidential client OAuth flow (server-side)\n\n```typescript\nimport {createCustomerApiClient} from '@shopify/customer-api-client';\n\n// Server-side only — never expose clientSecret in a browser\nconst client = createCustomerApiClient({\n  storeDomain: 'your-shop-name.myshopify.com',\n  clientId: 'your-oauth-client-id',\n  clientSecret: 'your-oauth-client-secret',\n  redirectUri: 'https://your-app.example.com/auth/callback',\n});\n\n// Step 1: Generate the authorization URL (no PKCE — codeVerifier is undefined)\nconst {url, state} = await client.getAuthorizationUrl();\n// Store state in the session for CSRF validation\nreq.session.oauthState = state;\nres.redirect(url);\n\n// Step 2: On the callback route, exchange the authorization code for tokens\n// No codeVerifier needed for confidential clients\nconst tokenSet = await client.exchangeCode({code: req.query.code});\n// Store tokens in the session or database\nreq.session.customerTokens = tokenSet;\n```\n\n### Restore tokens after a page reload\n\n```typescript\nconst stored = localStorage.getItem('customerTokens');\nif (stored) {\n  client.setTokens(JSON.parse(stored));\n}\n```\n\n### Refresh an expired access token\n\n```typescript\n// Uses the stored refresh token automatically if one was set via setTokens() or exchangeCode()\nconst newTokenSet = await client.refreshToken();\n\n// Or pass the refresh token explicitly\nconst newTokenSet = await client.refreshToken({\n  refreshToken: 'your-refresh-token',\n});\n```\n\n### Make an authenticated GraphQL request\n\n```typescript\nconst orderQuery = `\n  query CustomerOrders {\n    customer {\n      orders(first: 5) {\n        nodes {\n          id\n          name\n          totalPrice {\n            amount\n            currencyCode\n          }\n        }\n      }\n    }\n  }\n`;\n\n// Uses the stored access token automatically\nconst {data, errors, extensions} = await client.request(orderQuery);\n```\n\n### Make a request with a per-request access token\n\n```typescript\nconst {data, errors} = await client.request(orderQuery, {\n  customerAccessToken: 'customer-access-token',\n});\n```\n\n### Log out the customer\n\n```typescript\n// Returns the end-session URL; redirect the customer to it to complete logout\nconst logoutUrl = await client.getLogoutUrl({\n  postLogoutRedirectUri: 'https://your-app.example.com',\n});\n\nwindow.location.href = logoutUrl;\n```\n\n### Set a default API version at initialization\n\n```typescript\nconst client = createCustomerApiClient({\n  storeDomain: 'your-shop-name.myshopify.com',\n  clientId: 'your-oauth-client-id',\n  redirectUri: 'https://your-app.example.com/auth/callback',\n  apiVersion: '2026-01',\n});\n\n// All requests use '2026-01' unless overridden\nconst {data, errors} = await client.request(orderQuery);\n```\n\n### Override the API version for a single request\n\n```typescript\nconst {data, errors} = await client.request(orderQuery, {\n  apiVersion: '2024-10',\n});\n```\n\n## Typing variables and return objects\n\nThis client is compatible with the `@shopify/api-codegen-preset` package.\nYou can use that package to create types from your operations with the [Codegen CLI](https://www.graphql-cli.com/codegen/).\n\nThere are different ways to [configure codegen](../api-codegen-preset#configuration) with it, but the simplest way is to:\n\n1. Add the preset package as a dev dependency to your project, for example:\n   ```bash\n   npm install --save-dev @shopify/api-codegen-preset\n   ```\n1. Create a `.graphqlrc.ts` file in your root containing:\n\n   ```ts\n   import {ApiType, shopifyApiProject} from '@shopify/api-codegen-preset';\n\n   export default {\n     projects: {\n       default: shopifyApiProject({\n         apiType: ApiType.Customer,\n         outputDir: './types',\n       }),\n     },\n   };\n   ```\n\n1. Add `\"graphql-codegen\": \"graphql-codegen\"` to your `scripts` section in `package.json`.\n1. Tag your operations with `#graphql`, for example:\n   ```ts\n   const {data, errors} = await client.request(\n     `#graphql\n     query CustomerOrders {\n       customer {\n         orders(first: 5) {\n           nodes {\n             id\n             name\n           }\n         }\n       }\n     }`,\n   );\n   console.log(data?.customer.orders.nodes);\n   ```\n1. Run `npm run graphql-codegen` to parse the types from your operations.\n\n> [!NOTE]\n> Remember to ensure that your tsconfig includes the files under `./types`!\n\nOnce the script runs, it'll create the file `./types/customer.generated.d.ts`.\nWhen TS includes that file, it'll automatically cause the client to detect the types for each query.\n\n## Log Content Types\n\n### `HTTPResponseLog`\n\nThis log content is sent to the logger whenever an HTTP response is received by the client.\n\n| Property | Type                                                                      | Description                                                 |\n| -------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- |\n| type     | `LogType['HTTP-Response']`                                                | The type of log content. Is always set to `HTTP-Response`   |\n| content  | `{requestParams: [url, init?], response: Response}`                       | Contextual data regarding the request and received response |\n\n### `HTTPRetryLog`\n\nThis log content is sent to the logger whenever the client attempts to retry HTTP requests.\n\n| Property | Type                                                                                                                     | Description                                                                                                                                                                                                                                                                      |\n| -------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| type     | `LogType['HTTP-Retry']`                                                                                                  | The type of log content. Is always set to `HTTP-Retry`                                                                                                                                                                                                                           |\n| content  | `{requestParams: [url, init?], lastResponse?: Response, retryAttempt: number, maxRetries: number}`                       | Contextual data regarding the upcoming retry attempt.                                                                                                                                                                                                                            |\n","readmeFilename":"README.md"}