diff --git a/packages/pwa-kit-dev/bin/pwa-kit-dev.js b/packages/pwa-kit-dev/bin/pwa-kit-dev.js index d4c0ba365e..4903c99a77 100755 --- a/packages/pwa-kit-dev/bin/pwa-kit-dev.js +++ b/packages/pwa-kit-dev/bin/pwa-kit-dev.js @@ -249,7 +249,7 @@ const main = async () => { .addOption( new program.Option( '-b, --buildDirectory ', - 'a custom project directory where your build is located' + 'a custom project build directory that you want to push' ).default(p.join(process.cwd(), 'build'), './build') ) .addOption( @@ -285,12 +285,20 @@ const main = async () => { credentialsFile }) => { // Set the deployment target env var, this is required to ensure we - // get the correct configuration object. - process.env.DEPLOY_TARGET = target + // get the correct configuration object. Do not assign the variable it if + // the target value is `undefined` as it will serialied as a "undefined" + // string value. + if (target) { + process.env.DEPLOY_TARGET = target + } const credentials = await scriptUtils.readCredentials(credentialsFile) - const mobify = getConfig() || {} + if (!fse.pathExistsSync(buildDirectory)) { + throw new Error(`Supplied "buildDirectory" does not exist!`) + } + + const mobify = getConfig({buildDirectory}) || {} if (!projectSlug) { projectSlug = await getProjectName() diff --git a/packages/pwa-kit-runtime/CHANGELOG.md b/packages/pwa-kit-runtime/CHANGELOG.md index 758be0ebcd..c2a118f456 100644 --- a/packages/pwa-kit-runtime/CHANGELOG.md +++ b/packages/pwa-kit-runtime/CHANGELOG.md @@ -1,4 +1,5 @@ ## v2.8.0-dev (Mar 03, 2023) +- Add optional parameter to override configuration folder used in `getConfig` [#1049](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1049) ## v2.7.0 (Mar 03, 2023) - Support Node 16 [#965](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/965) diff --git a/packages/pwa-kit-runtime/src/utils/ssr-config.client.test.js b/packages/pwa-kit-runtime/src/utils/ssr-config.client.test.js new file mode 100644 index 0000000000..aeb203ffa5 --- /dev/null +++ b/packages/pwa-kit-runtime/src/utils/ssr-config.client.test.js @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +/* eslint-env jest */ +/* eslint max-nested-callbacks:0 */ + +import {getConfig} from './ssr-config.client' + +let windowSpy + +beforeEach(() => { + windowSpy = jest.spyOn(window, 'window', 'get') +}) + +afterEach(() => { + windowSpy.mockRestore() +}) + +describe('Client getConfig', () => { + test('returns window.__CONFIG__ value', () => { + windowSpy.mockImplementation(() => ({ + __CONFIG__: {} + })) + + expect(getConfig()).toEqual({}) + }) +}) diff --git a/packages/pwa-kit-runtime/src/utils/ssr-config.server.js b/packages/pwa-kit-runtime/src/utils/ssr-config.server.js index d23a54aee4..9e98d1d98d 100644 --- a/packages/pwa-kit-runtime/src/utils/ssr-config.server.js +++ b/packages/pwa-kit-runtime/src/utils/ssr-config.server.js @@ -8,6 +8,8 @@ /* istanbul ignore next */ const SUPPORTED_FILE_TYPES = ['js', 'yml', 'yaml', 'json'] +const IS_REMOTE = Object.prototype.hasOwnProperty.call(process.env, 'AWS_LAMBDA_FUNCTION_NAME') + /** * Returns the express app configuration file in object form. The file will be resolved in the * the following order: @@ -28,21 +30,26 @@ const SUPPORTED_FILE_TYPES = ['js', 'yml', 'yaml', 'json'] * Each file marked with `ext` can optionally be terminated with `js`, `yml|yaml` or * `json`. The file loaded is also determined based on that precidence of file extension. * + * @param {Object} opts.buildDirectory - Option path to the folder containing the configution. Byt default + * it is the `build` folder when running remotely and the project folder when developing locally. * @returns - the application configuration object. */ /* istanbul ignore next */ -export const getConfig = () => { - const isRemote = Object.prototype.hasOwnProperty.call(process.env, 'AWS_LAMBDA_FUNCTION_NAME') +export const getConfig = (opts = {}) => { + const {buildDirectory} = opts + const configDirBase = IS_REMOTE ? 'build' : '' let targetName = process?.env?.DEPLOY_TARGET || '' const targetSearchPlaces = SUPPORTED_FILE_TYPES.map((ext) => `config/${targetName}.${ext}`) const localeSearchPlaces = SUPPORTED_FILE_TYPES.map((ext) => `config/local.${ext}`) const defaultSearchPlaces = SUPPORTED_FILE_TYPES.map((ext) => `config/default.${ext}`) + const searchFrom = buildDirectory || process.cwd() + '/' + configDirBase + // Combined search places. const searchPlaces = [ - ...targetSearchPlaces, - ...(!isRemote ? localeSearchPlaces : []), + ...(targetName ? targetSearchPlaces : []), + ...(!IS_REMOTE ? localeSearchPlaces : []), ...defaultSearchPlaces, 'package.json' ] @@ -52,7 +59,7 @@ export const getConfig = () => { // Match config files based on the specificity from most to most general. const explorerSync = cosmiconfigSync(targetName, { packageProp: 'mobify', - searchPlaces: searchPlaces.map((path) => (isRemote ? `build/${path}` : path)), + searchPlaces: searchPlaces, loaders: { '.js': (filepath) => { // Because `require` is bootstrapped by webpack, the builtin @@ -67,7 +74,7 @@ export const getConfig = () => { }) // Load the config synchronously using a custom "searchPlaces". - const {config} = explorerSync.search() || {} + const {config} = explorerSync.search(searchFrom) || {} if (!config) { throw new Error( diff --git a/packages/pwa-kit-runtime/src/utils/ssr-config.server.test.js b/packages/pwa-kit-runtime/src/utils/ssr-config.server.test.js new file mode 100644 index 0000000000..6db3011261 --- /dev/null +++ b/packages/pwa-kit-runtime/src/utils/ssr-config.server.test.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +/* eslint-env jest */ +/* eslint max-nested-callbacks:0 */ + +import {getConfig} from './ssr-config.server' + +describe('Server "getConfig"', () => { + const env = process.env + + beforeEach(() => { + jest.resetModules() + process.env = {...env} + }) + + afterEach(() => { + process.env = env + }) + + test('throws when no config files are found running remotely', () => { + expect(getConfig).toThrow() + }) + + test('throws when no config files are found running locally', () => { + process.env.AWS_LAMBDA_FUNCTION_NAME = '' + expect(getConfig).toThrow() + }) +})