@sdg.la/wishlist-stack-hydrogen 0.9.0

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 ADDED
@@ -0,0 +1,139 @@
1
+ # @sdg.la/wishlist-stack-hydrogen
2
+
3
+ Hydrogen (react-router) integration for [`@sdg.la/wishlist-stack-sdk`](../client/).
4
+
5
+ This package supports **two server wiring styles**:
6
+ - **Context creation**: attach to your Hydrogen load context (`getLoadContext`).
7
+ - **Middleware-enabled**: attach via React Router middleware (when used).
8
+
9
+ It also provides:
10
+ - **Context helpers** (`getWishlistStackClient`, `getWishlistStack`) to avoid `context.get(...)` boilerplate
11
+ - **React Provider + hooks** for client-side usage (`@sdg.la/wishlist-stack-hydrogen/react`)
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm i @sdg.la/wishlist-stack-sdk @sdg.la/wishlist-stack-hydrogen
17
+ ```
18
+
19
+ ## 1) Server usage (attach to Hydrogen load context)
20
+
21
+ Use `createWishlistStackServerContext()` to attach:
22
+ - `context.wishlistStack` (server helper)
23
+ - `context.wishlistStackClient` (ready-to-use client, lazy + request-scoped)
24
+
25
+ ```ts
26
+ import {createWishlistStackServerContext} from '@sdg.la/wishlist-stack-hydrogen/server';
27
+
28
+ export function getLoadContext(hydrogenContext: unknown) {
29
+ createWishlistStackServerContext({
30
+ apiKey: process.env.WISHLIST_STACK_API_KEY!, // merchant key
31
+ baseUrl: process.env.WISHLIST_STACK_BASE_URL,
32
+ })(hydrogenContext);
33
+
34
+ return hydrogenContext;
35
+ }
36
+ ```
37
+
38
+ Now in loaders/actions you can do:
39
+
40
+ ```ts
41
+ export async function loader({context}: any) {
42
+ return await context.wishlistStackClient.groups.getAll();
43
+ }
44
+ ```
45
+
46
+ ### Context-map vs object context
47
+
48
+ Some Hydrogen/React Router setups expose a `context.get(...)` API. To avoid conditional access, use helpers:
49
+
50
+ ```ts
51
+ import {getWishlistStackClient} from '@sdg.la/wishlist-stack-hydrogen';
52
+
53
+ export async function loader({context}: any) {
54
+ const client = await getWishlistStackClient(context);
55
+ return await client.groups.getAll();
56
+ }
57
+ ```
58
+
59
+ ## 2) Server usage (middleware-enabled)
60
+
61
+ Register middleware and it will attach `wishlistStack` to the middleware context.
62
+
63
+ ```ts
64
+ import {createWishlistStackMiddleware} from '@sdg.la/wishlist-stack-hydrogen/middleware';
65
+
66
+ export const middleware = [
67
+ createWishlistStackMiddleware({
68
+ apiKey: process.env.WISHLIST_STACK_API_KEY!,
69
+ baseUrl: process.env.WISHLIST_STACK_BASE_URL,
70
+ }),
71
+ ];
72
+ ```
73
+
74
+ The middleware supports both `context.set(...)` (context map style) and plain object mutation.
75
+
76
+ ## 3) Client usage (React Provider + hooks)
77
+
78
+ Import from `@sdg.la/wishlist-stack-hydrogen/react`:
79
+
80
+ ```tsx
81
+ import {WishlistStackProvider, useWishlistStackClient} from '@sdg.la/wishlist-stack-hydrogen/react';
82
+ ```
83
+
84
+ ### Direct-from-browser (opt-in)
85
+
86
+ If you want client components to call the API directly, bootstrap config (and optionally token) in a loader and pass into the provider.
87
+
88
+ ```ts
89
+ // root loader
90
+ export async function loader({context}: any) {
91
+ const cfg = await context.wishlistStack.bootstrapClientConfig({exposeCustomerAccessToken: true});
92
+ return {wishlistStack: cfg};
93
+ }
94
+ ```
95
+
96
+ ```tsx
97
+ import {WishlistStackProvider} from '@sdg.la/wishlist-stack-hydrogen/react';
98
+ import {useLoaderData} from 'react-router';
99
+
100
+ export function App() {
101
+ const data = useLoaderData() as any;
102
+ return (
103
+ <WishlistStackProvider
104
+ mode="direct"
105
+ config={{apiKey: data.wishlistStack.apiKey, baseUrl: data.wishlistStack.baseUrl}}
106
+ initialCustomerAccessToken={data.wishlistStack.customerAccessToken}
107
+ >
108
+ {/* ... */}
109
+ </WishlistStackProvider>
110
+ );
111
+ }
112
+ ```
113
+
114
+ Then, anywhere in your app:
115
+
116
+ ```ts
117
+ import {useWishlistStackClient} from '@sdg.la/wishlist-stack-hydrogen/react';
118
+
119
+ export function MyComponent() {
120
+ const client = useWishlistStackClient();
121
+ // await client.groups.getAll()
122
+ return null;
123
+ }
124
+ ```
125
+
126
+ ### Optional global state (for "wishlisted?" checks)
127
+
128
+ ```ts
129
+ import {useWishlistStack} from '@sdg.la/wishlist-stack-hydrogen/react';
130
+
131
+ export function ProductCard({variantId}: {variantId: string}) {
132
+ const {state} = useWishlistStack();
133
+ const saved = state.savedVariantIds?.includes(variantId) ?? false;
134
+ // render "saved" UI
135
+ return null;
136
+ }
137
+ ```
138
+
139
+ You can hydrate `initialState` in your root route loader and pass it to `<WishlistStackProvider initialState={...} />` when you add an endpoint for it.
package/dist/index.cjs ADDED
@@ -0,0 +1,153 @@
1
+ 'use strict';
2
+
3
+ var wishlistStackSdk = require('@sdg.la/wishlist-stack-sdk');
4
+
5
+ // src/server.ts
6
+ function createLazyWishlistStackClient(getClient) {
7
+ return {
8
+ lists: {
9
+ getAll: (query) => getClient().then((c) => c.lists.getAll(query)),
10
+ getById: (listId) => getClient().then((c) => c.lists.getById(listId)),
11
+ create: (body) => getClient().then((c) => c.lists.create(body)),
12
+ update: (listId, body) => getClient().then((c) => c.lists.update(listId, body)),
13
+ remove: (listId) => getClient().then((c) => c.lists.remove(listId)),
14
+ addItems: (listId, body) => getClient().then((c) => c.lists.addItems(listId, body)),
15
+ updateItem: (listId, itemId, body) => getClient().then((c) => c.lists.updateItem(listId, itemId, body)),
16
+ removeItem: (listId, itemId) => getClient().then((c) => c.lists.removeItem(listId, itemId)),
17
+ share: (listId) => getClient().then((c) => c.lists.share(listId)),
18
+ unshare: (listId) => getClient().then((c) => c.lists.unshare(listId)),
19
+ addItemsLegacy: (id, body) => getClient().then((c) => c.lists.addItemsLegacy(id, body))
20
+ },
21
+ groups: {
22
+ getAll: () => getClient().then((c) => c.groups.getAll()),
23
+ getById: (groupId) => getClient().then((c) => c.groups.getById(groupId)),
24
+ create: (body) => getClient().then((c) => c.groups.create(body)),
25
+ update: (groupId, body) => getClient().then((c) => c.groups.update(groupId, body)),
26
+ remove: (groupId) => getClient().then((c) => c.groups.remove(groupId)),
27
+ reorder: (groupId, body) => getClient().then((c) => c.groups.reorder(groupId, body)),
28
+ share: (groupId) => getClient().then((c) => c.groups.share(groupId)),
29
+ unshare: (groupId) => getClient().then((c) => c.groups.unshare(groupId))
30
+ },
31
+ shared: {
32
+ getSharedList: (listId) => getClient().then((c) => c.shared.getSharedList(listId)),
33
+ getSharedGroup: (groupId) => getClient().then((c) => c.shared.getSharedGroup(groupId))
34
+ }
35
+ };
36
+ }
37
+ async function defaultGetCustomerAccessToken(context) {
38
+ const anyCtx = context;
39
+ const customerAccount = anyCtx?.customerAccount;
40
+ const fn = customerAccount?.getAccessToken;
41
+ if (typeof fn !== "function") return void 0;
42
+ try {
43
+ const token = await fn.call(customerAccount);
44
+ return typeof token === "string" ? token : void 0;
45
+ } catch {
46
+ return void 0;
47
+ }
48
+ }
49
+ function createWishlistStackServerContext(options) {
50
+ return function attachToContext(context) {
51
+ if (!options.apiKey) {
52
+ throw new Error("merchant api key is required. Pass it to createWishlistStackServerContext({ apiKey })");
53
+ }
54
+ const getToken = async () => {
55
+ if (options.getCustomerAccessToken) {
56
+ const token = await options.getCustomerAccessToken(context);
57
+ return typeof token === "string" ? token : void 0;
58
+ }
59
+ return await defaultGetCustomerAccessToken(context);
60
+ };
61
+ let cachedClient;
62
+ let cachedToken;
63
+ const server = {
64
+ async getCustomerAccessToken() {
65
+ return await getToken();
66
+ },
67
+ async getClient() {
68
+ const token = await getToken();
69
+ if (cachedClient && cachedToken === token) return cachedClient;
70
+ cachedToken = token;
71
+ cachedClient = wishlistStackSdk.createWishlistStackClient({
72
+ apiKey: options.apiKey,
73
+ baseUrl: options.baseUrl,
74
+ customerAccessToken: token
75
+ });
76
+ return cachedClient;
77
+ },
78
+ async bootstrapClientConfig(opts) {
79
+ const expose = opts?.exposeCustomerAccessToken ?? false;
80
+ const token = expose ? await getToken() : void 0;
81
+ return {
82
+ apiKey: options.apiKey,
83
+ baseUrl: options.baseUrl,
84
+ customerAccessToken: token
85
+ };
86
+ }
87
+ };
88
+ const wishlistStackClient = createLazyWishlistStackClient(server.getClient);
89
+ const anyCtx = context;
90
+ if (anyCtx && typeof anyCtx.set === "function") {
91
+ anyCtx.set("wishlistStack", server);
92
+ anyCtx.set("wishlistStackClient", wishlistStackClient);
93
+ } else if (anyCtx && typeof anyCtx === "object") {
94
+ anyCtx.wishlistStack = server;
95
+ anyCtx.wishlistStackClient = wishlistStackClient;
96
+ }
97
+ return { wishlistStack: server, wishlistStackClient };
98
+ };
99
+ }
100
+
101
+ // src/middleware.ts
102
+ function createWishlistStackMiddleware(options) {
103
+ const attach = createWishlistStackServerContext(options);
104
+ return async function wishlistStackMiddleware(args, next) {
105
+ const ctxObj = args.context ?? {};
106
+ attach(ctxObj);
107
+ return await next();
108
+ };
109
+ }
110
+
111
+ // src/context.ts
112
+ async function maybeAwait(value) {
113
+ return value instanceof Promise ? await value : value;
114
+ }
115
+ async function getWishlistStackClient(context) {
116
+ const ctx = context;
117
+ if (!ctx) throw new Error("Missing loader context (expected context.wishlistStackClient).");
118
+ if (ctx.wishlistStackClient) return ctx.wishlistStackClient;
119
+ if (typeof ctx.get === "function") {
120
+ const val = await maybeAwait(ctx.get("wishlistStackClient"));
121
+ if (val) return val;
122
+ }
123
+ throw new Error(
124
+ "Wishlist Stack client not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context."
125
+ );
126
+ }
127
+ async function getWishlistStack(context) {
128
+ const ctx = context;
129
+ if (!ctx) throw new Error("Missing loader context (expected context.wishlistStack).");
130
+ if (ctx.wishlistStack) return ctx.wishlistStack;
131
+ if (typeof ctx.get === "function") {
132
+ const val = await maybeAwait(ctx.get("wishlistStack"));
133
+ if (val) return val;
134
+ }
135
+ throw new Error(
136
+ "Wishlist Stack helper not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context."
137
+ );
138
+ }
139
+
140
+ Object.defineProperty(exports, "WishlistStackApiError", {
141
+ enumerable: true,
142
+ get: function () { return wishlistStackSdk.WishlistStackApiError; }
143
+ });
144
+ Object.defineProperty(exports, "isWishlistStackApiError", {
145
+ enumerable: true,
146
+ get: function () { return wishlistStackSdk.isWishlistStackApiError; }
147
+ });
148
+ exports.createWishlistStackMiddleware = createWishlistStackMiddleware;
149
+ exports.createWishlistStackServerContext = createWishlistStackServerContext;
150
+ exports.getWishlistStack = getWishlistStack;
151
+ exports.getWishlistStackClient = getWishlistStackClient;
152
+ //# sourceMappingURL=index.cjs.map
153
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/middleware.ts","../src/context.ts"],"names":["createWishlistStackClient"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createWishlistStackClient, type WishlistStackClient } from \"@sdg.la/wishlist-stack-sdk\";\nimport type { WishlistStackHydrogenOptions, WishlistStackHydrogenServer } from \"./types\";\n\nfunction createLazyWishlistStackClient(getClient: () => Promise<WishlistStackClient>): WishlistStackClient {\n return {\n lists: {\n getAll: (query) => getClient().then((c) => c.lists.getAll(query)),\n getById: (listId) => getClient().then((c) => c.lists.getById(listId)),\n create: (body) => getClient().then((c) => c.lists.create(body)),\n update: (listId, body) => getClient().then((c) => c.lists.update(listId, body)),\n remove: (listId) => getClient().then((c) => c.lists.remove(listId)),\n addItems: (listId, body) => getClient().then((c) => c.lists.addItems(listId, body)),\n updateItem: (listId, itemId, body) => getClient().then((c) => c.lists.updateItem(listId, itemId, body)),\n removeItem: (listId, itemId) => getClient().then((c) => c.lists.removeItem(listId, itemId)),\n share: (listId) => getClient().then((c) => c.lists.share(listId)),\n unshare: (listId) => getClient().then((c) => c.lists.unshare(listId)),\n addItemsLegacy: (id, body) => getClient().then((c) => c.lists.addItemsLegacy(id, body)),\n },\n groups: {\n getAll: () => getClient().then((c) => c.groups.getAll()),\n getById: (groupId) => getClient().then((c) => c.groups.getById(groupId)),\n create: (body) => getClient().then((c) => c.groups.create(body)),\n update: (groupId, body) => getClient().then((c) => c.groups.update(groupId, body)),\n remove: (groupId) => getClient().then((c) => c.groups.remove(groupId)),\n reorder: (groupId, body) => getClient().then((c) => c.groups.reorder(groupId, body)),\n share: (groupId) => getClient().then((c) => c.groups.share(groupId)),\n unshare: (groupId) => getClient().then((c) => c.groups.unshare(groupId)),\n },\n shared: {\n getSharedList: (listId) => getClient().then((c) => c.shared.getSharedList(listId)),\n getSharedGroup: (groupId) => getClient().then((c) => c.shared.getSharedGroup(groupId)),\n },\n };\n}\n\nasync function defaultGetCustomerAccessToken(context: unknown): Promise<string | undefined> {\n const anyCtx = context as any;\n const customerAccount = anyCtx?.customerAccount;\n const fn = customerAccount?.getAccessToken;\n if (typeof fn !== \"function\") return undefined;\n try {\n const token = await fn.call(customerAccount);\n return typeof token === \"string\" ? token : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function createWishlistStackServerContext(options: WishlistStackHydrogenOptions) {\n return function attachToContext(context: unknown): { wishlistStack: WishlistStackHydrogenServer; wishlistStackClient: WishlistStackClient } {\n if (!options.apiKey) {\n throw new Error(\"merchant api key is required. Pass it to createWishlistStackServerContext({ apiKey })\");\n }\n\n const getToken = async () => {\n if (options.getCustomerAccessToken) {\n const token = await options.getCustomerAccessToken(context);\n return typeof token === \"string\" ? token : undefined;\n }\n return await defaultGetCustomerAccessToken(context);\n };\n\n let cachedClient: WishlistStackClient | undefined;\n let cachedToken: string | undefined;\n\n const server: WishlistStackHydrogenServer = {\n async getCustomerAccessToken() {\n return await getToken();\n },\n async getClient() {\n const token = await getToken();\n // Cache by token value so calls within a single request reuse the client.\n if (cachedClient && cachedToken === token) return cachedClient;\n cachedToken = token;\n cachedClient = createWishlistStackClient({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n customerAccessToken: token,\n });\n return cachedClient;\n },\n async bootstrapClientConfig(opts) {\n const expose = opts?.exposeCustomerAccessToken ?? false;\n const token = expose ? await getToken() : undefined;\n return {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n customerAccessToken: token,\n };\n },\n };\n\n const wishlistStackClient = createLazyWishlistStackClient(server.getClient);\n\n const anyCtx = context as any;\n if (anyCtx && typeof anyCtx.set === \"function\") {\n // Context map style (some React Router middleware implementations).\n anyCtx.set(\"wishlistStack\", server);\n anyCtx.set(\"wishlistStackClient\", wishlistStackClient);\n } else if (anyCtx && typeof anyCtx === \"object\") {\n // Plain object style (Hydrogen load context is an object).\n anyCtx.wishlistStack = server;\n anyCtx.wishlistStackClient = wishlistStackClient;\n }\n\n return { wishlistStack: server, wishlistStackClient };\n };\n}\n\n","import type { WishlistStackHydrogenOptions } from \"./types\";\nimport { createWishlistStackServerContext } from \"./server\";\n\ntype MiddlewareArgs = {\n request: Request;\n context: any;\n};\n\ntype MiddlewareNext = () => Promise<Response> | Response;\n\n/**\n * React Router middleware helper (Hydrogen react-router, middleware-enabled).\n *\n * We intentionally avoid importing react-router types here; we only require the\n * common shape: an object `context` that we can mutate (or that has `set()`).\n */\nexport function createWishlistStackMiddleware(options: WishlistStackHydrogenOptions) {\n const attach = createWishlistStackServerContext(options);\n return async function wishlistStackMiddleware(args: MiddlewareArgs, next: MiddlewareNext) {\n const ctxObj = args.context ?? {};\n // `attach` registers `wishlistStack` and `wishlistStackClient` onto the context (supports `set()` and mutation).\n attach(ctxObj);\n\n return await next();\n };\n}\n\n","import type { WishlistStackClient } from \"@sdg.la/wishlist-stack-sdk\";\nimport type { WishlistStackHydrogenServer } from \"./types\";\n\ntype ContextMapLike = {\n get?: (key: string) => unknown;\n wishlistStack?: WishlistStackHydrogenServer;\n wishlistStackClient?: WishlistStackClient;\n};\n\nasync function maybeAwait<T>(value: T | Promise<T>): Promise<T> {\n return value instanceof Promise ? await value : value;\n}\n\n/**\n * Retrieve `wishlistStackClient` from a Hydrogen/React Router loader context.\n *\n * Supports both styles:\n * - plain object: `context.wishlistStackClient`\n * - context map: `context.get('wishlistStackClient')`\n */\nexport async function getWishlistStackClient(context: unknown): Promise<WishlistStackClient> {\n const ctx = context as ContextMapLike | null | undefined;\n if (!ctx) throw new Error(\"Missing loader context (expected context.wishlistStackClient).\");\n\n if (ctx.wishlistStackClient) return ctx.wishlistStackClient;\n if (typeof ctx.get === \"function\") {\n const val = await maybeAwait(ctx.get(\"wishlistStackClient\") as any);\n if (val) return val as WishlistStackClient;\n }\n\n throw new Error(\n \"Wishlist Stack client not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context.\",\n );\n}\n\n/**\n * Retrieve the server helper (`wishlistStack`) from a Hydrogen/React Router loader context.\n * (Useful for bootstrap/token helpers; most route code should just use `wishlistStackClient`.)\n */\nexport async function getWishlistStack(context: unknown): Promise<WishlistStackHydrogenServer> {\n const ctx = context as ContextMapLike | null | undefined;\n if (!ctx) throw new Error(\"Missing loader context (expected context.wishlistStack).\");\n\n if (ctx.wishlistStack) return ctx.wishlistStack;\n if (typeof ctx.get === \"function\") {\n const val = await maybeAwait(ctx.get(\"wishlistStack\") as any);\n if (val) return val as WishlistStackHydrogenServer;\n }\n\n throw new Error(\n \"Wishlist Stack helper not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context.\",\n );\n}\n\n"]}
@@ -0,0 +1,22 @@
1
+ import { W as WishlistStackHydrogenServer } from './types-7NZ9ikCG.cjs';
2
+ export { B as BootstrapClientConfig, a as WishlistStackHydrogenOptions } from './types-7NZ9ikCG.cjs';
3
+ export { createWishlistStackServerContext } from './server.cjs';
4
+ export { createWishlistStackMiddleware } from './middleware.cjs';
5
+ import { WishlistStackClient } from '@sdg.la/wishlist-stack-sdk';
6
+ export { WishlistStackApiError, isWishlistStackApiError } from '@sdg.la/wishlist-stack-sdk';
7
+
8
+ /**
9
+ * Retrieve `wishlistStackClient` from a Hydrogen/React Router loader context.
10
+ *
11
+ * Supports both styles:
12
+ * - plain object: `context.wishlistStackClient`
13
+ * - context map: `context.get('wishlistStackClient')`
14
+ */
15
+ declare function getWishlistStackClient(context: unknown): Promise<WishlistStackClient>;
16
+ /**
17
+ * Retrieve the server helper (`wishlistStack`) from a Hydrogen/React Router loader context.
18
+ * (Useful for bootstrap/token helpers; most route code should just use `wishlistStackClient`.)
19
+ */
20
+ declare function getWishlistStack(context: unknown): Promise<WishlistStackHydrogenServer>;
21
+
22
+ export { WishlistStackHydrogenServer, getWishlistStack, getWishlistStackClient };
@@ -0,0 +1,22 @@
1
+ import { W as WishlistStackHydrogenServer } from './types-7NZ9ikCG.js';
2
+ export { B as BootstrapClientConfig, a as WishlistStackHydrogenOptions } from './types-7NZ9ikCG.js';
3
+ export { createWishlistStackServerContext } from './server.js';
4
+ export { createWishlistStackMiddleware } from './middleware.js';
5
+ import { WishlistStackClient } from '@sdg.la/wishlist-stack-sdk';
6
+ export { WishlistStackApiError, isWishlistStackApiError } from '@sdg.la/wishlist-stack-sdk';
7
+
8
+ /**
9
+ * Retrieve `wishlistStackClient` from a Hydrogen/React Router loader context.
10
+ *
11
+ * Supports both styles:
12
+ * - plain object: `context.wishlistStackClient`
13
+ * - context map: `context.get('wishlistStackClient')`
14
+ */
15
+ declare function getWishlistStackClient(context: unknown): Promise<WishlistStackClient>;
16
+ /**
17
+ * Retrieve the server helper (`wishlistStack`) from a Hydrogen/React Router loader context.
18
+ * (Useful for bootstrap/token helpers; most route code should just use `wishlistStackClient`.)
19
+ */
20
+ declare function getWishlistStack(context: unknown): Promise<WishlistStackHydrogenServer>;
21
+
22
+ export { WishlistStackHydrogenServer, getWishlistStack, getWishlistStackClient };
package/dist/index.js ADDED
@@ -0,0 +1,141 @@
1
+ import { createWishlistStackClient } from '@sdg.la/wishlist-stack-sdk';
2
+ export { WishlistStackApiError, isWishlistStackApiError } from '@sdg.la/wishlist-stack-sdk';
3
+
4
+ // src/server.ts
5
+ function createLazyWishlistStackClient(getClient) {
6
+ return {
7
+ lists: {
8
+ getAll: (query) => getClient().then((c) => c.lists.getAll(query)),
9
+ getById: (listId) => getClient().then((c) => c.lists.getById(listId)),
10
+ create: (body) => getClient().then((c) => c.lists.create(body)),
11
+ update: (listId, body) => getClient().then((c) => c.lists.update(listId, body)),
12
+ remove: (listId) => getClient().then((c) => c.lists.remove(listId)),
13
+ addItems: (listId, body) => getClient().then((c) => c.lists.addItems(listId, body)),
14
+ updateItem: (listId, itemId, body) => getClient().then((c) => c.lists.updateItem(listId, itemId, body)),
15
+ removeItem: (listId, itemId) => getClient().then((c) => c.lists.removeItem(listId, itemId)),
16
+ share: (listId) => getClient().then((c) => c.lists.share(listId)),
17
+ unshare: (listId) => getClient().then((c) => c.lists.unshare(listId)),
18
+ addItemsLegacy: (id, body) => getClient().then((c) => c.lists.addItemsLegacy(id, body))
19
+ },
20
+ groups: {
21
+ getAll: () => getClient().then((c) => c.groups.getAll()),
22
+ getById: (groupId) => getClient().then((c) => c.groups.getById(groupId)),
23
+ create: (body) => getClient().then((c) => c.groups.create(body)),
24
+ update: (groupId, body) => getClient().then((c) => c.groups.update(groupId, body)),
25
+ remove: (groupId) => getClient().then((c) => c.groups.remove(groupId)),
26
+ reorder: (groupId, body) => getClient().then((c) => c.groups.reorder(groupId, body)),
27
+ share: (groupId) => getClient().then((c) => c.groups.share(groupId)),
28
+ unshare: (groupId) => getClient().then((c) => c.groups.unshare(groupId))
29
+ },
30
+ shared: {
31
+ getSharedList: (listId) => getClient().then((c) => c.shared.getSharedList(listId)),
32
+ getSharedGroup: (groupId) => getClient().then((c) => c.shared.getSharedGroup(groupId))
33
+ }
34
+ };
35
+ }
36
+ async function defaultGetCustomerAccessToken(context) {
37
+ const anyCtx = context;
38
+ const customerAccount = anyCtx?.customerAccount;
39
+ const fn = customerAccount?.getAccessToken;
40
+ if (typeof fn !== "function") return void 0;
41
+ try {
42
+ const token = await fn.call(customerAccount);
43
+ return typeof token === "string" ? token : void 0;
44
+ } catch {
45
+ return void 0;
46
+ }
47
+ }
48
+ function createWishlistStackServerContext(options) {
49
+ return function attachToContext(context) {
50
+ if (!options.apiKey) {
51
+ throw new Error("merchant api key is required. Pass it to createWishlistStackServerContext({ apiKey })");
52
+ }
53
+ const getToken = async () => {
54
+ if (options.getCustomerAccessToken) {
55
+ const token = await options.getCustomerAccessToken(context);
56
+ return typeof token === "string" ? token : void 0;
57
+ }
58
+ return await defaultGetCustomerAccessToken(context);
59
+ };
60
+ let cachedClient;
61
+ let cachedToken;
62
+ const server = {
63
+ async getCustomerAccessToken() {
64
+ return await getToken();
65
+ },
66
+ async getClient() {
67
+ const token = await getToken();
68
+ if (cachedClient && cachedToken === token) return cachedClient;
69
+ cachedToken = token;
70
+ cachedClient = createWishlistStackClient({
71
+ apiKey: options.apiKey,
72
+ baseUrl: options.baseUrl,
73
+ customerAccessToken: token
74
+ });
75
+ return cachedClient;
76
+ },
77
+ async bootstrapClientConfig(opts) {
78
+ const expose = opts?.exposeCustomerAccessToken ?? false;
79
+ const token = expose ? await getToken() : void 0;
80
+ return {
81
+ apiKey: options.apiKey,
82
+ baseUrl: options.baseUrl,
83
+ customerAccessToken: token
84
+ };
85
+ }
86
+ };
87
+ const wishlistStackClient = createLazyWishlistStackClient(server.getClient);
88
+ const anyCtx = context;
89
+ if (anyCtx && typeof anyCtx.set === "function") {
90
+ anyCtx.set("wishlistStack", server);
91
+ anyCtx.set("wishlistStackClient", wishlistStackClient);
92
+ } else if (anyCtx && typeof anyCtx === "object") {
93
+ anyCtx.wishlistStack = server;
94
+ anyCtx.wishlistStackClient = wishlistStackClient;
95
+ }
96
+ return { wishlistStack: server, wishlistStackClient };
97
+ };
98
+ }
99
+
100
+ // src/middleware.ts
101
+ function createWishlistStackMiddleware(options) {
102
+ const attach = createWishlistStackServerContext(options);
103
+ return async function wishlistStackMiddleware(args, next) {
104
+ const ctxObj = args.context ?? {};
105
+ attach(ctxObj);
106
+ return await next();
107
+ };
108
+ }
109
+
110
+ // src/context.ts
111
+ async function maybeAwait(value) {
112
+ return value instanceof Promise ? await value : value;
113
+ }
114
+ async function getWishlistStackClient(context) {
115
+ const ctx = context;
116
+ if (!ctx) throw new Error("Missing loader context (expected context.wishlistStackClient).");
117
+ if (ctx.wishlistStackClient) return ctx.wishlistStackClient;
118
+ if (typeof ctx.get === "function") {
119
+ const val = await maybeAwait(ctx.get("wishlistStackClient"));
120
+ if (val) return val;
121
+ }
122
+ throw new Error(
123
+ "Wishlist Stack client not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context."
124
+ );
125
+ }
126
+ async function getWishlistStack(context) {
127
+ const ctx = context;
128
+ if (!ctx) throw new Error("Missing loader context (expected context.wishlistStack).");
129
+ if (ctx.wishlistStack) return ctx.wishlistStack;
130
+ if (typeof ctx.get === "function") {
131
+ const val = await maybeAwait(ctx.get("wishlistStack"));
132
+ if (val) return val;
133
+ }
134
+ throw new Error(
135
+ "Wishlist Stack helper not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context."
136
+ );
137
+ }
138
+
139
+ export { createWishlistStackMiddleware, createWishlistStackServerContext, getWishlistStack, getWishlistStackClient };
140
+ //# sourceMappingURL=index.js.map
141
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/middleware.ts","../src/context.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { createWishlistStackClient, type WishlistStackClient } from \"@sdg.la/wishlist-stack-sdk\";\nimport type { WishlistStackHydrogenOptions, WishlistStackHydrogenServer } from \"./types\";\n\nfunction createLazyWishlistStackClient(getClient: () => Promise<WishlistStackClient>): WishlistStackClient {\n return {\n lists: {\n getAll: (query) => getClient().then((c) => c.lists.getAll(query)),\n getById: (listId) => getClient().then((c) => c.lists.getById(listId)),\n create: (body) => getClient().then((c) => c.lists.create(body)),\n update: (listId, body) => getClient().then((c) => c.lists.update(listId, body)),\n remove: (listId) => getClient().then((c) => c.lists.remove(listId)),\n addItems: (listId, body) => getClient().then((c) => c.lists.addItems(listId, body)),\n updateItem: (listId, itemId, body) => getClient().then((c) => c.lists.updateItem(listId, itemId, body)),\n removeItem: (listId, itemId) => getClient().then((c) => c.lists.removeItem(listId, itemId)),\n share: (listId) => getClient().then((c) => c.lists.share(listId)),\n unshare: (listId) => getClient().then((c) => c.lists.unshare(listId)),\n addItemsLegacy: (id, body) => getClient().then((c) => c.lists.addItemsLegacy(id, body)),\n },\n groups: {\n getAll: () => getClient().then((c) => c.groups.getAll()),\n getById: (groupId) => getClient().then((c) => c.groups.getById(groupId)),\n create: (body) => getClient().then((c) => c.groups.create(body)),\n update: (groupId, body) => getClient().then((c) => c.groups.update(groupId, body)),\n remove: (groupId) => getClient().then((c) => c.groups.remove(groupId)),\n reorder: (groupId, body) => getClient().then((c) => c.groups.reorder(groupId, body)),\n share: (groupId) => getClient().then((c) => c.groups.share(groupId)),\n unshare: (groupId) => getClient().then((c) => c.groups.unshare(groupId)),\n },\n shared: {\n getSharedList: (listId) => getClient().then((c) => c.shared.getSharedList(listId)),\n getSharedGroup: (groupId) => getClient().then((c) => c.shared.getSharedGroup(groupId)),\n },\n };\n}\n\nasync function defaultGetCustomerAccessToken(context: unknown): Promise<string | undefined> {\n const anyCtx = context as any;\n const customerAccount = anyCtx?.customerAccount;\n const fn = customerAccount?.getAccessToken;\n if (typeof fn !== \"function\") return undefined;\n try {\n const token = await fn.call(customerAccount);\n return typeof token === \"string\" ? token : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function createWishlistStackServerContext(options: WishlistStackHydrogenOptions) {\n return function attachToContext(context: unknown): { wishlistStack: WishlistStackHydrogenServer; wishlistStackClient: WishlistStackClient } {\n if (!options.apiKey) {\n throw new Error(\"merchant api key is required. Pass it to createWishlistStackServerContext({ apiKey })\");\n }\n\n const getToken = async () => {\n if (options.getCustomerAccessToken) {\n const token = await options.getCustomerAccessToken(context);\n return typeof token === \"string\" ? token : undefined;\n }\n return await defaultGetCustomerAccessToken(context);\n };\n\n let cachedClient: WishlistStackClient | undefined;\n let cachedToken: string | undefined;\n\n const server: WishlistStackHydrogenServer = {\n async getCustomerAccessToken() {\n return await getToken();\n },\n async getClient() {\n const token = await getToken();\n // Cache by token value so calls within a single request reuse the client.\n if (cachedClient && cachedToken === token) return cachedClient;\n cachedToken = token;\n cachedClient = createWishlistStackClient({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n customerAccessToken: token,\n });\n return cachedClient;\n },\n async bootstrapClientConfig(opts) {\n const expose = opts?.exposeCustomerAccessToken ?? false;\n const token = expose ? await getToken() : undefined;\n return {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n customerAccessToken: token,\n };\n },\n };\n\n const wishlistStackClient = createLazyWishlistStackClient(server.getClient);\n\n const anyCtx = context as any;\n if (anyCtx && typeof anyCtx.set === \"function\") {\n // Context map style (some React Router middleware implementations).\n anyCtx.set(\"wishlistStack\", server);\n anyCtx.set(\"wishlistStackClient\", wishlistStackClient);\n } else if (anyCtx && typeof anyCtx === \"object\") {\n // Plain object style (Hydrogen load context is an object).\n anyCtx.wishlistStack = server;\n anyCtx.wishlistStackClient = wishlistStackClient;\n }\n\n return { wishlistStack: server, wishlistStackClient };\n };\n}\n\n","import type { WishlistStackHydrogenOptions } from \"./types\";\nimport { createWishlistStackServerContext } from \"./server\";\n\ntype MiddlewareArgs = {\n request: Request;\n context: any;\n};\n\ntype MiddlewareNext = () => Promise<Response> | Response;\n\n/**\n * React Router middleware helper (Hydrogen react-router, middleware-enabled).\n *\n * We intentionally avoid importing react-router types here; we only require the\n * common shape: an object `context` that we can mutate (or that has `set()`).\n */\nexport function createWishlistStackMiddleware(options: WishlistStackHydrogenOptions) {\n const attach = createWishlistStackServerContext(options);\n return async function wishlistStackMiddleware(args: MiddlewareArgs, next: MiddlewareNext) {\n const ctxObj = args.context ?? {};\n // `attach` registers `wishlistStack` and `wishlistStackClient` onto the context (supports `set()` and mutation).\n attach(ctxObj);\n\n return await next();\n };\n}\n\n","import type { WishlistStackClient } from \"@sdg.la/wishlist-stack-sdk\";\nimport type { WishlistStackHydrogenServer } from \"./types\";\n\ntype ContextMapLike = {\n get?: (key: string) => unknown;\n wishlistStack?: WishlistStackHydrogenServer;\n wishlistStackClient?: WishlistStackClient;\n};\n\nasync function maybeAwait<T>(value: T | Promise<T>): Promise<T> {\n return value instanceof Promise ? await value : value;\n}\n\n/**\n * Retrieve `wishlistStackClient` from a Hydrogen/React Router loader context.\n *\n * Supports both styles:\n * - plain object: `context.wishlistStackClient`\n * - context map: `context.get('wishlistStackClient')`\n */\nexport async function getWishlistStackClient(context: unknown): Promise<WishlistStackClient> {\n const ctx = context as ContextMapLike | null | undefined;\n if (!ctx) throw new Error(\"Missing loader context (expected context.wishlistStackClient).\");\n\n if (ctx.wishlistStackClient) return ctx.wishlistStackClient;\n if (typeof ctx.get === \"function\") {\n const val = await maybeAwait(ctx.get(\"wishlistStackClient\") as any);\n if (val) return val as WishlistStackClient;\n }\n\n throw new Error(\n \"Wishlist Stack client not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context.\",\n );\n}\n\n/**\n * Retrieve the server helper (`wishlistStack`) from a Hydrogen/React Router loader context.\n * (Useful for bootstrap/token helpers; most route code should just use `wishlistStackClient`.)\n */\nexport async function getWishlistStack(context: unknown): Promise<WishlistStackHydrogenServer> {\n const ctx = context as ContextMapLike | null | undefined;\n if (!ctx) throw new Error(\"Missing loader context (expected context.wishlistStack).\");\n\n if (ctx.wishlistStack) return ctx.wishlistStack;\n if (typeof ctx.get === \"function\") {\n const val = await maybeAwait(ctx.get(\"wishlistStack\") as any);\n if (val) return val as WishlistStackHydrogenServer;\n }\n\n throw new Error(\n \"Wishlist Stack helper not found on loader context. Ensure you called createWishlistStackServerContext(...)(context) in your server/app load context.\",\n );\n}\n\n"]}
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ var wishlistStackSdk = require('@sdg.la/wishlist-stack-sdk');
4
+
5
+ // src/server.ts
6
+ function createLazyWishlistStackClient(getClient) {
7
+ return {
8
+ lists: {
9
+ getAll: (query) => getClient().then((c) => c.lists.getAll(query)),
10
+ getById: (listId) => getClient().then((c) => c.lists.getById(listId)),
11
+ create: (body) => getClient().then((c) => c.lists.create(body)),
12
+ update: (listId, body) => getClient().then((c) => c.lists.update(listId, body)),
13
+ remove: (listId) => getClient().then((c) => c.lists.remove(listId)),
14
+ addItems: (listId, body) => getClient().then((c) => c.lists.addItems(listId, body)),
15
+ updateItem: (listId, itemId, body) => getClient().then((c) => c.lists.updateItem(listId, itemId, body)),
16
+ removeItem: (listId, itemId) => getClient().then((c) => c.lists.removeItem(listId, itemId)),
17
+ share: (listId) => getClient().then((c) => c.lists.share(listId)),
18
+ unshare: (listId) => getClient().then((c) => c.lists.unshare(listId)),
19
+ addItemsLegacy: (id, body) => getClient().then((c) => c.lists.addItemsLegacy(id, body))
20
+ },
21
+ groups: {
22
+ getAll: () => getClient().then((c) => c.groups.getAll()),
23
+ getById: (groupId) => getClient().then((c) => c.groups.getById(groupId)),
24
+ create: (body) => getClient().then((c) => c.groups.create(body)),
25
+ update: (groupId, body) => getClient().then((c) => c.groups.update(groupId, body)),
26
+ remove: (groupId) => getClient().then((c) => c.groups.remove(groupId)),
27
+ reorder: (groupId, body) => getClient().then((c) => c.groups.reorder(groupId, body)),
28
+ share: (groupId) => getClient().then((c) => c.groups.share(groupId)),
29
+ unshare: (groupId) => getClient().then((c) => c.groups.unshare(groupId))
30
+ },
31
+ shared: {
32
+ getSharedList: (listId) => getClient().then((c) => c.shared.getSharedList(listId)),
33
+ getSharedGroup: (groupId) => getClient().then((c) => c.shared.getSharedGroup(groupId))
34
+ }
35
+ };
36
+ }
37
+ async function defaultGetCustomerAccessToken(context) {
38
+ const anyCtx = context;
39
+ const customerAccount = anyCtx?.customerAccount;
40
+ const fn = customerAccount?.getAccessToken;
41
+ if (typeof fn !== "function") return void 0;
42
+ try {
43
+ const token = await fn.call(customerAccount);
44
+ return typeof token === "string" ? token : void 0;
45
+ } catch {
46
+ return void 0;
47
+ }
48
+ }
49
+ function createWishlistStackServerContext(options) {
50
+ return function attachToContext(context) {
51
+ if (!options.apiKey) {
52
+ throw new Error("merchant api key is required. Pass it to createWishlistStackServerContext({ apiKey })");
53
+ }
54
+ const getToken = async () => {
55
+ if (options.getCustomerAccessToken) {
56
+ const token = await options.getCustomerAccessToken(context);
57
+ return typeof token === "string" ? token : void 0;
58
+ }
59
+ return await defaultGetCustomerAccessToken(context);
60
+ };
61
+ let cachedClient;
62
+ let cachedToken;
63
+ const server = {
64
+ async getCustomerAccessToken() {
65
+ return await getToken();
66
+ },
67
+ async getClient() {
68
+ const token = await getToken();
69
+ if (cachedClient && cachedToken === token) return cachedClient;
70
+ cachedToken = token;
71
+ cachedClient = wishlistStackSdk.createWishlistStackClient({
72
+ apiKey: options.apiKey,
73
+ baseUrl: options.baseUrl,
74
+ customerAccessToken: token
75
+ });
76
+ return cachedClient;
77
+ },
78
+ async bootstrapClientConfig(opts) {
79
+ const expose = opts?.exposeCustomerAccessToken ?? false;
80
+ const token = expose ? await getToken() : void 0;
81
+ return {
82
+ apiKey: options.apiKey,
83
+ baseUrl: options.baseUrl,
84
+ customerAccessToken: token
85
+ };
86
+ }
87
+ };
88
+ const wishlistStackClient = createLazyWishlistStackClient(server.getClient);
89
+ const anyCtx = context;
90
+ if (anyCtx && typeof anyCtx.set === "function") {
91
+ anyCtx.set("wishlistStack", server);
92
+ anyCtx.set("wishlistStackClient", wishlistStackClient);
93
+ } else if (anyCtx && typeof anyCtx === "object") {
94
+ anyCtx.wishlistStack = server;
95
+ anyCtx.wishlistStackClient = wishlistStackClient;
96
+ }
97
+ return { wishlistStack: server, wishlistStackClient };
98
+ };
99
+ }
100
+
101
+ // src/middleware.ts
102
+ function createWishlistStackMiddleware(options) {
103
+ const attach = createWishlistStackServerContext(options);
104
+ return async function wishlistStackMiddleware(args, next) {
105
+ const ctxObj = args.context ?? {};
106
+ attach(ctxObj);
107
+ return await next();
108
+ };
109
+ }
110
+
111
+ exports.createWishlistStackMiddleware = createWishlistStackMiddleware;
112
+ //# sourceMappingURL=middleware.cjs.map
113
+ //# sourceMappingURL=middleware.cjs.map