@scayle/storefront-nuxt
Version:
Nuxt integration for the SCAYLE Commerce Engine and Storefront API
176 lines (175 loc) • 5.96 kB
JavaScript
import { getRequestIP, getRequestHeaders } from "h3";
import {
createAndPurifyHeaders,
StorefrontAPIClient,
unwrap,
generateBasketKey,
generateWishlistKey,
DEFAULT_RPC_HTTP_METHOD
} from "@scayle/storefront-core";
import { useNitroApp } from "nitropack/runtime";
import { getCachedFunction } from "./cached.js";
import { getApiBasePath } from "./server/middleware/bootstrap-utils.js";
import { fetchCampaignKey } from "./campaignKey.js";
import * as moduleOptions from "#internal/storefront-options.mjs";
import { rpcHttpMethods } from "#virtual/rpcHttpMethods";
async function getWishlistKey(appKeys, session, $log, $shopConfig) {
return session.data.user ? await generateWishlistKey({
keyTemplate: appKeys.wishlistKey,
userId: String(session.data.user.id),
shopId: String($shopConfig.shopId),
hashAlgorithm: appKeys.hashAlgorithm,
log: $log
}) : session.id;
}
async function getBasketKey(appKeys, session, $log, $shopConfig) {
return session.data.user ? await generateBasketKey({
keyTemplate: appKeys.basketKey,
userId: String(session.data.user.id),
shopId: String($shopConfig.shopId),
hashAlgorithm: appKeys.hashAlgorithm,
log: $log
}) : session?.id;
}
function buildRpcCall(event, shopConfig, apiBasePath) {
const fetch = event.context.$fetchWithContext;
return async function rpcCall(method, params = void 0) {
const httpMethod = rpcHttpMethods[method] ?? DEFAULT_RPC_HTTP_METHOD;
const isGet = httpMethod === "GET";
const data = await fetch(`${apiBasePath}/rpc/${method}`, {
// @ts-expect-error Type 'RpcHttpMethod' is not assignable to type 'AvailableRouterMethod<...>'
method: httpMethod,
...isGet ? {
query: params !== void 0 ? { payload: JSON.stringify(params) } : void 0
} : {
body: {
payload: params
}
},
headers: {
"x-shop-id": shopConfig.shopId.toString()
}
});
return await unwrap(data);
};
}
export const buildContext = async (context) => {
const { $cache, $shopConfig, $storefront, $log, config, event, session } = context;
const sapiConfig = $shopConfig.sapi ?? $storefront.sapi;
const appKeys = $shopConfig.appKeys ?? $storefront.appKeys;
const idpConfig = $shopConfig.idp ?? $storefront.idp;
const sapiClient = new StorefrontAPIClient({
host: sapiConfig.host,
shopId: $shopConfig.shopId,
auth: {
type: "token",
token: sapiConfig.token
},
additionalHeaders: $storefront.internalAccessHeader ? {
"x-internal-access": $storefront.internalAccessHeader
} : {}
});
const cached = getCachedFunction($cache, $log, $storefront.cache?.enabled);
const { hooks } = useNitroApp();
const callRpc = buildRpcCall(
context.event,
$shopConfig,
getApiBasePath(moduleOptions, "/")
);
const rpcContext = {
cached,
sapiClient,
auth: {
resetPasswordUrl: $shopConfig.auth?.resetPasswordUrl
},
checkout: {
url: $shopConfig.checkout.host,
secret: $shopConfig.checkout.secret,
token: $shopConfig.checkout.token,
user: String($shopConfig.checkout.user),
cbdExpiration: $shopConfig.checkout.cbdExpiration
},
oauth: {
clientId: String($storefront.oauth.clientId),
clientSecret: $storefront.oauth.clientSecret,
apiHost: $storefront.oauth.apiHost
},
idp: idpConfig,
log: $log,
destroySessionsForUserId: async () => {
},
generateBasketKeyForUserId: (userId) => generateBasketKey({
keyTemplate: appKeys.basketKey,
userId,
shopId: String($shopConfig.shopId),
hashAlgorithm: appKeys.hashAlgorithm,
log: $log
}),
generateWishlistKeyForUserId: (userId) => generateWishlistKey({
keyTemplate: appKeys.wishlistKey,
userId,
shopId: String($shopConfig.shopId),
hashAlgorithm: appKeys.hashAlgorithm,
log: $log
}),
locale: $shopConfig.locale,
shopId: $shopConfig.shopId,
domain: $shopConfig.domain,
withParams: $storefront.withParams,
campaignKey: await fetchCampaignKey(sapiClient, cached, $log),
runtimeConfiguration: config,
get ip() {
return getRequestIP(event, { xForwardedFor: true });
},
get originalIp() {
return getRequestIP(event, { xForwardedFor: false });
},
get headers() {
return createAndPurifyHeaders(getRequestHeaders(event));
},
internalAccessHeader: $storefront.internalAccessHeader,
callHook: hooks.callHook,
callHookParallel: hooks.callHookParallel,
callHookWith: hooks.callHookWith,
wishlistKey: session ? await getWishlistKey(appKeys, session, $log, $shopConfig) : void 0,
basketKey: session ? await getBasketKey(appKeys, session, $log, $shopConfig) : void 0,
sessionId: session?.id,
get user() {
return session?.data?.user ?? void 0;
},
get accessToken() {
return session?.data?.accessToken ?? void 0;
},
get refreshToken() {
return session?.data?.refreshToken ?? void 0;
},
get sessionCustomData() {
return session?.data?.customData ?? void 0;
},
destroySession: session ? async () => {
await session.destroy();
} : void 0,
createUserBoundSession: session ? async () => {
$log.debug("creating user bound session");
const data = session.data;
await session.regenerate();
session.data = data;
await session.save();
} : void 0,
updateSessionCustomData: session ? async (customData) => {
session.data.customData = customData;
await session.save();
} : void 0,
updateUser: session ? async (user) => {
session.data.user = user;
await session.save();
} : void 0,
updateTokens: session ? async (tokens) => {
Object.assign(session.data, tokens);
await session.save();
} : void 0,
callRpc
};
await hooks?.callHook("storefront:context:created", rpcContext);
return rpcContext;
};