@salesforce/pwa-kit-dev 3.9.0-nightly-20241206080208 → 4.0.0-extensibility-preview.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.
Files changed (27) hide show
  1. package/bin/pwa-kit-dev.js +50 -24
  2. package/configs/babel/babel-config.js +10 -5
  3. package/configs/jest/jest-babel-transform.js +1 -1
  4. package/configs/jest/jest.config.js +4 -2
  5. package/configs/webpack/config.js +78 -89
  6. package/configs/webpack/utils.js +38 -2
  7. package/configs/webpack/utils.test.js +62 -0
  8. package/package.json +12 -10
  9. package/ssr/server/build-dev-server.js +2 -1
  10. package/ssr/server/build-dev-server.test.js +106 -2
  11. package/ssr/server/test_fixtures/node_modules/another-extension/src/setup-server.js +21 -0
  12. package/ssr/server/test_fixtures/node_modules/extension-with-bad-setup-server/src/setup-server.js +17 -0
  13. package/ssr/server/test_fixtures/node_modules/extension-with-setup-server-no-default-export/src/setup-server.js +17 -0
  14. package/{configs/webpack/test/overrides/path/data.js → ssr/server/test_fixtures/node_modules/extension-without-setup-server/src/random-file.js} +2 -2
  15. package/ssr/server/test_fixtures/node_modules/test-extension/src/setup-server.js +23 -0
  16. package/ssr/server/test_fixtures/node_modules/ts-extension/src/setup-server.ts +23 -0
  17. package/utils/logger-instance.js +19 -0
  18. package/utils/script-utils.js +8 -8
  19. package/utils/script-utils.test.js +9 -9
  20. package/configs/webpack/overrides-plugin.js +0 -168
  21. package/configs/webpack/overrides-plugin.test.js +0 -388
  22. package/configs/webpack/test/overrides/exists.js +0 -7
  23. package/configs/webpack/test/overrides/newExtension.js +0 -7
  24. package/configs/webpack/test/overrides/path/index.js +0 -7
  25. package/configs/webpack/test/overrides/path/index.mock.js +0 -7
  26. package/configs/webpack/test/overrides/path/nested/icon.svg +0 -0
  27. package/configs/webpack/test/package.json +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/pwa-kit-dev",
3
- "version": "3.9.0-nightly-20241206080208",
3
+ "version": "4.0.0-extensibility-preview.0",
4
4
  "description": "Build tools for pwa-kit",
5
5
  "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-dev#readme",
6
6
  "bugs": {
@@ -26,7 +26,7 @@
26
26
  "scripts": {
27
27
  "build": "cross-env NODE_ENV=production internal-lib-build build",
28
28
  "build:watch": "nodemon --watch 'src/**' --watch 'bin/**' --exec 'npm run build'",
29
- "format": "internal-lib-build format \"**/*.{js,jsx}\"",
29
+ "format": "internal-lib-build format \"**/*.{js,jsx,ts,tsx}\"",
30
30
  "lint": "npm run lint:js && npm run typecheck",
31
31
  "lint:fix": "npm run lint:js -- --fix",
32
32
  "lint:js": "eslint .",
@@ -58,14 +58,16 @@
58
58
  "@loadable/server": "^5.15.3",
59
59
  "@loadable/webpack-plugin": "^5.15.2",
60
60
  "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
61
- "@salesforce/pwa-kit-runtime": "3.9.0-nightly-20241206080208",
61
+ "@salesforce/pwa-kit-extension-sdk": "4.0.0-extensibility-preview.0",
62
+ "@salesforce/pwa-kit-runtime": "4.0.0-extensibility-preview.0",
62
63
  "@typescript-eslint/eslint-plugin": "^5.57.0",
63
64
  "@typescript-eslint/parser": "^5.57.0",
64
65
  "archiver": "1.3.0",
65
- "babel-jest": "^26.6.3",
66
+ "babel-jest": "^27.1.0",
66
67
  "babel-loader": "^8.3.0",
67
68
  "babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
68
69
  "babel-plugin-formatjs": "10.4.0",
70
+ "babel-plugin-module-resolver": "^5.0.2",
69
71
  "chalk": "^4.1.2",
70
72
  "commander": "^9.5.0",
71
73
  "compression": "1.7.4",
@@ -84,10 +86,10 @@
84
86
  "git-rev-sync": "^3.0.2",
85
87
  "glob": "7.2.3",
86
88
  "ignore-loader": "^0.1.2",
87
- "jest": "^26.6.3",
88
- "jest-cli": "^26.6.3",
89
- "jest-environment-jsdom": "^26.6.2",
90
- "jest-environment-jsdom-global": "^2.0.4",
89
+ "jest": "^27.1.0",
90
+ "jest-cli": "^27.1.0",
91
+ "jest-environment-jsdom": "^27.1.0",
92
+ "jest-environment-jsdom-global": "^3.0.0",
91
93
  "jest-expect-message": "1.1.3",
92
94
  "jest-fetch-mock": "^2.1.2",
93
95
  "mime-types": "2.1.35",
@@ -121,7 +123,7 @@
121
123
  "@types/node": "~16.0.3",
122
124
  "@types/node-fetch": "~2.6.3",
123
125
  "@types/validator": "~13.7.14",
124
- "internal-lib-build": "3.9.0-nightly-20241206080208",
126
+ "internal-lib-build": "4.0.0-extensibility-preview.0",
125
127
  "nock": "^13.3.0",
126
128
  "nodemon": "^2.0.22",
127
129
  "superagent": "^6.1.0",
@@ -147,5 +149,5 @@
147
149
  "publishConfig": {
148
150
  "directory": "dist"
149
151
  },
150
- "gitHead": "eb411ded96be11c84688a4d325cd525b37c661cc"
152
+ "gitHead": "16a2673cbdb9b22e3071435e8afbc2e89b2e37da"
151
153
  }
@@ -16,6 +16,7 @@ var _webpackDevMiddleware = _interopRequireDefault(require("webpack-dev-middlewa
16
16
  var _webpackHotServerMiddleware = _interopRequireDefault(require("webpack-hot-server-middleware"));
17
17
  var _webpackHotMiddleware = _interopRequireDefault(require("webpack-hot-middleware"));
18
18
  var _open = _interopRequireDefault(require("open"));
19
+ var _loggerInstance = _interopRequireDefault(require("../../utils/logger-instance"));
19
20
  var _requireFromString = _interopRequireDefault(require("require-from-string"));
20
21
  var _buildRemoteServer = require("@salesforce/pwa-kit-runtime/ssr/server/build-remote-server");
21
22
  var _ssrShared = require("@salesforce/pwa-kit-runtime/utils/ssr-shared");
@@ -42,7 +43,7 @@ const DevServerMixin = exports.DevServerMixin = {
42
43
  * @private
43
44
  */
44
45
  _logStartupMessage(options) {
45
- console.log(`Starting the DevServer on ${_chalk.default.cyan(this._getDevServerURL(options))}`);
46
+ _loggerInstance.default.log(`Starting the DevServer on ${_chalk.default.cyan(this._getDevServerURL(options))}`);
46
47
  },
47
48
  /**
48
49
  * @private
@@ -62,8 +62,15 @@ const insecureFetch = (url, opts) => {
62
62
  };
63
63
  const opts = (overrides = {}) => {
64
64
  const defaults = {
65
+ projectDir: testFixtures,
65
66
  buildDir: _path.default.join(testFixtures, 'build'),
66
67
  mobify: {
68
+ app: {
69
+ extensions: [
70
+ // temporary test CI
71
+ // 'ts-extension',
72
+ 'test-extension', 'another-extension', 'extension-with-bad-setup-server', 'extension-with-setup-server-no-default-export', 'extension-without-setup-server']
73
+ },
67
74
  ssrEnabled: true,
68
75
  ssrOnly: ['main.js.map', 'ssr.js', 'ssr.js.map'],
69
76
  ssrShared: ['main.js', 'ssr-loader.js', 'worker.js'],
@@ -560,7 +567,7 @@ describe('DevServer rendering', () => {
560
567
  });
561
568
  describe('DevServer service worker', () => {
562
569
  let tmpDir;
563
- beforeEach( /*#__PURE__*/_asyncToGenerator(function* () {
570
+ beforeEach(/*#__PURE__*/_asyncToGenerator(function* () {
564
571
  tmpDir = yield _fsExtra.default.mkdtemp(_path.default.join(_os.default.tmpdir(), 'pwa-kit-test-'));
565
572
  }));
566
573
  afterEach(() => {
@@ -652,4 +659,101 @@ describe('SLAS private client proxy', () => {
652
659
  }));
653
660
  }).toThrow();
654
661
  });
655
- });
662
+ });
663
+
664
+ // describe('extensions', () => {
665
+ // beforeEach(() => {
666
+ // jest.clearAllMocks()
667
+ // })
668
+
669
+ // test('can register extensions properly via _setupExtensions', () => {
670
+ // const app = NoWebpackDevServerFactory._createApp(opts())
671
+ // expect(app.__extensions).toBeDefined()
672
+ // return request(app)
673
+ // .get('/test-extension')
674
+ // .expect(200)
675
+ // .then((res) => {
676
+ // expect(res.text).toBe('test')
677
+ // })
678
+ // })
679
+
680
+ // test('mixed types in extensions configuration', async () => {
681
+ // const options = opts({
682
+ // mobify: {app: {extensions: [['test-extension', {path: '/foo'}], 'another-extension']}}
683
+ // })
684
+ // const app = NoWebpackDevServerFactory._createApp(options)
685
+ // expect(app.__extensions).toBeDefined()
686
+
687
+ // await request(app)
688
+ // .get('/test-extension')
689
+ // .expect(200)
690
+ // .then((res) => {
691
+ // expect(res.text).toBe('test')
692
+ // })
693
+
694
+ // await request(app)
695
+ // .get('/another-extension')
696
+ // .expect(200)
697
+ // .then((res) => {
698
+ // expect(res.text).toBe('test')
699
+ // })
700
+
701
+ // await request(app)
702
+ // .get('/test-extension-config')
703
+ // .expect(200)
704
+ // .then((res) => {
705
+ // // The config should have {enabled: true} by default
706
+ // expect(res.text).toBe('{"enabled":true,"path":"/foo"}')
707
+ // })
708
+ // })
709
+
710
+ // test('disabled extension will not run', () => {
711
+ // const options = opts({mobify: {app: {extensions: [['test-extension', {enabled: false}]]}}})
712
+ // const app = NoWebpackDevServerFactory._createApp(options)
713
+ // expect(app.__extensions).toBeDefined()
714
+ // return request(app).get('/test-extension').expect(404)
715
+ // })
716
+
717
+ // test('logs warning when setup-server file is not found', () => {
718
+ // const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
719
+ // const app = NoWebpackDevServerFactory._createApp(
720
+ // opts({
721
+ // mobify: {app: {extensions: ['extension-without-setup-server']}}
722
+ // })
723
+ // )
724
+ // expect(warn.mock.calls).toEqual([
725
+ // [
726
+ // 'pwa-kit-dev WARN No setup-server file found for extension-without-setup-server. Skipping.'
727
+ // ]
728
+ // ])
729
+ // })
730
+
731
+ // test('logs error when there is an error loading extension', () => {
732
+ // const errorlog = jest.spyOn(console, 'error').mockImplementation(() => {})
733
+ // const app = NoWebpackDevServerFactory._createApp(
734
+ // opts({
735
+ // mobify: {app: {extensions: ['extension-with-bad-setup-server']}}
736
+ // })
737
+ // )
738
+ // expect(errorlog.mock.calls).toEqual([
739
+ // [
740
+ // 'pwa-kit-dev.DevServerMixin._setupExtensions ERROR Error setting extension extension-with-bad-setup-server: {"error":{}}'
741
+ // ]
742
+ // ])
743
+ // })
744
+
745
+ // test('logs error when instantiating extension throws an error', () => {
746
+ // const errorlog = jest.spyOn(console, 'error').mockImplementation(() => {})
747
+ // const app = NoWebpackDevServerFactory._createApp(
748
+ // opts({
749
+ // mobify: {app: {extensions: ['extension-with-setup-server-no-default-export']}}
750
+ // })
751
+ // )
752
+
753
+ // expect(errorlog.mock.calls).toEqual([
754
+ // [
755
+ // `pwa-kit-dev.DevServerMixin._setupExtensions ERROR 'extension-with-setup-server-no-default-export' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`
756
+ // ]
757
+ // ])
758
+ // })
759
+ // })
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2024, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import {ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility'
9
+
10
+ class AnotherExtension extends ApplicationExtension {
11
+
12
+ extendApp(app) {
13
+ app.get('/another-extension', (req, res) => {
14
+ res.send('test')
15
+ })
16
+
17
+ return app
18
+ }
19
+ }
20
+
21
+ export default AnotherExtension
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) 2024, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import {ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility'
9
+
10
+ class Extension extends ApplicationExtension {
11
+
12
+ extendApp(app) {
13
+ throw new Error('extension will fail to initialize because of me')
14
+ }
15
+ }
16
+
17
+ export default Extension
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) 2024, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import {ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility'
8
+
9
+ class AnotherExtension extends ApplicationExtension {
10
+ extendApp(app) {
11
+ app.get('/another-extension', (req, res) => {
12
+ res.send('test')
13
+ })
14
+
15
+ return app
16
+ }
17
+ }
@@ -1,7 +1,7 @@
1
1
  /*
2
- * Copyright (c) 2023, Salesforce, Inc.
2
+ * Copyright (c) 2024, salesforce.com, inc.
3
3
  * All rights reserved.
4
4
  * SPDX-License-Identifier: BSD-3-Clause
5
5
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
6
  */
7
- "use strict";
7
+ // intentionally empty
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) 2024, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import {ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility'
8
+
9
+ class TestExtension extends ApplicationExtension{
10
+ extendApp(app) {
11
+ app.get('/test-extension', (req, res) => {
12
+ res.send('test')
13
+ })
14
+ app.get('/test-extension-config', (req, res) => {
15
+ const config = JSON.stringify(this.getConfig())
16
+ res.send(config)
17
+ })
18
+
19
+ return app
20
+ }
21
+ }
22
+
23
+ export default TestExtension
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) 2024, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import {Application, ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility'
9
+ // import {Application} from 'express'
10
+
11
+ class TypeScriptExtension extends ApplicationExtension {
12
+
13
+ extendApp(app: Application): Application {
14
+
15
+ app.get('/test-extension', (req, res) => {
16
+ res.send('test')
17
+ })
18
+
19
+ return app
20
+ }
21
+ }
22
+
23
+ export default TypeScriptExtension
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _loggerFactory = _interopRequireDefault(require("@salesforce/pwa-kit-runtime/utils/logger-factory"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /*
10
+ * Copyright (c) 2024, Salesforce, Inc.
11
+ * All rights reserved.
12
+ * SPDX-License-Identifier: BSD-3-Clause
13
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
14
+ */
15
+
16
+ const logger = Object.freeze((0, _loggerFactory.default)({
17
+ packageName: 'pwa-kit-dev'
18
+ }));
19
+ var _default = exports.default = logger;
@@ -77,17 +77,17 @@ const getProjectPkg = exports.getProjectPkg = /*#__PURE__*/function () {
77
77
  * @param dir Directory to walk
78
78
  * @returns Set of file paths within the directory
79
79
  */
80
- const walkDir = exports.walkDir = /*#__PURE__*/function () {
80
+ const _walkDir = exports.walkDir = /*#__PURE__*/function () {
81
81
  var _ref3 = _asyncToGenerator(function* (dir, baseDir, fileSet) {
82
82
  fileSet = fileSet || new Set();
83
83
  const entries = yield (0, _fsExtra.readdir)(dir, {
84
84
  withFileTypes: true
85
85
  });
86
- yield Promise.all(entries.map( /*#__PURE__*/function () {
86
+ yield Promise.all(entries.map(/*#__PURE__*/function () {
87
87
  var _ref4 = _asyncToGenerator(function* (entry) {
88
88
  const entryPath = _path.default.join(dir, entry.name);
89
89
  if (entry.isDirectory()) {
90
- yield walkDir(entryPath, baseDir, fileSet);
90
+ yield _walkDir(entryPath, baseDir, fileSet);
91
91
  } else {
92
92
  var _fileSet;
93
93
  (_fileSet = fileSet) === null || _fileSet === void 0 ? void 0 : _fileSet.add(entryPath.replace(baseDir + _path.default.sep, ''));
@@ -272,7 +272,7 @@ class CloudAPIClient {
272
272
  /** Milliseconds to wait between checks. */
273
273
  const delay = 30_000;
274
274
  /** Check the deployment status to see whether it has finished. */
275
- const check = /*#__PURE__*/function () {
275
+ const _check = /*#__PURE__*/function () {
276
276
  var _ref6 = _asyncToGenerator(function* () {
277
277
  const url = new _url.URL(`/api/projects/${project}/target/${environment}`, _this4.opts.origin);
278
278
  const res = yield _this4.opts.fetch(url, {
@@ -299,7 +299,7 @@ class CloudAPIClient {
299
299
  case 'PUBLISH_IN_PROGRESS':
300
300
  // In progress - check again after the next delay
301
301
  // `check` is async, so we need to use .catch to properly handle errors
302
- setTimeout(() => void check().catch(reject), delay);
302
+ setTimeout(() => void _check().catch(reject), delay);
303
303
  return;
304
304
  case 'CREATE_FAILED':
305
305
  case 'PUBLISH_FAILED':
@@ -318,7 +318,7 @@ class CloudAPIClient {
318
318
  };
319
319
  }();
320
320
  // Start checking after the first delay!
321
- setTimeout(() => void check().catch(reject), delay);
321
+ setTimeout(() => void _check().catch(reject), delay);
322
322
  });
323
323
  })();
324
324
  }
@@ -375,7 +375,7 @@ const createBundle = exports.createBundle = /*#__PURE__*/function () {
375
375
  archive.on('error', reject);
376
376
  output.on('finish', resolve);
377
377
  archive.finalize();
378
- })).then( /*#__PURE__*/_asyncToGenerator(function* () {
378
+ })).then(/*#__PURE__*/_asyncToGenerator(function* () {
379
379
  const {
380
380
  dependencies = {},
381
381
  devDependencies = {},
@@ -387,7 +387,7 @@ const createBundle = exports.createBundle = /*#__PURE__*/function () {
387
387
  const extendsTemplate = 'node_modules/' + ccExtensibility.extends;
388
388
  let cc_overrides = [];
389
389
  if (ccExtensibility.overridesDir) {
390
- const overrides_files = yield walkDir(ccExtensibility.overridesDir, ccExtensibility.overridesDir);
390
+ const overrides_files = yield _walkDir(ccExtensibility.overridesDir, ccExtensibility.overridesDir);
391
391
  cc_overrides = Array.from(overrides_files).filter(item => (0, _fsExtra.existsSync)(_path.default.join(extendsTemplate, item)));
392
392
  }
393
393
  const dependencyTree = yield getProjectDependencyTree();
@@ -41,7 +41,7 @@ jest.mock('child_process', () => {
41
41
  describe('scriptUtils', () => {
42
42
  const originalEnv = process.env;
43
43
  let tmpDir;
44
- beforeEach( /*#__PURE__*/_asyncToGenerator(function* () {
44
+ beforeEach(/*#__PURE__*/_asyncToGenerator(function* () {
45
45
  process.env = _objectSpread({}, originalEnv);
46
46
  tmpDir = yield (0, _fsExtra.mkdtemp)(_path.default.join(_os.default.tmpdir(), 'scriptUtils-tests'));
47
47
  // This is a workaround for jest.spyOn(), since I guess it doesn't work with our imports?
@@ -49,7 +49,7 @@ describe('scriptUtils', () => {
49
49
  _fsExtra.readJson.mockReset().mockImplementation(actualReadJson);
50
50
  _child_process.execSync.mockReset().mockImplementation(actualExecSync);
51
51
  }));
52
- afterEach( /*#__PURE__*/_asyncToGenerator(function* () {
52
+ afterEach(/*#__PURE__*/_asyncToGenerator(function* () {
53
53
  process.env = originalEnv;
54
54
  tmpDir && (yield (0, _fsExtra.rm)(tmpDir, {
55
55
  recursive: true
@@ -250,14 +250,14 @@ describe('scriptUtils', () => {
250
250
  }));
251
251
  test('should throw', /*#__PURE__*/_asyncToGenerator(function* () {
252
252
  const thePath = _path.default.join(tmpDir, '.mobify.test');
253
- yield expect( /*#__PURE__*/_asyncToGenerator(function* () {
253
+ yield expect(/*#__PURE__*/_asyncToGenerator(function* () {
254
254
  return yield scriptUtils.readCredentials(thePath);
255
255
  })).rejects.toThrow(Error);
256
256
  }));
257
257
  });
258
258
  describe('createBundle', () => {
259
259
  test('should throw if ssr_only and ssr_shared is empty', /*#__PURE__*/_asyncToGenerator(function* () {
260
- yield expect( /*#__PURE__*/_asyncToGenerator(function* () {
260
+ yield expect(/*#__PURE__*/_asyncToGenerator(function* () {
261
261
  return yield scriptUtils.createBundle({
262
262
  message: null,
263
263
  ssr_parameters: {},
@@ -269,7 +269,7 @@ describe('scriptUtils', () => {
269
269
  })).rejects.toThrow('no ssrOnly or ssrShared files are defined');
270
270
  }));
271
271
  test('should throw buildDir does not exist', /*#__PURE__*/_asyncToGenerator(function* () {
272
- yield expect( /*#__PURE__*/_asyncToGenerator(function* () {
272
+ yield expect(/*#__PURE__*/_asyncToGenerator(function* () {
273
273
  return yield scriptUtils.createBundle({
274
274
  message: null,
275
275
  ssr_parameters: {},
@@ -357,7 +357,7 @@ describe('scriptUtils', () => {
357
357
  text,
358
358
  json
359
359
  };
360
- const fetchMock = jest.fn( /*#__PURE__*/_asyncToGenerator(function* () {
360
+ const fetchMock = jest.fn(/*#__PURE__*/_asyncToGenerator(function* () {
361
361
  return responseMock;
362
362
  }));
363
363
  const client = new scriptUtils.CloudAPIClient({
@@ -410,7 +410,7 @@ describe('scriptUtils', () => {
410
410
  const json = () => Promise.resolve({
411
411
  token: 'token-value'
412
412
  });
413
- const fetchMock = jest.fn( /*#__PURE__*/_asyncToGenerator(function* () {
413
+ const fetchMock = jest.fn(/*#__PURE__*/_asyncToGenerator(function* () {
414
414
  return {
415
415
  status: 200,
416
416
  text,
@@ -474,8 +474,8 @@ describe('scriptUtils', () => {
474
474
  });
475
475
  describe('walkDir', () => {
476
476
  const files = ['a', 'b/1', 'b/2', 'c/d/e'].map(_path.default.normalize);
477
- beforeEach( /*#__PURE__*/_asyncToGenerator(function* () {
478
- yield Promise.all(files.map( /*#__PURE__*/function () {
477
+ beforeEach(/*#__PURE__*/_asyncToGenerator(function* () {
478
+ yield Promise.all(files.map(/*#__PURE__*/function () {
479
479
  var _ref38 = _asyncToGenerator(function* (file) {
480
480
  return yield (0, _fsExtra.createFile)(_path.default.join(tmpDir, file));
481
481
  });
@@ -1,168 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _path = _interopRequireDefault(require("path"));
8
- var _glob = _interopRequireDefault(require("glob"));
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- /*
11
- * Copyright (c) 2023, Salesforce, Inc.
12
- * All rights reserved.
13
- * SPDX-License-Identifier: BSD-3-Clause
14
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
15
- */
16
-
17
- /**
18
- * @class OverridesResolverPlugin
19
- *
20
- * This plugin provides the "Overrides" behavior of the Template Extensibility feature,
21
- * allowing third party implementations that depend on an npm module for the base implementation
22
- * and then overriding only specific files
23
- */
24
- class OverridesResolverPlugin {
25
- /**
26
- *
27
- * @param options
28
- * @param {string} options.overridesDir path to application base
29
- * @param {string[]} options.overrides paths to overrides
30
- * @param {string} options.projectDir path to project directory
31
- */
32
- constructor(options) {
33
- var _options$overridesDir, _options$projectDir, _this$pkg, _this$pkg$ccExtensibi, _this$pkg$ccExtensibi2, _this$pkg$ccExtensibi3, _this$pkg2, _this$pkg2$ccExtensib;
34
- // always coerce to posix fs paths, as glob sync and es6 imports don't use windows paths
35
- this.overridesDir = ((_options$overridesDir = options.overridesDir) === null || _options$overridesDir === void 0 ? void 0 : _options$overridesDir.replace(/\\/g, '/')) || '';
36
- this.extends = options.extends || [];
37
- // always coerce to posix fs paths, as glob sync and es6 imports don't use windows paths
38
- this.projectDir = (_options$projectDir = options.projectDir) === null || _options$projectDir === void 0 ? void 0 : _options$projectDir.replace(/\\/g, '/');
39
- this._allSearchDirs = [this.projectDir + this.overridesDir, ...this.extends];
40
- this.pkg = require(_path.default.resolve(this.projectDir, 'package.json'));
41
- this.extendsHashMap = new Map();
42
-
43
- // everything except directories
44
- // NOTE that the glob library expects posix so we replace windows file paths here
45
- const globPattern = `${(_this$pkg = this.pkg) === null || _this$pkg === void 0 ? void 0 : (_this$pkg$ccExtensibi = _this$pkg.ccExtensibility) === null || _this$pkg$ccExtensibi === void 0 ? void 0 : (_this$pkg$ccExtensibi2 = _this$pkg$ccExtensibi.overridesDir) === null || _this$pkg$ccExtensibi2 === void 0 ? void 0 : (_this$pkg$ccExtensibi3 = _this$pkg$ccExtensibi2.replace(/\\/g, '/')) === null || _this$pkg$ccExtensibi3 === void 0 ? void 0 : _this$pkg$ccExtensibi3.replace(/^\//, '')}/**/*.*`;
46
- const overridesFsRead = _glob.default.sync(globPattern);
47
- const overrideReplace = ((_this$pkg2 = this.pkg) === null || _this$pkg2 === void 0 ? void 0 : (_this$pkg2$ccExtensib = _this$pkg2.ccExtensibility) === null || _this$pkg2$ccExtensib === void 0 ? void 0 : _this$pkg2$ccExtensib.overridesDir) + '/';
48
-
49
- // For each filepath in the overrides directory:
50
- // Split it in one of two ways:
51
- // If the filepath is like /pages/home/index.js,
52
- // split on index and 'key' is /pages/home/
53
- // If the filepath is like /pages/home/data.js,
54
- // split on the . and 'key' is /pages/home/data
55
- // The negative lookaheads ensure the split occurs on the last occurence of .
56
- // This avoids collisions when both index.js and index.test.js are
57
- // present in the same directory
58
- overridesFsRead.forEach(item => {
59
- const end = item.substring(item.lastIndexOf('/index'));
60
- const [key, ...rest] = item.split(/(index(?!(\.[^.]*\.))|\.(?!([^.]*\.)))/);
61
- this.extendsHashMap.set(key.replace(overrideReplace, '').replace(/\/$/, ''), [end, rest.filter(Boolean)]);
62
- });
63
- }
64
- /**
65
- * This takes an import with the overrides dir / extends package removed and finds
66
- * the corresponding path from overridesFsRead
67
- *
68
- * Ie. Given an import @salesforce/retail-react-app/app/components/header,
69
- * requestPath is app/components/header
70
- *
71
- * @param requestPath - relative import path
72
- * @param dirs - this._allSearchDirs
73
- */
74
- findFileFromMap(requestPath, dirs) {
75
- const fileExt = _path.default.extname(requestPath);
76
- for (const dir of dirs) {
77
- let base = _path.default.join(dir, requestPath);
78
- if (fileExt) {
79
- const noExtPath = requestPath.replace(fileExt, '');
80
- if (this.extendsHashMap.has(noExtPath)) {
81
- return base;
82
- }
83
- } else {
84
- if (this.extendsHashMap.has(requestPath)) {
85
- const end = this.extendsHashMap.get(requestPath)[1];
86
- const isRequestingIndex = end[0] === 'index';
87
- let result = (base === null || base === void 0 ? void 0 : base.replace(/$\//, '')) + end.join('');
88
- if (isRequestingIndex) {
89
- result = _path.default.join(base, this.extendsHashMap.get(requestPath)[1].join(''));
90
- }
91
- return result;
92
- }
93
- }
94
- }
95
- }
96
-
97
- /*
98
- Given an import request, this function removes the override dir
99
- or the package name defined in extends.
100
- For example:
101
- import * from 'src/configs/webpack/test/overrides/path/data.js resolves to
102
- path/data.js
103
- import * from '@salesforce/retail-react-app/app/component/header resolves to
104
- app/component/header
105
- TODO: This function is only called if isFromExtends is true. In other words,
106
- this function is only called if the import request contains a package in extends
107
- We can probably simplify this function or rename it
108
- */
109
- toOverrideRelative(filepath) {
110
- const override = this._allSearchDirs.find(dir => {
111
- return filepath.indexOf(dir) === 0;
112
- });
113
- return filepath.substring((override === null || override === void 0 ? void 0 : override.length) + 1);
114
- }
115
-
116
- /*
117
- Helper function that returns true only if the import request points to a package in 'extends'
118
- and the issuer path (the file making the import request) is not located in the overrides dir.
119
- If true, we re-route the import request to the overrides dir.
120
- If false, the import request proceeds to the base package in node_modules
121
- For example, given an import request to a package defined in 'extends'
122
- (ie. @salesforce/retail-react-app):
123
- This will return true if the issuer is a file in a base template
124
- This will return false if the issuer is a file in the overrides dir
125
- This allow the base template to import from overrides and allows the overrides to import from
126
- the base template using the same syntax (ie. import from @salesforce/retail-react-app/...)
127
- */
128
- isFromExtends(request, filepath) {
129
- var _this$extends, _this$extends$, _this$extends$$starts;
130
- const pkgName = request.split(/(\/|\\)/).filter(item => !item.match(/(\/|\\)/)).slice(0, (_this$extends = this.extends) !== null && _this$extends !== void 0 && (_this$extends$ = _this$extends[0]) !== null && _this$extends$ !== void 0 && (_this$extends$$starts = _this$extends$.startsWith) !== null && _this$extends$$starts !== void 0 && _this$extends$$starts.call(_this$extends$, '@') ? 2 : 1).join('/');
131
-
132
- // we split by path delimeters (OS agnostic), filter out
133
- // separators, then spread both to form a normalized
134
- // '/base', 'path', 'to', 'dir' when both halves are joined
135
- const issuerPath = _path.default.join(...this.projectDir.split(_path.default.sep).filter(item => !item.match(/(\/|\\)/)), ...this.overridesDir.replace(/^(\/|\\)/, '').split('/').filter(item => !item.match(/(\/|\\)/)));
136
- return (
137
- // request includes extends
138
- this.extends.includes(pkgName) &&
139
- //
140
- // this is very important, to avoid circular imports, check that the
141
- // `issuer` (requesting context) isn't the overrides directory
142
-
143
- // request is not issued from overrides
144
- !filepath.includes(issuerPath)
145
- );
146
- }
147
- handleHook(requestContext, resolveContext, callback, resolver) {
148
- let targetFile;
149
- let overrideRelative;
150
- if (this.isFromExtends(requestContext.request, requestContext.path)) {
151
- overrideRelative = this.toOverrideRelative(requestContext.request).replace(/$\//, '');
152
- targetFile = this.findFileFromMap(overrideRelative, this._allSearchDirs);
153
- }
154
- if (targetFile) {
155
- const target = resolver.ensureHook('resolved');
156
- requestContext.path = _path.default.sep === '/' ? targetFile : targetFile.replace('/', _path.default.sep);
157
- resolver.doResolve(target, requestContext, `${this.constructor.name} found base override file`, resolveContext, callback);
158
- } else {
159
- return callback();
160
- }
161
- }
162
- apply(resolver) {
163
- resolver.getHook('resolve').tapAsync('FeatureResolverPlugin', (requestContext, resolveContext, callback) => {
164
- this.handleHook(requestContext, resolveContext, callback, resolver);
165
- });
166
- }
167
- }
168
- var _default = exports.default = OverridesResolverPlugin;