Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/composables/nuxt/plugin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { integrationPlugin } from '@vue-storefront/core'
import { integrationPlugin } from '@vue-storefront/magento-theme/helpers/integrationPlugin'
import { mapConfigToSetupObject } from '@vue-storefront/magento/nuxt/helpers';
import defaultConfig from '@vue-storefront/magento/nuxt/defaultConfig';
import cookie from '@vue-storefront/magento/nuxt/cookie';
Expand Down
4 changes: 2 additions & 2 deletions packages/theme/components/Header/SearchBar/SearchBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ import {
} from '@nuxtjs/composition-api';
import debounce from 'lodash.debounce';
import { clickOutside } from '~/utilities/directives/click-outside/click-outside-directive.js';
import { useCategorySearch, useFacet } from '~/composables';
import { categoryGetters } from '~/getters';
import SvgImage from '~/components/General/SvgImage.vue';
import { useFacet, useCategorySearch } from '~/composables';
import { categoryGetters } from '~/getters';

export default defineComponent({
name: 'SearchBar',
Expand Down
52 changes: 52 additions & 0 deletions packages/theme/helpers/integrationPlugin/_proxyUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { IncomingMessage } from 'node:http';
import { Context as NuxtContext } from '@nuxt/types';
import merge from 'lodash.merge';

export type ApiClientMethod = (...args: any) => Promise<any>;

interface CreateProxiedApiParams {
givenApi: Record<string, ApiClientMethod>;
client: any;
tag: string;
}

export const getBaseUrl = (req: IncomingMessage, basePath: string | undefined = '/'): string => {
if (!req) return `${basePath}api/`;
const { headers } = req;
// eslint-disable-next-line global-require, unicorn/prefer-module
const isHttps = require('is-https')(req);
const scheme = isHttps ? 'https' : 'http';
const host = headers['x-forwarded-host'] || headers.host;

return `${scheme}://${host}${basePath}api/`;
};

export const createProxiedApi = ({ givenApi, client, tag }: CreateProxiedApiParams) => new Proxy(givenApi, {
get: (target, prop, receiver) => {
const functionName = String(prop);
if (Reflect.has(target, functionName)) {
return Reflect.get(target, prop, receiver);
}

// eslint-disable-next-line @typescript-eslint/require-await
return async (...args) => client
.post(`/${tag}/${functionName}`, args)
.then((r) => r.data);
},
});

export const getCookies = (context: NuxtContext) => context?.req?.headers?.cookie ?? '';

export const getIntegrationConfig = (context: NuxtContext, configuration: any) => {
const cookie = getCookies(context);
const initialConfig = merge({
axios: {
baseURL: getBaseUrl(context?.req, context?.base),
headers: {
...(cookie ? { cookie } : {}),
},
},
}, configuration);

return initialConfig;
};
30 changes: 30 additions & 0 deletions packages/theme/helpers/integrationPlugin/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* It extends given integartion, defined by `tag` in the context.
*/
export const createExtendIntegrationInCtx = ({ tag, nuxtCtx, inject }) => (integrationProperties) => {
const integrationKey = '$' + tag;

if (!nuxtCtx.$vsf || !nuxtCtx.$vsf[integrationKey]) {
inject('vsf', { [integrationKey]: {} });
}

Object.keys(integrationProperties)
.filter(k => !['api', 'client', 'config'].includes(k))
.forEach(key => {
nuxtCtx.$vsf[integrationKey][key] = integrationProperties[key];
});
};

/**
* It creates a function that adds an integration to the context under the given name, defined by `tag`.
*/
export const createAddIntegrationToCtx = ({ tag, nuxtCtx, inject }) => (integrationProperties) => {
const integrationKey = '$' + tag;

if (nuxtCtx.$vsf && !nuxtCtx.$vsf[integrationKey]) {
nuxtCtx.$vsf[integrationKey] = integrationProperties;
return;
}

inject('vsf', { [integrationKey]: integrationProperties });
};
55 changes: 55 additions & 0 deletions packages/theme/helpers/integrationPlugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Context as NuxtContext, Plugin as NuxtPlugin } from '@nuxt/types';
import axios from 'axios';
import { createExtendIntegrationInCtx, createAddIntegrationToCtx } from './context';
import { getIntegrationConfig, createProxiedApi } from './_proxyUtils';

type InjectFn = (key: string, value: any) => void;
export type IntegrationPlugin = (pluginFn: NuxtPlugin) => NuxtPlugin;

const parseCookies = (cookieString: string): Record<string, string> => Object.fromEntries(cookieString
.split(';')
// eslint-disable-next-line unicorn/no-array-callback-reference
.filter(String)
.map((item) => item.split('=').map((part) => part.trim()))
.map(([name, value]) => [name, value]));

const setCookieValues = (cookieValues: Record<string, string>, cookieString = '') => {
const parsed = parseCookies(cookieString);

// eslint-disable-next-line no-return-assign
Object.entries(cookieValues).forEach(([name, value]) => parsed[name] = value);

return Object.entries(parsed).map(([name, value]) => `${name}=${value}`).join('; ');
};

export const integrationPlugin = (pluginFn: NuxtPlugin) => (nuxtCtx: NuxtContext, inject: InjectFn) => {
const configure = (tag, configuration) => {
const injectInContext = createAddIntegrationToCtx({ tag, nuxtCtx, inject });
const config = getIntegrationConfig(nuxtCtx, configuration);
const { middlewareUrl, ssrMiddlewareUrl } = (nuxtCtx as any).$config;

if (middlewareUrl) {
config.axios.baseURL = process.server ? ssrMiddlewareUrl || middlewareUrl : middlewareUrl;
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const client = axios.create(config.axios);
const api = createProxiedApi({ givenApi: configuration.api || {}, client, tag });

if ((nuxtCtx.app.i18n as any).cookieValues) {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
client.defaults.headers.cookie = setCookieValues((nuxtCtx.app.i18n as any).cookieValues, (client.defaults.headers as any).cookie);
}

injectInContext({ api, client, config });
};

const extend = (tag, integrationProperties) => {
createExtendIntegrationInCtx({ tag, nuxtCtx, inject })(integrationProperties);
};

const integration = { configure, extend };

pluginFn({ ...nuxtCtx, integration } as NuxtContext, inject);
};
9 changes: 5 additions & 4 deletions packages/theme/modules/catalog/pages/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,9 @@ import {
SfSelect,
SfSidebar,
} from '@storefront-ui/vue';
import { defineComponent, ref, useFetch } from '@nuxtjs/composition-api';
import { useVSFContext } from '@vue-storefront/core';
import {
defineComponent, ref, useContext, useFetch,
} from '@nuxtjs/composition-api';
import { CacheTagPrefix, useCache } from '@vue-storefront/cache';
import { facetGetters, productGetters } from '~/getters';
import {
Expand Down Expand Up @@ -439,8 +440,8 @@ export default defineComponent({

const { path, search: resolveUrl } = useUrlResolver();
const {
$magento: { config: magentoConfig },
} = useVSFContext();
$vsf: { $magento: { config: magentoConfig } },
} = useContext();
const { isAuthenticated } = useUser();
const {
addItem: addItemToWishlistBase,
Expand Down
5 changes: 5 additions & 0 deletions packages/theme/modules/context/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import path from 'node:path';

export default function VueStorefrontContextShimModule() {
this.addPlugin(path.resolve(__dirname, './plugins/context.js'));
}
15 changes: 15 additions & 0 deletions packages/theme/modules/context/plugins/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { configureContext } from '@vue-storefront/core';
import { useContext } from '@nuxtjs/composition-api';

const setUpBackwardsCompatibilityForSharedRefs = () => {
const useVSFContext = () => {
const { $sharedRefsMap } = useContext();
return { $sharedRefsMap };
};
configureContext({ useVSFContext });
};

export default (_ctx, inject) => {
setUpBackwardsCompatibilityForSharedRefs();
inject('sharedRefsMap', new Map()); // for sharedRef
};
6 changes: 6 additions & 0 deletions packages/theme/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export default () => {
'@vue-storefront/core',
],
},
// selectively disabling certain @vue-storefront/core plugins for migration
context: false,
}],
['@vue-storefront/magento/nuxt', {
i18n: {
Expand All @@ -99,6 +101,7 @@ export default () => {
}],
'@nuxt/image',
'@pinia/nuxt',
'~/modules/context',
],
modules: [
'~/modules/catalog',
Expand Down Expand Up @@ -190,6 +193,9 @@ export default () => {
extractCSS: true,
optimizeCSS: true,
parallel: true,
extend(cfg, ctx) {
cfg.devtool = 'source-map'
},
plugins: [
new webpack.DefinePlugin({
'process.VERSION': JSON.stringify({
Expand Down
8 changes: 5 additions & 3 deletions packages/theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"build": "nuxt build -m",
"build:analyze": "nuxt build -a -m",
"dev": "nuxt",
"dev-debug": "nuxt --inspect",
"dev:debug": "node --inspect ../../node_modules/.bin/nuxt dev",
"generate": "nuxt generate",
"lint": "eslint . --ext .ts,.vue",
"lint:fix": "eslint . --ext .ts,.vue --fix",
Expand All @@ -27,26 +27,28 @@
"update:update": "ncu -u"
},
"dependencies": {
"@beyonk/google-fonts-webpack-plugin": "^1.7",
"@nuxt/image": "^0.6.1",
"@nuxtjs/composition-api": "^0.31.0",
"@nuxtjs/device": "^2.1.0",
"@beyonk/google-fonts-webpack-plugin": "^1.7",
"@nuxtjs/pwa": "^3.3.5",
"@nuxtjs/style-resources": "^1.2.1",
"@pinia/nuxt": "^0.1.8",
"@storefront-ui/vue": "^0.11.5",
"@vue-storefront/magento": "^1.0.0-rc.6",
"@vue-storefront/cache": "~2.5.6",
"@vue-storefront/core": "~2.5.6",
"@vue-storefront/magento": "^1.0.0-rc.6",
"@vue-storefront/middleware": "~2.5.6",
"@vue-storefront/nuxt": "~2.5.6",
"@vue-storefront/redis-cache": "^1.0.1",
"axios": "^0.26.1",
"convict": "^6.2.1",
"convict-format-with-validator": "^6.2.0",
"cookie-universal-nuxt": "^2.1.5",
"deepdash": "^5.3.9",
"dotenv": "^16.0.0",
"graphql-request": "^4.0.0",
"is-https": "^4.0.0",
"isomorphic-dompurify": "^0.18.0",
"lodash.debounce": "^4.0.8",
"lodash.merge": "^4.6.2",
Expand Down
4 changes: 1 addition & 3 deletions packages/theme/pages/Checkout/Payment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ import {
SfProperty,
SfLink,
} from '@storefront-ui/vue';
import { useVSFContext } from '@vue-storefront/core';
import {
ref,
computed,
Expand Down Expand Up @@ -197,8 +196,7 @@ export default defineComponent({
const order = ref(null);
const { cart, load, setCart } = useCart();
const { make, loading } = useMakeOrder();
const { $magento } = useVSFContext();
const { app } = useContext();
const { app, $vsf: { $magento } } = useContext();
const router = useRouter();
const isPaymentReady = ref(false);
const terms = ref(false);
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5436,6 +5436,13 @@ axios@^0.21.0:
dependencies:
follow-redirects "^1.14.0"

axios@^0.26.1:
version "0.26.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9"
integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==
dependencies:
follow-redirects "^1.14.8"

babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
Expand Down Expand Up @@ -9724,7 +9731,7 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"

follow-redirects@^1.10.0, follow-redirects@^1.14.0:
follow-redirects@^1.10.0, follow-redirects@^1.14.0, follow-redirects@^1.14.8:
version "1.14.9"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7"
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==
Expand Down