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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Adds module which handles cache invalidation for Fastly. - @gibkigonzo (#4096)
- Add vsf-cache-nginx and vsf-cache-varnish modules - @gibkigonzo (#4096)
- Added meta info for CMS pages from Magento @mdanilowicz (#4392)
- Add useful core events to server & logger - @cewald (#4419)

### Fixed

Expand Down
11 changes: 9 additions & 2 deletions core/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ const {
executor: afterProductThumbnailPathGeneratedExecutor
} = createMutatorHook<{ path: string, pathType: string, sizeX: number, sizeY: number }, { path: string }>()

const {
hook: beforeLogRenderedHook,
executor: beforeLogRenderedExecutor
} = createMutatorHook<{ type: string, message: any, tag: any, context: any, noDefaultOutput?: boolean }, { message: any, tag: any, context: any, noDefaultOutput?: boolean }>()

/** Only for internal usage in core */
const coreHooksExecutors = {
afterAppInit: afterAppInitExecutor,
beforeStoreViewChanged: beforeStoreViewChangedExecutor,
afterStoreViewChanged: afterStoreViewChangedExecutor,
beforeHydrated: beforeHydratedExecutor,
afterProductThumbnailPathGenerate: afterProductThumbnailPathGeneratedExecutor
afterProductThumbnailPathGenerate: afterProductThumbnailPathGeneratedExecutor,
beforeLogRendered: beforeLogRenderedExecutor
}

const coreHooks = {
Expand All @@ -46,7 +52,8 @@ const coreHooks = {
*/
afterStoreViewChanged: afterStoreViewChangedHook,
beforeHydrated: beforeHydratedHook,
afterProductThumbnailPathGenerate: afterProductThumbnailPathGeneratedHook
afterProductThumbnailPathGenerate: afterProductThumbnailPathGeneratedHook,
beforeLogRendered: beforeLogRenderedHook
}

export {
Expand Down
26 changes: 26 additions & 0 deletions core/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isServer } from '@vue-storefront/core/helpers'
import { coreHooksExecutors } from '@vue-storefront/core/hooks'
import buildTimeConfig from 'config'
const bgColorStyle = (color) => `color: white; background: ${color}; padding: 4px; font-weight: bold; font-size: 0.8em'`

Expand Down Expand Up @@ -71,6 +72,12 @@ class Logger {
return () => {}
}

let noDefaultOutput
({ message, tag, context, noDefaultOutput } = coreHooksExecutors.beforeLogRendered({ type: 'debug', message, tag, context }))
if (noDefaultOutput === true) {
return () => {}
}

if (isServer) {
return console.debug.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context)
}
Expand Down Expand Up @@ -107,6 +114,12 @@ class Logger {
return () => {}
}

let noDefaultOutput
({ message, tag, context, noDefaultOutput } = coreHooksExecutors.beforeLogRendered({ type: 'info', message, tag, context }))
if (noDefaultOutput === true) {
return () => {}
}

if (isServer) {
return console.log.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context)
}
Expand All @@ -130,6 +143,13 @@ class Logger {
if (!this.canPrint('warn')) {
return () => {}
}

let noDefaultOutput
({ message, tag, context, noDefaultOutput } = coreHooksExecutors.beforeLogRendered({ type: 'warn', message, tag, context }))
if (noDefaultOutput === true) {
return () => {}
}

if (isServer) {
return console.warn.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context)
}
Expand All @@ -150,6 +170,12 @@ class Logger {
* @param context meaningful data related to this message
*/
public error (message: any, tag: string = null, context: any = null): () => void {
let noDefaultOutput
({ message, tag, context, noDefaultOutput } = coreHooksExecutors.beforeLogRendered({ type: 'error', message, tag, context }))
if (noDefaultOutput === true) {
return () => {}
}

if (isServer) { // always show errors in SSR
return console.error.bind(console, (tag ? `[${tag}] ` : '') + this.convertToString(message), context)
}
Expand Down
4 changes: 2 additions & 2 deletions core/lib/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const quickSearchByQuery = async ({ query = {}, start = 0, size = 50, ent
return
}
} catch (err) {
console.error('Cannot read cache for ' + cacheKey + ', ' + err)
Logger.error('Cannot read cache for ' + cacheKey + ', ' + err)()
}

/* use only for cache */
Expand All @@ -91,7 +91,7 @@ export const quickSearchByQuery = async ({ query = {}, start = 0, size = 50, ent
const res = searchAdapter.entities[Request.type].resultProcessor(resp, start, size)

if (res) { // otherwise it can be just a offline mode
cache.setItem(cacheKey, res, null, config.elasticsearch.disablePersistentQueriesCache).catch((err) => { console.error('Cannot store cache for ' + cacheKey + ', ' + err) })
cache.setItem(cacheKey, res, null, config.elasticsearch.disablePersistentQueriesCache).catch((err) => { Logger.error('Cannot store cache for ' + cacheKey + ', ' + err)() })
if (!servedFromCache) { // if navigator onLine == false means ES is unreachable and probably this will return false; sometimes returned false faster than indexedDb cache returns result ...
Logger.debug('Result from ES for ' + cacheKey + ' (' + entityType + '), ms=' + (new Date().getTime() - benchmarkTime.getTime()))()
res.cache = false
Expand Down
9 changes: 5 additions & 4 deletions core/modules/cart/helpers/cartCacheHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as types from '../store/mutation-types';
import * as types from '../store/mutation-types'
import { Logger } from '@vue-storefront/core/lib/logger'

import { StorageManager } from '@vue-storefront/core/lib/storage-manager'

Expand All @@ -15,19 +16,19 @@ export function cartCacheHandlerFactory (Vue) {
type.endsWith(types.CART_UPD_ITEM_PROPS)
) {
return StorageManager.get('cart').setItem('current-cart', state.cart.cartItems).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
} else if (
type.endsWith(types.CART_LOAD_CART_SERVER_TOKEN)
) {
return StorageManager.get('cart').setItem('current-cart-token', state.cart.cartServerToken).catch((reason) => {
console.error(reason)
Logger.error(reason)()
})
} else if (
type.endsWith(types.CART_SET_ITEMS_HASH)
) {
return StorageManager.get('cart').setItem('current-cart-hash', state.cart.cartItemsHash).catch((reason) => {
console.error(reason)
Logger.error(reason)()
})
}
}
Expand Down
13 changes: 10 additions & 3 deletions core/modules/cart/test/unit/helpers/cartCacheHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Vue from 'vue'
import Vuex from 'vuex'

import * as types from '../../../store/mutation-types'
import { Logger } from '@vue-storefront/core/lib/logger'

const StorageManager = {
cart: {
Expand All @@ -20,6 +21,12 @@ jest.mock('@vue-storefront/core/helpers', () => ({
jest.mock('@vue-storefront/core/app', () => ({ createApp: jest.fn() }))
jest.mock('@vue-storefront/i18n', () => ({ loadLanguageAsync: jest.fn() }))

jest.mock('@vue-storefront/core/lib/logger', () => ({
Logger: {
error: () => () => {}
}
}))

Vue.use(Vuex);

describe('Cart afterRegistration', () => {
Expand Down Expand Up @@ -55,7 +62,7 @@ describe('Cart afterRegistration', () => {
}
};

const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementationOnce(() => {});
const consoleErrorSpy = jest.spyOn(Logger, 'error');

StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.reject('foo'));

Expand Down Expand Up @@ -86,7 +93,7 @@ describe('Cart afterRegistration', () => {
}
};

const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementationOnce(() => {});
const consoleErrorSpy = jest.spyOn(Logger, 'error');

StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.reject('foo'));

Expand All @@ -102,7 +109,7 @@ describe('Cart afterRegistration', () => {
}
};

const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementationOnce(() => {});
const consoleErrorSpy = jest.spyOn(Logger, 'error');

StorageManager.get('cart').setItem.mockImplementationOnce(() => Promise.reject('foo'));

Expand Down
17 changes: 9 additions & 8 deletions core/modules/catalog/store/product/mutations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MutationTree } from 'vuex'
import { Logger } from '@vue-storefront/core/lib/logger'
import * as types from './mutation-types'
import ProductState, { PagedProductList } from '../../types/ProductState'
import Vue from 'vue'
Expand Down Expand Up @@ -92,28 +93,28 @@ const mutations: MutationTree<ProductState> = {
state.breadcrumbs = payload
},
[types.CATALOG_ADD_CUSTOM_OPTION_VALIDATOR] (state, { validationRule, validatorFunction }) {
console.error('Deprecated mutation CATALOG_ADD_CUSTOM_OPTION_VALIDATOR - use PRODUCT_SET_CUSTOM_OPTION_VALIDATOR instead')
Logger.error('Deprecated mutation CATALOG_ADD_CUSTOM_OPTION_VALIDATOR - use PRODUCT_SET_CUSTOM_OPTION_VALIDATOR instead')()
},
[types.CATALOG_UPD_RELATED] (state, { key, items }) {
console.error('Deprecated mutation CATALOG_UPD_RELATED - use PRODUCT_SET_RELATED instead')
Logger.error('Deprecated mutation CATALOG_UPD_RELATED - use PRODUCT_SET_RELATED instead')()
},
[types.CATALOG_UPD_BUNDLE_OPTION] (state, { optionId, optionQty, optionSelections }) {
console.error('Deprecated mutation CATALOG_UPD_BUNDLE_OPTION - use PRODUCT_SET_BUNDLE_OPTION instead')
Logger.error('Deprecated mutation CATALOG_UPD_BUNDLE_OPTION - use PRODUCT_SET_BUNDLE_OPTION instead')()
},
[types.CATALOG_UPD_PRODUCTS] (state, { products, append }) {
console.error('Deprecated mutation CATALOG_UPD_PRODUCTS - use PRODUCT_SET_PAGED_PRODUCTS or PRODUCT_ADD_PAGED_PRODUCTS instead')
Logger.error('Deprecated mutation CATALOG_UPD_PRODUCTS - use PRODUCT_SET_PAGED_PRODUCTS or PRODUCT_ADD_PAGED_PRODUCTS instead')()
},
[types.CATALOG_SET_PRODUCT_CURRENT] (state, product) {
console.error('Deprecated mutation CATALOG_SET_PRODUCT_CURRENT - use PRODUCT_SET_CURRENT instead')
Logger.error('Deprecated mutation CATALOG_SET_PRODUCT_CURRENT - use PRODUCT_SET_CURRENT instead')()
},
[types.CATALOG_SET_PRODUCT_ORIGINAL] (state, product) {
console.error('Deprecated mutation CATALOG_SET_PRODUCT_ORIGINAL - use PRODUCT_SET_ORIGINAL instead')
Logger.error('Deprecated mutation CATALOG_SET_PRODUCT_ORIGINAL - use PRODUCT_SET_ORIGINAL instead')()
},
[types.CATALOG_RESET_PRODUCT] (state, productOriginal) {
console.error('Deprecated mutation CATALOG_RESET_PRODUCT - use PRODUCT_RESET_CURRENT instead')
Logger.error('Deprecated mutation CATALOG_RESET_PRODUCT - use PRODUCT_RESET_CURRENT instead')()
},
[types.CATALOG_UPD_GALLERY] (state, productGallery) {
console.error('Deprecated mutation CATALOG_UPD_GALLERY - use PRODUCT_SET_GALLERY instead')
Logger.error('Deprecated mutation CATALOG_UPD_GALLERY - use PRODUCT_SET_GALLERY instead')()
}
}

Expand Down
7 changes: 4 additions & 3 deletions core/modules/checkout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { StorefrontModule } from '@vue-storefront/core/lib/modules'
import { checkoutModule } from './store/checkout'
import { paymentModule } from './store/payment'
import { shippingModule } from './store/shipping'
import { Logger } from '@vue-storefront/core/lib/logger'
import * as types from './store/checkout/mutation-types'
import { StorageManager } from '@vue-storefront/core/lib/storage-manager'

Expand All @@ -19,23 +20,23 @@ export const CheckoutModule: StorefrontModule = function ({ store }) {
type.endsWith(types.CHECKOUT_SAVE_PERSONAL_DETAILS)
) {
StorageManager.get('checkout').setItem('personal-details', state.checkout.personalDetails).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
}

if (
type.endsWith(types.CHECKOUT_SAVE_SHIPPING_DETAILS) || type.endsWith(types.CHECKOUT_UPDATE_PROP_VALUE)
) {
StorageManager.get('checkout').setItem('shipping-details', state.checkout.shippingDetails).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
}

if (
type.endsWith(types.CHECKOUT_SAVE_PAYMENT_DETAILS)
) {
StorageManager.get('checkout').setItem('payment-details', state.checkout.paymentDetails).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
}
})
Expand Down
2 changes: 1 addition & 1 deletion core/modules/recently-viewed/store/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function plugin (mutation, state) {

if (type.startsWith(types.SN_RECENTLY_VIEWED)) { // check if this mutation is recently-viewed related
cacheStorage.setItem('recently-viewed', state['recently-viewed'].items).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
})
}
}
4 changes: 2 additions & 2 deletions core/modules/url/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ export const actions: ActionTree<UrlState, any> = {
* This method could be overriden in custom module to provide custom URL mapping logic
*/
async mappingFallback ({ dispatch }, { url, params }: { url: string, params: any}) {
console.warn(`
Logger.warn(`
Deprecated action mappingFallback - use mapFallbackUrl instead.
You can enable mapFallbackUrl by changing 'config.urlModule.enableMapFallbackUrl' to true
`)
`)()
const { storeCode, appendStoreCode } = currentStoreView()
const productQuery = new SearchQuery()
url = (removeStoreCodeFromRoute(url.startsWith('/') ? url.slice(1) : url) as string)
Expand Down
9 changes: 5 additions & 4 deletions core/modules/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { userStore } from './store'
import { StorefrontModule } from '@vue-storefront/core/lib/modules'
import { StorageManager } from '@vue-storefront/core/lib/storage-manager'
import { isServer } from '@vue-storefront/core/helpers'
import { Logger } from '@vue-storefront/core/lib/logger'
import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'
import * as types from './store/mutation-types'

Expand Down Expand Up @@ -36,27 +37,27 @@ export const UserModule: StorefrontModule = async function ({ store }) {
type.endsWith(types.USER_INFO_LOADED)
) {
StorageManager.get('user').setItem('current-user', state.user.current).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
}

if (
type.endsWith(types.USER_ORDERS_HISTORY_LOADED)
) {
StorageManager.get('user').setItem('orders-history', state.user.orders_history).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
}

if (
type.endsWith(types.USER_TOKEN_CHANGED)
) {
StorageManager.get('user').setItem('current-token', state.user.token).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
if (state.user.refreshToken) {
StorageManager.get('user').setItem('current-refresh-token', state.user.refreshToken).catch((reason) => {
console.error(reason) // it doesn't work on SSR
Logger.error(reason)() // it doesn't work on SSR
}) // populate cache
}
}
Expand Down
32 changes: 17 additions & 15 deletions core/scripts/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ app.get('*', (req, res, next) => {
res.redirect('/error')
console.error(`Error during render : ${req.url}`)
console.error(err)
serverHooksExecutors.ssrException({ err, req, isProd })
next()
}
}
Expand Down Expand Up @@ -322,20 +323,21 @@ app.get('*', (req, res, next) => {
let port = process.env.PORT || config.server.port
const host = process.env.HOST || config.server.host
const start = () => {
app.listen(port, host)
.on('listening', () => {
console.log(`\n\n----------------------------------------------------------`)
console.log('| |')
console.log(`| Vue Storefront Server started at http://${host}:${port} |`)
console.log('| |')
console.log(`----------------------------------------------------------\n\n`)
})
.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
port = parseInt(port) + 1
console.log(`The port is already in use, trying ${port}`)
start()
}
})
const server = app.listen(port, host)
server.on('listening', () => {
console.log(`\n\n----------------------------------------------------------`)
console.log('| |')
console.log(`| Vue Storefront Server started at http://${host}:${port} |`)
console.log('| |')
console.log(`----------------------------------------------------------\n\n`)

serverHooksExecutors.httpServerIsReady({ server, config: config.server, isProd })
}).on('error', (e) => {
if (e.code === 'EADDRINUSE') {
port = parseInt(port) + 1
console.log(`The port is already in use, trying ${port}`)
start()
}
})
}
start()
Loading