shopify-nuxt 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/module.json +1 -1
- package/dist/runtime/composables/useShopifyFetch.d.ts +2 -0
- package/dist/runtime/composables/useShopifyFetch.js +15 -3
- package/dist/runtime/server/utils/authenticate-admin.d.ts +2 -1
- package/dist/runtime/types.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,26 @@ It builds on the `@shopify/shopify-api` package and creates a Nuxt module layer
|
|
|
16
16
|
|
|
17
17
|
> **Note**: this package will enable your app's backend to work with Shopify APIs, and by default it will behave as an [embedded app](https://shopify.dev/docs/apps/auth/oauth/session-tokens). It uses the CDN-based [Shopify App Bridge](https://shopify.dev/docs/apps/tools/app-bridge) for frontend authentication.
|
|
18
18
|
|
|
19
|
+
## How is this different from `@nuxtjs/shopify`?
|
|
20
|
+
|
|
21
|
+
[`@nuxtjs/shopify`](https://shopify.nuxtjs.org) and `shopify-nuxt` solve completely different problems — you may even use both in the same project.
|
|
22
|
+
|
|
23
|
+
| | [`@nuxtjs/shopify`](https://shopify.nuxtjs.org) | `shopify-nuxt` (this package) |
|
|
24
|
+
| ----------------------------- | ----------------------------------------------- | ------------------------------------------- |
|
|
25
|
+
| **Use case** | Headless storefront | Shopify admin app (embedded) |
|
|
26
|
+
| **Who it's for** | Merchants building custom storefronts | Developers building Shopify apps |
|
|
27
|
+
| **Authentication** | Static access token in config | OAuth + per-merchant session token exchange |
|
|
28
|
+
| **Runs inside Shopify Admin** | No | Yes (App Bridge iframe) |
|
|
29
|
+
| **App Bridge** | No | Yes — CDN-based, auto-injected |
|
|
30
|
+
| **Webhooks** | No | Yes — HMAC-verified |
|
|
31
|
+
| **Billing API** | No | Yes |
|
|
32
|
+
| **Per-shop session storage** | No | Yes — pluggable adapters |
|
|
33
|
+
| **Equivalent to** | Shopify Hydrogen / storefront SDKs | `@shopify/shopify-app-react-router` |
|
|
34
|
+
|
|
35
|
+
**Use `@nuxtjs/shopify`** if you want to build a custom Nuxt storefront that queries products, collections, and customer data from a Shopify store using the Storefront or Admin API with a static token.
|
|
36
|
+
|
|
37
|
+
**Use `shopify-nuxt`** if you are building a Shopify app — something that runs inside the Shopify Admin, authenticates merchants via OAuth, handles session tokens, manages webhooks, and optionally charges merchants via the Billing API.
|
|
38
|
+
|
|
19
39
|
## Requirements
|
|
20
40
|
|
|
21
41
|
To follow these usage guides, you will need to:
|
package/dist/module.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { NitroFetchRequest, TypedInternalResponse, AvailableRouterMethod } from 'nitropack/types';
|
|
2
2
|
import type { RouterMethod } from 'h3';
|
|
3
3
|
type ShopifyFetchData<T, R extends NitroFetchRequest, M extends RouterMethod> = [T] extends [undefined] ? TypedInternalResponse<R, unknown, M> : T;
|
|
4
|
+
type QueryParams = Record<string, string | number | boolean | null | undefined>;
|
|
4
5
|
export declare function useShopifyFetch<T = undefined, R extends NitroFetchRequest = NitroFetchRequest, M extends AvailableRouterMethod<R> = 'get' extends AvailableRouterMethod<R> ? 'get' : AvailableRouterMethod<R>>(url: R, options?: Omit<RequestInit, 'method'> & {
|
|
5
6
|
method?: Uppercase<M> | M;
|
|
7
|
+
query?: QueryParams;
|
|
6
8
|
}): Promise<{
|
|
7
9
|
data: ShopifyFetchData<T, R, Extract<Lowercase<M>, RouterMethod>>;
|
|
8
10
|
response: Response;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useNuxtApp, useRequestEvent } from "#app";
|
|
2
2
|
export async function useShopifyFetch(url, options) {
|
|
3
|
-
const opts = options ?? {};
|
|
3
|
+
const { query, ...opts } = options ?? {};
|
|
4
4
|
if (import.meta.server) {
|
|
5
5
|
const event = useRequestEvent();
|
|
6
6
|
const headers2 = {};
|
|
@@ -18,7 +18,8 @@ export async function useShopifyFetch(url, options) {
|
|
|
18
18
|
const fetchResponse2 = await globalThis.$fetch.raw(url, {
|
|
19
19
|
...rest,
|
|
20
20
|
method,
|
|
21
|
-
headers: headers2
|
|
21
|
+
headers: headers2,
|
|
22
|
+
query
|
|
22
23
|
});
|
|
23
24
|
return { data: fetchResponse2._data, response: fetchResponse2 };
|
|
24
25
|
}
|
|
@@ -32,7 +33,18 @@ export async function useShopifyFetch(url, options) {
|
|
|
32
33
|
const token = await shopify.idToken();
|
|
33
34
|
const headers = new Headers(opts.headers || {});
|
|
34
35
|
headers.set("Authorization", `Bearer ${token}`);
|
|
35
|
-
|
|
36
|
+
let resolvedUrl = url;
|
|
37
|
+
if (query) {
|
|
38
|
+
const params = new URLSearchParams();
|
|
39
|
+
for (const [key, value] of Object.entries(query)) {
|
|
40
|
+
if (value !== null && value !== void 0) {
|
|
41
|
+
params.set(key, String(value));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const qs = params.toString();
|
|
45
|
+
if (qs) resolvedUrl += (resolvedUrl.includes("?") ? "&" : "?") + qs;
|
|
46
|
+
}
|
|
47
|
+
const fetchResponse = await fetch(resolvedUrl, {
|
|
36
48
|
...opts,
|
|
37
49
|
headers
|
|
38
50
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
2
|
import type { AdminContext } from '../../types.js';
|
|
3
|
+
import type { JwtPayload } from '@shopify/shopify-api';
|
|
3
4
|
/**
|
|
4
5
|
* Authenticate an admin request and return an authenticated admin context.
|
|
5
6
|
*
|
|
@@ -14,4 +15,4 @@ import type { AdminContext } from '../../types.js';
|
|
|
14
15
|
* })
|
|
15
16
|
* ```
|
|
16
17
|
*/
|
|
17
|
-
export declare function useShopifyAdmin(event: H3Event): Promise<AdminContext
|
|
18
|
+
export declare function useShopifyAdmin<T extends object = JwtPayload>(event: H3Event): Promise<AdminContext<T>>;
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -87,13 +87,13 @@ export interface ShopifyRuntimeConfig {
|
|
|
87
87
|
/** Billing configuration */
|
|
88
88
|
billing?: Record<string, any>;
|
|
89
89
|
}
|
|
90
|
-
export interface AdminContext {
|
|
90
|
+
export interface AdminContext<T extends object = JwtPayload> {
|
|
91
91
|
/** The authenticated session */
|
|
92
92
|
session: Session;
|
|
93
93
|
/** Admin API client (graphql + rest) */
|
|
94
94
|
admin: AdminApiContext;
|
|
95
95
|
/** The decoded session token (embedded apps only) */
|
|
96
|
-
sessionToken?:
|
|
96
|
+
sessionToken?: T;
|
|
97
97
|
/** Billing helpers */
|
|
98
98
|
billing: BillingContext;
|
|
99
99
|
/** CORS header helper */
|
package/package.json
CHANGED