From c1ab02f617b05fed71466c4e61cc19c58ac1d592 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 11 Jun 2024 14:16:01 -0700 Subject: [PATCH 001/929] Initial Commit --- packages/extension-test-a/app/pages/test.jsx | 13 +++ packages/extension-test-a/app/routes.jsx | 19 ++++ packages/extension-test-a/package.json | 12 +++ packages/extension-test-b/app/pages/test.jsx | 13 +++ packages/extension-test-b/app/routes.jsx | 19 ++++ packages/extension-test-b/package.json | 12 +++ .../src/configs/babel/extensibility-plugin.js | 89 ++++++++++++++++++ .../pwa-kit-dev/src/configs/webpack/config.js | 18 ++-- .../configs/webpack/extensibility-plugin.js | 66 +++++++++++++ .../pwa-kit-dev/src/utils/resolver-utils.js | 93 +++++++++++++++++++ .../src/utils/resolver-utils.test.js | 44 +++++++++ .../components/route-component/index.js | 3 +- .../ssr/universal/components/routes/index.jsx | 10 ++ .../app/pages/home.tsx | 2 +- .../app/routes.tsx | 4 + .../template-typescript-minimal/package.json | 10 ++ 16 files changed, 413 insertions(+), 14 deletions(-) create mode 100644 packages/extension-test-a/app/pages/test.jsx create mode 100644 packages/extension-test-a/app/routes.jsx create mode 100644 packages/extension-test-a/package.json create mode 100644 packages/extension-test-b/app/pages/test.jsx create mode 100644 packages/extension-test-b/app/routes.jsx create mode 100644 packages/extension-test-b/package.json create mode 100644 packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js create mode 100644 packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js create mode 100644 packages/pwa-kit-dev/src/utils/resolver-utils.js create mode 100644 packages/pwa-kit-dev/src/utils/resolver-utils.test.js create mode 100644 packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx diff --git a/packages/extension-test-a/app/pages/test.jsx b/packages/extension-test-a/app/pages/test.jsx new file mode 100644 index 0000000000..5bdec4022b --- /dev/null +++ b/packages/extension-test-a/app/pages/test.jsx @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import React from 'react' + +const Test = () => { + return
Test Page A
+} + +export default Test \ No newline at end of file diff --git a/packages/extension-test-a/app/routes.jsx b/packages/extension-test-a/app/routes.jsx new file mode 100644 index 0000000000..235e7d0f73 --- /dev/null +++ b/packages/extension-test-a/app/routes.jsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import _routes from '*/app/routes' +import Test from './pages/test' + +export const routes = [ + ..._routes, + { + path: '/test-a', + component: Test, + exact: true + } +] + +export default routes \ No newline at end of file diff --git a/packages/extension-test-a/package.json b/packages/extension-test-a/package.json new file mode 100644 index 0000000000..7f0f89a3a1 --- /dev/null +++ b/packages/extension-test-a/package.json @@ -0,0 +1,12 @@ +{ + "name": "@salesforce/extension-test-a", + "version": "1.0.0-dev", + "private": true, + "devDependencies": { + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + } +} + \ No newline at end of file diff --git a/packages/extension-test-b/app/pages/test.jsx b/packages/extension-test-b/app/pages/test.jsx new file mode 100644 index 0000000000..8e3af02234 --- /dev/null +++ b/packages/extension-test-b/app/pages/test.jsx @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import React from 'react' + +const Test = () => { + return
Test Page B
+} + +export default Test \ No newline at end of file diff --git a/packages/extension-test-b/app/routes.jsx b/packages/extension-test-b/app/routes.jsx new file mode 100644 index 0000000000..214b1450d4 --- /dev/null +++ b/packages/extension-test-b/app/routes.jsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import _routes from '*/app/routes' +import Test from './pages/test' + +export const routes = [ + ..._routes, + { + path: '/test-b', + component: Test, + exact: true + } +] + +export default routes \ No newline at end of file diff --git a/packages/extension-test-b/package.json b/packages/extension-test-b/package.json new file mode 100644 index 0000000000..fe2727358e --- /dev/null +++ b/packages/extension-test-b/package.json @@ -0,0 +1,12 @@ +{ + "name": "@salesforce/extension-test-b", + "version": "1.0.0-dev", + "private": true, + "devDependencies": { + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + } +} + \ No newline at end of file diff --git a/packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js b/packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js new file mode 100644 index 0000000000..84446173b5 --- /dev/null +++ b/packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +// const resolve = require('resolve/sync') +// const ResolverUtils = require('../../utils/resolver-utils') +import resolve from 'resolve/sync' +import * as ResolverUtils from '../../utils/resolver-utils' + +function transformImport(nodePath, state) { + // DEV NOTE: The following line might be required in this condition to be conpatible when this plugin is + // used in conjunction with the webpack plugin. + // || !nodePath?.node?.source?.value?.includes('customize-app') + + nodePath = nodePath.get('source') + + // Exit early if: + // + // 1. We already visited and resolved the node path. + // 2. We are not resolving a string literal type. + // 3. We are not resolving a "wildcard" import. + if ( + state.moduleResolverVisited.has(nodePath) || + !state.types.isStringLiteral(nodePath) || + !nodePath?.node?.source?.value?.startsWith('*') || + nodePath.node.pathResolved + ) { + return + } + + const sourcePath = nodePath.node.value + + // Lets attempt to resolve the wildcard import path. + const modulePath = resolve(sourcePath, { + basedir: '/Users/bchypak/Projects/pwa-kit/packages/example-project', + extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], + packageIterator: (request) => ResolverUtils.buildCandidatePathArray({sourcePath: request}) + }) + + if (modulePath) { + nodePath.replaceWith(state.types.stringLiteral(modulePath)) + nodePath.node.pathResolved = true + + // Update processing cache. + state.moduleResolverVisited.add(nodePath) + } +} + +const importVisitors = { + 'ImportDeclaration|ExportDeclaration': transformImport +} + +const visitor = { + Program: { + enter(programPath, state) { + programPath.traverse(importVisitors, state) + }, + exit(programPath, state) { + programPath.traverse(importVisitors, state) + } + } +} + +export default ({types}) => ({ + name: 'module-resolver', + + manipulateOptions(opts) { + if (opts.filename === undefined) { + opts.filename = 'unknown' + } + }, + + pre() { + this.types = types + + // We need to keep track of all handled nodes so we do not try to transform them twice, + // because we run before (enter) and after (exit) all nodes are handled + this.moduleResolverVisited = new Set() + }, + + visitor, + + post() { + this.moduleResolverVisited.clear() + } +}) diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 54634949cf..0459cf5301 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -18,8 +18,8 @@ import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer' import LoadablePlugin from '@loadable/webpack-plugin' import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin' import SpeedMeasurePlugin from 'speed-measure-webpack-plugin' +import ExtensibilityPlugin from './extensibility-plugin' -import OverridesResolverPlugin from './overrides-plugin' import {sdkReplacementPlugin} from './plugins' import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config-names' @@ -184,17 +184,11 @@ const baseConfig = (target) => { path: buildDir }, resolve: { - ...(EXT_EXTENDS && EXT_OVERRIDES_DIR - ? { - plugins: [ - new OverridesResolverPlugin({ - extends: [EXT_EXTENDS], - overridesDir: EXT_OVERRIDES_DIR, - projectDir: process.cwd() - }) - ] - } - : {}), + plugins: [ + new ExtensibilityPlugin({ + projectDir: process.cwd() + }) + ], extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], alias: { ...Object.assign( diff --git a/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js b/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js new file mode 100644 index 0000000000..aa3d586da0 --- /dev/null +++ b/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import resolve from 'resolve/sync' +import {buildCandidatePathArray} from '../../utils/resolver-utils' + +/** + * @class ExtensionsResolverPlugin + * + * This plugin provides the "Extensions" behavior of the Template Extensibility feature, + * allowing third party implementations that depend on an npm module for the base implementation + * and then overriding only specific files + */ +class ExtensionsResolverPlugin { + constructor(options) { + this.projectDir = options.projectDir?.replace(/\\/g, '/') + } + + handleHook(request, resolveContext, callback, resolver) { + // Early exit for none Feature Loader imports + if (!request.request.startsWith('*')) { + callback() + return + } + + const target = resolver.ensureHook('resolved') + const importPath = request.request + const sourcePath = request.context.issuer + + // NOTE: Should we pass in a bogus value as the first argument so we know we are + // soley replying on the packageIterator? + const modulePath = resolve(importPath, { + basedir: this.projectDir, + extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], + packageIterator: () => buildCandidatePathArray(importPath, {sourcePath}) // NOTE: Should I be used the passed in "request" object? + }) + + if (modulePath) { + // Update the requests path with the one resoved from above. + request.path = modulePath + + resolver.doResolve( + target, + request, + `${this.constructor.name} found base override file`, + resolveContext, + callback + ) + } + } + + apply(resolver) { + resolver + .getHook('resolve') + // TODO: Finalize the name of this plugin, and the file name too. + .tapAsync('FeatureResolverPlugin', (requestContext, resolveContext, callback) => { + this.handleHook(requestContext, resolveContext, callback, resolver) + }) + } +} + +export default ExtensionsResolverPlugin diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js new file mode 100644 index 0000000000..129945d09e --- /dev/null +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import path from 'path' +import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' + +const EXTENSION_NAMESPACE = '@salesforce' +const EXTENSION_PREFIX = 'extension' +const NODE_MODULES = 'node_modules' + +// Returns an extension tupal given a extension reference. +// @private +const parseExtensionRef = (ref) => (Array.isArray(ref) ? ref : [ref, {}]) + +/** + * Given an array of PWA-Kit Extension "short names", returns an array of extension module names. + * @param {} shortNames + */ +export const expand = (extensionRefs = []) => { + // NOTE: We are going to want to have special consideration for "local" referenced extensions. + return extensionRefs + .filter((extensionRef) => Boolean(extensionRef)) + .map((extensionRef) => { + const [shortName, config] = parseExtensionRef(extensionRef) + const isLocalExtension = shortName.startsWith('.') + + return [ + isLocalExtension + ? shortName + : `${EXTENSION_NAMESPACE}/${EXTENSION_PREFIX}-${shortName}`, + config + ] + }) +} + +/** + * Based on the current extensibility configuration, return an array of candiate file paths to be used + * in the wild-card import module resolution. + */ +export const buildCandidatePathArray = (importPath, opts = {}) => { + const {extensions = getConfig()?.app?.extensions, sourcePath} = opts + + // Replace wildcard character as it has done its job getting us to this point. + importPath = importPath.replace('*/', '') + + // const isExtension = sourcePath.includes(`${EXTENSION_PREFIX}-`) + const isSelfReference = sourcePath.includes(importPath) + const cwd = process.cwd() + let paths = [] + + // TODO: Finalize how this works. + const sdkComponentPaths = { + 'app/routes': '/src/ssr/universal/components/app/routes' + } + + // The inital candidate paths include the "base" project, all the extensions, and the PWA-Kit SDK. + paths = expand(extensions) + .reverse() + .map(([extension]) => path.join(cwd, NODE_MODULES, extension, importPath)) + + // Add non-extension serach locations locations. The base project and the sdk as the final callback. + paths = [ + // Base Project + path.join(cwd, importPath), + // Extensions + ...paths, + // SDK + path.join( + cwd, + NODE_MODULES, + '@salesforce', + 'pwa-kit-react-sdk', + sdkComponentPaths[importPath] + ) + ] + + // Under certain circumstances we want to truncate the cadidate path array to prevent circular dependancies. + // In particular, we only want to include extensions up to, but not including, the importing extension source if it is + // a self-named import (e.g. importing routes from an overridden file names routes) + if (isSelfReference) { + // Find the index of the extension and chop the list. + // const currentExtension = sourcePath.match(new RegExp(`${EXTENSION_PREFIX}-([^/]+)`))[1] + const index = paths.indexOf(sourcePath.split('.')[0]) + // TODO: This logic needs to be hardends up a little. + paths = paths.slice(index + 1) + } + + return paths +} diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js new file mode 100644 index 0000000000..ac9f603625 --- /dev/null +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import * as resolverUtils from './resolver-utils' + +describe('resolverUtils', () => { + describe('"expand" util returns correct return value when', () => { + ;[ + { + name: 'extensions are all module extensions', + input: ['module-extension-a', 'module-extension-b', 'module-extension-c'], + expected: [ + '@salesforce/extension-module-extension-a', + '@salesforce/extension-module-extension-b', + '@salesforce/extension-module-extension-c' + ] + }, + { + name: 'extensions are a mix of module extensions and local extension', + input: ['module-extension-a', 'module-extension-b', './local-extension-c'], + expected: [ + '@salesforce/extension-module-extension-a', + '@salesforce/extension-module-extension-b', + './local-extension-c' + ] + }, + { + name: 'extensions include falsey values', + input: ['module-extension-a', '', './local-extension-c', false], + expected: ['@salesforce/extension-module-extension-a', './local-extension-c'] + } + ].forEach((testCase) => { + test(`${testCase.name}`, () => { + const result = resolverUtils.expand(testCase.input) + + expect(result).toEqual(testCase.expected) + }) + }) + }) +}) diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js b/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js index 50a401cd0d..de911ddaeb 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js @@ -11,7 +11,8 @@ import hoistNonReactStatic from 'hoist-non-react-statics' import {AppErrorContext} from '../../components/app-error-boundary' import Throw404 from '../../components/throw-404' import {getAppConfig} from '../../compatibility' -import routes from '../../routes' +// import routes from '../../routes' +import routes from '*/app/routes' import {pages as pageEvents} from '../../events' import {withLegacyGetProps} from '../../components/with-legacy-get-props' import Refresh from '../refresh' diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx b/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx new file mode 100644 index 0000000000..e292c9669f --- /dev/null +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +const routes = [] + +export default routes \ No newline at end of file diff --git a/packages/template-typescript-minimal/app/pages/home.tsx b/packages/template-typescript-minimal/app/pages/home.tsx index 02d42102e8..fe6b76be9d 100644 --- a/packages/template-typescript-minimal/app/pages/home.tsx +++ b/packages/template-typescript-minimal/app/pages/home.tsx @@ -18,7 +18,7 @@ const style = ` body { background: linear-gradient(-45deg, #e73c7e, #23a6d5, #ee7752); background-size: 400% 400%; - animation: gradient 10s ease infinite; + animation: gradient 10s ease 5; height: 100vh; } @keyframes gradient { diff --git a/packages/template-typescript-minimal/app/routes.tsx b/packages/template-typescript-minimal/app/routes.tsx index b0e5aaf66a..74286e5fce 100644 --- a/packages/template-typescript-minimal/app/routes.tsx +++ b/packages/template-typescript-minimal/app/routes.tsx @@ -5,10 +5,12 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import loadable, {LoadableComponent} from '@loadable/component' +import _routes from '*/app/routes' const Home = loadable(() => import('./pages/home')) const routes = [ + ..._routes, { path: '/', exact: true, @@ -18,4 +20,6 @@ const routes = [ } ] +console.log('App Routes: ', routes.map(({path}) => path)) + export default routes diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 6df606f14a..bf74a9663d 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -18,6 +18,8 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", + "@salesforce/extension-test-a": "1.0.0-dev", + "@salesforce/extension-test-b": "1.0.0-dev", "@salesforce/pwa-kit-dev": "3.6.0-dev", "@salesforce/pwa-kit-react-sdk": "3.6.0-dev", "@salesforce/pwa-kit-runtime": "3.6.0-dev", @@ -36,6 +38,14 @@ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" }, "mobify": { + "app":{ + "extensions": [ + "test-a", + ["test-b", { + "greeting": "hello" + }] + ] + }, "ssrEnabled": true, "ssrOnly": [ "ssr.js", From 9bb082b68c828a97dd69c73c6bf00cb257bd39bd Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Wed, 12 Jun 2024 11:30:18 -0700 Subject: [PATCH 002/929] Clean up, add local extension --- .../configs/webpack/extensibility-plugin.js | 2 +- .../pwa-kit-dev/src/utils/resolver-utils.js | 66 +++++++++++-------- .../extension-test-c/app/pages/test.jsx | 13 ++++ .../extension-test-c/app/routes.jsx | 19 ++++++ .../template-typescript-minimal/package.json | 3 +- 5 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx create mode 100644 packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx diff --git a/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js b/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js index aa3d586da0..32e4842393 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js +++ b/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js @@ -36,7 +36,7 @@ class ExtensionsResolverPlugin { const modulePath = resolve(importPath, { basedir: this.projectDir, extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], - packageIterator: () => buildCandidatePathArray(importPath, {sourcePath}) // NOTE: Should I be used the passed in "request" object? + packageIterator: () => buildCandidatePathArray(importPath, sourcePath) // NOTE: Should I be used the passed in "request" object? }) if (modulePath) { diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 129945d09e..60b51f0088 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -11,38 +11,48 @@ import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' const EXTENSION_NAMESPACE = '@salesforce' const EXTENSION_PREFIX = 'extension' const NODE_MODULES = 'node_modules' +const SDK_COMPONENT_MAP = { + 'app/routes': '/ssr/universal/components/routes' +} // Returns an extension tupal given a extension reference. // @private const parseExtensionRef = (ref) => (Array.isArray(ref) ? ref : [ref, {}]) /** - * Given an array of PWA-Kit Extension "short names", returns an array of extension module names. - * @param {} shortNames + * Normalize and expand the extension configuration array so that it is easier to process. + * @param {{String, Object}[]} extensions - The extensions configuration value as defined in the PWA-Kit config. + * @returns {Object[]} extensions - The extensions array in object form. + * + * @example + * const result = expand(["store-finder", ["account-pages", {singlePage: true}], './extensions/local-extension']); + * console.log(result) + * // [["@salesforce/extension-store-finder", {}], ["@salesforce/extension-account-pages", {singlePage: true}], ["/home/project/extensions/local-extension", {}]] */ -export const expand = (extensionRefs = []) => { - // NOTE: We are going to want to have special consideration for "local" referenced extensions. - return extensionRefs - .filter((extensionRef) => Boolean(extensionRef)) - .map((extensionRef) => { - const [shortName, config] = parseExtensionRef(extensionRef) - const isLocalExtension = shortName.startsWith('.') +export const expand = (extensions = []) => + extensions + .filter((extension) => Boolean(extension)) + .map((extension) => { + const [shortName, config] = parseExtensionRef(extension) + const isRelativePath = shortName.startsWith('.') + const isAbsolutePath = shortName.startsWith(path.sep) return [ - isLocalExtension - ? shortName + isRelativePath || isAbsolutePath + ? isRelativePath + ? path.join(process.cwd(), shortName.replace('.', '')) + : shortName : `${EXTENSION_NAMESPACE}/${EXTENSION_PREFIX}-${shortName}`, config ] }) -} /** * Based on the current extensibility configuration, return an array of candiate file paths to be used * in the wild-card import module resolution. */ -export const buildCandidatePathArray = (importPath, opts = {}) => { - const {extensions = getConfig()?.app?.extensions, sourcePath} = opts +export const buildCandidatePathArray = (importPath, sourcePath, opts = {}) => { + const {extensions = getConfig()?.app?.extensions} = opts // Replace wildcard character as it has done its job getting us to this point. importPath = importPath.replace('*/', '') @@ -52,17 +62,22 @@ export const buildCandidatePathArray = (importPath, opts = {}) => { const cwd = process.cwd() let paths = [] - // TODO: Finalize how this works. - const sdkComponentPaths = { - 'app/routes': '/src/ssr/universal/components/app/routes' - } - // The inital candidate paths include the "base" project, all the extensions, and the PWA-Kit SDK. paths = expand(extensions) .reverse() - .map(([extension]) => path.join(cwd, NODE_MODULES, extension, importPath)) + .map((extension) => { + // The reference can be a module/package or an absolute path to a file. + const [extensionRef] = extension + const isLocalExtension = extensionRef.startsWith(path.sep) + + return path.join( + ...(isLocalExtension + ? [extensionRef, importPath] + : [cwd, NODE_MODULES, extensionRef, importPath]) + ) + }) - // Add non-extension serach locations locations. The base project and the sdk as the final callback. + // Add non-extension search locations locations. The base project and the sdk as the final callback. paths = [ // Base Project path.join(cwd, importPath), @@ -72,9 +87,9 @@ export const buildCandidatePathArray = (importPath, opts = {}) => { path.join( cwd, NODE_MODULES, - '@salesforce', + EXTENSION_NAMESPACE, 'pwa-kit-react-sdk', - sdkComponentPaths[importPath] + SDK_COMPONENT_MAP[importPath] ) ] @@ -82,10 +97,9 @@ export const buildCandidatePathArray = (importPath, opts = {}) => { // In particular, we only want to include extensions up to, but not including, the importing extension source if it is // a self-named import (e.g. importing routes from an overridden file names routes) if (isSelfReference) { - // Find the index of the extension and chop the list. - // const currentExtension = sourcePath.match(new RegExp(`${EXTENSION_PREFIX}-([^/]+)`))[1] + // NOTE: Overriding files requires that you use the exact file name, you cannot replace a non-index file with one that + // is an index file. const index = paths.indexOf(sourcePath.split('.')[0]) - // TODO: This logic needs to be hardends up a little. paths = paths.slice(index + 1) } diff --git a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx new file mode 100644 index 0000000000..4d72da035f --- /dev/null +++ b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import React from 'react' + +const Test = () => { + return
Test Page C
+} + +export default Test \ No newline at end of file diff --git a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx new file mode 100644 index 0000000000..073a66a284 --- /dev/null +++ b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import _routes from '*/app/routes' +import Test from './pages/test' + +export const routes = [ + ..._routes, + { + path: '/test-c', + component: Test, + exact: true + } +] + +export default routes \ No newline at end of file diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index bf74a9663d..498290a172 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -43,7 +43,8 @@ "test-a", ["test-b", { "greeting": "hello" - }] + }], + "./app/extensions/extension-test-c" ] }, "ssrEnabled": true, From 9f479a7fe2f3674889cdc024ba680f61676d6422 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Wed, 12 Jun 2024 15:30:26 -0700 Subject: [PATCH 003/929] Add tests for "buildCandidatePathArray" --- .../pwa-kit-dev/src/utils/resolver-utils.js | 36 +++++------ .../src/utils/resolver-utils.test.js | 60 ++++++++++++++++--- 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 60b51f0088..f65d2d2028 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -49,33 +49,33 @@ export const expand = (extensions = []) => /** * Based on the current extensibility configuration, return an array of candiate file paths to be used - * in the wild-card import module resolution. + * in the wild-card import module resolution for the given import path.. + * + * @param {String} importPath - The import module-name. + * @param {String} sourcePath - The path the the file of the source import. + * @returns {String[]} paths - The potential paths to find the module import. */ export const buildCandidatePathArray = (importPath, sourcePath, opts = {}) => { - const {extensions = getConfig()?.app?.extensions} = opts - // Replace wildcard character as it has done its job getting us to this point. importPath = importPath.replace('*/', '') - // const isExtension = sourcePath.includes(`${EXTENSION_PREFIX}-`) + const {extensions = getConfig()?.app?.extensions} = opts const isSelfReference = sourcePath.includes(importPath) const cwd = process.cwd() - let paths = [] + let paths = expand(extensions).reverse() - // The inital candidate paths include the "base" project, all the extensions, and the PWA-Kit SDK. - paths = expand(extensions) - .reverse() - .map((extension) => { - // The reference can be a module/package or an absolute path to a file. - const [extensionRef] = extension - const isLocalExtension = extensionRef.startsWith(path.sep) + // Map all the extensions and resolve the module names to absolute paths. + paths = paths.map((extension) => { + // The reference can be a module/package or an absolute path to a file. + const [extensionRef] = extension + const isLocalExtension = extensionRef.startsWith(path.sep) - return path.join( - ...(isLocalExtension - ? [extensionRef, importPath] - : [cwd, NODE_MODULES, extensionRef, importPath]) - ) - }) + return path.join( + ...(isLocalExtension + ? [extensionRef, importPath] + : [cwd, NODE_MODULES, extensionRef, importPath]) + ) + }) // Add non-extension search locations locations. The base project and the sdk as the final callback. paths = [ diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index ac9f603625..e75a95a918 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -14,24 +14,32 @@ describe('resolverUtils', () => { name: 'extensions are all module extensions', input: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ - '@salesforce/extension-module-extension-a', - '@salesforce/extension-module-extension-b', - '@salesforce/extension-module-extension-c' + ['@salesforce/extension-module-extension-a', {}], + ['@salesforce/extension-module-extension-b', {}], + ['@salesforce/extension-module-extension-c', {}] ] }, { name: 'extensions are a mix of module extensions and local extension', input: ['module-extension-a', 'module-extension-b', './local-extension-c'], expected: [ - '@salesforce/extension-module-extension-a', - '@salesforce/extension-module-extension-b', - './local-extension-c' + ['@salesforce/extension-module-extension-a', {}], + ['@salesforce/extension-module-extension-b', {}], + [`${process.cwd()}/local-extension-c`, {}] ] }, { name: 'extensions include falsey values', input: ['module-extension-a', '', './local-extension-c', false], - expected: ['@salesforce/extension-module-extension-a', './local-extension-c'] + expected: [ + ['@salesforce/extension-module-extension-a', {}], + [`${process.cwd()}/local-extension-c`, {}] + ] + }, + { + name: 'extensions includes absolute values', + input: [`${process.cwd()}/local-extension-a`], + expected: [[`${process.cwd()}/local-extension-a`, {}]] } ].forEach((testCase) => { test(`${testCase.name}`, () => { @@ -41,4 +49,42 @@ describe('resolverUtils', () => { }) }) }) + + describe('"buildCandidatePathArray" util returns array of paths used to module resolving', () => { + ;[ + { + name: 'Correct absolute paths are returned with valid input data', + importPath: '*/app/routes', + sourcePath: `${process.cwd()}/node_modules/@salesforce/pwa-kit-react-sdk/ssr/universal/components/routes/index.jsx`, + extensions: ['module-extension-a', 'module-extension-b', 'module-extension-c'], + expected: [ + `${process.cwd()}/app/routes`, + `${process.cwd()}/node_modules/@salesforce/extension-module-extension-c/app/routes`, + `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes`, + `${process.cwd()}/node_modules/@salesforce/extension-module-extension-a/app/routes`, + `${process.cwd()}/node_modules/@salesforce/pwa-kit-react-sdk/ssr/universal/components/routes` + ] + }, + { + name: 'If sourcePath implies a selfreference, only the paths before its first mention is included', + importPath: '*/app/routes', + sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + extensions: ['module-extension-a', 'module-extension-b'], + expected: [ + `${process.cwd()}/node_modules/@salesforce/extension-module-extension-a/app/routes`, + `${process.cwd()}/node_modules/@salesforce/pwa-kit-react-sdk/ssr/universal/components/routes` + ] + } + ].forEach((testCase) => { + test(`${testCase.name}`, () => { + const result = resolverUtils.buildCandidatePathArray( + testCase.importPath, + testCase.sourcePath, + {extensions: testCase.extensions} + ) + + expect(result).toEqual(testCase.expected) + }) + }) + }) }) From 438693844566331de91d7917dd71496057241682 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 13 Jun 2024 09:52:14 -0700 Subject: [PATCH 004/929] Small refactor of util --- .../pwa-kit-dev/src/utils/resolver-utils.js | 25 +++++++-- .../src/utils/resolver-utils.test.js | 53 +++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index f65d2d2028..400aad6874 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -14,10 +14,25 @@ const NODE_MODULES = 'node_modules' const SDK_COMPONENT_MAP = { 'app/routes': '/ssr/universal/components/routes' } +const INDEX_FILE = 'index' -// Returns an extension tupal given a extension reference. +// Returns true/false indicating if the importPath resolves to a same named file as the sourcePath. // @private -const parseExtensionRef = (ref) => (Array.isArray(ref) ? ref : [ref, {}]) +export const isSelfReference = (importPath, sourcePath) => { + const indexRegExp = new RegExp(`(\/${INDEX_FILE})$`) + + // Sanitize the input. Here we want to remove the file extension and index file if it exists. + sourcePath = sourcePath.split('.')[0] + sourcePath = sourcePath.split(path.sep).join('/') + sourcePath = sourcePath.replace(indexRegExp, '') + + // Do the same for the import path even thought it's not common to use /index and file extensions in your module + // imports. + importPath = importPath.split('.')[0] + importPath = importPath.replace(indexRegExp, '') + + return sourcePath.endsWith(importPath) +} /** * Normalize and expand the extension configuration array so that it is easier to process. @@ -33,7 +48,7 @@ export const expand = (extensions = []) => extensions .filter((extension) => Boolean(extension)) .map((extension) => { - const [shortName, config] = parseExtensionRef(extension) + const [shortName, config = {}] = Array.isArray(extension) ? extension : [extension, {}] const isRelativePath = shortName.startsWith('.') const isAbsolutePath = shortName.startsWith(path.sep) @@ -60,7 +75,7 @@ export const buildCandidatePathArray = (importPath, sourcePath, opts = {}) => { importPath = importPath.replace('*/', '') const {extensions = getConfig()?.app?.extensions} = opts - const isSelfReference = sourcePath.includes(importPath) + const isSelfReferenceImport = isSelfReference(importPath, sourcePath) const cwd = process.cwd() let paths = expand(extensions).reverse() @@ -96,7 +111,7 @@ export const buildCandidatePathArray = (importPath, sourcePath, opts = {}) => { // Under certain circumstances we want to truncate the cadidate path array to prevent circular dependancies. // In particular, we only want to include extensions up to, but not including, the importing extension source if it is // a self-named import (e.g. importing routes from an overridden file names routes) - if (isSelfReference) { + if (isSelfReferenceImport) { // NOTE: Overriding files requires that you use the exact file name, you cannot replace a non-index file with one that // is an index file. const index = paths.indexOf(sourcePath.split('.')[0]) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index e75a95a918..d46885759c 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -8,6 +8,59 @@ import * as resolverUtils from './resolver-utils' describe('resolverUtils', () => { + describe('"isSelfReference" util returns whether or not a wildcard import is for the same module it is coming from.', () => { + ;[ + { + name: 'Importing the wildcard routes from the routes file', + importPath: 'app/routes', + sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + expected: true + }, + , + { + name: 'Importing a page component from the routes file', + importPath: 'app/pages/new-home', + sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + expected: false + } + ].forEach((testCase) => { + test(`${testCase.name}`, () => { + const result = resolverUtils.isSelfReference( + testCase.importPath, + testCase.sourcePath + ) + + expect(result).toEqual(testCase.expected) + }) + }) + }) + describe('"isSelfReference" util returns whether or not a wildcard import is for the same module it is coming from.', () => { + ;[ + { + name: 'Importing the wildcard routes from the routes file', + importPath: 'app/routes', + sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + expected: true + }, + , + { + name: 'Importing a page component from the routes file', + importPath: 'app/pages/new-home', + sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + expected: false + } + ].forEach((testCase) => { + test(`${testCase.name}`, () => { + const result = resolverUtils.isSelfReference( + testCase.importPath, + testCase.sourcePath + ) + + expect(result).toEqual(testCase.expected) + }) + }) + }) + describe('"expand" util returns correct return value when', () => { ;[ { From 22a550bf0f5d6f75d337b6fadcf890817e4c857c Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 13 Jun 2024 10:16:15 -0700 Subject: [PATCH 005/929] Linting --- .../pwa-kit-dev/src/utils/resolver-utils.js | 2 +- .../src/utils/resolver-utils.test.js | 27 ------------------- .../ssr/universal/components/routes/index.jsx | 2 +- .../extension-test-c/app/pages/test.jsx | 2 +- .../extension-test-c/app/routes.jsx | 2 +- .../app/routes.tsx | 3 +-- 6 files changed, 5 insertions(+), 33 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 400aad6874..f8c6a54fe1 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -19,7 +19,7 @@ const INDEX_FILE = 'index' // Returns true/false indicating if the importPath resolves to a same named file as the sourcePath. // @private export const isSelfReference = (importPath, sourcePath) => { - const indexRegExp = new RegExp(`(\/${INDEX_FILE})$`) + const indexRegExp = new RegExp(`(/${INDEX_FILE})$`) // Sanitize the input. Here we want to remove the file extension and index file if it exists. sourcePath = sourcePath.split('.')[0] diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index d46885759c..dda619020d 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -16,33 +16,6 @@ describe('resolverUtils', () => { sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, expected: true }, - , - { - name: 'Importing a page component from the routes file', - importPath: 'app/pages/new-home', - sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, - expected: false - } - ].forEach((testCase) => { - test(`${testCase.name}`, () => { - const result = resolverUtils.isSelfReference( - testCase.importPath, - testCase.sourcePath - ) - - expect(result).toEqual(testCase.expected) - }) - }) - }) - describe('"isSelfReference" util returns whether or not a wildcard import is for the same module it is coming from.', () => { - ;[ - { - name: 'Importing the wildcard routes from the routes file', - importPath: 'app/routes', - sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, - expected: true - }, - , { name: 'Importing a page component from the routes file', importPath: 'app/pages/new-home', diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx b/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx index e292c9669f..43b32abffa 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/components/routes/index.jsx @@ -7,4 +7,4 @@ const routes = [] -export default routes \ No newline at end of file +export default routes diff --git a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx index 4d72da035f..f2d347d180 100644 --- a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx +++ b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx @@ -10,4 +10,4 @@ const Test = () => { return
Test Page C
} -export default Test \ No newline at end of file +export default Test diff --git a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx index 073a66a284..6a0912c716 100644 --- a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx +++ b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx @@ -16,4 +16,4 @@ export const routes = [ } ] -export default routes \ No newline at end of file +export default routes diff --git a/packages/template-typescript-minimal/app/routes.tsx b/packages/template-typescript-minimal/app/routes.tsx index 74286e5fce..938b015d2a 100644 --- a/packages/template-typescript-minimal/app/routes.tsx +++ b/packages/template-typescript-minimal/app/routes.tsx @@ -5,6 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import loadable, {LoadableComponent} from '@loadable/component' +// @ts-ignore import _routes from '*/app/routes' const Home = loadable(() => import('./pages/home')) @@ -20,6 +21,4 @@ const routes = [ } ] -console.log('App Routes: ', routes.map(({path}) => path)) - export default routes From 1f6ef6f683271b69b4c6f16a20b5b4500d5954e8 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 13 Jun 2024 10:19:50 -0700 Subject: [PATCH 006/929] Remove example code --- packages/extension-test-a/app/pages/test.jsx | 13 --- packages/extension-test-a/app/routes.jsx | 19 ---- packages/extension-test-a/package.json | 12 --- packages/extension-test-b/app/pages/test.jsx | 13 --- packages/extension-test-b/app/routes.jsx | 19 ---- packages/extension-test-b/package.json | 12 --- .../src/configs/babel/extensibility-plugin.js | 89 ------------------- .../pwa-kit-dev/src/configs/webpack/config.js | 18 ++-- .../configs/webpack/extensibility-plugin.js | 66 -------------- .../extension-test-c/app/pages/test.jsx | 13 --- .../extension-test-c/app/routes.jsx | 19 ---- .../app/routes.tsx | 3 - 12 files changed, 12 insertions(+), 284 deletions(-) delete mode 100644 packages/extension-test-a/app/pages/test.jsx delete mode 100644 packages/extension-test-a/app/routes.jsx delete mode 100644 packages/extension-test-a/package.json delete mode 100644 packages/extension-test-b/app/pages/test.jsx delete mode 100644 packages/extension-test-b/app/routes.jsx delete mode 100644 packages/extension-test-b/package.json delete mode 100644 packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js delete mode 100644 packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js delete mode 100644 packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx delete mode 100644 packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx diff --git a/packages/extension-test-a/app/pages/test.jsx b/packages/extension-test-a/app/pages/test.jsx deleted file mode 100644 index 5bdec4022b..0000000000 --- a/packages/extension-test-a/app/pages/test.jsx +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import React from 'react' - -const Test = () => { - return
Test Page A
-} - -export default Test \ No newline at end of file diff --git a/packages/extension-test-a/app/routes.jsx b/packages/extension-test-a/app/routes.jsx deleted file mode 100644 index 235e7d0f73..0000000000 --- a/packages/extension-test-a/app/routes.jsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import _routes from '*/app/routes' -import Test from './pages/test' - -export const routes = [ - ..._routes, - { - path: '/test-a', - component: Test, - exact: true - } -] - -export default routes \ No newline at end of file diff --git a/packages/extension-test-a/package.json b/packages/extension-test-a/package.json deleted file mode 100644 index 7f0f89a3a1..0000000000 --- a/packages/extension-test-a/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@salesforce/extension-test-a", - "version": "1.0.0-dev", - "private": true, - "devDependencies": { - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - } -} - \ No newline at end of file diff --git a/packages/extension-test-b/app/pages/test.jsx b/packages/extension-test-b/app/pages/test.jsx deleted file mode 100644 index 8e3af02234..0000000000 --- a/packages/extension-test-b/app/pages/test.jsx +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import React from 'react' - -const Test = () => { - return
Test Page B
-} - -export default Test \ No newline at end of file diff --git a/packages/extension-test-b/app/routes.jsx b/packages/extension-test-b/app/routes.jsx deleted file mode 100644 index 214b1450d4..0000000000 --- a/packages/extension-test-b/app/routes.jsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import _routes from '*/app/routes' -import Test from './pages/test' - -export const routes = [ - ..._routes, - { - path: '/test-b', - component: Test, - exact: true - } -] - -export default routes \ No newline at end of file diff --git a/packages/extension-test-b/package.json b/packages/extension-test-b/package.json deleted file mode 100644 index fe2727358e..0000000000 --- a/packages/extension-test-b/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@salesforce/extension-test-b", - "version": "1.0.0-dev", - "private": true, - "devDependencies": { - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - } -} - \ No newline at end of file diff --git a/packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js b/packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js deleted file mode 100644 index 84446173b5..0000000000 --- a/packages/pwa-kit-dev/src/configs/babel/extensibility-plugin.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// const resolve = require('resolve/sync') -// const ResolverUtils = require('../../utils/resolver-utils') -import resolve from 'resolve/sync' -import * as ResolverUtils from '../../utils/resolver-utils' - -function transformImport(nodePath, state) { - // DEV NOTE: The following line might be required in this condition to be conpatible when this plugin is - // used in conjunction with the webpack plugin. - // || !nodePath?.node?.source?.value?.includes('customize-app') - - nodePath = nodePath.get('source') - - // Exit early if: - // - // 1. We already visited and resolved the node path. - // 2. We are not resolving a string literal type. - // 3. We are not resolving a "wildcard" import. - if ( - state.moduleResolverVisited.has(nodePath) || - !state.types.isStringLiteral(nodePath) || - !nodePath?.node?.source?.value?.startsWith('*') || - nodePath.node.pathResolved - ) { - return - } - - const sourcePath = nodePath.node.value - - // Lets attempt to resolve the wildcard import path. - const modulePath = resolve(sourcePath, { - basedir: '/Users/bchypak/Projects/pwa-kit/packages/example-project', - extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], - packageIterator: (request) => ResolverUtils.buildCandidatePathArray({sourcePath: request}) - }) - - if (modulePath) { - nodePath.replaceWith(state.types.stringLiteral(modulePath)) - nodePath.node.pathResolved = true - - // Update processing cache. - state.moduleResolverVisited.add(nodePath) - } -} - -const importVisitors = { - 'ImportDeclaration|ExportDeclaration': transformImport -} - -const visitor = { - Program: { - enter(programPath, state) { - programPath.traverse(importVisitors, state) - }, - exit(programPath, state) { - programPath.traverse(importVisitors, state) - } - } -} - -export default ({types}) => ({ - name: 'module-resolver', - - manipulateOptions(opts) { - if (opts.filename === undefined) { - opts.filename = 'unknown' - } - }, - - pre() { - this.types = types - - // We need to keep track of all handled nodes so we do not try to transform them twice, - // because we run before (enter) and after (exit) all nodes are handled - this.moduleResolverVisited = new Set() - }, - - visitor, - - post() { - this.moduleResolverVisited.clear() - } -}) diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 0459cf5301..54634949cf 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -18,8 +18,8 @@ import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer' import LoadablePlugin from '@loadable/webpack-plugin' import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin' import SpeedMeasurePlugin from 'speed-measure-webpack-plugin' -import ExtensibilityPlugin from './extensibility-plugin' +import OverridesResolverPlugin from './overrides-plugin' import {sdkReplacementPlugin} from './plugins' import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config-names' @@ -184,11 +184,17 @@ const baseConfig = (target) => { path: buildDir }, resolve: { - plugins: [ - new ExtensibilityPlugin({ - projectDir: process.cwd() - }) - ], + ...(EXT_EXTENDS && EXT_OVERRIDES_DIR + ? { + plugins: [ + new OverridesResolverPlugin({ + extends: [EXT_EXTENDS], + overridesDir: EXT_OVERRIDES_DIR, + projectDir: process.cwd() + }) + ] + } + : {}), extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], alias: { ...Object.assign( diff --git a/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js b/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js deleted file mode 100644 index 32e4842393..0000000000 --- a/packages/pwa-kit-dev/src/configs/webpack/extensibility-plugin.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import resolve from 'resolve/sync' -import {buildCandidatePathArray} from '../../utils/resolver-utils' - -/** - * @class ExtensionsResolverPlugin - * - * This plugin provides the "Extensions" behavior of the Template Extensibility feature, - * allowing third party implementations that depend on an npm module for the base implementation - * and then overriding only specific files - */ -class ExtensionsResolverPlugin { - constructor(options) { - this.projectDir = options.projectDir?.replace(/\\/g, '/') - } - - handleHook(request, resolveContext, callback, resolver) { - // Early exit for none Feature Loader imports - if (!request.request.startsWith('*')) { - callback() - return - } - - const target = resolver.ensureHook('resolved') - const importPath = request.request - const sourcePath = request.context.issuer - - // NOTE: Should we pass in a bogus value as the first argument so we know we are - // soley replying on the packageIterator? - const modulePath = resolve(importPath, { - basedir: this.projectDir, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], - packageIterator: () => buildCandidatePathArray(importPath, sourcePath) // NOTE: Should I be used the passed in "request" object? - }) - - if (modulePath) { - // Update the requests path with the one resoved from above. - request.path = modulePath - - resolver.doResolve( - target, - request, - `${this.constructor.name} found base override file`, - resolveContext, - callback - ) - } - } - - apply(resolver) { - resolver - .getHook('resolve') - // TODO: Finalize the name of this plugin, and the file name too. - .tapAsync('FeatureResolverPlugin', (requestContext, resolveContext, callback) => { - this.handleHook(requestContext, resolveContext, callback, resolver) - }) - } -} - -export default ExtensionsResolverPlugin diff --git a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx deleted file mode 100644 index f2d347d180..0000000000 --- a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/pages/test.jsx +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import React from 'react' - -const Test = () => { - return
Test Page C
-} - -export default Test diff --git a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx b/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx deleted file mode 100644 index 6a0912c716..0000000000 --- a/packages/template-typescript-minimal/app/extensions/extension-test-c/app/routes.jsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import _routes from '*/app/routes' -import Test from './pages/test' - -export const routes = [ - ..._routes, - { - path: '/test-c', - component: Test, - exact: true - } -] - -export default routes diff --git a/packages/template-typescript-minimal/app/routes.tsx b/packages/template-typescript-minimal/app/routes.tsx index 938b015d2a..b0e5aaf66a 100644 --- a/packages/template-typescript-minimal/app/routes.tsx +++ b/packages/template-typescript-minimal/app/routes.tsx @@ -5,13 +5,10 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import loadable, {LoadableComponent} from '@loadable/component' -// @ts-ignore -import _routes from '*/app/routes' const Home = loadable(() => import('./pages/home')) const routes = [ - ..._routes, { path: '/', exact: true, From 3d9a7acc87af22109fc7096887e03bdb88ea4f77 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 13 Jun 2024 10:25:39 -0700 Subject: [PATCH 007/929] Remove old references --- packages/template-typescript-minimal/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 498290a172..a8144affe6 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -18,8 +18,6 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/extension-test-a": "1.0.0-dev", - "@salesforce/extension-test-b": "1.0.0-dev", "@salesforce/pwa-kit-dev": "3.6.0-dev", "@salesforce/pwa-kit-react-sdk": "3.6.0-dev", "@salesforce/pwa-kit-runtime": "3.6.0-dev", From 062228fbeded17c0f9958f99c45cbaedf1c7f88b Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 13 Jun 2024 11:20:43 -0700 Subject: [PATCH 008/929] Remove demo use of wildcard import in sdk --- .../src/ssr/universal/components/route-component/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js b/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js index de911ddaeb..50a401cd0d 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js @@ -11,8 +11,7 @@ import hoistNonReactStatic from 'hoist-non-react-statics' import {AppErrorContext} from '../../components/app-error-boundary' import Throw404 from '../../components/throw-404' import {getAppConfig} from '../../compatibility' -// import routes from '../../routes' -import routes from '*/app/routes' +import routes from '../../routes' import {pages as pageEvents} from '../../events' import {withLegacyGetProps} from '../../components/with-legacy-get-props' import Refresh from '../refresh' From 005186f4be31b5b056e7964f195e53c6a51dc9ad Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 13 Jun 2024 15:19:33 -0700 Subject: [PATCH 009/929] Update CHANGELOG.md --- packages/pwa-kit-dev/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pwa-kit-dev/CHANGELOG.md b/packages/pwa-kit-dev/CHANGELOG.md index ec1fa8f038..3e41e0d9cc 100644 --- a/packages/pwa-kit-dev/CHANGELOG.md +++ b/packages/pwa-kit-dev/CHANGELOG.md @@ -1,4 +1,6 @@ ## v3.6.0-dev (Apr 17, 2024) +- Implement core wildcard import logic to be used in upcoming webpack/babel plugins [#1826](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1826) + ## v3.5.1 (Apr 17, 2024) - Update SLAS private proxy path [#1752](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1752) From 1a307597a566da8226649266800e3467dbaa79a8 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 08:41:10 -0700 Subject: [PATCH 010/929] Fix tests for windows --- .../src/utils/resolver-utils.test.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index dda619020d..bbbb38a50f 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -5,6 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ +import path from 'path' import * as resolverUtils from './resolver-utils' describe('resolverUtils', () => { @@ -13,13 +14,14 @@ describe('resolverUtils', () => { { name: 'Importing the wildcard routes from the routes file', importPath: 'app/routes', - sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes.jsx'), + expected: true }, { name: 'Importing a page component from the routes file', importPath: 'app/pages/new-home', - sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes.jsx'), expected: false } ].forEach((testCase) => { @@ -81,24 +83,25 @@ describe('resolverUtils', () => { { name: 'Correct absolute paths are returned with valid input data', importPath: '*/app/routes', - sourcePath: `${process.cwd()}/node_modules/@salesforce/pwa-kit-react-sdk/ssr/universal/components/routes/index.jsx`, + sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'pwa-kit-react-sdk', 'ssr', 'universal', 'components', 'routes', 'index.jsx'), + extensions: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ - `${process.cwd()}/app/routes`, - `${process.cwd()}/node_modules/@salesforce/extension-module-extension-c/app/routes`, - `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes`, - `${process.cwd()}/node_modules/@salesforce/extension-module-extension-a/app/routes`, - `${process.cwd()}/node_modules/@salesforce/pwa-kit-react-sdk/ssr/universal/components/routes` + path.join(process.cwd(), 'app', 'routes'), + path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-c', 'app', 'routes'), + path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes'), + path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-a', 'app', 'routes'), + path.join(process.cwd(), 'node_modules', '@salesforce', 'pwa-kit-react-sdk', 'ssr', 'universal', 'components', 'routes'), ] }, { name: 'If sourcePath implies a selfreference, only the paths before its first mention is included', importPath: '*/app/routes', - sourcePath: `${process.cwd()}/node_modules/@salesforce/extension-module-extension-b/app/routes.jsx`, + sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes.jsx'), extensions: ['module-extension-a', 'module-extension-b'], expected: [ - `${process.cwd()}/node_modules/@salesforce/extension-module-extension-a/app/routes`, - `${process.cwd()}/node_modules/@salesforce/pwa-kit-react-sdk/ssr/universal/components/routes` + path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-a', 'app', 'routes'), + path.join(process.cwd(), 'node_modules', '@salesforce', 'pwa-kit-react-sdk', 'ssr', 'universal', 'components', 'routes'), ] } ].forEach((testCase) => { From 11b83a686b05fd5b5e6ef444abca755f0f42bde9 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 09:03:36 -0700 Subject: [PATCH 011/929] Lint! --- .../src/utils/resolver-utils.test.js | 97 +++++++++++++++++-- 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index bbbb38a50f..bd3c509bdb 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -14,14 +14,28 @@ describe('resolverUtils', () => { { name: 'Importing the wildcard routes from the routes file', importPath: 'app/routes', - sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes.jsx'), + sourcePath: path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-b', + 'app', + 'routes.jsx' + ), expected: true }, { name: 'Importing a page component from the routes file', importPath: 'app/pages/new-home', - sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes.jsx'), + sourcePath: path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-b', + 'app', + 'routes.jsx' + ), expected: false } ].forEach((testCase) => { @@ -83,25 +97,88 @@ describe('resolverUtils', () => { { name: 'Correct absolute paths are returned with valid input data', importPath: '*/app/routes', - sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'pwa-kit-react-sdk', 'ssr', 'universal', 'components', 'routes', 'index.jsx'), + sourcePath: path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'pwa-kit-react-sdk', + 'ssr', + 'universal', + 'components', + 'routes', + 'index.jsx' + ), extensions: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ path.join(process.cwd(), 'app', 'routes'), - path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-c', 'app', 'routes'), - path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes'), - path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-a', 'app', 'routes'), - path.join(process.cwd(), 'node_modules', '@salesforce', 'pwa-kit-react-sdk', 'ssr', 'universal', 'components', 'routes'), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-c', + 'app', + 'routes' + ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-b', + 'app', + 'routes' + ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-a', + 'app', + 'routes' + ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'pwa-kit-react-sdk', + 'ssr', + 'universal', + 'components', + 'routes' + ) ] }, { name: 'If sourcePath implies a selfreference, only the paths before its first mention is included', importPath: '*/app/routes', - sourcePath: path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-b', 'app', 'routes.jsx'), + sourcePath: path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-b', + 'app', + 'routes.jsx' + ), extensions: ['module-extension-a', 'module-extension-b'], expected: [ - path.join(process.cwd(), 'node_modules', '@salesforce', 'extension-module-extension-a', 'app', 'routes'), - path.join(process.cwd(), 'node_modules', '@salesforce', 'pwa-kit-react-sdk', 'ssr', 'universal', 'components', 'routes'), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-a', + 'app', + 'routes' + ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'pwa-kit-react-sdk', + 'ssr', + 'universal', + 'components', + 'routes' + ) ] } ].forEach((testCase) => { From 4194dc0be860f9f677f92ce942ba83cf5933caf5 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 10:53:48 -0700 Subject: [PATCH 012/929] Refactor expand util --- .../pwa-kit-dev/src/utils/resolver-utils.js | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index f8c6a54fe1..10f8060ad3 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -48,18 +48,33 @@ export const expand = (extensions = []) => extensions .filter((extension) => Boolean(extension)) .map((extension) => { - const [shortName, config = {}] = Array.isArray(extension) ? extension : [extension, {}] - const isRelativePath = shortName.startsWith('.') - const isAbsolutePath = shortName.startsWith(path.sep) + let [nameRef, config = {}] = Array.isArray(extension) ? extension : [extension, {}] + + // We determine the type of extention reference by it's first character. + switch (nameRef[0]) { + case ".": + // Relative Path + nameRef = nameRef.split(/\/|\\/).join(path.sep) + nameRef = path.join(process.cwd(), nameRef.replace('.', '')) + break + case "/": + // Absolute Path (UNIX) + nameRef = nameRef.split(/\/|\\/).join(path.sep) + break + case "\\": + // Absolute Path (Windows) + nameRef = nameRef.split(/\/|\\/).join(path.sep) + break + case "@": + // Module Path + // Do nothing... + break + default: + // Default is to treat the reference as a extension "short" name. + nameRef = `${EXTENSION_NAMESPACE}/${EXTENSION_PREFIX}-${nameRef}` + } - return [ - isRelativePath || isAbsolutePath - ? isRelativePath - ? path.join(process.cwd(), shortName.replace('.', '')) - : shortName - : `${EXTENSION_NAMESPACE}/${EXTENSION_PREFIX}-${shortName}`, - config - ] + return [nameRef, config] }) /** From 013ed529135bfa86ad8ea95b301fdafa5fa0cac5 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 10:59:02 -0700 Subject: [PATCH 013/929] Lint! --- packages/pwa-kit-dev/src/utils/resolver-utils.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 10f8060ad3..32ccb7ac75 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -49,23 +49,23 @@ export const expand = (extensions = []) => .filter((extension) => Boolean(extension)) .map((extension) => { let [nameRef, config = {}] = Array.isArray(extension) ? extension : [extension, {}] - + // We determine the type of extention reference by it's first character. switch (nameRef[0]) { - case ".": + case '.': // Relative Path nameRef = nameRef.split(/\/|\\/).join(path.sep) nameRef = path.join(process.cwd(), nameRef.replace('.', '')) break - case "/": + case '/': // Absolute Path (UNIX) nameRef = nameRef.split(/\/|\\/).join(path.sep) break - case "\\": + case '\\': // Absolute Path (Windows) nameRef = nameRef.split(/\/|\\/).join(path.sep) break - case "@": + case '@': // Module Path // Do nothing... break From 925dc1f7613b9c79ec2d574ef66e2d960cba4c39 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 11:23:38 -0700 Subject: [PATCH 014/929] Fix test input/output --- packages/pwa-kit-dev/src/utils/resolver-utils.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index bd3c509bdb..eddb41b1fe 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -72,15 +72,15 @@ describe('resolverUtils', () => { }, { name: 'extensions include falsey values', - input: ['module-extension-a', '', './local-extension-c', false], + input: ['module-extension-a', '', `.${path.sep}local-extension-c`, false], expected: [ ['@salesforce/extension-module-extension-a', {}], - [`${process.cwd()}/local-extension-c`, {}] + [path.join(process.cwd(), 'local-extension-c'), {}] ] }, { name: 'extensions includes absolute values', - input: [`${process.cwd()}/local-extension-a`], + input: [path.join(process.cwd(), 'local-extension-a')], expected: [[`${process.cwd()}/local-extension-a`, {}]] } ].forEach((testCase) => { From a93ff9f2822fbdb87880f76591bd50e72f49d6e5 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 11:48:53 -0700 Subject: [PATCH 015/929] Add more test coverage --- .../src/utils/resolver-utils.test.js | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index eddb41b1fe..e453e2d9b3 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -79,9 +79,26 @@ describe('resolverUtils', () => { ] }, { - name: 'extensions includes absolute values', - input: [path.join(process.cwd(), 'local-extension-a')], - expected: [[`${process.cwd()}/local-extension-a`, {}]] + name: 'extensions includes absolute path and module path values', + input: [ + path.join(process.cwd(), 'local-extension-a'), + path.join('@salesforce', 'module-extension-a') + ], + expected: [ + [`${process.cwd()}/local-extension-a`, {}], + [path.join('@salesforce', 'module-extension-a'), {}] + ] + }, + { + name: 'extensions includes windows file paths', + input: [ + '.\\local-extension-a', + '\\home\\local-extension-a' + ], + expected: [ + [`${process.cwd()}/local-extension-a`, {}], + [path.join(path.sep, 'home', 'local-extension-a'), {}] + ] } ].forEach((testCase) => { test(`${testCase.name}`, () => { From 7dbb491b5e2dfbaed1c25cba349d237d75b8727e Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 11:53:55 -0700 Subject: [PATCH 016/929] Lint! --- packages/pwa-kit-dev/src/utils/resolver-utils.test.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index e453e2d9b3..bb40590866 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -91,10 +91,7 @@ describe('resolverUtils', () => { }, { name: 'extensions includes windows file paths', - input: [ - '.\\local-extension-a', - '\\home\\local-extension-a' - ], + input: ['.\\local-extension-a', '\\home\\local-extension-a'], expected: [ [`${process.cwd()}/local-extension-a`, {}], [path.join(path.sep, 'home', 'local-extension-a'), {}] From e0c146d967631e76111678bf6a7bd86f346b6416 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 13:36:35 -0700 Subject: [PATCH 017/929] Fix text expected results for windows. --- packages/pwa-kit-dev/src/utils/resolver-utils.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index bb40590866..b1c3eef497 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -67,7 +67,7 @@ describe('resolverUtils', () => { expected: [ ['@salesforce/extension-module-extension-a', {}], ['@salesforce/extension-module-extension-b', {}], - [`${process.cwd()}/local-extension-c`, {}] + [path.join(process.cwd(), 'local-extension-c'), {}] ] }, { @@ -85,7 +85,7 @@ describe('resolverUtils', () => { path.join('@salesforce', 'module-extension-a') ], expected: [ - [`${process.cwd()}/local-extension-a`, {}], + [path.join(process.cwd(), 'local-extension-a'), {}], [path.join('@salesforce', 'module-extension-a'), {}] ] }, @@ -93,7 +93,7 @@ describe('resolverUtils', () => { name: 'extensions includes windows file paths', input: ['.\\local-extension-a', '\\home\\local-extension-a'], expected: [ - [`${process.cwd()}/local-extension-a`, {}], + [path.join(process.cwd(), 'local-extension-a'), {}], [path.join(path.sep, 'home', 'local-extension-a'), {}] ] } From 69c1456bc2d876aace8bb056a511448c3b147a63 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 14 Jun 2024 14:59:41 -0700 Subject: [PATCH 018/929] Fix regex for absolute path matching --- .../pwa-kit-dev/src/utils/resolver-utils.js | 19 +++++++------------ .../src/utils/resolver-utils.test.js | 2 +- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 32ccb7ac75..24600b4d9d 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -50,28 +50,23 @@ export const expand = (extensions = []) => .map((extension) => { let [nameRef, config = {}] = Array.isArray(extension) ? extension : [extension, {}] - // We determine the type of extention reference by it's first character. - switch (nameRef[0]) { - case '.': + switch (true) { + case /^\./.test(nameRef): // Relative Path nameRef = nameRef.split(/\/|\\/).join(path.sep) nameRef = path.join(process.cwd(), nameRef.replace('.', '')) break - case '/': - // Absolute Path (UNIX) + case /^(\/|\\|\w:)/.test(nameRef): + // Absolute Path (UNIX|Windows) nameRef = nameRef.split(/\/|\\/).join(path.sep) break - case '\\': - // Absolute Path (Windows) - nameRef = nameRef.split(/\/|\\/).join(path.sep) - break - case '@': - // Module Path - // Do nothing... + case /^@/.test(nameRef): + // Do nothing break default: // Default is to treat the reference as a extension "short" name. nameRef = `${EXTENSION_NAMESPACE}/${EXTENSION_PREFIX}-${nameRef}` + break } return [nameRef, config] diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index b1c3eef497..661f9a2b41 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -53,7 +53,7 @@ describe('resolverUtils', () => { describe('"expand" util returns correct return value when', () => { ;[ { - name: 'extensions are all module extensions', + name: 'extensions are all short names', input: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ ['@salesforce/extension-module-extension-a', {}], From c8d8cd07ed8d4446ad8eba08905e44b4ee0c7e6f Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 21 Jun 2024 11:12:37 -0700 Subject: [PATCH 019/929] Bump version to 4.0.0 --- lerna.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- packages/commerce-sdk-react/CHANGELOG.md | 2 ++ packages/commerce-sdk-react/package.json | 4 ++-- packages/internal-lib-build/package-lock.json | 4 ++-- packages/internal-lib-build/package.json | 4 ++-- packages/pwa-kit-create-app/package-lock.json | 4 ++-- packages/pwa-kit-create-app/package.json | 6 +++--- packages/pwa-kit-dev/CHANGELOG.md | 1 + packages/pwa-kit-dev/package-lock.json | 4 ++-- packages/pwa-kit-dev/package.json | 6 +++--- packages/pwa-kit-react-sdk/CHANGELOG.md | 1 + packages/pwa-kit-react-sdk/package-lock.json | 4 ++-- packages/pwa-kit-react-sdk/package.json | 8 ++++---- packages/pwa-kit-runtime/CHANGELOG.md | 1 + packages/pwa-kit-runtime/package-lock.json | 4 ++-- packages/pwa-kit-runtime/package.json | 8 ++++---- packages/template-express-minimal/package-lock.json | 4 ++-- packages/template-express-minimal/package.json | 6 +++--- packages/template-mrt-reference-app/package-lock.json | 4 ++-- packages/template-mrt-reference-app/package.json | 6 +++--- packages/template-retail-react-app/package.json | 6 +++--- packages/template-typescript-minimal/package-lock.json | 4 ++-- packages/template-typescript-minimal/package.json | 8 ++++---- packages/test-commerce-sdk-react/package-lock.json | 4 ++-- packages/test-commerce-sdk-react/package.json | 10 +++++----- 27 files changed, 63 insertions(+), 58 deletions(-) diff --git a/lerna.json b/lerna.json index c59b19b349..bf15a4fe27 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "3.6.0-dev", + "version": "4.0.0-dev", "packages": [ "packages/*" ] diff --git a/package-lock.json b/package-lock.json index b170912a30..e53f05a560 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pwa-kit", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pwa-kit", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "hasInstallScript": true, "dependencies": { "node-fetch": "^2.6.9" diff --git a/package.json b/package.json index 5b927c551c..db47801a06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pwa-kit", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "scripts": { "bump-version": "node ./scripts/bump-version/index.js", "bump-version:retail-react-app": "node ./scripts/bump-version/index.js --package=@salesforce/retail-react-app", diff --git a/packages/commerce-sdk-react/CHANGELOG.md b/packages/commerce-sdk-react/CHANGELOG.md index e312494585..4f6d9ffd67 100644 --- a/packages/commerce-sdk-react/CHANGELOG.md +++ b/packages/commerce-sdk-react/CHANGELOG.md @@ -1,3 +1,5 @@ +## v2.0.0-dev (Jun 21, 2024) +## v4.0.0-dev (Jun 21, 2024) ## v2.0.0-dev (May 21, 2024) - Upgrade to commerce-sdk-isomorphic v2.0.0 [#1794](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1794) - Add `useCustomQuery` and `useCustomMutation` for SCAPI custom endpoint support [#1793](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1793) diff --git a/packages/commerce-sdk-react/package.json b/packages/commerce-sdk-react/package.json index c926706c0c..6f433a0924 100644 --- a/packages/commerce-sdk-react/package.json +++ b/packages/commerce-sdk-react/package.json @@ -45,7 +45,7 @@ "jwt-decode": "^4.0.0" }, "devDependencies": { - "@salesforce/pwa-kit-dev": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", "@tanstack/react-query": "^4.28.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", @@ -59,7 +59,7 @@ "@types/react-helmet": "~6.1.6", "@types/react-router-dom": "~5.3.3", "cross-env": "^5.2.1", - "internal-lib-build": "3.6.0-dev", + "internal-lib-build": "4.0.0-dev", "jsonwebtoken": "^9.0.0", "nock": "^13.3.0", "nodemon": "^2.0.22", diff --git a/packages/internal-lib-build/package-lock.json b/packages/internal-lib-build/package-lock.json index 09d927e6ea..cce80f5c99 100644 --- a/packages/internal-lib-build/package-lock.json +++ b/packages/internal-lib-build/package-lock.json @@ -1,12 +1,12 @@ { "name": "internal-lib-build", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "internal-lib-build", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@babel/cli": "^7.21.0", diff --git a/packages/internal-lib-build/package.json b/packages/internal-lib-build/package.json index 67b61a192e..2d1659e5cb 100644 --- a/packages/internal-lib-build/package.json +++ b/packages/internal-lib-build/package.json @@ -1,6 +1,6 @@ { "name": "internal-lib-build", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "private": true, "description": "Build tools for *libraries* in the monorepo", "bugs": { @@ -60,7 +60,7 @@ "shelljs": "^0.8.5" }, "devDependencies": { - "@salesforce/pwa-kit-dev": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", "npm-packlist": "^4.0.0", "typescript": "4.9.5" }, diff --git a/packages/pwa-kit-create-app/package-lock.json b/packages/pwa-kit-create-app/package-lock.json index 7003b68356..9edce5514e 100644 --- a/packages/pwa-kit-create-app/package-lock.json +++ b/packages/pwa-kit-create-app/package-lock.json @@ -1,12 +1,12 @@ { "name": "@salesforce/pwa-kit-create-app", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@salesforce/pwa-kit-create-app", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "See license in LICENSE", "dependencies": { "commander": "^9.5.0", diff --git a/packages/pwa-kit-create-app/package.json b/packages/pwa-kit-create-app/package.json index 976d2dbaaf..11267706b6 100644 --- a/packages/pwa-kit-create-app/package.json +++ b/packages/pwa-kit-create-app/package.json @@ -1,6 +1,6 @@ { "name": "@salesforce/pwa-kit-create-app", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "description": "Salesforce's project generator tool", "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-create-app#readme", "bugs": { @@ -38,8 +38,8 @@ "tar": "^6.2.1" }, "devDependencies": { - "@salesforce/pwa-kit-dev": "3.6.0-dev", - "internal-lib-build": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", + "internal-lib-build": "4.0.0-dev", "verdaccio": "^5.22.1" }, "engines": { diff --git a/packages/pwa-kit-dev/CHANGELOG.md b/packages/pwa-kit-dev/CHANGELOG.md index ec1fa8f038..f639deda29 100644 --- a/packages/pwa-kit-dev/CHANGELOG.md +++ b/packages/pwa-kit-dev/CHANGELOG.md @@ -1,3 +1,4 @@ +## v4.0.0-dev (Jun 21, 2024) ## v3.6.0-dev (Apr 17, 2024) ## v3.5.1 (Apr 17, 2024) - Update SLAS private proxy path [#1752](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1752) diff --git a/packages/pwa-kit-dev/package-lock.json b/packages/pwa-kit-dev/package-lock.json index 3e655b1bda..1a4973783b 100644 --- a/packages/pwa-kit-dev/package-lock.json +++ b/packages/pwa-kit-dev/package-lock.json @@ -1,12 +1,12 @@ { "name": "@salesforce/pwa-kit-dev", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@salesforce/pwa-kit-dev", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@babel/cli": "^7.21.0", diff --git a/packages/pwa-kit-dev/package.json b/packages/pwa-kit-dev/package.json index 001842d5f5..1746d665db 100644 --- a/packages/pwa-kit-dev/package.json +++ b/packages/pwa-kit-dev/package.json @@ -1,6 +1,6 @@ { "name": "@salesforce/pwa-kit-dev", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "description": "Build tools for pwa-kit", "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-dev#readme", "bugs": { @@ -58,7 +58,7 @@ "@loadable/server": "^5.15.3", "@loadable/webpack-plugin": "^5.15.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.57.0", "archiver": "1.3.0", @@ -121,7 +121,7 @@ "@types/node": "~16.0.3", "@types/node-fetch": "~2.6.3", "@types/validator": "~13.7.14", - "internal-lib-build": "3.6.0-dev", + "internal-lib-build": "4.0.0-dev", "nock": "^13.3.0", "nodemon": "^2.0.22", "superagent": "^6.1.0", diff --git a/packages/pwa-kit-react-sdk/CHANGELOG.md b/packages/pwa-kit-react-sdk/CHANGELOG.md index a1ab37fe8b..232e8f9fd1 100644 --- a/packages/pwa-kit-react-sdk/CHANGELOG.md +++ b/packages/pwa-kit-react-sdk/CHANGELOG.md @@ -1,3 +1,4 @@ +## v4.0.0-dev (Jun 21, 2024) ## v3.6.0-dev (Apr 17, 2024) ## v3.5.1 (Apr 17, 2024) diff --git a/packages/pwa-kit-react-sdk/package-lock.json b/packages/pwa-kit-react-sdk/package-lock.json index a72e656ac6..ae87628ba0 100644 --- a/packages/pwa-kit-react-sdk/package-lock.json +++ b/packages/pwa-kit-react-sdk/package-lock.json @@ -1,12 +1,12 @@ { "name": "@salesforce/pwa-kit-react-sdk", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@salesforce/pwa-kit-react-sdk", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@loadable/babel-plugin": "^5.15.3", diff --git a/packages/pwa-kit-react-sdk/package.json b/packages/pwa-kit-react-sdk/package.json index 699caeb86c..4e2d93f448 100644 --- a/packages/pwa-kit-react-sdk/package.json +++ b/packages/pwa-kit-react-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@salesforce/pwa-kit-react-sdk", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "description": "A library that supports the isomorphic React rendering pipeline for Commerce Cloud Managed Runtime apps", "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-react-sdk#readme", "bugs": { @@ -37,7 +37,7 @@ "@loadable/babel-plugin": "^5.15.3", "@loadable/server": "^5.15.3", "@loadable/webpack-plugin": "^5.15.2", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@tanstack/react-query": "^4.28.0", "cross-env": "^5.2.1", "event-emitter": "^0.3.5", @@ -50,11 +50,11 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-dev": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", - "internal-lib-build": "3.6.0-dev", + "internal-lib-build": "4.0.0-dev", "node-html-parser": "^3.3.6", "nodemon": "^2.0.22", "react": "^18.2.0", diff --git a/packages/pwa-kit-runtime/CHANGELOG.md b/packages/pwa-kit-runtime/CHANGELOG.md index da1fc28b6f..139d181fbb 100644 --- a/packages/pwa-kit-runtime/CHANGELOG.md +++ b/packages/pwa-kit-runtime/CHANGELOG.md @@ -1,3 +1,4 @@ +## v4.0.0-dev (Jun 21, 2024) ## v3.6.0-dev (Jun 11, 2024) - Add logger to print logs generated by PWA Kit packages [#1822](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1822) - Added the `x-correlation-id` response header, which is set to the MRT correlation ID. This enhances traceability by including the correlation ID from the request in the response. [#1787](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1787) diff --git a/packages/pwa-kit-runtime/package-lock.json b/packages/pwa-kit-runtime/package-lock.json index 3fbeab94c6..0959b8722c 100644 --- a/packages/pwa-kit-runtime/package-lock.json +++ b/packages/pwa-kit-runtime/package-lock.json @@ -1,12 +1,12 @@ { "name": "@salesforce/pwa-kit-runtime", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@salesforce/pwa-kit-runtime", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@loadable/babel-plugin": "^5.15.3", diff --git a/packages/pwa-kit-runtime/package.json b/packages/pwa-kit-runtime/package.json index 372833c9cb..ef040cf50a 100644 --- a/packages/pwa-kit-runtime/package.json +++ b/packages/pwa-kit-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@salesforce/pwa-kit-runtime", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "description": "The PWAKit Runtime", "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-runtime#readme", "bugs": { @@ -46,11 +46,11 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-dev": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", "@serverless/event-mocks": "^1.1.1", "aws-lambda-mock-context": "^3.2.1", "fs-extra": "^11.1.1", - "internal-lib-build": "3.6.0-dev", + "internal-lib-build": "4.0.0-dev", "nock": "^13.3.0", "nodemon": "^2.0.22", "sinon": "^13.0.2", @@ -58,7 +58,7 @@ "supertest": "^4.0.2" }, "peerDependencies": { - "@salesforce/pwa-kit-dev": "3.6.0-dev" + "@salesforce/pwa-kit-dev": "4.0.0-dev" }, "peerDependenciesMeta": { "@salesforce/pwa-kit-dev": { diff --git a/packages/template-express-minimal/package-lock.json b/packages/template-express-minimal/package-lock.json index 391d8c529a..76483e3b30 100644 --- a/packages/template-express-minimal/package-lock.json +++ b/packages/template-express-minimal/package-lock.json @@ -1,12 +1,12 @@ { "name": "template-express-minimal", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "template-express-minimal", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "See license in LICENSE", "devDependencies": { "supertest": "^4.0.2" diff --git a/packages/template-express-minimal/package.json b/packages/template-express-minimal/package.json index e089ca8222..873b9bb39d 100644 --- a/packages/template-express-minimal/package.json +++ b/packages/template-express-minimal/package.json @@ -1,6 +1,6 @@ { "name": "template-express-minimal", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "private": true, "license": "See license in LICENSE", "scripts": { @@ -15,8 +15,8 @@ "test": "pwa-kit-dev test" }, "devDependencies": { - "@salesforce/pwa-kit-dev": "3.6.0-dev", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "supertest": "^4.0.2" }, "mobify": { diff --git a/packages/template-mrt-reference-app/package-lock.json b/packages/template-mrt-reference-app/package-lock.json index 34ee84f2af..719c462d75 100644 --- a/packages/template-mrt-reference-app/package-lock.json +++ b/packages/template-mrt-reference-app/package-lock.json @@ -1,12 +1,12 @@ { "name": "template-mrt-reference-app", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "template-mrt-reference-app", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "license": "See license in LICENSE", "dependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.450.0", diff --git a/packages/template-mrt-reference-app/package.json b/packages/template-mrt-reference-app/package.json index 316bd20980..169dbb6764 100644 --- a/packages/template-mrt-reference-app/package.json +++ b/packages/template-mrt-reference-app/package.json @@ -1,6 +1,6 @@ { "name": "template-mrt-reference-app", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "private": true, "license": "See license in LICENSE", "scripts": { @@ -16,8 +16,8 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-dev": "3.6.0-dev", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@smithy/smithy-client": "^2.1.15", "aws-sdk-client-mock": "^3.0.0", "cross-fetch": "^3.1.4", diff --git a/packages/template-retail-react-app/package.json b/packages/template-retail-react-app/package.json index ba2e28f78c..c2a5795f46 100644 --- a/packages/template-retail-react-app/package.json +++ b/packages/template-retail-react-app/package.json @@ -46,9 +46,9 @@ "@loadable/component": "^5.15.3", "@peculiar/webcrypto": "^1.4.2", "@salesforce/commerce-sdk-react": "2.0.0-dev", - "@salesforce/pwa-kit-dev": "3.6.0-dev", - "@salesforce/pwa-kit-react-sdk": "3.6.0-dev", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@tanstack/react-query": "^4.28.0", "@tanstack/react-query-devtools": "^4.29.1", "@testing-library/dom": "^9.0.1", diff --git a/packages/template-typescript-minimal/package-lock.json b/packages/template-typescript-minimal/package-lock.json index f073015b84..9bc7d3abf4 100644 --- a/packages/template-typescript-minimal/package-lock.json +++ b/packages/template-typescript-minimal/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-minimal", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-minimal", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "devDependencies": { "@loadable/component": "^5.15.3", "@tanstack/react-query": "^4.28.0", diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 6df606f14a..26329f0685 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -1,6 +1,6 @@ { "name": "typescript-minimal", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "private": true, "scripts": { "build": "pwa-kit-dev build", @@ -18,9 +18,9 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-dev": "3.6.0-dev", - "@salesforce/pwa-kit-react-sdk": "3.6.0-dev", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@tanstack/react-query": "^4.28.0", "@types/loadable__component": "~5.13.4", "@types/react": "~18.2.0", diff --git a/packages/test-commerce-sdk-react/package-lock.json b/packages/test-commerce-sdk-react/package-lock.json index 614e66ce7e..903b9c7cb3 100644 --- a/packages/test-commerce-sdk-react/package-lock.json +++ b/packages/test-commerce-sdk-react/package-lock.json @@ -1,12 +1,12 @@ { "name": "test-commerce-sdk-react", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "test-commerce-sdk-react", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "devDependencies": { "@loadable/component": "^5.15.3", "@tanstack/react-query": "^4.28.0", diff --git a/packages/test-commerce-sdk-react/package.json b/packages/test-commerce-sdk-react/package.json index ff401eae17..458f4ecf74 100644 --- a/packages/test-commerce-sdk-react/package.json +++ b/packages/test-commerce-sdk-react/package.json @@ -1,6 +1,6 @@ { "name": "test-commerce-sdk-react", - "version": "3.6.0-dev", + "version": "4.0.0-dev", "private": true, "scripts": { "build": "pwa-kit-dev build", @@ -19,16 +19,16 @@ "devDependencies": { "@loadable/component": "^5.15.3", "@salesforce/commerce-sdk-react": "2.0.0-dev", - "@salesforce/pwa-kit-dev": "3.6.0-dev", - "@salesforce/pwa-kit-react-sdk": "3.6.0-dev", - "@salesforce/pwa-kit-runtime": "3.6.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@tanstack/react-query": "^4.28.0", "@types/loadable__component": "~5.13.4", "@types/node": "~16.0.3", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "@types/react-router-dom": "~5.3.3", - "internal-lib-build": "3.6.0-dev", + "internal-lib-build": "4.0.0-dev", "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", From 63009e5d072205139ff699b223667d8627a1a4ef Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 21 Jun 2024 14:52:42 -0700 Subject: [PATCH 020/929] Function name change and PR feedback --- packages/pwa-kit-dev/src/utils/resolver-utils.js | 15 ++++++++------- .../pwa-kit-dev/src/utils/resolver-utils.test.js | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 24600b4d9d..8da496722a 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -6,7 +6,6 @@ */ import path from 'path' -import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' const EXTENSION_NAMESPACE = '@salesforce' const EXTENSION_PREFIX = 'extension' @@ -78,15 +77,17 @@ export const expand = (extensions = []) => * * @param {String} importPath - The import module-name. * @param {String} sourcePath - The path the the file of the source import. + * @param {Object} opts - The path the the file of the source import. + * @param {Array} opts.extensions - List of extensions used by the base PWA-Kit application. + * @param {String>} opts.productDir - Absolute path of the base project. * @returns {String[]} paths - The potential paths to find the module import. */ -export const buildCandidatePathArray = (importPath, sourcePath, opts = {}) => { +export const buildCandidatePaths = (importPath, sourcePath, opts = {}) => { // Replace wildcard character as it has done its job getting us to this point. importPath = importPath.replace('*/', '') - const {extensions = getConfig()?.app?.extensions} = opts + const {extensions = [], productDir = process.cwd()} = opts const isSelfReferenceImport = isSelfReference(importPath, sourcePath) - const cwd = process.cwd() let paths = expand(extensions).reverse() // Map all the extensions and resolve the module names to absolute paths. @@ -98,19 +99,19 @@ export const buildCandidatePathArray = (importPath, sourcePath, opts = {}) => { return path.join( ...(isLocalExtension ? [extensionRef, importPath] - : [cwd, NODE_MODULES, extensionRef, importPath]) + : [productDir, NODE_MODULES, extensionRef, importPath]) ) }) // Add non-extension search locations locations. The base project and the sdk as the final callback. paths = [ // Base Project - path.join(cwd, importPath), + path.join(productDir, importPath), // Extensions ...paths, // SDK path.join( - cwd, + productDir, NODE_MODULES, EXTENSION_NAMESPACE, 'pwa-kit-react-sdk', diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index 661f9a2b41..95fb73bea9 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -106,7 +106,7 @@ describe('resolverUtils', () => { }) }) - describe('"buildCandidatePathArray" util returns array of paths used to module resolving', () => { + describe('"buildCandidatePaths" util returns array of paths used to module resolving', () => { ;[ { name: 'Correct absolute paths are returned with valid input data', @@ -197,7 +197,7 @@ describe('resolverUtils', () => { } ].forEach((testCase) => { test(`${testCase.name}`, () => { - const result = resolverUtils.buildCandidatePathArray( + const result = resolverUtils.buildCandidatePaths( testCase.importPath, testCase.sourcePath, {extensions: testCase.extensions} From 1e55703f16b76c81fae521e8610c22cc9736fe80 Mon Sep 17 00:00:00 2001 From: Kevin He Date: Tue, 16 Jul 2024 23:05:36 -0700 Subject: [PATCH 021/929] add test-extensibility-base project --- .../test-extensibility-base/.eslintignore | 8 + packages/test-extensibility-base/.eslintrc.js | 10 + packages/test-extensibility-base/.gitignore | 3 + .../test-extensibility-base/.prettierrc.yaml | 7 + packages/test-extensibility-base/README.md | 3 + .../app/components/_app-config/index.js | 30 ++ .../app/components/hello-javascript.jsx | 13 + .../app/components/hello-typescript.tsx | 17 + .../test-extensibility-base/app/main.test.js | 9 + packages/test-extensibility-base/app/main.tsx | 9 + .../app/pages/home.tsx | 135 +++++++ .../app/request-processor.js | 13 + .../test-extensibility-base/app/routes.tsx | 21 + packages/test-extensibility-base/app/ssr.js | 48 +++ .../app/static/favicon.ico | Bin 0 -> 5430 bytes .../app/typescript-file.ts | 10 + .../test-extensibility-base/babel.config.js | 7 + .../test-extensibility-base/jest.config.js | 20 + .../test-extensibility-base/package-lock.json | 374 ++++++++++++++++++ packages/test-extensibility-base/package.json | 75 ++++ packages/test-extensibility-base/pwa-kit.d.ts | 9 + .../test-extensibility-base/tsconfig.json | 102 +++++ 22 files changed, 923 insertions(+) create mode 100644 packages/test-extensibility-base/.eslintignore create mode 100644 packages/test-extensibility-base/.eslintrc.js create mode 100644 packages/test-extensibility-base/.gitignore create mode 100644 packages/test-extensibility-base/.prettierrc.yaml create mode 100644 packages/test-extensibility-base/README.md create mode 100644 packages/test-extensibility-base/app/components/_app-config/index.js create mode 100644 packages/test-extensibility-base/app/components/hello-javascript.jsx create mode 100644 packages/test-extensibility-base/app/components/hello-typescript.tsx create mode 100644 packages/test-extensibility-base/app/main.test.js create mode 100644 packages/test-extensibility-base/app/main.tsx create mode 100644 packages/test-extensibility-base/app/pages/home.tsx create mode 100644 packages/test-extensibility-base/app/request-processor.js create mode 100644 packages/test-extensibility-base/app/routes.tsx create mode 100644 packages/test-extensibility-base/app/ssr.js create mode 100644 packages/test-extensibility-base/app/static/favicon.ico create mode 100644 packages/test-extensibility-base/app/typescript-file.ts create mode 100644 packages/test-extensibility-base/babel.config.js create mode 100644 packages/test-extensibility-base/jest.config.js create mode 100644 packages/test-extensibility-base/package-lock.json create mode 100644 packages/test-extensibility-base/package.json create mode 100644 packages/test-extensibility-base/pwa-kit.d.ts create mode 100644 packages/test-extensibility-base/tsconfig.json diff --git a/packages/test-extensibility-base/.eslintignore b/packages/test-extensibility-base/.eslintignore new file mode 100644 index 0000000000..4329a9339b --- /dev/null +++ b/packages/test-extensibility-base/.eslintignore @@ -0,0 +1,8 @@ +build +coverage +docs +app/static +jest.config.js +webpack +scripts/generator/assets +dist diff --git a/packages/test-extensibility-base/.eslintrc.js b/packages/test-extensibility-base/.eslintrc.js new file mode 100644 index 0000000000..7afa841fe1 --- /dev/null +++ b/packages/test-extensibility-base/.eslintrc.js @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +module.exports = { + extends: [require.resolve('@salesforce/pwa-kit-dev/configs/eslint')] +} diff --git a/packages/test-extensibility-base/.gitignore b/packages/test-extensibility-base/.gitignore new file mode 100644 index 0000000000..ea0304cb8c --- /dev/null +++ b/packages/test-extensibility-base/.gitignore @@ -0,0 +1,3 @@ +build.tar +node_modules/ +build/ \ No newline at end of file diff --git a/packages/test-extensibility-base/.prettierrc.yaml b/packages/test-extensibility-base/.prettierrc.yaml new file mode 100644 index 0000000000..33069bf2b2 --- /dev/null +++ b/packages/test-extensibility-base/.prettierrc.yaml @@ -0,0 +1,7 @@ +printWidth: 100 +singleQuote: true +semi: false +bracketSpacing: false +tabWidth: 4 +arrowParens: 'always' +trailingComma: 'none' diff --git a/packages/test-extensibility-base/README.md b/packages/test-extensibility-base/README.md new file mode 100644 index 0000000000..6a542c0832 --- /dev/null +++ b/packages/test-extensibility-base/README.md @@ -0,0 +1,3 @@ +# test-extensibility-base + +This is a clone of the typescript minimal template, used as a test playground for the multi-extensibility feature. \ No newline at end of file diff --git a/packages/test-extensibility-base/app/components/_app-config/index.js b/packages/test-extensibility-base/app/components/_app-config/index.js new file mode 100644 index 0000000000..6d9fb3950a --- /dev/null +++ b/packages/test-extensibility-base/app/components/_app-config/index.js @@ -0,0 +1,30 @@ +/* + * 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 + */ +import {withLegacyGetProps} from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/with-legacy-get-props' +import {withReactQuery} from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/with-react-query' +import AppConfig from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/_app-config' + +const isServerSide = typeof window === 'undefined' + +// Recommended settings for PWA-Kit usages. +// NOTE: they will be applied on both server and client side. +const options = { + queryClientConfig: { + defaultOptions: { + queries: { + retry: false, + staleTime: 2 * 1000, + ...(isServerSide ? {retryOnMount: false} : {}) + }, + mutations: { + retry: false + } + } + } +} + +export default withReactQuery(withLegacyGetProps(AppConfig), options) diff --git a/packages/test-extensibility-base/app/components/hello-javascript.jsx b/packages/test-extensibility-base/app/components/hello-javascript.jsx new file mode 100644 index 0000000000..f7819f7f65 --- /dev/null +++ b/packages/test-extensibility-base/app/components/hello-javascript.jsx @@ -0,0 +1,13 @@ +/* + * 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 + */ +import React from 'react' + +const HelloJS = () => { + return This is a JS component. +} + +export default HelloJS diff --git a/packages/test-extensibility-base/app/components/hello-typescript.tsx b/packages/test-extensibility-base/app/components/hello-typescript.tsx new file mode 100644 index 0000000000..085aa494ef --- /dev/null +++ b/packages/test-extensibility-base/app/components/hello-typescript.tsx @@ -0,0 +1,17 @@ +/* + * 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 + */ +import React from 'react' + +interface Props { + message: string +} + +const HelloTS = ({message}: Props) => { + return And this is a TS component (it takes a prop: "{message}"). +} + +export default HelloTS diff --git a/packages/test-extensibility-base/app/main.test.js b/packages/test-extensibility-base/app/main.test.js new file mode 100644 index 0000000000..0724ec4fdf --- /dev/null +++ b/packages/test-extensibility-base/app/main.test.js @@ -0,0 +1,9 @@ +/* + * 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 + */ +test('basic test', () => { + expect(1 + 1).toBe(2) +}) diff --git a/packages/test-extensibility-base/app/main.tsx b/packages/test-extensibility-base/app/main.tsx new file mode 100644 index 0000000000..0d6c9a5f83 --- /dev/null +++ b/packages/test-extensibility-base/app/main.tsx @@ -0,0 +1,9 @@ +/* + * 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 + */ +import {start} from '@salesforce/pwa-kit-react-sdk/ssr/browser/main' + +start() diff --git a/packages/test-extensibility-base/app/pages/home.tsx b/packages/test-extensibility-base/app/pages/home.tsx new file mode 100644 index 0000000000..d18d03ecc9 --- /dev/null +++ b/packages/test-extensibility-base/app/pages/home.tsx @@ -0,0 +1,135 @@ +/* + * 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 + */ +import React, {useEffect, useState} from 'react' +import {useQuery} from '@tanstack/react-query' + +import HelloTS from '../components/hello-typescript' +import HelloJS from '../components/hello-javascript' + +interface Props { + value: number +} + +const style = ` +body { + background: linear-gradient(-45deg, #e73c7e, #23a6d5, #ee7752); + background-size: 400% 400%; + animation: gradient 10s ease 5; + height: 100vh; +} +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} +@keyframes fade { + 0% { opacity: 0 } + 100% { opacity: 1 } +} +.fade-in { + font-size: 18px; + opacity: 0; + animation: fade 1s ease-in-out; + animation-fill-mode: forwards; +} +.fade-in-0 { animation-delay: 0s} +.fade-in-1 { animation-delay: 4s} +.fade-in-2 { animation-delay: 8s} +.fade-in-3 { animation-delay: 12s} +.fade-in-4 { animation-delay: 16s} +.fade-in-5 { animation-delay: 20s} +body { + font-family: "Helvetica", sans-serif; + font-weight: 300; + color: rgba(255,255,255,0.8); + color: chartreuse; +} +.loading-screen { + mix-blend-mode: color-dodge; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + height: 100vh; +} +h1 { + font-size: 10em; + font-weight: 900; + letter-spacing: -0.05em; +} +.title { + text-align: right; +} +.divider { + mix-blend-mode: lighten; + width: 8px; + background-color: chartreuse; + height: 507px; + margin-left: 5em; + margin-right: 3em; +} +` + +const Home = ({value}: Props) => { + const [counter, setCounter] = useState(0) + + useEffect(() => { + const interval = setInterval(() => { + setCounter(counter + 1) + }, 1000) + return () => clearInterval(interval) + }, [counter, setCounter]) + + const query = useQuery( + ['example-data'], + () => + new Promise((resolve) => { + setTimeout(() => { + resolve('This came from react-query') + }, 1000) + }) + ) + + return ( +
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/extension-sample/src/pages/sample.tsx b/packages/extension-sample/src/pages/sample.tsx index 8167d1c653..110afbf21c 100644 --- a/packages/extension-sample/src/pages/sample.tsx +++ b/packages/extension-sample/src/pages/sample.tsx @@ -6,11 +6,19 @@ */ import React, {Fragment} from 'react' +// Temporary +import {useExtensions} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' + const Sample = () => { + + const extensions = useExtensions() + return (

Welcome to the Sample Page 👋


+ +

If you are reading this, it means that this page was successfully added to your base project. 🎉

This Application Extension was installed by running the below command in your PWA-Kit project. diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 5b699ed8cc..683219dbe3 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -366,7 +366,15 @@ const staticFolderCopyPlugin = new CopyPlugin({ .replace(/\\/g, '/'), to: `static/`, noErrorOnMissing: true - } + }, + ...(appConfig?.extensions || []).map((extension) => { + return { + from: `${projectDir}/node_modules/${extension}/assets`, + to: `static/${extension}`, + // Add exclude for readme file. + noErrorOnMissing: true + } + }) ] }) diff --git a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx index 1760580123..72fb19adf8 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx +++ b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx @@ -19,7 +19,7 @@ import {getRoutes, routeComponent} from '../universal/components/route-component import {applyAppExtensions} from '../universal/extensibility/utils' import {uuidv4} from '../../utils/uuidv4.client' import logger from '../../utils/logger-instance' -import {getExtensions} from '../universal/extensibility/extensions' +import {getExtensions, ExtensionsContext} from '../universal/extensibility/extensions' /* istanbul ignore next */ export const registerServiceWorker = (url) => { @@ -44,40 +44,43 @@ export const registerServiceWorker = (url) => { }) } -export const OuterApp = ({routes, error, WrappedApp, locals, onHydrate}) => { +export const OuterApp = ({routes, error, extensions, WrappedApp, locals, onHydrate}) => { const AppConfig = getAppConfig() const isInitialPageRef = useRef(true) return ( - - - { - // If we are hydrating an error page use the server correlation id. - if (isInitialPageRef.current && window.__ERROR__) { - isInitialPageRef.current = false - return window.__INITIAL_CORRELATION_ID__ - } - return uuidv4() - }} - > - - - - - - + + + + { + // If we are hydrating an error page use the server correlation id. + if (isInitialPageRef.current && window.__ERROR__) { + isInitialPageRef.current = false + return window.__INITIAL_CORRELATION_ID__ + } + return uuidv4() + }} + > + + + + + + + ) } OuterApp.propTypes = { routes: PropTypes.array.isRequired, error: PropTypes.object, + extensions: PropTypes.array, // TODO: Do better! WrappedApp: PropTypes.func.isRequired, locals: PropTypes.object, onHydrate: PropTypes.func @@ -127,6 +130,7 @@ export const start = () => { const props = { error: window.__ERROR__, + extensions, locals: locals, routes: getRoutes(locals), WrappedApp diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts index a1fe29aad3..b6ba8e982d 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts @@ -6,6 +6,9 @@ */ import {IRouteConfig} from './types' +// Temporary +import {bundleBasePath} from '@salesforce/pwa-kit-runtime/utils/ssr-namespace-paths' + /** * An abstract class representing an Application Extension. This class provides * foundational methods and properties for extending an application with additional @@ -47,6 +50,16 @@ export default abstract class ApplicationExtension { return this.constructor.name } + public getAssetURL(path: string): string { + const onClient = typeof window !== 'undefined' + const publicPath = onClient + ? // @ts-ignore + `${window.Progressive.buildOrigin as string}` + : `${bundleBasePath}/${process.env.BUNDLE_ID || 'development'}/` + + return path ? `${publicPath}${path}` : publicPath + } + /** * Called during the rendering of the base application on the server and the client. * It is predominantly used to enhance the "base" application by wrapping it with React providers. diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/contexts/extensions.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/contexts/extensions.ts new file mode 100644 index 0000000000..692a5021bf --- /dev/null +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/contexts/extensions.ts @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import React from 'react' + +export default React.createContext([]) diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts new file mode 100644 index 0000000000..76dcbe9044 --- /dev/null +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +/* istanbul ignore file */ + +import React, {useContext} from 'react' +import ExtensionsContext from '../contexts/extensions' + +/** + * Use this hook to get the application extensions value of the closest ExtensionsProvider component. + * + * @returns {object} Array of Extensions + */ +export const useExtensions = () => { + const context = React.useContext(ExtensionsContext) + if (context === undefined) { + throw new Error('useExtensions needs to be used within ExtensionsProvider') + } + return context +} + +/** + * Server context + * @typedef {Object} ServerContext + * @property {Object} req - Request object + * @property {Object} res - Response object + */ + +/** + * Get the server context + * @returns {ServerContext} ServerContext object + * + * @example + * const {res} = useServerContext() + * if (res && query.error) { res.status(404) } + */ +export const useServerContext = () => { + const serverContext = useContext(ServerContext) + + return serverContext +} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts index 2bdba4f6db..a234ccb259 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts @@ -10,4 +10,5 @@ export {default as extensions} from './extensions' export {default as ApplicationExtension} from './application-extension' -export * from './types' +export {default as ExtensionsContext} from './contexts/extensions' +export * from './types' \ No newline at end of file From 0bccf904bf639aa94eb78e4ebfcc7f14f7bbb7ba Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 24 Sep 2024 13:10:04 -0700 Subject: [PATCH 118/929] Solutioning... --- .../extension-sample/src/pages/sample.tsx | 12 ++--- .../{assets => static}/README.md | 0 .../{assets => static}/salesforce-logo.svg | 0 .../pwa-kit-dev/src/configs/webpack/config.js | 3 +- .../src/ssr/browser/main.jsx | 54 +++++++++---------- .../extensibility/hooks/use-extensions.ts | 44 --------------- .../src/ssr/universal/utils.ts | 10 +++- 7 files changed, 41 insertions(+), 82 deletions(-) rename packages/extension-sample/{assets => static}/README.md (100%) rename packages/extension-sample/{assets => static}/salesforce-logo.svg (100%) delete mode 100644 packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts diff --git a/packages/extension-sample/src/pages/sample.tsx b/packages/extension-sample/src/pages/sample.tsx index 110afbf21c..7ca0187f05 100644 --- a/packages/extension-sample/src/pages/sample.tsx +++ b/packages/extension-sample/src/pages/sample.tsx @@ -5,19 +5,17 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import React, {Fragment} from 'react' - -// Temporary -import {useExtensions} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' +import {getAssetUrl} from '@salesforce/pwa-kit-react-sdk/ssr/universal/utils' const Sample = () => { - - const extensions = useExtensions() - + const assetUrl = getAssetUrl('/static/@salesforce/extension-sample/salesforce-logo.svg', {extensionName: 'sample'}) + // const logoUrl = getStaticAsset('sample/salesforce-logo.svg') + // const logoUrl = getStaticAsset('salesforce-logo.svg', {extensionName: 'sample'}) return (

Welcome to the Sample Page 👋


- +

If you are reading this, it means that this page was successfully added to your base project. 🎉

diff --git a/packages/extension-sample/assets/README.md b/packages/extension-sample/static/README.md similarity index 100% rename from packages/extension-sample/assets/README.md rename to packages/extension-sample/static/README.md diff --git a/packages/extension-sample/assets/salesforce-logo.svg b/packages/extension-sample/static/salesforce-logo.svg similarity index 100% rename from packages/extension-sample/assets/salesforce-logo.svg rename to packages/extension-sample/static/salesforce-logo.svg diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 683219dbe3..d87644c59c 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -368,8 +368,9 @@ const staticFolderCopyPlugin = new CopyPlugin({ noErrorOnMissing: true }, ...(appConfig?.extensions || []).map((extension) => { + // Parse the extension name out. return { - from: `${projectDir}/node_modules/${extension}/assets`, + from: `${projectDir}/node_modules/${extension}/static`, to: `static/${extension}`, // Add exclude for readme file. noErrorOnMissing: true diff --git a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx index 72fb19adf8..1760580123 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx +++ b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx @@ -19,7 +19,7 @@ import {getRoutes, routeComponent} from '../universal/components/route-component import {applyAppExtensions} from '../universal/extensibility/utils' import {uuidv4} from '../../utils/uuidv4.client' import logger from '../../utils/logger-instance' -import {getExtensions, ExtensionsContext} from '../universal/extensibility/extensions' +import {getExtensions} from '../universal/extensibility/extensions' /* istanbul ignore next */ export const registerServiceWorker = (url) => { @@ -44,43 +44,40 @@ export const registerServiceWorker = (url) => { }) } -export const OuterApp = ({routes, error, extensions, WrappedApp, locals, onHydrate}) => { +export const OuterApp = ({routes, error, WrappedApp, locals, onHydrate}) => { const AppConfig = getAppConfig() const isInitialPageRef = useRef(true) return ( - - - - { - // If we are hydrating an error page use the server correlation id. - if (isInitialPageRef.current && window.__ERROR__) { - isInitialPageRef.current = false - return window.__INITIAL_CORRELATION_ID__ - } - return uuidv4() - }} - > - - - - - - - + + + { + // If we are hydrating an error page use the server correlation id. + if (isInitialPageRef.current && window.__ERROR__) { + isInitialPageRef.current = false + return window.__INITIAL_CORRELATION_ID__ + } + return uuidv4() + }} + > + + + + + + ) } OuterApp.propTypes = { routes: PropTypes.array.isRequired, error: PropTypes.object, - extensions: PropTypes.array, // TODO: Do better! WrappedApp: PropTypes.func.isRequired, locals: PropTypes.object, onHydrate: PropTypes.func @@ -130,7 +127,6 @@ export const start = () => { const props = { error: window.__ERROR__, - extensions, locals: locals, routes: getRoutes(locals), WrappedApp diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts deleted file mode 100644 index 76dcbe9044..0000000000 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/hooks/use-extensions.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -/* istanbul ignore file */ - -import React, {useContext} from 'react' -import ExtensionsContext from '../contexts/extensions' - -/** - * Use this hook to get the application extensions value of the closest ExtensionsProvider component. - * - * @returns {object} Array of Extensions - */ -export const useExtensions = () => { - const context = React.useContext(ExtensionsContext) - if (context === undefined) { - throw new Error('useExtensions needs to be used within ExtensionsProvider') - } - return context -} - -/** - * Server context - * @typedef {Object} ServerContext - * @property {Object} req - Request object - * @property {Object} res - Response object - */ - -/** - * Get the server context - * @returns {ServerContext} ServerContext object - * - * @example - * const {res} = useServerContext() - * if (res && query.error) { res.status(404) } - */ -export const useServerContext = () => { - const serverContext = useContext(ServerContext) - - return serverContext -} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts index 986a3f2ee8..4cc1777db9 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts @@ -19,6 +19,10 @@ import hoistNonReactStatics from 'hoist-non-react-statics' const onClient = typeof window !== 'undefined' +type GetAssetUrlOptions = { + extensionName: string +} + /** * Get the URL that should be used to load an asset from the bundle. * @@ -26,12 +30,16 @@ const onClient = typeof window !== 'undefined' * @function * @returns {string} */ -export const getAssetUrl = (path: string) => { +export const getAssetUrl = (path: string, opts: GetAssetUrlOptions) => { + const {extensionName} = opts || {} + console.log('getAssetUrl: ', extensionName) /* istanbul ignore next */ const publicPath = onClient ? // @ts-ignore `${window.Progressive.buildOrigin as string}` : `${bundleBasePath}/${process.env.BUNDLE_ID || 'development'}/` + + // http://localhost:3000/mobify/bundle/development/static/@salesforce/extension-sample/salesforce-logo.svg return path ? `${publicPath}${path}` : publicPath } From 7642bfa49a087c4bd82af002a304a907c27e2d30 Mon Sep 17 00:00:00 2001 From: Vincent Marta Date: Tue, 24 Sep 2024 15:00:30 -0600 Subject: [PATCH 119/929] [App Extensibility] Supports handling mixed types (string or a tuple) in the extension config (@W-16340556@) (#2010) * Implement IApplicationExtension class interface * Add server logs * wip * wip * Use default export * WIP ts config * Use happyPackMode when no tsconfig file * Add tsconfig to runtime * Update logger usages * Fix tests * Fix more tests * Fix tests * PR Feedback * PR Feedback * Roughly support tuple configuration * Pass config to the server app * Pass config to the React app * Add remote serverSetup tests * Add dev setup extensions tests * PR Feedback * PR Feedback * Not running those app extensions if they're `enabled=false` By default, extension config will have `enabled=true`. * Clean up code * Remove this test link * Add some tests * Update test * getConfig shouldn't return undefined Because there should at least be the default `enabled=true`. * Typing the app extension's config object * Fix and align the TS setup for both packages * Add types for express * Align with recent changes to use getExtensions() * Add comment * Refactor to use an existing util function * Fix linting error * Add todo * Repeat the same updates for build-remote-server.js * Clearly differentiate installed and configured extensions * Not using the `expand` util function for now * Remove todos * Remove unused variable * Some refactoring * For clarity, rename to `packageName` * Move to types.ts file * Add type for the extension config * Import from the index files instead * Move to the types file * Not including the server options for now * Duplicate config types for now * Test the default config value * Update changelog files --------- Co-authored-by: Adam Raya Navarro --- packages/extension-sample/src/setup-app.ts | 11 ++--- packages/extension-sample/src/setup-server.ts | 8 +++- packages/extension-sample/src/types/config.ts | 22 +++++++-- packages/pwa-kit-dev/CHANGELOG.md | 1 + .../pwa-kit-dev/src/configs/webpack/config.js | 4 +- .../webpack/loaders/extensions-loader.js | 46 ++++++++++++------- .../webpack/loaders/extensions-loader.test.js | 35 ++++++++++---- .../src/ssr/server/build-dev-server.js | 41 +++++++++++------ .../src/ssr/server/build-dev-server.test.js | 37 +++++++++++++++ .../test-extension/setup-server.js | 19 -------- .../test-extension/src/setup-server.js | 4 ++ .../src/utils/extensibility-utils.js | 11 ++++- .../pwa-kit-dev/src/utils/resolver-utils.js | 1 + packages/pwa-kit-react-sdk/CHANGELOG.md | 1 + packages/pwa-kit-react-sdk/package.json | 4 +- .../extensibility/application-extension.ts | 8 ++-- .../ssr/universal/extensibility/extensions.ts | 12 ++--- .../src/ssr/universal/extensibility/types.ts | 4 ++ .../src/ssr/universal/extensibility/utils.ts | 6 +-- packages/pwa-kit-runtime/CHANGELOG.md | 2 + packages/pwa-kit-runtime/package.json | 2 +- .../src/ssr/server/build-remote-server.js | 41 +++++++++++------ .../ssr/server/build-remote-server.test.js | 37 +++++++++++++++ .../extensibility/application-extension.ts | 8 ++-- .../src/ssr/server/extensibility/types.ts | 4 ++ .../extensions/test-extension/setup-server.js | 4 ++ .../template-typescript-minimal/package.json | 6 ++- 27 files changed, 266 insertions(+), 113 deletions(-) delete mode 100644 packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/setup-server.js diff --git a/packages/extension-sample/src/setup-app.ts b/packages/extension-sample/src/setup-app.ts index b64c88dee1..f7e2d6c8c5 100644 --- a/packages/extension-sample/src/setup-app.ts +++ b/packages/extension-sample/src/setup-app.ts @@ -7,16 +7,15 @@ import React from 'react' import loadable from '@loadable/component' -import {IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility/types' -import {ApplicationExtension} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' +import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' import withRedBorder from './components/with-red-border' +import {ReactExtensionConfig as Config} from './types' const SamplePage = loadable(() => import('./pages/sample')) - const defaultPath: string = '/sample-page' -class Sample extends ApplicationExtension { - + +class Sample extends ApplicationExtension { extendApp(App: React.ComponentType): React.ComponentType { return withRedBorder(App) } @@ -26,7 +25,7 @@ class Sample extends ApplicationExtension { return [ { exact: true, - path: this.getConfig()?.path || defaultPath, + path: this.getConfig().path || defaultPath, component: SamplePage }, ...routes diff --git a/packages/extension-sample/src/setup-server.ts b/packages/extension-sample/src/setup-server.ts index 5de01aecaf..f04f886a7d 100644 --- a/packages/extension-sample/src/setup-server.ts +++ b/packages/extension-sample/src/setup-server.ts @@ -9,14 +9,18 @@ import { Application as ExpressApplication, ApplicationExtension as ExpressApplicationExtension } from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' +import {ServerExtensionConfig as Config} from './types' -class SampleExtension extends ExpressApplicationExtension { +class SampleExtension extends ExpressApplicationExtension { extendApp(app: ExpressApplication): ExpressApplication { app.get('/sample', (req, res) => { console.log('SampleExtension extendApp GET /sample') - res.send('Hello from an express SampleExtension!') + res.send( + `

Hello from an express SampleExtension!

+
extensionConfig = ${JSON.stringify(this.getConfig())}
` + ) }) return app diff --git a/packages/extension-sample/src/types/config.ts b/packages/extension-sample/src/types/config.ts index 9deb18b1ce..fa9d245435 100644 --- a/packages/extension-sample/src/types/config.ts +++ b/packages/extension-sample/src/types/config.ts @@ -4,9 +4,23 @@ * 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 */ +import { + ApplicationExtensionConfig as _ServerExtensionConfig +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' + +import { + ApplicationExtensionConfig as _ReactExtensionConfig +} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' // This is where you are going to define the configuration type for your App Extension. This is used in the constructor -// the extension itself. Update this config type to your specfic needs!! -export interface IConfig { - path: string; -} \ No newline at end of file +// of the extension itself. Update this config type to your specific needs! + +// TODO: Rather than 2 duplicate types, how can we have a single config type here? +export interface ServerExtensionConfig extends _ServerExtensionConfig { + // react-router-style path to the new sample page + path?: string +} +export interface ReactExtensionConfig extends _ReactExtensionConfig { + // react-router-style path to the new sample page + path?: string +} diff --git a/packages/pwa-kit-dev/CHANGELOG.md b/packages/pwa-kit-dev/CHANGELOG.md index dd29d6fbbb..e55d53848b 100644 --- a/packages/pwa-kit-dev/CHANGELOG.md +++ b/packages/pwa-kit-dev/CHANGELOG.md @@ -1,6 +1,7 @@ ## v4.0.0-dev (Jun 21, 2024) - Replace `IApplicationExtension` with `ApplicationExtension` abstract class. [#2019](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2019) - Change Webpack logic to include all installed Application Extensions in the app bundle. [#2004](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2004) +- Support the tuples way of configuring the app extensions [#2010](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2010) ## v3.6.0 (Apr 17, 2024) - Implement core wildcard import logic to be used in upcoming webpack/babel plugins [#1826](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1826) diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 5b699ed8cc..2127bcb037 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -23,7 +23,7 @@ import OverridesResolverPlugin from './overrides-plugin' import {sdkReplacementPlugin} from './plugins' import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config-names' import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -import {buildAliases, nameRegex} from '../../utils/extensibility-utils' +import {buildAliases, getExtensionNames, nameRegex} from '../../utils/extensibility-utils' const projectDir = process.cwd() const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) @@ -589,7 +589,7 @@ const requestProcessor = // Don't mistake this with the concept of extensions for Webpack. const extensions = mode === 'production' - ? (appConfig?.extensions || []) + ? (getExtensionNames(appConfig?.extensions) || []) .map((extension) => { const setupServerFilePathBase = `${projectDir}/node_modules/${extension}/src/setup-server` const foundType = ['ts', 'js'].find((type) => diff --git a/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.js b/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.js index 2fc977cfad..9dd8d7b15b 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.js +++ b/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.js @@ -10,7 +10,7 @@ import {kebabToUpperCamelCase} from '../utils' import {nameRegex} from '../../../utils/extensibility-utils' const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' -const APP_EXTENSION_PREFIX = 'extension' +const APP_EXTENSION_PREFIX = 'extension' // aligns with what's in `nameRegex` /** * The `extensions-loader` as a mechanism to get all configured extensions for a given pwa-kit @@ -27,10 +27,6 @@ const APP_EXTENSION_PREFIX = 'extension' * @returns {string} The string representation of a module exporting all the named application extension modules. */ module.exports = function () { - // TODO: We need to account for extensions being tuples. Here we assume it's a simple - // string that is the npm package name, the only expectation is that the package name starts with `extension-`, - // it can be namespaced or not. We'll most likely want to create utilities for validation and parsing of the - // extensions configuration array when we add support for the tupal config format. const {pkg} = this.getOptions() || {} const {devDependencies} = pkg @@ -50,6 +46,7 @@ module.exports = function () { } }) + // TODO: later consider updating `normalizeExtensionsList` to use a util function return dedent` /* * Copyright (c) 2024, salesforce.com, inc. @@ -66,20 +63,35 @@ module.exports = function () { `import ${instanceVariable} from '${modulePath}'` ) .join('\n ')} - + + const installedExtensions = [ + ${extensionDetails + .map( + ({packageName, instanceVariable}) => + `{packageName: '${packageName}', instanceVariable: ${instanceVariable}}` + ) + .join(',\n ')} + ] + + const normalizeExtensionsList = (extensions = []) => + extensions.map((extension) => { + return { + packageName: Array.isArray(extension) ? extension[0] : extension, + config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} + } + }) + export const getExtensions = () => { - const configuredExtensions = getConfig()?.app?.extensions || [] + const configuredExtensions = (normalizeExtensionsList(getConfig()?.app?.extensions) || []) + .filter((extension) => extension.config.enabled) + .map((extension) => { + // Make sure that the configured extensions are installed, before instantiating them + const found = installedExtensions.find((ext) => ext.packageName === extension.packageName) + return found ? new found.instanceVariable(extension.config || {}) : false + }) + .filter(Boolean) - return [ - ${extensionDetails - .map(({instanceVariable, packageName}) => { - const config = {} // TODO: Parse config config here. - return `configuredExtensions.includes('${packageName}') ? new ${instanceVariable}(${JSON.stringify( - config - )}) : false` - }) - .join(',\n ')} - ].filter(Boolean) + return configuredExtensions } ` } diff --git a/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js b/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js index 9054f9e7eb..8b837888eb 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js +++ b/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js @@ -9,12 +9,10 @@ import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' import dedent from 'dedent' import compiler from './test/compiler' -import ExtensionLoader from './extensions-loader' - const mockConfig = { app: { extensions: [ - '@salesforce/extension-this', + ['@salesforce/extension-this', {path: '/foo'}], '@salesforce/extension-that', '@companyx/extension-another', 'extension-this' @@ -61,15 +59,32 @@ describe('Extension Loader', () => { import CompanyxAnother from '@companyx/extension-another/setup-app' import This from 'extension-this/setup-app' + const installedExtensions = [ + {packageName: '@salesforce/extension-this', instanceVariable: SalesforceThis}, + {packageName: '@salesforce/extension-that', instanceVariable: SalesforceThat}, + {packageName: '@companyx/extension-another', instanceVariable: CompanyxAnother}, + {packageName: 'extension-this', instanceVariable: This} + ] + + const normalizeExtensionsList = (extensions = []) => + extensions.map((extension) => { + return { + packageName: Array.isArray(extension) ? extension[0] : extension, + config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} + } + }) + export const getExtensions = () => { - const configuredExtensions = getConfig()?.app?.extensions || [] + const configuredExtensions = (normalizeExtensionsList(getConfig()?.app?.extensions) || []) + .filter((extension) => extension.config.enabled) + .map((extension) => { + // Make sure that the configured extensions are installed, before instantiating them + const found = installedExtensions.find((ext) => ext.packageName === extension.packageName) + return found ? new found.instanceVariable(extension.config || {}) : false + }) + .filter(Boolean) - return [ - configuredExtensions.includes('@salesforce/extension-this') ? new SalesforceThis({}) : false, - configuredExtensions.includes('@salesforce/extension-that') ? new SalesforceThat({}) : false, - configuredExtensions.includes('@companyx/extension-another') ? new CompanyxAnother({}) : false, - configuredExtensions.includes('extension-this') ? new This({}) : false - ].filter(Boolean) + return configuredExtensions } `) }) diff --git a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js index 2fce9abe06..e648ce0927 100644 --- a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js +++ b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js @@ -137,22 +137,33 @@ export const DevServerMixin = { _setupExtensions(app, options) { logger.info('Setting up extensions...') - // TODO: support extensions options array syntax i.e. ['extension-a', {}] - const extensions = options.mobify?.app?.extensions || [] + // Normalize the extensions list for easier parsing + const extensions = (options.mobify?.app?.extensions || []) + .map((extension) => { + return { + // TODO: later we'll consider reusing a util function or perhaps eliminate this + packageName: Array.isArray(extension) ? extension[0] : extension, + config: Array.isArray(extension) + ? {enabled: true, ...extension[1]} + : {enabled: true} + } + }) + .filter((extension) => extension.config.enabled) + logger.info('Extensions to load', { namespace: 'DevServerMixin._setupExtensions', additionalProperties: {extensions: extensions} }) - app.__extensions = extensions || [] + app.__extensions = extensions extensions.forEach((extension) => { - logger.info(`Loading extension: ${extension}`) + logger.info(`Loading extension: ${extension.packageName}`) const setupServerFilePathBase = path.join( options.projectDir, 'node_modules', - extension, + extension.packageName, 'src', 'setup-server' ) @@ -162,7 +173,7 @@ export const DevServerMixin = { } else if (fs.existsSync(`${setupServerFilePathBase}.js`)) { filePath = `${setupServerFilePathBase}.js` } else { - logger.warn(`No setup-server file found for ${extension}. Skipping.`) + logger.warn(`No setup-server file found for ${extension.packageName}. Skipping.`) return } @@ -171,7 +182,7 @@ export const DevServerMixin = { console.log('filePath, __filename: ', filePath, __filename) ExtensionClass = tsx.require(filePath, __filename).default } catch (e) { - logger.error(`Error loading extension ${extension}:`, { + logger.error(`Error loading extension ${extension.packageName}:`, { namespace: 'DevServerMixin._setupExtensions', additionalProperties: {error: e} }) @@ -186,7 +197,7 @@ export const DevServerMixin = { if (!isPrototype) { logger.error( - `'${extension}' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`, + `'${extension.packageName}' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`, { namespace: 'DevServerMixin._setupExtensions' } @@ -196,11 +207,11 @@ export const DevServerMixin = { let extensionInstance try { - logger.info(`Instantiating extension class for ${extension}...`) - extensionInstance = new ExtensionClass(options) - logger.info(`Successfully instantiated extension ${extension}.`) + logger.info(`Instantiating extension class for ${extension.packageName}...`) + extensionInstance = new ExtensionClass(extension.config) + logger.info(`Successfully instantiated extension ${extension.packageName}.`) } catch (e) { - logger.error(`Error instantiating extension ${extension}:`, { + logger.error(`Error instantiating extension ${extension.packageName}:`, { namespace: 'DevServerMixin._setupExtensions', additionalProperties: {error: e} }) @@ -209,11 +220,11 @@ export const DevServerMixin = { // Extend the app using the provided method try { - logger.info(`Extending app using extension ${extension}...`) + logger.info(`Extending app using extension ${extension.packageName}...`) app = extensionInstance.extendApp(app) - logger.info(`Successfully extended app with ${extension}.`) + logger.info(`Successfully extended app with ${extension.packageName}.`) } catch (e) { - logger.error(`Error setting extension ${extension}:`, { + logger.error(`Error setting extension ${extension.packageName}:`, { namespace: 'DevServerMixin._setupExtensions', additionalProperties: {error: e} }) diff --git a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.test.js b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.test.js index cdc947f638..df81f90a91 100644 --- a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.test.js +++ b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.test.js @@ -817,6 +817,43 @@ describe('extensions', () => { }) }) + test('mixed types in extensions configuration', async () => { + const options = opts({ + mobify: {app: {extensions: [['test-extension', {path: '/foo'}], 'another-extension']}} + }) + const app = NoWebpackDevServerFactory._createApp(options) + expect(app.__extensions).toBeDefined() + + await request(app) + .get('/test-extension') + .expect(200) + .then((res) => { + expect(res.text).toBe('test') + }) + + await request(app) + .get('/another-extension') + .expect(200) + .then((res) => { + expect(res.text).toBe('test') + }) + + await request(app) + .get('/test-extension-config') + .expect(200) + .then((res) => { + // The config should have {enabled: true} by default + expect(res.text).toBe('{"enabled":true,"path":"/foo"}') + }) + }) + + test('disabled extension will not run', () => { + const options = opts({mobify: {app: {extensions: [['test-extension', {enabled: false}]]}}}) + const app = NoWebpackDevServerFactory._createApp(options) + expect(app.__extensions).toBeDefined() + return request(app).get('/test-extension').expect(404) + }) + test('logs warning when setup-server file is not found', () => { const warn = jest.spyOn(console, 'warn').mockImplementation(() => {}) const app = NoWebpackDevServerFactory._createApp( diff --git a/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/setup-server.js b/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/setup-server.js deleted file mode 100644 index 8e13312b29..0000000000 --- a/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/setup-server.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import {ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' -console.log('ApplicationExtension ApplicationExtension ApplicationExtension: ', ApplicationExtension) -class TestExtension extends ApplicationExtension { - extendApp(app) { - app.get('/test-extension', (req, res) => { - res.send('test') - }) - - return app - } -} - -export default TestExtension diff --git a/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/src/setup-server.js b/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/src/setup-server.js index 5bd0e1565f..998c615fcb 100644 --- a/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/src/setup-server.js +++ b/packages/pwa-kit-dev/src/ssr/server/test_fixtures/node_modules/test-extension/src/setup-server.js @@ -11,6 +11,10 @@ class TestExtension extends ApplicationExtension{ app.get('/test-extension', (req, res) => { res.send('test') }) + app.get('/test-extension-config', (req, res) => { + const config = JSON.stringify(this.getConfig()) + res.send(config) + }) return app } diff --git a/packages/pwa-kit-dev/src/utils/extensibility-utils.js b/packages/pwa-kit-dev/src/utils/extensibility-utils.js index a0d0839e13..d815d626ae 100644 --- a/packages/pwa-kit-dev/src/utils/extensibility-utils.js +++ b/packages/pwa-kit-dev/src/utils/extensibility-utils.js @@ -31,7 +31,7 @@ const SUPPORTED_FILE_TYPES = ['.ts', '.js'] export const buildAliases = (extensions = []) => { const projectDir = process.cwd() - const aliases = extensions.reduce((acc, extension) => { + const aliases = getExtensionNames(extensions).reduce((acc, extension) => { const basePath = path.join( projectDir, 'node_modules', @@ -100,3 +100,12 @@ export const findFileWithExtension = (basePath, extensions = []) => { * .filter(Boolean) */ export const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ + +/** + * @private + */ +export const getExtensionNames = (extensions) => { + return (extensions || []).map((extension) => { + return Array.isArray(extension) ? extension[0] : extension + }) +} diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 9cd71c0849..99ac107602 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -63,6 +63,7 @@ export const expand = (extensions = []) => // Do nothing break default: + // TODO: revise this to be more aligned with `nameRegex` in extensibility-utils.js (e.g. namespace is now optional) // Default is to treat the reference as a extension "short" name. nameRef = `${EXTENSION_NAMESPACE}/${EXTENSION_PREFIX}-${nameRef}` break diff --git a/packages/pwa-kit-react-sdk/CHANGELOG.md b/packages/pwa-kit-react-sdk/CHANGELOG.md index 59c7e163d8..15652d58ea 100644 --- a/packages/pwa-kit-react-sdk/CHANGELOG.md +++ b/packages/pwa-kit-react-sdk/CHANGELOG.md @@ -1,5 +1,6 @@ ## v4.0.0-dev (Jun 21, 2024) - Update Application Extensions import in `react-rendering.js` and `main.js` (#2004)[https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2004] +- Define interface of the app extension's config [#2010](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2010) ## v3.7.0 (Aug 07, 2024) - Add `beforeHydrate` option to withReactQuery component [#1912](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1912) diff --git a/packages/pwa-kit-react-sdk/package.json b/packages/pwa-kit-react-sdk/package.json index 4faf46e8f9..80b8bbabd6 100644 --- a/packages/pwa-kit-react-sdk/package.json +++ b/packages/pwa-kit-react-sdk/package.json @@ -22,8 +22,8 @@ "storefront-preview" ], "scripts": { - "build": "cross-env NODE_ENV=production internal-lib-build build & tsc", - "build:watch": "nodemon --watch 'src/**' --exec 'npm run build'", + "build": "cross-env NODE_ENV=production internal-lib-build build && tsc", + "build:watch": "nodemon --watch 'src/**' --ext 'js,jsx,ts,tsx' --exec 'npm run build'", "format": "internal-lib-build format \"**/*.{js,jsx,ts,tsx}\"", "lint": "npm run lint:js", "lint:fix": "npm run lint:js -- --fix", diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts index a1fe29aad3..66749be232 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts @@ -15,15 +15,15 @@ import {IRouteConfig} from './types' * * @abstract */ -export default abstract class ApplicationExtension { - private config: Record +export default abstract class ApplicationExtension { + private config: Config /** * Constructs a new instance of the ApplicationExtension class. * * @param config - The configuration object used to set up the extension. */ - constructor(config?: any) { + constructor(config: Config) { this.config = config } @@ -33,7 +33,7 @@ export default abstract class ApplicationExtension { * @protected * @returns config - The configuration object. */ - public getConfig(): Record { + public getConfig(): Config { return this.config } diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts index f47e6f6aec..60b4b8efdb 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts @@ -5,10 +5,10 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import ApplicationExtension from './application-extension' +// This file exports an empty function. During local development and the production build process, +// it'll be replaced to return those application extensions configured by the base PWA-Kit project. +const getExtensions = () => {} -// This file exports the default extensions object, which is empty. During local development and the production -// build process, this object is replaced with those application extensions configured by the base PWA-Kit project. -const extensions: ApplicationExtension[] = [] - -export default extensions +export default { + getExtensions +} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts index 4dfdddd854..54c8035fc4 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts @@ -13,3 +13,7 @@ export interface IRouteConfig { exact?: boolean component: React.ComponentType } + +export interface ApplicationExtensionConfig extends Record { + enabled: boolean +} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts index 8e0141be85..09b485ff97 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts @@ -8,6 +8,7 @@ import React from 'react' import {applyHOCs} from '../utils' import ApplicationExtension from './application-extension' +import {ApplicationExtensionConfig} from './types' /** * Given the provided Application, apply all the App extensions to it. @@ -16,12 +17,9 @@ import ApplicationExtension from './application-extension' */ export const applyAppExtensions = ( App: React.ComponentType, - extensions: ApplicationExtension[] + extensions: ApplicationExtension[] ): React.ComponentType => { const extendAppHocs = extensions - // TODO: All Application Extensions configuration objects will extend from a single IApplicationExtensionConfig type so that we - // can add a feature to toggle if the extension is enabled or disabled. This will happen in the tupal config support ticket. - // .map((extension) => extension.getConfig().enabled && extension.extendApp) .map((extension) => extension.extendApp.bind(extension)) .filter(Boolean) diff --git a/packages/pwa-kit-runtime/CHANGELOG.md b/packages/pwa-kit-runtime/CHANGELOG.md index 2cbc3c63b6..b3e8edd1ee 100644 --- a/packages/pwa-kit-runtime/CHANGELOG.md +++ b/packages/pwa-kit-runtime/CHANGELOG.md @@ -1,5 +1,7 @@ ## v4.0.0-dev (Jun 21, 2024) - Replace `IApplicationExtension` with `ApplicationExtension` abstract class. [#2019](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2019) +- Define interface of the app extension's config [#2010](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2010) +- Support the tuples way of configuring the app extensions [#2010](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2010) ## v3.7.0 (Aug 07, 2024) diff --git a/packages/pwa-kit-runtime/package.json b/packages/pwa-kit-runtime/package.json index e712407c0d..0079ee0851 100644 --- a/packages/pwa-kit-runtime/package.json +++ b/packages/pwa-kit-runtime/package.json @@ -20,7 +20,7 @@ ], "scripts": { "build": "cross-env NODE_ENV=production internal-lib-build build && tsc", - "build:watch": "nodemon --watch 'src/**' --exec 'npm run build'", + "build:watch": "nodemon --watch 'src/**' --ext 'js,jsx,ts,tsx' --exec 'npm run build'", "format": "internal-lib-build format \"**/*.{js,jsx}\"", "lint": "npm run lint:js", "lint:fix": "npm run lint:js -- --fix", diff --git a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js index 14ae28d836..90a4255755 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js +++ b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js @@ -662,8 +662,19 @@ export const RemoteServerFactory = { _setupExtensions(app, options) { logger.info('Setting up extensions...') - // TODO: support extensions options array syntax i.e. ['extension-a', {}] - const extensions = options.mobify?.app?.extensions || [] + // Normalize the extensions list for easier parsing + const extensions = (options.mobify?.app?.extensions || []) + .map((extension) => { + return { + // TODO: later we'll consider reusing a util function or perhaps eliminate this + packageName: Array.isArray(extension) ? extension[0] : extension, + config: Array.isArray(extension) + ? {enabled: true, ...extension[1]} + : {enabled: true} + } + }) + .filter((extension) => extension.config.enabled) + logger.info('Extensions to load', { namespace: 'RemoteServerFactory._setupExtensions', additionalProperties: {extensions: extensions} @@ -674,12 +685,12 @@ export const RemoteServerFactory = { let _require extensions.forEach((extension) => { - logger.info(`Loading extension: ${extension}`) + logger.info(`Loading extension: ${extension.packageName}`) const setupServerFilePath = path.join( options.buildDir, 'extensions', - extension, + extension.packageName, 'setup-server.js' ) @@ -695,11 +706,13 @@ export const RemoteServerFactory = { ExtensionClass = _require(setupServerFilePath).default } catch (e) { if (e.message && e.message.startsWith('Cannot find module')) { - logger.warn(`No setup-server.js file found for ${extension}. Skipping.`) + logger.warn( + `No setup-server.js file found for ${extension.packageName}. Skipping.` + ) return } - logger.error(`Error loading extension ${extension}:`, { + logger.error(`Error loading extension ${extension.packageName}:`, { namespace: 'RemoteServerFactory._setupExtensions', additionalProperties: {error: e} }) @@ -714,7 +727,7 @@ export const RemoteServerFactory = { if (!isPrototype) { logger.error( - `'${extension}' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`, + `'${extension.packageName}' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`, { namespace: 'RemoteServerFactory._setupExtensions' } @@ -724,11 +737,11 @@ export const RemoteServerFactory = { let extensionInstance try { - logger.info(`Instantiating extension class for ${extension}...`) - extensionInstance = new ExtensionClass(options) - logger.info(`Successfully instantiated extension ${extension}.`) + logger.info(`Instantiating extension class for ${extension.packageName}...`) + extensionInstance = new ExtensionClass(extension.config) + logger.info(`Successfully instantiated extension ${extension.packageName}.`) } catch (e) { - logger.error(`Error instantiating extension ${extension}:`, { + logger.error(`Error instantiating extension ${extension.packageName}:`, { namespace: 'RemoteServerFactory._setupExtensions', additionalProperties: {error: e} }) @@ -737,11 +750,11 @@ export const RemoteServerFactory = { // Extend the app using the provided method try { - logger.log(`Extending app using extension ${extension}...`) + logger.log(`Extending app using extension ${extension.packageName}...`) app = extensionInstance.extendApp(app) - logger.log(`Successfully extended app with ${extension}.`) + logger.log(`Successfully extended app with ${extension.packageName}.`) } catch (e) { - logger.error(`Error setting extension ${extension}:`, { + logger.error(`Error setting extension ${extension.packageName}:`, { namespace: 'RemoteServerFactory._setupExtensions', additionalProperties: {error: e} }) diff --git a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js index 45bae00643..8b4e77651a 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js +++ b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.test.js @@ -105,6 +105,43 @@ describe('extensions', () => { }) }) + test('mixed types in extensions configuration', async () => { + const options = opts({ + mobify: {app: {extensions: [['test-extension', {path: '/foo'}], 'another-extension']}} + }) + const app = RemoteServerFactory._createApp(options) + expect(app.__extensions).toBeDefined() + + await request(app) + .get('/test-extension') + .expect(200) + .then((res) => { + expect(res.text).toBe('test') + }) + + await request(app) + .get('/another-extension') + .expect(200) + .then((res) => { + expect(res.text).toBe('test') + }) + + await request(app) + .get('/test-extension-config') + .expect(200) + .then((res) => { + // The config should have {enabled: true} by default + expect(res.text).toBe('{"enabled":true,"path":"/foo"}') + }) + }) + + test('disabled extension will not run', () => { + const options = opts({mobify: {app: {extensions: [['test-extension', {enabled: false}]]}}}) + const app = RemoteServerFactory._createApp(options) + expect(app.__extensions).toBeDefined() + return request(app).get('/test-extension').expect(404) + }) + test('logs warning when setup-server.js file is not found', () => { const warn = jest.spyOn(console, 'warn').mockImplementation(() => {}) const app = RemoteServerFactory._createApp( diff --git a/packages/pwa-kit-runtime/src/ssr/server/extensibility/application-extension.ts b/packages/pwa-kit-runtime/src/ssr/server/extensibility/application-extension.ts index c102438d7b..bb70facaf7 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/extensibility/application-extension.ts +++ b/packages/pwa-kit-runtime/src/ssr/server/extensibility/application-extension.ts @@ -15,15 +15,15 @@ import {Application} from './types' * * @abstract */ -export default abstract class ApplicationExtension { - private config: Record +export default abstract class ApplicationExtension { + private config: Config /** * Constructs a new instance of the ApplicationExtension class. * * @param config - The configuration object used to set up the extension. */ - constructor(config?: any) { + constructor(config: Config) { this.config = config } @@ -33,7 +33,7 @@ export default abstract class ApplicationExtension { * @protected * @returns config - The configuration object. */ - public getConfig(): Record { + public getConfig(): Config { return this.config } diff --git a/packages/pwa-kit-runtime/src/ssr/server/extensibility/types.ts b/packages/pwa-kit-runtime/src/ssr/server/extensibility/types.ts index 544fcf881f..fcba920ed6 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/extensibility/types.ts +++ b/packages/pwa-kit-runtime/src/ssr/server/extensibility/types.ts @@ -7,3 +7,7 @@ import {Application} from 'express' export type {Application} + +export interface ApplicationExtensionConfig extends Record { + enabled: boolean +} diff --git a/packages/pwa-kit-runtime/src/ssr/server/test_fixtures/extensions/test-extension/setup-server.js b/packages/pwa-kit-runtime/src/ssr/server/test_fixtures/extensions/test-extension/setup-server.js index f5abfb04b2..11b354f32c 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/test_fixtures/extensions/test-extension/setup-server.js +++ b/packages/pwa-kit-runtime/src/ssr/server/test_fixtures/extensions/test-extension/setup-server.js @@ -16,6 +16,10 @@ class TestExtension extends ApplicationExtension { app.get('/test-extension', (req, res) => { res.send('test') }) + app.get('/test-extension-config', (req, res) => { + const config = JSON.stringify(this.getConfig()) + res.send(config) + }) return app } diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index fb77e02dfa..33c5aaf874 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -38,8 +38,10 @@ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" }, "mobify": { - "app":{ - "extensions": ["@salesforce/extension-sample"] + "app": { + "extensions": [ + ["@salesforce/extension-sample", {"path": "/foo-page"}] + ] }, "ssrEnabled": true, "ssrOnly": [ From 1972fb745fce00e2f610951f1327ce8910a883e5 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 24 Sep 2024 14:10:10 -0700 Subject: [PATCH 120/929] Fix sample extensions and fix resolve code --- packages/extension-chakra-ui/package.json | 1 + packages/extension-chakra-ui/src/setup-app.ts | 16 +++------- .../extension-chakra-ui/src/setup-server.ts | 23 +++++++++++--- packages/extension-sample-2/package.json | 1 + .../extension-sample-2/src/setup-server.ts | 23 +++++++++++--- .../plugins/overrides-resolver-plugin.test.js | 30 +++++++++++++++++++ .../src/ssr/server/build-dev-server.js | 1 - .../pwa-kit-dev/src/utils/resolver-utils.js | 15 ++++------ 8 files changed, 79 insertions(+), 31 deletions(-) diff --git a/packages/extension-chakra-ui/package.json b/packages/extension-chakra-ui/package.json index d6be456895..447481de18 100644 --- a/packages/extension-chakra-ui/package.json +++ b/packages/extension-chakra-ui/package.json @@ -18,6 +18,7 @@ "devDependencies": { "@loadable/component": "^5.15.3", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "react": "^18.2.0", diff --git a/packages/extension-chakra-ui/src/setup-app.ts b/packages/extension-chakra-ui/src/setup-app.ts index b55b1549fb..c1827e0cd2 100644 --- a/packages/extension-chakra-ui/src/setup-app.ts +++ b/packages/extension-chakra-ui/src/setup-app.ts @@ -6,21 +6,13 @@ */ import React from 'react' -import {IApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility/types' -import {IConfig} from './types' -import withChakraUI from './components/with-chakra-ui' +import {ApplicationExtension} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' +import {IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility/types' -class Sample implements IApplicationExtension { - private config: IConfig; +import withChakraUI from './components/with-chakra-ui' - constructor(config: IConfig) { - this.config = config - } +class Sample extends ApplicationExtension { - getName(): string { - return 'sample' - } - extendApp(App: React.ComponentType): React.ComponentType { return withChakraUI(App) } diff --git a/packages/extension-chakra-ui/src/setup-server.ts b/packages/extension-chakra-ui/src/setup-server.ts index 64b365a0e8..8355d9ed14 100644 --- a/packages/extension-chakra-ui/src/setup-server.ts +++ b/packages/extension-chakra-ui/src/setup-server.ts @@ -4,7 +4,22 @@ * 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 */ -/* istanbul ignore next */ -export default ({app}) => { - console.log('Setup Server App') -} \ No newline at end of file +import { + Application as ExpressApplication, + ApplicationExtension as ExpressApplicationExtension +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' + +class ChakraUI extends ExpressApplicationExtension { + + extendApp(app: ExpressApplication): ExpressApplication { + + app.get('/sample', (req, res) => { + console.log('SampleExtension extendApp GET /sample') + res.send('Hello from an express SampleExtension!') + }) + + return app + } +} + +export default ChakraUI diff --git a/packages/extension-sample-2/package.json b/packages/extension-sample-2/package.json index 00c7847f37..7dbffd12da 100644 --- a/packages/extension-sample-2/package.json +++ b/packages/extension-sample-2/package.json @@ -12,6 +12,7 @@ "devDependencies": { "@loadable/component": "^5.15.3", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "react": "^18.2.0", diff --git a/packages/extension-sample-2/src/setup-server.ts b/packages/extension-sample-2/src/setup-server.ts index 64b365a0e8..7d4ec19712 100644 --- a/packages/extension-sample-2/src/setup-server.ts +++ b/packages/extension-sample-2/src/setup-server.ts @@ -4,7 +4,22 @@ * 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 */ -/* istanbul ignore next */ -export default ({app}) => { - console.log('Setup Server App') -} \ No newline at end of file +import { + Application as ExpressApplication, + ApplicationExtension as ExpressApplicationExtension +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' + +class SampleExtension2 extends ExpressApplicationExtension { + + extendApp(app: ExpressApplication): ExpressApplication { + + app.get('/sample-2', (req, res) => { + console.log('SampleExtension extendApp GET /sample') + res.send('Hello from an express SampleExtension!') + }) + + return app + } +} + +export default SampleExtension2 diff --git a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js index 5801ab0453..97468abbf3 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js +++ b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js @@ -69,6 +69,36 @@ describe('Overrides Resolver Plugin', () => { expect(output.modules[1].source).toBe('// @salesforce/extension-this') } }, + { + description: + 'Wildcard import pioritizes module resolution to the "overrides" folder if match import exists.', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-that', '@salesforce/extension-this'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'`, + + // Overrides + + // Local Files + '/virtual/project/app/pages/sample-page.jsx': '// Sample Page', + + // Extensions Overrides + '/virtual/project/node_modules/@salesforce/extension-this/src/pages/sample-page.jsx': + '// @salesforce/extension-this', + '/virtual/project/node_modules/@salesforce/extension-this/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-this-override' + // TODO: Why don't index files work here? + } + }, + expects: (output) => { + expect(output.modules[1].source).toBe('// @salesforce/extension-this-override') + } + }, { description: 'Wildcard import throws when no match is found.', entryPoint: 'app/routes.jsx', diff --git a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js index 2fce9abe06..a10cce3941 100644 --- a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js +++ b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js @@ -168,7 +168,6 @@ export const DevServerMixin = { let ExtensionClass try { - console.log('filePath, __filename: ', filePath, __filename) ExtensionClass = tsx.require(filePath, __filename).default } catch (e) { logger.error(`Error loading extension ${extension}:`, { diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 9eb80e41a8..29c7b13e29 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -98,17 +98,12 @@ export const buildCandidatePaths = (importPath, sourcePath, opts = {}) => { let paths = expand(extensions).reverse() // Map all the extensions and resolve the module names to absolute paths. - paths = paths.map((extension) => { + paths = paths.reduce((acc, extensionEntry) => { // The reference can be a module/package or an absolute path to a file. - const [extensionRef] = extension - const isLocalExtension = extensionRef.startsWith(path.sep) - - return path.join( - ...(isLocalExtension - ? [extensionRef, importPath] - : [projectDir, NODE_MODULES, extensionRef, SRC, OVERRIDES, importPath]) - ) - }) + const [extensionRef] = extensionEntry + const srcPath = path.join(projectDir, NODE_MODULES, extensionRef, SRC) + return [...acc, path.join(srcPath, OVERRIDES, importPath), path.join(srcPath, importPath)] + }, []) // Add non-extension search locations locations. The base project and the sdk as the final callback. paths = [ From a600ffe9462c852155fa80e64db2a2d3b7b5d681 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 24 Sep 2024 14:37:39 -0700 Subject: [PATCH 121/929] Remove remaining references to ccExtensibility Also add temporary alias in webpack for the retail project --- packages/pwa-kit-dev/src/configs/webpack/config.js | 3 +++ packages/template-retail-react-app/package.json | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 0f7be465af..6707edc2af 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -188,6 +188,9 @@ const baseConfig = (target) => { ], extensions: SUPPORTED_FILE_EXTENSIONS, alias: { + // TODO: This alias is temporary. When we investigate turning the retail template into an application extension + // we'll have to decide if we want to continue using an alias, or change back to using relative paths. + '@salesforce/retail-react-app': projectDir, // Create alias's for "all" extensions, enabled or disabled, as they as they are being imported from the SDK package // and cannot be resolved from that location. We create alias's for all because we do not know which extensions // are configured at build time. diff --git a/packages/template-retail-react-app/package.json b/packages/template-retail-react-app/package.json index 8e4aace9f1..c824be793a 100644 --- a/packages/template-retail-react-app/package.json +++ b/packages/template-retail-react-app/package.json @@ -3,11 +3,6 @@ "version": "4.1.0-dev", "license": "See license in LICENSE", "author": "cc-pwa-kit@salesforce.com", - "ccExtensibility": { - "extendable": [ - "@salesforce/retail-react-app" - ] - }, "scripts": { "analyze-build": "cross-env MOBIFY_ANALYZE=true npm run build", "build": "npm run build-translations && pwa-kit-dev build", From 6c5a10a012dfa76c88629cd329a41db892e0466a Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 24 Sep 2024 14:58:11 -0700 Subject: [PATCH 122/929] Fix resolve util to account for doubling the search paths --- .../pwa-kit-dev/src/utils/resolver-utils.js | 2 +- .../src/utils/resolver-utils.test.js | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index aac35c9a3e..9873428ce5 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -131,7 +131,7 @@ export const buildCandidatePaths = (importPath, sourcePath, opts = {}) => { // NOTE: Overriding files requires that you use the exact file name, you cannot replace a non-index file with one that // is an index file. const index = paths.indexOf(sourcePath.split('.')[0]) - paths = paths.slice(index + 1) + paths = paths.slice(index + 2) } return paths diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index 7dfa9fc92a..662c27c1d4 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -157,6 +157,15 @@ describe('resolverUtils', () => { 'app', 'routes' ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-c', + 'src', + 'app', + 'routes' + ), path.join( process.cwd(), 'node_modules', @@ -167,6 +176,15 @@ describe('resolverUtils', () => { 'app', 'routes' ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-b', + 'src', + 'app', + 'routes' + ), path.join( process.cwd(), 'node_modules', @@ -176,6 +194,15 @@ describe('resolverUtils', () => { 'overrides', 'app', 'routes' + ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-a', + 'src', + 'app', + 'routes' ) // NOTE: This has been removed at we currently aren't using the `overrides-resolver-plugin` to resolve special components. // path.join( @@ -214,6 +241,15 @@ describe('resolverUtils', () => { 'overrides', 'app', 'routes' + ), + path.join( + process.cwd(), + 'node_modules', + '@salesforce', + 'extension-module-extension-a', + 'src', + 'app', + 'routes' ) // NOTE: This has been removed at we currently aren't using the `overrides-resolver-plugin` to resolve special components. // path.join( From 00b54cbcb3c7c911b132308e2e33116c7ab1a3a9 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Wed, 25 Sep 2024 15:51:00 -0700 Subject: [PATCH 123/929] Cleanup --- packages/extension-sample-2/src/setup-app.ts | 6 +++++- packages/pwa-kit-dev/src/configs/webpack/config.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/extension-sample-2/src/setup-app.ts b/packages/extension-sample-2/src/setup-app.ts index 025bb5a2f1..55c12aca0c 100644 --- a/packages/extension-sample-2/src/setup-app.ts +++ b/packages/extension-sample-2/src/setup-app.ts @@ -9,12 +9,16 @@ import React from 'react' import loadable from '@loadable/component' import {IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility/types' import {ApplicationExtension} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' + +// Project Imports import withRedBorder from './components/with-red-border' +import {IConfig as Config} from './types' + const SamplePage = loadable(() => import('./pages/sample-2')) const defaultPath: string = '/sample-page-2' -class Sample extends ApplicationExtension { +class Sample extends ApplicationExtension { extendApp(App: React.ComponentType): React.ComponentType { return withRedBorder(App) diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 6707edc2af..d245a4d8cf 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -250,7 +250,7 @@ const baseConfig = (target) => { } }, { - test: /universal\/extensibility\/extensions/, + test: /universal[\\/]+extensibility[\\/]+extensions/, loader: `@salesforce/pwa-kit-dev/configs/webpack/loaders/extensions-loader`, options: { pkg From 2de3ecd2ca780ae21d9c3170d1f87f4618369046 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Wed, 25 Sep 2024 16:24:45 -0700 Subject: [PATCH 124/929] Remove remnants of specialized get entry point code --- packages/pwa-kit-dev/bin/pwa-kit-dev.js | 32 ++++++------------- .../app/pages/home.tsx | 2 +- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/packages/pwa-kit-dev/bin/pwa-kit-dev.js b/packages/pwa-kit-dev/bin/pwa-kit-dev.js index e07e4e30b7..971ac6de97 100755 --- a/packages/pwa-kit-dev/bin/pwa-kit-dev.js +++ b/packages/pwa-kit-dev/bin/pwa-kit-dev.js @@ -59,17 +59,8 @@ const getProjectName = async () => { return projectPkg.name } -const getAppEntrypoint = async () => { - const defaultPath = p.join(process.cwd(), 'app', 'ssr.js') - if (await fse.pathExists(defaultPath)) return defaultPath - - const projectPkg = await scriptUtils.getProjectPkg() - const {overridesDir} = projectPkg?.ccExtensibility ?? {} - if (!overridesDir || typeof overridesDir !== 'string') return null - - const overridePath = p.join(process.cwd(), p.sep + overridesDir, 'app', 'ssr.js') - if (await fse.pathExists(overridePath)) return overridePath - return null +const getAppEntrypoint = () => { + return p.join(process.cwd(), 'app', 'ssr.js') } const main = async () => { @@ -248,18 +239,15 @@ const main = async () => { 'babel-node' ) - const entrypoint = await getAppEntrypoint() - if (!entrypoint) { - error('Could not determine app entrypoint.') - process.exit(1) - } - - execSync(`${babelNode} ${inspect ? '--inspect' : ''} ${babelArgs} ${entrypoint}`, { - env: { - ...process.env, - ...(noHMR ? {HMR: 'false'} : {}) + execSync( + `${babelNode} ${inspect ? '--inspect' : ''} ${babelArgs} ${getAppEntrypoint()}`, + { + env: { + ...process.env, + ...(noHMR ? {HMR: 'false'} : {}) + } } - }) + ) }) program diff --git a/packages/template-typescript-minimal/app/pages/home.tsx b/packages/template-typescript-minimal/app/pages/home.tsx index c223db97fe..060c870715 100644 --- a/packages/template-typescript-minimal/app/pages/home.tsx +++ b/packages/template-typescript-minimal/app/pages/home.tsx @@ -128,7 +128,7 @@ const Home = ({value}: Props) => { Create your account - Sample Page + Sample Page
Sample Page 2
From 51069483794610146a2f970cefbb865b9e3bbc5f Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 26 Sep 2024 08:54:31 -0700 Subject: [PATCH 125/929] Adjusted resolver to include base project override folder --- .../plugins/overrides-resolver-plugin.test.js | 36 ++++++++++++++----- .../pwa-kit-dev/src/utils/resolver-utils.js | 1 + .../src/utils/resolver-utils.test.js | 1 + 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js index 97468abbf3..9cb094dfba 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js +++ b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.test.js @@ -11,7 +11,7 @@ import OverridesResolverPlugin from './overrides-resolver-plugin' describe('Overrides Resolver Plugin', () => { const testCases = [ { - description: 'Wildcard import resolved to correct extension override', + description: 'Wildcard import resolves to correct base project file', entryPoint: 'app/routes.jsx', // Compiler configuration. compilerConfig: { @@ -25,7 +25,33 @@ describe('Overrides Resolver Plugin', () => { // Overrides // Local Files - '/virtual/project/app/pages/sample-page.jsx': '// Sample Page', + '/virtual/project/app/pages/sample-page.jsx': '// Base Project - Sample Page', + + // Extensions Overrides + '/virtual/project/node_modules/@salesforce/extension-that/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-that', + '/virtual/project/node_modules/@salesforce/extension-this/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-this' + // TODO: Why don't index files work here? + } + }, + expects: (output) => { + expect(output.modules[1].source).toBe('// Base Project - Sample Page') + } + }, + { + description: 'Wildcard import resolved to correct extension override', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-this', '@salesforce/extension-that'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'`, + + // Overrides // Extensions Overrides '/virtual/project/node_modules/@salesforce/extension-that/src/overrides/pages/sample-page.jsx': @@ -54,9 +80,6 @@ describe('Overrides Resolver Plugin', () => { // Overrides - // Local Files - '/virtual/project/app/pages/sample-page.jsx': '// Sample Page', - // Extensions Overrides '/virtual/project/node_modules/@salesforce/extension-that/src/overrides/pages/sample-page.jsx': '// @salesforce/extension-that', @@ -84,9 +107,6 @@ describe('Overrides Resolver Plugin', () => { // Overrides - // Local Files - '/virtual/project/app/pages/sample-page.jsx': '// Sample Page', - // Extensions Overrides '/virtual/project/node_modules/@salesforce/extension-this/src/pages/sample-page.jsx': '// @salesforce/extension-this', diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-dev/src/utils/resolver-utils.js index 9873428ce5..c8396abe56 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.js @@ -110,6 +110,7 @@ export const buildCandidatePaths = (importPath, sourcePath, opts = {}) => { paths = [ // Base Project path.join(projectDir, APP, OVERRIDES, importPath), + path.join(projectDir, APP, importPath), // Extensions ...paths, // SDK diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index 662c27c1d4..1a6952862b 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -147,6 +147,7 @@ describe('resolverUtils', () => { extensions: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ path.join(process.cwd(), 'app', 'overrides', 'app', 'routes'), + path.join(process.cwd(), 'app', 'app', 'routes'), path.join( process.cwd(), 'node_modules', From 5377221fca89f031cca5ed43e67515ca6f18f1ba Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 26 Sep 2024 09:03:50 -0700 Subject: [PATCH 126/929] Update packages/pwa-kit-dev/src/configs/webpack/config.js Co-authored-by: Adam Raya Signed-off-by: Ben Chypak --- packages/pwa-kit-dev/src/configs/webpack/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index d245a4d8cf..118abe3cc1 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -91,7 +91,7 @@ const getBundleAnalyzerPlugin = (name = 'report', pluginOptions) => }) const entryPointExists = (segments) => { - for (let ext of ['.js', '.jsx', '.ts', '.tsx']) { + for (let ext of SUPPORTED_FILE_EXTENSIONS) { const p = resolve(projectDir, ...segments) + ext if (fse.existsSync(p)) { return true From 68f5459e62c4ce86afb9b39ad149547b06649a0f Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 26 Sep 2024 09:34:13 -0700 Subject: [PATCH 127/929] PR feedback --- .../plugins/overrides-resolver-plugin.js | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js index 791e26e22b..08c6ddcb96 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js +++ b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js @@ -31,35 +31,38 @@ class OverridesResolverPlugin { callback() return } - const target = resolver.ensureHook('resolved') const importPath = request.request const sourcePath = request.context.issuer // Resolve the import with the provided packageIterator. - const modulePath = resolve(importPath, { - basedir: this.projectDir, - extensions: this.fileExtensions, - packageIterator: () => - buildCandidatePaths(importPath, sourcePath, { - extensions: this.extensions, - projectDir: this.projectDir - }), - ...this.resolveOptions - }) - - if (modulePath) { - // Update the requests path with the one resoved from above. - request.path = modulePath - - resolver.doResolve( - target, - request, - `${this.constructor.name} found base override file`, - resolveContext, - callback - ) + let modulePath + + try { + modulePath = resolve(importPath, { + basedir: this.projectDir, + extensions: this.fileExtensions, + packageIterator: () => + buildCandidatePaths(importPath, sourcePath, { + extensions: this.extensions, + projectDir: this.projectDir + }), + ...this.resolveOptions + }) + } catch (e) { + return callback(e) } + + // Update the requests path with the one resoved from above. + request.path = modulePath + + resolver.doResolve( + target, + request, + `${this.constructor.name} found base override file`, + resolveContext, + callback + ) } apply(resolver) { From bf0e9911e7bd9276f100c967653c42fe364e9f56 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 26 Sep 2024 09:37:03 -0700 Subject: [PATCH 128/929] PR feedback --- .../configs/webpack/plugins/overrides-resolver-plugin.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js index 08c6ddcb96..6fc0804e09 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js +++ b/packages/pwa-kit-dev/src/configs/webpack/plugins/overrides-resolver-plugin.js @@ -19,7 +19,7 @@ export const DEFAULT_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.json'] */ class OverridesResolverPlugin { constructor(options) { - this.projectDir = options.projectDir?.replace(/\\/g, '/') + this.projectDir = options.projectDir?.replace(/\\/g, '/') || process.cwd() this.extensions = options.extensions || [] this.fileExtensions = options.fileExtensions || DEFAULT_FILE_EXTENSIONS this.resolveOptions = options.resolveOptions || {} @@ -37,7 +37,7 @@ class OverridesResolverPlugin { // Resolve the import with the provided packageIterator. let modulePath - + try { modulePath = resolve(importPath, { basedir: this.projectDir, @@ -52,7 +52,7 @@ class OverridesResolverPlugin { } catch (e) { return callback(e) } - + // Update the requests path with the one resoved from above. request.path = modulePath From 0c587537b0bdaa4f84a51256a7d416ac22cca646 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 27 Sep 2024 09:01:45 -0700 Subject: [PATCH 129/929] Fix typo in test --- packages/pwa-kit-dev/src/utils/resolver-utils.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index 1a6952862b..2cef6d7b05 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -147,7 +147,7 @@ describe('resolverUtils', () => { extensions: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ path.join(process.cwd(), 'app', 'overrides', 'app', 'routes'), - path.join(process.cwd(), 'app', 'app', 'routes'), + path.join(process.cwd(), 'app', 'routes'), path.join( process.cwd(), 'node_modules', From a224f5b6329021751916f1e8f111d7b8e8803d90 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 27 Sep 2024 11:03:50 -0700 Subject: [PATCH 130/929] Update to use real world example --- .../src/utils/resolver-utils.test.js | 136 +++++++++--------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js index 2cef6d7b05..09824be762 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js +++ b/packages/pwa-kit-dev/src/utils/resolver-utils.test.js @@ -130,24 +130,21 @@ describe('resolverUtils', () => { describe('"buildCandidatePaths" util returns array of paths used to module resolving', () => { ;[ { - name: 'Correct absolute paths are returned with valid input data', - importPath: '*/app/routes', + name: 'Correct paths are returned when wildcard import is used in an application extension', + importPath: '*/pages/sample', sourcePath: path.join( process.cwd(), 'node_modules', '@salesforce', - 'pwa-kit-react-sdk', - 'ssr', - 'universal', - 'components', - 'routes', - 'index.jsx' + 'extension-module-extension-a', + 'src', + 'setup-app.ts' ), extensions: ['module-extension-a', 'module-extension-b', 'module-extension-c'], expected: [ - path.join(process.cwd(), 'app', 'overrides', 'app', 'routes'), - path.join(process.cwd(), 'app', 'routes'), + path.join(process.cwd(), 'app', 'overrides', 'pages', 'sample'), + path.join(process.cwd(), 'app', 'pages', 'sample'), path.join( process.cwd(), 'node_modules', @@ -155,8 +152,8 @@ describe('resolverUtils', () => { 'extension-module-extension-c', 'src', 'overrides', - 'app', - 'routes' + 'pages', + 'sample' ), path.join( process.cwd(), @@ -164,8 +161,8 @@ describe('resolverUtils', () => { '@salesforce', 'extension-module-extension-c', 'src', - 'app', - 'routes' + 'pages', + 'sample' ), path.join( process.cwd(), @@ -174,8 +171,8 @@ describe('resolverUtils', () => { 'extension-module-extension-b', 'src', 'overrides', - 'app', - 'routes' + 'pages', + 'sample' ), path.join( process.cwd(), @@ -183,8 +180,8 @@ describe('resolverUtils', () => { '@salesforce', 'extension-module-extension-b', 'src', - 'app', - 'routes' + 'pages', + 'sample' ), path.join( process.cwd(), @@ -193,55 +190,8 @@ describe('resolverUtils', () => { 'extension-module-extension-a', 'src', 'overrides', - 'app', - 'routes' - ), - path.join( - process.cwd(), - 'node_modules', - '@salesforce', - 'extension-module-extension-a', - 'src', - 'app', - 'routes' - ) - // NOTE: This has been removed at we currently aren't using the `overrides-resolver-plugin` to resolve special components. - // path.join( - // process.cwd(), - // 'node_modules', - // '@salesforce', - // 'pwa-kit-react-sdk', - // 'ssr', - // 'universal', - // 'components', - // 'routes' - // ) - ] - }, - { - name: 'If sourcePath implies a selfreference, only the paths before its first mention is included', - importPath: '*/app/routes', - sourcePath: path.join( - process.cwd(), - 'node_modules', - '@salesforce', - 'extension-module-extension-b', - 'src', - 'overrides', - 'app', - 'routes.jsx' - ), - extensions: ['module-extension-a', 'module-extension-b'], - expected: [ - path.join( - process.cwd(), - 'node_modules', - '@salesforce', - 'extension-module-extension-a', - 'src', - 'overrides', - 'app', - 'routes' + 'pages', + 'sample' ), path.join( process.cwd(), @@ -249,8 +199,8 @@ describe('resolverUtils', () => { '@salesforce', 'extension-module-extension-a', 'src', - 'app', - 'routes' + 'pages', + 'sample' ) // NOTE: This has been removed at we currently aren't using the `overrides-resolver-plugin` to resolve special components. // path.join( @@ -265,6 +215,54 @@ describe('resolverUtils', () => { // ) ] } + // , + // { + // name: 'If sourcePath implies a self-reference, only the paths before its first mention is included', + // importPath: '*/app/routes', + // sourcePath: path.join( + // process.cwd(), + // 'node_modules', + // '@salesforce', + // 'extension-module-extension-b', + // 'src', + // 'overrides', + // 'app', + // 'routes.jsx' + // ), + // extensions: ['module-extension-a', 'module-extension-b'], + // expected: [ + // path.join( + // process.cwd(), + // 'node_modules', + // '@salesforce', + // 'extension-module-extension-a', + // 'src', + // 'overrides', + // 'app', + // 'routes' + // ), + // path.join( + // process.cwd(), + // 'node_modules', + // '@salesforce', + // 'extension-module-extension-a', + // 'src', + // 'app', + // 'routes' + // ) + // // NOTE: This has been removed at we currently aren't using the `overrides-resolver-plugin` to resolve special components. + // // path.join( + // // process.cwd(), + // // 'node_modules', + // // '@salesforce', + // // 'pwa-kit-react-sdk', + // // 'ssr', + // // 'universal', + // // 'components', + // // 'routes' + // // ) + // ] + // } ].forEach((testCase) => { test(`${testCase.name}`, () => { const result = resolverUtils.buildCandidatePaths( From 3c05843d98dc3eb06c9188a3c13686762193158a Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 27 Sep 2024 13:57:19 -0700 Subject: [PATCH 131/929] Remove extensions committed by mistake. --- packages/extension-chakra-ui/README.md | 68 - packages/extension-chakra-ui/assets/README.md | 0 .../example/EXAMPLE_PROJECT.md | 9 - .../extension-chakra-ui/package-lock.json | 2300 ----------------- packages/extension-chakra-ui/package.json | 31 - .../src/components/with-chakra-ui.tsx | 27 - packages/extension-chakra-ui/src/setup-app.ts | 25 - .../extension-chakra-ui/src/setup-server.ts | 25 - .../extension-chakra-ui/src/types/config.ts | 12 - .../extension-chakra-ui/src/types/index.ts | 8 - packages/extension-sample-2/README.md | 68 - packages/extension-sample-2/assets/README.md | 0 .../example/EXAMPLE_PROJECT.md | 9 - packages/extension-sample-2/package-lock.json | 166 -- packages/extension-sample-2/package.json | 25 - .../src/components/with-red-border.tsx | 26 - .../src/overrides/pages/sample.tsx | 34 - .../extension-sample-2/src/pages/sample-2.tsx | 34 - packages/extension-sample-2/src/setup-app.ts | 39 - .../extension-sample-2/src/setup-server.ts | 25 - .../extension-sample-2/src/types/config.ts | 12 - .../extension-sample-2/src/types/index.ts | 8 - .../app/pages/home.tsx | 36 - .../template-typescript-minimal/package.json | 6 +- 24 files changed, 1 insertion(+), 2992 deletions(-) delete mode 100644 packages/extension-chakra-ui/README.md delete mode 100644 packages/extension-chakra-ui/assets/README.md delete mode 100644 packages/extension-chakra-ui/example/EXAMPLE_PROJECT.md delete mode 100644 packages/extension-chakra-ui/package-lock.json delete mode 100644 packages/extension-chakra-ui/package.json delete mode 100644 packages/extension-chakra-ui/src/components/with-chakra-ui.tsx delete mode 100644 packages/extension-chakra-ui/src/setup-app.ts delete mode 100644 packages/extension-chakra-ui/src/setup-server.ts delete mode 100644 packages/extension-chakra-ui/src/types/config.ts delete mode 100644 packages/extension-chakra-ui/src/types/index.ts delete mode 100644 packages/extension-sample-2/README.md delete mode 100644 packages/extension-sample-2/assets/README.md delete mode 100644 packages/extension-sample-2/example/EXAMPLE_PROJECT.md delete mode 100644 packages/extension-sample-2/package-lock.json delete mode 100644 packages/extension-sample-2/package.json delete mode 100644 packages/extension-sample-2/src/components/with-red-border.tsx delete mode 100644 packages/extension-sample-2/src/overrides/pages/sample.tsx delete mode 100644 packages/extension-sample-2/src/pages/sample-2.tsx delete mode 100644 packages/extension-sample-2/src/setup-app.ts delete mode 100644 packages/extension-sample-2/src/setup-server.ts delete mode 100644 packages/extension-sample-2/src/types/config.ts delete mode 100644 packages/extension-sample-2/src/types/index.ts diff --git a/packages/extension-chakra-ui/README.md b/packages/extension-chakra-ui/README.md deleted file mode 100644 index d19ecefd06..0000000000 --- a/packages/extension-chakra-ui/README.md +++ /dev/null @@ -1,68 +0,0 @@ - __ _ __ _ _ -/ _\ __ _ _ __ ___ _ __ | | ___ /__\_ _| |_ ___ _ __ ___(_) ___ _ __ -\ \ / _` | '_ ` _ \| '_ \| |/ _ \ /_\ \ \/ / __/ _ \ '_ \/ __| |/ _ \| '_ \ -_\ \ (_| | | | | | | |_) | | __/ //__ > <| || __/ | | \__ \ | (_) | | | | -\__/\__,_|_| |_| |_| .__/|_|\___| \__/ /_/\_\\__\___|_| |_|___/_|\___/|_| |_| - |_| - -# Description - -This is a sample PWA-Kit Application Extension. The purpose of this application extensions is to show how -the Application Extensions API can be used to enhance your PWA-Kit base project. - -# Folder Structure - -Insert description of generic Application Extension folder structure here. - -# Peer Dependancies - -PWA-Kit Application Extensions are NPM packages at their most simplest form, and as such you can define -what peer dependencies are required when using it. Because this sample application extension provides -UI via a new "Sample" page, it requires that the below dependencies are installed at a minimum. - -Depending on what features your application extensions provides it's recommended you include any third-party -packages as peer dependencies so that your base application doesn't end up having multiple versions of a -given package. - -"react": "^18.2.0", -"react-dom": "^18.2.0" - -# Configuration - -This section is optional and will depend on your application extensions implementation. If you have features -that are configurable, then list those configurations here so that the PWA-Kit project implementor can configure -the extension as they like. - -``` -{ - path: 'sample-page' -} -``` - -# Installation - -``` -> npm install @salesforce/extension-sample --legacy-peer-deps*
-> Downloading npm package...
-> Installing extention...
-> Finished.
-> Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. -``` - -# Advanced Usage - -In order to customize this Application Extension to your particulare needs we suggest that you refer to the section titled -"configuration", but if there is something that you want to customize that isn't configurable and cannot wait for a feature -request to be fulfilled, then you can use overrides. - -Below is a list of files that can't be overridden from within your PWA-Kit base project. Please refer to the documentation here on -how to properly override extensions. Additionally it's up to the Application Extension developer as to which files can and -cannot be overridden. Please refer to this documentation on how to write your first PWA-Kit Application Extension. - -## Overridable Files - -``` -/src/path/to/overridable/file.ts -``` - - diff --git a/packages/extension-chakra-ui/assets/README.md b/packages/extension-chakra-ui/assets/README.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/extension-chakra-ui/example/EXAMPLE_PROJECT.md b/packages/extension-chakra-ui/example/EXAMPLE_PROJECT.md deleted file mode 100644 index 1d2550062d..0000000000 --- a/packages/extension-chakra-ui/example/EXAMPLE_PROJECT.md +++ /dev/null @@ -1,9 +0,0 @@ -# Description - -This folder will house a sample PWA-Kit project built using the `template-typescript-minimal` base project. Its -purpose is to test the Application Extension being developed without having to manually install it in another -project. - -Additionally we'll update the `create-app` project so that we can generate a stub implementation of an Application -Extensions. This will reduce the friction for "Extension Developers", it will also allow use to use TypeScript -soley. \ No newline at end of file diff --git a/packages/extension-chakra-ui/package-lock.json b/packages/extension-chakra-ui/package-lock.json deleted file mode 100644 index aefcb9b3e9..0000000000 --- a/packages/extension-chakra-ui/package-lock.json +++ /dev/null @@ -1,2300 +0,0 @@ -{ - "name": "@salesforce/extension-chakra-ui", - "version": "1.0.0-dev", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@salesforce/extension-chakra-ui", - "version": "1.0.0-dev", - "dependencies": { - "@chakra-ui/react": "^2.8.2", - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "framer-motion": "^11.5.4" - }, - "devDependencies": { - "@loadable/component": "^5.15.3", - "@types/react": "~18.2.0", - "@types/react-dom": "~18.2.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - }, - "peerDependencies": { - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "dependencies": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", - "dependencies": { - "@babel/types": "^7.25.6" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@chakra-ui/accordion": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-2.3.1.tgz", - "integrity": "sha512-FSXRm8iClFyU+gVaXisOSEw0/4Q+qZbFRiuhIAkVU6Boj0FxAMrlo9a8AV5TuF77rgaHytCdHk0Ng+cyUijrag==", - "dependencies": { - "@chakra-ui/descendant": "3.1.0", - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/alert": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.2.2.tgz", - "integrity": "sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw==", - "dependencies": { - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/spinner": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/anatomy": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz", - "integrity": "sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg==" - }, - "node_modules/@chakra-ui/avatar": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-2.3.0.tgz", - "integrity": "sha512-8gKSyLfygnaotbJbDMHDiJoF38OHXUYVme4gGxZ1fLnQEdPVEaIWfH+NndIjOM0z8S+YEFnT9KyGMUtvPrBk3g==", - "dependencies": { - "@chakra-ui/image": "2.1.0", - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/breadcrumb": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-2.2.0.tgz", - "integrity": "sha512-4cWCG24flYBxjruRi4RJREWTGF74L/KzI2CognAW/d/zWR0CjiScuJhf37Am3LFbCySP6WSoyBOtTIoTA4yLEA==", - "dependencies": { - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/breakpoint-utils": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.8.tgz", - "integrity": "sha512-Pq32MlEX9fwb5j5xx8s18zJMARNHlQZH2VH1RZgfgRDpp7DcEgtRW5AInfN5CfqdHLO1dGxA7I3MqEuL5JnIsA==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5" - } - }, - "node_modules/@chakra-ui/button": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/button/-/button-2.1.0.tgz", - "integrity": "sha512-95CplwlRKmmUXkdEp/21VkEWgnwcx2TOBG6NfYlsuLBDHSLlo5FKIiE2oSi4zXc4TLcopGcWPNcm/NDaSC5pvA==", - "dependencies": { - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/spinner": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/card": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/card/-/card-2.2.0.tgz", - "integrity": "sha512-xUB/k5MURj4CtPAhdSoXZidUbm8j3hci9vnc+eZJVDqhDOShNlD6QeniQNRPRys4lWAQLCbFcrwL29C8naDi6g==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/checkbox": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-2.3.2.tgz", - "integrity": "sha512-85g38JIXMEv6M+AcyIGLh7igNtfpAN6KGQFYxY9tBj0eWvWk4NKQxvqqyVta0bSAyIl1rixNIIezNpNWk2iO4g==", - "dependencies": { - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-callback-ref": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/react-use-safe-layout-effect": "2.1.0", - "@chakra-ui/react-use-update-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/visually-hidden": "2.2.0", - "@zag-js/focus-visible": "0.16.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/clickable": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-2.1.0.tgz", - "integrity": "sha512-flRA/ClPUGPYabu+/GLREZVZr9j2uyyazCAUHAdrTUEdDYCr31SVGhgh7dgKdtq23bOvAQJpIJjw/0Bs0WvbXw==", - "dependencies": { - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/close-button": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.1.1.tgz", - "integrity": "sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw==", - "dependencies": { - "@chakra-ui/icon": "3.2.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/color-mode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz", - "integrity": "sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg==", - "dependencies": { - "@chakra-ui/react-use-safe-layout-effect": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/control-box": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-2.1.0.tgz", - "integrity": "sha512-gVrRDyXFdMd8E7rulL0SKeoljkLQiPITFnsyMO8EFHNZ+AHt5wK4LIguYVEq88APqAGZGfHFWXr79RYrNiE3Mg==", - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/counter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-2.1.0.tgz", - "integrity": "sha512-s6hZAEcWT5zzjNz2JIWUBzRubo9la/oof1W7EKZVVfPYHERnl5e16FmBC79Yfq8p09LQ+aqFKm/etYoJMMgghw==", - "dependencies": { - "@chakra-ui/number-utils": "2.0.7", - "@chakra-ui/react-use-callback-ref": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/css-reset": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-2.3.0.tgz", - "integrity": "sha512-cQwwBy5O0jzvl0K7PLTLgp8ijqLPKyuEMiDXwYzl95seD3AoeuoCLyzZcJtVqaUZ573PiBdAbY/IlZcwDOItWg==", - "peerDependencies": { - "@emotion/react": ">=10.0.35", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/descendant": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-3.1.0.tgz", - "integrity": "sha512-VxCIAir08g5w27klLyi7PVo8BxhW4tgU/lxQyujkmi4zx7hT9ZdrcQLAted/dAa+aSIZ14S1oV0Q9lGjsAdxUQ==", - "dependencies": { - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/dom-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/dom-utils/-/dom-utils-2.1.0.tgz", - "integrity": "sha512-ZmF2qRa1QZ0CMLU8M1zCfmw29DmPNtfjR9iTo74U5FPr3i1aoAh7fbJ4qAlZ197Xw9eAW28tvzQuoVWeL5C7fQ==" - }, - "node_modules/@chakra-ui/editable": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/editable/-/editable-3.1.0.tgz", - "integrity": "sha512-j2JLrUL9wgg4YA6jLlbU88370eCRyor7DZQD9lzpY95tSOXpTljeg3uF9eOmDnCs6fxp3zDWIfkgMm/ExhcGTg==", - "dependencies": { - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-callback-ref": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-focus-on-pointer-down": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/react-use-safe-layout-effect": "2.1.0", - "@chakra-ui/react-use-update-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/event-utils": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@chakra-ui/event-utils/-/event-utils-2.0.8.tgz", - "integrity": "sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw==" - }, - "node_modules/@chakra-ui/focus-lock": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-2.1.0.tgz", - "integrity": "sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w==", - "dependencies": { - "@chakra-ui/dom-utils": "2.1.0", - "react-focus-lock": "^2.9.4" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/form-control": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-2.2.0.tgz", - "integrity": "sha512-wehLC1t4fafCVJ2RvJQT2jyqsAwX7KymmiGqBu7nQoQz8ApTkGABWpo/QwDh3F/dBLrouHDoOvGmYTqft3Mirw==", - "dependencies": { - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/hooks": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.2.1.tgz", - "integrity": "sha512-RQbTnzl6b1tBjbDPf9zGRo9rf/pQMholsOudTxjy4i9GfTfz6kgp5ValGjQm2z7ng6Z31N1cnjZ1AlSzQ//ZfQ==", - "dependencies": { - "@chakra-ui/react-utils": "2.0.12", - "@chakra-ui/utils": "2.0.15", - "compute-scroll-into-view": "3.0.3", - "copy-to-clipboard": "3.3.3" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/icon": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.2.0.tgz", - "integrity": "sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/image": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-2.1.0.tgz", - "integrity": "sha512-bskumBYKLiLMySIWDGcz0+D9Th0jPvmX6xnRMs4o92tT3Od/bW26lahmV2a2Op2ItXeCmRMY+XxJH5Gy1i46VA==", - "dependencies": { - "@chakra-ui/react-use-safe-layout-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/input": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/input/-/input-2.1.2.tgz", - "integrity": "sha512-GiBbb3EqAA8Ph43yGa6Mc+kUPjh4Spmxp1Pkelr8qtudpc3p2PJOOebLpd90mcqw8UePPa+l6YhhPtp6o0irhw==", - "dependencies": { - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/object-utils": "2.1.0", - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/layout": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/layout/-/layout-2.3.1.tgz", - "integrity": "sha512-nXuZ6WRbq0WdgnRgLw+QuxWAHuhDtVX8ElWqcTK+cSMFg/52eVP47czYBE5F35YhnoW2XBwfNoNgZ7+e8Z01Rg==", - "dependencies": { - "@chakra-ui/breakpoint-utils": "2.0.8", - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/object-utils": "2.1.0", - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/lazy-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@chakra-ui/lazy-utils/-/lazy-utils-2.0.5.tgz", - "integrity": "sha512-UULqw7FBvcckQk2n3iPO56TMJvDsNv0FKZI6PlUNJVaGsPbsYxK/8IQ60vZgaTVPtVcjY6BE+y6zg8u9HOqpyg==" - }, - "node_modules/@chakra-ui/live-region": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-2.1.0.tgz", - "integrity": "sha512-ZOxFXwtaLIsXjqnszYYrVuswBhnIHHP+XIgK1vC6DePKtyK590Wg+0J0slDwThUAd4MSSIUa/nNX84x1GMphWw==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/media-query": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-3.3.0.tgz", - "integrity": "sha512-IsTGgFLoICVoPRp9ykOgqmdMotJG0CnPsKvGQeSFOB/dZfIujdVb14TYxDU4+MURXry1MhJ7LzZhv+Ml7cr8/g==", - "dependencies": { - "@chakra-ui/breakpoint-utils": "2.0.8", - "@chakra-ui/react-env": "3.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/menu": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/menu/-/menu-2.2.1.tgz", - "integrity": "sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g==", - "dependencies": { - "@chakra-ui/clickable": "2.1.0", - "@chakra-ui/descendant": "3.1.0", - "@chakra-ui/lazy-utils": "2.0.5", - "@chakra-ui/popper": "3.1.0", - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-animation-state": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-disclosure": "2.1.0", - "@chakra-ui/react-use-focus-effect": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/react-use-outside-click": "2.2.0", - "@chakra-ui/react-use-update-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/modal": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-2.3.1.tgz", - "integrity": "sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ==", - "dependencies": { - "@chakra-ui/close-button": "2.1.1", - "@chakra-ui/focus-lock": "2.1.0", - "@chakra-ui/portal": "2.1.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.1.0", - "aria-hidden": "^1.2.3", - "react-remove-scroll": "^2.5.6" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@chakra-ui/number-input": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-2.1.2.tgz", - "integrity": "sha512-pfOdX02sqUN0qC2ysuvgVDiws7xZ20XDIlcNhva55Jgm095xjm8eVdIBfNm3SFbSUNxyXvLTW/YQanX74tKmuA==", - "dependencies": { - "@chakra-ui/counter": "2.1.0", - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-callback-ref": "2.1.0", - "@chakra-ui/react-use-event-listener": "2.1.0", - "@chakra-ui/react-use-interval": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/react-use-safe-layout-effect": "2.1.0", - "@chakra-ui/react-use-update-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/number-utils": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@chakra-ui/number-utils/-/number-utils-2.0.7.tgz", - "integrity": "sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg==" - }, - "node_modules/@chakra-ui/object-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz", - "integrity": "sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ==" - }, - "node_modules/@chakra-ui/pin-input": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-2.1.0.tgz", - "integrity": "sha512-x4vBqLStDxJFMt+jdAHHS8jbh294O53CPQJoL4g228P513rHylV/uPscYUHrVJXRxsHfRztQO9k45jjTYaPRMw==", - "dependencies": { - "@chakra-ui/descendant": "3.1.0", - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/popover": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/popover/-/popover-2.2.1.tgz", - "integrity": "sha512-K+2ai2dD0ljvJnlrzesCDT9mNzLifE3noGKZ3QwLqd/K34Ym1W/0aL1ERSynrcG78NKoXS54SdEzkhCZ4Gn/Zg==", - "dependencies": { - "@chakra-ui/close-button": "2.1.1", - "@chakra-ui/lazy-utils": "2.0.5", - "@chakra-ui/popper": "3.1.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-animation-state": "2.1.0", - "@chakra-ui/react-use-disclosure": "2.1.0", - "@chakra-ui/react-use-focus-effect": "2.1.0", - "@chakra-ui/react-use-focus-on-pointer-down": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/popper": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/popper/-/popper-3.1.0.tgz", - "integrity": "sha512-ciDdpdYbeFG7og6/6J8lkTFxsSvwTdMLFkpVylAF6VNC22jssiWfquj2eyD4rJnzkRFPvIWJq8hvbfhsm+AjSg==", - "dependencies": { - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@popperjs/core": "^2.9.3" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/portal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.1.0.tgz", - "integrity": "sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg==", - "dependencies": { - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-safe-layout-effect": "2.1.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@chakra-ui/progress": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/progress/-/progress-2.2.0.tgz", - "integrity": "sha512-qUXuKbuhN60EzDD9mHR7B67D7p/ZqNS2Aze4Pbl1qGGZfulPW0PY8Rof32qDtttDQBkzQIzFGE8d9QpAemToIQ==", - "dependencies": { - "@chakra-ui/react-context": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/provider": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/provider/-/provider-2.4.2.tgz", - "integrity": "sha512-w0Tef5ZCJK1mlJorcSjItCSbyvVuqpvyWdxZiVQmE6fvSJR83wZof42ux0+sfWD+I7rHSfj+f9nzhNaEWClysw==", - "dependencies": { - "@chakra-ui/css-reset": "2.3.0", - "@chakra-ui/portal": "2.1.0", - "@chakra-ui/react-env": "3.1.0", - "@chakra-ui/system": "2.6.2", - "@chakra-ui/utils": "2.0.15" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0", - "@emotion/styled": "^11.0.0", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@chakra-ui/radio": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/radio/-/radio-2.1.2.tgz", - "integrity": "sha512-n10M46wJrMGbonaghvSRnZ9ToTv/q76Szz284gv4QUWvyljQACcGrXIONUnQ3BIwbOfkRqSk7Xl/JgZtVfll+w==", - "dependencies": { - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@zag-js/focus-visible": "0.16.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.8.2.tgz", - "integrity": "sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ==", - "dependencies": { - "@chakra-ui/accordion": "2.3.1", - "@chakra-ui/alert": "2.2.2", - "@chakra-ui/avatar": "2.3.0", - "@chakra-ui/breadcrumb": "2.2.0", - "@chakra-ui/button": "2.1.0", - "@chakra-ui/card": "2.2.0", - "@chakra-ui/checkbox": "2.3.2", - "@chakra-ui/close-button": "2.1.1", - "@chakra-ui/control-box": "2.1.0", - "@chakra-ui/counter": "2.1.0", - "@chakra-ui/css-reset": "2.3.0", - "@chakra-ui/editable": "3.1.0", - "@chakra-ui/focus-lock": "2.1.0", - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/hooks": "2.2.1", - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/image": "2.1.0", - "@chakra-ui/input": "2.1.2", - "@chakra-ui/layout": "2.3.1", - "@chakra-ui/live-region": "2.1.0", - "@chakra-ui/media-query": "3.3.0", - "@chakra-ui/menu": "2.2.1", - "@chakra-ui/modal": "2.3.1", - "@chakra-ui/number-input": "2.1.2", - "@chakra-ui/pin-input": "2.1.0", - "@chakra-ui/popover": "2.2.1", - "@chakra-ui/popper": "3.1.0", - "@chakra-ui/portal": "2.1.0", - "@chakra-ui/progress": "2.2.0", - "@chakra-ui/provider": "2.4.2", - "@chakra-ui/radio": "2.1.2", - "@chakra-ui/react-env": "3.1.0", - "@chakra-ui/select": "2.1.2", - "@chakra-ui/skeleton": "2.1.0", - "@chakra-ui/skip-nav": "2.1.0", - "@chakra-ui/slider": "2.1.0", - "@chakra-ui/spinner": "2.1.0", - "@chakra-ui/stat": "2.1.1", - "@chakra-ui/stepper": "2.3.1", - "@chakra-ui/styled-system": "2.9.2", - "@chakra-ui/switch": "2.1.2", - "@chakra-ui/system": "2.6.2", - "@chakra-ui/table": "2.1.0", - "@chakra-ui/tabs": "3.0.0", - "@chakra-ui/tag": "3.1.1", - "@chakra-ui/textarea": "2.1.2", - "@chakra-ui/theme": "3.3.1", - "@chakra-ui/theme-utils": "2.0.21", - "@chakra-ui/toast": "7.0.2", - "@chakra-ui/tooltip": "2.3.1", - "@chakra-ui/transition": "2.1.0", - "@chakra-ui/utils": "2.0.15", - "@chakra-ui/visually-hidden": "2.2.0" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0", - "@emotion/styled": "^11.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@chakra-ui/react-children-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-children-utils/-/react-children-utils-2.0.6.tgz", - "integrity": "sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-context": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.1.0.tgz", - "integrity": "sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-env": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-3.1.0.tgz", - "integrity": "sha512-Vr96GV2LNBth3+IKzr/rq1IcnkXv+MLmwjQH6C8BRtn3sNskgDFD5vLkVXcEhagzZMCh8FR3V/bzZPojBOyNhw==", - "dependencies": { - "@chakra-ui/react-use-safe-layout-effect": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.7.tgz", - "integrity": "sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-animation-state": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.1.0.tgz", - "integrity": "sha512-CFZkQU3gmDBwhqy0vC1ryf90BVHxVN8cTLpSyCpdmExUEtSEInSCGMydj2fvn7QXsz/za8JNdO2xxgJwxpLMtg==", - "dependencies": { - "@chakra-ui/dom-utils": "2.1.0", - "@chakra-ui/react-use-event-listener": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-callback-ref": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz", - "integrity": "sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-controllable-state": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.1.0.tgz", - "integrity": "sha512-QR/8fKNokxZUs4PfxjXuwl0fj/d71WPrmLJvEpCTkHjnzu7LnYvzoe2wB867IdooQJL0G1zBxl0Dq+6W1P3jpg==", - "dependencies": { - "@chakra-ui/react-use-callback-ref": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-disclosure": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.1.0.tgz", - "integrity": "sha512-Ax4pmxA9LBGMyEZJhhUZobg9C0t3qFE4jVF1tGBsrLDcdBeLR9fwOogIPY9Hf0/wqSlAryAimICbr5hkpa5GSw==", - "dependencies": { - "@chakra-ui/react-use-callback-ref": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-event-listener": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.1.0.tgz", - "integrity": "sha512-U5greryDLS8ISP69DKDsYcsXRtAdnTQT+jjIlRYZ49K/XhUR/AqVZCK5BkR1spTDmO9H8SPhgeNKI70ODuDU/Q==", - "dependencies": { - "@chakra-ui/react-use-callback-ref": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-focus-effect": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.1.0.tgz", - "integrity": "sha512-xzVboNy7J64xveLcxTIJ3jv+lUJKDwRM7Szwn9tNzUIPD94O3qwjV7DDCUzN2490nSYDF4OBMt/wuDBtaR3kUQ==", - "dependencies": { - "@chakra-ui/dom-utils": "2.1.0", - "@chakra-ui/react-use-event-listener": "2.1.0", - "@chakra-ui/react-use-safe-layout-effect": "2.1.0", - "@chakra-ui/react-use-update-effect": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-focus-on-pointer-down": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.1.0.tgz", - "integrity": "sha512-2jzrUZ+aiCG/cfanrolsnSMDykCAbv9EK/4iUyZno6BYb3vziucmvgKuoXbMPAzWNtwUwtuMhkby8rc61Ue+Lg==", - "dependencies": { - "@chakra-ui/react-use-event-listener": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-interval": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-interval/-/react-use-interval-2.1.0.tgz", - "integrity": "sha512-8iWj+I/+A0J08pgEXP1J1flcvhLBHkk0ln7ZvGIyXiEyM6XagOTJpwNhiu+Bmk59t3HoV/VyvyJTa+44sEApuw==", - "dependencies": { - "@chakra-ui/react-use-callback-ref": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-latest-ref": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.1.0.tgz", - "integrity": "sha512-m0kxuIYqoYB0va9Z2aW4xP/5b7BzlDeWwyXCH6QpT2PpW3/281L3hLCm1G0eOUcdVlayqrQqOeD6Mglq+5/xoQ==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-merge-refs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz", - "integrity": "sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-outside-click": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.2.0.tgz", - "integrity": "sha512-PNX+s/JEaMneijbgAM4iFL+f3m1ga9+6QK0E5Yh4s8KZJQ/bLwZzdhMz8J/+mL+XEXQ5J0N8ivZN28B82N1kNw==", - "dependencies": { - "@chakra-ui/react-use-callback-ref": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-pan-event": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.1.0.tgz", - "integrity": "sha512-xmL2qOHiXqfcj0q7ZK5s9UjTh4Gz0/gL9jcWPA6GVf+A0Od5imEDa/Vz+533yQKWiNSm1QGrIj0eJAokc7O4fg==", - "dependencies": { - "@chakra-ui/event-utils": "2.0.8", - "@chakra-ui/react-use-latest-ref": "2.1.0", - "framesync": "6.1.2" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-previous": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-previous/-/react-use-previous-2.1.0.tgz", - "integrity": "sha512-pjxGwue1hX8AFcmjZ2XfrQtIJgqbTF3Qs1Dy3d1krC77dEsiCUbQ9GzOBfDc8pfd60DrB5N2tg5JyHbypqh0Sg==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-safe-layout-effect": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz", - "integrity": "sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-size": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-size/-/react-use-size-2.1.0.tgz", - "integrity": "sha512-tbLqrQhbnqOjzTaMlYytp7wY8BW1JpL78iG7Ru1DlV4EWGiAmXFGvtnEt9HftU0NJ0aJyjgymkxfVGI55/1Z4A==", - "dependencies": { - "@zag-js/element-size": "0.10.5" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-timeout": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz", - "integrity": "sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ==", - "dependencies": { - "@chakra-ui/react-use-callback-ref": "2.1.0" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-use-update-effect": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz", - "integrity": "sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA==", - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/react-utils": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz", - "integrity": "sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw==", - "dependencies": { - "@chakra-ui/utils": "2.0.15" - }, - "peerDependencies": { - "react": ">=18" - } - }, - "node_modules/@chakra-ui/select": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/select/-/select-2.1.2.tgz", - "integrity": "sha512-ZwCb7LqKCVLJhru3DXvKXpZ7Pbu1TDZ7N0PdQ0Zj1oyVLJyrpef1u9HR5u0amOpqcH++Ugt0f5JSmirjNlctjA==", - "dependencies": { - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/shared-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz", - "integrity": "sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q==" - }, - "node_modules/@chakra-ui/skeleton": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-2.1.0.tgz", - "integrity": "sha512-JNRuMPpdZGd6zFVKjVQ0iusu3tXAdI29n4ZENYwAJEMf/fN0l12sVeirOxkJ7oEL0yOx2AgEYFSKdbcAgfUsAQ==", - "dependencies": { - "@chakra-ui/media-query": "3.3.0", - "@chakra-ui/react-use-previous": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/skip-nav": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/skip-nav/-/skip-nav-2.1.0.tgz", - "integrity": "sha512-Hk+FG+vadBSH0/7hwp9LJnLjkO0RPGnx7gBJWI4/SpoJf3e4tZlWYtwGj0toYY4aGKl93jVghuwGbDBEMoHDug==", - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/slider": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/slider/-/slider-2.1.0.tgz", - "integrity": "sha512-lUOBcLMCnFZiA/s2NONXhELJh6sY5WtbRykPtclGfynqqOo47lwWJx+VP7xaeuhDOPcWSSecWc9Y1BfPOCz9cQ==", - "dependencies": { - "@chakra-ui/number-utils": "2.0.7", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-callback-ref": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-latest-ref": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/react-use-pan-event": "2.1.0", - "@chakra-ui/react-use-size": "2.1.0", - "@chakra-ui/react-use-update-effect": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/spinner": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.1.0.tgz", - "integrity": "sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/stat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/stat/-/stat-2.1.1.tgz", - "integrity": "sha512-LDn0d/LXQNbAn2KaR3F1zivsZCewY4Jsy1qShmfBMKwn6rI8yVlbvu6SiA3OpHS0FhxbsZxQI6HefEoIgtqY6Q==", - "dependencies": { - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/stepper": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/stepper/-/stepper-2.3.1.tgz", - "integrity": "sha512-ky77lZbW60zYkSXhYz7kbItUpAQfEdycT0Q4bkHLxfqbuiGMf8OmgZOQkOB9uM4v0zPwy2HXhe0vq4Dd0xa55Q==", - "dependencies": { - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/styled-system": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz", - "integrity": "sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5", - "csstype": "^3.1.2", - "lodash.mergewith": "4.6.2" - } - }, - "node_modules/@chakra-ui/switch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/switch/-/switch-2.1.2.tgz", - "integrity": "sha512-pgmi/CC+E1v31FcnQhsSGjJnOE2OcND4cKPyTE+0F+bmGm48Q/b5UmKD9Y+CmZsrt/7V3h8KNczowupfuBfIHA==", - "dependencies": { - "@chakra-ui/checkbox": "2.3.2", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/system": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.6.2.tgz", - "integrity": "sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==", - "dependencies": { - "@chakra-ui/color-mode": "2.2.0", - "@chakra-ui/object-utils": "2.1.0", - "@chakra-ui/react-utils": "2.0.12", - "@chakra-ui/styled-system": "2.9.2", - "@chakra-ui/theme-utils": "2.0.21", - "@chakra-ui/utils": "2.0.15", - "react-fast-compare": "3.2.2" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0", - "@emotion/styled": "^11.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/table": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/table/-/table-2.1.0.tgz", - "integrity": "sha512-o5OrjoHCh5uCLdiUb0Oc0vq9rIAeHSIRScc2ExTC9Qg/uVZl2ygLrjToCaKfaaKl1oQexIeAcZDKvPG8tVkHyQ==", - "dependencies": { - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/tabs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-3.0.0.tgz", - "integrity": "sha512-6Mlclp8L9lqXmsGWF5q5gmemZXOiOYuh0SGT/7PgJVNPz3LXREXlXg2an4MBUD8W5oTkduCX+3KTMCwRrVrDYw==", - "dependencies": { - "@chakra-ui/clickable": "2.1.0", - "@chakra-ui/descendant": "3.1.0", - "@chakra-ui/lazy-utils": "2.0.5", - "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-controllable-state": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/react-use-safe-layout-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/tag": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/tag/-/tag-3.1.1.tgz", - "integrity": "sha512-Bdel79Dv86Hnge2PKOU+t8H28nm/7Y3cKd4Kfk9k3lOpUh4+nkSGe58dhRzht59lEqa4N9waCgQiBdkydjvBXQ==", - "dependencies": { - "@chakra-ui/icon": "3.2.0", - "@chakra-ui/react-context": "2.1.0" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/textarea": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-2.1.2.tgz", - "integrity": "sha512-ip7tvklVCZUb2fOHDb23qPy/Fr2mzDOGdkrpbNi50hDCiV4hFX02jdQJdi3ydHZUyVgZVBKPOJ+lT9i7sKA2wA==", - "dependencies": { - "@chakra-ui/form-control": "2.2.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/theme": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.3.1.tgz", - "integrity": "sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ==", - "dependencies": { - "@chakra-ui/anatomy": "2.2.2", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/theme-tools": "2.1.2" - }, - "peerDependencies": { - "@chakra-ui/styled-system": ">=2.8.0" - } - }, - "node_modules/@chakra-ui/theme-tools": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz", - "integrity": "sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA==", - "dependencies": { - "@chakra-ui/anatomy": "2.2.2", - "@chakra-ui/shared-utils": "2.0.5", - "color2k": "^2.0.2" - }, - "peerDependencies": { - "@chakra-ui/styled-system": ">=2.0.0" - } - }, - "node_modules/@chakra-ui/theme-utils": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz", - "integrity": "sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/styled-system": "2.9.2", - "@chakra-ui/theme": "3.3.1", - "lodash.mergewith": "4.6.2" - } - }, - "node_modules/@chakra-ui/toast": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-7.0.2.tgz", - "integrity": "sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA==", - "dependencies": { - "@chakra-ui/alert": "2.2.2", - "@chakra-ui/close-button": "2.1.1", - "@chakra-ui/portal": "2.1.0", - "@chakra-ui/react-context": "2.1.0", - "@chakra-ui/react-use-timeout": "2.1.0", - "@chakra-ui/react-use-update-effect": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/styled-system": "2.9.2", - "@chakra-ui/theme": "3.3.1" - }, - "peerDependencies": { - "@chakra-ui/system": "2.6.2", - "framer-motion": ">=4.0.0", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@chakra-ui/tooltip": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-2.3.1.tgz", - "integrity": "sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A==", - "dependencies": { - "@chakra-ui/dom-utils": "2.1.0", - "@chakra-ui/popper": "3.1.0", - "@chakra-ui/portal": "2.1.0", - "@chakra-ui/react-types": "2.0.7", - "@chakra-ui/react-use-disclosure": "2.1.0", - "@chakra-ui/react-use-event-listener": "2.1.0", - "@chakra-ui/react-use-merge-refs": "2.1.0", - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "framer-motion": ">=4.0.0", - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@chakra-ui/transition": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-2.1.0.tgz", - "integrity": "sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ==", - "dependencies": { - "@chakra-ui/shared-utils": "2.0.5" - }, - "peerDependencies": { - "framer-motion": ">=4.0.0", - "react": ">=18" - } - }, - "node_modules/@chakra-ui/utils": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.15.tgz", - "integrity": "sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA==", - "dependencies": { - "@types/lodash.mergewith": "4.6.7", - "css-box-model": "1.2.1", - "framesync": "6.1.2", - "lodash.mergewith": "4.6.2" - } - }, - "node_modules/@chakra-ui/visually-hidden": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-2.2.0.tgz", - "integrity": "sha512-KmKDg01SrQ7VbTD3+cPWf/UfpF5MSwm3v7MWi0n5t8HnnadT13MF0MJCDSXbBWnzLv1ZKJ6zlyAOeARWX+DpjQ==", - "peerDependencies": { - "@chakra-ui/system": ">=2.0.0", - "react": ">=18" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.2.0", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.13.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", - "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", - "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", - "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", - "dependencies": { - "@emotion/memoize": "^0.9.0" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" - }, - "node_modules/@emotion/react": { - "version": "11.13.3", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", - "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz", - "integrity": "sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==", - "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.0", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" - }, - "node_modules/@emotion/styled": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/is-prop-valid": "^1.3.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@loadable/component": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", - "integrity": "sha512-fJWxx9b5WHX90QKmizo9B+es2so8DnBthI1mbflwCoOyvzEwxiZ/SVDCTtXEnHG72/kGBdzr297SSIekYtzSOQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.18", - "hoist-non-react-statics": "^3.3.1", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@types/lodash": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", - "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==" - }, - "node_modules/@types/lodash.mergewith": { - "version": "4.6.7", - "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz", - "integrity": "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==", - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "devOptional": true - }, - "node_modules/@types/react": { - "version": "18.2.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", - "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", - "devOptional": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.2.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", - "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@zag-js/dom-query": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.16.0.tgz", - "integrity": "sha512-Oqhd6+biWyKnhKwFFuZrrf6lxBz2tX2pRQe6grUnYwO6HJ8BcbqZomy2lpOdr+3itlaUqx+Ywj5E5ZZDr/LBfQ==" - }, - "node_modules/@zag-js/element-size": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.10.5.tgz", - "integrity": "sha512-uQre5IidULANvVkNOBQ1tfgwTQcGl4hliPSe69Fct1VfYb2Fd0jdAcGzqQgPhfrXFpR62MxLPB7erxJ/ngtL8w==" - }, - "node_modules/@zag-js/focus-visible": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.16.0.tgz", - "integrity": "sha512-a7U/HSopvQbrDU4GLerpqiMcHKEkQkNPeDZJWz38cw/6Upunh41GjHetq5TB84hxyCaDzJ6q2nEdNoBQfC0FKA==", - "dependencies": { - "@zag-js/dom-query": "0.16.0" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/color2k": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", - "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==" - }, - "node_modules/compute-scroll-into-view": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz", - "integrity": "sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A==" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-box-model": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", - "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", - "dependencies": { - "tiny-invariant": "^1.0.6" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" - }, - "node_modules/focus-lock": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.5.tgz", - "integrity": "sha512-QFaHbhv9WPUeLYBDe/PAuLKJ4Dd9OPvKs9xZBr3yLXnUrDNaVXKu2baDBXe3naPY30hgHYSsf2JW4jzas2mDEQ==", - "dependencies": { - "tslib": "^2.0.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/framer-motion": { - "version": "11.5.4", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.5.4.tgz", - "integrity": "sha512-E+tb3/G6SO69POkdJT+3EpdMuhmtCh9EWuK4I1DnIC23L7tFPrl8vxP+LSovwaw6uUr73rUbpb4FgK011wbRJQ==", - "dependencies": { - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/framesync": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", - "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", - "dependencies": { - "tslib": "2.4.0" - } - }, - "node_modules/framesync/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-clientside-effect": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", - "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", - "dependencies": { - "@babel/runtime": "^7.12.13" - }, - "peerDependencies": { - "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "node_modules/react-focus-lock": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.2.tgz", - "integrity": "sha512-T/7bsofxYqnod2xadvuwjGKHOoL5GH7/EIPI5UyEvaU/c2CcphvGI371opFtuY/SYdbMsNiuF4HsHQ50nA/TKQ==", - "dependencies": { - "@babel/runtime": "^7.0.0", - "focus-lock": "^1.3.5", - "prop-types": "^15.6.2", - "react-clientside-effect": "^1.2.6", - "use-callback-ref": "^1.3.2", - "use-sidecar": "^1.1.2" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react-remove-scroll": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", - "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.6", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", - "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", - "dependencies": { - "react-style-singleton": "^2.2.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-style-singleton": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", - "dependencies": { - "get-nonce": "^1.0.0", - "invariant": "^2.2.4", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, - "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" - }, - "node_modules/use-callback-ref": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", - "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", - "dependencies": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - } - } -} diff --git a/packages/extension-chakra-ui/package.json b/packages/extension-chakra-ui/package.json deleted file mode 100644 index 447481de18..0000000000 --- a/packages/extension-chakra-ui/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@salesforce/extension-chakra-ui", - "version": "1.0.0-dev", - "private": true, - "scripts": { - }, - "dependencies": { - "@chakra-ui/react": "^2.8.2", - "@emotion/react": "^11.13.3", - "@emotion/styled": "^11.13.0", - "framer-motion": "^11.5.4" - }, - "peerDependencies": { - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", - "@salesforce/pwa-kit-runtime": "4.0.0-dev", - "@types/react": "~18.2.0", - "@types/react-dom": "~18.2.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - } - } \ No newline at end of file diff --git a/packages/extension-chakra-ui/src/components/with-chakra-ui.tsx b/packages/extension-chakra-ui/src/components/with-chakra-ui.tsx deleted file mode 100644 index 74dc71353c..0000000000 --- a/packages/extension-chakra-ui/src/components/with-chakra-ui.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' -import {ChakraProvider} from '@chakra-ui/react' - -// Define a type for the HOC props -type WithRedBorderProps = React.ComponentPropsWithoutRef; - -// Define the HOC function -const withRedBorder =

(WrappedComponent: React.ComponentType

) => { - const WithRedBorder: React.FC

= (props: WithRedBorderProps) => { - return ( - - - - ) - } - - return WithRedBorder -} - -export default withRedBorder \ No newline at end of file diff --git a/packages/extension-chakra-ui/src/setup-app.ts b/packages/extension-chakra-ui/src/setup-app.ts deleted file mode 100644 index c1827e0cd2..0000000000 --- a/packages/extension-chakra-ui/src/setup-app.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' -import {ApplicationExtension} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' -import {IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility/types' - -import withChakraUI from './components/with-chakra-ui' - -class Sample extends ApplicationExtension { - - extendApp(App: React.ComponentType): React.ComponentType { - return withChakraUI(App) - } - - extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { - return routes - } -} - -export default Sample diff --git a/packages/extension-chakra-ui/src/setup-server.ts b/packages/extension-chakra-ui/src/setup-server.ts deleted file mode 100644 index 8355d9ed14..0000000000 --- a/packages/extension-chakra-ui/src/setup-server.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import { - Application as ExpressApplication, - ApplicationExtension as ExpressApplicationExtension -} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' - -class ChakraUI extends ExpressApplicationExtension { - - extendApp(app: ExpressApplication): ExpressApplication { - - app.get('/sample', (req, res) => { - console.log('SampleExtension extendApp GET /sample') - res.send('Hello from an express SampleExtension!') - }) - - return app - } -} - -export default ChakraUI diff --git a/packages/extension-chakra-ui/src/types/config.ts b/packages/extension-chakra-ui/src/types/config.ts deleted file mode 100644 index 9deb18b1ce..0000000000 --- a/packages/extension-chakra-ui/src/types/config.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// This is where you are going to define the configuration type for your App Extension. This is used in the constructor -// the extension itself. Update this config type to your specfic needs!! -export interface IConfig { - path: string; -} \ No newline at end of file diff --git a/packages/extension-chakra-ui/src/types/index.ts b/packages/extension-chakra-ui/src/types/index.ts deleted file mode 100644 index 4b7923357f..0000000000 --- a/packages/extension-chakra-ui/src/types/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -export * from './config' \ No newline at end of file diff --git a/packages/extension-sample-2/README.md b/packages/extension-sample-2/README.md deleted file mode 100644 index d19ecefd06..0000000000 --- a/packages/extension-sample-2/README.md +++ /dev/null @@ -1,68 +0,0 @@ - __ _ __ _ _ -/ _\ __ _ _ __ ___ _ __ | | ___ /__\_ _| |_ ___ _ __ ___(_) ___ _ __ -\ \ / _` | '_ ` _ \| '_ \| |/ _ \ /_\ \ \/ / __/ _ \ '_ \/ __| |/ _ \| '_ \ -_\ \ (_| | | | | | | |_) | | __/ //__ > <| || __/ | | \__ \ | (_) | | | | -\__/\__,_|_| |_| |_| .__/|_|\___| \__/ /_/\_\\__\___|_| |_|___/_|\___/|_| |_| - |_| - -# Description - -This is a sample PWA-Kit Application Extension. The purpose of this application extensions is to show how -the Application Extensions API can be used to enhance your PWA-Kit base project. - -# Folder Structure - -Insert description of generic Application Extension folder structure here. - -# Peer Dependancies - -PWA-Kit Application Extensions are NPM packages at their most simplest form, and as such you can define -what peer dependencies are required when using it. Because this sample application extension provides -UI via a new "Sample" page, it requires that the below dependencies are installed at a minimum. - -Depending on what features your application extensions provides it's recommended you include any third-party -packages as peer dependencies so that your base application doesn't end up having multiple versions of a -given package. - -"react": "^18.2.0", -"react-dom": "^18.2.0" - -# Configuration - -This section is optional and will depend on your application extensions implementation. If you have features -that are configurable, then list those configurations here so that the PWA-Kit project implementor can configure -the extension as they like. - -``` -{ - path: 'sample-page' -} -``` - -# Installation - -``` -> npm install @salesforce/extension-sample --legacy-peer-deps*
-> Downloading npm package...
-> Installing extention...
-> Finished.
-> Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. -``` - -# Advanced Usage - -In order to customize this Application Extension to your particulare needs we suggest that you refer to the section titled -"configuration", but if there is something that you want to customize that isn't configurable and cannot wait for a feature -request to be fulfilled, then you can use overrides. - -Below is a list of files that can't be overridden from within your PWA-Kit base project. Please refer to the documentation here on -how to properly override extensions. Additionally it's up to the Application Extension developer as to which files can and -cannot be overridden. Please refer to this documentation on how to write your first PWA-Kit Application Extension. - -## Overridable Files - -``` -/src/path/to/overridable/file.ts -``` - - diff --git a/packages/extension-sample-2/assets/README.md b/packages/extension-sample-2/assets/README.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/extension-sample-2/example/EXAMPLE_PROJECT.md b/packages/extension-sample-2/example/EXAMPLE_PROJECT.md deleted file mode 100644 index 1d2550062d..0000000000 --- a/packages/extension-sample-2/example/EXAMPLE_PROJECT.md +++ /dev/null @@ -1,9 +0,0 @@ -# Description - -This folder will house a sample PWA-Kit project built using the `template-typescript-minimal` base project. Its -purpose is to test the Application Extension being developed without having to manually install it in another -project. - -Additionally we'll update the `create-app` project so that we can generate a stub implementation of an Application -Extensions. This will reduce the friction for "Extension Developers", it will also allow use to use TypeScript -soley. \ No newline at end of file diff --git a/packages/extension-sample-2/package-lock.json b/packages/extension-sample-2/package-lock.json deleted file mode 100644 index 0adfae6f24..0000000000 --- a/packages/extension-sample-2/package-lock.json +++ /dev/null @@ -1,166 +0,0 @@ -{ - "name": "@salesforce/extension-sample", - "version": "1.0.0-dev", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@salesforce/extension-sample", - "version": "1.0.0-dev", - "dependencies": { - "hoist-non-react-statics": "^3.3.2" - }, - "devDependencies": { - "@loadable/component": "^5.15.3", - "@types/react": "~18.2.0", - "@types/react-dom": "~18.2.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - }, - "peerDependencies": { - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@loadable/component": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", - "integrity": "sha512-fJWxx9b5WHX90QKmizo9B+es2so8DnBthI1mbflwCoOyvzEwxiZ/SVDCTtXEnHG72/kGBdzr297SSIekYtzSOQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.18", - "hoist-non-react-statics": "^3.3.1", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.2.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", - "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", - "dev": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.2.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", - "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - } - } - } -} diff --git a/packages/extension-sample-2/package.json b/packages/extension-sample-2/package.json deleted file mode 100644 index 7dbffd12da..0000000000 --- a/packages/extension-sample-2/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "@salesforce/extension-sample-2", - "version": "1.0.0-dev", - "private": true, - "scripts": { - }, - "peerDependencies": { - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", - "@salesforce/pwa-kit-runtime": "4.0.0-dev", - "@types/react": "~18.2.0", - "@types/react-dom": "~18.2.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - } - } \ No newline at end of file diff --git a/packages/extension-sample-2/src/components/with-red-border.tsx b/packages/extension-sample-2/src/components/with-red-border.tsx deleted file mode 100644 index 7f53983c35..0000000000 --- a/packages/extension-sample-2/src/components/with-red-border.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' - -// Define a type for the HOC props -type WithRedBorderProps = React.ComponentPropsWithoutRef; - -// Define the HOC function -const withRedBorder =

(WrappedComponent: React.ComponentType

) => { - const WithRedBorder: React.FC

= (props: WithRedBorderProps) => { - return ( -

- -
- ) - } - - return WithRedBorder -} - -export default withRedBorder \ No newline at end of file diff --git a/packages/extension-sample-2/src/overrides/pages/sample.tsx b/packages/extension-sample-2/src/overrides/pages/sample.tsx deleted file mode 100644 index 72f9cb6db0..0000000000 --- a/packages/extension-sample-2/src/overrides/pages/sample.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import React, {Fragment} from 'react' - -const Sample = () => { - return ( - -

Welcome to the Sample Page (Overidden from Sample 2 Application Extension) 👋

-
-

If you are reading this, it means that this page was successfully added to your base project. 🎉

-

- This Application Extension was installed by running the below command in your PWA-Kit project. - Its dependancies were automatically installed and the extension configured into your projects extensions array. -

-
- - > npm install @salesforce/extension-sample --legacy-peer-deps*
- > Downloading npm package...
- > Installing extention...
- > Finished.
- > Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. -
-
-
- ) -} - -Sample.getTemplateName = () => 'sample' - -export default Sample \ No newline at end of file diff --git a/packages/extension-sample-2/src/pages/sample-2.tsx b/packages/extension-sample-2/src/pages/sample-2.tsx deleted file mode 100644 index 3d7e9bce89..0000000000 --- a/packages/extension-sample-2/src/pages/sample-2.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import React, {Fragment} from 'react' - -const Sample = () => { - return ( - -

Welcome to the Sample Page 2 👋

-
-

If you are reading this, it means that this page was successfully added to your base project. 🎉

-

- This Application Extension was installed by running the below command in your PWA-Kit project. - Its dependancies were automatically installed and the extension configured into your projects extensions array. -

-
- - > npm install @salesforce/extension-sample --legacy-peer-deps*
- > Downloading npm package...
- > Installing extention...
- > Finished.
- > Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. -
-
-
- ) -} - -Sample.getTemplateName = () => 'sample' - -export default Sample \ No newline at end of file diff --git a/packages/extension-sample-2/src/setup-app.ts b/packages/extension-sample-2/src/setup-app.ts deleted file mode 100644 index 55c12aca0c..0000000000 --- a/packages/extension-sample-2/src/setup-app.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' -import loadable from '@loadable/component' -import {IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility/types' -import {ApplicationExtension} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' - -// Project Imports -import withRedBorder from './components/with-red-border' -import {IConfig as Config} from './types' - - -const SamplePage = loadable(() => import('./pages/sample-2')) - -const defaultPath: string = '/sample-page-2' -class Sample extends ApplicationExtension { - - extendApp(App: React.ComponentType): React.ComponentType { - return withRedBorder(App) - } - - extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { - return [ - { - exact: true, - path: this.getConfig()?.path || defaultPath, - component: SamplePage - }, - ...routes - ] - } -} - -export default Sample diff --git a/packages/extension-sample-2/src/setup-server.ts b/packages/extension-sample-2/src/setup-server.ts deleted file mode 100644 index 7d4ec19712..0000000000 --- a/packages/extension-sample-2/src/setup-server.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import { - Application as ExpressApplication, - ApplicationExtension as ExpressApplicationExtension -} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' - -class SampleExtension2 extends ExpressApplicationExtension { - - extendApp(app: ExpressApplication): ExpressApplication { - - app.get('/sample-2', (req, res) => { - console.log('SampleExtension extendApp GET /sample') - res.send('Hello from an express SampleExtension!') - }) - - return app - } -} - -export default SampleExtension2 diff --git a/packages/extension-sample-2/src/types/config.ts b/packages/extension-sample-2/src/types/config.ts deleted file mode 100644 index 9deb18b1ce..0000000000 --- a/packages/extension-sample-2/src/types/config.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// This is where you are going to define the configuration type for your App Extension. This is used in the constructor -// the extension itself. Update this config type to your specfic needs!! -export interface IConfig { - path: string; -} \ No newline at end of file diff --git a/packages/extension-sample-2/src/types/index.ts b/packages/extension-sample-2/src/types/index.ts deleted file mode 100644 index 4b7923357f..0000000000 --- a/packages/extension-sample-2/src/types/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -export * from './config' \ No newline at end of file diff --git a/packages/template-typescript-minimal/app/pages/home.tsx b/packages/template-typescript-minimal/app/pages/home.tsx index 060c870715..f70a575534 100644 --- a/packages/template-typescript-minimal/app/pages/home.tsx +++ b/packages/template-typescript-minimal/app/pages/home.tsx @@ -7,17 +7,6 @@ import React, {useEffect, useState} from 'react' import {useQuery} from '@tanstack/react-query' import {Link} from 'react-router-dom' -import { - Button, - Drawer, - DrawerBody, - DrawerFooter, - DrawerHeader, - DrawerOverlay, - DrawerContent, - DrawerCloseButton, - useDisclosure -} from '@chakra-ui/react' import HelloTS from '../components/hello-typescript' import HelloJS from '../components/hello-javascript' @@ -112,35 +101,10 @@ const Home = ({value}: Props) => { }) ) - const {isOpen, onOpen, onClose} = useDisclosure() - const btnRef = React.useRef(null) - return (
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/template-typescript-minimal/app/overrides/components/with-red-border.jsx b/packages/template-typescript-minimal/app/overrides/components/with-red-border.jsx deleted file mode 100644 index d57399ffea..0000000000 --- a/packages/template-typescript-minimal/app/overrides/components/with-red-border.jsx +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' - -// OVERRIDE!! This border is now BLUE..... - -// Define the HOC function -const withRedBorder = (WrappedComponent) => { - const WithRedBorder = (props) => { - return ( -
- -
- ) - } - - return WithRedBorder -} - -export default withRedBorder diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 40e7ec1eac..84a4994c44 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -18,6 +18,10 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", + + "@salesforce/extension-sample": "1.0.0-dev", + "@salesforce/extension-sample-with-overrides": "1.0.0-dev", + "@salesforce/pwa-kit-dev": "4.0.0-dev", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", "@salesforce/pwa-kit-runtime": "4.0.0-dev", @@ -43,7 +47,7 @@ }, "mobify": { "app":{ - "extensions": [] + "extensions": ["@salesforce/extension-sample", ["@salesforce/extension-sample-with-overrides", {"enabled": false}]] }, "ssrEnabled": true, "ssrOnly": [ From f366e0bb0c0652a8a1d4428432d91483295caee5 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 4 Oct 2024 11:45:24 -0700 Subject: [PATCH 143/929] Update CHANGELOG.md --- packages/pwa-kit-dev/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/pwa-kit-dev/CHANGELOG.md b/packages/pwa-kit-dev/CHANGELOG.md index 0188f6f996..f7a1c6d2fe 100644 --- a/packages/pwa-kit-dev/CHANGELOG.md +++ b/packages/pwa-kit-dev/CHANGELOG.md @@ -1,4 +1,5 @@ ## v4.0.0-dev (Jun 21, 2024) +- Overrides in `disabled` Application Extensions will take no effect. [#2051](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2051) - Ensure Application Extensions have their static folder copied into the bundle. [#2040](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2040) - Create new `OverrideResolverPlugin` and integrate into the Webpack configuration. [#2012](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2012) - Replace `IApplicationExtension` with `ApplicationExtension` abstract class. [#2019](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2019) From ed9bea6b03e7ce7f86f760c2cb05f8be34fecc49 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 4 Oct 2024 13:30:18 -0700 Subject: [PATCH 144/929] Fix failing tests --- .../src/configs/webpack/loaders/extensions-loader.test.js | 2 ++ packages/pwa-kit-dev/src/utils/extensibility-utils.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js b/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js index 8b837888eb..ee0a860745 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js +++ b/packages/pwa-kit-dev/src/configs/webpack/loaders/extensions-loader.test.js @@ -66,6 +66,8 @@ describe('Extension Loader', () => { {packageName: 'extension-this', instanceVariable: This} ] + // TODO: Once we create @salesforce/pwa-kit-extensibility we will refactor this code to use a shared utility that + // normalizes/expands the configuration array before it is uses in this loader. const normalizeExtensionsList = (extensions = []) => extensions.map((extension) => { return { diff --git a/packages/pwa-kit-dev/src/utils/extensibility-utils.js b/packages/pwa-kit-dev/src/utils/extensibility-utils.js index 650e56ccce..6449a381bc 100644 --- a/packages/pwa-kit-dev/src/utils/extensibility-utils.js +++ b/packages/pwa-kit-dev/src/utils/extensibility-utils.js @@ -125,5 +125,5 @@ export const getExtensionNames = (extensions) => { */ export const isEnabled = (extensionEntry = []) => { const [name, config = {}] = extensionEntry - return name && config?.enabled !== false + return !!(name && config?.enabled !== false) } From abc3318c775aa1ee3aafe5f114cdbada53842f0b Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 8 Oct 2024 10:47:47 -0700 Subject: [PATCH 145/929] Initial Commit --- .../extension-sample-with-overrides/README.md | 68 - .../example/EXAMPLE_PROJECT.md | 9 - .../package-lock.json | 986 ------------- .../package.json | 24 - .../src/setup-app.ts | 25 - .../src/setup-server.ts | 22 - .../src/types/config.ts | 26 - .../static/salesforce-logo.svg | 31 - packages/extension-sample/package.json | 3 +- packages/extension-sample/src/setup-app.ts | 4 +- packages/extension-sample/src/types/config.ts | 16 +- packages/pwa-kit-dev/package.json | 2 +- .../pwa-kit-dev/src/configs/webpack/config.js | 23 +- .../pwa-kit-extension-support/.eslintignore | 7 + .../pwa-kit-extension-support/.eslintrc.js | 10 + packages/pwa-kit-extension-support/.gitignore | 20 + packages/pwa-kit-extension-support/.npmignore | 1 + .../pwa-kit-extension-support/.prettierignore | 5 + .../.prettierrc.yaml | 7 + .../CHANGELOG.md} | 0 packages/pwa-kit-extension-support/LICENSE | 14 + packages/pwa-kit-extension-support/README.md | 0 .../package-lock.json | 1278 +++++++++++++++++ .../pwa-kit-extension-support/package.json | 57 + .../webpack/loaders/extensions-loader.test.js | 93 ++ .../webpack/loaders/extensions-loader.ts | 119 ++ .../plugins/overrides-resolver-plugin.test.js | 204 +++ .../plugins/overrides-resolver-plugin.ts | 109 ++ .../src/core/application-extension.ts | 74 + .../src/core/extensions.ts | 14 + .../src/core/index.ts | 12 + .../src/types/application-extension-config.ts | 10 + .../src/types/index.ts | 2 +- .../src/utils/extensibility-utils.test.js | 0 .../src/utils/extensibility-utils.ts} | 18 +- .../src/utils/index.ts | 54 + .../src/utils/resolver-utils.test.js | 0 .../src/utils/resolver-utils.ts} | 27 +- .../src/utils/utils.ts | 49 + .../pwa-kit-extension-support/tsconfig.json | 105 ++ packages/pwa-kit-react-sdk/package.json | 1 + .../src/ssr/server/react-rendering.js | 5 +- .../overrides/components/with-red-border.tsx | 2 +- .../template-typescript-minimal/package.json | 5 +- 44 files changed, 2304 insertions(+), 1237 deletions(-) delete mode 100644 packages/extension-sample-with-overrides/README.md delete mode 100644 packages/extension-sample-with-overrides/example/EXAMPLE_PROJECT.md delete mode 100644 packages/extension-sample-with-overrides/package-lock.json delete mode 100644 packages/extension-sample-with-overrides/package.json delete mode 100644 packages/extension-sample-with-overrides/src/setup-app.ts delete mode 100644 packages/extension-sample-with-overrides/src/setup-server.ts delete mode 100644 packages/extension-sample-with-overrides/src/types/config.ts delete mode 100644 packages/extension-sample-with-overrides/static/salesforce-logo.svg create mode 100644 packages/pwa-kit-extension-support/.eslintignore create mode 100644 packages/pwa-kit-extension-support/.eslintrc.js create mode 100644 packages/pwa-kit-extension-support/.gitignore create mode 100644 packages/pwa-kit-extension-support/.npmignore create mode 100644 packages/pwa-kit-extension-support/.prettierignore create mode 100644 packages/pwa-kit-extension-support/.prettierrc.yaml rename packages/{extension-sample-with-overrides/static/README.md => pwa-kit-extension-support/CHANGELOG.md} (100%) create mode 100644 packages/pwa-kit-extension-support/LICENSE create mode 100644 packages/pwa-kit-extension-support/README.md create mode 100644 packages/pwa-kit-extension-support/package-lock.json create mode 100644 packages/pwa-kit-extension-support/package.json create mode 100644 packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.test.js create mode 100644 packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts create mode 100644 packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.test.js create mode 100644 packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts create mode 100644 packages/pwa-kit-extension-support/src/core/application-extension.ts create mode 100644 packages/pwa-kit-extension-support/src/core/extensions.ts create mode 100644 packages/pwa-kit-extension-support/src/core/index.ts create mode 100644 packages/pwa-kit-extension-support/src/types/application-extension-config.ts rename packages/{extension-sample-with-overrides => pwa-kit-extension-support}/src/types/index.ts (75%) rename packages/{pwa-kit-dev => pwa-kit-extension-support}/src/utils/extensibility-utils.test.js (100%) rename packages/{pwa-kit-dev/src/utils/extensibility-utils.js => pwa-kit-extension-support/src/utils/extensibility-utils.ts} (86%) create mode 100644 packages/pwa-kit-extension-support/src/utils/index.ts rename packages/{pwa-kit-dev => pwa-kit-extension-support}/src/utils/resolver-utils.test.js (100%) rename packages/{pwa-kit-dev/src/utils/resolver-utils.js => pwa-kit-extension-support/src/utils/resolver-utils.ts} (86%) create mode 100644 packages/pwa-kit-extension-support/src/utils/utils.ts create mode 100644 packages/pwa-kit-extension-support/tsconfig.json rename packages/{extension-sample-with-overrides/src => template-typescript-minimal/app}/overrides/components/with-red-border.tsx (91%) diff --git a/packages/extension-sample-with-overrides/README.md b/packages/extension-sample-with-overrides/README.md deleted file mode 100644 index d19ecefd06..0000000000 --- a/packages/extension-sample-with-overrides/README.md +++ /dev/null @@ -1,68 +0,0 @@ - __ _ __ _ _ -/ _\ __ _ _ __ ___ _ __ | | ___ /__\_ _| |_ ___ _ __ ___(_) ___ _ __ -\ \ / _` | '_ ` _ \| '_ \| |/ _ \ /_\ \ \/ / __/ _ \ '_ \/ __| |/ _ \| '_ \ -_\ \ (_| | | | | | | |_) | | __/ //__ > <| || __/ | | \__ \ | (_) | | | | -\__/\__,_|_| |_| |_| .__/|_|\___| \__/ /_/\_\\__\___|_| |_|___/_|\___/|_| |_| - |_| - -# Description - -This is a sample PWA-Kit Application Extension. The purpose of this application extensions is to show how -the Application Extensions API can be used to enhance your PWA-Kit base project. - -# Folder Structure - -Insert description of generic Application Extension folder structure here. - -# Peer Dependancies - -PWA-Kit Application Extensions are NPM packages at their most simplest form, and as such you can define -what peer dependencies are required when using it. Because this sample application extension provides -UI via a new "Sample" page, it requires that the below dependencies are installed at a minimum. - -Depending on what features your application extensions provides it's recommended you include any third-party -packages as peer dependencies so that your base application doesn't end up having multiple versions of a -given package. - -"react": "^18.2.0", -"react-dom": "^18.2.0" - -# Configuration - -This section is optional and will depend on your application extensions implementation. If you have features -that are configurable, then list those configurations here so that the PWA-Kit project implementor can configure -the extension as they like. - -``` -{ - path: 'sample-page' -} -``` - -# Installation - -``` -> npm install @salesforce/extension-sample --legacy-peer-deps*
-> Downloading npm package...
-> Installing extention...
-> Finished.
-> Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. -``` - -# Advanced Usage - -In order to customize this Application Extension to your particulare needs we suggest that you refer to the section titled -"configuration", but if there is something that you want to customize that isn't configurable and cannot wait for a feature -request to be fulfilled, then you can use overrides. - -Below is a list of files that can't be overridden from within your PWA-Kit base project. Please refer to the documentation here on -how to properly override extensions. Additionally it's up to the Application Extension developer as to which files can and -cannot be overridden. Please refer to this documentation on how to write your first PWA-Kit Application Extension. - -## Overridable Files - -``` -/src/path/to/overridable/file.ts -``` - - diff --git a/packages/extension-sample-with-overrides/example/EXAMPLE_PROJECT.md b/packages/extension-sample-with-overrides/example/EXAMPLE_PROJECT.md deleted file mode 100644 index 1d2550062d..0000000000 --- a/packages/extension-sample-with-overrides/example/EXAMPLE_PROJECT.md +++ /dev/null @@ -1,9 +0,0 @@ -# Description - -This folder will house a sample PWA-Kit project built using the `template-typescript-minimal` base project. Its -purpose is to test the Application Extension being developed without having to manually install it in another -project. - -Additionally we'll update the `create-app` project so that we can generate a stub implementation of an Application -Extensions. This will reduce the friction for "Extension Developers", it will also allow use to use TypeScript -soley. \ No newline at end of file diff --git a/packages/extension-sample-with-overrides/package-lock.json b/packages/extension-sample-with-overrides/package-lock.json deleted file mode 100644 index d62908b37e..0000000000 --- a/packages/extension-sample-with-overrides/package-lock.json +++ /dev/null @@ -1,986 +0,0 @@ -{ - "name": "@salesforce/extension-sample", - "version": "1.0.0-dev", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@salesforce/extension-sample", - "version": "1.0.0-dev", - "devDependencies": { - "@loadable/component": "^5.15.3", - "@types/react": "~18.2.0", - "@types/react-dom": "~18.2.1", - "express": "^4.19.2", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - }, - "peerDependencies": { - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", - "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@loadable/component": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", - "integrity": "sha512-fJWxx9b5WHX90QKmizo9B+es2so8DnBthI1mbflwCoOyvzEwxiZ/SVDCTtXEnHG72/kGBdzr297SSIekYtzSOQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.18", - "hoist-non-react-statics": "^3.3.1", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.2.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", - "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", - "dev": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.2.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", - "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.20.0.tgz", - "integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "dev": true - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/serve-static": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.0.tgz", - "integrity": "sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-static/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-static/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/serve-static/node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - } - } -} diff --git a/packages/extension-sample-with-overrides/package.json b/packages/extension-sample-with-overrides/package.json deleted file mode 100644 index 5aeeb9b1e2..0000000000 --- a/packages/extension-sample-with-overrides/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@salesforce/extension-sample-with-overrides", - "version": "1.0.0-dev", - "scripts": {}, - "peerDependencies": { - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", - "@salesforce/pwa-kit-runtime": "4.0.0-dev", - "@types/react": "~18.2.0", - "@types/react-dom": "~18.2.1", - "express": "^4.19.2", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "engines": { - "node": "^16.11.0 || ^18.0.0 || ^20.0.0", - "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - } -} diff --git a/packages/extension-sample-with-overrides/src/setup-app.ts b/packages/extension-sample-with-overrides/src/setup-app.ts deleted file mode 100644 index 5167f336c0..0000000000 --- a/packages/extension-sample-with-overrides/src/setup-app.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' -import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' - -import {ReactExtensionConfig as Config} from './types' - -const defaultPath: string = '/sample-page' -class Sample extends ApplicationExtension { - extendApp(App: React.ComponentType): React.ComponentType { - return App - } - - extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { - console.log('Extend Routes for ', this.getName()) - return routes - } -} - -export default Sample diff --git a/packages/extension-sample-with-overrides/src/setup-server.ts b/packages/extension-sample-with-overrides/src/setup-server.ts deleted file mode 100644 index 0f5ef21b05..0000000000 --- a/packages/extension-sample-with-overrides/src/setup-server.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import { - Application as ExpressApplication, - ApplicationExtension as ExpressApplicationExtension -} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' -import {ServerExtensionConfig as Config} from './types' - -class SampleExtension extends ExpressApplicationExtension { - - extendApp(app: ExpressApplication): ExpressApplication { - - return app - } -} - -export default SampleExtension diff --git a/packages/extension-sample-with-overrides/src/types/config.ts b/packages/extension-sample-with-overrides/src/types/config.ts deleted file mode 100644 index fa9d245435..0000000000 --- a/packages/extension-sample-with-overrides/src/types/config.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import { - ApplicationExtensionConfig as _ServerExtensionConfig -} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' - -import { - ApplicationExtensionConfig as _ReactExtensionConfig -} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' - -// This is where you are going to define the configuration type for your App Extension. This is used in the constructor -// of the extension itself. Update this config type to your specific needs! - -// TODO: Rather than 2 duplicate types, how can we have a single config type here? -export interface ServerExtensionConfig extends _ServerExtensionConfig { - // react-router-style path to the new sample page - path?: string -} -export interface ReactExtensionConfig extends _ReactExtensionConfig { - // react-router-style path to the new sample page - path?: string -} diff --git a/packages/extension-sample-with-overrides/static/salesforce-logo.svg b/packages/extension-sample-with-overrides/static/salesforce-logo.svg deleted file mode 100644 index b2f3856b54..0000000000 --- a/packages/extension-sample-with-overrides/static/salesforce-logo.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/extension-sample/package.json b/packages/extension-sample/package.json index 8206fe55bd..f739f9c88a 100644 --- a/packages/extension-sample/package.json +++ b/packages/extension-sample/package.json @@ -9,8 +9,7 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", - "@salesforce/pwa-kit-runtime": "4.0.0-dev", + "@salesforce/pwa-kit-extension-support": "4.0.0-dev", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "express": "^4.19.2", diff --git a/packages/extension-sample/src/setup-app.ts b/packages/extension-sample/src/setup-app.ts index 1cba0a4a7d..e83646c293 100644 --- a/packages/extension-sample/src/setup-app.ts +++ b/packages/extension-sample/src/setup-app.ts @@ -10,7 +10,7 @@ import loadable from '@loadable/component' import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' import withRedBorder from '*/components/with-red-border' -import {ReactExtensionConfig as Config} from './types' +import {Config} from './types' const SamplePage = loadable(() => import('*/pages/sample')) @@ -21,7 +21,7 @@ class Sample extends ApplicationExtension { } extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { - console.log('Extend Routes for ', this.getName()) + console.log('Extend Routes for ', this.getName(), this.getConfig().path || defaultPath) return [ { exact: true, diff --git a/packages/extension-sample/src/types/config.ts b/packages/extension-sample/src/types/config.ts index fa9d245435..e1fec00a8d 100644 --- a/packages/extension-sample/src/types/config.ts +++ b/packages/extension-sample/src/types/config.ts @@ -4,23 +4,11 @@ * 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 */ -import { - ApplicationExtensionConfig as _ServerExtensionConfig -} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' - -import { - ApplicationExtensionConfig as _ReactExtensionConfig -} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' +import type {ApplicationExtensionConfig} from '@salesforce/pwa-kit-extension-support/types' // This is where you are going to define the configuration type for your App Extension. This is used in the constructor // of the extension itself. Update this config type to your specific needs! - -// TODO: Rather than 2 duplicate types, how can we have a single config type here? -export interface ServerExtensionConfig extends _ServerExtensionConfig { - // react-router-style path to the new sample page - path?: string -} -export interface ReactExtensionConfig extends _ReactExtensionConfig { +export interface Config extends ApplicationExtensionConfig { // react-router-style path to the new sample page path?: string } diff --git a/packages/pwa-kit-dev/package.json b/packages/pwa-kit-dev/package.json index ec7326c77f..afe6c130d7 100644 --- a/packages/pwa-kit-dev/package.json +++ b/packages/pwa-kit-dev/package.json @@ -58,7 +58,7 @@ "@loadable/server": "^5.15.3", "@loadable/webpack-plugin": "^5.15.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", - "@salesforce/pwa-kit-runtime": "4.0.0-dev", + "@salesforce/pwa-kit-extension-support": "4.0.0-dev", "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.57.0", "archiver": "1.3.0", diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 86897633bd..6cf32d72ec 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -20,8 +20,11 @@ import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin' import SpeedMeasurePlugin from 'speed-measure-webpack-plugin' import WebpackNotifierPlugin from 'webpack-notifier' +// TODO: Simplify the exports in this package. +import OverridesResolverPlugin from '@salesforce/pwa-kit-extension-support/configs/webpack/plugins/overrides-resolver-plugin.js' + // Local Plugins -import OverridesResolverPlugin from './plugins/overrides-resolver-plugin' +// import OverridesResolverPlugin from './plugins/overrides-resolver-plugin' import {sdkReplacementPlugin} from './plugins' // Constants @@ -29,7 +32,8 @@ import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config- // Utilities import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -import {buildAliases, getExtensionNames, nameRegex} from '../../utils/extensibility-utils' +// import {buildAliases, getExtensionNames, nameRegex} from '../../utils/extensibility-utils' +import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/utils/extensibility-utils.js' const projectDir = process.cwd() const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) @@ -252,10 +256,17 @@ const baseConfig = (target) => { } }, { - test: /universal[\\/]+extensibility[\\/]+extensions/, - loader: `@salesforce/pwa-kit-dev/configs/webpack/loaders/extensions-loader`, - options: { - pkg + // NOTE: Might be better to export a rule directly that we can plog in here, this will + // make the "extensions" file private so was can change that implementation detail later + // if we choose to do so. + test: /core[\\/]+extensions/, + // loader: '@salesforce/pwa-kit-extension-support/dist/configs/webpack/loaders/extensions-loader', + use: { + loader: findDepInStack('@salesforce/pwa-kit-extension-support/dist/configs/webpack/loaders/extensions-loader'), + options: { + pkg, + getConfig + } } } ].filter(Boolean) diff --git a/packages/pwa-kit-extension-support/.eslintignore b/packages/pwa-kit-extension-support/.eslintignore new file mode 100644 index 0000000000..1b836c1987 --- /dev/null +++ b/packages/pwa-kit-extension-support/.eslintignore @@ -0,0 +1,7 @@ +coverage +dist +docs +generator-assets +vendor +temp +temp_static diff --git a/packages/pwa-kit-extension-support/.eslintrc.js b/packages/pwa-kit-extension-support/.eslintrc.js new file mode 100644 index 0000000000..6c346cb7aa --- /dev/null +++ b/packages/pwa-kit-extension-support/.eslintrc.js @@ -0,0 +1,10 @@ +/* + * 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 + */ + +module.exports = { + extends: ['./dist/configs/eslint/no-react.js'] +} diff --git a/packages/pwa-kit-extension-support/.gitignore b/packages/pwa-kit-extension-support/.gitignore new file mode 100644 index 0000000000..b1e401cc24 --- /dev/null +++ b/packages/pwa-kit-extension-support/.gitignore @@ -0,0 +1,20 @@ +.projectile +.DS_Store +build +dist +coverage +docs/www +docs/public/latest/styleguidist +docs/public/latest/theme/ +docs/public/latest/utility-functions/reference/ +node_modules +/npm-debug.log +/tmp +/.vscode +.idea/ +.tern-port +temp/ +temp_static/ +src/static/browser-detection.min.js +progressive-web-sdk-*.tgz +!src/ssr/server/test_fixtures/node_modules \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/.npmignore b/packages/pwa-kit-extension-support/.npmignore new file mode 100644 index 0000000000..d8f8d46921 --- /dev/null +++ b/packages/pwa-kit-extension-support/.npmignore @@ -0,0 +1 @@ +docs diff --git a/packages/pwa-kit-extension-support/.prettierignore b/packages/pwa-kit-extension-support/.prettierignore new file mode 100644 index 0000000000..9504b7397b --- /dev/null +++ b/packages/pwa-kit-extension-support/.prettierignore @@ -0,0 +1,5 @@ +coverage +dist +generator-assets +docs +vendor diff --git a/packages/pwa-kit-extension-support/.prettierrc.yaml b/packages/pwa-kit-extension-support/.prettierrc.yaml new file mode 100644 index 0000000000..33069bf2b2 --- /dev/null +++ b/packages/pwa-kit-extension-support/.prettierrc.yaml @@ -0,0 +1,7 @@ +printWidth: 100 +singleQuote: true +semi: false +bracketSpacing: false +tabWidth: 4 +arrowParens: 'always' +trailingComma: 'none' diff --git a/packages/extension-sample-with-overrides/static/README.md b/packages/pwa-kit-extension-support/CHANGELOG.md similarity index 100% rename from packages/extension-sample-with-overrides/static/README.md rename to packages/pwa-kit-extension-support/CHANGELOG.md diff --git a/packages/pwa-kit-extension-support/LICENSE b/packages/pwa-kit-extension-support/LICENSE new file mode 100644 index 0000000000..d8f701f7ed --- /dev/null +++ b/packages/pwa-kit-extension-support/LICENSE @@ -0,0 +1,14 @@ +BSD 3-Clause License + +Copyright (c) 2021, Salesforce.com, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/pwa-kit-extension-support/README.md b/packages/pwa-kit-extension-support/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/pwa-kit-extension-support/package-lock.json b/packages/pwa-kit-extension-support/package-lock.json new file mode 100644 index 0000000000..dd63a8d21d --- /dev/null +++ b/packages/pwa-kit-extension-support/package-lock.json @@ -0,0 +1,1278 @@ +{ + "name": "@salesforce/pwa-kit-extension-support", + "version": "4.0.0-dev", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@salesforce/pwa-kit-extension-support", + "version": "4.0.0-dev", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "dedent": "^1.5.3", + "fs-extra": "^11.2.0", + "hoist-non-react-statics": "^3.3.2", + "resolve": "^1.22.8" + }, + "devDependencies": { + "@types/fs-extra": "^11.0.4", + "@types/hoist-non-react-statics": "~3.3.5", + "@types/node": "^20", + "@types/react-router-dom": "^5.3.3", + "@types/resolve": "^1.20.6", + "@types/webpack": "^5.28.5", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^5.3.4", + "type-fest": "^4.26.1" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^5.3.4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "dev": true + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dev": true, + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.16.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", + "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dev": true, + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dev": true, + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true + }, + "node_modules/@types/webpack": { + "version": "5.28.5", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-5.28.5.tgz", + "integrity": "sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "tapable": "^2.2.0", + "webpack": "^5" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.33", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", + "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.34.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz", + "integrity": "sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "dev": true + }, + "node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "dev": true + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + } + } +} diff --git a/packages/pwa-kit-extension-support/package.json b/packages/pwa-kit-extension-support/package.json new file mode 100644 index 0000000000..232c874ca3 --- /dev/null +++ b/packages/pwa-kit-extension-support/package.json @@ -0,0 +1,57 @@ +{ + "name": "@salesforce/pwa-kit-extension-support", + "version": "4.0.0-dev", + "description": "", + "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit#readme", + "bugs": { + "url": "https://github.com/SalesforceCommerceCloud/pwa-kit/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/SalesforceCommerceCloud/pwa-kit.git" + }, + "license": "SEE LICENSE IN LICENSE", + "author": "cc-pwa-kit@salesforce.com", + "files": [ + "CHANGELOG.md", + "LICENSE", + "configs", + "core", + "types", + "utils" + ], + "exports": { + "./*": "./dist/*" + }, + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc" + }, + "dependencies": { + "dedent": "^1.5.3", + "fs-extra": "^11.2.0", + "hoist-non-react-statics": "^3.3.2", + "resolve": "^1.22.8" + }, + "devDependencies": { + "@types/fs-extra": "^11.0.4", + "@types/hoist-non-react-statics": "~3.3.5", + "@types/node": "^20", + "@types/react-router-dom": "^5.3.3", + "@types/resolve": "^1.20.6", + "@types/webpack": "^5.28.5", + "type-fest": "^4.26.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^5.3.4" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^5.3.4" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + } +} diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.test.js b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.test.js new file mode 100644 index 0000000000..ee0a860745 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.test.js @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' +import dedent from 'dedent' +import compiler from './test/compiler' + +const mockConfig = { + app: { + extensions: [ + ['@salesforce/extension-this', {path: '/foo'}], + '@salesforce/extension-that', + '@companyx/extension-another', + 'extension-this' + ] + } +} + +const mockPkgConfig = { + devDependencies: { + '@salesforce/extension-this': '1.0.0-dev', + '@salesforce/extension-that': '1.0.0-dev', + '@companyx/extension-another': '1.0.0-dev', + 'extension-this': '1.0.0-dev' + } +} + +jest.mock('@salesforce/pwa-kit-runtime/utils/ssr-config', () => { + return { + getConfig: jest.fn(() => mockConfig) + } +}) + +describe('Extension Loader', () => { + beforeAll(() => { + getConfig.mockImplementation(() => mockConfig) + }) + + test('Returns single file re-exporting all extensions configured.', async () => { + const stats = await compiler('mock-extensions.js', {pkg: mockPkgConfig}) + const output = stats.toJson({source: true}).modules[1].source + + expect(output).toBe(dedent` + /* + * Copyright (c) 2024, salesforce.com, 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 + */ + import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' + + // App Extensions + import SalesforceThis from '@salesforce/extension-this/setup-app' + import SalesforceThat from '@salesforce/extension-that/setup-app' + import CompanyxAnother from '@companyx/extension-another/setup-app' + import This from 'extension-this/setup-app' + + const installedExtensions = [ + {packageName: '@salesforce/extension-this', instanceVariable: SalesforceThis}, + {packageName: '@salesforce/extension-that', instanceVariable: SalesforceThat}, + {packageName: '@companyx/extension-another', instanceVariable: CompanyxAnother}, + {packageName: 'extension-this', instanceVariable: This} + ] + + // TODO: Once we create @salesforce/pwa-kit-extensibility we will refactor this code to use a shared utility that + // normalizes/expands the configuration array before it is uses in this loader. + const normalizeExtensionsList = (extensions = []) => + extensions.map((extension) => { + return { + packageName: Array.isArray(extension) ? extension[0] : extension, + config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} + } + }) + + export const getExtensions = () => { + const configuredExtensions = (normalizeExtensionsList(getConfig()?.app?.extensions) || []) + .filter((extension) => extension.config.enabled) + .map((extension) => { + // Make sure that the configured extensions are installed, before instantiating them + const found = installedExtensions.find((ext) => ext.packageName === extension.packageName) + return found ? new found.instanceVariable(extension.config || {}) : false + }) + .filter(Boolean) + + return configuredExtensions + } + `) + }) +}) diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts new file mode 100644 index 0000000000..273602d61c --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2024, 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 + */ + +import dedent from 'dedent' +import {LoaderContext} from 'webpack' +import {PackageJson} from 'type-fest' + +import {kebabToUpperCamelCase} from '../../../utils' +import {nameRegex} from '../../../utils/extensibility-utils' + +const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' +const APP_EXTENSION_PREFIX = 'extension' // aligns with what's in `nameRegex` + +// TODO: Move these to a better location. +interface ExtensionsLoaderOptions { + pkg: PackageJson, + getConfig: () => any +} + +interface ExtensionsLoaderContext extends LoaderContext { + // You can add any additional properties if needed +} + +/** + * The `extensions-loader` as a mechanism to get all configured extensions for a given pwa-kit + * application. We use this loader as a simple way to determine what extension code in required in + * the application bundle, without this we would have to rely on other more complex ways of + * including application extensions in the bundle, like custom webpack entry points for extension. + * + * With this solution we can rely on the fact that all installed application extensions are referenced + * in code and will be in the bundle. + * + * The named export `getExtensions` will only return the application extensions required/configured by + * the current PWA-Kit application. + * + * @returns {string} The string representation of a module exporting all the named application extension modules. + */ +module.exports = function (this: ExtensionsLoaderContext) { + const {pkg, getConfig} = this.getOptions() || {} + const {devDependencies} = pkg + + // TODO: clean this up.. looks like this is a bad variable name for the type that it represents. + const extensions = Object.keys(devDependencies || {}) + .map((packageName) => packageName.match(nameRegex)) + .filter(Boolean) + + // Ensure that only valid extension names are loaded. + const extensionDetails = extensions.map((match) => { + const [packageName, namespace, name] = match || [] + return { + instanceVariable: kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`), + modulePath: `${ + namespace ? `@${namespace}/` : '' + }${APP_EXTENSION_PREFIX}-${name}/${APP_EXTENSION_CLIENT_ENTRY}`, + packageName + } + }) + + const appExtensions = getConfig()?.app?.extensions + // TODO: later consider updating `normalizeExtensionsList` to use a util function + const result = dedent` + /* + * Copyright (c) 2024, salesforce.com, 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 + */ + // NOTE: I'm not completely sure why this was giving me isses as it should be running in the context of the + // base application and not the extension-support project. + // import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' + + // TODO: Once we create @salesforce/pwa-kit-extensibility we will refactor this code to use a shared utility that + // normalizes/expands the configuration array before it is uses in this loader. + const normalizeExtensionsList = (extensions = []) => + extensions.map((extension) => { + return { + packageName: Array.isArray(extension) ? extension[0] : extension, + config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} + } + }) + + // App Extensions + ${extensionDetails + .map( + ({instanceVariable, modulePath}) => + `import ${instanceVariable} from '${modulePath}'` + ) + .join('\n ')} + + const installedExtensions = [ + ${extensionDetails + .map( + ({packageName, instanceVariable}) => + `{packageName: '${packageName}', instanceVariable: ${instanceVariable}}` + ) + .join(',\n ')} + ] + + const configuredExtensions = (normalizeExtensionsList(${JSON.stringify(appExtensions)}) || []) + .filter((extension) => extension.config.enabled) + .map((extension) => { + // Make sure that the configured extensions are installed, before instantiating them + const found = installedExtensions.find((ext) => ext.packageName === extension.packageName) + return found ? new found.instanceVariable(extension.config || {}) : false + }) + .filter(Boolean) + + export const getExtensions = () => { + return configuredExtensions + } + ` + + console.log('result: ', result) + return result +} diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.test.js b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.test.js new file mode 100644 index 0000000000..9cb094dfba --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.test.js @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import {BASE_DIR, runWebpackCompiler} from '../test-utils' +import OverridesResolverPlugin from './overrides-resolver-plugin' + +describe('Overrides Resolver Plugin', () => { + const testCases = [ + { + description: 'Wildcard import resolves to correct base project file', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-this', '@salesforce/extension-that'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'`, + + // Overrides + + // Local Files + '/virtual/project/app/pages/sample-page.jsx': '// Base Project - Sample Page', + + // Extensions Overrides + '/virtual/project/node_modules/@salesforce/extension-that/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-that', + '/virtual/project/node_modules/@salesforce/extension-this/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-this' + // TODO: Why don't index files work here? + } + }, + expects: (output) => { + expect(output.modules[1].source).toBe('// Base Project - Sample Page') + } + }, + { + description: 'Wildcard import resolved to correct extension override', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-this', '@salesforce/extension-that'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'`, + + // Overrides + + // Extensions Overrides + '/virtual/project/node_modules/@salesforce/extension-that/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-that', + '/virtual/project/node_modules/@salesforce/extension-this/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-this' + // TODO: Why don't index files work here? + } + }, + expects: (output) => { + expect(output.modules[1].source).toBe('// @salesforce/extension-that') + } + }, + { + description: + 'Wildcard import resolved to correct extension override when app extension is reversed', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-that', '@salesforce/extension-this'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'`, + + // Overrides + + // Extensions Overrides + '/virtual/project/node_modules/@salesforce/extension-that/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-that', + '/virtual/project/node_modules/@salesforce/extension-this/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-this' + // TODO: Why don't index files work here? + } + }, + expects: (output) => { + expect(output.modules[1].source).toBe('// @salesforce/extension-this') + } + }, + { + description: + 'Wildcard import pioritizes module resolution to the "overrides" folder if match import exists.', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-that', '@salesforce/extension-this'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'`, + + // Overrides + + // Extensions Overrides + '/virtual/project/node_modules/@salesforce/extension-this/src/pages/sample-page.jsx': + '// @salesforce/extension-this', + '/virtual/project/node_modules/@salesforce/extension-this/src/overrides/pages/sample-page.jsx': + '// @salesforce/extension-this-override' + // TODO: Why don't index files work here? + } + }, + expects: (output) => { + expect(output.modules[1].source).toBe('// @salesforce/extension-this-override') + } + }, + { + description: 'Wildcard import throws when no match is found.', + entryPoint: 'app/routes.jsx', + // Compiler configuration. + compilerConfig: { + extensions: ['@salesforce/extension-that', '@salesforce/extension-this'], + files: { + // Virtual Project Files + + // Entry Point + '/virtual/project/app/routes.jsx': `import SamplePage from '*/pages/sample-page'` + + // Overrides + } + }, + expects: (_, err) => { + // console.log('output: ', output) + expect(err).toBeDefined() + } + } + ] + + testCases.forEach((options) => { + const {compilerConfig, description, entryPoint, expects} = options + const {extensions, files} = compilerConfig + + test(`${description}`, async () => { + let output, err + + try { + const stats = await runWebpackCompiler(entryPoint, { + files, + buildPlugins: ({fileSystem}) => { + return [ + new OverridesResolverPlugin({ + projectDir: BASE_DIR, + extensions: extensions, + fileExtensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], + resolveOptions: { + // Override the `fs` methods used by `resolve` to point to the virtual file system + readFile: (filePath, encoding, cb) => { + try { + const data = fileSystem.readFileSync(filePath, encoding) + cb(null, data) + } catch (err) { + cb(err) + } + }, + isFile: (filePath) => { + try { + return fileSystem.statSync(filePath).isFile() + } catch (e) { + return false + } + }, + isDirectory: (dirPath) => { + try { + return fileSystem.statSync(dirPath).isDirectory() + } catch (e) { + return false + } + }, + realpath: (filePath, cb) => { + // In the virtual file system, the real path is just the file path itself + cb(null, filePath) + }, + realpathSync: (filePath) => filePath // Sync version + } + }) + ] + } + }) + + // Here we are looking at the first module imported via the wildcard syntax and testing that it's right. + output = stats.toJson({source: true}) + } catch (e) { + err = e + } + + expects(output, err) + }) + }) +}) diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts new file mode 100644 index 0000000000..d7e4730f3a --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024, 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 + */ + +import resolve from 'resolve' +import {Resolver} from 'webpack' + +import {buildCandidatePaths} from '../../../utils/resolver-utils' + +export const DEFAULT_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.json'] + +interface OverridesResolverPluginOptions { + projectDir: string + extensions: ApplicationExtensionEntry[] + fileExtensions?: string[] + resolveOptions: any +} + +interface ApplicationExtensionConfig extends Record { + enabled: boolean +} +type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] +type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string + + +const defaultOptions = { + projectDir: process.cwd(), + extensions: [], + fileExtension: DEFAULT_FILE_EXTENSIONS, + resolveOptions: {} +} + +/** + * @class OverridesResolverPlugin + * + * This plugin provides the "overrides" behavior of the application extensibility feature. This allows + * App Extension developers to define which files are part of their public api thus can be overridden, but + * also the module resolution algorithm. + */ +class OverridesResolverPlugin { + private options: OverridesResolverPluginOptions + + constructor(options: OverridesResolverPluginOptions) { + this.options = { + ...defaultOptions, + ...options + } + } + + handleHook( + request: any, + resolveContext: any, + callback: (err?: Error | null, result?: any) => void, + resolver: Resolver + ) { + // Early exit for none Feature Loader imports + if (!request.request.startsWith('*')) { + callback() + return + } + const target = resolver.ensureHook('resolved') + const importPath = request.request + const sourcePath = request.context.issuer + + // Resolve the import with the provided packageIterator. + let modulePath + + try { + modulePath = resolve.sync(importPath, { + basedir: this.options.projectDir, + extensions: this.options.fileExtensions, + packageIterator: () => + buildCandidatePaths(importPath, sourcePath, { + extensionEntries: this.options.extensions, + projectDir: this.options.projectDir + }), + ...this.options.resolveOptions + }) + } catch (e: any) { + return callback(e) + } + + // Update the requests path with the one resoved from above. + request.path = modulePath + + resolver.doResolve( + target, + request, + `${this.constructor.name} found base override file`, + resolveContext, + callback + ) + } + + apply(resolver: Resolver) { + resolver + .getHook('resolve') + .tapAsync( + 'OverridesResolverPlugin', + (requestContext: any, resolveContext: any, callback: (err?: Error | null, result?: any) => void) => { + this.handleHook(requestContext, resolveContext, callback, resolver) + }) + } +} + +export default OverridesResolverPlugin diff --git a/packages/pwa-kit-extension-support/src/core/application-extension.ts b/packages/pwa-kit-extension-support/src/core/application-extension.ts new file mode 100644 index 0000000000..278c47e45b --- /dev/null +++ b/packages/pwa-kit-extension-support/src/core/application-extension.ts @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import {RouteProps} from 'react-router-dom' + +/** + * An abstract class representing an Application Extension. This class provides + * foundational methods and properties for extending an application with additional + * configuration and routing capabilities. It is designed to be subclassed + * by other Application Extensions that need to augment the base application, particularly + * during server and client-side rendering. + * + * @abstract + */ +export default abstract class ApplicationExtension { + private config: Config + + /** + * Constructs a new instance of the ApplicationExtension class. + * + * @param config - The configuration object used to set up the extension. + */ + constructor(config: Config) { + this.config = config + } + + /** + * Returns the configuration that was used to instantiate this application extension. + * + * @protected + * @returns config - The configuration object. + */ + public getConfig(): Config { + return this.config + } + + /** + * Returns the name of the extension that will be used for logging. + * + * @protected + * @returns name - The name of the extension. + */ + public getName(): string { + return this.constructor.name + } + + /** + * Called during the rendering of the base application on the server and the client. + * It is predominantly used to enhance the "base" application by wrapping it with React providers. + * + * @protected + * @param App - The base application component. + * @returns EnhancedApp - The enhanced application component. + */ + public extendApp(App: React.ComponentType): React.ComponentType { + return App + } + + /** + * Called during server rendering and client application initialization. This method allows + * you to modify the routes of the base application, typically used to add new routes pointing + * at page components added by your application extension. + * + * @protected + * @param routes - The base application routes. + * @returns routes - The modified application routes. + */ + public extendRoutes(routes: RouteProps[]): RouteProps[] { + return routes + } +} diff --git a/packages/pwa-kit-extension-support/src/core/extensions.ts b/packages/pwa-kit-extension-support/src/core/extensions.ts new file mode 100644 index 0000000000..60b4b8efdb --- /dev/null +++ b/packages/pwa-kit-extension-support/src/core/extensions.ts @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +// This file exports an empty function. During local development and the production build process, +// it'll be replaced to return those application extensions configured by the base PWA-Kit project. +const getExtensions = () => {} + +export default { + getExtensions +} diff --git a/packages/pwa-kit-extension-support/src/core/index.ts b/packages/pwa-kit-extension-support/src/core/index.ts new file mode 100644 index 0000000000..8cf1213918 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/core/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +// TODO: Figure out why this index file isn't working. E.g. import {extensions} from '../universal/extensibility' +// is broken. + +export {default as extensions} from './extensions' +export {default as ApplicationExtension} from './application-extension' diff --git a/packages/pwa-kit-extension-support/src/types/application-extension-config.ts b/packages/pwa-kit-extension-support/src/types/application-extension-config.ts new file mode 100644 index 0000000000..1e80f7cfa4 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/types/application-extension-config.ts @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export interface ApplicationExtensionConfig extends Record { + enabled: boolean +} diff --git a/packages/extension-sample-with-overrides/src/types/index.ts b/packages/pwa-kit-extension-support/src/types/index.ts similarity index 75% rename from packages/extension-sample-with-overrides/src/types/index.ts rename to packages/pwa-kit-extension-support/src/types/index.ts index 4b7923357f..3025d0673a 100644 --- a/packages/extension-sample-with-overrides/src/types/index.ts +++ b/packages/pwa-kit-extension-support/src/types/index.ts @@ -5,4 +5,4 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -export * from './config' \ No newline at end of file +export {ApplicationExtensionConfig} from './application-extension-config' \ No newline at end of file diff --git a/packages/pwa-kit-dev/src/utils/extensibility-utils.test.js b/packages/pwa-kit-extension-support/src/utils/extensibility-utils.test.js similarity index 100% rename from packages/pwa-kit-dev/src/utils/extensibility-utils.test.js rename to packages/pwa-kit-extension-support/src/utils/extensibility-utils.test.js diff --git a/packages/pwa-kit-dev/src/utils/extensibility-utils.js b/packages/pwa-kit-extension-support/src/utils/extensibility-utils.ts similarity index 86% rename from packages/pwa-kit-dev/src/utils/extensibility-utils.js rename to packages/pwa-kit-extension-support/src/utils/extensibility-utils.ts index 6449a381bc..ce6a7b88e3 100644 --- a/packages/pwa-kit-dev/src/utils/extensibility-utils.js +++ b/packages/pwa-kit-extension-support/src/utils/extensibility-utils.ts @@ -28,7 +28,7 @@ const SUPPORTED_FILE_TYPES = ['.ts', '.js'] * ['@salesforce/extension-checkout/setup-app']: '/path/to/setup-app.ts', * } */ -export const buildAliases = (extensions = []) => { +export const buildAliases = (extensions: ApplicationExtensionEntry[] = []) => { const projectDir = process.cwd() const aliases = getExtensionNames(extensions).reduce((acc, extension) => { @@ -76,7 +76,7 @@ export const buildAliases = (extensions = []) => { * console.log('File not found.') * } */ -export const findFileWithExtension = (basePath, extensions = []) => { +export const findFileWithExtension = (basePath: string, extensions: string[] = []) => { for (const ext of extensions) { const filePath = path.format({...path.parse(basePath), base: undefined, ext}) if (fs.existsSync(filePath)) { @@ -104,12 +104,20 @@ export const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ /** * @private */ -export const getExtensionNames = (extensions) => { +export const getExtensionNames = (extensions: ApplicationExtensionEntry[]) => { return (extensions || []).map((extension) => { return Array.isArray(extension) ? extension[0] : extension }) } +// TODO: Move these to the types file! +interface ApplicationExtensionConfig extends Record { + enabled: boolean +} + +type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] +type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string + /** * Determines if an extension is enabled based on the provided Application Extension entry. * @@ -123,7 +131,7 @@ export const getExtensionNames = (extensions) => { * @returns {boolean} - Returns `true` if the extension has a name and is enabled (or if the enabled flag is `undefined`). * Returns `false` if the extension is explicitly disabled or if no name is provided. */ -export const isEnabled = (extensionEntry = []) => { - const [name, config = {}] = extensionEntry +export const isEnabled = (extensionEntry: ApplicationExtensionEntryArray): boolean => { + const [name, config] = extensionEntry return !!(name && config?.enabled !== false) } diff --git a/packages/pwa-kit-extension-support/src/utils/index.ts b/packages/pwa-kit-extension-support/src/utils/index.ts new file mode 100644 index 0000000000..bd549169db --- /dev/null +++ b/packages/pwa-kit-extension-support/src/utils/index.ts @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export {applyApplicationExtensions} from './utils' + +/** + * Converts a kebab-case string to UpperCamelCase (PascalCase). + * + * @param {string} str - The kebab-case string to be converted. + * @returns {string} The converted UpperCamelCase string. + * + * @example + * // Returns 'HelloWorld' + * kebabToUpperCamelCase('hello-world') + * + * @example + * // Returns 'FooBarBaz' + * kebabToUpperCamelCase('foo-bar-baz') + */ +export const kebabToUpperCamelCase = (str: string) => + str + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join('') + +/** + * Converts a kebab-case string to lowerCamelCase. + * + * The first word in the resulting string will be in lower case, and each subsequent word will start with an uppercase letter. + * + * @param {string} str - The kebab-case string to be converted. + * @returns {string} The converted lowerCamelCase string. + * + * @example + * // Returns 'helloWorld' + * kebabToLowerCamelCase('hello-world') + * + * @example + * // Returns 'fooBarBaz' + * kebabToLowerCamelCase('foo-bar-baz') + */ +export const kebabToLowerCamelCase = (str: string) => + str + .split('-') + .map((word, index) => + index === 0 + ? word.toLowerCase() + : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ) + .join('') diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.test.js b/packages/pwa-kit-extension-support/src/utils/resolver-utils.test.js similarity index 100% rename from packages/pwa-kit-dev/src/utils/resolver-utils.test.js rename to packages/pwa-kit-extension-support/src/utils/resolver-utils.test.js diff --git a/packages/pwa-kit-dev/src/utils/resolver-utils.js b/packages/pwa-kit-extension-support/src/utils/resolver-utils.ts similarity index 86% rename from packages/pwa-kit-dev/src/utils/resolver-utils.js rename to packages/pwa-kit-extension-support/src/utils/resolver-utils.ts index 7cdae4f50c..75823ddc14 100644 --- a/packages/pwa-kit-dev/src/utils/resolver-utils.js +++ b/packages/pwa-kit-extension-support/src/utils/resolver-utils.ts @@ -22,12 +22,12 @@ const PWA_KIT_REACT_SDK = 'pwa-kit-react-sdk' // TODO: We should determine if we want the `overrides-resolver-plugin` to handle resolution of application special // components like _app and _document. If so we can update this map and remove the special logic from our webpack // configuration. -const SDK_COMPONENT_MAP = {} +const SDK_COMPONENT_MAP: Record = {} const INDEX_FILE = 'index' // TODO: Make this value obey the webpack's `resolve.mainFiles` options. // Returns true/false indicating if the importPath resolves to a same named file as the sourcePath. // @private -export const isSelfReference = (importPath, sourcePath) => { +export const isSelfReference = (importPath: string, sourcePath: string) => { const indexRegExp = new RegExp(`(/${INDEX_FILE})$`) // Sanitize the input. Here we want to remove the file extension and index file if it exists. @@ -53,11 +53,11 @@ export const isSelfReference = (importPath, sourcePath) => { * console.log(result) * // [["@salesforce/extension-store-finder", {}], ["@salesforce/extension-account-pages", {singlePage: true}], ["/home/project/extensions/local-extension", {}]] */ -export const expand = (extensions = []) => +export const expand = (extensions: ApplicationExtensionEntry[] = []): ApplicationExtensionEntryArray[] => extensions .filter((extension) => Boolean(extension)) .map((extension) => { - let [nameRef, config = {}] = Array.isArray(extension) ? extension : [extension, {}] + let [nameRef, config = {}] : [string, any] = Array.isArray(extension) ? extension : [extension, {}] switch (true) { case /^\./.test(nameRef): @@ -82,6 +82,19 @@ export const expand = (extensions = []) => return [nameRef, config] }) +type BuildCandidatePathsOptions = { + projectDir: string, + extensionEntries: ApplicationExtensionEntry[] +} + +interface ApplicationExtensionConfig extends Record { + enabled: boolean +} + +type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] +type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string + + /** * Based on the current extensibility configuration, return an array of candiate file paths to be used * in the wild-card import module resolution for the given import path.. @@ -90,10 +103,10 @@ export const expand = (extensions = []) => * @param {String} sourcePath - The path the the file of the source import. * @param {Object} opts - The path the the file of the source import. * @param {Array} opts.extensionEntries - List of extension entries (tupals) used by the base PWA-Kit application. - * @param {String>} opts.projectDir - Absolute path of the base project. + * @param {String} opts.projectDir - Absolute path of the base project. * @returns {String[]} paths - The potential paths to find the module import. */ -export const buildCandidatePaths = (importPath, sourcePath, opts = {}) => { +export const buildCandidatePaths = (importPath: string, sourcePath: string, opts: BuildCandidatePathsOptions) => { // Replace wildcard character as it has done its job getting us to this point. importPath = importPath.replace('*/', '') @@ -114,7 +127,7 @@ export const buildCandidatePaths = (importPath, sourcePath, opts = {}) => { path.join(srcPath, OVERRIDES, importPath), path.join(srcPath, importPath) ] - }, []) + }, [] as ApplicationExtensionEntry[]) // Add non-extension search locations locations. The base project and the sdk as the final callback. paths = [ diff --git a/packages/pwa-kit-extension-support/src/utils/utils.ts b/packages/pwa-kit-extension-support/src/utils/utils.ts new file mode 100644 index 0000000000..8d1d5666a3 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/utils/utils.ts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import React from 'react' +import hoistNonReactStatics from 'hoist-non-react-statics' +import ApplicationExtension from '../core/application-extension' +import {ApplicationExtensionConfig} from '../types' + +// NOTE: Similar to how I was thinking that the ExpressJS interface should be a middleware, +// it might also be wise to make the React interface with application extensibility be an HOC. +// This will ensure that in both worlds we are using a familiar pattern. + +/** + * Applies a series of Higher-Order Components (HOCs) to a given React component. + * + * @template T - The type of the React component. + * @param {T} Component - The React component to which the HOCs will be applied. + * @param {Array<(component: T) => T>} hocs - An array of Higher-Order Components (HOCs) to apply to the component. + * @returns {T} - The React component wrapped with the provided HOCs. + */ +export const applyHOCs = >( + Component: T, + hocs: Array<(component: T) => T> +): T => { + return hocs.reduce((AccumulatedComponent, hoc) => { + const WrappedComponent = hoc(AccumulatedComponent) + return hoistNonReactStatics(WrappedComponent, AccumulatedComponent) as T + }, Component) +} + +/** + * Given the provided Application, apply all the App extensions to it. + * + * @param App + */ +export const applyApplicationExtensions = ( + App: React.ComponentType, + extensions: ApplicationExtension[] +): React.ComponentType => { + const extendAppHocs = extensions + .map((extension) => extension.extendApp.bind(extension)) + .filter(Boolean) + + return applyHOCs(App, extendAppHocs) +} diff --git a/packages/pwa-kit-extension-support/tsconfig.json b/packages/pwa-kit-extension-support/tsconfig.json new file mode 100644 index 0000000000..001d20a4eb --- /dev/null +++ b/packages/pwa-kit-extension-support/tsconfig.json @@ -0,0 +1,105 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + "rootDir": "./src", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/packages/pwa-kit-react-sdk/package.json b/packages/pwa-kit-react-sdk/package.json index 80b8bbabd6..5f265e303a 100644 --- a/packages/pwa-kit-react-sdk/package.json +++ b/packages/pwa-kit-react-sdk/package.json @@ -38,6 +38,7 @@ "@loadable/babel-plugin": "^5.15.3", "@loadable/server": "^5.15.3", "@loadable/webpack-plugin": "^5.15.2", + "@salesforce/pwa-kit-extension-support": "4.0.0-dev", "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@tanstack/react-query": "^4.28.0", "cross-env": "^5.2.1", diff --git a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js index a9efa05853..5e224bffc5 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js +++ b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js @@ -28,9 +28,8 @@ import {ServerContext, CorrelationIdProvider} from '../universal/contexts' import App from '../universal/components/_app' import Document from '../universal/components/_document' -import {getExtensions} from '../universal/extensibility/extensions' +import {getExtensions} from '@salesforce/pwa-kit-extension-support/core/extensions' import Throw404 from '../universal/components/throw-404' - import {getAppConfig} from '../universal/compatibility' import Switch from '../universal/components/switch' import {getRoutes, routeComponent} from '../universal/components/route-component' @@ -128,7 +127,7 @@ export const render = async (req, res, next) => { // Get the application config which should have been stored at this point. const config = getConfig() const extensions = getExtensions() - + console.log('React Rendering: ', extensions) AppConfig.restore(res.locals) // Use locals to thread the application extensions through the rendering pipeline. diff --git a/packages/extension-sample-with-overrides/src/overrides/components/with-red-border.tsx b/packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx similarity index 91% rename from packages/extension-sample-with-overrides/src/overrides/components/with-red-border.tsx rename to packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx index f37a7b612e..7257f58f3d 100644 --- a/packages/extension-sample-with-overrides/src/overrides/components/with-red-border.tsx +++ b/packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx @@ -14,7 +14,7 @@ type WithRedBorderProps = React.ComponentPropsWithoutRef; const withRedBorder =

(WrappedComponent: React.ComponentType

) => { const WithRedBorder: React.FC

= (props: WithRedBorderProps) => { return ( -

+
) diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 84a4994c44..d9294ebd23 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -18,10 +18,7 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - "@salesforce/extension-sample": "1.0.0-dev", - "@salesforce/extension-sample-with-overrides": "1.0.0-dev", - "@salesforce/pwa-kit-dev": "4.0.0-dev", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", "@salesforce/pwa-kit-runtime": "4.0.0-dev", @@ -47,7 +44,7 @@ }, "mobify": { "app":{ - "extensions": ["@salesforce/extension-sample", ["@salesforce/extension-sample-with-overrides", {"enabled": false}]] + "extensions": ["@salesforce/extension-sample"] }, "ssrEnabled": true, "ssrOnly": [ From bcba9cc1a37120f72504907e2e91ec6bf7facd87 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 8 Oct 2024 13:53:58 -0700 Subject: [PATCH 146/929] Testing stuff --- packages/extension-sample/src/setup-app.ts | 2 +- packages/pwa-kit-dev/src/configs/webpack/config.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/extension-sample/src/setup-app.ts b/packages/extension-sample/src/setup-app.ts index e83646c293..d32275b2bc 100644 --- a/packages/extension-sample/src/setup-app.ts +++ b/packages/extension-sample/src/setup-app.ts @@ -12,7 +12,7 @@ import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ import withRedBorder from '*/components/with-red-border' import {Config} from './types' -const SamplePage = loadable(() => import('*/pages/sample')) +const SamplePage = loadable(() => import(/* webpackChunkName: "extension-2-page-sample-2" */'./pages/sample')) const defaultPath: string = '/sample-page' class Sample extends ApplicationExtension { diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 6cf32d72ec..d7846236e6 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -21,7 +21,7 @@ import SpeedMeasurePlugin from 'speed-measure-webpack-plugin' import WebpackNotifierPlugin from 'webpack-notifier' // TODO: Simplify the exports in this package. -import OverridesResolverPlugin from '@salesforce/pwa-kit-extension-support/configs/webpack/plugins/overrides-resolver-plugin.js' +import OverridesResolverPlugin from '@salesforce/pwa-kit-extension-support/configs/webpack/plugins/overrides-resolver-plugin' // Local Plugins // import OverridesResolverPlugin from './plugins/overrides-resolver-plugin' @@ -32,7 +32,6 @@ import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config- // Utilities import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -// import {buildAliases, getExtensionNames, nameRegex} from '../../utils/extensibility-utils' import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/utils/extensibility-utils.js' const projectDir = process.cwd() From 415f5e2f52ad82d6af5ee58b296fa1191079f085 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 8 Oct 2024 15:24:36 -0700 Subject: [PATCH 147/929] Working loadables! --- packages/extension-sample/src/setup-app.ts | 2 +- .../pwa-kit-dev/src/configs/webpack/config.js | 17 +- .../pwa-kit-extension-support/babel.config.js | 7 + .../package-lock.json | 87 ++ .../pwa-kit-extension-support/package.json | 9 +- .../webpack/loaders/extensions-loader.ts | 6 +- .../pwa-kit-extension-support/tsconfig.json | 4 +- .../src/ssr/browser/main.jsx | 2 +- .../src/ssr/server/react-rendering.js | 2 +- .../package-lock.json | 1227 ++++++++++++++++- 10 files changed, 1292 insertions(+), 71 deletions(-) create mode 100644 packages/pwa-kit-extension-support/babel.config.js diff --git a/packages/extension-sample/src/setup-app.ts b/packages/extension-sample/src/setup-app.ts index d32275b2bc..2003743644 100644 --- a/packages/extension-sample/src/setup-app.ts +++ b/packages/extension-sample/src/setup-app.ts @@ -12,7 +12,7 @@ import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ import withRedBorder from '*/components/with-red-border' import {Config} from './types' -const SamplePage = loadable(() => import(/* webpackChunkName: "extension-2-page-sample-2" */'./pages/sample')) +const SamplePage = loadable(() => import(/* webpackChunkName: "extension-sample-page-sample" */'./pages/sample')) const defaultPath: string = '/sample-page' class Sample extends ApplicationExtension { diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index d7846236e6..179806e8df 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -32,7 +32,7 @@ import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config- // Utilities import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/utils/extensibility-utils.js' +import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/utils/extensibility-utils' const projectDir = process.cwd() const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) @@ -143,6 +143,7 @@ const baseConfig = (target) => { if (!['web', 'node'].includes(target)) { throw Error(`The value "${target}" is not a supported webpack target`) } + class Builder { constructor() { this.config = { @@ -193,6 +194,11 @@ const baseConfig = (target) => { ], extensions: SUPPORTED_FILE_EXTENSIONS, alias: { + ...Object.assign( + ...DEPS_TO_DEDUPE.map((dep) => ({ + [dep]: findDepInStack(dep) + })) + ), // TODO: This alias is temporary. When we investigate turning the retail template into an application extension // we'll have to decide if we want to continue using an alias, or change back to using relative paths. '@salesforce/retail-react-app': projectDir, @@ -203,11 +209,6 @@ const baseConfig = (target) => { Object.keys(pkg?.devDependencies || {}).filter((dependency) => dependency.match(nameRegex) ) - ), - ...Object.assign( - ...DEPS_TO_DEDUPE.map((dep) => ({ - [dep]: findDepInStack(dep) - })) ) }, ...(target === 'web' ? {fallback: {crypto: false}} : {}) @@ -259,9 +260,9 @@ const baseConfig = (target) => { // make the "extensions" file private so was can change that implementation detail later // if we choose to do so. test: /core[\\/]+extensions/, - // loader: '@salesforce/pwa-kit-extension-support/dist/configs/webpack/loaders/extensions-loader', + use: { - loader: findDepInStack('@salesforce/pwa-kit-extension-support/dist/configs/webpack/loaders/extensions-loader'), + loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), options: { pkg, getConfig diff --git a/packages/pwa-kit-extension-support/babel.config.js b/packages/pwa-kit-extension-support/babel.config.js new file mode 100644 index 0000000000..79f5aa5857 --- /dev/null +++ b/packages/pwa-kit-extension-support/babel.config.js @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ +module.exports = require('internal-lib-build/configs/babel.config') diff --git a/packages/pwa-kit-extension-support/package-lock.json b/packages/pwa-kit-extension-support/package-lock.json index dd63a8d21d..59dfebaaae 100644 --- a/packages/pwa-kit-extension-support/package-lock.json +++ b/packages/pwa-kit-extension-support/package-lock.json @@ -9,6 +9,7 @@ "version": "4.0.0-dev", "license": "SEE LICENSE IN LICENSE", "dependencies": { + "cross-env": "^5.2.1", "dedent": "^1.5.3", "fs-extra": "^11.2.0", "hoist-non-react-statics": "^3.3.2", @@ -493,6 +494,36 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/cross-env": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", + "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==", + "dependencies": { + "cross-spawn": "^6.0.5" + }, + "bin": { + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -704,6 +735,11 @@ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -801,6 +837,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -816,6 +857,14 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "engines": { + "node": ">=4" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -1008,6 +1057,14 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -1017,6 +1074,25 @@ "randombytes": "^2.1.0" } }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1273,6 +1349,17 @@ "engines": { "node": ">=10.13.0" } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } } } } diff --git a/packages/pwa-kit-extension-support/package.json b/packages/pwa-kit-extension-support/package.json index 232c874ca3..ad5fa3339f 100644 --- a/packages/pwa-kit-extension-support/package.json +++ b/packages/pwa-kit-extension-support/package.json @@ -20,14 +20,16 @@ "types", "utils" ], - "exports": { - "./*": "./dist/*" + "publishConfig": { + "directory": "dist" }, "types": "dist/index.d.ts", "scripts": { - "build": "tsc" + "build-old": "tsc", + "build": "cross-env NODE_ENV=production internal-lib-build build && tsc" }, "dependencies": { + "cross-env": "^5.2.1", "dedent": "^1.5.3", "fs-extra": "^11.2.0", "hoist-non-react-statics": "^3.3.2", @@ -40,6 +42,7 @@ "@types/react-router-dom": "^5.3.3", "@types/resolve": "^1.20.6", "@types/webpack": "^5.28.5", + "internal-lib-build": "4.0.0-dev", "type-fest": "^4.26.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index 273602d61c..032f47a0a7 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -61,8 +61,9 @@ module.exports = function (this: ExtensionsLoaderContext) { }) const appExtensions = getConfig()?.app?.extensions + // TODO: later consider updating `normalizeExtensionsList` to use a util function - const result = dedent` + return dedent` /* * Copyright (c) 2024, salesforce.com, inc. * All rights reserved. @@ -113,7 +114,4 @@ module.exports = function (this: ExtensionsLoaderContext) { return configuredExtensions } ` - - console.log('result: ', result) - return result } diff --git a/packages/pwa-kit-extension-support/tsconfig.json b/packages/pwa-kit-extension-support/tsconfig.json index 001d20a4eb..ec2c889ac6 100644 --- a/packages/pwa-kit-extension-support/tsconfig.json +++ b/packages/pwa-kit-extension-support/tsconfig.json @@ -27,7 +27,7 @@ /* Modules */ "module": "commonjs", /* Specify what module code is generated. */ "rootDir": "./src", /* Specify the root folder within your source files. */ - // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ @@ -46,7 +46,7 @@ /* Emit */ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ "outDir": "./dist", /* Specify an output folder for all emitted files. */ diff --git a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx index 1760580123..02850db2b3 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx +++ b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx @@ -10,6 +10,7 @@ import {hydrateRoot} from 'react-dom/client' import PropTypes from 'prop-types' import {BrowserRouter as Router} from 'react-router-dom' import {loadableReady} from '@loadable/component' +import {getExtensions} from '@salesforce/pwa-kit-extension-support/core/extensions' import {ServerContext, CorrelationIdProvider} from '../universal/contexts' import App from '../universal/components/_app' @@ -19,7 +20,6 @@ import {getRoutes, routeComponent} from '../universal/components/route-component import {applyAppExtensions} from '../universal/extensibility/utils' import {uuidv4} from '../../utils/uuidv4.client' import logger from '../../utils/logger-instance' -import {getExtensions} from '../universal/extensibility/extensions' /* istanbul ignore next */ export const registerServiceWorker = (url) => { diff --git a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js index 5e224bffc5..bbd69d00ba 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js +++ b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js @@ -21,6 +21,7 @@ import sprite from 'svg-sprite-loader/runtime/sprite.build' import {isRemote} from '@salesforce/pwa-kit-runtime/utils/ssr-server' import {proxyConfigs} from '@salesforce/pwa-kit-runtime/utils/ssr-shared' import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' +import {getExtensions} from '@salesforce/pwa-kit-extension-support/core/extensions' import {getAssetUrl} from '../universal/utils' import {applyAppExtensions} from '../universal/extensibility/utils' @@ -28,7 +29,6 @@ import {ServerContext, CorrelationIdProvider} from '../universal/contexts' import App from '../universal/components/_app' import Document from '../universal/components/_document' -import {getExtensions} from '@salesforce/pwa-kit-extension-support/core/extensions' import Throw404 from '../universal/components/throw-404' import {getAppConfig} from '../universal/compatibility' import Switch from '../universal/components/switch' diff --git a/packages/template-typescript-minimal/package-lock.json b/packages/template-typescript-minimal/package-lock.json index 67e214c03c..aa383eb014 100644 --- a/packages/template-typescript-minimal/package-lock.json +++ b/packages/template-typescript-minimal/package-lock.json @@ -11,7 +11,10 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", + "@loadable/babel-plugin": "^5.15.3", "@loadable/component": "^5.15.3", + "@loadable/server": "^5.15.3", + "@loadable/webpack-plugin": "^5.15.2", "@tanstack/react-query": "^4.28.0", "@types/loadable__component": "~5.13.4", "@types/react": "~18.2.0", @@ -29,72 +32,217 @@ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/compat-data": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", + "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", + "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", + "dev": true, + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "peer": true + }, "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "dev": true, "dependencies": { - "@babel/types": "^7.25.6", + "@babel/types": "^7.25.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", + "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", + "dev": true, + "peer": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "dev": true, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -104,12 +252,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", + "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", "dev": true, "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.25.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -118,6 +266,18 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.25.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", @@ -131,30 +291,30 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -163,13 +323,13 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", + "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1601,6 +1761,17 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -1617,6 +1788,25 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@loadable/babel-plugin": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/@loadable/babel-plugin/-/babel-plugin-5.16.1.tgz", + "integrity": "sha512-y+oKjRTt5XXf907ReFxiZyQtkYiIa4NAPQYlxb2qh5rUO/UsOKPq2PhCSHvfwoZOUJaMsY0FnoAPZ6lhFZkayQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-dynamic-import": "^7.7.4" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@loadable/component": { "version": "5.16.4", "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", @@ -1638,6 +1828,45 @@ "react": "^16.3.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@loadable/server": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@loadable/server/-/server-5.16.5.tgz", + "integrity": "sha512-y87OMpi43B8mGg/r4Fy6PLkisj0c3SiQqxHqxmCAK1j3UUuYyq1EPLSKTjnrMBUerROA5R0isHobHCNfD20Cnw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@loadable/component": "^5.0.1", + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@loadable/webpack-plugin": { + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@loadable/webpack-plugin/-/webpack-plugin-5.15.2.tgz", + "integrity": "sha512-+o87jPHn3E8sqW0aBA+qwKuG8JyIfMGdz3zECv0t/JF0KHhxXtzIlTiqzlIYc5ZpFs/vKSQfjzGIR5tPJjoXDw==", + "dev": true, + "dependencies": { + "make-dir": "^3.0.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "webpack": ">=4.6.0" + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -1685,12 +1914,26 @@ } } }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "peer": true + }, "node_modules/@types/history": { "version": "4.7.11", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", "dev": true }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "peer": true + }, "node_modules/@types/loadable__component": { "version": "5.13.9", "resolved": "https://registry.npmjs.org/@types/loadable__component/-/loadable__component-5.13.9.tgz", @@ -1715,6 +1958,16 @@ "@types/lodash": "*" } }, + "node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "peer": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -1767,6 +2020,181 @@ "@types/react-router": "*" } }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "peer": true + }, "node_modules/@zag-js/dom-query": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.16.0.tgz", @@ -1788,6 +2216,56 @@ "@zag-js/dom-query": "0.16.0" } }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -1827,6 +2305,46 @@ "npm": ">=6" } }, + "node_modules/browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "peer": true + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1836,6 +2354,27 @@ "node": ">=6" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1859,6 +2398,16 @@ "node": ">=0.8.0" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1880,6 +2429,13 @@ "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==", "dev": true }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, "node_modules/compute-scroll-into-view": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz", @@ -1955,6 +2511,27 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "dev": true }, + "node_modules/electron-to-chromium": { + "version": "1.5.33", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", + "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", + "dev": true, + "peer": true + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1964,6 +2541,23 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "peer": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1976,6 +2570,77 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "peer": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "peer": true + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -2043,6 +2708,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", @@ -2052,6 +2727,13 @@ "node": ">=6" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "peer": true + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -2061,6 +2743,13 @@ "node": ">=4" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "peer": true + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2157,6 +2846,47 @@ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2164,15 +2894,15 @@ "dev": true }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-parse-even-better-errors": { @@ -2181,12 +2911,48 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "peer": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", @@ -2205,12 +2971,81 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "peer": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "peer": true + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "peer": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2291,6 +3126,26 @@ "react-is": "^16.13.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -2533,6 +3388,27 @@ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", "dev": true }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -2542,6 +3418,44 @@ "loose-envify": "^1.1.0" } }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2551,6 +3465,27 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", @@ -2581,6 +3516,70 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.34.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz", + "integrity": "sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -2627,6 +3626,54 @@ "node": ">=4.2.0" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "peer": true + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/use-callback-ref": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", @@ -2685,6 +3732,84 @@ "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", "dev": true }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "peer": true + }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", From f22b15cc2455b51d04666c38ffc43d8c89d6d376 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 10 Oct 2024 09:57:39 -0700 Subject: [PATCH 148/929] Initial Working Solution --- .../src/components/with-red-border.tsx | 4 +- .../extension-sample/src/pages/sample.tsx | 2 +- packages/extension-sample/src/setup-app.ts | 6 +- .../pwa-kit-dev/src/configs/webpack/config.js | 10 +-- .../application-extensions-placeholder.ts | 13 ++++ .../src/{types => configs/webpack}/index.ts | 3 +- .../webpack/loaders/extensions-loader.ts | 8 +- .../webpack/loaders/index.ts} | 4 +- .../src/configs/webpack/plugins/index.ts | 8 ++ .../plugins/overrides-resolver-plugin.ts | 13 ++-- .../src/core/extensions.ts | 14 ---- .../src/core/index.ts | 12 --- .../application-extensions-middleware.ts | 6 ++ .../src/express}/index.ts | 5 +- .../application-extension.ts => index.ts} | 4 +- .../src/react/components/index.ts | 8 ++ .../components/withApplicationExtensions.tsx | 48 ++++++++++++ .../contexts/ApplicationExtensionsContext.tsx | 16 ++++ .../ApplicationExtensionsProvider.tsx | 30 ++++++++ .../src/react/contexts/index.ts | 9 +++ .../src/react/hooks/index.ts | 8 ++ .../react/hooks/useApplicationExtensions.tsx | 26 +++++++ .../src/react/index.ts | 10 +++ .../{utils/utils.ts => react/utils/index.ts} | 18 ----- .../utils/extensibility-utils.test.js | 0 .../{ => shared}/utils/extensibility-utils.ts | 11 +-- .../src/{ => shared}/utils/index.ts | 4 +- .../{ => shared}/utils/resolver-utils.test.js | 0 .../src/{ => shared}/utils/resolver-utils.ts | 16 +--- .../src/shared/utils/universal-utils.ts | 15 ++++ .../src}/types.ts | 18 ++--- .../pwa-kit-extension-support/tsconfig.json | 2 +- .../src/ssr/browser/main.jsx | 12 +-- .../src/ssr/server/react-rendering.js | 13 +--- .../components/route-component/index.js | 6 +- .../components/with-legacy-get-props/index.js | 2 +- .../extensibility/application-extension.ts | 74 ------------------- .../ssr/universal/extensibility/extensions.ts | 14 ---- .../src/ssr/universal/extensibility/index.ts | 13 ---- .../src/ssr/universal/extensibility/utils.ts | 27 ------- .../src/ssr/universal/utils.ts | 1 + .../overrides/components/with-red-border.tsx | 4 +- 42 files changed, 254 insertions(+), 263 deletions(-) create mode 100644 packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts rename packages/pwa-kit-extension-support/src/{types => configs/webpack}/index.ts (75%) rename packages/pwa-kit-extension-support/src/{types/application-extension-config.ts => configs/webpack/loaders/index.ts} (69%) create mode 100644 packages/pwa-kit-extension-support/src/configs/webpack/plugins/index.ts delete mode 100644 packages/pwa-kit-extension-support/src/core/extensions.ts delete mode 100644 packages/pwa-kit-extension-support/src/core/index.ts create mode 100644 packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts rename packages/{pwa-kit-react-sdk/src => pwa-kit-extension-support/src/express}/index.ts (66%) rename packages/pwa-kit-extension-support/src/{core/application-extension.ts => index.ts} (94%) create mode 100644 packages/pwa-kit-extension-support/src/react/components/index.ts create mode 100644 packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx create mode 100644 packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsContext.tsx create mode 100644 packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx create mode 100644 packages/pwa-kit-extension-support/src/react/contexts/index.ts create mode 100644 packages/pwa-kit-extension-support/src/react/hooks/index.ts create mode 100644 packages/pwa-kit-extension-support/src/react/hooks/useApplicationExtensions.tsx create mode 100644 packages/pwa-kit-extension-support/src/react/index.ts rename packages/pwa-kit-extension-support/src/{utils/utils.ts => react/utils/index.ts} (70%) rename packages/pwa-kit-extension-support/src/{ => shared}/utils/extensibility-utils.test.js (100%) rename packages/pwa-kit-extension-support/src/{ => shared}/utils/extensibility-utils.ts (94%) rename packages/pwa-kit-extension-support/src/{ => shared}/utils/index.ts (94%) rename packages/pwa-kit-extension-support/src/{ => shared}/utils/resolver-utils.test.js (100%) rename packages/pwa-kit-extension-support/src/{ => shared}/utils/resolver-utils.ts (94%) create mode 100644 packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts rename packages/{pwa-kit-react-sdk/src/ssr/universal/extensibility => pwa-kit-extension-support/src}/types.ts (54%) delete mode 100644 packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts delete mode 100644 packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts delete mode 100644 packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts delete mode 100644 packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts diff --git a/packages/extension-sample/src/components/with-red-border.tsx b/packages/extension-sample/src/components/with-red-border.tsx index 7f53983c35..1dc4d1b587 100644 --- a/packages/extension-sample/src/components/with-red-border.tsx +++ b/packages/extension-sample/src/components/with-red-border.tsx @@ -8,10 +8,10 @@ import React from 'react' // Define a type for the HOC props -type WithRedBorderProps = React.ComponentPropsWithoutRef; +type WithRedBorderProps = React.ComponentPropsWithoutRef // Define the HOC function -const withRedBorder =

(WrappedComponent: React.ComponentType

) => { +const withRedBorder =

(WrappedComponent: React.ComponentType

) => { const WithRedBorder: React.FC

= (props: WithRedBorderProps) => { return (

diff --git a/packages/extension-sample/src/pages/sample.tsx b/packages/extension-sample/src/pages/sample.tsx index b19378f9e6..b1a6b8b94f 100644 --- a/packages/extension-sample/src/pages/sample.tsx +++ b/packages/extension-sample/src/pages/sample.tsx @@ -8,7 +8,7 @@ import React, {Fragment} from 'react' import {getStaticAssetUrl} from '@salesforce/pwa-kit-react-sdk/ssr/universal/utils' const Sample = () => { - const logoUrl = getStaticAssetUrl('salesforce-logo.svg', {extensionPackageName: '@salesforce/extension-sample'}) + const logoUrl = getStaticAssetUrl('salesforce-logo.svg', {appExtensionPackageName: '@salesforce/extension-sample'}) return (

Welcome to the Sample Page 👋

diff --git a/packages/extension-sample/src/setup-app.ts b/packages/extension-sample/src/setup-app.ts index 2003743644..a484674522 100644 --- a/packages/extension-sample/src/setup-app.ts +++ b/packages/extension-sample/src/setup-app.ts @@ -12,11 +12,13 @@ import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ import withRedBorder from '*/components/with-red-border' import {Config} from './types' -const SamplePage = loadable(() => import(/* webpackChunkName: "extension-sample-page-sample" */'./pages/sample')) +// NOTE: FIXME! +// const SamplePage = loadable(() => import(/* webpackChunkName: "extension-sample-page-sample" */'./pages/sample')) +import SamplePage from './pages/sample' const defaultPath: string = '/sample-page' class Sample extends ApplicationExtension { - extendApp(App: React.ComponentType): React.ComponentType { + extendApp(App: React.ComponentClass): React.ComponentClass { return withRedBorder(App) } diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 179806e8df..22bac0b202 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -20,11 +20,10 @@ import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin' import SpeedMeasurePlugin from 'speed-measure-webpack-plugin' import WebpackNotifierPlugin from 'webpack-notifier' -// TODO: Simplify the exports in this package. -import OverridesResolverPlugin from '@salesforce/pwa-kit-extension-support/configs/webpack/plugins/overrides-resolver-plugin' +// PWA-Kit Plugins +import {OverridesResolverPlugin} from '@salesforce/pwa-kit-extension-support/configs/webpack' // Local Plugins -// import OverridesResolverPlugin from './plugins/overrides-resolver-plugin' import {sdkReplacementPlugin} from './plugins' // Constants @@ -32,7 +31,7 @@ import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config- // Utilities import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/utils/extensibility-utils' +import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/shared/utils' const projectDir = process.cwd() const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) @@ -259,8 +258,7 @@ const baseConfig = (target) => { // NOTE: Might be better to export a rule directly that we can plog in here, this will // make the "extensions" file private so was can change that implementation detail later // if we choose to do so. - test: /core[\\/]+extensions/, - + test: /application-extensions-placeholder\.js/i, use: { loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), options: { diff --git a/packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts b/packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts new file mode 100644 index 0000000000..4a3382f4e8 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024, 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 + */ +// Types +import {ApplicationExtensionConfig} from '../types' +import {ApplicationExtension} from '..' + +const APPLICATION_EXTENSIONS: ApplicationExtension[] = [] + +export default APPLICATION_EXTENSIONS diff --git a/packages/pwa-kit-extension-support/src/types/index.ts b/packages/pwa-kit-extension-support/src/configs/webpack/index.ts similarity index 75% rename from packages/pwa-kit-extension-support/src/types/index.ts rename to packages/pwa-kit-extension-support/src/configs/webpack/index.ts index 3025d0673a..3d48d94873 100644 --- a/packages/pwa-kit-extension-support/src/types/index.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/index.ts @@ -5,4 +5,5 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -export {ApplicationExtensionConfig} from './application-extension-config' \ No newline at end of file +export * from './loaders' +export * from './plugins' diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index 032f47a0a7..a3949c4532 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -9,8 +9,8 @@ import dedent from 'dedent' import {LoaderContext} from 'webpack' import {PackageJson} from 'type-fest' -import {kebabToUpperCamelCase} from '../../../utils' -import {nameRegex} from '../../../utils/extensibility-utils' +import {kebabToUpperCamelCase} from '../../../shared/utils' +import {nameRegex} from '../../../shared/utils/extensibility-utils' const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' const APP_EXTENSION_PREFIX = 'extension' // aligns with what's in `nameRegex` @@ -110,8 +110,6 @@ module.exports = function (this: ExtensionsLoaderContext) { }) .filter(Boolean) - export const getExtensions = () => { - return configuredExtensions - } + export default configuredExtensions ` } diff --git a/packages/pwa-kit-extension-support/src/types/application-extension-config.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts similarity index 69% rename from packages/pwa-kit-extension-support/src/types/application-extension-config.ts rename to packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts index 1e80f7cfa4..2bc35d8dbb 100644 --- a/packages/pwa-kit-extension-support/src/types/application-extension-config.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts @@ -5,6 +5,4 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -export interface ApplicationExtensionConfig extends Record { - enabled: boolean -} +export * from './extensions-loader' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/plugins/index.ts b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/index.ts new file mode 100644 index 0000000000..122ae0561f --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export {default as OverridesResolverPlugin} from './overrides-resolver-plugin' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts index d7e4730f3a..872f2d0b9b 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/plugins/overrides-resolver-plugin.ts @@ -8,7 +8,11 @@ import resolve from 'resolve' import {Resolver} from 'webpack' -import {buildCandidatePaths} from '../../../utils/resolver-utils' +// Local +import {buildCandidatePaths} from '../../../shared/utils/resolver-utils' + +// Type +import {ApplicationExtensionEntry} from '../../../types' export const DEFAULT_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.json'] @@ -19,13 +23,6 @@ interface OverridesResolverPluginOptions { resolveOptions: any } -interface ApplicationExtensionConfig extends Record { - enabled: boolean -} -type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] -type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string - - const defaultOptions = { projectDir: process.cwd(), extensions: [], diff --git a/packages/pwa-kit-extension-support/src/core/extensions.ts b/packages/pwa-kit-extension-support/src/core/extensions.ts deleted file mode 100644 index 60b4b8efdb..0000000000 --- a/packages/pwa-kit-extension-support/src/core/extensions.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// This file exports an empty function. During local development and the production build process, -// it'll be replaced to return those application extensions configured by the base PWA-Kit project. -const getExtensions = () => {} - -export default { - getExtensions -} diff --git a/packages/pwa-kit-extension-support/src/core/index.ts b/packages/pwa-kit-extension-support/src/core/index.ts deleted file mode 100644 index 8cf1213918..0000000000 --- a/packages/pwa-kit-extension-support/src/core/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// TODO: Figure out why this index file isn't working. E.g. import {extensions} from '../universal/extensibility' -// is broken. - -export {default as extensions} from './extensions' -export {default as ApplicationExtension} from './application-extension' diff --git a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts new file mode 100644 index 0000000000..eb9cc98d54 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ \ No newline at end of file diff --git a/packages/pwa-kit-react-sdk/src/index.ts b/packages/pwa-kit-extension-support/src/express/index.ts similarity index 66% rename from packages/pwa-kit-react-sdk/src/index.ts rename to packages/pwa-kit-extension-support/src/express/index.ts index be39c5f9ae..eb9cc98d54 100644 --- a/packages/pwa-kit-react-sdk/src/index.ts +++ b/packages/pwa-kit-extension-support/src/express/index.ts @@ -1,7 +1,6 @@ /* - * Copyright (c) 2024, Salesforce, Inc. + * Copyright (c) 2024, salesforce.com, 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 - */ -export * from './ssr/universal/extensibility' + */ \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/core/application-extension.ts b/packages/pwa-kit-extension-support/src/index.ts similarity index 94% rename from packages/pwa-kit-extension-support/src/core/application-extension.ts rename to packages/pwa-kit-extension-support/src/index.ts index 278c47e45b..0292286abb 100644 --- a/packages/pwa-kit-extension-support/src/core/application-extension.ts +++ b/packages/pwa-kit-extension-support/src/index.ts @@ -15,7 +15,7 @@ import {RouteProps} from 'react-router-dom' * * @abstract */ -export default abstract class ApplicationExtension { +export abstract class ApplicationExtension { private config: Config /** @@ -55,7 +55,7 @@ export default abstract class ApplicationExtension { * @param App - The base application component. * @returns EnhancedApp - The enhanced application component. */ - public extendApp(App: React.ComponentType): React.ComponentType { + public extendApp(App: React.ComponentType): React.ComponentType { return App } diff --git a/packages/pwa-kit-extension-support/src/react/components/index.ts b/packages/pwa-kit-extension-support/src/react/components/index.ts new file mode 100644 index 0000000000..121d8586d2 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/components/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export {default as withApplicationExtensions } from './withApplicationExtensions' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx b/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx new file mode 100644 index 0000000000..68c3864aa3 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import React from 'react' + +// Local +import {applyHOCs} from '../utils' +import {getApplicationExtensions} from '../../shared/utils/universal-utils' + +type withApplicationExtensionsOptions = { + locals?: any +} + +/** + * Higher-order component (HOC) that applies application extensions to a wrapped component. + * + * This function retrieves all registered application extensions using `getApplicationExtensions()`, + * and maps them into an array of higher-order components (HOCs). Each HOC is a function + * that takes a component and returns an extended version of that component. + * + * The `applyHOCs` utility is then used to sequentially apply each of these HOCs to + * the `WrappedComponent`, resulting in a final `ExtendedComponent` that includes + * all the applied extensions. + * + * @template P - The props type for the wrapped component. + * @param WrappedComponent - The original React component that will be wrapped by extensions. + * @returns A new React component with all extensions applied, rendering the `WrappedComponent` + * with the extended behavior. + */ + +const withApplicationExtensions =

(WrappedComponent: React.ComponentType

, options: withApplicationExtensionsOptions) => { + const extensions = getApplicationExtensions() + const extendAppHocs: Array<(component: React.ComponentType

) => React.ComponentType

> = extensions + .map((extension) => extension.extendApp.bind(extension)) + .filter(Boolean) + + if (options?.locals) { + options.locals.applicationExtensions = extensions + } + + return applyHOCs(WrappedComponent, extendAppHocs) +} + +export default withApplicationExtensions diff --git a/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsContext.tsx b/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsContext.tsx new file mode 100644 index 0000000000..e7007bd295 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsContext.tsx @@ -0,0 +1,16 @@ +/* + * 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 + */ + +import React from 'react' +import {ApplicationExtension} from '../..' +import {ApplicationExtensionConfig as Config} from '../../types' + +const defaultValue: ApplicationExtension[] = [] + +const ApplicationExtensionsContext = React.createContext(defaultValue) + +export default ApplicationExtensionsContext diff --git a/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx b/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx new file mode 100644 index 0000000000..ce45c61af5 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx @@ -0,0 +1,30 @@ +/* + * 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 + */ + +import React from 'react' + +// Local +// TODO: We can probably pass this in as an initial value.? +import {getApplicationExtensions} from '../../shared/utils/universal-utils' +import ApplicationExtensionsContext from './ApplicationExtensionsContext' + +// TODO: Clean this up. +type ApplicationExtensionsProviderProps = { + children: any +} + +const ApplicationExtensionsProvider = ({children}: ApplicationExtensionsProviderProps) => { + const extensions = getApplicationExtensions() + + return ( + + {children} + + ) +} + +export default ApplicationExtensionsProvider \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/react/contexts/index.ts b/packages/pwa-kit-extension-support/src/react/contexts/index.ts new file mode 100644 index 0000000000..6362b9eadd --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/contexts/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export {default as ApplicationExtensionsContext } from './ApplicationExtensionsContext' +export {default as ApplicationExtensionsProvider} from './ApplicationExtensionsProvider' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/react/hooks/index.ts b/packages/pwa-kit-extension-support/src/react/hooks/index.ts new file mode 100644 index 0000000000..7ce38e0ed1 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/hooks/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export {default as useApplicationExtensions } from './useApplicationExtensions' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/react/hooks/useApplicationExtensions.tsx b/packages/pwa-kit-extension-support/src/react/hooks/useApplicationExtensions.tsx new file mode 100644 index 0000000000..7396c6baef --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/hooks/useApplicationExtensions.tsx @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import {useContext} from 'react' +import {ApplicationExtensionsContext} from '../contexts' +import {ApplicationExtension} from '../..' +import {ApplicationExtensionConfig as Config} from '../../types' + +/** + * Custom React hook to get all the Application Extensions currently used + */ +const useApplicationExtensions = (): ApplicationExtension[] => { + const context = useContext(ApplicationExtensionsContext) + + if (context === undefined) { + throw new Error('useApplicationExtensions must be used within ApplicationExtensionsProvider') + } + + return context +} + +export default useApplicationExtensions \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/react/index.ts b/packages/pwa-kit-extension-support/src/react/index.ts new file mode 100644 index 0000000000..3bbb44c3a6 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export * from './components' +export * from './contexts' +export * from './hooks' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/utils/utils.ts b/packages/pwa-kit-extension-support/src/react/utils/index.ts similarity index 70% rename from packages/pwa-kit-extension-support/src/utils/utils.ts rename to packages/pwa-kit-extension-support/src/react/utils/index.ts index 8d1d5666a3..e81b5c7856 100644 --- a/packages/pwa-kit-extension-support/src/utils/utils.ts +++ b/packages/pwa-kit-extension-support/src/react/utils/index.ts @@ -7,8 +7,6 @@ import React from 'react' import hoistNonReactStatics from 'hoist-non-react-statics' -import ApplicationExtension from '../core/application-extension' -import {ApplicationExtensionConfig} from '../types' // NOTE: Similar to how I was thinking that the ExpressJS interface should be a middleware, // it might also be wise to make the React interface with application extensibility be an HOC. @@ -31,19 +29,3 @@ export const applyHOCs = >( return hoistNonReactStatics(WrappedComponent, AccumulatedComponent) as T }, Component) } - -/** - * Given the provided Application, apply all the App extensions to it. - * - * @param App - */ -export const applyApplicationExtensions = ( - App: React.ComponentType, - extensions: ApplicationExtension[] -): React.ComponentType => { - const extendAppHocs = extensions - .map((extension) => extension.extendApp.bind(extension)) - .filter(Boolean) - - return applyHOCs(App, extendAppHocs) -} diff --git a/packages/pwa-kit-extension-support/src/utils/extensibility-utils.test.js b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.test.js similarity index 100% rename from packages/pwa-kit-extension-support/src/utils/extensibility-utils.test.js rename to packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.test.js diff --git a/packages/pwa-kit-extension-support/src/utils/extensibility-utils.ts b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts similarity index 94% rename from packages/pwa-kit-extension-support/src/utils/extensibility-utils.ts rename to packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts index ce6a7b88e3..9ec59626bd 100644 --- a/packages/pwa-kit-extension-support/src/utils/extensibility-utils.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts @@ -8,6 +8,9 @@ import path from 'path' import fs from 'fs-extra' +// Types +import {ApplicationExtensionEntry, ApplicationExtensionEntryArray} from '../../types' + const REACT_EXTENSIBILITY_FILE = 'setup-app' const SUPPORTED_FILE_TYPES = ['.ts', '.js'] @@ -110,14 +113,6 @@ export const getExtensionNames = (extensions: ApplicationExtensionEntry[]) => { }) } -// TODO: Move these to the types file! -interface ApplicationExtensionConfig extends Record { - enabled: boolean -} - -type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] -type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string - /** * Determines if an extension is enabled based on the provided Application Extension entry. * diff --git a/packages/pwa-kit-extension-support/src/utils/index.ts b/packages/pwa-kit-extension-support/src/shared/utils/index.ts similarity index 94% rename from packages/pwa-kit-extension-support/src/utils/index.ts rename to packages/pwa-kit-extension-support/src/shared/utils/index.ts index bd549169db..2a39bd7598 100644 --- a/packages/pwa-kit-extension-support/src/utils/index.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/index.ts @@ -5,7 +5,9 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -export {applyApplicationExtensions} from './utils' +// Re-exports +export * from './extensibility-utils' +export * from './resolver-utils' /** * Converts a kebab-case string to UpperCamelCase (PascalCase). diff --git a/packages/pwa-kit-extension-support/src/utils/resolver-utils.test.js b/packages/pwa-kit-extension-support/src/shared/utils/resolver-utils.test.js similarity index 100% rename from packages/pwa-kit-extension-support/src/utils/resolver-utils.test.js rename to packages/pwa-kit-extension-support/src/shared/utils/resolver-utils.test.js diff --git a/packages/pwa-kit-extension-support/src/utils/resolver-utils.ts b/packages/pwa-kit-extension-support/src/shared/utils/resolver-utils.ts similarity index 94% rename from packages/pwa-kit-extension-support/src/utils/resolver-utils.ts rename to packages/pwa-kit-extension-support/src/shared/utils/resolver-utils.ts index 75823ddc14..7abb179f6b 100644 --- a/packages/pwa-kit-extension-support/src/utils/resolver-utils.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/resolver-utils.ts @@ -11,6 +11,9 @@ import path from 'path' // Project imports import {isEnabled} from './extensibility-utils' +// Types +import {ApplicationExtensionEntry, ApplicationExtensionEntryArray, BuildCandidatePathsOptions} from '../../types' + const EXTENSION_NAMESPACE = '@salesforce' const EXTENSION_PREFIX = 'extension' const NODE_MODULES = 'node_modules' @@ -82,19 +85,6 @@ export const expand = (extensions: ApplicationExtensionEntry[] = []): Applicatio return [nameRef, config] }) -type BuildCandidatePathsOptions = { - projectDir: string, - extensionEntries: ApplicationExtensionEntry[] -} - -interface ApplicationExtensionConfig extends Record { - enabled: boolean -} - -type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] -type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string - - /** * Based on the current extensibility configuration, return an array of candiate file paths to be used * in the wild-card import module resolution for the given import path.. diff --git a/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts b/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts new file mode 100644 index 0000000000..3993a9dfac --- /dev/null +++ b/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024, 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 + */ + +// Types +import {ApplicationExtensionConfig} from '../../types' + +// Local +import {ApplicationExtension} from '../..' +import APPLICATION_EXTENSIONS from '../../assets/application-extensions-placeholder' + +export const getApplicationExtensions = (): ApplicationExtension[] => APPLICATION_EXTENSIONS diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts b/packages/pwa-kit-extension-support/src/types.ts similarity index 54% rename from packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts rename to packages/pwa-kit-extension-support/src/types.ts index 54c8035fc4..f64eef8bd9 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/types.ts +++ b/packages/pwa-kit-extension-support/src/types.ts @@ -5,15 +5,15 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import React from 'react' - -// TODO: Move this somewhere closer to the router code. -export interface IRouteConfig { - path: string - exact?: boolean - component: React.ComponentType -} - export interface ApplicationExtensionConfig extends Record { enabled: boolean } + +export type ApplicationExtensionEntryArray = [string, ApplicationExtensionConfig] + +export type ApplicationExtensionEntry = ApplicationExtensionEntryArray | string + +export type BuildCandidatePathsOptions = { + projectDir: string, + extensionEntries: ApplicationExtensionEntry[] +} \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/tsconfig.json b/packages/pwa-kit-extension-support/tsconfig.json index ec2c889ac6..e15d36c800 100644 --- a/packages/pwa-kit-extension-support/tsconfig.json +++ b/packages/pwa-kit-extension-support/tsconfig.json @@ -13,7 +13,7 @@ /* Language and Environment */ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ + "jsx": "react-jsx", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ diff --git a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx index 02850db2b3..04b5e79991 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx +++ b/packages/pwa-kit-react-sdk/src/ssr/browser/main.jsx @@ -10,14 +10,13 @@ import {hydrateRoot} from 'react-dom/client' import PropTypes from 'prop-types' import {BrowserRouter as Router} from 'react-router-dom' import {loadableReady} from '@loadable/component' -import {getExtensions} from '@salesforce/pwa-kit-extension-support/core/extensions' +import {withApplicationExtensions} from '@salesforce/pwa-kit-extension-support/react' import {ServerContext, CorrelationIdProvider} from '../universal/contexts' import App from '../universal/components/_app' import {getAppConfig} from '../universal/compatibility' import Switch from '../universal/components/switch' import {getRoutes, routeComponent} from '../universal/components/route-component' -import {applyAppExtensions} from '../universal/extensibility/utils' import {uuidv4} from '../../utils/uuidv4.client' import logger from '../../utils/logger-instance' @@ -116,14 +115,7 @@ export const start = () => { // been warned. window.__HYDRATING__ = true - let WrappedApp = routeComponent(App, false, locals) - const extensions = getExtensions() - - // Use locals to thread the application extensions through the react app start flow. - locals.appExtensions = extensions - - // Initialize all the react app extensions. - WrappedApp = applyAppExtensions(WrappedApp, extensions) + const WrappedApp = withApplicationExtensions(routeComponent(App, false, locals), {locals}) const props = { error: window.__ERROR__, diff --git a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js index bbd69d00ba..a3578e75ee 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js +++ b/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js @@ -21,10 +21,9 @@ import sprite from 'svg-sprite-loader/runtime/sprite.build' import {isRemote} from '@salesforce/pwa-kit-runtime/utils/ssr-server' import {proxyConfigs} from '@salesforce/pwa-kit-runtime/utils/ssr-shared' import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -import {getExtensions} from '@salesforce/pwa-kit-extension-support/core/extensions' +import {withApplicationExtensions} from '@salesforce/pwa-kit-extension-support/react' import {getAssetUrl} from '../universal/utils' -import {applyAppExtensions} from '../universal/extensibility/utils' import {ServerContext, CorrelationIdProvider} from '../universal/contexts' import App from '../universal/components/_app' @@ -126,17 +125,11 @@ export const render = async (req, res, next) => { const AppConfig = getAppConfig() // Get the application config which should have been stored at this point. const config = getConfig() - const extensions = getExtensions() - console.log('React Rendering: ', extensions) + AppConfig.restore(res.locals) // Use locals to thread the application extensions through the rendering pipeline. - res.locals.appExtensions = extensions - - let WrappedApp = routeComponent(App, false, res.locals) - - // Initialize all the react app extensions. - WrappedApp = applyAppExtensions(WrappedApp, extensions) + const WrappedApp = withApplicationExtensions(routeComponent(App, false, res.locals), {locals: res.locals}) const routes = getRoutes(res.locals) diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js b/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js index 0da47e11fb..3e8900d877 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/components/route-component/index.js @@ -404,14 +404,14 @@ export const routeComponent = (Wrapped, isPage, locals) => { */ export const getRoutes = (locals = {}) => { let _routes = routes - const {appExtensions = []} = locals + const {applicationExtensions = []} = locals if (typeof routes === 'function') { _routes = routes() } // Call the `extendRoutes` function for all the Application Extensions. - appExtensions.forEach((appExtension) => { - _routes = appExtension.extendRoutes(_routes) + applicationExtensions.forEach((applicationExtension) => { + _routes = applicationExtension.extendRoutes(_routes) }) const allRoutes = [ diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/components/with-legacy-get-props/index.js b/packages/pwa-kit-react-sdk/src/ssr/universal/components/with-legacy-get-props/index.js index 66dfd160c5..54b3792627 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/components/with-legacy-get-props/index.js +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/components/with-legacy-get-props/index.js @@ -25,8 +25,8 @@ export const withLegacyGetProps = (Wrapped) => { * @private */ static async doInitAppState({App, match, route, req, res, location}) { + debugger const {params} = match - const components = [App, route.component] const promises = components.map((c, i) => { // getTemplateName is a promise and it's intentially not awaited here diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts deleted file mode 100644 index 66749be232..0000000000 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/application-extension.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ -import {IRouteConfig} from './types' - -/** - * An abstract class representing an Application Extension. This class provides - * foundational methods and properties for extending an application with additional - * configuration and routing capabilities. It is designed to be subclassed - * by other Application Extensions that need to augment the base application, particularly - * during server and client-side rendering. - * - * @abstract - */ -export default abstract class ApplicationExtension { - private config: Config - - /** - * Constructs a new instance of the ApplicationExtension class. - * - * @param config - The configuration object used to set up the extension. - */ - constructor(config: Config) { - this.config = config - } - - /** - * Returns the configuration that was used to instantiate this application extension. - * - * @protected - * @returns config - The configuration object. - */ - public getConfig(): Config { - return this.config - } - - /** - * Returns the name of the extension that will be used for logging. - * - * @protected - * @returns name - The name of the extension. - */ - public getName(): string { - return this.constructor.name - } - - /** - * Called during the rendering of the base application on the server and the client. - * It is predominantly used to enhance the "base" application by wrapping it with React providers. - * - * @protected - * @param App - The base application component. - * @returns EnhancedApp - The enhanced application component. - */ - public extendApp(App: React.ComponentType): React.ComponentType { - return App - } - - /** - * Called during server rendering and client application initialization. This method allows - * you to modify the routes of the base application, typically used to add new routes pointing - * at page components added by your application extension. - * - * @protected - * @param routes - The base application routes. - * @returns routes - The modified application routes. - */ - public extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { - return routes - } -} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts deleted file mode 100644 index 60b4b8efdb..0000000000 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/extensions.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// This file exports an empty function. During local development and the production build process, -// it'll be replaced to return those application extensions configured by the base PWA-Kit project. -const getExtensions = () => {} - -export default { - getExtensions -} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts deleted file mode 100644 index 2bdba4f6db..0000000000 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -// TODO: Figure out why this index file isn't working. E.g. import {extensions} from '../universal/extensibility' -// is broken. - -export {default as extensions} from './extensions' -export {default as ApplicationExtension} from './application-extension' -export * from './types' diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts deleted file mode 100644 index 09b485ff97..0000000000 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/extensibility/utils.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2024, salesforce.com, 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 - */ - -import React from 'react' -import {applyHOCs} from '../utils' -import ApplicationExtension from './application-extension' -import {ApplicationExtensionConfig} from './types' - -/** - * Given the provided Application, apply all the App extensions to it. - * - * @param App - */ -export const applyAppExtensions = ( - App: React.ComponentType, - extensions: ApplicationExtension[] -): React.ComponentType => { - const extendAppHocs = extensions - .map((extension) => extension.extendApp.bind(extension)) - .filter(Boolean) - - return applyHOCs(App, extendAppHocs) -} diff --git a/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts b/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts index 6880bc7113..4eb1735768 100644 --- a/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts +++ b/packages/pwa-kit-react-sdk/src/ssr/universal/utils.ts @@ -119,3 +119,4 @@ export const applyHOCs = >( return hoistNonReactStatics(WrappedComponent, AccumulatedComponent) as T }, Component) } + diff --git a/packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx b/packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx index 7257f58f3d..48417e65c9 100644 --- a/packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx +++ b/packages/template-typescript-minimal/app/overrides/components/with-red-border.tsx @@ -8,10 +8,10 @@ import React from 'react' // Define a type for the HOC props -type WithRedBorderProps = React.ComponentPropsWithoutRef; +type WithRedBorderProps = React.ComponentPropsWithoutRef // Define the HOC function -const withRedBorder =

(WrappedComponent: React.ComponentType

) => { +const withRedBorder =

(WrappedComponent: React.ComponentType

) => { const WithRedBorder: React.FC

= (props: WithRedBorderProps) => { return (

From 5f642add1a9489867410b4b37e4b432fbf068441 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 11 Oct 2024 16:09:03 -0700 Subject: [PATCH 149/929] "Something is working checkpoint" --- packages/extension-sample/package-lock.json | 104 ++ packages/extension-sample/package.json | 5 + packages/extension-sample/src/setup-app.ts | 12 +- packages/extension-sample/src/setup-server.ts | 18 +- packages/pwa-kit-dev/bin/pwa-kit-dev.js | 5 +- packages/pwa-kit-dev/package.json | 1 + .../src/configs/babel/babel-config.js | 12 + .../pwa-kit-dev/src/configs/webpack/config.js | 73 +- .../src/ssr/server/build-dev-server.js | 104 -- .../package-lock.json | 1269 +++++++++++++++++ .../pwa-kit-extension-support/package.json | 7 + .../application-extensions-placeholder.ts | 13 - .../babel/plugin-application-extensions.ts | 116 ++ .../webpack/loaders/extensions-loader.ts | 8 +- .../src/express/application-extension.ts | 40 + .../application-extensions-middleware.ts | 28 +- .../application-extensions-placeholder.ts | 19 + .../src/express/index.ts | 14 +- .../pwa-kit-extension-support/src/index.ts | 30 +- .../src/react/ApplicationExtension.ts | 51 + .../application-extensions-placeholder.ts | 19 + .../components/withApplicationExtensions.tsx | 23 +- .../ApplicationExtensionsProvider.tsx | 6 +- .../src/react/index.ts | 5 +- .../src/react/utils/index.ts | 6 +- .../src/shared/utils/extensibility-utils.ts | 21 +- .../src/shared/utils/universal-utils.ts | 25 +- packages/pwa-kit-runtime/package.json | 1 + .../src/ssr/server/build-remote-server.js | 124 +- 29 files changed, 1785 insertions(+), 374 deletions(-) delete mode 100644 packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts create mode 100644 packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts create mode 100644 packages/pwa-kit-extension-support/src/express/application-extension.ts create mode 100644 packages/pwa-kit-extension-support/src/express/assets/application-extensions-placeholder.ts create mode 100644 packages/pwa-kit-extension-support/src/react/ApplicationExtension.ts create mode 100644 packages/pwa-kit-extension-support/src/react/assets/application-extensions-placeholder.ts diff --git a/packages/extension-sample/package-lock.json b/packages/extension-sample/package-lock.json index d62908b37e..1d921ce043 100644 --- a/packages/extension-sample/package-lock.json +++ b/packages/extension-sample/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0-dev", "devDependencies": { "@loadable/component": "^5.15.3", + "@types/express": "^5.0.0", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "express": "^4.19.2", @@ -58,12 +59,88 @@ "react": "^16.3.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", + "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", "dev": true }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, "node_modules/@types/react": { "version": "18.2.79", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", @@ -83,6 +160,27 @@ "@types/react": "*" } }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -955,6 +1053,12 @@ "node": ">= 0.6" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/packages/extension-sample/package.json b/packages/extension-sample/package.json index f739f9c88a..167071065a 100644 --- a/packages/extension-sample/package.json +++ b/packages/extension-sample/package.json @@ -4,12 +4,16 @@ "scripts": {}, "peerDependencies": { "@loadable/component": "^5.15.3", + "@salesforce/pwa-kit-extension-support": "4.0.0-dev", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@loadable/component": "^5.15.3", "@salesforce/pwa-kit-extension-support": "4.0.0-dev", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@types/express": "^5.0.0", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "express": "^4.19.2", @@ -20,4 +24,5 @@ "node": "^16.11.0 || ^18.0.0 || ^20.0.0", "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" } + } diff --git a/packages/extension-sample/src/setup-app.ts b/packages/extension-sample/src/setup-app.ts index a484674522..39f9695f42 100644 --- a/packages/extension-sample/src/setup-app.ts +++ b/packages/extension-sample/src/setup-app.ts @@ -7,23 +7,27 @@ import React from 'react' import loadable from '@loadable/component' -import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' +import {RouteProps} from 'react-router-dom' +// Platform Imports +import {ApplicationExtension} from '@salesforce/pwa-kit-extension-support/react' + +// Local Imports import withRedBorder from '*/components/with-red-border' import {Config} from './types' + // NOTE: FIXME! // const SamplePage = loadable(() => import(/* webpackChunkName: "extension-sample-page-sample" */'./pages/sample')) import SamplePage from './pages/sample' const defaultPath: string = '/sample-page' class Sample extends ApplicationExtension { - extendApp(App: React.ComponentClass): React.ComponentClass { + extendApp(App: React.ComponentType): React.ComponentType { return withRedBorder(App) } - extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { - console.log('Extend Routes for ', this.getName(), this.getConfig().path || defaultPath) + extendRoutes(routes: RouteProps[]): RouteProps[] { return [ { exact: true, diff --git a/packages/extension-sample/src/setup-server.ts b/packages/extension-sample/src/setup-server.ts index f04f886a7d..6acf5b0164 100644 --- a/packages/extension-sample/src/setup-server.ts +++ b/packages/extension-sample/src/setup-server.ts @@ -5,16 +5,20 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { - Application as ExpressApplication, - ApplicationExtension as ExpressApplicationExtension -} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' -import {ServerExtensionConfig as Config} from './types' +// Third-Party Imports +import {Application} from 'express' -class SampleExtension extends ExpressApplicationExtension { +// Platform Imports +import {ApplicationExtension} from '@salesforce/pwa-kit-extension-support/express/application-extension' +// import {ApplicationExtension} from '@salesforce/pwa-kit-extension-support/express' // NOTE: Doing this causes a circular dependency. Looks to fix whatever is happening in the index file. - extendApp(app: ExpressApplication): ExpressApplication { +// Local Imports +import {Config} from './types' +class SampleExtension extends ApplicationExtension { + + extendApp(app: Application): Application { + console.log('setup-server: SampleExtension: extendApp: ', app) app.get('/sample', (req, res) => { console.log('SampleExtension extendApp GET /sample') res.send( diff --git a/packages/pwa-kit-dev/bin/pwa-kit-dev.js b/packages/pwa-kit-dev/bin/pwa-kit-dev.js index 971ac6de97..85bc81dcc5 100755 --- a/packages/pwa-kit-dev/bin/pwa-kit-dev.js +++ b/packages/pwa-kit-dev/bin/pwa-kit-dev.js @@ -239,8 +239,11 @@ const main = async () => { 'babel-node' ) + // This incluse 100% needs some work execSync( - `${babelNode} ${inspect ? '--inspect' : ''} ${babelArgs} ${getAppEntrypoint()}`, + `${babelNode} ${ + inspect ? '--inspect' : '' + } -i [\"/(?:\\/.*)?\\/node_modules\\//(?!@salesforce\/pwa-kit-extension-support\/dist)\\//i\"] ${babelArgs} ${getAppEntrypoint()}`, { env: { ...process.env, diff --git a/packages/pwa-kit-dev/package.json b/packages/pwa-kit-dev/package.json index afe6c130d7..adfdf30b90 100644 --- a/packages/pwa-kit-dev/package.json +++ b/packages/pwa-kit-dev/package.json @@ -66,6 +66,7 @@ "babel-loader": "^8.3.0", "babel-plugin-dynamic-import-node-babel-7": "^2.0.7", "babel-plugin-formatjs": "10.4.0", + "babel-plugin-module-resolver": "^5.0.2", "chalk": "^4.1.2", "commander": "^9.5.0", "compression": "1.7.4", diff --git a/packages/pwa-kit-dev/src/configs/babel/babel-config.js b/packages/pwa-kit-dev/src/configs/babel/babel-config.js index 3ffbc8efbf..99ae162b38 100644 --- a/packages/pwa-kit-dev/src/configs/babel/babel-config.js +++ b/packages/pwa-kit-dev/src/configs/babel/babel-config.js @@ -19,6 +19,18 @@ const config = { require('@babel/preset-react') ], plugins: [ + // [ + // require('babel-plugin-module-resolver'), + // { + // root: ["/Users/bchypak/Projects/pwa-kit/packages/template-typescript-minimal/node_modules"], // or whatever your source directory is + // // NOTE: I shouldn't have to use alias's here because the root should be enough to determine there these things exists. But this + // // does show that the plugin is running. So that is good news. + // alias: { + // '@salesforce/extension-sample/setup-server': '/Users/bchypak/Projects/pwa-kit/packages/extension-sample/src/setup-server.ts', + // } + // } + // ], + // require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), require('@babel/plugin-transform-async-to-generator'), require('@babel/plugin-proposal-object-rest-spread'), require('@babel/plugin-transform-object-assign'), diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 22bac0b202..807d28d1ee 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -263,7 +263,8 @@ const baseConfig = (target) => { loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), options: { pkg, - getConfig + getConfig, + target } } } @@ -546,76 +547,8 @@ const requestProcessor = }) .build() -// This is the extensions for multi-extensibility feature in PWA Kit. -// Don't mistake this with the concept of extensions for Webpack. -const extensions = - mode === 'production' - ? (getExtensionNames(appConfig?.extensions) || []) - .map((extension) => { - const setupServerFilePathBase = `${projectDir}/node_modules/${extension}/src/setup-server` - const foundType = ['ts', 'js'].find((type) => - fse.existsSync(`${setupServerFilePathBase}.${type}`) - ) - - if (!foundType) { - // No setup-server file found, early exit because it's optional - return - } - - const defaultTsConfig = { - target: 'ES2020', - module: 'commonjs', - strict: true, - esModuleInterop: true, - skipLibCheck: true - } - - let tsConfigFound = fse.existsSync( - `${projectDir}/node_modules/${extension}/tsconfig.json` - ) - - return { - name: 'extensions', - target: 'node', - mode, - entry: setupServerFilePathBase, - output: { - path: `${buildDir}/extensions/${extension}`, - filename: 'setup-server.js', - libraryTarget: 'commonjs2' - }, - resolve: { - extensions: ['.ts', '.js'] - }, - module: { - rules: [ - { - test: /\.ts?$/, - use: { - loader: findDepInStack('ts-loader'), - options: { - // If tsconfig is not found, ignore tsconfig.json and rely on - // using the default compilerOptions - // TODO: Avoid using happyPackMode in the future. - // This was required to get your PR working because the `tsconfig.json` - // file was not found. - happyPackMode: !tsConfigFound, - compilerOptions: tsConfigFound ? {} : defaultTsConfig - } - }, - exclude: /node_modules/ - } - ] - }, - optimization: { - minimize: false - } - } - }) - .filter(Boolean) - : [] -module.exports = [client, ssr, renderer, clientOptional, requestProcessor, ...extensions] +module.exports = [client, ssr, renderer, clientOptional, requestProcessor] .filter(Boolean) .map((config) => { return new SpeedMeasurePlugin({disable: !process.env.MEASURE}).wrap(config) diff --git a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js index 071798d711..339e16605a 100644 --- a/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js +++ b/packages/pwa-kit-dev/src/ssr/server/build-dev-server.js @@ -19,7 +19,6 @@ import open from 'open' import logger from '../../utils/logger-instance' import requireFromString from 'require-from-string' import {RemoteServerFactory} from '@salesforce/pwa-kit-runtime/ssr/server/build-remote-server' -import {ApplicationExtension} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' import {proxyConfigs} from '@salesforce/pwa-kit-runtime/utils/ssr-shared' import {bundleBasePath} from '@salesforce/pwa-kit-runtime/utils/ssr-namespace-paths' @@ -32,7 +31,6 @@ import { import {randomUUID} from 'crypto' import chalk from 'chalk' -import tsx from 'tsx/cjs/api' const CONTENT_TYPE = 'content-type' const CONTENT_ENCODING = 'content-encoding' @@ -131,108 +129,6 @@ export const DevServerMixin = { }) }, - /** - * @private - */ - _setupExtensions(app, options) { - logger.info('Setting up extensions...') - - // Normalize the extensions list for easier parsing - const extensions = (options.mobify?.app?.extensions || []) - .map((extension) => { - return { - // TODO: later we'll consider reusing a util function or perhaps eliminate this - packageName: Array.isArray(extension) ? extension[0] : extension, - config: Array.isArray(extension) - ? {enabled: true, ...extension[1]} - : {enabled: true} - } - }) - .filter((extension) => extension.config.enabled) - - logger.info('Extensions to load', { - namespace: 'DevServerMixin._setupExtensions', - additionalProperties: {extensions: extensions} - }) - - app.__extensions = extensions - - extensions.forEach((extension) => { - logger.info(`Loading extension: ${extension.packageName}`) - - const setupServerFilePathBase = path.join( - options.projectDir, - 'node_modules', - extension.packageName, - 'src', - 'setup-server' - ) - let filePath - if (fs.existsSync(`${setupServerFilePathBase}.ts`)) { - filePath = `${setupServerFilePathBase}.ts` - } else if (fs.existsSync(`${setupServerFilePathBase}.js`)) { - filePath = `${setupServerFilePathBase}.js` - } else { - logger.warn(`No setup-server file found for ${extension.packageName}. Skipping.`) - return - } - - let ExtensionClass - try { - ExtensionClass = tsx.require(filePath, __filename).default - } catch (e) { - logger.error(`Error loading extension ${extension.packageName}:`, { - namespace: 'DevServerMixin._setupExtensions', - additionalProperties: {error: e} - }) - return - } - - // Ensure that the default export is a class that extends abstract class "ApplicationExtension". - const isPrototype = Object.prototype.isPrototypeOf.call( - ApplicationExtension.prototype, - ExtensionClass?.prototype - ) - - if (!isPrototype) { - logger.error( - `'${extension.packageName}' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`, - { - namespace: 'DevServerMixin._setupExtensions' - } - ) - return - } - - let extensionInstance - try { - logger.info(`Instantiating extension class for ${extension.packageName}...`) - extensionInstance = new ExtensionClass(extension.config) - logger.info(`Successfully instantiated extension ${extension.packageName}.`) - } catch (e) { - logger.error(`Error instantiating extension ${extension.packageName}:`, { - namespace: 'DevServerMixin._setupExtensions', - additionalProperties: {error: e} - }) - return - } - - // Extend the app using the provided method - try { - logger.info(`Extending app using extension ${extension.packageName}...`) - app = extensionInstance.extendApp(app) - logger.info(`Successfully extended app with ${extension.packageName}.`) - } catch (e) { - logger.error(`Error setting extension ${extension.packageName}:`, { - namespace: 'DevServerMixin._setupExtensions', - additionalProperties: {error: e} - }) - } - }) - - logger.info('Finished setting up extensions.') - }, - /** * @private */ diff --git a/packages/pwa-kit-extension-support/package-lock.json b/packages/pwa-kit-extension-support/package-lock.json index 59dfebaaae..3434fbaa07 100644 --- a/packages/pwa-kit-extension-support/package-lock.json +++ b/packages/pwa-kit-extension-support/package-lock.json @@ -16,12 +16,16 @@ "resolve": "^1.22.8" }, "devDependencies": { + "@babel/core": "^7.21.3", + "@babel/parser": "^7.21.3", + "@types/express": "^5.0.0", "@types/fs-extra": "^11.0.4", "@types/hoist-non-react-statics": "~3.3.5", "@types/node": "^20", "@types/react-router-dom": "^5.3.3", "@types/resolve": "^1.20.6", "@types/webpack": "^5.28.5", + "express": "^4.19.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^5.3.4", @@ -32,11 +36,242 @@ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" }, "peerDependencies": { + "@babel/core": "^7.21.3", + "@babel/parser": "^7.21.3", + "express": "^4.19.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^5.3.4" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.25.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.8", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.8", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/runtime": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", @@ -49,6 +284,52 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -107,12 +388,55 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", + "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/fs-extra": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", @@ -139,6 +463,12 @@ "hoist-non-react-statics": "^3.3.0" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -154,6 +484,12 @@ "@types/node": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "node_modules/@types/node": { "version": "20.16.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", @@ -169,6 +505,18 @@ "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", "dev": true }, + "node_modules/@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, "node_modules/@types/react": { "version": "18.3.11", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", @@ -206,6 +554,27 @@ "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/webpack": { "version": "5.28.5", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-5.28.5.tgz", @@ -375,6 +744,19 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -421,6 +803,63 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, "node_modules/browserslist": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", @@ -459,6 +898,34 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001667", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", @@ -479,6 +946,41 @@ } ] }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -488,12 +990,69 @@ "node": ">=6.0" } }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, "node_modules/cross-env": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", @@ -530,6 +1089,23 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -543,12 +1119,63 @@ } } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, "node_modules/electron-to-chromium": { "version": "1.5.33", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", "dev": true }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/enhanced-resolve": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", @@ -562,6 +1189,27 @@ "node": ">=10.13.0" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", @@ -577,6 +1225,21 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -620,6 +1283,15 @@ "node": ">=4.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -629,6 +1301,69 @@ "node": ">=0.8.x" } }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -641,6 +1376,57 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -662,12 +1448,61 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -682,6 +1517,42 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -715,6 +1586,49 @@ "react-is": "^16.7.0" } }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-core-module": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", @@ -760,6 +1674,18 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -772,6 +1698,18 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -804,12 +1742,60 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -831,6 +1817,21 @@ "node": ">= 0.6" } }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -857,6 +1858,39 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -896,6 +1930,19 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -905,6 +1952,21 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -914,6 +1976,30 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -1030,6 +2116,12 @@ } ] }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -1065,6 +2157,54 @@ "semver": "bin/semver" } }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -1074,6 +2214,44 @@ "randombytes": "^2.1.0" } }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -1093,6 +2271,24 @@ "node": ">=0.10.0" } }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1112,6 +2308,15 @@ "source-map": "^0.6.0" } }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1211,6 +2416,24 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", "dev": true }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/type-fest": { "version": "4.26.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", @@ -1223,6 +2446,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -1237,6 +2473,15 @@ "node": ">= 10.0.0" } }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -1276,12 +2521,30 @@ "punycode": "^2.1.0" } }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", "dev": true }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/watchpack": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", @@ -1360,6 +2623,12 @@ "bin": { "which": "bin/which" } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true } } } diff --git a/packages/pwa-kit-extension-support/package.json b/packages/pwa-kit-extension-support/package.json index ad5fa3339f..d8b0b605b5 100644 --- a/packages/pwa-kit-extension-support/package.json +++ b/packages/pwa-kit-extension-support/package.json @@ -36,12 +36,16 @@ "resolve": "^1.22.8" }, "devDependencies": { + "@babel/core": "^7.21.3", + "@babel/parser": "^7.21.3", + "@types/express": "^5.0.0", "@types/fs-extra": "^11.0.4", "@types/hoist-non-react-statics": "~3.3.5", "@types/node": "^20", "@types/react-router-dom": "^5.3.3", "@types/resolve": "^1.20.6", "@types/webpack": "^5.28.5", + "express": "^4.19.2", "internal-lib-build": "4.0.0-dev", "type-fest": "^4.26.1", "react": "^18.2.0", @@ -49,6 +53,9 @@ "react-router-dom": "^5.3.4" }, "peerDependencies": { + "@babel/core": "^7.21.3", + "@babel/parser": "^7.21.3", + "express": "^4.19.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^5.3.4" diff --git a/packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts b/packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts deleted file mode 100644 index 4a3382f4e8..0000000000 --- a/packages/pwa-kit-extension-support/src/assets/application-extensions-placeholder.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2024, 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 - */ -// Types -import {ApplicationExtensionConfig} from '../types' -import {ApplicationExtension} from '..' - -const APPLICATION_EXTENSIONS: ApplicationExtension[] = [] - -export default APPLICATION_EXTENSIONS diff --git a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts new file mode 100644 index 0000000000..671bf96fae --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024, 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 + */ + +const parser = require("@babel/parser") +const babel = require("@babel/core") +// TODO: Refactor the shared logic +let extensionLoader = require('../webpack/loaders/extensions-loader') +import fse from 'fs-extra' +import _path, {resolve} from 'path' + +const projectDir = process.cwd() +const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) + +// const Module = require('module'); +// const originalRequire = Module.prototype.require; + +const getOptions =() => { + return { + pkg, + getConfig: () => ({ + app: { + extensions: ['@salesforce/extension-sample'] + } + }), + mode: 'server' + } +} +// application-extensions-placeholder +// const fileToReplace = 'assets/application-extensions-placeholder.js' +const repalcementContent = extensionLoader({getOptions}, {getOptions}) +// A Set to keep track of processed file paths +const processedFiles = new Set() + +module.exports = function replaceFileContentPlugin() { + return { + // pre() { + // // Hook into `require` to customize the module resolution logic + // Module.prototype.require = function (request: any) { + // console.log('request: ', request) + // if (false) { + // const resolvedPath = _path.resolve(projectDir, request); + // return originalRequire.call(this, resolvedPath); + // } + // return originalRequire.call(this, request) + // } + // }, + // post() { + // // Restore the original `require` function after the plugin finishes + // Module.prototype.require = originalRequire; + // }, + visitor: { + Program(path: any, state: any) { + const filePath = state.file.opts.filename + + // Add a marker to the state to prevent reprocessing + if (processedFiles.has(filePath)) { + // If the file has been processed, skip further transformations + return + } + + // Check if the file matches one of the files we want to replace + if (filePath.endsWith('assets/application-extensions-placeholder.js')) { + console.log('Project Directory: ', projectDir) + const newContent = repalcementContent + + let parsedAst; + try { + // Parse the new content as a full program + parsedAst = parser.parse(newContent, { + sourceType: "module", // Ensure it supports import/export + plugins: [ + "jsx", + "typescript"], // Add additional plugins if needed + }).program; + } catch (error: any) { + throw new Error(`Failed to parse content for ${filePath}: ${error.message}`) + } + + // Mark the file as processed by adding its path to the Set + processedFiles.add(filePath) + + // Replace the entire file content with the parsed AST + path.replaceWith(parsedAst) + + // Manually transpile the code to ES5 using Babel + const transpiledCode = babel.transformFromAstSync(parsedAst, newContent, { + filename: filePath, + presets: [ + [ + '/Users/bchypak/Projects/pwa-kit/packages/pwa-kit-dev/node_modules/@babel/preset-env', + { + targets: { + node: "current" + } + } + ] + ], // Transpile to ES5 + }).code + + // Parse the transpiled code and replace the current program node with it + const transpiledAst = parser.parse(transpiledCode, { + sourceType: "script", // Now using script because it's ES5 + }).program + + // Replace with the transpiled AST and complete the plugin execution. + path.replaceWith(transpiledAst) + path.stop() + } + } + } + } +} diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index a3949c4532..9158a030da 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -13,7 +13,7 @@ import {kebabToUpperCamelCase} from '../../../shared/utils' import {nameRegex} from '../../../shared/utils/extensibility-utils' const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' -const APP_EXTENSION_PREFIX = 'extension' // aligns with what's in `nameRegex` +const APP_EXTENSION_PREFIX = 'extension-' // aligns with what's in `nameRegex` // TODO: Move these to a better location. interface ExtensionsLoaderOptions { @@ -55,7 +55,7 @@ module.exports = function (this: ExtensionsLoaderContext) { instanceVariable: kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`), modulePath: `${ namespace ? `@${namespace}/` : '' - }${APP_EXTENSION_PREFIX}-${name}/${APP_EXTENSION_CLIENT_ENTRY}`, + }${APP_EXTENSION_PREFIX}${name}/${APP_EXTENSION_CLIENT_ENTRY}`, packageName } }) @@ -83,7 +83,9 @@ module.exports = function (this: ExtensionsLoaderContext) { config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} } }) - + + // import Test from '@salesforce/extension-sample/setup-server' + // console.log('Manual Import: ', Test) // App Extensions ${extensionDetails .map( diff --git a/packages/pwa-kit-extension-support/src/express/application-extension.ts b/packages/pwa-kit-extension-support/src/express/application-extension.ts new file mode 100644 index 0000000000..a2e3d19123 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/express/application-extension.ts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import {ApplicationExtensionConfig} from "../types" + +import {ApplicationExtension as BaseApplicationExtension} from ".." +import {Application} from 'express' + +/** + * An abstract class representing an Application Extension. This class provides + * foundational methods and properties for extending an application with additional + * configuration and routing capabilities. It is designed to be subclassed + * by other Application Extensions that need to augment the base application, particularly + * during server and client-side rendering. + * + * @abstract + */ +export class ApplicationExtension extends BaseApplicationExtension{ + /** + * Called during the rendering of the base application on the server and the client. + * It is predominantly used to enhance the "base" application by wrapping it with React providers. + * + * @protected + * @param App - The base application component. + * @returns EnhancedApp - The enhanced application component. + */ + public extendApp(App: Application): Application { + return App + } +} diff --git a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts index eb9cc98d54..1c3309745c 100644 --- a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts +++ b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts @@ -3,4 +3,30 @@ * 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 - */ \ No newline at end of file + */ + +// Third-Party Imports +import {Request, Response, NextFunction, Application} from 'express' + +// Local Imports +import {ApplicationExtension} from './application-extension' +// import {getApplicationExtensions} from '../shared/utils/universal-utils' // Because there is some kind of module caching we can't have this shared! + +// TODO: Define our own type for this extension. +// import {ApplicationExtensionConfig} from '../types' + +import APPLICATION_EXTENSIONS from './assets/application-extensions-placeholder' + +// Define the middleware function that modifies the app +const applicationExtensionsMiddleware = (app: Application) => { + // const applicationExtensions = getApplicationExtensions>() as ApplicationExtension[] + console.log('applicationExtensionsMiddleware: applying ', APPLICATION_EXTENSIONS) + APPLICATION_EXTENSIONS.forEach((applicationExtension) => { + app = applicationExtension.extendApp(app) + }) + return (req: Request, res: Response, next: NextFunction): void => { + next() + } +} + +export default applicationExtensionsMiddleware \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/express/assets/application-extensions-placeholder.ts b/packages/pwa-kit-extension-support/src/express/assets/application-extensions-placeholder.ts new file mode 100644 index 0000000000..c0de040809 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/express/assets/application-extensions-placeholder.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, 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 + */ +// Types +import {ApplicationExtensionConfig as ApplicationExtensionConfigBase} from '../../types' +import {ApplicationExtension as ApplicationExtensionBase} from '../application-extension' + +// interface ExtendedApplicationExtensionConfig extends ApplicationExtensionConfigBase {} +// Declare the generic type `T` and extend it from `ApplicationExtensionConfigBase` +interface ApplicationExtension extends ApplicationExtensionBase {} + +// Define an array of ApplicationExtension +const APPLICATION_EXTENSIONS: ApplicationExtension[] = [] +// const APPLICATION_EXTENSIONS: ApplicationExtension[] = [] +// Export the array +export default APPLICATION_EXTENSIONS \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/express/index.ts b/packages/pwa-kit-extension-support/src/express/index.ts index eb9cc98d54..91f53784ac 100644 --- a/packages/pwa-kit-extension-support/src/express/index.ts +++ b/packages/pwa-kit-extension-support/src/express/index.ts @@ -3,4 +3,16 @@ * 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 - */ \ No newline at end of file + */ + +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import './application-extension' +import './application-extensions-middleware' + +export * from './application-extension' +export {default as applicationExtensionMiddleware} from './application-extensions-middleware' \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/index.ts b/packages/pwa-kit-extension-support/src/index.ts index 0292286abb..f8b158d3a2 100644 --- a/packages/pwa-kit-extension-support/src/index.ts +++ b/packages/pwa-kit-extension-support/src/index.ts @@ -4,7 +4,8 @@ * 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 */ -import {RouteProps} from 'react-router-dom' + +import {ApplicationExtensionConfig} from './types' /** * An abstract class representing an Application Extension. This class provides @@ -15,7 +16,7 @@ import {RouteProps} from 'react-router-dom' * * @abstract */ -export abstract class ApplicationExtension { +export abstract class ApplicationExtension { private config: Config /** @@ -46,29 +47,4 @@ export abstract class ApplicationExtension { public getName(): string { return this.constructor.name } - - /** - * Called during the rendering of the base application on the server and the client. - * It is predominantly used to enhance the "base" application by wrapping it with React providers. - * - * @protected - * @param App - The base application component. - * @returns EnhancedApp - The enhanced application component. - */ - public extendApp(App: React.ComponentType): React.ComponentType { - return App - } - - /** - * Called during server rendering and client application initialization. This method allows - * you to modify the routes of the base application, typically used to add new routes pointing - * at page components added by your application extension. - * - * @protected - * @param routes - The base application routes. - * @returns routes - The modified application routes. - */ - public extendRoutes(routes: RouteProps[]): RouteProps[] { - return routes - } } diff --git a/packages/pwa-kit-extension-support/src/react/ApplicationExtension.ts b/packages/pwa-kit-extension-support/src/react/ApplicationExtension.ts new file mode 100644 index 0000000000..4e69a1b002 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/ApplicationExtension.ts @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import {RouteProps} from 'react-router-dom' + +// Local +import {ApplicationExtension as ApplicationExtensionBase} from ".." + +// Types +import {ApplicationExtensionConfig} from "../types" + +// type GenericHocType = (component: React.ComponentType) => React.ComponentType + +/** + * An abstract class representing an Application Extension. This class provides + * foundational methods and properties for extending an application with additional + * configuration and routing capabilities. It is designed to be subclassed + * by other Application Extensions that need to augment the base application, particularly + * during server and client-side rendering. + * + * @abstract + */ +export class ApplicationExtension extends ApplicationExtensionBase{ + /** + * Called during the rendering of the base application on the server and the client. + * It is predominantly used to enhance the "base" application by wrapping it with React providers. + * + * @protected + * @param App - The base application component. + * @returns EnhancedApp - The enhanced application component. + */ + public extendApp>(App: React.ComponentType): React.ComponentType { + return App + } + + /** + * Called during server rendering and client application initialization. This method allows + * you to modify the routes of the base application, typically used to add new routes pointing + * at page components added by your application extension. + * + * @protected + * @param routes - The base application routes. + * @returns routes - The modified application routes. + */ + public extendRoutes(routes: RouteProps[]): RouteProps[] { + return routes + } +} \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/react/assets/application-extensions-placeholder.ts b/packages/pwa-kit-extension-support/src/react/assets/application-extensions-placeholder.ts new file mode 100644 index 0000000000..47fdba9f43 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/react/assets/application-extensions-placeholder.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024, 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 + */ +// Types +import {ApplicationExtensionConfig as ApplicationExtensionConfigBase} from '../../types' +import {ApplicationExtension as ApplicationExtensionBase} from '../ApplicationExtension' + +// interface ExtendedApplicationExtensionConfig extends ApplicationExtensionConfigBase {} +// Declare the generic type `T` and extend it from `ApplicationExtensionConfigBase` +interface ApplicationExtension extends ApplicationExtensionBase {} + +// Define an array of ApplicationExtension +const APPLICATION_EXTENSIONS: ApplicationExtension[] = [] +// const APPLICATION_EXTENSIONS: ApplicationExtension[] = [] +// Export the array +export default APPLICATION_EXTENSIONS diff --git a/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx b/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx index 68c3864aa3..67cb2edfcb 100644 --- a/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx +++ b/packages/pwa-kit-extension-support/src/react/components/withApplicationExtensions.tsx @@ -9,7 +9,13 @@ import React from 'react' // Local import {applyHOCs} from '../utils' -import {getApplicationExtensions} from '../../shared/utils/universal-utils' +// import {getApplicationExtensions} from '../../shared/utils/universal-utils' +import APPLICATION_EXTENSIONS from '../assets/application-extensions-placeholder' + + +// Types +import {ApplicationExtension} from '../ApplicationExtension' +import {ApplicationExtensionConfig as ApplicationExtensionConfigBase} from '../../types' type withApplicationExtensionsOptions = { locals?: any @@ -31,18 +37,21 @@ type withApplicationExtensionsOptions = { * @returns A new React component with all extensions applied, rendering the `WrappedComponent` * with the extended behavior. */ +type GenericHocType = (component: React.ComponentType) => React.ComponentType -const withApplicationExtensions =

(WrappedComponent: React.ComponentType

, options: withApplicationExtensionsOptions) => { - const extensions = getApplicationExtensions() - const extendAppHocs: Array<(component: React.ComponentType

) => React.ComponentType

> = extensions - .map((extension) => extension.extendApp.bind(extension)) +const withApplicationExtensions = >(WrappedComponent: React.ComponentType, options: withApplicationExtensionsOptions) => { + // const extensions = getApplicationExtensions

() as P[] + const hocs: GenericHocType[] = APPLICATION_EXTENSIONS + .map((extension: any) => extension.extendApp.bind(extension) as GenericHocType) .filter(Boolean) if (options?.locals) { - options.locals.applicationExtensions = extensions + options.locals.applicationExtensions = APPLICATION_EXTENSIONS } - return applyHOCs(WrappedComponent, extendAppHocs) + return applyHOCs(WrappedComponent, hocs) } export default withApplicationExtensions + + diff --git a/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx b/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx index ce45c61af5..e5628bdb57 100644 --- a/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx +++ b/packages/pwa-kit-extension-support/src/react/contexts/ApplicationExtensionsProvider.tsx @@ -9,7 +9,7 @@ import React from 'react' // Local // TODO: We can probably pass this in as an initial value.? -import {getApplicationExtensions} from '../../shared/utils/universal-utils' +// import {getApplicationExtensions} from '../../shared/utils/universal-utils' import ApplicationExtensionsContext from './ApplicationExtensionsContext' // TODO: Clean this up. @@ -18,10 +18,10 @@ type ApplicationExtensionsProviderProps = { } const ApplicationExtensionsProvider = ({children}: ApplicationExtensionsProviderProps) => { - const extensions = getApplicationExtensions() + // const extensions = getApplicationExtensions() return ( - + {children} ) diff --git a/packages/pwa-kit-extension-support/src/react/index.ts b/packages/pwa-kit-extension-support/src/react/index.ts index 3bbb44c3a6..c91259d112 100644 --- a/packages/pwa-kit-extension-support/src/react/index.ts +++ b/packages/pwa-kit-extension-support/src/react/index.ts @@ -5,6 +5,9 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ +import './ApplicationExtension' + export * from './components' export * from './contexts' -export * from './hooks' \ No newline at end of file +export * from './hooks' +export * from './ApplicationExtension' diff --git a/packages/pwa-kit-extension-support/src/react/utils/index.ts b/packages/pwa-kit-extension-support/src/react/utils/index.ts index e81b5c7856..634a6c9cda 100644 --- a/packages/pwa-kit-extension-support/src/react/utils/index.ts +++ b/packages/pwa-kit-extension-support/src/react/utils/index.ts @@ -20,11 +20,13 @@ import hoistNonReactStatics from 'hoist-non-react-statics' * @param {Array<(component: T) => T>} hocs - An array of Higher-Order Components (HOCs) to apply to the component. * @returns {T} - The React component wrapped with the provided HOCs. */ +// type GenericHocType = (component: React.ComponentType) => React.ComponentType + export const applyHOCs = >( Component: T, - hocs: Array<(component: T) => T> + hocs: any ): T => { - return hocs.reduce((AccumulatedComponent, hoc) => { + return hocs.reduce((AccumulatedComponent: any, hoc: any) => { const WrappedComponent = hoc(AccumulatedComponent) return hoistNonReactStatics(WrappedComponent, AccumulatedComponent) as T }, Component) diff --git a/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts index 9ec59626bd..0f4c965df3 100644 --- a/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts @@ -12,6 +12,8 @@ import fs from 'fs-extra' import {ApplicationExtensionEntry, ApplicationExtensionEntryArray} from '../../types' const REACT_EXTENSIBILITY_FILE = 'setup-app' +const EXPRESS_EXTENSIBILITY_FILE = 'setup-server' + const SUPPORTED_FILE_TYPES = ['.ts', '.js'] /** @@ -39,20 +41,23 @@ export const buildAliases = (extensions: ApplicationExtensionEntry[] = []) => { projectDir, 'node_modules', extension, - 'src', // 🤔 - REACT_EXTENSIBILITY_FILE + 'src' + // , // 🤔 + // REACT_EXTENSIBILITY_FILE ) - const foundFilePath = findFileWithExtension(basePath, SUPPORTED_FILE_TYPES) + // const foundFilePath = findFileWithExtension(basePath, SUPPORTED_FILE_TYPES) - if (!foundFilePath) { - // no setup-server file found, early exit because it's optional - return acc - } + // if (!foundFilePath) { + // // no setup-server file found, early exit because it's optional + // return acc + // } return { ...acc, - [`${extension}/${REACT_EXTENSIBILITY_FILE}`]: foundFilePath + // [`${extension}/${REACT_EXTENSIBILITY_FILE}`]: findFileWithExtension(path.join(basePath, REACT_EXTENSIBILITY_FILE), SUPPORTED_FILE_TYPES), + // [`${extension}/${EXPRESS_EXTENSIBILITY_FILE}`]: findFileWithExtension(path.join(basePath, EXPRESS_EXTENSIBILITY_FILE), SUPPORTED_FILE_TYPES) + [`${extension}`]: basePath } }, {}) diff --git a/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts b/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts index 3993a9dfac..a06dbfb86c 100644 --- a/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/universal-utils.ts @@ -6,10 +6,27 @@ */ // Types -import {ApplicationExtensionConfig} from '../../types' +import {ApplicationExtensionConfig as ApplicationExtensionConfigBase} from '../../types' // Local -import {ApplicationExtension} from '../..' -import APPLICATION_EXTENSIONS from '../../assets/application-extensions-placeholder' +import {ApplicationExtension as ApplicationExtensionBase} from '../..' +// import APPLICATION_EXTENSIONS from '../../assets/application-extensions-placeholder' +// console.log('import APPLICATION_EXTENSIONS: ', APPLICATION_EXTENSIONS) +// TODO: Move these to the global types folder. +interface ApplicationExtensionConfig extends ApplicationExtensionConfigBase {} +interface ApplicationExtension extends ApplicationExtensionBase {} -export const getApplicationExtensions = (): ApplicationExtension[] => APPLICATION_EXTENSIONS +// export const getApplicationExtensions = >(): ApplicationExtension[] => { +// console.log('getApplicationExtensions: ', APPLICATION_EXTENSIONS) +// // Search for the matching extension in the array +// return APPLICATION_EXTENSIONS as T[] +// } + + +// class O {} +// class A extends O {} +// class B extends O {} + +// const getArray2 = (): T[] => { +// return [new B() as T] +// } \ No newline at end of file diff --git a/packages/pwa-kit-runtime/package.json b/packages/pwa-kit-runtime/package.json index 0079ee0851..576c00eab7 100644 --- a/packages/pwa-kit-runtime/package.json +++ b/packages/pwa-kit-runtime/package.json @@ -47,6 +47,7 @@ "devDependencies": { "@loadable/component": "^5.15.3", "@salesforce/pwa-kit-dev": "4.0.0-dev", + "@salesforce/pwa-kit-extension-support": "4.0.0-dev", "@serverless/event-mocks": "^1.1.1", "@types/express": "^4.17.21", "aws-lambda-mock-context": "^3.2.1", diff --git a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js index 90a4255755..16ffad5a0d 100644 --- a/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js +++ b/packages/pwa-kit-runtime/src/ssr/server/build-remote-server.js @@ -50,7 +50,7 @@ import awsServerlessExpress from 'aws-serverless-express' import expressLogging from 'morgan' import logger from '../../utils/logger-instance' import {createProxyMiddleware} from 'http-proxy-middleware' -import {ApplicationExtension} from './extensibility' +import {applicationExtensionMiddleware} from '@salesforce/pwa-kit-extension-support/express' /** * An Array of mime-types (Content-Type values) that are considered @@ -370,8 +370,6 @@ export const RemoteServerFactory = { // processing. this._setupCommonMiddleware(app, options) - this._setupExtensions(app, options) - this._addStaticAssetServing(app) this._addDevServerGarbageCollection(app) return app @@ -649,121 +647,6 @@ export const RemoteServerFactory = { }) }, - /** - * This function is called during server initialization. - * - * This function assumes that optionally, there is a `setup-server.js` - * file in each extension directory in the build. - * - * This file should export a default which is a class extending ApplicationExtension abstract class. - * - * @private - */ - _setupExtensions(app, options) { - logger.info('Setting up extensions...') - - // Normalize the extensions list for easier parsing - const extensions = (options.mobify?.app?.extensions || []) - .map((extension) => { - return { - // TODO: later we'll consider reusing a util function or perhaps eliminate this - packageName: Array.isArray(extension) ? extension[0] : extension, - config: Array.isArray(extension) - ? {enabled: true, ...extension[1]} - : {enabled: true} - } - }) - .filter((extension) => extension.config.enabled) - - logger.info('Extensions to load', { - namespace: 'RemoteServerFactory._setupExtensions', - additionalProperties: {extensions: extensions} - }) - - app.__extensions = extensions - - let _require - - extensions.forEach((extension) => { - logger.info(`Loading extension: ${extension.packageName}`) - - const setupServerFilePath = path.join( - options.buildDir, - 'extensions', - extension.packageName, - 'setup-server.js' - ) - - // Only eval when there are extensions - // this makes it slightly faster for projects that - // have no extensions - if (!_require) { - _require = eval('require') - } - - let ExtensionClass - try { - ExtensionClass = _require(setupServerFilePath).default - } catch (e) { - if (e.message && e.message.startsWith('Cannot find module')) { - logger.warn( - `No setup-server.js file found for ${extension.packageName}. Skipping.` - ) - return - } - - logger.error(`Error loading extension ${extension.packageName}:`, { - namespace: 'RemoteServerFactory._setupExtensions', - additionalProperties: {error: e} - }) - throw e - } - - // Ensure that the default export is a class that extends abstract class "ApplicationExtension". - const isPrototype = Object.prototype.isPrototypeOf.call( - ApplicationExtension.prototype, - ExtensionClass?.prototype - ) - - if (!isPrototype) { - logger.error( - `'${extension.packageName}' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`, - { - namespace: 'RemoteServerFactory._setupExtensions' - } - ) - return - } - - let extensionInstance - try { - logger.info(`Instantiating extension class for ${extension.packageName}...`) - extensionInstance = new ExtensionClass(extension.config) - logger.info(`Successfully instantiated extension ${extension.packageName}.`) - } catch (e) { - logger.error(`Error instantiating extension ${extension.packageName}:`, { - namespace: 'RemoteServerFactory._setupExtensions', - additionalProperties: {error: e} - }) - return - } - - // Extend the app using the provided method - try { - logger.log(`Extending app using extension ${extension.packageName}...`) - app = extensionInstance.extendApp(app) - logger.log(`Successfully extended app with ${extension.packageName}.`) - } catch (e) { - logger.error(`Error setting extension ${extension.packageName}:`, { - namespace: 'RemoteServerFactory._setupExtensions', - additionalProperties: {error: e} - }) - } - }) - - logger.info('Finished setting up extensions.') - }, - /** * @private */ @@ -871,6 +754,11 @@ export const RemoteServerFactory = { // to add in their projects, like in any regular Express app. app.use(ssrMiddleware) app.use(errorHandlerMiddleware) + console.log('Applying Application Extension Middleware: ', applicationExtensionMiddleware) + + // NOTE: Think about changing the name of this function to `applyApplicationExtensions`. First look into + // what a common pattern is for application enhancement. + applicationExtensionMiddleware(app) applyPatches(options) }, From a270da2427ca2ae5da1361c0f1b647897efc3301 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Wed, 16 Oct 2024 10:20:49 -0700 Subject: [PATCH 150/929] It works now.. no need for a stand alone webpack loader. --- .../src/configs/babel/babel-config.js | 2 +- .../pwa-kit-dev/src/configs/webpack/config.js | 17 +++++++- .../babel/plugin-application-extensions.ts | 40 +++++++++---------- .../webpack/loaders/extensions-loader.ts | 17 ++++---- 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/packages/pwa-kit-dev/src/configs/babel/babel-config.js b/packages/pwa-kit-dev/src/configs/babel/babel-config.js index 99ae162b38..0a1de924d3 100644 --- a/packages/pwa-kit-dev/src/configs/babel/babel-config.js +++ b/packages/pwa-kit-dev/src/configs/babel/babel-config.js @@ -30,7 +30,7 @@ const config = { // } // } // ], - // require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), + require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), // NOTE: Would be nice to import with only /babel require('@babel/plugin-transform-async-to-generator'), require('@babel/plugin-proposal-object-rest-spread'), require('@babel/plugin-transform-object-assign'), diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 807d28d1ee..68934ab50f 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -258,16 +258,29 @@ const baseConfig = (target) => { // NOTE: Might be better to export a rule directly that we can plog in here, this will // make the "extensions" file private so was can change that implementation detail later // if we choose to do so. - test: /application-extensions-placeholder\.js/i, + test: /react\/assets\/application-extensions-placeholder\.js/i, use: { loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), options: { pkg, getConfig, - target + target: 'web' } } } + // , + // { + // // TODO: Export rule from app extensibility sdk instead of using these loaders directly + // test: /express\/assets\/application-extensions-placeholder\.js/i, + // use: { + // loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), + // options: { + // pkg, + // getConfig, + // target: 'node' + // } + // } + // } ].filter(Boolean) } } diff --git a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts index 671bf96fae..9b3b4d03d0 100644 --- a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts +++ b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts @@ -15,9 +15,6 @@ import _path, {resolve} from 'path' const projectDir = process.cwd() const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) -// const Module = require('module'); -// const originalRequire = Module.prototype.require; - const getOptions =() => { return { pkg, @@ -26,7 +23,7 @@ const getOptions =() => { extensions: ['@salesforce/extension-sample'] } }), - mode: 'server' + target: 'node' } } // application-extensions-placeholder @@ -35,24 +32,25 @@ const repalcementContent = extensionLoader({getOptions}, {getOptions}) // A Set to keep track of processed file paths const processedFiles = new Set() -module.exports = function replaceFileContentPlugin() { +module.exports = function replaceFileContentPlugin({ types: t } : any) { return { - // pre() { - // // Hook into `require` to customize the module resolution logic - // Module.prototype.require = function (request: any) { - // console.log('request: ', request) - // if (false) { - // const resolvedPath = _path.resolve(projectDir, request); - // return originalRequire.call(this, resolvedPath); - // } - // return originalRequire.call(this, request) - // } - // }, - // post() { - // // Restore the original `require` function after the plugin finishes - // Module.prototype.require = originalRequire; - // }, visitor: { + ImportDeclaration(path: any) { + const aliases: any = { + '@salesforce/extension-sample': '/Users/bchypak/Projects/pwa-kit/packages/template-typescript-minimal/node_modules/@salesforce/extension-sample/src/' + } + + const source = path.node.source.value + + // Check for alias + for (const alias in aliases) { + if (source.startsWith(alias)) { + const newPath = source.replace(alias, aliases[alias]) + console.log('newPath: ', newPath) + path.node.source = t.stringLiteral(newPath) + } + } + }, Program(path: any, state: any) { const filePath = state.file.opts.filename @@ -63,7 +61,7 @@ module.exports = function replaceFileContentPlugin() { } // Check if the file matches one of the files we want to replace - if (filePath.endsWith('assets/application-extensions-placeholder.js')) { + if (filePath.endsWith('express/assets/application-extensions-placeholder.js')) { console.log('Project Directory: ', projectDir) const newContent = repalcementContent diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index 9158a030da..833bc8fe10 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -13,12 +13,16 @@ import {kebabToUpperCamelCase} from '../../../shared/utils' import {nameRegex} from '../../../shared/utils/extensibility-utils' const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' +const APP_EXTENSION_SERVER_ENTRY = 'setup-server' const APP_EXTENSION_PREFIX = 'extension-' // aligns with what's in `nameRegex` + + // TODO: Move these to a better location. interface ExtensionsLoaderOptions { pkg: PackageJson, - getConfig: () => any + getConfig: () => any, + target: 'node' | 'web' } interface ExtensionsLoaderContext extends LoaderContext { @@ -39,8 +43,9 @@ interface ExtensionsLoaderContext extends LoaderContext * * @returns {string} The string representation of a module exporting all the named application extension modules. */ -module.exports = function (this: ExtensionsLoaderContext) { - const {pkg, getConfig} = this.getOptions() || {} +module.exports = function (this: ExtensionsLoaderContext, that: any) { + // console.log('this|that: ', this, that) + const {pkg, getConfig, target = 'web'} = that?.getOptions?.() || this.getOptions() || {} const {devDependencies} = pkg // TODO: clean this up.. looks like this is a bad variable name for the type that it represents. @@ -55,7 +60,7 @@ module.exports = function (this: ExtensionsLoaderContext) { instanceVariable: kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`), modulePath: `${ namespace ? `@${namespace}/` : '' - }${APP_EXTENSION_PREFIX}${name}/${APP_EXTENSION_CLIENT_ENTRY}`, + }${APP_EXTENSION_PREFIX}${name}/${target === 'web' ? APP_EXTENSION_CLIENT_ENTRY : APP_EXTENSION_SERVER_ENTRY}`, packageName } }) @@ -83,9 +88,7 @@ module.exports = function (this: ExtensionsLoaderContext) { config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} } }) - - // import Test from '@salesforce/extension-sample/setup-server' - // console.log('Manual Import: ', Test) + // App Extensions ${extensionDetails .map( From d6d330ddc7a6ce7c062eef43396cefa3aa6ec1b6 Mon Sep 17 00:00:00 2001 From: Kevin He Date: Wed, 16 Oct 2024 16:27:48 -0700 Subject: [PATCH 151/929] initialize store locator extension --- .../package-lock.json | 4 +- packages/extension-store-locator/README.md | 68 + .../extension-store-locator/package-lock.json | 2122 +++++++++++++++++ packages/extension-store-locator/package.json | 26 + .../src/pages/store-locator/index.tsx | 59 + .../extension-store-locator/src/setup-app.ts | 33 + .../src/setup-server.ts | 22 + .../src/types /config.ts | 26 + .../src/types /index.ts | 8 + .../template-typescript-minimal/package.json | 3 +- 10 files changed, 2368 insertions(+), 3 deletions(-) create mode 100644 packages/extension-store-locator/README.md create mode 100644 packages/extension-store-locator/package-lock.json create mode 100644 packages/extension-store-locator/package.json create mode 100644 packages/extension-store-locator/src/pages/store-locator/index.tsx create mode 100644 packages/extension-store-locator/src/setup-app.ts create mode 100644 packages/extension-store-locator/src/setup-server.ts create mode 100644 packages/extension-store-locator/src/types /config.ts create mode 100644 packages/extension-store-locator/src/types /index.ts diff --git a/packages/extension-sample-with-overrides/package-lock.json b/packages/extension-sample-with-overrides/package-lock.json index d62908b37e..1a83135070 100644 --- a/packages/extension-sample-with-overrides/package-lock.json +++ b/packages/extension-sample-with-overrides/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@salesforce/extension-sample", + "name": "@salesforce/extension-sample-with-overrides", "version": "1.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@salesforce/extension-sample", + "name": "@salesforce/extension-sample-with-overrides", "version": "1.0.0-dev", "devDependencies": { "@loadable/component": "^5.15.3", diff --git a/packages/extension-store-locator/README.md b/packages/extension-store-locator/README.md new file mode 100644 index 0000000000..d19ecefd06 --- /dev/null +++ b/packages/extension-store-locator/README.md @@ -0,0 +1,68 @@ + __ _ __ _ _ +/ _\ __ _ _ __ ___ _ __ | | ___ /__\_ _| |_ ___ _ __ ___(_) ___ _ __ +\ \ / _` | '_ ` _ \| '_ \| |/ _ \ /_\ \ \/ / __/ _ \ '_ \/ __| |/ _ \| '_ \ +_\ \ (_| | | | | | | |_) | | __/ //__ > <| || __/ | | \__ \ | (_) | | | | +\__/\__,_|_| |_| |_| .__/|_|\___| \__/ /_/\_\\__\___|_| |_|___/_|\___/|_| |_| + |_| + +# Description + +This is a sample PWA-Kit Application Extension. The purpose of this application extensions is to show how +the Application Extensions API can be used to enhance your PWA-Kit base project. + +# Folder Structure + +Insert description of generic Application Extension folder structure here. + +# Peer Dependancies + +PWA-Kit Application Extensions are NPM packages at their most simplest form, and as such you can define +what peer dependencies are required when using it. Because this sample application extension provides +UI via a new "Sample" page, it requires that the below dependencies are installed at a minimum. + +Depending on what features your application extensions provides it's recommended you include any third-party +packages as peer dependencies so that your base application doesn't end up having multiple versions of a +given package. + +"react": "^18.2.0", +"react-dom": "^18.2.0" + +# Configuration + +This section is optional and will depend on your application extensions implementation. If you have features +that are configurable, then list those configurations here so that the PWA-Kit project implementor can configure +the extension as they like. + +``` +{ + path: 'sample-page' +} +``` + +# Installation + +``` +> npm install @salesforce/extension-sample --legacy-peer-deps*
+> Downloading npm package...
+> Installing extention...
+> Finished.
+> Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. +``` + +# Advanced Usage + +In order to customize this Application Extension to your particulare needs we suggest that you refer to the section titled +"configuration", but if there is something that you want to customize that isn't configurable and cannot wait for a feature +request to be fulfilled, then you can use overrides. + +Below is a list of files that can't be overridden from within your PWA-Kit base project. Please refer to the documentation here on +how to properly override extensions. Additionally it's up to the Application Extension developer as to which files can and +cannot be overridden. Please refer to this documentation on how to write your first PWA-Kit Application Extension. + +## Overridable Files + +``` +/src/path/to/overridable/file.ts +``` + + diff --git a/packages/extension-store-locator/package-lock.json b/packages/extension-store-locator/package-lock.json new file mode 100644 index 0000000000..5b77fcd04b --- /dev/null +++ b/packages/extension-store-locator/package-lock.json @@ -0,0 +1,2122 @@ +{ + "name": "@salesforce/extension-store-locator", + "version": "1.0.0-dev", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@salesforce/extension-store-locator", + "version": "1.0.0-dev", + "devDependencies": { + "@chakra-ui/react": "^2.10.3", + "@loadable/component": "^5.15.3", + "@types/react": "~18.2.0", + "@types/react-dom": "~18.2.1", + "express": "^4.19.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + }, + "peerDependencies": { + "@chakra-ui/react": "^2.10.3", + "@loadable/component": "^5.15.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/highlight": "^7.25.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.25.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/@babel/types": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@chakra-ui/anatomy": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.3.4.tgz", + "integrity": "sha512-fFIYN7L276gw0Q7/ikMMlZxP7mvnjRaWJ7f3Jsf9VtDOi6eAYIBRrhQe6+SZ0PGmoOkRaBc7gSE5oeIbgFFyrw==", + "dev": true + }, + "node_modules/@chakra-ui/hooks": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.4.2.tgz", + "integrity": "sha512-LRKiVE1oA7afT5tbbSKAy7Uas2xFHE6IkrQdbhWCHmkHBUtPvjQQDgwtnd4IRZPmoEfNGwoJ/MQpwOM/NRTTwA==", + "dev": true, + "dependencies": { + "@chakra-ui/utils": "2.2.2", + "@zag-js/element-size": "0.31.1", + "copy-to-clipboard": "3.3.3", + "framesync": "6.1.2" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.10.3.tgz", + "integrity": "sha512-oWmGGzzKWBfoB3hrrQxWwFirlxJXGdk3v4SLnLPPYRy9IMibmQM5rAUJ/NxZum1mrYGP5lo7DHcIWDfV2A3ubw==", + "dev": true, + "dependencies": { + "@chakra-ui/hooks": "2.4.2", + "@chakra-ui/styled-system": "2.12.0", + "@chakra-ui/theme": "3.4.6", + "@chakra-ui/utils": "2.2.2", + "@popperjs/core": "^2.11.8", + "@zag-js/focus-visible": "^0.31.1", + "aria-hidden": "^1.2.3", + "react-fast-compare": "3.2.2", + "react-focus-lock": "^2.9.6", + "react-remove-scroll": "^2.5.7" + }, + "peerDependencies": { + "@emotion/react": ">=11", + "@emotion/styled": ">=11", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/styled-system": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.12.0.tgz", + "integrity": "sha512-zoqLw1I2y4GlZ0LDoyw8o0JjoDOW6u0IwFPAoHuw0UMbP8glHUGvwEL1STug/i/GzBKw83yoF6ae41HIQvhMww==", + "dev": true, + "dependencies": { + "@chakra-ui/utils": "2.2.2", + "csstype": "^3.1.2" + } + }, + "node_modules/@chakra-ui/theme": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.4.6.tgz", + "integrity": "sha512-ZwFBLfiMC3URwaO31ONXoKH9k0TX0OW3UjdPF3EQkQpYyrk/fm36GkkzajjtdpWEd7rzDLRsQjPmvwNaSoNDtg==", + "dev": true, + "dependencies": { + "@chakra-ui/anatomy": "2.3.4", + "@chakra-ui/theme-tools": "2.2.6", + "@chakra-ui/utils": "2.2.2" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.8.0" + } + }, + "node_modules/@chakra-ui/theme-tools": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.2.6.tgz", + "integrity": "sha512-3UhKPyzKbV3l/bg1iQN9PBvffYp+EBOoYMUaeTUdieQRPFzo2jbYR0lNCxqv8h5aGM/k54nCHU2M/GStyi9F2A==", + "dev": true, + "dependencies": { + "@chakra-ui/anatomy": "2.3.4", + "@chakra-ui/utils": "2.2.2", + "color2k": "^2.0.2" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.0.0" + } + }, + "node_modules/@chakra-ui/utils": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.2.2.tgz", + "integrity": "sha512-jUPLT0JzRMWxpdzH6c+t0YMJYrvc5CLericgITV3zDSXblkfx3DsYXqU11DJTSGZI9dUKzM1Wd0Wswn4eJwvFQ==", + "dev": true, + "dependencies": { + "@types/lodash.mergewith": "4.6.9", + "lodash.mergewith": "4.6.2" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "dev": true, + "peer": true + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "dev": true, + "peer": true + }, + "node_modules/@emotion/react": { + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "dev": true, + "peer": true + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "dev": true, + "peer": true + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "dev": true, + "peer": true, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", + "dev": true, + "peer": true + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "dev": true, + "peer": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@loadable/component": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", + "integrity": "sha512-fJWxx9b5WHX90QKmizo9B+es2so8DnBthI1mbflwCoOyvzEwxiZ/SVDCTtXEnHG72/kGBdzr297SSIekYtzSOQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.18", + "hoist-non-react-statics": "^3.3.1", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", + "dev": true + }, + "node_modules/@types/lodash.mergewith": { + "version": "4.6.9", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.9.tgz", + "integrity": "sha512-fgkoCAOF47K7sxrQ7Mlud2TH023itugZs2bUg8h/KzT+BnZNrR2jAOmaokbLunHNnobXVWOezAeNn/lZqwxkcw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "peer": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.2.79", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", + "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.25", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", + "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@zag-js/dom-query": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.31.1.tgz", + "integrity": "sha512-oiuohEXAXhBxpzzNm9k2VHGEOLC1SXlXSbRPcfBZ9so5NRQUA++zCE7cyQJqGLTZR0t3itFLlZqDbYEXRrefwg==", + "dev": true + }, + "node_modules/@zag-js/element-size": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.31.1.tgz", + "integrity": "sha512-4T3yvn5NqqAjhlP326Fv+w9RqMIBbNN9H72g5q2ohwzhSgSfZzrKtjL4rs9axY/cw9UfMfXjRjEE98e5CMq7WQ==", + "dev": true + }, + "node_modules/@zag-js/focus-visible": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.31.1.tgz", + "integrity": "sha512-dbLksz7FEwyFoANbpIlNnd3bVm0clQSUsnP8yUVQucStZPsuWjCrhL2jlAbGNrTrahX96ntUMXHb/sM68TibFg==", + "dev": true, + "dependencies": { + "@zag-js/dom-query": "0.31.1" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dev": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/color2k": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", + "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "peer": true + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dev": true, + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "peer": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true, + "peer": true + }, + "node_modules/focus-lock": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.5.tgz", + "integrity": "sha512-QFaHbhv9WPUeLYBDe/PAuLKJ4Dd9OPvKs9xZBr3yLXnUrDNaVXKu2baDBXe3naPY30hgHYSsf2JW4jzas2mDEQ==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/framer-motion": { + "version": "11.11.9", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.9.tgz", + "integrity": "sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==", + "dev": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/framesync": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", + "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", + "dev": true, + "dependencies": { + "tslib": "2.4.0" + } + }, + "node_modules/framesync/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dev": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "peer": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "peer": true + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "peer": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "peer": true + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "peer": true + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "peer": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "peer": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "peer": true + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-clientside-effect": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.13" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "dev": true + }, + "node_modules/react-focus-lock": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.2.tgz", + "integrity": "sha512-T/7bsofxYqnod2xadvuwjGKHOoL5GH7/EIPI5UyEvaU/c2CcphvGI371opFtuY/SYdbMsNiuF4HsHQ50nA/TKQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^1.3.5", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.2", + "use-sidecar": "^1.1.2" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/react-remove-scroll": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", + "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", + "dev": true, + "dependencies": { + "react-remove-scroll-bar": "^2.3.6", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "dev": true, + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dev": true, + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "peer": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "dev": true, + "peer": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "dev": true + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "dev": true + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "dev": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dev": true, + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 6" + } + } + } +} diff --git a/packages/extension-store-locator/package.json b/packages/extension-store-locator/package.json new file mode 100644 index 0000000000..88c9d57c6f --- /dev/null +++ b/packages/extension-store-locator/package.json @@ -0,0 +1,26 @@ +{ + "name": "@salesforce/extension-store-locator", + "version": "1.0.0-dev", + "scripts": {}, + "peerDependencies": { + "@chakra-ui/react": "^2.10.3", + "@loadable/component": "^5.15.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@chakra-ui/react": "^2.10.3", + "@loadable/component": "^5.15.3", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", + "@types/react": "~18.2.0", + "@types/react-dom": "~18.2.1", + "express": "^4.19.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + } +} diff --git a/packages/extension-store-locator/src/pages/store-locator/index.tsx b/packages/extension-store-locator/src/pages/store-locator/index.tsx new file mode 100644 index 0000000000..348a159deb --- /dev/null +++ b/packages/extension-store-locator/src/pages/store-locator/index.tsx @@ -0,0 +1,59 @@ +// /* +// * Copyright (c) 2021, salesforce.com, 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 +// */ + +// import React from "react"; + +// // Components +// import { Box, Container } from "@chakra-ui/react"; +// import StoreLocatorContent from "@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-content"; + +// // Others +// import { +// StoreLocatorContext, +// useStoreLocator, +// } from "@salesforce/retail-react-app/app/components/store-locator-modal/index"; + +// const StoreLocator = () => { +// const storeLocator = useStoreLocator(); + +// return ( +// +// +// +// +// +// +// +// +// ); +// }; + +// StoreLocator.getTemplateName = () => "store-locator"; + +// StoreLocator.propTypes = {}; + +// export default StoreLocator; + +import React from "react"; +const StoreLocator = () => { + return

123

; +}; + +StoreLocator.getTemplateName = () => "store-locator"; + +StoreLocator.propTypes = {}; + +export default StoreLocator; diff --git a/packages/extension-store-locator/src/setup-app.ts b/packages/extension-store-locator/src/setup-app.ts new file mode 100644 index 0000000000..4f7d4fb651 --- /dev/null +++ b/packages/extension-store-locator/src/setup-app.ts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import React from "react"; +import loadable from "@loadable/component"; +import { + ApplicationExtension, + IRouteConfig, +} from "@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility"; + +import { ReactExtensionConfig as Config } from "./types"; + +const StoreLocator = loadable(() => import("./pages/store-locator")); + +class Sample extends ApplicationExtension { + extendApp(App: React.ComponentType): React.ComponentType { + return App; + } + + extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { + routes.push({ + path: "/store-locator", + component: StoreLocator, + }); + return routes; + } +} + +export default Sample; diff --git a/packages/extension-store-locator/src/setup-server.ts b/packages/extension-store-locator/src/setup-server.ts new file mode 100644 index 0000000000..0f5ef21b05 --- /dev/null +++ b/packages/extension-store-locator/src/setup-server.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import { + Application as ExpressApplication, + ApplicationExtension as ExpressApplicationExtension +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' +import {ServerExtensionConfig as Config} from './types' + +class SampleExtension extends ExpressApplicationExtension { + + extendApp(app: ExpressApplication): ExpressApplication { + + return app + } +} + +export default SampleExtension diff --git a/packages/extension-store-locator/src/types /config.ts b/packages/extension-store-locator/src/types /config.ts new file mode 100644 index 0000000000..fa9d245435 --- /dev/null +++ b/packages/extension-store-locator/src/types /config.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import { + ApplicationExtensionConfig as _ServerExtensionConfig +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' + +import { + ApplicationExtensionConfig as _ReactExtensionConfig +} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' + +// This is where you are going to define the configuration type for your App Extension. This is used in the constructor +// of the extension itself. Update this config type to your specific needs! + +// TODO: Rather than 2 duplicate types, how can we have a single config type here? +export interface ServerExtensionConfig extends _ServerExtensionConfig { + // react-router-style path to the new sample page + path?: string +} +export interface ReactExtensionConfig extends _ReactExtensionConfig { + // react-router-style path to the new sample page + path?: string +} diff --git a/packages/extension-store-locator/src/types /index.ts b/packages/extension-store-locator/src/types /index.ts new file mode 100644 index 0000000000..4b7923357f --- /dev/null +++ b/packages/extension-store-locator/src/types /index.ts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export * from './config' \ No newline at end of file diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 84a4994c44..211be40c2f 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -21,6 +21,7 @@ "@salesforce/extension-sample": "1.0.0-dev", "@salesforce/extension-sample-with-overrides": "1.0.0-dev", + "@salesforce/extension-store-locator": "1.0.0-dev", "@salesforce/pwa-kit-dev": "4.0.0-dev", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", @@ -47,7 +48,7 @@ }, "mobify": { "app":{ - "extensions": ["@salesforce/extension-sample", ["@salesforce/extension-sample-with-overrides", {"enabled": false}]] + "extensions": ["@salesforce/extension-sample", ["@salesforce/extension-sample-with-overrides", {"enabled": false}], "@salesforce/extension-store-locator"] }, "ssrEnabled": true, "ssrOnly": [ From 499c5dd06bd86dd9a8928e389f4afd3add53c9ca Mon Sep 17 00:00:00 2001 From: Adam Raya Date: Wed, 16 Oct 2024 16:55:54 -0700 Subject: [PATCH 152/929] =?UTF-8?q?[App=20Extensibility=20=E2=9A=99?= =?UTF-8?q?=EF=B8=8F]=20Update=20`Create=20App`=20to=20generate=20App=20Ex?= =?UTF-8?q?tension=20stubs=20(@W-16848439@)=20(#2060)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add initial project question * Add template-base-app-extension * Support namespace directory * clean up * Create .npmignore file * Support namespace on PWA Kit project with App Extensions * Update dev dir constant naming * Update naming * PR Feedback * Add projectName to Installing dependencies message * PR Feedback adjust wording for INITIAL_QUESTION * Slugify appExtension name * PR Feedback * Update build script with extension-base * Update build script with extension-base * Clean up * Revert "PR Feedback" This reverts commit bea1b3d1a3c83984b5ec28e90dbe3ecc5c3ba56b. * PR Feedback --- packages/extension-base/README.md | 78 ++ packages/extension-base/package-lock.json | 986 ++++++++++++++++++ packages/extension-base/package.json | 25 + .../src/components/with-red-border.tsx | 26 + packages/extension-base/src/pages/sample.tsx | 38 + packages/extension-base/src/setup-app.ts | 36 + packages/extension-base/src/setup-server.ts | 34 + packages/extension-base/src/types/config.ts | 26 + packages/extension-base/src/types/index.ts | 8 + packages/extension-base/static/README.md | 0 .../extension-base/static/salesforce-logo.svg | 31 + packages/pwa-kit-create-app/scripts/build.js | 18 +- .../scripts/create-mobify-app.js | 223 +++- .../template-typescript-minimal/package.json | 8 - 14 files changed, 1484 insertions(+), 53 deletions(-) create mode 100644 packages/extension-base/README.md create mode 100644 packages/extension-base/package-lock.json create mode 100644 packages/extension-base/package.json create mode 100644 packages/extension-base/src/components/with-red-border.tsx create mode 100644 packages/extension-base/src/pages/sample.tsx create mode 100644 packages/extension-base/src/setup-app.ts create mode 100644 packages/extension-base/src/setup-server.ts create mode 100644 packages/extension-base/src/types/config.ts create mode 100644 packages/extension-base/src/types/index.ts create mode 100644 packages/extension-base/static/README.md create mode 100644 packages/extension-base/static/salesforce-logo.svg diff --git a/packages/extension-base/README.md b/packages/extension-base/README.md new file mode 100644 index 0000000000..88e9b42088 --- /dev/null +++ b/packages/extension-base/README.md @@ -0,0 +1,78 @@ + __ _ __ _ _ +/ _\ __ _ _ __ ___ _ __ | | ___ /__\_ _| |_ ___ _ __ ___(_) ___ _ __ +\ \ / _` | '_ ` _ \| '_ \| |/ _ \ /_\ \ \/ / __/ _ \ '_ \/ __| |/ _ \| '_ \ +_\ \ (_| | | | | | | |_) | | __/ //__ > <| || __/ | | \__ \ | (_) | | | | +\__/\__,_|_| |_| |_| .__/|_|\___| \__/ /_/\_\\__\___|_| |_|___/_|\___/|_| |_| + |_| + +# Description + +This is a sample PWA-Kit Application Extension. The purpose of this application extensions is to show how +the Application Extensions API can be used to enhance your PWA-Kit base project. + +# Folder Structure + +This directory contains the PWA Kit Application Extension base files and structure. It includes the following files: +``` +├── src +│ ├── setup-server.ts +│ └── setup-client.ts +└── dev +``` + +1. `src/setup-server.ts`: The server-side setup function for the extension. +2. `src/setup-client.ts`: The client-side setup function for the extension. +3. `dev/`: PWA Kit App TypeScript template project used for developing the generated PWA Kit App Extension. + +# Peer Dependancies + +PWA-Kit Application Extensions are NPM packages at their most simplest form, and as such you can define +what peer dependencies are required when using it. Because this sample application extension provides +UI via a new "Sample" page, it requires that the below dependencies are installed at a minimum. + +Depending on what features your application extensions provides it's recommended you include any third-party +packages as peer dependencies so that your base application doesn't end up having multiple versions of a +given package. + +"react": "^18.2.0", +"react-dom": "^18.2.0" + +# Configuration + +This section is optional and will depend on your application extensions implementation. If you have features +that are configurable, then list those configurations here so that the PWA-Kit project implementor can configure +the extension as they like. + +``` +{ + path: 'sample-page' +} +``` + +# Installation + +``` +> npm install @salesforce/extension-sample --legacy-peer-deps*
+> Downloading npm package...
+> Installing extention...
+> Finished.
+> Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. +``` + +# Advanced Usage + +In order to customize this Application Extension to your particulare needs we suggest that you refer to the section titled +"configuration", but if there is something that you want to customize that isn't configurable and cannot wait for a feature +request to be fulfilled, then you can use overrides. + +Below is a list of files that can't be overridden from within your PWA-Kit base project. Please refer to the documentation here on +how to properly override extensions. Additionally it's up to the Application Extension developer as to which files can and +cannot be overridden. Please refer to this documentation on how to write your first PWA-Kit Application Extension. + +## Overridable Files + +``` +/src/path/to/overridable/file.ts +``` + + diff --git a/packages/extension-base/package-lock.json b/packages/extension-base/package-lock.json new file mode 100644 index 0000000000..c0679e3dc1 --- /dev/null +++ b/packages/extension-base/package-lock.json @@ -0,0 +1,986 @@ +{ + "name": "@salesforce/extension-base", + "version": "1.0.0-dev", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@salesforce/extension-base", + "version": "1.0.0-dev", + "devDependencies": { + "@loadable/component": "^5.15.3", + "@types/react": "~18.2.0", + "@types/react-dom": "~18.2.1", + "express": "^4.19.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + }, + "peerDependencies": { + "@loadable/component": "^5.15.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@loadable/component": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", + "integrity": "sha512-fJWxx9b5WHX90QKmizo9B+es2so8DnBthI1mbflwCoOyvzEwxiZ/SVDCTtXEnHG72/kGBdzr297SSIekYtzSOQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.18", + "hoist-non-react-statics": "^3.3.1", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.2.79", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", + "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.25", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", + "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.20.0.tgz", + "integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dev": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.0.tgz", + "integrity": "sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-static/node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/packages/extension-base/package.json b/packages/extension-base/package.json new file mode 100644 index 0000000000..66f5d311ad --- /dev/null +++ b/packages/extension-base/package.json @@ -0,0 +1,25 @@ +{ + "name": "@salesforce/extension-base", + "version": "1.0.0-dev", + "private": true, + "scripts": {}, + "peerDependencies": { + "@loadable/component": "^5.15.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@loadable/component": "^5.15.3", + "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", + "@salesforce/pwa-kit-runtime": "4.0.0-dev", + "@types/react": "~18.2.0", + "@types/react-dom": "~18.2.1", + "express": "^4.19.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + } +} diff --git a/packages/extension-base/src/components/with-red-border.tsx b/packages/extension-base/src/components/with-red-border.tsx new file mode 100644 index 0000000000..7f53983c35 --- /dev/null +++ b/packages/extension-base/src/components/with-red-border.tsx @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import React from 'react' + +// Define a type for the HOC props +type WithRedBorderProps = React.ComponentPropsWithoutRef; + +// Define the HOC function +const withRedBorder =

(WrappedComponent: React.ComponentType

) => { + const WithRedBorder: React.FC

= (props: WithRedBorderProps) => { + return ( +

+ +
+ ) + } + + return WithRedBorder +} + +export default withRedBorder \ No newline at end of file diff --git a/packages/extension-base/src/pages/sample.tsx b/packages/extension-base/src/pages/sample.tsx new file mode 100644 index 0000000000..b19378f9e6 --- /dev/null +++ b/packages/extension-base/src/pages/sample.tsx @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import React, {Fragment} from 'react' +import {getStaticAssetUrl} from '@salesforce/pwa-kit-react-sdk/ssr/universal/utils' + +const Sample = () => { + const logoUrl = getStaticAssetUrl('salesforce-logo.svg', {extensionPackageName: '@salesforce/extension-sample'}) + return ( + +

Welcome to the Sample Page 👋

+
+ + +

If you are reading this, it means that this page was successfully added to your base project. 🎉

+

+ This Application Extension was installed by running the below command in your PWA-Kit project. + Its dependancies were automatically installed and the extension configured into your projects extensions array. +

+
+ + > npm install @salesforce/extension-sample --legacy-peer-deps*
+ > Downloading npm package...
+ > Installing extention...
+ > Finished.
+ > Congratulations! The Sample extension was successfully installed! Please visit https://www.npmjs.com/package/@salesforce/extension-sample for more information on how to use this extension. +
+
+
+ ) +} + +Sample.getTemplateName = () => 'sample' + +export default Sample \ No newline at end of file diff --git a/packages/extension-base/src/setup-app.ts b/packages/extension-base/src/setup-app.ts new file mode 100644 index 0000000000..1cba0a4a7d --- /dev/null +++ b/packages/extension-base/src/setup-app.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import React from 'react' +import loadable from '@loadable/component' +import {ApplicationExtension, IRouteConfig} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' + +import withRedBorder from '*/components/with-red-border' +import {ReactExtensionConfig as Config} from './types' + +const SamplePage = loadable(() => import('*/pages/sample')) + +const defaultPath: string = '/sample-page' +class Sample extends ApplicationExtension { + extendApp(App: React.ComponentType): React.ComponentType { + return withRedBorder(App) + } + + extendRoutes(routes: IRouteConfig[]): IRouteConfig[] { + console.log('Extend Routes for ', this.getName()) + return [ + { + exact: true, + path: this.getConfig().path || defaultPath, + component: SamplePage + }, + ...routes + ] + } +} + +export default Sample diff --git a/packages/extension-base/src/setup-server.ts b/packages/extension-base/src/setup-server.ts new file mode 100644 index 0000000000..c7fac79550 --- /dev/null +++ b/packages/extension-base/src/setup-server.ts @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +import { + Application as ExpressApplication, + ApplicationExtension as ExpressApplicationExtension +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' +import {ServerExtensionConfig as Config} from './types' + +class SampleExtension extends ExpressApplicationExtension { + + extendApp(app: ExpressApplication): ExpressApplication { + + // This endpoint serves as an example of how to extend the existing PWA Kit App Express server application + // It demonstrates the process of adding a new route and handling function for a GET request + // Upon receiving a request to the '/sample' path, the endpoint sends a response showcasing the server's functionality + // It also includes the current extension configuration as part of the response + app.get('/sample', (req, res) => { + console.log('SampleExtension extendApp GET /sample') + res.send( + `

Hello from an Express SampleExtension!

+
extensionConfig = ${JSON.stringify(this.getConfig())}
` + ) + }) + + return app + } +} + +export default SampleExtension diff --git a/packages/extension-base/src/types/config.ts b/packages/extension-base/src/types/config.ts new file mode 100644 index 0000000000..fa9d245435 --- /dev/null +++ b/packages/extension-base/src/types/config.ts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ +import { + ApplicationExtensionConfig as _ServerExtensionConfig +} from '@salesforce/pwa-kit-runtime/ssr/server/extensibility' + +import { + ApplicationExtensionConfig as _ReactExtensionConfig +} from '@salesforce/pwa-kit-react-sdk/ssr/universal/extensibility' + +// This is where you are going to define the configuration type for your App Extension. This is used in the constructor +// of the extension itself. Update this config type to your specific needs! + +// TODO: Rather than 2 duplicate types, how can we have a single config type here? +export interface ServerExtensionConfig extends _ServerExtensionConfig { + // react-router-style path to the new sample page + path?: string +} +export interface ReactExtensionConfig extends _ReactExtensionConfig { + // react-router-style path to the new sample page + path?: string +} diff --git a/packages/extension-base/src/types/index.ts b/packages/extension-base/src/types/index.ts new file mode 100644 index 0000000000..4b7923357f --- /dev/null +++ b/packages/extension-base/src/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024, salesforce.com, 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 + */ + +export * from './config' \ No newline at end of file diff --git a/packages/extension-base/static/README.md b/packages/extension-base/static/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/extension-base/static/salesforce-logo.svg b/packages/extension-base/static/salesforce-logo.svg new file mode 100644 index 0000000000..b2f3856b54 --- /dev/null +++ b/packages/extension-base/static/salesforce-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/pwa-kit-create-app/scripts/build.js b/packages/pwa-kit-create-app/scripts/build.js index 957775a46d..45168e8be9 100644 --- a/packages/pwa-kit-create-app/scripts/build.js +++ b/packages/pwa-kit-create-app/scripts/build.js @@ -15,6 +15,7 @@ sh.set('-e') sh.config.silent = false const TEMPLATE_PREFIX = 'template-' +const EXTENSION_BASE_NAME = 'extension-base' const monorepoRoot = p.resolve(__dirname, '..', '..', '..') const templatesDir = p.resolve(__dirname, '..', 'templates') @@ -24,18 +25,20 @@ const mkdtempSync = () => fs.mkdtempSync(p.resolve(os.tmpdir(), 'pwa-template-tm const tarPathForPkg = (pkg) => p.resolve(templatesDir, `${pkg}.tar.gz`) const main = () => { - const pkgNames = [ + const templatePkgNames = [ 'retail-react-app', 'express-minimal', 'typescript-minimal', 'mrt-reference-app' ] + const extensionPkgName = [EXTENSION_BASE_NAME] + if (!sh.test('-d', templatesDir)) { sh.mkdir('-p', templatesDir) } - sh.rm('-rf', pkgNames.map(tarPathForPkg)) + sh.rm('-rf', templatePkgNames.map(tarPathForPkg)) const tmpDir = mkdtempSync() const checkoutDir = p.join(tmpDir, 'mobify-platform-sdks') @@ -47,13 +50,14 @@ const main = () => { ) return Promise.all( - pkgNames.map((pkgName) => { + [...templatePkgNames, ...extensionPkgName].map((pkgName) => { + const finalPkgName = extensionPkgName.includes(pkgName) + ? pkgName + : `${TEMPLATE_PREFIX}${pkgName}` + // Emulate an NPM package by having the tar contain a "package" folder. const tmpPackageDir = mkdtempSync() - sh.mv( - p.join(packageDir, `${TEMPLATE_PREFIX}${pkgName}`), - p.join(tmpPackageDir, 'package') - ) + sh.mv(p.join(packageDir, finalPkgName), p.join(tmpPackageDir, 'package')) return tar .c( diff --git a/packages/pwa-kit-create-app/scripts/create-mobify-app.js b/packages/pwa-kit-create-app/scripts/create-mobify-app.js index 50cf4c9e61..a074a7a1be 100755 --- a/packages/pwa-kit-create-app/scripts/create-mobify-app.js +++ b/packages/pwa-kit-create-app/scripts/create-mobify-app.js @@ -72,6 +72,14 @@ const validProjectName = (s) => { return regex.test(s) || 'Value can only contain letters, numbers, space and hyphens.' } +const validAppExtensionNameRegex = /^(@[a-zA-Z0-9-_]+\/)?extension-[a-zA-Z0-9-_]+$/ +const validProjectAppExtensionName = (input) => { + if (!validAppExtensionNameRegex.test(input)) { + return 'The Application Extension name must follow the format @{namespace}/extension-{package-name} (namespace is optional).' + } + return true +} + const validUrl = (s) => { try { new URL(s) @@ -111,7 +119,25 @@ const TEMPLATE_SOURCE_NPM = 'npm' const TEMPLATE_SOURCE_BUNDLE = 'bundle' const DEFAULT_TEMPLATE_VERSION = 'latest' -const askApplicationExtensibiltyQuestions = (appExtensions) => { +const LOCAL_DEV_PROJECT_DIR = 'dev' + +const INITIAL_QUESTION = [ + { + name: 'project.type', + message: 'What type of PWA Kit project would you like to create?', + type: 'list', + choices: [ + {name: 'PWA Kit Application', value: 'PWAKitAppProject'}, + { + name: 'PWA Kit Application Extension', + value: 'PWAKitAppExtensionProject' + } + ], + default: 'PWAKitAppProject' + } +] + +const askApplicationExtensibilityQuestions = (availableAppExtensions) => { return [ { name: 'project.useAppExtensibility', @@ -123,7 +149,7 @@ const askApplicationExtensibiltyQuestions = (appExtensions) => { name: 'project.selectedAppExtensions', message: 'Which Application Extensions do you want to install?', type: 'checkbox', - choices: appExtensions, + choices: availableAppExtensions, when: (answers) => answers.project.useAppExtensibility === true }, { @@ -133,7 +159,7 @@ const askApplicationExtensibiltyQuestions = (appExtensions) => { 'you will NO LONGER be able to consume upgrades from NPM. All changes\n' + 'made to the extracted code will be YOUR RESPONSIBILITY.\n' + '\n' + - 'Do you want to proceed with extracting the Application Extension code?', + 'Do you want to proceed with extracting the Application Extensions code?', type: 'confirm', default: false, when: (answers) => answers.project.useAppExtensibility === true @@ -141,6 +167,16 @@ const askApplicationExtensibiltyQuestions = (appExtensions) => { ] } +const APPLICATION_EXTENSION_QUESTIONS = [ + { + name: 'project.extensionName', + message: + 'What is the name of your Application Extension? \n' + + 'The name must follow the pattern "@{namespace}/extension-{package-name}", where namespace is optional.', + validate: validProjectAppExtensionName + } +] + const EXTENSIBILITY_QUESTIONS = [ { name: 'project.extend', @@ -470,6 +506,16 @@ const PRESETS = [ }, private: true }, + { + id: 'base-app-extension', + name: 'Template base Application Extension', + description: '', + templateSource: { + type: TEMPLATE_SOURCE_BUNDLE, + id: 'base-app-extension' + }, + private: true + }, { id: 'app-extension-sample-extract', name: 'Application Extension sample project (Extract Application Extensions code)', @@ -536,12 +582,33 @@ const readJson = (path) => JSON.parse(sh.cat(path)) const writeJson = (path, data) => new sh.ShellString(JSON.stringify(data, null, 2)).to(path) +/** + * Updates the `package.json` file in place by merging new updates with the existing content. + * + * @param {string} pkgJsonPath - The file path to the `package.json` file that needs to be updated. + * @param {Object} updates - An object containing the updates to be merged into the existing `package.json`. + */ +const updatePackageJson = (pkgJsonPath, updates) => { + const pkgJSON = readJson(pkgJsonPath) + const finalPkgData = merge(pkgJSON, updates) + writeJson(pkgJsonPath, finalPkgData) +} + const slugifyName = (name) => slugify(name, { lower: true, strict: true }).slice(0, PROJECT_ID_MAX_LENGTH) +const getSlugifiedProjectName = (projectName) => { + // Split the project name into namespace and name if it's in the format @namespace/name + const [slugifiedNamespace, slugifiedName] = projectName.includes('/') + ? projectName.split('/').map(slugifyName) + : ['', slugifyName(projectName)] + + return slugifiedNamespace ? `@${slugifiedNamespace}/${slugifiedName}` : slugifiedName +} + /** * Check if the provided path is an empty directory. * @param {*} path @@ -632,6 +699,19 @@ const expandKey = (key, value) => undefined ) +/** + * Creates an .npmignore file at the root of the generated project. + * Ensures the specified directories and files are excluded from being published to npm. + * + * @param {string} outputDir - The path to the root of the generated project. + * @param {string[]} ignorePaths - An array of directory or file paths to ignore in the npm package. + */ +const createNpmIgnoreFile = (outputDir, ignorePaths = []) => { + const npmIgnoreContent = ignorePaths.join('\n') + '\n' + + fs.writeFileSync(p.join(outputDir, '.npmignore'), npmIgnoreContent) +} + /** * Provided an object there the keys use "dot notation", expand each individual key. * NOTE: This only expands keys at the root level, and not those nested. @@ -653,8 +733,11 @@ const expandObject = (obj = {}) => * @param {*} outputDir * @param {*} param1 */ -const npmInstall = (outputDir, {verbose}) => { - console.log('Installing dependencies... This may take a few minutes.\n') +const npmInstall = (outputDir, {verbose, projectName}) => { + console.log(`Installing dependencies${ + projectName ? ` for ${projectName}` : '' + }... This may take a few minutes. +`) const npmLogLevel = verbose ? 'notice' : 'error' const disableStdOut = ['inherit', 'ignore', 'inherit'] const stdio = verbose ? 'inherit' : disableStdOut @@ -717,9 +800,10 @@ const processAppExtensions = ( ) => { if (appExtensions.length > 0 && extractAppExtensions) { appExtensions.forEach((appExtensionName) => { - const appExtensionTmp = fs.mkdtempSync( - p.resolve(os.tmpdir(), `extract-${appExtensionName.replace('@salesforce/', '')}`) - ) + // Create the full path for the temporary directory, preserving the namespace + const appExtensionTmp = p.join(os.tmpdir(), `extract-${appExtensionName}`) + fs.mkdirSync(appExtensionTmp, {recursive: true}) + const appExtensionTarFile = sh .exec(`npm pack ${appExtensionName} --pack-destination="${appExtensionTmp}"`, { silent: true @@ -784,9 +868,13 @@ const fetchAvailableAppExtensions = () => { * @param {*} answers * @param {*} param2 */ -const runGenerator = (context, {outputDir, templateVersion, verbose}) => { +const runGenerator = async ( + context, + {outputDir, templateVersion, verbose, installDependencies = true} +) => { const {answers, preset} = context const {templateSource} = preset + const { extend = false, selectedAppExtensions = [], @@ -796,6 +884,9 @@ const runGenerator = (context, {outputDir, templateVersion, verbose}) => { // Check if the output directory doesn't already exist. checkOutputDir(outputDir) + // Ensure the output directory exists + fs.mkdirSync(outputDir, {recursive: true}) + // We need to get some assets from the base template. So extract it after // downloading from NPM or copying from the template bundle folder. const tmp = fs.mkdtempSync(p.resolve(os.tmpdir(), 'extract-template')) @@ -846,7 +937,7 @@ const runGenerator = (context, {outputDir, templateVersion, verbose}) => { }) } else { // Copy the base template either from the package or npm. - sh.cp('-rf', packagePath, outputDir) + sh.cp('-rf', p.join(packagePath, '*'), outputDir) // Copy template specific assets over. const assetsDir = p.join(ASSETS_TEMPLATES_DIR, id) @@ -861,20 +952,60 @@ const runGenerator = (context, {outputDir, templateVersion, verbose}) => { }) } - // Process selected Application Extensions - processAppExtensions(selectedAppExtensions, extractAppExtensions, appExtensionsDir) + // Check project type and handle appropriately + if (answers.project.type === 'PWAKitAppExtensionProject') { + const devOutputDir = p.join(outputDir, LOCAL_DEV_PROJECT_DIR) + + // Update the root package.json to add a start script + updatePackageJson(p.resolve(outputDir, 'package.json'), { + scripts: { + start: `npm --prefix ./${LOCAL_DEV_PROJECT_DIR} start`, + 'start:inspect': `npm --prefix ./${LOCAL_DEV_PROJECT_DIR} run start:inspect` + } + }) + + // Recursively call runGenerator for the 'typescript-minimal' local dev project + const localDevProjectContext = { + ...context, + preset: { + id: 'typescript-minimal', + templateSource: {type: TEMPLATE_SOURCE_BUNDLE, id: 'typescript-minimal'}, + private: true + }, + answers: {project: {type: 'PWAKitAppProject', name: 'local-dev-project'}} + } - // Update the generated project's package.json. NOTE: For bootstrapped projects this - // can be done in the template building. But since we have two types of project builds, - // (bootstrap/bundle) we'll do it here where it works in both scenarios. - const pkgJsonPath = p.resolve(outputDir, 'package.json') - const pkgJSON = readJson(pkgJsonPath) + await runGenerator(localDevProjectContext, { + outputDir: devOutputDir, + templateVersion, + verbose, + installDependencies: false + }) + + // Update the typescript-minimal dev package.json with dependencies + updatePackageJson(p.resolve(devOutputDir, 'package.json'), { + devDependencies: {[answers.project.name]: 'file:../'}, + mobify: {app: {extensions: [answers.project.name]}} + }) + + // Create the .npmignore file, excluding the typescript-minimal local dev project folder + createNpmIgnoreFile(outputDir, [`${LOCAL_DEV_PROJECT_DIR}/`]) + + npmInstall(devOutputDir, { + verbose, + projectName: localDevProjectContext.answers.project.name + }) + } else { + processAppExtensions(selectedAppExtensions, extractAppExtensions, appExtensionsDir) + } // Add selected Application Extensions to devDependencies and mobify object const appExtensionDeps = selectedAppExtensions.reduce((acc, appExtensionName) => { // Find the corresponding Application Extension details - const appExtension = context.appExtensions.find((ext) => ext.value === appExtensionName) - const version = appExtension ? appExtension.version : '1.0.0-dev' + const appExtensionDetails = context.availableAppExtensions.find( + (ext) => ext.value === appExtensionName + ) + const version = appExtensionDetails ? appExtensionDetails.version : '1.0.0-dev' acc[appExtensionName] = extractAppExtensions ? `file:./app/application-extensions/${appExtensionName}` @@ -882,26 +1013,29 @@ const runGenerator = (context, {outputDir, templateVersion, verbose}) => { return acc }, {}) - const finalPkgData = merge(pkgJSON, { - name: slugifyName(context.answers.project.name || context.preset.id), + updatePackageJson(p.resolve(outputDir, 'package.json'), { + name: getSlugifiedProjectName(context.answers.project.name || context.preset.id), version: GENERATED_PROJECT_VERSION, devDependencies: appExtensionDeps, - mobify: { - app: { - extensions: selectedAppExtensions.map((appExtensionName) => [appExtensionName]) + ...(selectedAppExtensions.length > 0 && { + mobify: { + app: { + extensions: selectedAppExtensions.map((appExtensionName) => [ + appExtensionName + ]) + } } - } + }) }) - // Write updated package.json back to the output directory - writeJson(pkgJsonPath, finalPkgData) - // Clean up the temporary directory sh.rm('-rf', tmp) } - // Install dependencies for the newly minted project. - npmInstall(outputDir, {verbose}) + if (installDependencies) { + // Install dependencies for the newly minted project. + npmInstall(outputDir, {verbose, projectName: context.answers.project.name}) + } } const foundNode = process.versions.node @@ -942,17 +1076,30 @@ const main = async (opts) => { // If no preset argument is provided, ask Application Extensibility questions if (!presetId) { - const appExtensions = fetchAvailableAppExtensions() + // Ask initial question + const initialAnswers = await inquirer.prompt(INITIAL_QUESTION) + context = {...context, answers: {project: initialAnswers.project}} + + if (initialAnswers.project.type === 'PWAKitAppExtensionProject') { + // Ask for extension name if Application Extension is selected + const extensionNameAnswers = await inquirer.prompt(APPLICATION_EXTENSION_QUESTIONS) + context.answers.project.name = extensionNameAnswers.project.extensionName + context.preset = PRESETS.find(({id}) => id === 'base-app-extension') + } else { + const availableAppExtensions = fetchAvailableAppExtensions() - // Include version info in context - context.appExtensions = appExtensions + // Include version info in context + context.availableAppExtensions = availableAppExtensions - const generationAnswers = await prompt(askApplicationExtensibiltyQuestions(appExtensions)) - context = merge(context, {answers: expandObject(generationAnswers)}) + const generationAnswers = await prompt( + askApplicationExtensibilityQuestions(availableAppExtensions) + ) + context = merge(context, {answers: expandObject(generationAnswers)}) - if (context.answers.project.useAppExtensibility) { - // Add the 'typescript-minimal' preset for Application Extension - context.preset = PRESETS.find(({id}) => id === 'typescript-minimal') + if (context.answers.project.useAppExtensibility) { + // Add the 'typescript-minimal' preset for Application Extension + context.preset = PRESETS.find(({id}) => id === 'typescript-minimal') + } } } diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 84a4994c44..5da74e33b3 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -18,10 +18,6 @@ }, "devDependencies": { "@loadable/component": "^5.15.3", - - "@salesforce/extension-sample": "1.0.0-dev", - "@salesforce/extension-sample-with-overrides": "1.0.0-dev", - "@salesforce/pwa-kit-dev": "4.0.0-dev", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", "@salesforce/pwa-kit-runtime": "4.0.0-dev", @@ -35,7 +31,6 @@ "react-helmet": "^6.1.0", "react-router-dom": "^5.3.4", "typescript": "4.9.5", - "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", @@ -46,9 +41,6 @@ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" }, "mobify": { - "app":{ - "extensions": ["@salesforce/extension-sample", ["@salesforce/extension-sample-with-overrides", {"enabled": false}]] - }, "ssrEnabled": true, "ssrOnly": [ "ssr.js", From 7c2d59adc0a1ef42b3a75be6adf03c6a2566b43a Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 17 Oct 2024 10:53:41 -0700 Subject: [PATCH 153/929] Daily Checkpoint --- packages/extension-sample/src/setup-server.ts | 2 +- .../src/configs/babel/babel-config.js | 105 +++++++++--------- .../pwa-kit-dev/src/configs/webpack/config.js | 33 +----- .../package-lock.json | 50 ++++++++- .../pwa-kit-extension-support/package.json | 1 + .../src/configs/application-extensions.hbs | 16 +++ .../babel/plugin-application-extensions.ts | 7 +- .../webpack/loaders/extensions-loader.ts | 64 ++++++++++- .../src/configs/webpack/loaders/index.ts | 22 +++- .../src/shared/utils/index.ts | 24 ++++ 10 files changed, 234 insertions(+), 90 deletions(-) create mode 100644 packages/pwa-kit-extension-support/src/configs/application-extensions.hbs diff --git a/packages/extension-sample/src/setup-server.ts b/packages/extension-sample/src/setup-server.ts index 6acf5b0164..df437103e4 100644 --- a/packages/extension-sample/src/setup-server.ts +++ b/packages/extension-sample/src/setup-server.ts @@ -18,7 +18,7 @@ import {Config} from './types' class SampleExtension extends ApplicationExtension { extendApp(app: Application): Application { - console.log('setup-server: SampleExtension: extendApp: ', app) + // console.log('setup-server: SampleExtension: extendApp: ', app) app.get('/sample', (req, res) => { console.log('SampleExtension extendApp GET /sample') res.send( diff --git a/packages/pwa-kit-dev/src/configs/babel/babel-config.js b/packages/pwa-kit-dev/src/configs/babel/babel-config.js index 0a1de924d3..4610b4e85d 100644 --- a/packages/pwa-kit-dev/src/configs/babel/babel-config.js +++ b/packages/pwa-kit-dev/src/configs/babel/babel-config.js @@ -4,60 +4,63 @@ * 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 */ -const config = { - sourceType: 'unambiguous', - presets: [ - [ - require('@babel/preset-env'), - { - targets: { - node: 18 +const DEFAULT_TARGET = 'node' + +// PWA-Kit Imports +import {getApplicationExtensionInfo} from '@salesforce/pwa-kit-extension-support/shared/utils' +import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' + +const config = (api) => { + + return { + sourceType: 'unambiguous', + presets: [ + [ + require('@babel/preset-env'), + { + targets: { + node: 18 + } } - } - ], - require('@babel/preset-typescript'), - require('@babel/preset-react') - ], - plugins: [ - // [ - // require('babel-plugin-module-resolver'), - // { - // root: ["/Users/bchypak/Projects/pwa-kit/packages/template-typescript-minimal/node_modules"], // or whatever your source directory is - // // NOTE: I shouldn't have to use alias's here because the root should be enough to determine there these things exists. But this - // // does show that the plugin is running. So that is good news. - // alias: { - // '@salesforce/extension-sample/setup-server': '/Users/bchypak/Projects/pwa-kit/packages/extension-sample/src/setup-server.ts', - // } - // } - // ], - require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), // NOTE: Would be nice to import with only /babel - require('@babel/plugin-transform-async-to-generator'), - require('@babel/plugin-proposal-object-rest-spread'), - require('@babel/plugin-transform-object-assign'), - [ - require('@babel/plugin-transform-runtime'), - { - regenerator: true - } + ], + require('@babel/preset-typescript'), + require('@babel/preset-react') ], - require('@babel/plugin-syntax-dynamic-import'), - require('@loadable/babel-plugin'), - require('@babel/plugin-proposal-optional-chaining'), - [ - require('babel-plugin-formatjs'), - { - idInterpolationPattern: '[sha512:contenthash:base64:6]', - ast: true + plugins: [ + [ + require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), + { + target: api.caller(caller => caller?.target || DEFAULT_TARGET), + ...getApplicationExtensionInfo(getConfig) + } + ], + require('@babel/plugin-transform-async-to-generator'), + require('@babel/plugin-proposal-object-rest-spread'), + require('@babel/plugin-transform-object-assign'), + [ + require('@babel/plugin-transform-runtime'), + { + regenerator: true + } + ], + require('@babel/plugin-syntax-dynamic-import'), + require('@loadable/babel-plugin'), + require('@babel/plugin-proposal-optional-chaining'), + [ + require('babel-plugin-formatjs'), + { + idInterpolationPattern: '[sha512:contenthash:base64:6]', + ast: true + } + ], + require('@babel/plugin-transform-async-generator-functions') + ].filter(Boolean), + env: { + test: { + presets: [require('@babel/preset-env'), require('@babel/preset-react')], + plugins: [require('babel-plugin-dynamic-import-node-babel-7')] } - ], - require('@babel/plugin-transform-async-generator-functions') - ], - env: { - test: { - presets: [require('@babel/preset-env'), require('@babel/preset-react')], - plugins: [require('babel-plugin-dynamic-import-node-babel-7')] } - } + } } - export default config diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 68934ab50f..cf38a9f51f 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -30,8 +30,10 @@ import {sdkReplacementPlugin} from './plugins' import {CLIENT, SERVER, CLIENT_OPTIONAL, SSR, REQUEST_PROCESSOR} from './config-names' // Utilities +import {getApplicationExtensionInfo} from '@salesforce/pwa-kit-extension-support/shared/utils' +import {ruleForApplicationExtensibility} from '@salesforce/pwa-kit-extension-support/configs/webpack/loaders' import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -import {buildAliases, getExtensionNames, nameRegex} from '@salesforce/pwa-kit-extension-support/shared/utils' +import {buildAliases, nameRegex} from '@salesforce/pwa-kit-extension-support/shared/utils' const projectDir = process.cwd() const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) @@ -254,33 +256,8 @@ const baseConfig = (target) => { loader: findDepInStack('source-map-loader') } }, - { - // NOTE: Might be better to export a rule directly that we can plog in here, this will - // make the "extensions" file private so was can change that implementation detail later - // if we choose to do so. - test: /react\/assets\/application-extensions-placeholder\.js/i, - use: { - loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), - options: { - pkg, - getConfig, - target: 'web' - } - } - } - // , - // { - // // TODO: Export rule from app extensibility sdk instead of using these loaders directly - // test: /express\/assets\/application-extensions-placeholder\.js/i, - // use: { - // loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), - // options: { - // pkg, - // getConfig, - // target: 'node' - // } - // } - // } + ruleForApplicationExtensibility(findDepInStack, {pkg, getConfig, target: 'web'}), + ruleForApplicationExtensibility(findDepInStack, {pkg, getConfig, target: 'node'}) ].filter(Boolean) } } diff --git a/packages/pwa-kit-extension-support/package-lock.json b/packages/pwa-kit-extension-support/package-lock.json index 3434fbaa07..6ff3463aec 100644 --- a/packages/pwa-kit-extension-support/package-lock.json +++ b/packages/pwa-kit-extension-support/package-lock.json @@ -12,6 +12,7 @@ "cross-env": "^5.2.1", "dedent": "^1.5.3", "fs-extra": "^11.2.0", + "handlebars": "^4.7.8", "hoist-non-react-statics": "^3.3.2", "resolve": "^1.22.8" }, @@ -1508,6 +1509,26 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1817,6 +1838,14 @@ "node": ">= 0.6" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1835,8 +1864,7 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/nice-try": { "version": "1.0.5", @@ -2293,7 +2321,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2459,6 +2486,18 @@ "node": ">= 0.6" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -2624,6 +2663,11 @@ "which": "bin/which" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/packages/pwa-kit-extension-support/package.json b/packages/pwa-kit-extension-support/package.json index d8b0b605b5..4097b74bf7 100644 --- a/packages/pwa-kit-extension-support/package.json +++ b/packages/pwa-kit-extension-support/package.json @@ -31,6 +31,7 @@ "dependencies": { "cross-env": "^5.2.1", "dedent": "^1.5.3", + "handlebars": "^4.7.8", "fs-extra": "^11.2.0", "hoist-non-react-statics": "^3.3.2", "resolve": "^1.22.8" diff --git a/packages/pwa-kit-extension-support/src/configs/application-extensions.hbs b/packages/pwa-kit-extension-support/src/configs/application-extensions.hbs new file mode 100644 index 0000000000..5f79fdea93 --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/application-extensions.hbs @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2024, salesforce.com, 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 +*/ + +{{#each installed}} +import {{getInstanceName .}} from {{.}} +{{/each}} + +export default [ + {{#each configured}} + new {{getInstanceName .}}({}){{#if (isNotLast @index @root.configured.length)}},{{/if}} + {{/each}} +] \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts index 9b3b4d03d0..dd7b682ad9 100644 --- a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts +++ b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts @@ -35,7 +35,11 @@ const processedFiles = new Set() module.exports = function replaceFileContentPlugin({ types: t } : any) { return { visitor: { - ImportDeclaration(path: any) { + ImportDeclaration(path: any, state: any) { + console.log('state options: ', state.opts) + + // Hmmmm 🤔 I can't remember why I did this, but if this is a solution to a problem we'll have to make sure we make + // it work for all configured application extensions. const aliases: any = { '@salesforce/extension-sample': '/Users/bchypak/Projects/pwa-kit/packages/template-typescript-minimal/node_modules/@salesforce/extension-sample/src/' } @@ -46,7 +50,6 @@ module.exports = function replaceFileContentPlugin({ types: t } : any) { for (const alias in aliases) { if (source.startsWith(alias)) { const newPath = source.replace(alias, aliases[alias]) - console.log('newPath: ', newPath) path.node.source = t.stringLiteral(newPath) } } diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index 833bc8fe10..2bd775003e 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -8,6 +8,7 @@ import dedent from 'dedent' import {LoaderContext} from 'webpack' import {PackageJson} from 'type-fest' +import Handlebars from 'handlebars' import {kebabToUpperCamelCase} from '../../../shared/utils' import {nameRegex} from '../../../shared/utils/extensibility-utils' @@ -16,8 +17,6 @@ const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' const APP_EXTENSION_SERVER_ENTRY = 'setup-server' const APP_EXTENSION_PREFIX = 'extension-' // aligns with what's in `nameRegex` - - // TODO: Move these to a better location. interface ExtensionsLoaderOptions { pkg: PackageJson, @@ -29,6 +28,51 @@ interface ExtensionsLoaderContext extends LoaderContext // You can add any additional properties if needed } +const templateString = dedent` + /* + * Copyright (c) 2024, salesforce.com, 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 + */ + + {{#each installed}} + import {{getInstanceName .}} from {{.}} + {{/each}} + + export default [ + {{#each configured}} + new {{getInstanceName .}}({}){{#if (isNotLast @index @root.configured.length)}},{{/if}} + {{/each}} + ] +` +const renderTemplate = (templateString: string, data: any) => { + const kebabToUpperCamelCase = (aString: string) => { + return aString.split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join('') + } + + Handlebars.registerHelper('getInstanceName', function (aString) { + const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ + const [packageName, namespace, name] = aString.match(nameRegex) + + return kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`) + }) + + Handlebars.registerHelper('isNotLast', function (index, arrayLength) { + return index !== arrayLength - 1; + }) + + // Compile the template + const template = Handlebars.compile(templateString) + + // Apply data to the compiled template + const output = template(data) + + return output + } + /** * The `extensions-loader` as a mechanism to get all configured extensions for a given pwa-kit * application. We use this loader as a simple way to determine what extension code in required in @@ -48,6 +92,17 @@ module.exports = function (this: ExtensionsLoaderContext, that: any) { const {pkg, getConfig, target = 'web'} = that?.getOptions?.() || this.getOptions() || {} const {devDependencies} = pkg + // ------ + console.log('process.cwd()', process.cwd()) + const renderedHTML = renderTemplate( + templateString, + { + installed: ['@salesforce/extension-sample', '@salesforce/extension-sample-2'], + configured: ['@salesforce/extension-sample'], + } + ) + console.log(renderedHTML) + // ------ // TODO: clean this up.. looks like this is a bad variable name for the type that it represents. const extensions = Object.keys(devDependencies || {}) .map((packageName) => packageName.match(nameRegex)) @@ -67,8 +122,7 @@ module.exports = function (this: ExtensionsLoaderContext, that: any) { const appExtensions = getConfig()?.app?.extensions - // TODO: later consider updating `normalizeExtensionsList` to use a util function - return dedent` + const result = dedent` /* * Copyright (c) 2024, salesforce.com, inc. * All rights reserved. @@ -117,4 +171,6 @@ module.exports = function (this: ExtensionsLoaderContext, that: any) { export default configuredExtensions ` + console.log('result: ', result) + return result } diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts index 2bc35d8dbb..409895cb69 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts @@ -5,4 +5,24 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -export * from './extensions-loader' \ No newline at end of file +export * from './extensions-loader' + +export const ruleForApplicationExtensibility = (findDepInStack: any, options: any) => { + const {target} = options + const testRegexStr = `${target === 'node' ? 'express' : 'react'}\/assets\/application-extensions-placeholder\.js` + + // TODO: User the newly created utility getApplicationExtensionInfo to get the information required here. + // NOTE: Passing around the `getConfig` is going to be interesting to make it look nice. Might jsut abandon it??? + return { + test: new RegExp(testRegexStr, 'i'), + use: { + loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), + options: { + // pkg, + // getConfig, + // target: 'node' + ...options + } + } + } +} diff --git a/packages/pwa-kit-extension-support/src/shared/utils/index.ts b/packages/pwa-kit-extension-support/src/shared/utils/index.ts index 2a39bd7598..f24c41f245 100644 --- a/packages/pwa-kit-extension-support/src/shared/utils/index.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/index.ts @@ -5,6 +5,10 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ +// Third-Party Imports +import {resolve} from 'path' +import fse from 'fs-extra' + // Re-exports export * from './extensibility-utils' export * from './resolver-utils' @@ -54,3 +58,23 @@ export const kebabToLowerCamelCase = (str: string) => : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() ) .join('') + +export const getApplicationExtensionInfo = (getConfig: any) => { + console.log('getApplicationExtensionInfo: ') + + const projectDir = process.cwd() + const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ + const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) + + const installedExtensions = Object.keys(pkg?.devDependencies || {}) + .map((packageName) => (packageName.match(nameRegex) !== null ? packageName : undefined)) + .filter(Boolean) + + // NOTE: Might have to get the expanded version of these. + const configuredExtensions = getConfig()?.app?.extensions + + return { + installed: installedExtensions, + configured: configuredExtensions + } +} \ No newline at end of file From 54aa84771156831d67897db68f7cc2c7fa69c845 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 17 Oct 2024 11:57:14 -0700 Subject: [PATCH 154/929] Checkpoint 2 --- .../package-lock.json | 42 +++++ .../pwa-kit-extension-support/package.json | 1 + .../src/configs/application-extensions.hbs | 16 -- .../babel/plugin-application-extensions.ts | 47 +++--- .../src/configs/utils.ts | 59 ++++++++ .../webpack/loaders/extensions-loader.ts | 143 ++---------------- .../application-extensions-middleware.ts | 1 + 7 files changed, 130 insertions(+), 179 deletions(-) delete mode 100644 packages/pwa-kit-extension-support/src/configs/application-extensions.hbs create mode 100644 packages/pwa-kit-extension-support/src/configs/utils.ts diff --git a/packages/pwa-kit-extension-support/package-lock.json b/packages/pwa-kit-extension-support/package-lock.json index 6ff3463aec..9aa3ea1bc2 100644 --- a/packages/pwa-kit-extension-support/package-lock.json +++ b/packages/pwa-kit-extension-support/package-lock.json @@ -19,6 +19,7 @@ "devDependencies": { "@babel/core": "^7.21.3", "@babel/parser": "^7.21.3", + "@types/babel__core": "^7.20.5", "@types/express": "^5.0.0", "@types/fs-extra": "^11.0.4", "@types/hoist-non-react-statics": "~3.3.5", @@ -389,6 +390,47 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", diff --git a/packages/pwa-kit-extension-support/package.json b/packages/pwa-kit-extension-support/package.json index 4097b74bf7..453107d4b8 100644 --- a/packages/pwa-kit-extension-support/package.json +++ b/packages/pwa-kit-extension-support/package.json @@ -40,6 +40,7 @@ "@babel/core": "^7.21.3", "@babel/parser": "^7.21.3", "@types/express": "^5.0.0", + "@types/babel__core": "^7.20.5", "@types/fs-extra": "^11.0.4", "@types/hoist-non-react-statics": "~3.3.5", "@types/node": "^20", diff --git a/packages/pwa-kit-extension-support/src/configs/application-extensions.hbs b/packages/pwa-kit-extension-support/src/configs/application-extensions.hbs deleted file mode 100644 index 5f79fdea93..0000000000 --- a/packages/pwa-kit-extension-support/src/configs/application-extensions.hbs +++ /dev/null @@ -1,16 +0,0 @@ -/* -* Copyright (c) 2024, salesforce.com, 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 -*/ - -{{#each installed}} -import {{getInstanceName .}} from {{.}} -{{/each}} - -export default [ - {{#each configured}} - new {{getInstanceName .}}({}){{#if (isNotLast @index @root.configured.length)}},{{/if}} - {{/each}} -] \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts index dd7b682ad9..831b14401d 100644 --- a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts +++ b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts @@ -4,31 +4,17 @@ * 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 */ - +// Third-Party +// NOTE: These do not like the "import" syntax. Will break the plugin if you change it. const parser = require("@babel/parser") const babel = require("@babel/core") -// TODO: Refactor the shared logic -let extensionLoader = require('../webpack/loaders/extensions-loader') -import fse from 'fs-extra' -import _path, {resolve} from 'path' -const projectDir = process.cwd() -const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) +import {renderTemplate} from '../utils' +import {buildAliases} from '../../shared/utils' -const getOptions =() => { - return { - pkg, - getConfig: () => ({ - app: { - extensions: ['@salesforce/extension-sample'] - } - }), - target: 'node' - } -} // application-extensions-placeholder // const fileToReplace = 'assets/application-extensions-placeholder.js' -const repalcementContent = extensionLoader({getOptions}, {getOptions}) +// const repalcementContent = extensionLoader({getOptions}, {getOptions}) // A Set to keep track of processed file paths const processedFiles = new Set() @@ -38,14 +24,11 @@ module.exports = function replaceFileContentPlugin({ types: t } : any) { ImportDeclaration(path: any, state: any) { console.log('state options: ', state.opts) - // Hmmmm 🤔 I can't remember why I did this, but if this is a solution to a problem we'll have to make sure we make - // it work for all configured application extensions. - const aliases: any = { - '@salesforce/extension-sample': '/Users/bchypak/Projects/pwa-kit/packages/template-typescript-minimal/node_modules/@salesforce/extension-sample/src/' - } - + // This is analogus to the work we did in webpack to have aliases for the extensions. + // TODO: This should be coming from the options. + const aliases: any = buildAliases(['@salesforce/extension-sample']) const source = path.node.source.value - + // Check for alias for (const alias in aliases) { if (source.startsWith(alias)) { @@ -65,10 +48,16 @@ module.exports = function replaceFileContentPlugin({ types: t } : any) { // Check if the file matches one of the files we want to replace if (filePath.endsWith('express/assets/application-extensions-placeholder.js')) { - console.log('Project Directory: ', projectDir) - const newContent = repalcementContent - let parsedAst; + const newContent = renderTemplate( + { + installed: ['@salesforce/extension-sample'], + configured: ['@salesforce/extension-sample'], + target: 'node' + } + ) + + let parsedAst try { // Parse the new content as a full program parsedAst = parser.parse(newContent, { diff --git a/packages/pwa-kit-extension-support/src/configs/utils.ts b/packages/pwa-kit-extension-support/src/configs/utils.ts new file mode 100644 index 0000000000..122c6cb3dd --- /dev/null +++ b/packages/pwa-kit-extension-support/src/configs/utils.ts @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024, 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 + */ + +import dedent from 'dedent' +import Handlebars from 'handlebars' + +const templateString = dedent` + /* + * Copyright (c) 2024, salesforce.com, 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 + */ + + {{#each installed}} + import {{getInstanceName .}} from '{{.}}/setup-{{#if (isNode @root.target)}}server{{else}}app{{/if}}' + {{/each}} + + export default [ + {{#each configured}} + new {{getInstanceName .}}({}){{#if (isNotLast @index @root.configured.length)}},{{/if}} + {{/each}} + ] +` + +export const renderTemplate = (data: any) => { + const kebabToUpperCamelCase = (aString: string) => { + return aString.split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join('') + } + + Handlebars.registerHelper('getInstanceName', function (aString) { + const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ + const [_, namespace, name] = aString.match(nameRegex) + + return kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`) + }) + + Handlebars.registerHelper('isNotLast', function (index, arrayLength) { + return index !== arrayLength - 1 + }) + + Handlebars.registerHelper('isNode', function (target) { + return target === 'node' + }) + + // Compile the template + const template = Handlebars.compile(templateString) + + // Apply data to the compiled template + const output = template(data) + + return output +} \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index 2bd775003e..7acffb1b94 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -5,17 +5,12 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import dedent from 'dedent' +// Third-Party import {LoaderContext} from 'webpack' import {PackageJson} from 'type-fest' -import Handlebars from 'handlebars' -import {kebabToUpperCamelCase} from '../../../shared/utils' -import {nameRegex} from '../../../shared/utils/extensibility-utils' - -const APP_EXTENSION_CLIENT_ENTRY = 'setup-app' -const APP_EXTENSION_SERVER_ENTRY = 'setup-server' -const APP_EXTENSION_PREFIX = 'extension-' // aligns with what's in `nameRegex` +// Local +import {renderTemplate} from '../../utils' // TODO: Move these to a better location. interface ExtensionsLoaderOptions { @@ -28,51 +23,6 @@ interface ExtensionsLoaderContext extends LoaderContext // You can add any additional properties if needed } -const templateString = dedent` - /* - * Copyright (c) 2024, salesforce.com, 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 - */ - - {{#each installed}} - import {{getInstanceName .}} from {{.}} - {{/each}} - - export default [ - {{#each configured}} - new {{getInstanceName .}}({}){{#if (isNotLast @index @root.configured.length)}},{{/if}} - {{/each}} - ] -` -const renderTemplate = (templateString: string, data: any) => { - const kebabToUpperCamelCase = (aString: string) => { - return aString.split('-') - .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) - .join('') - } - - Handlebars.registerHelper('getInstanceName', function (aString) { - const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ - const [packageName, namespace, name] = aString.match(nameRegex) - - return kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`) - }) - - Handlebars.registerHelper('isNotLast', function (index, arrayLength) { - return index !== arrayLength - 1; - }) - - // Compile the template - const template = Handlebars.compile(templateString) - - // Apply data to the compiled template - const output = template(data) - - return output - } - /** * The `extensions-loader` as a mechanism to get all configured extensions for a given pwa-kit * application. We use this loader as a simple way to determine what extension code in required in @@ -87,90 +37,15 @@ const renderTemplate = (templateString: string, data: any) => { * * @returns {string} The string representation of a module exporting all the named application extension modules. */ -module.exports = function (this: ExtensionsLoaderContext, that: any) { - // console.log('this|that: ', this, that) - const {pkg, getConfig, target = 'web'} = that?.getOptions?.() || this.getOptions() || {} - const {devDependencies} = pkg +module.exports = function (this: ExtensionsLoaderContext): string { + // const {pkg, getConfig, target = 'web'} = this.getOptions() || {} + const {target = 'node'} = this?.getOptions?.() || {} - // ------ - console.log('process.cwd()', process.cwd()) - const renderedHTML = renderTemplate( - templateString, + return renderTemplate( { - installed: ['@salesforce/extension-sample', '@salesforce/extension-sample-2'], + installed: ['@salesforce/extension-sample'], configured: ['@salesforce/extension-sample'], + target } ) - console.log(renderedHTML) - // ------ - // TODO: clean this up.. looks like this is a bad variable name for the type that it represents. - const extensions = Object.keys(devDependencies || {}) - .map((packageName) => packageName.match(nameRegex)) - .filter(Boolean) - - // Ensure that only valid extension names are loaded. - const extensionDetails = extensions.map((match) => { - const [packageName, namespace, name] = match || [] - return { - instanceVariable: kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`), - modulePath: `${ - namespace ? `@${namespace}/` : '' - }${APP_EXTENSION_PREFIX}${name}/${target === 'web' ? APP_EXTENSION_CLIENT_ENTRY : APP_EXTENSION_SERVER_ENTRY}`, - packageName - } - }) - - const appExtensions = getConfig()?.app?.extensions - - const result = dedent` - /* - * Copyright (c) 2024, salesforce.com, 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 - */ - // NOTE: I'm not completely sure why this was giving me isses as it should be running in the context of the - // base application and not the extension-support project. - // import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' - - // TODO: Once we create @salesforce/pwa-kit-extensibility we will refactor this code to use a shared utility that - // normalizes/expands the configuration array before it is uses in this loader. - const normalizeExtensionsList = (extensions = []) => - extensions.map((extension) => { - return { - packageName: Array.isArray(extension) ? extension[0] : extension, - config: Array.isArray(extension) ? {enabled: true, ...extension[1]} : {enabled: true} - } - }) - - // App Extensions - ${extensionDetails - .map( - ({instanceVariable, modulePath}) => - `import ${instanceVariable} from '${modulePath}'` - ) - .join('\n ')} - - const installedExtensions = [ - ${extensionDetails - .map( - ({packageName, instanceVariable}) => - `{packageName: '${packageName}', instanceVariable: ${instanceVariable}}` - ) - .join(',\n ')} - ] - - const configuredExtensions = (normalizeExtensionsList(${JSON.stringify(appExtensions)}) || []) - .filter((extension) => extension.config.enabled) - .map((extension) => { - // Make sure that the configured extensions are installed, before instantiating them - const found = installedExtensions.find((ext) => ext.packageName === extension.packageName) - return found ? new found.instanceVariable(extension.config || {}) : false - }) - .filter(Boolean) - - export default configuredExtensions - ` - console.log('result: ', result) - return result } diff --git a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts index 1c3309745c..073741b0e1 100644 --- a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts +++ b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts @@ -24,6 +24,7 @@ const applicationExtensionsMiddleware = (app: Application) => { APPLICATION_EXTENSIONS.forEach((applicationExtension) => { app = applicationExtension.extendApp(app) }) + return (req: Request, res: Response, next: NextFunction): void => { next() } From 6acc87296f76fb29a5218e0471a0429e26551806 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 17 Oct 2024 16:39:26 -0700 Subject: [PATCH 155/929] Checkpoint 2 --- .../src/configs/babel/babel-config.js | 96 +++++++++---------- .../pwa-kit-dev/src/configs/webpack/config.js | 20 +++- .../babel/plugin-application-extensions.ts | 12 ++- .../src/configs/utils.ts | 41 ++++---- .../webpack/loaders/extensions-loader.ts | 13 +-- .../src/configs/webpack/loaders/index.ts | 32 ++++--- .../application-extensions-middleware.ts | 1 + .../src/shared/utils/extensibility-utils.ts | 17 +--- .../src/shared/utils/index.ts | 16 ++-- .../template-typescript-minimal/package.json | 2 +- 10 files changed, 126 insertions(+), 124 deletions(-) diff --git a/packages/pwa-kit-dev/src/configs/babel/babel-config.js b/packages/pwa-kit-dev/src/configs/babel/babel-config.js index 4610b4e85d..5bb63035e5 100644 --- a/packages/pwa-kit-dev/src/configs/babel/babel-config.js +++ b/packages/pwa-kit-dev/src/configs/babel/babel-config.js @@ -4,63 +4,59 @@ * 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 */ -const DEFAULT_TARGET = 'node' // PWA-Kit Imports import {getApplicationExtensionInfo} from '@salesforce/pwa-kit-extension-support/shared/utils' import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' -const config = (api) => { - - return { - sourceType: 'unambiguous', - presets: [ - [ - require('@babel/preset-env'), - { - targets: { - node: 18 - } +const config = { + sourceType: 'unambiguous', + presets: [ + [ + require('@babel/preset-env'), + { + targets: { + node: 18 } - ], - require('@babel/preset-typescript'), - require('@babel/preset-react') + } ], - plugins: [ - [ - require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), - { - target: api.caller(caller => caller?.target || DEFAULT_TARGET), - ...getApplicationExtensionInfo(getConfig) - } - ], - require('@babel/plugin-transform-async-to-generator'), - require('@babel/plugin-proposal-object-rest-spread'), - require('@babel/plugin-transform-object-assign'), - [ - require('@babel/plugin-transform-runtime'), - { - regenerator: true - } - ], - require('@babel/plugin-syntax-dynamic-import'), - require('@loadable/babel-plugin'), - require('@babel/plugin-proposal-optional-chaining'), - [ - require('babel-plugin-formatjs'), - { - idInterpolationPattern: '[sha512:contenthash:base64:6]', - ast: true - } - ], - require('@babel/plugin-transform-async-generator-functions') - ].filter(Boolean), - env: { - test: { - presets: [require('@babel/preset-env'), require('@babel/preset-react')], - plugins: [require('babel-plugin-dynamic-import-node-babel-7')] + require('@babel/preset-typescript'), + require('@babel/preset-react') + ], + plugins: [ + [ + require('@salesforce/pwa-kit-extension-support/configs/babel/plugin-application-extensions'), + { + target: 'node', + ...getApplicationExtensionInfo(getConfig()) } + ], + require('@babel/plugin-transform-async-to-generator'), + require('@babel/plugin-proposal-object-rest-spread'), + require('@babel/plugin-transform-object-assign'), + [ + require('@babel/plugin-transform-runtime'), + { + regenerator: true + } + ], + require('@babel/plugin-syntax-dynamic-import'), + require('@loadable/babel-plugin'), + require('@babel/plugin-proposal-optional-chaining'), + [ + require('babel-plugin-formatjs'), + { + idInterpolationPattern: '[sha512:contenthash:base64:6]', + ast: true + } + ], + require('@babel/plugin-transform-async-generator-functions') + ].filter(Boolean), + env: { + test: { + presets: [require('@babel/preset-env'), require('@babel/preset-react')], + plugins: [require('babel-plugin-dynamic-import-node-babel-7')] } - } -} + } +} export default config diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index cf38a9f51f..609775e434 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -256,8 +256,24 @@ const baseConfig = (target) => { loader: findDepInStack('source-map-loader') } }, - ruleForApplicationExtensibility(findDepInStack, {pkg, getConfig, target: 'web'}), - ruleForApplicationExtensibility(findDepInStack, {pkg, getConfig, target: 'node'}) + ruleForApplicationExtensibility( + { + loaderResolver: findDepInStack, + loaderOptions: { + appConfig: getConfig(), + target: 'web' + } + } + ), + ruleForApplicationExtensibility( + { + loaderResolver: findDepInStack, + loaderOptions: { + appConfig: getConfig(), + target: 'node' + } + } + ) ].filter(Boolean) } } diff --git a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts index 831b14401d..9eaf7c1590 100644 --- a/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts +++ b/packages/pwa-kit-extension-support/src/configs/babel/plugin-application-extensions.ts @@ -22,11 +22,12 @@ module.exports = function replaceFileContentPlugin({ types: t } : any) { return { visitor: { ImportDeclaration(path: any, state: any) { - console.log('state options: ', state.opts) + const {installed} = state.opts + // TODO: Throw is undefined? // This is analogus to the work we did in webpack to have aliases for the extensions. // TODO: This should be coming from the options. - const aliases: any = buildAliases(['@salesforce/extension-sample']) + const aliases: any = buildAliases(installed) const source = path.node.source.value // Check for alias @@ -39,6 +40,7 @@ module.exports = function replaceFileContentPlugin({ types: t } : any) { }, Program(path: any, state: any) { const filePath = state.file.opts.filename + const {installed, configured, target} = state.opts // Add a marker to the state to prevent reprocessing if (processedFiles.has(filePath)) { @@ -51,9 +53,9 @@ module.exports = function replaceFileContentPlugin({ types: t } : any) { const newContent = renderTemplate( { - installed: ['@salesforce/extension-sample'], - configured: ['@salesforce/extension-sample'], - target: 'node' + installed, + configured, + target } ) diff --git a/packages/pwa-kit-extension-support/src/configs/utils.ts b/packages/pwa-kit-extension-support/src/configs/utils.ts index 122c6cb3dd..a54740c94c 100644 --- a/packages/pwa-kit-extension-support/src/configs/utils.ts +++ b/packages/pwa-kit-extension-support/src/configs/utils.ts @@ -8,6 +8,19 @@ import dedent from 'dedent' import Handlebars from 'handlebars' +// Local +import {kebabToUpperCamelCase, nameRegex} from '../shared/utils' + +// Regeister Handlebars helpers +Handlebars.registerHelper('getInstanceName', (aString) => { + const [_, namespace, name] = aString.match(nameRegex) + + return kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`) +}) +Handlebars.registerHelper('isNotLast', (index, arrayLength) => index !== arrayLength - 1) +Handlebars.registerHelper('isNode', (target) => target === 'node') +Handlebars.registerHelper('jsonStringify', (context) => JSON.stringify(context, null, 0)) + const templateString = dedent` /* * Copyright (c) 2024, salesforce.com, inc. @@ -22,38 +35,16 @@ const templateString = dedent` export default [ {{#each configured}} - new {{getInstanceName .}}({}){{#if (isNotLast @index @root.configured.length)}},{{/if}} + new {{getInstanceName this.[0]}}({{{jsonStringify this.[1]}}}){{#if (isNotLast @index @root.configured.length)}},{{/if}} {{/each}} ] ` export const renderTemplate = (data: any) => { - const kebabToUpperCamelCase = (aString: string) => { - return aString.split('-') - .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) - .join('') - } - - Handlebars.registerHelper('getInstanceName', function (aString) { - const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ - const [_, namespace, name] = aString.match(nameRegex) - - return kebabToUpperCamelCase(`${namespace ? `${namespace}-` : ''}-${name}`) - }) - - Handlebars.registerHelper('isNotLast', function (index, arrayLength) { - return index !== arrayLength - 1 - }) - - Handlebars.registerHelper('isNode', function (target) { - return target === 'node' - }) - // Compile the template const template = Handlebars.compile(templateString) + console.log('template(data): ', data, template(data)) // Apply data to the compiled template - const output = template(data) - - return output + return template(data) } \ No newline at end of file diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts index 7acffb1b94..b1dee0109e 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/extensions-loader.ts @@ -38,14 +38,7 @@ interface ExtensionsLoaderContext extends LoaderContext * @returns {string} The string representation of a module exporting all the named application extension modules. */ module.exports = function (this: ExtensionsLoaderContext): string { - // const {pkg, getConfig, target = 'web'} = this.getOptions() || {} - const {target = 'node'} = this?.getOptions?.() || {} - - return renderTemplate( - { - installed: ['@salesforce/extension-sample'], - configured: ['@salesforce/extension-sample'], - target - } - ) + // TODO: Add some argument checks here. + + return renderTemplate(this.getOptions()) } diff --git a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts index 409895cb69..b471409a42 100644 --- a/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts +++ b/packages/pwa-kit-extension-support/src/configs/webpack/loaders/index.ts @@ -5,24 +5,32 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ +// Local +import {getApplicationExtensionInfo} from '../../../shared/utils' + +// Exports export * from './extensions-loader' -export const ruleForApplicationExtensibility = (findDepInStack: any, options: any) => { - const {target} = options - const testRegexStr = `${target === 'node' ? 'express' : 'react'}\/assets\/application-extensions-placeholder\.js` - +const LOADER_IMPORT = '@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader' +const DEFAULT_TARGET = 'node' + +export const ruleForApplicationExtensibility = (options: any = {}) => { + const {loaderResolver, loaderOptions = {}} = options + const { + target = DEFAULT_TARGET, + appConfig + } = loaderOptions + // TODO: User the newly created utility getApplicationExtensionInfo to get the information required here. - // NOTE: Passing around the `getConfig` is going to be interesting to make it look nice. Might jsut abandon it??? + // NOTE: Passing around the `getConfig` is going to be interesting to make it look nice. Might just abandon it??? return { - test: new RegExp(testRegexStr, 'i'), + test: new RegExp(`${target === 'node' ? 'express' : 'react'}\/assets\/application-extensions-placeholder\.js`, 'i'), use: { - loader: findDepInStack('@salesforce/pwa-kit-extension-support/configs/webpack/loaders/extensions-loader'), + loader: loaderResolver ? loaderResolver(LOADER_IMPORT) : LOADER_IMPORT, options: { - // pkg, - // getConfig, - // target: 'node' - ...options + ...getApplicationExtensionInfo(appConfig), + target } } - } + } } diff --git a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts index 073741b0e1..7f5e6b7057 100644 --- a/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts +++ b/packages/pwa-kit-extension-support/src/express/application-extensions-middleware.ts @@ -22,6 +22,7 @@ const applicationExtensionsMiddleware = (app: Application) => { // const applicationExtensions = getApplicationExtensions>() as ApplicationExtension[] console.log('applicationExtensionsMiddleware: applying ', APPLICATION_EXTENSIONS) APPLICATION_EXTENSIONS.forEach((applicationExtension) => { + // if (applicationExtension.getConfig().enabled) app = applicationExtension.extendApp(app) }) diff --git a/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts index 0f4c965df3..0c6e7e548c 100644 --- a/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/extensibility-utils.ts @@ -5,17 +5,19 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import path from 'path' +// Third-Party import fs from 'fs-extra' +import path from 'path' // Types import {ApplicationExtensionEntry, ApplicationExtensionEntryArray} from '../../types' +// CONSTANTS const REACT_EXTENSIBILITY_FILE = 'setup-app' const EXPRESS_EXTENSIBILITY_FILE = 'setup-server' - const SUPPORTED_FILE_TYPES = ['.ts', '.js'] +// TODO: Update this block comment. /** * Given a list of extensions, returns an object where the key is the extensions * app entry import string, and the value the path to the source file. @@ -42,21 +44,10 @@ export const buildAliases = (extensions: ApplicationExtensionEntry[] = []) => { 'node_modules', extension, 'src' - // , // 🤔 - // REACT_EXTENSIBILITY_FILE ) - // const foundFilePath = findFileWithExtension(basePath, SUPPORTED_FILE_TYPES) - - // if (!foundFilePath) { - // // no setup-server file found, early exit because it's optional - // return acc - // } - return { ...acc, - // [`${extension}/${REACT_EXTENSIBILITY_FILE}`]: findFileWithExtension(path.join(basePath, REACT_EXTENSIBILITY_FILE), SUPPORTED_FILE_TYPES), - // [`${extension}/${EXPRESS_EXTENSIBILITY_FILE}`]: findFileWithExtension(path.join(basePath, EXPRESS_EXTENSIBILITY_FILE), SUPPORTED_FILE_TYPES) [`${extension}`]: basePath } }, {}) diff --git a/packages/pwa-kit-extension-support/src/shared/utils/index.ts b/packages/pwa-kit-extension-support/src/shared/utils/index.ts index f24c41f245..d18072882b 100644 --- a/packages/pwa-kit-extension-support/src/shared/utils/index.ts +++ b/packages/pwa-kit-extension-support/src/shared/utils/index.ts @@ -9,6 +9,10 @@ import {resolve} from 'path' import fse from 'fs-extra' +// Local +import {expand} from './resolver-utils' +import {nameRegex} from './extensibility-utils' + // Re-exports export * from './extensibility-utils' export * from './resolver-utils' @@ -59,20 +63,20 @@ export const kebabToLowerCamelCase = (str: string) => ) .join('') -export const getApplicationExtensionInfo = (getConfig: any) => { - console.log('getApplicationExtensionInfo: ') - +export const getApplicationExtensionInfo = (appConfig?: any) => { const projectDir = process.cwd() - const nameRegex = /^(?:@([^/]+)\/)?extension-(.+)$/ const pkg = fse.readJsonSync(resolve(projectDir, 'package.json')) + // Use the application configuration in the projects application if one isn't provided. + appConfig = appConfig ? appConfig : fse.readJsonSync(resolve(projectDir, 'package.json'))?.mobify || {} + const installedExtensions = Object.keys(pkg?.devDependencies || {}) .map((packageName) => (packageName.match(nameRegex) !== null ? packageName : undefined)) .filter(Boolean) // NOTE: Might have to get the expanded version of these. - const configuredExtensions = getConfig()?.app?.extensions - + const configuredExtensions = expand(appConfig?.app?.extensions || []) + console.log('getApplicationExtensionInfo: ', configuredExtensions) return { installed: installedExtensions, configured: configuredExtensions diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index d9294ebd23..c920337f90 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -44,7 +44,7 @@ }, "mobify": { "app":{ - "extensions": ["@salesforce/extension-sample"] + "extensions": [["@salesforce/extension-sample", {"enabled": false}]] }, "ssrEnabled": true, "ssrOnly": [ From 902826187e18c795a44edefc2d5eb1aa8e6b4e2c Mon Sep 17 00:00:00 2001 From: Kevin He Date: Thu, 17 Oct 2024 17:25:20 -0700 Subject: [PATCH 156/929] wip --- packages/extension-store-locator/package.json | 5 + .../components/store-locator-modal/index.jsx | 102 +++++ .../store-locator-modal/index.test.jsx | 212 ++++++++++ .../store-locator-content.jsx | 207 +++++++++ .../store-locator-content.test.jsx | 400 ++++++++++++++++++ .../store-locator-input.jsx | 230 ++++++++++ .../store-locator-input.test.jsx | 75 ++++ .../store-locator-modal/stores-list.jsx | 90 ++++ .../store-locator-modal/stores-list.test.jsx | 172 ++++++++ .../src/pages/store-locator/index.tsx | 82 ++-- 10 files changed, 1526 insertions(+), 49 deletions(-) create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/index.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/index.test.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.test.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.test.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/stores-list.jsx create mode 100644 packages/extension-store-locator/src/components/store-locator-modal/stores-list.test.jsx diff --git a/packages/extension-store-locator/package.json b/packages/extension-store-locator/package.json index 88c9d57c6f..4b5c98e8ac 100644 --- a/packages/extension-store-locator/package.json +++ b/packages/extension-store-locator/package.json @@ -5,12 +5,14 @@ "peerDependencies": { "@chakra-ui/react": "^2.10.3", "@loadable/component": "^5.15.3", + "@salesforce/commerce-sdk-react": "3.1.0-dev", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@chakra-ui/react": "^2.10.3", "@loadable/component": "^5.15.3", + "@salesforce/commerce-sdk-react": "3.1.0-dev", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@types/react": "~18.2.0", @@ -22,5 +24,8 @@ "engines": { "node": "^16.11.0 || ^18.0.0 || ^20.0.0", "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + }, + "dependencies": { + "@salesforce/commerce-sdk-react": "^3.1.0-dev" } } diff --git a/packages/extension-store-locator/src/components/store-locator-modal/index.jsx b/packages/extension-store-locator/src/components/store-locator-modal/index.jsx new file mode 100644 index 0000000000..48008b060f --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/index.jsx @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React, {useState, createContext} from 'react' +import PropTypes from 'prop-types' + +// Components +import { + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + useBreakpointValue +} from '@chakra-ui/react' +import StoreLocatorContent from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-content' + +// Others +import { + DEFAULT_STORE_LOCATOR_COUNTRY, + DEFAULT_STORE_LOCATOR_POSTAL_CODE, + STORE_LOCATOR_NUM_STORES_PER_LOAD +} from '@salesforce/retail-react-app/app/constants' + +export const StoreLocatorContext = createContext() +export const useStoreLocator = () => { + const [userHasSetManualGeolocation, setUserHasSetManualGeolocation] = useState(false) + const [automaticGeolocationHasFailed, setAutomaticGeolocationHasFailed] = useState(false) + const [userWantsToShareLocation, setUserWantsToShareLocation] = useState(false) + + const [searchStoresParams, setSearchStoresParams] = useState({ + countryCode: DEFAULT_STORE_LOCATOR_COUNTRY.countryCode, + postalCode: DEFAULT_STORE_LOCATOR_POSTAL_CODE, + limit: STORE_LOCATOR_NUM_STORES_PER_LOAD + }) + + return { + userHasSetManualGeolocation, + setUserHasSetManualGeolocation, + automaticGeolocationHasFailed, + setAutomaticGeolocationHasFailed, + userWantsToShareLocation, + setUserWantsToShareLocation, + searchStoresParams, + setSearchStoresParams + } +} + +const StoreLocatorModal = ({isOpen, onClose}) => { + const storeLocator = useStoreLocator() + const isDesktopView = useBreakpointValue({base: false, lg: true}) + + return ( + + {isDesktopView ? ( + + + + + + + + + ) : ( + + + + + + + + + )} + + ) +} + +StoreLocatorModal.propTypes = { + isOpen: PropTypes.bool, + onClose: PropTypes.func +} + +export default StoreLocatorModal diff --git a/packages/extension-store-locator/src/components/store-locator-modal/index.test.jsx b/packages/extension-store-locator/src/components/store-locator-modal/index.test.jsx new file mode 100644 index 0000000000..2fadf4cb89 --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/index.test.jsx @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React from 'react' +import StoreLocatorModal from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils' +import {rest} from 'msw' + +const mockStoresData = [ + { + address1: '162 University Ave', + city: 'Palo Alto', + countryCode: 'US', + distance: 0.0, + distanceUnit: 'km', + id: '00041', + latitude: 37.189396, + longitude: -121.705327, + name: 'Palo Alto Store', + posEnabled: false, + postalCode: '94301', + stateCode: 'CA', + storeHours: 'THIS IS ENGLISH STORE HOURS', + storeLocatorEnabled: true, + c_countryCodeValue: 'US' + }, + { + address1: 'Holstenstraße 1', + city: 'Kiel', + countryCode: 'DE', + distance: 8847.61, + distanceUnit: 'km', + id: '00031', + inventoryId: 'inventory_m_store_store23', + latitude: 54.3233, + longitude: 10.1394, + name: 'Kiel Electronics Store', + phone: '+49 431 123456', + posEnabled: false, + postalCode: '24103', + storeHours: + 'Monday 9 AM–7 PM\nTuesday 9 AM–7 PM\nWednesday 9 AM–7 PM\nThursday 9 AM–8 PM\nFriday 9 AM–7 PM\nSaturday 9 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Heiligengeiststraße 2', + city: 'Oldenburg', + countryCode: 'DE', + distance: 8873.75, + distanceUnit: 'km', + id: '00036', + inventoryId: 'inventory_m_store_store28', + latitude: 53.1445, + longitude: 8.2146, + name: 'Oldenburg Tech Depot', + phone: '+49 441 876543', + posEnabled: false, + postalCode: '26121', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Obernstraße 2', + city: 'Bremen', + countryCode: 'DE', + distance: 8904.18, + distanceUnit: 'km', + id: '00011', + inventoryId: 'inventory_m_store_store2', + latitude: 53.0765, + longitude: 8.8085, + name: 'Bremen Tech Store', + phone: '+49 421 234567', + posEnabled: false, + postalCode: '28195', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Sögestraße 40', + city: 'Bremen', + countryCode: 'DE', + distance: 8904.19, + distanceUnit: 'km', + id: '00026', + inventoryId: 'inventory_m_store_store18', + latitude: 53.0758, + longitude: 8.8072, + name: 'Bremen Tech World', + phone: '+49 421 567890', + posEnabled: false, + postalCode: '28195', + storeHours: + 'Monday 9 AM–8 PM\nTuesday 9 AM–8 PM\nWednesday 9 AM–8 PM\nThursday 9 AM–9 PM\nFriday 9 AM–8 PM\nSaturday 9 AM–7 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Jungfernstieg 12', + city: 'Hamburg', + countryCode: 'DE', + distance: 8910.05, + distanceUnit: 'km', + id: '00005', + inventoryId: 'inventory_m_store_store5', + latitude: 53.553405, + longitude: 9.992196, + name: 'Hamburg Electronics Outlet', + phone: '+49 40 444444444', + posEnabled: false, + postalCode: '20354', + storeHours: + 'Monday 10 AM–8 PM\nTuesday 10 AM–8 PM\nWednesday 10 AM–8 PM\nThursday 10 AM–9 PM\nFriday 10 AM–8 PM\nSaturday 10 AM–7 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Große Straße 40', + city: 'Osnabrück', + countryCode: 'DE', + distance: 8942.1, + distanceUnit: 'km', + id: '00037', + inventoryId: 'inventory_m_store_store29', + latitude: 52.2799, + longitude: 8.0472, + name: 'Osnabrück Tech Mart', + phone: '+49 541 654321', + posEnabled: false, + postalCode: '49074', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Kröpeliner Straße 48', + city: 'Rostock', + countryCode: 'DE', + distance: 8945.47, + distanceUnit: 'km', + id: '00032', + inventoryId: 'inventory_m_store_store24', + latitude: 54.0899, + longitude: 12.1349, + name: 'Rostock Tech Store', + phone: '+49 381 234567', + posEnabled: false, + postalCode: '18055', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Kennedyplatz 7', + city: 'Essen', + countryCode: 'DE', + distance: 8969.09, + distanceUnit: 'km', + id: '00013', + inventoryId: 'inventory_m_store_store4', + latitude: 51.4566, + longitude: 7.0125, + name: 'Essen Electronics Depot', + phone: '+49 201 456789', + posEnabled: false, + postalCode: '45127', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Kettwiger Straße 17', + city: 'Essen', + countryCode: 'DE', + distance: 8969.13, + distanceUnit: 'km', + id: '00030', + inventoryId: 'inventory_m_store_store22', + latitude: 51.4556, + longitude: 7.0116, + name: 'Essen Tech Hub', + phone: '+49 201 654321', + posEnabled: false, + postalCode: '45127', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + } +] +const mockStores = { + limit: 10, + data: mockStoresData, + offset: 0, + total: 30 +} + +describe('StoreLocatorModal', () => { + test('renders without crashing', () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res(ctx.delay(0), ctx.status(200), ctx.json(mockStores)) + }) + ) + expect(() => { + renderWithProviders() + }).not.toThrow() + }) +}) diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx new file mode 100644 index 0000000000..0883ec7550 --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React, {useState, useContext} from 'react' +import {useIntl} from 'react-intl' + +// Components +import {Heading, Accordion, AccordionItem, Box, Button} from '@chakra-ui/react' +import StoresList from '@salesforce/retail-react-app/app/components/store-locator-modal/stores-list' +import StoreLocatorInput from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-input' + +// Others +import { + SUPPORTED_STORE_LOCATOR_COUNTRIES, + DEFAULT_STORE_LOCATOR_COUNTRY, + STORE_LOCATOR_DISTANCE, + STORE_LOCATOR_NUM_STORES_PER_LOAD, + STORE_LOCATOR_DISTANCE_UNIT +} from '@salesforce/retail-react-app/app/constants' + +//This is an API limit and is therefore not configurable +const NUM_STORES_PER_REQUEST_API_MAX = 200 + +// Hooks +import {useSearchStores} from '@salesforce/commerce-sdk-react' +import {useForm} from 'react-hook-form' + +import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' + +const StoreLocatorContent = () => { + const { + searchStoresParams, + setSearchStoresParams, + userHasSetManualGeolocation, + setUserHasSetManualGeolocation + } = useContext(StoreLocatorContext) + const {countryCode, postalCode, latitude, longitude, limit} = searchStoresParams + const intl = useIntl() + const form = useForm({ + mode: 'onChange', + reValidateMode: 'onChange', + defaultValues: { + countryCode: userHasSetManualGeolocation ? countryCode : '', + postalCode: userHasSetManualGeolocation ? postalCode : '' + } + }) + + const [numStoresToShow, setNumStoresToShow] = useState(limit) + // Either the countryCode & postalCode or latitude & longitude are defined, never both + const { + data: searchStoresData, + isLoading, + refetch, + isFetching + } = useSearchStores({ + parameters: { + countryCode: countryCode, + postalCode: postalCode, + latitude: latitude, + longitude: longitude, + locale: intl.locale, + maxDistance: STORE_LOCATOR_DISTANCE, + limit: NUM_STORES_PER_REQUEST_API_MAX, + distanceUnit: STORE_LOCATOR_DISTANCE_UNIT + } + }) + + const storesInfo = + isLoading || isFetching + ? undefined + : searchStoresData?.data?.slice(0, numStoresToShow) || [] + const numStores = searchStoresData?.total || 0 + + const submitForm = async (formData) => { + const {postalCode, countryCode} = formData + if (postalCode !== '') { + if (countryCode !== '') { + setSearchStoresParams({ + postalCode: postalCode, + countryCode: countryCode, + limit: STORE_LOCATOR_NUM_STORES_PER_LOAD + }) + setUserHasSetManualGeolocation(true) + } else { + if (SUPPORTED_STORE_LOCATOR_COUNTRIES.length === 0) { + setSearchStoresParams({ + postalCode: postalCode, + countryCode: DEFAULT_STORE_LOCATOR_COUNTRY.countryCode, + limit: STORE_LOCATOR_NUM_STORES_PER_LOAD + }) + setUserHasSetManualGeolocation(true) + } + } + } + // Reset the number of stores in the UI + setNumStoresToShow(STORE_LOCATOR_NUM_STORES_PER_LOAD) + + // Ensures API call is made regardless of caching to provide UX feedback on click + refetch() + } + + const displayStoreLocatorStatusMessage = () => { + if (storesInfo === undefined) + return intl.formatMessage({ + id: 'store_locator.description.loading_locations', + defaultMessage: 'Loading locations...' + }) + if (storesInfo.length === 0) + return intl.formatMessage({ + id: 'store_locator.description.no_locations', + defaultMessage: 'Sorry, there are no locations in this area' + }) + if (searchStoresParams.postalCode !== undefined) + return `${intl.formatMessage( + { + id: 'store_locator.description.viewing_near_postal_code', + defaultMessage: + 'Viewing stores within {distance}{distanceUnit} of {postalCode} in ' + }, + { + distance: STORE_LOCATOR_DISTANCE, + distanceUnit: STORE_LOCATOR_DISTANCE_UNIT, + postalCode: searchStoresParams.postalCode + } + )} + ${ + SUPPORTED_STORE_LOCATOR_COUNTRIES.length !== 0 + ? intl.formatMessage( + SUPPORTED_STORE_LOCATOR_COUNTRIES.find( + (o) => o.countryCode === searchStoresParams.countryCode + ).countryName + ) + : intl.formatMessage(DEFAULT_STORE_LOCATOR_COUNTRY.countryName) + }` + else + return intl.formatMessage({ + id: 'store_locator.description.viewing_near_your_location', + defaultMessage: 'Viewing stores near your location' + }) + } + + return ( + <> + + {intl.formatMessage({ + id: 'store_locator.title', + defaultMessage: 'Find a Store' + })} + + + + {/* Details */} + + + {displayStoreLocatorStatusMessage()} + + + + + {!isFetching && + numStoresToShow < numStores && + numStoresToShow < NUM_STORES_PER_REQUEST_API_MAX ? ( + + + + ) : ( + '' + )} + + ) +} + +StoreLocatorContent.propTypes = {} + +export default StoreLocatorContent diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.test.jsx b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.test.jsx new file mode 100644 index 0000000000..7f50d4aea7 --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.test.jsx @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React, {useEffect} from 'react' +import StoreLocatorContent from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-content' +import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils' +import {waitFor, screen} from '@testing-library/react' +import PropTypes from 'prop-types' +import {STORE_LOCATOR_NUM_STORES_PER_LOAD} from '@salesforce/retail-react-app/app/constants' +import {rest} from 'msw' +import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +import {useStoreLocator} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +const mockStoresData = [ + { + address1: '162 University Ave', + city: 'Palo Alto', + countryCode: 'US', + distance: 0.0, + distanceUnit: 'km', + id: '00041', + latitude: 37.189396, + longitude: -121.705327, + name: 'Palo Alto Store', + posEnabled: false, + postalCode: '94301', + stateCode: 'CA', + storeHours: 'THIS IS ENGLISH STORE HOURS', + storeLocatorEnabled: true, + c_countryCodeValue: 'US' + }, + { + address1: 'Holstenstraße 1', + city: 'Kiel', + countryCode: 'DE', + distance: 8847.61, + distanceUnit: 'km', + id: '00031', + inventoryId: 'inventory_m_store_store23', + latitude: 54.3233, + longitude: 10.1394, + name: 'Kiel Electronics Store', + phone: '+49 431 123456', + posEnabled: false, + postalCode: '24103', + storeHours: + 'Monday 9 AM–7 PM\nTuesday 9 AM–7 PM\nWednesday 9 AM–7 PM\nThursday 9 AM–8 PM\nFriday 9 AM–7 PM\nSaturday 9 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Heiligengeiststraße 2', + city: 'Oldenburg', + countryCode: 'DE', + distance: 8873.75, + distanceUnit: 'km', + id: '00036', + inventoryId: 'inventory_m_store_store28', + latitude: 53.1445, + longitude: 8.2146, + name: 'Oldenburg Tech Depot', + phone: '+49 441 876543', + posEnabled: false, + postalCode: '26121', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Obernstraße 2', + city: 'Bremen', + countryCode: 'DE', + distance: 8904.18, + distanceUnit: 'km', + id: '00011', + inventoryId: 'inventory_m_store_store2', + latitude: 53.0765, + longitude: 8.8085, + name: 'Bremen Tech Store', + phone: '+49 421 234567', + posEnabled: false, + postalCode: '28195', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Sögestraße 40', + city: 'Bremen', + countryCode: 'DE', + distance: 8904.19, + distanceUnit: 'km', + id: '00026', + inventoryId: 'inventory_m_store_store18', + latitude: 53.0758, + longitude: 8.8072, + name: 'Bremen Tech World', + phone: '+49 421 567890', + posEnabled: false, + postalCode: '28195', + storeHours: + 'Monday 9 AM–8 PM\nTuesday 9 AM–8 PM\nWednesday 9 AM–8 PM\nThursday 9 AM–9 PM\nFriday 9 AM–8 PM\nSaturday 9 AM–7 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Jungfernstieg 12', + city: 'Hamburg', + countryCode: 'DE', + distance: 8910.05, + distanceUnit: 'km', + id: '00005', + inventoryId: 'inventory_m_store_store5', + latitude: 53.553405, + longitude: 9.992196, + name: 'Hamburg Electronics Outlet', + phone: '+49 40 444444444', + posEnabled: false, + postalCode: '20354', + storeHours: + 'Monday 10 AM–8 PM\nTuesday 10 AM–8 PM\nWednesday 10 AM–8 PM\nThursday 10 AM–9 PM\nFriday 10 AM–8 PM\nSaturday 10 AM–7 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Große Straße 40', + city: 'Osnabrück', + countryCode: 'DE', + distance: 8942.1, + distanceUnit: 'km', + id: '00037', + inventoryId: 'inventory_m_store_store29', + latitude: 52.2799, + longitude: 8.0472, + name: 'Osnabrück Tech Mart', + phone: '+49 541 654321', + posEnabled: false, + postalCode: '49074', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Kröpeliner Straße 48', + city: 'Rostock', + countryCode: 'DE', + distance: 8945.47, + distanceUnit: 'km', + id: '00032', + inventoryId: 'inventory_m_store_store24', + latitude: 54.0899, + longitude: 12.1349, + name: 'Rostock Tech Store', + phone: '+49 381 234567', + posEnabled: false, + postalCode: '18055', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Kennedyplatz 7', + city: 'Essen', + countryCode: 'DE', + distance: 8969.09, + distanceUnit: 'km', + id: '00013', + inventoryId: 'inventory_m_store_store4', + latitude: 51.4566, + longitude: 7.0125, + name: 'Essen Electronics Depot', + phone: '+49 201 456789', + posEnabled: false, + postalCode: '45127', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Kettwiger Straße 17', + city: 'Essen', + countryCode: 'DE', + distance: 8969.13, + distanceUnit: 'km', + id: '00030', + inventoryId: 'inventory_m_store_store22', + latitude: 51.4556, + longitude: 7.0116, + name: 'Essen Tech Hub', + phone: '+49 201 654321', + posEnabled: false, + postalCode: '45127', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + } +] +const mockStoresTotalIsHigherThanLimit = { + limit: 10, + data: mockStoresData, + offset: 0, + total: 30 +} + +const mockStoresTotalIsEqualToLimit = { + limit: 10, + data: mockStoresData, + offset: 0, + total: 10 +} + +const mockNoStores = { + limit: 0, + total: 0 +} + +const WrapperComponent = ({searchStoresParams, userHasSetManualGeolocation}) => { + const storeLocator = useStoreLocator() + useEffect(() => { + storeLocator.setSearchStoresParams(searchStoresParams) + storeLocator.setUserHasSetManualGeolocation(userHasSetManualGeolocation) + }, []) + return ( + + + + ) +} +WrapperComponent.propTypes = { + storesInfo: PropTypes.array, + userHasSetManualGeolocation: PropTypes.bool, + searchStoresParams: PropTypes.object +} + +describe('StoreLocatorContent', () => { + test('renders without crashing', () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res( + ctx.delay(0), + ctx.status(200), + ctx.json(mockStoresTotalIsHigherThanLimit) + ) + }) + ) + expect(() => { + renderWithProviders( + + ) + }).not.toThrow() + }) + + test('Expected information exists', async () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res( + ctx.delay(0), + ctx.status(200), + ctx.json(mockStoresTotalIsHigherThanLimit) + ) + }) + ) + renderWithProviders( + + ) + + await waitFor(async () => { + const findButton = screen.getByRole('button', {name: /Find/i}) + const useMyLocationButton = screen.getByRole('button', {name: /Use My Location/i}) + const descriptionFindAStore = screen.getByText(/Find a Store/i) + const viewing = screen.getByText(/Viewing stores within 100km of 10178 in Germany/i) + + expect(findButton).toBeInTheDocument() + expect(useMyLocationButton).toBeInTheDocument() + expect(descriptionFindAStore).toBeInTheDocument() + expect(viewing).toBeInTheDocument() + }) + }) + + test('No stores text exists', async () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res(ctx.delay(0), ctx.status(200), ctx.json(mockNoStores)) + }) + ) + renderWithProviders( + + ) + + await waitFor(async () => { + const noLocations = screen.getByText(/Sorry, there are no locations in this area/i) + + expect(noLocations).toBeInTheDocument() + }) + }) + + test('Near your location text exists', async () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res( + ctx.delay(0), + ctx.status(200), + ctx.json(mockStoresTotalIsHigherThanLimit) + ) + }) + ) + + renderWithProviders( + + ) + + await waitFor(async () => { + const nearYourLocation = screen.getByText(/Viewing stores near your location/i) + + expect(nearYourLocation).toBeInTheDocument() + }) + }) + + test('Load More button exists when total stores is higher than display limit', async () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res( + ctx.delay(0), + ctx.status(200), + ctx.json(mockStoresTotalIsHigherThanLimit) + ) + }) + ) + screen.debug() + + renderWithProviders( + + ) + await waitFor(async () => { + const findButton = screen.getByRole('button', {name: /Find/i}) + const aStore = screen.getByText(/162 University Ave/i) + const loadMore = screen.getByText(/Load More/i) + expect(findButton).toBeInTheDocument() + expect(aStore).toBeInTheDocument() + expect(loadMore).toBeInTheDocument() + }) + }) + + test('Load More button doesnt exist when total stores is equal to display limit', async () => { + global.server.use( + rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => { + return res(ctx.delay(0), ctx.status(200), ctx.json(mockStoresTotalIsEqualToLimit)) + }) + ) + renderWithProviders( + + ) + await waitFor(() => { + const loadMore = screen.queryByText(/Load More/i) + expect(loadMore).not.toBeInTheDocument() + }) + }) +}) diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx new file mode 100644 index 0000000000..1200063e65 --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React, {useEffect, useContext} from 'react' +import {useIntl} from 'react-intl' +import PropTypes from 'prop-types' + +// Components +import { + Button, + InputGroup, + Select, + Box, + Input, + FormControl, + FormErrorMessage +} from '@chakra-ui/react' +import {AlertIcon} from '@salesforce/retail-react-app/app/components/icons' +import {Controller} from 'react-hook-form' + +// Others +import { + SUPPORTED_STORE_LOCATOR_COUNTRIES, + STORE_LOCATOR_NUM_STORES_PER_LOAD +} from '@salesforce/retail-react-app/app/constants' +import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' + +const useGeolocation = () => { + const { + setSearchStoresParams, + setAutomaticGeolocationHasFailed, + setUserHasSetManualGeolocation, + userHasSetManualGeolocation + } = useContext(StoreLocatorContext) + + const getGeolocationError = () => { + setAutomaticGeolocationHasFailed(true) + } + const getGeolocationSuccess = (position) => { + setAutomaticGeolocationHasFailed(false) + setSearchStoresParams({ + latitude: position.coords.latitude, + longitude: position.coords.longitude, + limit: STORE_LOCATOR_NUM_STORES_PER_LOAD + }) + } + + const getUserGeolocation = () => { + if (navigator?.geolocation) { + navigator.geolocation.getCurrentPosition(getGeolocationSuccess, getGeolocationError) + setUserHasSetManualGeolocation(false) + } else { + console.log('Geolocation not supported') + } + } + + useEffect(() => { + if (!userHasSetManualGeolocation) getUserGeolocation() + }, []) + + return getUserGeolocation +} + +const StoreLocatorInput = ({form, submitForm}) => { + const { + searchStoresParams, + userHasSetManualGeolocation, + automaticGeolocationHasFailed, + setUserWantsToShareLocation, + userWantsToShareLocation + } = useContext(StoreLocatorContext) + + const getUserGeolocation = useGeolocation() + const {control} = form + const intl = useIntl() + return ( +
+ + {SUPPORTED_STORE_LOCATOR_COUNTRIES.length > 0 && ( + { + return SUPPORTED_STORE_LOCATOR_COUNTRIES.length !== 0 ? ( + + + {form.formState.errors.countryCode && ( + + + )} + + ) : ( + <> + ) + }} + > + )} + + + { + return ( + + + {form.formState.errors.postalCode && ( + + + )} + + ) + }} + > + + + + {intl.formatMessage({ + id: 'store_locator.description.or', + defaultMessage: 'Or' + })} + + + + + + +
+ ) +} + +StoreLocatorInput.propTypes = { + form: PropTypes.object, + submitForm: PropTypes.func +} + +export default StoreLocatorInput diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.test.jsx b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.test.jsx new file mode 100644 index 0000000000..03d1c6880b --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.test.jsx @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React, {useEffect} from 'react' +import StoreLocatorInput from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-input' +import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils' +import {waitFor, screen} from '@testing-library/react' +import {useForm} from 'react-hook-form' +import PropTypes from 'prop-types' +import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +import {useStoreLocator} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +import {STORE_LOCATOR_NUM_STORES_PER_LOAD} from '@salesforce/retail-react-app/app/constants' + +const WrapperComponent = ({userHasSetManualGeolocation}) => { + const form = useForm({ + mode: 'onChange', + reValidateMode: 'onChange', + defaultValues: { + countryCode: 'DE', + postalCode: '10178' + } + }) + const storeLocator = useStoreLocator() + useEffect(() => { + storeLocator.setUserHasSetManualGeolocation(userHasSetManualGeolocation) + storeLocator.setSearchStoresParams({ + postalCode: '10178', + countryCode: 'DE', + limit: STORE_LOCATOR_NUM_STORES_PER_LOAD + }) + }, []) + + return ( + + + + ) +} +WrapperComponent.propTypes = { + storesInfo: PropTypes.array, + userHasSetManualGeolocation: PropTypes.bool, + getUserGeolocation: PropTypes.func +} + +describe('StoreLocatorInput', () => { + afterEach(() => { + jest.clearAllMocks() + jest.resetModules() + }) + test('Renders without crashing', () => { + expect(() => { + renderWithProviders( + + ) + }).not.toThrow() + }) + + test('Expected information exists', async () => { + renderWithProviders( + + ) + + await waitFor(async () => { + const findButton = screen.getByRole('button', {name: /Find/i}) + const useMyLocationButton = screen.getByRole('button', {name: /Use My Location/i}) + + expect(findButton).toBeInTheDocument() + expect(useMyLocationButton).toBeInTheDocument() + }) + }) +}) diff --git a/packages/extension-store-locator/src/components/store-locator-modal/stores-list.jsx b/packages/extension-store-locator/src/components/store-locator-modal/stores-list.jsx new file mode 100644 index 0000000000..865b0aff74 --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/stores-list.jsx @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React from 'react' +import {useIntl} from 'react-intl' +import PropTypes from 'prop-types' + +// Components +import {AccordionItem, AccordionButton, AccordionIcon, AccordionPanel, Box} from '@chakra-ui/react' + +const StoresList = ({storesInfo}) => { + const intl = useIntl() + + return storesInfo?.map((store, index) => { + return ( + + + {store.name ? {store.name} : ''} + + {store.address1} + + + {store.city}, {store.stateCode ? store.stateCode : ''} {store.postalCode} + + {store.distance !== undefined ? ( + <> +
+ + {store.distance} {store.distanceUnit}{' '} + {intl.formatMessage({ + id: 'store_locator.description.away', + defaultMessage: 'away' + })} + + + ) : ( + '' + )} + {store.phone !== undefined ? ( + <> +
+ + {intl.formatMessage({ + id: 'store_locator.description.phone', + defaultMessage: 'Phone:' + })}{' '} + {store.phone} + + + ) : ( + '' + )} + {store?.storeHours ? ( + <> + {' '} + + + {intl.formatMessage({ + id: 'store_locator.action.viewMore', + defaultMessage: 'View More' + })} + + + + +
+ {' '} + + ) : ( + '' + )} + + + ) + }) +} + +StoresList.propTypes = { + storesInfo: PropTypes.array +} + +export default StoresList diff --git a/packages/extension-store-locator/src/components/store-locator-modal/stores-list.test.jsx b/packages/extension-store-locator/src/components/store-locator-modal/stores-list.test.jsx new file mode 100644 index 0000000000..6f33297be2 --- /dev/null +++ b/packages/extension-store-locator/src/components/store-locator-modal/stores-list.test.jsx @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2021, salesforce.com, 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 + */ + +import React from 'react' +import StoresList from '@salesforce/retail-react-app/app/components/store-locator-modal/stores-list' +import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils' +import {waitFor, screen} from '@testing-library/react' +import userEvent from '@testing-library/user-event' +import {Accordion} from '@chakra-ui/react' + +const mockSearchStoresData = [ + { + address1: 'Kirchgasse 12', + city: 'Wiesbaden', + countryCode: 'DE', + distance: 0.74, + distanceUnit: 'km', + id: '00019', + inventoryId: 'inventory_m_store_store11', + latitude: 50.0826, + longitude: 8.24, + name: 'Wiesbaden Tech Depot', + phone: '+49 611 876543', + posEnabled: false, + postalCode: '65185', + storeHours: 'Monday 9 AM to 7 PM', + storeLocatorEnabled: true + }, + { + address1: 'Schaumainkai 63', + city: 'Frankfurt am Main', + countryCode: 'DE', + distance: 30.78, + distanceUnit: 'km', + id: '00002', + inventoryId: 'inventory_m_store_store4', + latitude: 50.097416, + longitude: 8.669059, + name: 'Frankfurt Electronics Store', + phone: '+49 69 111111111', + posEnabled: false, + postalCode: '60596', + storeHours: + 'Monday 10 AM–6 PM\nTuesday 10 AM–6 PM\nWednesday 10 AM–6 PM\nThursday 10 AM–9 PM\nFriday 10 AM–6 PM\nSaturday 10 AM–6 PM\nSunday 10 AM–6 PM', + storeLocatorEnabled: true + }, + { + address1: 'Löhrstraße 87', + city: 'Koblenz', + countryCode: 'DE', + distance: 55.25, + distanceUnit: 'km', + id: '00035', + inventoryId: 'inventory_m_store_store27', + latitude: 50.3533, + longitude: 7.5946, + name: 'Koblenz Electronics Store', + phone: '+49 261 123456', + posEnabled: false, + postalCode: '56068', + storeHours: + 'Monday 9 AM–7 PM\nTuesday 9 AM–7 PM\nWednesday 9 AM–7 PM\nThursday 9 AM–8 PM\nFriday 9 AM–7 PM\nSaturday 9 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + }, + { + address1: 'Hauptstraße 47', + city: 'Heidelberg', + countryCode: 'DE', + distance: 81.1, + distanceUnit: 'km', + id: '00021', + inventoryId: 'inventory_m_store_store13', + latitude: 49.4077, + longitude: 8.6908, + name: 'Heidelberg Tech Mart', + phone: '+49 6221 123456', + posEnabled: false, + postalCode: '69117', + storeHours: + 'Monday 10 AM–7 PM\nTuesday 10 AM–7 PM\nWednesday 10 AM–7 PM\nThursday 10 AM–8 PM\nFriday 10 AM–7 PM\nSaturday 10 AM–6 PM\nSunday Closed', + storeLocatorEnabled: true + } +] + +describe('StoresList', () => { + test('renders without crashing', () => { + expect(() => { + renderWithProviders( + + + + ) + }).not.toThrow() + }) + + test('Expected information exists', async () => { + renderWithProviders( + + + + ) + + await waitFor(async () => { + const aStoreName = screen.getByText(/Wiesbaden Tech Depot/i) + const aStoreAddress = screen.getByText(/Kirchgasse 12/i) + const aStoreCityAndPostalCode = screen.getByText(/Wiesbaden, 65185/i) + const aStoreDistance = screen.getByText(/0.74 km away/i) + const aStorePhoneNumber = screen.getByText(/49 611 876543/i) + + expect(aStoreName).toBeInTheDocument() + expect(aStoreAddress).toBeInTheDocument() + expect(aStoreCityAndPostalCode).toBeInTheDocument() + expect(aStoreDistance).toBeInTheDocument() + expect(aStorePhoneNumber).toBeInTheDocument() + }) + }) + + test('Clicking View More opens store hours', async () => { + renderWithProviders( + + + + ) + + await waitFor(async () => { + const viewMoreButtons = screen.getAllByRole('button', {name: /View More/i}) + + // Click on the first button + await userEvent.click(viewMoreButtons[0]) + + const aStoreOpenHours = screen.getByText(/Monday\s*9\s*AM\s*to\s*7\s*PM/i) + expect(aStoreOpenHours).toBeInTheDocument() + }) + }) + + test('Is sorted by distance away', async () => { + renderWithProviders( + + + + ) + await waitFor(async () => { + const numbers = [ + screen.getByText(/\s*0\.74\s*km\s*away\s*/), + screen.getByText(/\s*30\.78\s*km\s*away\s*/), + screen.getByText(/\s*55\.25\s*km\s*away\s*/), + screen.getByText(/\s*81\.1\s*km\s*away\s*/) + ] + + // Check that the numbers are in the document + numbers.forEach((number) => { + expect(number).toBeInTheDocument() + }) + + // Check that the numbers are in the correct order + const numberTexts = numbers.map((number) => number.textContent) + expect(numberTexts).toEqual([ + '0.74 km away', + '30.78 km away', + '55.25 km away', + '81.1 km away' + ]) + // Check that the numbers are in the correct visual order + const positions = numbers.map((number) => number.getBoundingClientRect().top) + expect(positions).toEqual([...positions].sort((a, b) => a - b)) + }) + }) +}) diff --git a/packages/extension-store-locator/src/pages/store-locator/index.tsx b/packages/extension-store-locator/src/pages/store-locator/index.tsx index 348a159deb..8666a84ddc 100644 --- a/packages/extension-store-locator/src/pages/store-locator/index.tsx +++ b/packages/extension-store-locator/src/pages/store-locator/index.tsx @@ -1,55 +1,39 @@ -// /* -// * Copyright (c) 2021, salesforce.com, 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 -// */ - -// import React from "react"; - -// // Components -// import { Box, Container } from "@chakra-ui/react"; -// import StoreLocatorContent from "@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-content"; - -// // Others -// import { -// StoreLocatorContext, -// useStoreLocator, -// } from "@salesforce/retail-react-app/app/components/store-locator-modal/index"; - -// const StoreLocator = () => { -// const storeLocator = useStoreLocator(); - -// return ( -// -// -// -// -// -// -// -// -// ); -// }; - -// StoreLocator.getTemplateName = () => "store-locator"; - -// StoreLocator.propTypes = {}; - -// export default StoreLocator; +/* + * Copyright (c) 2024, salesforce.com, 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 + */ import React from "react"; +import { Box, Container } from "@chakra-ui/react"; +import StoreLocatorContent from "../../components/store-locator-modal/store-locator-content"; +import { + StoreLocatorContext, + useStoreLocator, +} from "../../components/store-locator-modal/index"; + const StoreLocator = () => { - return

123

; + const storeLocator = useStoreLocator(); + + return ( + + + + + + + + ); }; StoreLocator.getTemplateName = () => "store-locator"; From bbf3cb1eba3b985347f2cd52480f90a3976df4bf Mon Sep 17 00:00:00 2001 From: Kevin He Date: Thu, 17 Oct 2024 17:34:36 -0700 Subject: [PATCH 157/929] add peer dependency - commerce-sdk-react --- .../extension-store-locator/package-lock.json | 358 ++++++++++++++---- packages/extension-store-locator/package.json | 15 +- 2 files changed, 296 insertions(+), 77 deletions(-) diff --git a/packages/extension-store-locator/package-lock.json b/packages/extension-store-locator/package-lock.json index 5b77fcd04b..dd4be89f37 100644 --- a/packages/extension-store-locator/package-lock.json +++ b/packages/extension-store-locator/package-lock.json @@ -21,10 +21,10 @@ "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" }, "peerDependencies": { - "@chakra-ui/react": "^2.10.3", - "@loadable/component": "^5.15.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "@chakra-ui/react": "^2", + "@loadable/component": "^5", + "react": "^18", + "react-dom": "^18" } }, "node_modules/@babel/code-frame": { @@ -32,6 +32,7 @@ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/highlight": "^7.25.7", @@ -46,6 +47,7 @@ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/types": "^7.25.7", @@ -62,6 +64,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/traverse": "^7.25.7", @@ -76,6 +79,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6.9.0" @@ -86,6 +90,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6.9.0" @@ -96,6 +101,7 @@ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.25.7", @@ -112,6 +118,7 @@ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/types": "^7.25.8" @@ -128,6 +135,7 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -140,6 +148,7 @@ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/code-frame": "^7.25.7", @@ -155,6 +164,7 @@ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/code-frame": "^7.25.7", @@ -169,36 +179,12 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "peer": true - }, "node_modules/@babel/types": { "version": "7.25.8", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.25.7", @@ -213,13 +199,15 @@ "version": "2.3.4", "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.3.4.tgz", "integrity": "sha512-fFIYN7L276gw0Q7/ikMMlZxP7mvnjRaWJ7f3Jsf9VtDOi6eAYIBRrhQe6+SZ0PGmoOkRaBc7gSE5oeIbgFFyrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@chakra-ui/hooks": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.4.2.tgz", "integrity": "sha512-LRKiVE1oA7afT5tbbSKAy7Uas2xFHE6IkrQdbhWCHmkHBUtPvjQQDgwtnd4IRZPmoEfNGwoJ/MQpwOM/NRTTwA==", "dev": true, + "license": "MIT", "dependencies": { "@chakra-ui/utils": "2.2.2", "@zag-js/element-size": "0.31.1", @@ -235,6 +223,7 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.10.3.tgz", "integrity": "sha512-oWmGGzzKWBfoB3hrrQxWwFirlxJXGdk3v4SLnLPPYRy9IMibmQM5rAUJ/NxZum1mrYGP5lo7DHcIWDfV2A3ubw==", "dev": true, + "license": "MIT", "dependencies": { "@chakra-ui/hooks": "2.4.2", "@chakra-ui/styled-system": "2.12.0", @@ -260,6 +249,7 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.12.0.tgz", "integrity": "sha512-zoqLw1I2y4GlZ0LDoyw8o0JjoDOW6u0IwFPAoHuw0UMbP8glHUGvwEL1STug/i/GzBKw83yoF6ae41HIQvhMww==", "dev": true, + "license": "MIT", "dependencies": { "@chakra-ui/utils": "2.2.2", "csstype": "^3.1.2" @@ -270,6 +260,7 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.4.6.tgz", "integrity": "sha512-ZwFBLfiMC3URwaO31ONXoKH9k0TX0OW3UjdPF3EQkQpYyrk/fm36GkkzajjtdpWEd7rzDLRsQjPmvwNaSoNDtg==", "dev": true, + "license": "MIT", "dependencies": { "@chakra-ui/anatomy": "2.3.4", "@chakra-ui/theme-tools": "2.2.6", @@ -284,6 +275,7 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.2.6.tgz", "integrity": "sha512-3UhKPyzKbV3l/bg1iQN9PBvffYp+EBOoYMUaeTUdieQRPFzo2jbYR0lNCxqv8h5aGM/k54nCHU2M/GStyi9F2A==", "dev": true, + "license": "MIT", "dependencies": { "@chakra-ui/anatomy": "2.3.4", "@chakra-ui/utils": "2.2.2", @@ -298,6 +290,7 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.2.2.tgz", "integrity": "sha512-jUPLT0JzRMWxpdzH6c+t0YMJYrvc5CLericgITV3zDSXblkfx3DsYXqU11DJTSGZI9dUKzM1Wd0Wswn4eJwvFQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/lodash.mergewith": "4.6.9", "lodash.mergewith": "4.6.2" @@ -311,6 +304,7 @@ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.16.7", @@ -331,6 +325,7 @@ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@emotion/memoize": "^0.9.0", @@ -345,6 +340,7 @@ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@emotion/is-prop-valid": { @@ -352,6 +348,7 @@ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@emotion/memoize": "^0.9.0" @@ -362,6 +359,7 @@ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@emotion/react": { @@ -369,6 +367,7 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", @@ -394,6 +393,7 @@ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@emotion/hash": "^0.9.2", @@ -408,6 +408,7 @@ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@emotion/styled": { @@ -415,6 +416,7 @@ "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", @@ -439,6 +441,7 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { @@ -446,6 +449,7 @@ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", "dev": true, + "license": "MIT", "peer": true, "peerDependencies": { "react": ">=16.8.0" @@ -456,6 +460,7 @@ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@emotion/weak-memoize": { @@ -463,6 +468,7 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@jridgewell/gen-mapping": { @@ -470,6 +476,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -485,6 +492,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6.0.0" @@ -495,6 +503,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6.0.0" @@ -505,6 +514,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@jridgewell/trace-mapping": { @@ -512,6 +522,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -523,6 +534,7 @@ "resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.16.4.tgz", "integrity": "sha512-fJWxx9b5WHX90QKmizo9B+es2so8DnBthI1mbflwCoOyvzEwxiZ/SVDCTtXEnHG72/kGBdzr297SSIekYtzSOQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.18", "hoist-non-react-statics": "^3.3.1", @@ -544,6 +556,7 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -553,13 +566,15 @@ "version": "4.17.10", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/lodash.mergewith": { "version": "4.6.9", "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.9.tgz", "integrity": "sha512-fgkoCAOF47K7sxrQ7Mlud2TH023itugZs2bUg8h/KzT+BnZNrR2jAOmaokbLunHNnobXVWOezAeNn/lZqwxkcw==", "dev": true, + "license": "MIT", "dependencies": { "@types/lodash": "*" } @@ -569,19 +584,22 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/prop-types": { "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/react": { "version": "18.2.79", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", "dev": true, + "license": "MIT", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -592,6 +610,7 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz", "integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } @@ -600,19 +619,22 @@ "version": "0.31.1", "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.31.1.tgz", "integrity": "sha512-oiuohEXAXhBxpzzNm9k2VHGEOLC1SXlXSbRPcfBZ9so5NRQUA++zCE7cyQJqGLTZR0t3itFLlZqDbYEXRrefwg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@zag-js/element-size": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.31.1.tgz", "integrity": "sha512-4T3yvn5NqqAjhlP326Fv+w9RqMIBbNN9H72g5q2ohwzhSgSfZzrKtjL4rs9axY/cw9UfMfXjRjEE98e5CMq7WQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@zag-js/focus-visible": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.31.1.tgz", "integrity": "sha512-dbLksz7FEwyFoANbpIlNnd3bVm0clQSUsnP8yUVQucStZPsuWjCrhL2jlAbGNrTrahX96ntUMXHb/sM68TibFg==", "dev": true, + "license": "MIT", "dependencies": { "@zag-js/dom-query": "0.31.1" } @@ -622,6 +644,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -635,6 +658,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "color-convert": "^1.9.0" @@ -648,6 +672,7 @@ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -659,13 +684,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.12.5", @@ -682,6 +709,7 @@ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -701,11 +729,29 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -715,6 +761,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -734,6 +781,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=6" @@ -744,6 +792,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "ansi-styles": "^3.2.1", @@ -759,6 +808,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=0.8.0" @@ -769,6 +819,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "color-name": "1.1.3" @@ -779,19 +830,22 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/color2k": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -804,6 +858,7 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -813,6 +868,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/cookie": { @@ -820,6 +876,7 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -828,13 +885,15 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/copy-to-clipboard": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", "dev": true, + "license": "MIT", "dependencies": { "toggle-selection": "^1.0.6" } @@ -844,6 +903,7 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/parse-json": "^4.0.0", @@ -860,15 +920,26 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/define-data-property": { @@ -876,6 +947,7 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -893,6 +965,7 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -902,6 +975,7 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -911,19 +985,22 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -933,6 +1010,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "is-arrayish": "^0.2.1" @@ -943,6 +1021,7 @@ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -955,6 +1034,7 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -963,13 +1043,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=10" @@ -983,6 +1065,7 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -992,6 +1075,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -1029,11 +1113,29 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/finalhandler": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -1047,11 +1149,29 @@ "node": ">= 0.8" } }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/focus-lock": { @@ -1059,6 +1179,7 @@ "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.5.tgz", "integrity": "sha512-QFaHbhv9WPUeLYBDe/PAuLKJ4Dd9OPvKs9xZBr3yLXnUrDNaVXKu2baDBXe3naPY30hgHYSsf2JW4jzas2mDEQ==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.3" }, @@ -1071,6 +1192,7 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1080,6 +1202,7 @@ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.9.tgz", "integrity": "sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "tslib": "^2.4.0" @@ -1106,6 +1229,7 @@ "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz", "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "2.4.0" } @@ -1114,13 +1238,15 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1130,6 +1256,7 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1139,6 +1266,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -1158,6 +1286,7 @@ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1167,6 +1296,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=4" @@ -1177,6 +1307,7 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -1189,6 +1320,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=4" @@ -1199,6 +1331,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -1211,6 +1344,7 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1223,6 +1357,7 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1235,6 +1370,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -1247,6 +1383,7 @@ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" } @@ -1256,6 +1393,7 @@ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -1272,6 +1410,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -1284,6 +1423,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "parent-module": "^1.0.0", @@ -1300,13 +1440,15 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" } @@ -1316,6 +1458,7 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -1325,6 +1468,7 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/is-core-module": { @@ -1332,6 +1476,7 @@ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "hasown": "^2.0.2" @@ -1347,13 +1492,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "peer": true, "bin": { "jsesc": "bin/jsesc" @@ -1367,6 +1514,7 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/lines-and-columns": { @@ -1374,19 +1522,22 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -1399,6 +1550,7 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1408,6 +1560,7 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -1417,6 +1570,7 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1426,6 +1580,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -1438,6 +1593,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1447,6 +1603,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -1455,16 +1612,18 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1474,6 +1633,7 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1483,6 +1643,7 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1495,6 +1656,7 @@ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -1507,6 +1669,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "callsites": "^3.0.0" @@ -1520,6 +1683,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", @@ -1539,6 +1703,7 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1548,19 +1713,22 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/path-to-regexp": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=8" @@ -1571,6 +1739,7 @@ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, + "license": "ISC", "peer": true }, "node_modules/prop-types": { @@ -1578,6 +1747,7 @@ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -1589,6 +1759,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -1602,6 +1773,7 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -1617,6 +1789,7 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1626,6 +1799,7 @@ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -1641,6 +1815,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -1653,6 +1828,7 @@ "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13" }, @@ -1665,6 +1841,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -1677,13 +1854,15 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/react-focus-lock": { "version": "2.13.2", "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.2.tgz", "integrity": "sha512-T/7bsofxYqnod2xadvuwjGKHOoL5GH7/EIPI5UyEvaU/c2CcphvGI371opFtuY/SYdbMsNiuF4HsHQ50nA/TKQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.0.0", "focus-lock": "^1.3.5", @@ -1706,13 +1885,15 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/react-remove-scroll": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", "dev": true, + "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.6", "react-style-singleton": "^2.2.1", @@ -1738,6 +1919,7 @@ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", "dev": true, + "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.1", "tslib": "^2.0.0" @@ -1760,6 +1942,7 @@ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", "dev": true, + "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", "invariant": "^2.2.4", @@ -1782,13 +1965,15 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "is-core-module": "^2.13.0", @@ -1807,6 +1992,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=4" @@ -1830,19 +2016,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } @@ -1852,6 +2041,7 @@ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -1871,26 +2061,39 @@ "node": ">= 0.8.0" } }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, + "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -1906,6 +2109,7 @@ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -1922,13 +2126,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -1947,6 +2153,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, + "license": "BSD-3-Clause", "peer": true, "engines": { "node": ">=0.10.0" @@ -1957,6 +2164,7 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1966,6 +2174,7 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/supports-color": { @@ -1973,6 +2182,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "has-flag": "^3.0.0" @@ -1986,6 +2196,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">= 0.4" @@ -1999,6 +2210,7 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=4" @@ -2008,13 +2220,15 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6" } @@ -2023,13 +2237,15 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -2043,6 +2259,7 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2052,6 +2269,7 @@ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -2073,6 +2291,7 @@ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "dev": true, + "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -2095,6 +2314,7 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -2104,6 +2324,7 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2113,6 +2334,7 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, + "license": "ISC", "peer": true, "engines": { "node": ">= 6" diff --git a/packages/extension-store-locator/package.json b/packages/extension-store-locator/package.json index 4b5c98e8ac..5e85fad79d 100644 --- a/packages/extension-store-locator/package.json +++ b/packages/extension-store-locator/package.json @@ -3,16 +3,16 @@ "version": "1.0.0-dev", "scripts": {}, "peerDependencies": { - "@chakra-ui/react": "^2.10.3", - "@loadable/component": "^5.15.3", - "@salesforce/commerce-sdk-react": "3.1.0-dev", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "@chakra-ui/react": "^2", + "@loadable/component": "^5", + "@salesforce/commerce-sdk-react": "^3.1.0-dev", + "react": "^18", + "react-dom": "^18" }, "devDependencies": { "@chakra-ui/react": "^2.10.3", "@loadable/component": "^5.15.3", - "@salesforce/commerce-sdk-react": "3.1.0-dev", + "@salesforce/commerce-sdk-react": "^3.1.0-dev", "@salesforce/pwa-kit-react-sdk": "4.0.0-dev", "@salesforce/pwa-kit-runtime": "4.0.0-dev", "@types/react": "~18.2.0", @@ -24,8 +24,5 @@ "engines": { "node": "^16.11.0 || ^18.0.0 || ^20.0.0", "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" - }, - "dependencies": { - "@salesforce/commerce-sdk-react": "^3.1.0-dev" } } From ffc8451875333dcc9dded490317c5414c669fdcb Mon Sep 17 00:00:00 2001 From: Kevin He Date: Thu, 17 Oct 2024 17:52:20 -0700 Subject: [PATCH 158/929] add peer dependencies, clean import statements --- .../extension-store-locator/package-lock.json | 495 +++++++++++++++++- packages/extension-store-locator/package.json | 8 +- .../index.jsx | 22 +- .../index.test.jsx | 0 .../store-locator-content.jsx | 29 +- .../store-locator-content.test.jsx | 0 .../store-locator-input.jsx | 26 +- .../store-locator-input.test.jsx | 0 .../stores-list.jsx | 4 +- .../stores-list.test.jsx | 0 .../src/pages/store-locator/index.tsx | 4 +- 11 files changed, 531 insertions(+), 57 deletions(-) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/index.jsx (88%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/index.test.jsx (100%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/store-locator-content.jsx (91%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/store-locator-content.test.jsx (100%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/store-locator-input.jsx (93%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/store-locator-input.test.jsx (100%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/stores-list.jsx (98%) rename packages/extension-store-locator/src/components/{store-locator-modal => store-locator}/stores-list.test.jsx (100%) diff --git a/packages/extension-store-locator/package-lock.json b/packages/extension-store-locator/package-lock.json index dd4be89f37..c052be5bbf 100644 --- a/packages/extension-store-locator/package-lock.json +++ b/packages/extension-store-locator/package-lock.json @@ -13,8 +13,10 @@ "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "express": "^4.19.2", + "prop-types": "^15.8.1", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-intl": "^5.25.1" }, "engines": { "node": "^16.11.0 || ^18.0.0 || ^20.0.0", @@ -23,6 +25,8 @@ "peerDependencies": { "@chakra-ui/react": "^2", "@loadable/component": "^5", + "@salesforce/commerce-sdk-react": "^3.1.0-dev", + "prop-types": "^15.8.1", "react": "^18", "react-dom": "^18" } @@ -134,7 +138,7 @@ "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -471,6 +475,108 @@ "license": "MIT", "peer": true }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz", + "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/intl-localematcher": "0.2.25", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", + "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz", + "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/icu-skeleton-parser": "1.3.6", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz", + "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.2.1.tgz", + "integrity": "sha512-vgvyUOOrzqVaOFYzTf2d3+ToSkH2JpR7x/4U1RyoHQLmvEaTQvXJ7A2qm1Iy3brGNXC/+/7bUlc3lpH+h/LOJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/fast-memoize": "1.2.1", + "@formatjs/icu-messageformat-parser": "2.1.0", + "@formatjs/intl-displaynames": "5.4.3", + "@formatjs/intl-listformat": "6.5.3", + "intl-messageformat": "9.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "typescript": "^4.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@formatjs/intl-displaynames": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-5.4.3.tgz", + "integrity": "sha512-4r12A3mS5dp5hnSaQCWBuBNfi9Amgx2dzhU4lTFfhSxgb5DOAiAbMpg6+7gpWZgl4ahsj3l2r/iHIjdmdXOE2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/intl-localematcher": "0.2.25", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl-listformat": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.3.tgz", + "integrity": "sha512-ozpz515F/+3CU+HnLi5DYPsLa6JoCfBggBSSg/8nOB5LYSFW9+ZgNQJxJ8tdhKYeODT+4qVHX27EeJLoxLGLNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/intl-localematcher": "0.2.25", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz", + "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -562,6 +668,81 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@salesforce/commerce-sdk-react": { + "version": "3.1.0-nightly-20241017080159", + "resolved": "https://registry.npmjs.org/@salesforce/commerce-sdk-react/-/commerce-sdk-react-3.1.0-nightly-20241017080159.tgz", + "integrity": "sha512-uxAftgQbyTns+LNUVEhVD7BuK7wF/5OSRb+wlJyGmdKFLuXUjfidOf3+lCCoSMdIV/2FC7RdttWCurInRSsoUQ==", + "license": "See license in LICENSE", + "peer": true, + "dependencies": { + "commerce-sdk-isomorphic": "^3.1.1", + "js-cookie": "^3.0.1", + "jwt-decode": "^4.0.0" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0" + }, + "optionalDependencies": { + "prop-types": "^15.8.1", + "react-router-dom": "^5.3.4" + }, + "peerDependencies": { + "@tanstack/react-query": "^4.28.0", + "react": "^18.2.0", + "react-helmet": "^6.1.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "4.36.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.36.1.tgz", + "integrity": "sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==", + "license": "MIT", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.36.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.36.1.tgz", + "integrity": "sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tanstack/query-core": "4.36.1", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", @@ -840,6 +1021,25 @@ "dev": true, "license": "MIT" }, + "node_modules/commerce-sdk-isomorphic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/commerce-sdk-isomorphic/-/commerce-sdk-isomorphic-3.1.1.tgz", + "integrity": "sha512-DFOXLiLlEW3oiWunRbPqGYt5Dxypgre8wMiBBpF/SDsc3GX+AURydeVA5FbsT9WsGw6Y9O3FUV4Djy2l60Pr0A==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "nanoid": "^3.3.4", + "node-fetch": "2.6.12", + "seedrandom": "^3.0.5" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -1378,11 +1578,27 @@ "node": ">= 0.4" } }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" @@ -1443,6 +1659,19 @@ "dev": true, "license": "ISC" }, + "node_modules/intl-messageformat": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz", + "integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/fast-memoize": "1.2.1", + "@formatjs/icu-messageformat-parser": "2.1.0", + "tslib": "^2.1.0" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -1488,11 +1717,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=14" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/jsesc": { @@ -1517,6 +1763,16 @@ "license": "MIT", "peer": true }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -1536,7 +1792,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -1618,6 +1873,25 @@ "dev": true, "license": "MIT" }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -1628,11 +1902,31 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "license": "MIT", + "peer": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -1746,7 +2040,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -1814,7 +2107,6 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -1840,7 +2132,6 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -1854,7 +2145,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "dev": true, "license": "MIT" }, "node_modules/react-focus-lock": { @@ -1881,11 +2171,54 @@ } } }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "license": "MIT", + "peer": true, + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/react-intl": { + "version": "5.25.1", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.25.1.tgz", + "integrity": "sha512-pkjdQDvpJROoXLMltkP/5mZb0/XqrqLoPGKUCfbdkP8m6U9xbK40K51Wu+a4aQqTEvEK5lHBk0fWzUV72SJ3Hg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/icu-messageformat-parser": "2.1.0", + "@formatjs/intl": "2.2.1", + "@formatjs/intl-displaynames": "5.4.3", + "@formatjs/intl-listformat": "6.5.3", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/react": "16 || 17 || 18", + "hoist-non-react-statics": "^3.3.2", + "intl-messageformat": "9.13.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "react": "^16.3.0 || 17 || 18", + "typescript": "^4.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, "node_modules/react-remove-scroll": { @@ -1937,6 +2270,69 @@ } } }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router/node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -1965,7 +2361,7 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/resolve": { @@ -1998,6 +2394,14 @@ "node": ">=4" } }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2030,12 +2434,18 @@ "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "license": "MIT", + "peer": true + }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -2205,6 +2615,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -2233,6 +2659,13 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT", + "peer": true + }, "node_modules/tslib": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", @@ -2309,6 +2742,16 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -2319,6 +2762,14 @@ "node": ">= 0.4.0" } }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2329,6 +2780,24 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "peer": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", diff --git a/packages/extension-store-locator/package.json b/packages/extension-store-locator/package.json index 5e85fad79d..ef1ec19581 100644 --- a/packages/extension-store-locator/package.json +++ b/packages/extension-store-locator/package.json @@ -6,8 +6,10 @@ "@chakra-ui/react": "^2", "@loadable/component": "^5", "@salesforce/commerce-sdk-react": "^3.1.0-dev", + "prop-types": "^15", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "react-intl": "^5" }, "devDependencies": { "@chakra-ui/react": "^2.10.3", @@ -18,8 +20,10 @@ "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "express": "^4.19.2", + "prop-types": "^15.8.1", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-intl": "^5.25.1" }, "engines": { "node": "^16.11.0 || ^18.0.0 || ^20.0.0", diff --git a/packages/extension-store-locator/src/components/store-locator-modal/index.jsx b/packages/extension-store-locator/src/components/store-locator/index.jsx similarity index 88% rename from packages/extension-store-locator/src/components/store-locator-modal/index.jsx rename to packages/extension-store-locator/src/components/store-locator/index.jsx index 48008b060f..cd746eb0e9 100644 --- a/packages/extension-store-locator/src/components/store-locator-modal/index.jsx +++ b/packages/extension-store-locator/src/components/store-locator/index.jsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, salesforce.com, inc. + * Copyright (c) 2024, salesforce.com, 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 @@ -7,8 +7,6 @@ import React, {useState, createContext} from 'react' import PropTypes from 'prop-types' - -// Components import { Modal, ModalBody, @@ -16,14 +14,18 @@ import { ModalContent, useBreakpointValue } from '@chakra-ui/react' -import StoreLocatorContent from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-content' +import StoreLocatorContent from './store-locator-content' +// todo make these configs +const DEFAULT_STORE_LOCATOR_COUNTRY = { + countryCode: 'DE', + countryName: 'Germany' +} +const DEFAULT_STORE_LOCATOR_POSTAL_CODE = '10178' +const STORE_LOCATOR_DISTANCE = 100 +const STORE_LOCATOR_NUM_STORES_PER_LOAD = 10 +const STORE_LOCATOR_DISTANCE_UNIT = 'km' +const STORE_LOCATOR_IS_ENABLED = true -// Others -import { - DEFAULT_STORE_LOCATOR_COUNTRY, - DEFAULT_STORE_LOCATOR_POSTAL_CODE, - STORE_LOCATOR_NUM_STORES_PER_LOAD -} from '@salesforce/retail-react-app/app/constants' export const StoreLocatorContext = createContext() export const useStoreLocator = () => { diff --git a/packages/extension-store-locator/src/components/store-locator-modal/index.test.jsx b/packages/extension-store-locator/src/components/store-locator/index.test.jsx similarity index 100% rename from packages/extension-store-locator/src/components/store-locator-modal/index.test.jsx rename to packages/extension-store-locator/src/components/store-locator/index.test.jsx diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx b/packages/extension-store-locator/src/components/store-locator/store-locator-content.jsx similarity index 91% rename from packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx rename to packages/extension-store-locator/src/components/store-locator/store-locator-content.jsx index 0883ec7550..a4066328a5 100644 --- a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.jsx +++ b/packages/extension-store-locator/src/components/store-locator/store-locator-content.jsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, salesforce.com, inc. + * Copyright (c) 2024, salesforce.com, 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 @@ -7,29 +7,28 @@ import React, {useState, useContext} from 'react' import {useIntl} from 'react-intl' - -// Components import {Heading, Accordion, AccordionItem, Box, Button} from '@chakra-ui/react' -import StoresList from '@salesforce/retail-react-app/app/components/store-locator-modal/stores-list' -import StoreLocatorInput from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-input' +import StoresList from './stores-list' +import StoreLocatorInput from './store-locator-input' -// Others -import { - SUPPORTED_STORE_LOCATOR_COUNTRIES, - DEFAULT_STORE_LOCATOR_COUNTRY, - STORE_LOCATOR_DISTANCE, - STORE_LOCATOR_NUM_STORES_PER_LOAD, - STORE_LOCATOR_DISTANCE_UNIT -} from '@salesforce/retail-react-app/app/constants' +// todo make these configs +const DEFAULT_STORE_LOCATOR_COUNTRY = { + countryCode: 'DE', + countryName: 'Germany' +} +const DEFAULT_STORE_LOCATOR_POSTAL_CODE = '10178' +const STORE_LOCATOR_DISTANCE = 100 +const STORE_LOCATOR_NUM_STORES_PER_LOAD = 10 +const STORE_LOCATOR_DISTANCE_UNIT = 'km' +const STORE_LOCATOR_IS_ENABLED = true //This is an API limit and is therefore not configurable const NUM_STORES_PER_REQUEST_API_MAX = 200 -// Hooks import {useSearchStores} from '@salesforce/commerce-sdk-react' import {useForm} from 'react-hook-form' -import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +import {StoreLocatorContext} from './index' const StoreLocatorContent = () => { const { diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.test.jsx b/packages/extension-store-locator/src/components/store-locator/store-locator-content.test.jsx similarity index 100% rename from packages/extension-store-locator/src/components/store-locator-modal/store-locator-content.test.jsx rename to packages/extension-store-locator/src/components/store-locator/store-locator-content.test.jsx diff --git a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx b/packages/extension-store-locator/src/components/store-locator/store-locator-input.jsx similarity index 93% rename from packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx rename to packages/extension-store-locator/src/components/store-locator/store-locator-input.jsx index 1200063e65..b8cba212ef 100644 --- a/packages/extension-store-locator/src/components/store-locator-modal/store-locator-input.jsx +++ b/packages/extension-store-locator/src/components/store-locator/store-locator-input.jsx @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, salesforce.com, inc. + * Copyright (c) 2024, salesforce.com, 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 @@ -8,8 +8,6 @@ import React, {useEffect, useContext} from 'react' import {useIntl} from 'react-intl' import PropTypes from 'prop-types' - -// Components import { Button, InputGroup, @@ -19,15 +17,19 @@ import { FormControl, FormErrorMessage } from '@chakra-ui/react' -import {AlertIcon} from '@salesforce/retail-react-app/app/components/icons' +// import {AlertIcon} from '@salesforce/retail-react-app/app/components/icons' import {Controller} from 'react-hook-form' - -// Others -import { - SUPPORTED_STORE_LOCATOR_COUNTRIES, - STORE_LOCATOR_NUM_STORES_PER_LOAD -} from '@salesforce/retail-react-app/app/constants' -import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal/index' +// todo make these configs +const DEFAULT_STORE_LOCATOR_COUNTRY = { + countryCode: 'DE', + countryName: 'Germany' +} +const DEFAULT_STORE_LOCATOR_POSTAL_CODE = '10178' +const STORE_LOCATOR_DISTANCE = 100 +const STORE_LOCATOR_NUM_STORES_PER_LOAD = 10 +const STORE_LOCATOR_DISTANCE_UNIT = 'km' +const STORE_LOCATOR_IS_ENABLED = true +import {StoreLocatorContext} from './index' const useGeolocation = () => { const { @@ -120,7 +122,7 @@ const StoreLocatorInput = ({form, submitForm}) => { sx={{marginBottom: '10px'}} color="red.600" > -