From 5fd0b2b8a506a78385c76d6efc4e47ca5077139d Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 25 Apr 2025 13:59:39 -0700 Subject: [PATCH 1/9] Initial implementation --- packages/extension-starter/.force_overrides | 11 + .../components/content.tsx | 16 + .../pwa-kit-dev/src/configs/webpack/config.js | 8 +- .../webpack/overrides-resolver-loader.ts | 102 +- .../src/configs/webpack/types.ts | 7 + .../.force_overrides | 2 +- .../package-lock.json | 981 ++++++++++++++++++ .../template-typescript-minimal/package.json | 47 +- 8 files changed, 1148 insertions(+), 26 deletions(-) create mode 100644 packages/extension-starter/.force_overrides create mode 100644 packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx diff --git a/packages/extension-starter/.force_overrides b/packages/extension-starter/.force_overrides new file mode 100644 index 0000000000..b184679956 --- /dev/null +++ b/packages/extension-starter/.force_overrides @@ -0,0 +1,11 @@ +// DISCLAIMER +// +// BY USING THIS FILE, YOU AGREE THAT THE FUNCTIONALITY OF YOUR INSTALLED EXTENSION(S) IS NOT GUARANTEED. +// ADDITIONALLY UPGRADABILITY OF EXTENSIONS CAN ALSO NO LONGER BE GUARANTEED AND IS NOT SUPPORTED BY SALESFORCE. +// USE ONLY AS A TEMPORARY SOLUTION TO URGENTLY PATCH/UPDATE AN EXTENSION. +// +// USAGE: +// PLACE THE RELATIVE __POSIX__ PATH TO THE EXTENSION FILE YOU WANT TO OVERRIDE STARTING WITH THE EXTENSION PACKAGE NAME. +// MULTIPLE OVERRIDES CAN BE ADDED TO THIS FILE, ONE PER LINE. +// EXAMPLE: +./node_modules/@salesforce/extension-chakra-store-locator/src/components/content.tsx \ No newline at end of file diff --git a/packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx b/packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx new file mode 100644 index 0000000000..1a26085991 --- /dev/null +++ b/packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx @@ -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 + */ + +import React from 'react' + +export const StoreLocatorContent = (): JSX.Element => { + return ( + <> +
hello
+ + ) +} diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index be985a8793..15392d2102 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -150,6 +150,7 @@ const baseConfig = (target) => { throw Error(`The value "${target}" is not a supported webpack target`) } + const extensions = getConfiguredExtensions(getConfig()) class Builder { constructor() { this.config = { @@ -273,7 +274,12 @@ const baseConfig = (target) => { target: 'node' } }), - ruleForOverrideResolver({target, projectDir, isMonoRepo}) + ruleForOverrideResolver({ + extensions, + isMonoRepo, + projectDir, + target + }) ].filter(Boolean) } } diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts index a5d1a4407d..60d72297c4 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts @@ -14,10 +14,11 @@ import resolve from 'resolve' import {buildCandidatePaths, getPackageName, SETUP_FILE_REGEX} from '../../shared/utils' // Types -import type {ExtendedCompiler} from './types' +import type {ExtendedCompiler, OverridesResolverRuleOptions} from './types' import type {OverrideStatsEntry} from './override-stats-plugin' // Constants +const LOCAL_EXTENSIONS_DIR = 'application-extensions' const EXTENSION_PACKAGE_PREFIX = 'extension-' const EXTENSION_PACKAGE_NAMESPACE = '@salesforce' const IMPORT_REGEX = /import\s+(?:(?:[\w*\s{},]*)\s+from\s+)?['"](\..*?)['"]/g @@ -71,9 +72,13 @@ const OverrideResolverLoader = function (this: LoaderContext) { // Lets use the compiler configuration to ensure we are resolving the correct file extensions. const compilerOptions = this._compiler?.options - const extensions = compilerOptions?.resolve?.extensions || [] + + // const extensions = compilerOptions?.resolve?.extensions || [] + const extensions = [ '.ts', '.tsx', '.js', '.jsx', '.json' ] const basedir = options?.baseDir || process.cwd() - const applicationExtensions = compiler?.custom?.extensions || [] + const applicationExtensions = options?.extensions || compiler?.custom?.extensions || [] + console.log('extensions: ', extensions) + // Get the master list of all possible candidate paths based on your current extension configuration. const paths = buildCandidatePaths(projectRelPath, packageName, { @@ -82,6 +87,7 @@ const OverrideResolverLoader = function (this: LoaderContext) { extensionEntries: applicationExtensions }) + // Also include the base override path and the path from the extension doing the import. const resolvedResourcePath = resolve.sync(projectRelPath, { basedir, @@ -90,6 +96,14 @@ const OverrideResolverLoader = function (this: LoaderContext) { ...options?.resolveOptions }) + + if (projectRelPath.includes('content')) { + console.log('Extensions: ', applicationExtensions) + console.log('Paths: ', paths) + console.log('Resolved Resource Path: ', resolvedResourcePath) + console.log('File Extensions: ', extensions) + } + // Record override stats if RECORD_OVERRIDES is enabled if (this._compilation && 'overrideStats' in this._compilation) { const compilation = this._compilation as {overrideStats: OverrideStatsEntry[]} @@ -205,31 +219,72 @@ export const validateOverrideSource = (source: string, options: any = {}) => { return hasOverride } +/** + * Reads and parses a .force_overrides file into a list of clean override entries. + * - Skips empty lines + * - Skips full-line comments (`// comment`) + * - Supports inline comments (`override // comment`) + */ +const getOverridesFromFile = (filePath: string): string[] => { + try { + const content = fse.readFileSync(filePath, 'utf8') + return content + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith('//')) + .map((line) => line.split('//')[0].trim()) // remove inline comments + .filter(Boolean) + } catch (e: any) { + if (e.code !== 'ENOENT') { + console.warn(`Error reading override file at ${filePath}:`, e) + } + return [] + } +} + /** * Generates a Webpack rule for application extensibility, configuring the loader for * handling application extensions based on the target (e.g., 'node' for server-side, * 'web' for client-side). Specifically this enables the ability to override the resolution * via the `.force_overrides` file. * - * @param {Object} [options={}] - Options to customize the Webpack rule. - * @param {string} [options.projectDir] - Loader-specific options. - * @param {string} [options.target=DEFAULT_TARGET] - The target environment, either 'node' or 'web'. - * @param {boolean} [options.isMonoRepo] - Changes the source path normalization based on if the project is run in a mono-repo. - * + * @param {RuleOptions} options - Options to customize the Webpack rule. * @returns {Object} A Webpack rule configuration object for handling application extensions. */ -export const ruleForOverrideResolver = (options: any = {}) => { - const {projectDir, target, isMonoRepo} = options - let overridables: string[] = [] - - try { - overridables = fse - .readFileSync(path.join(projectDir, OVERRIDABLE_FILE_NAME), 'utf8') - .split(/\r?\n/) - .filter((line) => !line.startsWith('//')) - } catch (e) { - // If where is no .force_overrides file, we can safely return null. - return null +export const ruleForOverrideResolver = (options: OverridesResolverRuleOptions): object => { + const {extensions = [], projectDir, target = 'web', isMonoRepo = false} = options + const overridablesSet = new Set() + + // Determine possible locations for the .force_overrides files in the project. Please note that + // and extension can't exists as a node_module and a local package, but for simplicity sake we'll use for + // for candidate locations prioritizing the local package. + const forceOverridesFilePaths: string[] = [ + path.join(projectDir, OVERRIDABLE_FILE_NAME), + ...extensions + .map((ext) => [ + path.join( + projectDir, + LOCAL_EXTENSIONS_DIR, + typeof ext === 'string' ? ext : ext[0], + OVERRIDABLE_FILE_NAME + ), + path.join( + projectDir, + NODE_MODULES_FOLDER, + typeof ext === 'string' ? ext : ext[0], + OVERRIDABLE_FILE_NAME + ) + ]) + .flat() + ] + + // Create a "master" list of all the overrides in the project. + // NOTE: That files defined in an extensions .force_overrides file will technically leak outside ot its scope + // allowing other extensions to now override those extensions as well. This isn't ideal, but fo this initial version + // we can go with it. + for (const filePath of forceOverridesFilePaths) { + const overrides = getOverridesFromFile(filePath) + overrides.forEach((entry) => overridablesSet.add(entry)) } return { @@ -237,11 +292,14 @@ export const ruleForOverrideResolver = (options: any = {}) => { return validateOverrideSource(source, { isMonoRepo, target, - overridables + overridables: Array.from(overridablesSet) }) }, use: { - loader: '@salesforce/pwa-kit-extension-sdk/configs/webpack/overrides-resolver-loader' + loader: '@salesforce/pwa-kit-extension-sdk/configs/webpack/overrides-resolver-loader', + options: { + extensions + } } } } diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts index 61ed428523..70fb6aa351 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts @@ -25,3 +25,10 @@ export type ExtendedCompiler = Compiler & { extensions: any[] } } + +export interface OverridesResolverRuleOptions { + extensions?: ApplicationExtensionEntry[] + projectDir: string + target?: string + isMonoRepo?: boolean +} diff --git a/packages/template-typescript-minimal/.force_overrides b/packages/template-typescript-minimal/.force_overrides index e24ac593de..aabb0e8213 100644 --- a/packages/template-typescript-minimal/.force_overrides +++ b/packages/template-typescript-minimal/.force_overrides @@ -8,4 +8,4 @@ // PLACE THE RELATIVE __POSIX__ PATH TO THE EXTENSION FILE YOU WANT TO OVERRIDE STARTING WITH THE EXTENSION PACKAGE NAME. // MULTIPLE OVERRIDES CAN BE ADDED TO THIS FILE, ONE PER LINE.\ // EXAMPLE: -// ./node_modules/@salesforce/extension-sample/src/pages/home.tsx \ No newline at end of file +./node_modules/@salesforce/extension-sample/src/pages/home.tsx \ No newline at end of file diff --git a/packages/template-typescript-minimal/package-lock.json b/packages/template-typescript-minimal/package-lock.json index b22faf9752..8953f63b91 100644 --- a/packages/template-typescript-minimal/package-lock.json +++ b/packages/template-typescript-minimal/package-lock.json @@ -12,17 +12,21 @@ "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@loadable/component": "^5.15.3", + "@salesforce/commerce-sdk-react": "^3.2.0-extensibility-preview.0", "@tanstack/react-query": "^4.28.0", "@types/loadable__component": "~5.13.4", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.1", "@types/react-router-dom": "~5.3.3", "cross-env": "^5.2.1", + "express": "^4.19.2", "framer-motion": "^11.5.4", "full-icu": "^1.5.0", + "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", + "react-hook-form": "^7.43.9", "react-intl": "^5.25.1", "react-router-dom": "^5.3.4", "typescript": "4.9.5", @@ -627,6 +631,30 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@salesforce/commerce-sdk-react": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@salesforce/commerce-sdk-react/-/commerce-sdk-react-3.2.1.tgz", + "integrity": "sha512-puQZuNiGoKcDpE2W5KcciYx89GTeKwehBzUnkRJSL3YInMG/2pOylAXUzEUjBMiU+IkJ92zsDaJ88uBZQm/osA==", + "dev": true, + "dependencies": { + "commerce-sdk-isomorphic": "^3.2.0", + "js-cookie": "^3.0.1", + "jwt-decode": "^4.0.0" + }, + "engines": { + "node": "^16.11.0 || ^18.0.0 || ^20.0.0 || ^22.0.0", + "npm": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.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", @@ -793,6 +821,19 @@ "@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/aria-hidden": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", @@ -806,6 +847,12 @@ "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", @@ -822,6 +869,45 @@ "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/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/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -832,6 +918,44 @@ "node": "*" } }, + "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-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "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", @@ -849,6 +973,45 @@ "dev": true, "license": "MIT" }, + "node_modules/commerce-sdk-isomorphic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/commerce-sdk-isomorphic/-/commerce-sdk-isomorphic-3.3.0.tgz", + "integrity": "sha512-i+aSgVsQjh7VyODRiVB35LPQNWMoYkjrGMiw7pmYzpTsRkXv79uG8m7fGePbXjcvuVPg6H+AN+TqtebcDQukiA==", + "dev": true, + "dependencies": { + "nanoid": "^3.3.8", + "node-fetch": "2.6.13", + "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", + "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", @@ -856,6 +1019,21 @@ "dev": true, "license": "MIT" }, + "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", @@ -942,6 +1120,25 @@ } } }, + "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", @@ -949,6 +1146,35 @@ "dev": true, "license": "MIT" }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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", @@ -959,6 +1185,42 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "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-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "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", @@ -972,6 +1234,82 @@ "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.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "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.12", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "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.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -982,6 +1320,39 @@ "pend": "~1.2.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/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/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -1002,6 +1373,15 @@ "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.18.2", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz", @@ -1047,6 +1427,15 @@ "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, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/full-icu": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/full-icu/-/full-icu-1.5.0.tgz", @@ -1072,6 +1461,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.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", @@ -1082,6 +1495,19 @@ "node": ">=6" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1092,6 +1518,30 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "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", @@ -1130,6 +1580,34 @@ "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.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -1147,6 +1625,12 @@ "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/intl-messageformat": { "version": "9.13.0", "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz", @@ -1160,6 +1644,15 @@ "tslib": "^2.1.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", @@ -1197,6 +1690,15 @@ "dev": true, "license": "ISC" }, + "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==", + "dev": 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", @@ -1224,6 +1726,15 @@ "dev": true, "license": "MIT" }, + "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==", + "dev": 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", @@ -1251,6 +1762,75 @@ "loose-envify": "cli.js" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "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/motion-dom": { "version": "11.18.1", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", @@ -1275,6 +1855,33 @@ "dev": true, "license": "MIT" }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "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", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -1282,6 +1889,26 @@ "dev": true, "license": "MIT" }, + "node_modules/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "dev": 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", @@ -1292,6 +1919,30 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "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", @@ -1324,6 +1975,15 @@ "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-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -1387,6 +2047,58 @@ "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", @@ -1474,6 +2186,22 @@ "react": ">=16.3.0" } }, + "node_modules/react-hook-form": { + "version": "7.56.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.1.tgz", + "integrity": "sha512-qWAVokhSpshhcEuQDSANHx3jiAEFzu2HAaaQIzi/r9FNPm1ioAvuJSD4EuZzWd7Al7nTRKcKPnBKO7sRn+zavQ==", + "dev": true, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "node_modules/react-intl": { "version": "5.25.1", "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.25.1.tgz", @@ -1676,6 +2404,32 @@ "dev": true, "license": "MIT" }, + "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", @@ -1686,6 +2440,12 @@ "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==", + "dev": true + }, "node_modules/semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -1696,6 +2456,75 @@ "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/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/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", @@ -1719,6 +2548,78 @@ "node": ">=0.10.0" } }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.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", @@ -1729,6 +2630,15 @@ "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", @@ -1770,6 +2680,21 @@ "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, + "engines": { + "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==", + "dev": true + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -1777,6 +2702,19 @@ "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, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -1791,6 +2729,15 @@ "node": ">=4.2.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/use-callback-ref": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", @@ -1846,6 +2793,15 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.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", @@ -1853,6 +2809,31 @@ "dev": true, "license": "MIT" }, + "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/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==", + "dev": 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==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 3c9ef2aaac..4c5c01c0ee 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -23,6 +23,8 @@ "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@loadable/component": "^5.15.3", + "@salesforce/extension-starter": "0.1.0-extensibility-preview.4", + "@salesforce/extension-chakra-store-locator": "0.1.0-extensibility-preview.4", "@salesforce/pwa-kit-dev": "4.0.0-extensibility-preview.4", "@salesforce/pwa-kit-extension-sdk": "4.0.0-extensibility-preview.4", "@salesforce/pwa-kit-react-sdk": "4.0.0-extensibility-preview.4", @@ -41,7 +43,12 @@ "react-intl": "^5.25.1", "react-router-dom": "^5.3.4", "typescript": "4.9.5", - "zustand": "5.0.3" + "zustand": "5.0.3", + + "express": "^4.19.2", + "@salesforce/commerce-sdk-react": "^3.2.0-extensibility-preview.0", + "prop-types": "^15.8.1", + "react-hook-form": "^7.43.9" }, "engines": { "node": "^16.11.0 || ^18.0.0 || ^20.0.0 || ^22.0.0", @@ -49,7 +56,43 @@ }, "mobify": { "app": { - "extensions": [] + "extensions": [ + [ + "@salesforce/extension-chakra-store-locator", + { + "enabled": true, + "path": "/store-locator", + "radius": 100, + "radiusUnit": "km", + "defaultPageSize": 10, + "defaultPostalCode": "10178", + "defaultCountry": "Germany", + "defaultCountryCode": "DE", + "supportedCountries": [ + { + "countryCode": "US", + "countryName": "United States" + }, + { + "countryCode": "DE", + "countryName": "Germany" + } + ], + "commerceApi": { + "proxyPath": "/mobify/proxy/api", + "parameters": { + "shortCode": "8o7m175y", + "clientId": "c9c45bfd-0ed3-4aa2-9971-40f88962b836", + "organizationId": "f_ecom_zzrf_001", + "siteId": "RefArchGlobal", + "locale": "en-GB", + "currency": "USD" + } + } + } + ], + ["@salesforce/extension-starter", {"enabled": true}] + ] }, "ssrEnabled": true, "ssrOnly": [ From a9d038f28866880ebaf462f1b502ba3fc46cb5aa Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 29 Apr 2025 09:28:40 -0700 Subject: [PATCH 2/9] Make constants file, clean up, remove logs --- .../pwa-kit-dev/src/configs/webpack/config.js | 7 +- .../src/configs/constants.ts | 17 +++ .../src/configs/utils.ts | 62 +++++++++++ .../webpack/overrides-resolver-loader.ts | 100 +++++------------- .../src/configs/webpack/types.ts | 1 + 5 files changed, 111 insertions(+), 76 deletions(-) create mode 100644 packages/pwa-kit-extension-sdk/src/configs/constants.ts diff --git a/packages/pwa-kit-dev/src/configs/webpack/config.js b/packages/pwa-kit-dev/src/configs/webpack/config.js index 15392d2102..a434a8ed9b 100644 --- a/packages/pwa-kit-dev/src/configs/webpack/config.js +++ b/packages/pwa-kit-dev/src/configs/webpack/config.js @@ -219,7 +219,7 @@ const baseConfig = (target) => { }, plugins: [ new ApplicationExtensionConfigPlugin({ - extensions: getConfiguredExtensions(getConfig()) + extensions }), new webpack.DefinePlugin({ DEBUG, @@ -264,18 +264,19 @@ const baseConfig = (target) => { }, ruleForApplicationExtensibility({ loaderOptions: { - configured: getConfiguredExtensions(getConfig()), + configured: extensions, target: 'web' } }), ruleForApplicationExtensibility({ loaderOptions: { - configured: getConfiguredExtensions(getConfig()), + configured: extensions, target: 'node' } }), ruleForOverrideResolver({ extensions, + resolveExtensions: SUPPORTED_FILE_EXTENSIONS, isMonoRepo, projectDir, target diff --git a/packages/pwa-kit-extension-sdk/src/configs/constants.ts b/packages/pwa-kit-extension-sdk/src/configs/constants.ts new file mode 100644 index 0000000000..cfbb42f629 --- /dev/null +++ b/packages/pwa-kit-extension-sdk/src/configs/constants.ts @@ -0,0 +1,17 @@ +/* + * 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 + */ + +// Constants // TODO: Move to a shared location +export const LOCAL_EXTENSIONS_DIR = 'application-extensions' +export const EXTENSION_PACKAGE_PREFIX = 'extension-' +export const EXTENSION_PACKAGE_NAMESPACE = '@salesforce' +export const IMPORT_REGEX = /import\s+(?:(?:[\w*\s{},]*)\s+from\s+)?['"](\..*?)['"]/g +export const OVERRIDABLE_FILE_NAME = '.force_overrides' +export const MONO_REPO_WORKSPACE_FOLDER = 'packages' +export const NODE_MODULES_FOLDER = 'node_modules' +export const REQUIRES_REGEX = /require\(['"](\..*?)['"]\)/g +export const SRC_FOLDER = 'src' diff --git a/packages/pwa-kit-extension-sdk/src/configs/utils.ts b/packages/pwa-kit-extension-sdk/src/configs/utils.ts index 13587ebee5..a4b52454de 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/utils.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/utils.ts @@ -7,13 +7,19 @@ // Third-Party import dedent from 'dedent' +import fse from 'fs-extra' import Handlebars from 'handlebars' +import path from 'path' // Local import {kebabToUpperCamelCase, nameRegex} from '../shared/utils' // Types import {ApplicationExtensionsLoaderOptions} from './webpack/types' +import type {ApplicationExtensionEntry} from '../types' + +// Constants +import {LOCAL_EXTENSIONS_DIR, OVERRIDABLE_FILE_NAME, NODE_MODULES_FOLDER} from './constants' // Register Handlebars helpers Handlebars.registerHelper('getInstanceName', (aString: string) => { @@ -84,3 +90,59 @@ export const renderTemplate = (data: ApplicationExtensionsLoaderOptions) => { // Apply data to the compiled template return template(data).trim() } + +/** + * PRIVATE: Reads and parses a .force_overrides file into a list of clean override entries. + * - Skips empty lines + * - Skips full-line comments (`// comment`) + * - Supports inline comments (`override // comment`) + */ +export const getOverridesFromFile = (filePath: string): string[] => { + try { + const content = fse.readFileSync(filePath, 'utf8') + return content + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith('//')) + .map((line) => line.split('//')[0].trim()) // remove inline comments + .filter(Boolean) + } catch (e: any) { + if (e.code !== 'ENOENT') { + console.warn(`Error reading override file at ${filePath}:`, e) + } + return [] + } +} + +/** + * PRIVATE: Returns a list of potential file paths where `.force_overrides` files might exist. + * + * These paths include: + * - A top-level `.force_overrides` file in the root of the project. + * - One per extension, prioritized with the local package version first. + * + * Note: + * - Each extension is assumed to be either a string or a tuple, where the first item is the extension name. + * - This function does not check if the files actually exist; it simply builds candidate paths. + * + * @param projectDir - The root directory of the project. + * @param extensions - A list of extension names or tuples where the first element is the extension name. + * @returns An array of string file paths to check for overrides. + */ +export const getForceOverridesFilePaths = ( + projectDir: string, + extensions: ApplicationExtensionEntry[] +): string[] => { + return [ + path.join(projectDir, OVERRIDABLE_FILE_NAME), + ...extensions + .map((ext) => { + const name = typeof ext === 'string' ? ext : ext[0] + return [ + path.join(projectDir, LOCAL_EXTENSIONS_DIR, name, OVERRIDABLE_FILE_NAME), + path.join(projectDir, NODE_MODULES_FOLDER, name, OVERRIDABLE_FILE_NAME) + ] + }) + .flat() + ] +} diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts index 60d72297c4..f176931e21 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts @@ -5,28 +5,29 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import {LoaderContext} from 'webpack' -import fse from 'fs-extra' + import os from 'os' import path from 'path' import resolve from 'resolve' // Local Imports import {buildCandidatePaths, getPackageName, SETUP_FILE_REGEX} from '../../shared/utils' +import {getForceOverridesFilePaths, getOverridesFromFile} from '../utils' // Types import type {ExtendedCompiler, OverridesResolverRuleOptions} from './types' import type {OverrideStatsEntry} from './override-stats-plugin' // Constants -const LOCAL_EXTENSIONS_DIR = 'application-extensions' -const EXTENSION_PACKAGE_PREFIX = 'extension-' -const EXTENSION_PACKAGE_NAMESPACE = '@salesforce' -const IMPORT_REGEX = /import\s+(?:(?:[\w*\s{},]*)\s+from\s+)?['"](\..*?)['"]/g -const OVERRIDABLE_FILE_NAME = '.force_overrides' -const MONO_REPO_WORKSPACE_FOLDER = 'packages' -const NODE_MODULES_FOLDER = 'node_modules' -const REQUIRES_REGEX = /require\(['"](\..*?)['"]\)/g -const SRC = 'src' +import { + EXTENSION_PACKAGE_PREFIX, + EXTENSION_PACKAGE_NAMESPACE, + IMPORT_REGEX, + MONO_REPO_WORKSPACE_FOLDER, + NODE_MODULES_FOLDER, + REQUIRES_REGEX, + SRC_FOLDER +} from '../constants' // Cache for processed overrides const OVERRIDABLE_CACHE = { @@ -53,9 +54,10 @@ const OverrideResolverLoader = function (this: LoaderContext) { // use `packageIterator` in the "resolve" function used later on. const {resourcePath, _compiler} = this + // TECH DEPT: Accessing `_compiler` is a bit of a hack, but it works. We should look to work around this. const compiler = _compiler as ExtendedCompiler - const projectRelPath = resourcePath.split(`${SRC}${path.sep}`)[1].split('.')[0] // File path relative to the project directory without file extension - const projectPath = resourcePath.split(SRC)[0] + const projectRelPath = resourcePath.split(`${SRC_FOLDER}${path.sep}`)[1].split('.')[0] // File path relative to the project directory without file extension + const projectPath = resourcePath.split(SRC_FOLDER)[0] const options = this.getOptions() // Get the package name @@ -71,14 +73,9 @@ const OverrideResolverLoader = function (this: LoaderContext) { } // Lets use the compiler configuration to ensure we are resolving the correct file extensions. - const compilerOptions = this._compiler?.options - - // const extensions = compilerOptions?.resolve?.extensions || [] - const extensions = [ '.ts', '.tsx', '.js', '.jsx', '.json' ] + const extensions = options?.resolveExtensions const basedir = options?.baseDir || process.cwd() const applicationExtensions = options?.extensions || compiler?.custom?.extensions || [] - console.log('extensions: ', extensions) - // Get the master list of all possible candidate paths based on your current extension configuration. const paths = buildCandidatePaths(projectRelPath, packageName, { @@ -87,7 +84,6 @@ const OverrideResolverLoader = function (this: LoaderContext) { extensionEntries: applicationExtensions }) - // Also include the base override path and the path from the extension doing the import. const resolvedResourcePath = resolve.sync(projectRelPath, { basedir, @@ -96,14 +92,6 @@ const OverrideResolverLoader = function (this: LoaderContext) { ...options?.resolveOptions }) - - if (projectRelPath.includes('content')) { - console.log('Extensions: ', applicationExtensions) - console.log('Paths: ', paths) - console.log('Resolved Resource Path: ', resolvedResourcePath) - console.log('File Extensions: ', extensions) - } - // Record override stats if RECORD_OVERRIDES is enabled if (this._compilation && 'overrideStats' in this._compilation) { const compilation = this._compilation as {overrideStats: OverrideStatsEntry[]} @@ -219,29 +207,6 @@ export const validateOverrideSource = (source: string, options: any = {}) => { return hasOverride } -/** - * Reads and parses a .force_overrides file into a list of clean override entries. - * - Skips empty lines - * - Skips full-line comments (`// comment`) - * - Supports inline comments (`override // comment`) - */ -const getOverridesFromFile = (filePath: string): string[] => { - try { - const content = fse.readFileSync(filePath, 'utf8') - return content - .split(/\r?\n/) - .map((line) => line.trim()) - .filter((line) => line && !line.startsWith('//')) - .map((line) => line.split('//')[0].trim()) // remove inline comments - .filter(Boolean) - } catch (e: any) { - if (e.code !== 'ENOENT') { - console.warn(`Error reading override file at ${filePath}:`, e) - } - return [] - } -} - /** * Generates a Webpack rule for application extensibility, configuring the loader for * handling application extensions based on the target (e.g., 'node' for server-side, @@ -252,33 +217,21 @@ const getOverridesFromFile = (filePath: string): string[] => { * @returns {Object} A Webpack rule configuration object for handling application extensions. */ export const ruleForOverrideResolver = (options: OverridesResolverRuleOptions): object => { - const {extensions = [], projectDir, target = 'web', isMonoRepo = false} = options + const { + extensions = [], + projectDir, + resolveExtensions = [], + target = 'web', + isMonoRepo = false + } = options const overridablesSet = new Set() // Determine possible locations for the .force_overrides files in the project. Please note that // and extension can't exists as a node_module and a local package, but for simplicity sake we'll use for // for candidate locations prioritizing the local package. - const forceOverridesFilePaths: string[] = [ - path.join(projectDir, OVERRIDABLE_FILE_NAME), - ...extensions - .map((ext) => [ - path.join( - projectDir, - LOCAL_EXTENSIONS_DIR, - typeof ext === 'string' ? ext : ext[0], - OVERRIDABLE_FILE_NAME - ), - path.join( - projectDir, - NODE_MODULES_FOLDER, - typeof ext === 'string' ? ext : ext[0], - OVERRIDABLE_FILE_NAME - ) - ]) - .flat() - ] - - // Create a "master" list of all the overrides in the project. + const forceOverridesFilePaths: string[] = getForceOverridesFilePaths(projectDir, extensions) + + // Create a "master" list of all the overrides in the project. // NOTE: That files defined in an extensions .force_overrides file will technically leak outside ot its scope // allowing other extensions to now override those extensions as well. This isn't ideal, but fo this initial version // we can go with it. @@ -298,7 +251,8 @@ export const ruleForOverrideResolver = (options: OverridesResolverRuleOptions): use: { loader: '@salesforce/pwa-kit-extension-sdk/configs/webpack/overrides-resolver-loader', options: { - extensions + extensions, + resolveExtensions } } } diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts index 70fb6aa351..6f8efdba43 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/types.ts @@ -29,6 +29,7 @@ export type ExtendedCompiler = Compiler & { export interface OverridesResolverRuleOptions { extensions?: ApplicationExtensionEntry[] projectDir: string + resolveExtensions: string[] target?: string isMonoRepo?: boolean } From fb9550e52710a2585ab23f7b25b815814f0eac08 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 29 Apr 2025 10:33:36 -0700 Subject: [PATCH 3/9] Update CHANGELOG.md --- packages/pwa-kit-extension-sdk/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/pwa-kit-extension-sdk/CHANGELOG.md b/packages/pwa-kit-extension-sdk/CHANGELOG.md index e6e64a2f9f..dd65665bcd 100644 --- a/packages/pwa-kit-extension-sdk/CHANGELOG.md +++ b/packages/pwa-kit-extension-sdk/CHANGELOG.md @@ -1,4 +1,5 @@ ## v4.0.0-extensibility-preview.4 (Feb 12, 2025) +- Support `.force_overries` in extension projects [#2380](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2380) - Replace `extendRoutes` with `getRoutes` and `getRoutesAsync` to have simpler API and allow for async SCAPI calls (for example, Shopper SEO's getUrlMapping) [#2308](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2308) - Change signature of `beforeRouteMatch` to allow for more parameters (now also passing in the locals object) [#2308](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2308) - Added caching to `getRoutesAsync` and implemented serialization for application extension async routes [#2300](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2300) From f48a14b90ff6a440d63be8309479f1cd12017a46 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 29 Apr 2025 10:48:36 -0700 Subject: [PATCH 4/9] Add tests for utilities. --- .../src/configs/utils.test.ts | 85 ++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/packages/pwa-kit-extension-sdk/src/configs/utils.test.ts b/packages/pwa-kit-extension-sdk/src/configs/utils.test.ts index 9dcc662a42..7856930b55 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/utils.test.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/utils.test.ts @@ -7,11 +7,15 @@ import * as fse from 'fs-extra' import * as path from 'path' import {buildBabelExtensibilityArgs} from './babel/utils' -import {ApplicationExtensionEntryTuple} from '../types' +import {ApplicationExtensionEntry, ApplicationExtensionEntryTuple} from '../types' +import {LOCAL_EXTENSIONS_DIR, OVERRIDABLE_FILE_NAME, NODE_MODULES_FOLDER} from './constants' +import {getOverridesFromFile, getForceOverridesFilePaths} from './utils' +import e from 'express' jest.mock('fs-extra', () => ({ ...jest.requireActual('fs-extra'), - realpathSync: jest.fn() + realpathSync: jest.fn(), + readFileSync: jest.fn() })) const EXTENSIONS: ApplicationExtensionEntryTuple[] = [ @@ -85,3 +89,80 @@ describe('buildBabelExtensibilityArgs', () => { expect(result2).toBe(expectedArgs) }) }) + +describe('getOverridesFromFile', () => { + const readFileSyncMock = jest.spyOn(fse, 'readFileSync') as jest.Mock + + test('returns parsed override entries, skipping comments and blank lines', () => { + readFileSyncMock.mockReturnValue(` + // This is a comment + override1 + override2 // inline comment + + // Another comment + override3 + `) + + const result = getOverridesFromFile('mock/path/.force_overrides') + + expect(result).toEqual(['override1', 'override2', 'override3']) + }) + + test('returns an empty array if file not found (ENOENT)', () => { + const error = new Error('File not found') as any + error.code = 'ENOENT' + readFileSyncMock.mockImplementation(() => { + throw error + }) + + const result = getOverridesFromFile('nonexistent/path') + expect(result).toEqual([]) + }) + + test('logs warning for other read errors and returns empty array', () => { + const error = new Error('Permission denied') as any + error.code = 'EACCES' + const warnSpy = jest.spyOn(console, 'warn').mockImplementation() + + readFileSyncMock.mockImplementation(() => { + throw error + }) + + const result = getOverridesFromFile('bad/path') + expect(warnSpy).toHaveBeenCalledWith( + expect.stringContaining('Error reading override file at'), + error + ) + expect(result).toEqual([]) + + warnSpy.mockRestore() + }) +}) + +describe('getForceOverridesFilePaths', () => { + const projectDir = '/project' + const extensions: ApplicationExtensionEntry[] = [ + ['ext-a', {enabled: true}], + ['ext-b', {enabled: true}], + ['ext-c', {enabled: true}] + ] + + test('returns all potential override paths', () => { + const result = getForceOverridesFilePaths(projectDir, extensions) + + expect(result).toEqual([ + path.join(projectDir, OVERRIDABLE_FILE_NAME), + path.join(projectDir, LOCAL_EXTENSIONS_DIR, 'ext-a', OVERRIDABLE_FILE_NAME), + path.join(projectDir, NODE_MODULES_FOLDER, 'ext-a', OVERRIDABLE_FILE_NAME), + path.join(projectDir, LOCAL_EXTENSIONS_DIR, 'ext-b', OVERRIDABLE_FILE_NAME), + path.join(projectDir, NODE_MODULES_FOLDER, 'ext-b', OVERRIDABLE_FILE_NAME), + path.join(projectDir, LOCAL_EXTENSIONS_DIR, 'ext-c', OVERRIDABLE_FILE_NAME), + path.join(projectDir, NODE_MODULES_FOLDER, 'ext-c', OVERRIDABLE_FILE_NAME) + ]) + }) + + test('handles an empty extensions array', () => { + const result = getForceOverridesFilePaths(projectDir, []) + expect(result).toEqual([path.join(projectDir, OVERRIDABLE_FILE_NAME)]) + }) +}) From 7d38fc455dc99ee0bd004d70ef1f4efd41d4510c Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 29 Apr 2025 14:29:46 -0700 Subject: [PATCH 5/9] Fix failing tests --- .../src/configs/webpack/overrides-resolver-loader.test.ts | 1 + .../src/configs/webpack/overrides-resolver-loader.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.test.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.test.ts index e3ee2f2d3f..097be859be 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.test.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.test.ts @@ -356,6 +356,7 @@ describe('Overrides Resolver Loader', () => { ), options: { baseDir: '/', + resolveExtensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], resolveOptions: { // Override the `fs` methods used by `resolve` to point to the virtual file system existsSync: (filePath: string) => { diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts index f176931e21..8e11987a6a 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts @@ -54,7 +54,7 @@ const OverrideResolverLoader = function (this: LoaderContext) { // use `packageIterator` in the "resolve" function used later on. const {resourcePath, _compiler} = this - // TECH DEPT: Accessing `_compiler` is a bit of a hack, but it works. We should look to work around this. + // TECH DEBT: Accessing `_compiler` is a bit of a hack, but it works. We should look to work around this. const compiler = _compiler as ExtendedCompiler const projectRelPath = resourcePath.split(`${SRC_FOLDER}${path.sep}`)[1].split('.')[0] // File path relative to the project directory without file extension const projectPath = resourcePath.split(SRC_FOLDER)[0] From 64067c4c4d07ee9ddfddbee3d9476ad6baa8d1e0 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Mon, 5 May 2025 14:53:24 -0700 Subject: [PATCH 6/9] PR feedback round 1 --- .../src/configs/utils.ts | 19 +++++++++---------- .../webpack/overrides-resolver-loader.ts | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/pwa-kit-extension-sdk/src/configs/utils.ts b/packages/pwa-kit-extension-sdk/src/configs/utils.ts index a4b52454de..c3a26768cf 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/utils.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/utils.ts @@ -92,7 +92,8 @@ export const renderTemplate = (data: ApplicationExtensionsLoaderOptions) => { } /** - * PRIVATE: Reads and parses a .force_overrides file into a list of clean override entries. + * @private + * Reads and parses a .force_overrides file into a list of clean override entries. * - Skips empty lines * - Skips full-line comments (`// comment`) * - Supports inline comments (`override // comment`) @@ -135,14 +136,12 @@ export const getForceOverridesFilePaths = ( ): string[] => { return [ path.join(projectDir, OVERRIDABLE_FILE_NAME), - ...extensions - .map((ext) => { - const name = typeof ext === 'string' ? ext : ext[0] - return [ - path.join(projectDir, LOCAL_EXTENSIONS_DIR, name, OVERRIDABLE_FILE_NAME), - path.join(projectDir, NODE_MODULES_FOLDER, name, OVERRIDABLE_FILE_NAME) - ] - }) - .flat() + ...extensions.flatMap((ext) => { + const name = typeof ext === 'string' ? ext : ext[0] + return [ + path.join(projectDir, LOCAL_EXTENSIONS_DIR, name, OVERRIDABLE_FILE_NAME), + path.join(projectDir, NODE_MODULES_FOLDER, name, OVERRIDABLE_FILE_NAME) + ] + }) ] } diff --git a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts index 8e11987a6a..97025d1700 100644 --- a/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts +++ b/packages/pwa-kit-extension-sdk/src/configs/webpack/overrides-resolver-loader.ts @@ -73,7 +73,7 @@ const OverrideResolverLoader = function (this: LoaderContext) { } // Lets use the compiler configuration to ensure we are resolving the correct file extensions. - const extensions = options?.resolveExtensions + const fileExtensions = options?.resolveExtensions const basedir = options?.baseDir || process.cwd() const applicationExtensions = options?.extensions || compiler?.custom?.extensions || [] @@ -87,7 +87,7 @@ const OverrideResolverLoader = function (this: LoaderContext) { // Also include the base override path and the path from the extension doing the import. const resolvedResourcePath = resolve.sync(projectRelPath, { basedir, - extensions, + extensions: fileExtensions, packageIterator: () => paths, ...options?.resolveOptions }) From a02fbf629b5554f6fe146d99c3954e555dde27d7 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Mon, 5 May 2025 16:16:07 -0700 Subject: [PATCH 7/9] Remove test configuration --- packages/extension-starter/.force_overrides | 2 +- .../template-typescript-minimal/package.json | 47 +------------------ 2 files changed, 3 insertions(+), 46 deletions(-) diff --git a/packages/extension-starter/.force_overrides b/packages/extension-starter/.force_overrides index b184679956..00474591bc 100644 --- a/packages/extension-starter/.force_overrides +++ b/packages/extension-starter/.force_overrides @@ -8,4 +8,4 @@ // PLACE THE RELATIVE __POSIX__ PATH TO THE EXTENSION FILE YOU WANT TO OVERRIDE STARTING WITH THE EXTENSION PACKAGE NAME. // MULTIPLE OVERRIDES CAN BE ADDED TO THIS FILE, ONE PER LINE. // EXAMPLE: -./node_modules/@salesforce/extension-chakra-store-locator/src/components/content.tsx \ No newline at end of file +// ./node_modules/@salesforce/extension-chakra-store-locator/src/components/content.tsx \ No newline at end of file diff --git a/packages/template-typescript-minimal/package.json b/packages/template-typescript-minimal/package.json index 4c5c01c0ee..3c9ef2aaac 100644 --- a/packages/template-typescript-minimal/package.json +++ b/packages/template-typescript-minimal/package.json @@ -23,8 +23,6 @@ "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@loadable/component": "^5.15.3", - "@salesforce/extension-starter": "0.1.0-extensibility-preview.4", - "@salesforce/extension-chakra-store-locator": "0.1.0-extensibility-preview.4", "@salesforce/pwa-kit-dev": "4.0.0-extensibility-preview.4", "@salesforce/pwa-kit-extension-sdk": "4.0.0-extensibility-preview.4", "@salesforce/pwa-kit-react-sdk": "4.0.0-extensibility-preview.4", @@ -43,12 +41,7 @@ "react-intl": "^5.25.1", "react-router-dom": "^5.3.4", "typescript": "4.9.5", - "zustand": "5.0.3", - - "express": "^4.19.2", - "@salesforce/commerce-sdk-react": "^3.2.0-extensibility-preview.0", - "prop-types": "^15.8.1", - "react-hook-form": "^7.43.9" + "zustand": "5.0.3" }, "engines": { "node": "^16.11.0 || ^18.0.0 || ^20.0.0 || ^22.0.0", @@ -56,43 +49,7 @@ }, "mobify": { "app": { - "extensions": [ - [ - "@salesforce/extension-chakra-store-locator", - { - "enabled": true, - "path": "/store-locator", - "radius": 100, - "radiusUnit": "km", - "defaultPageSize": 10, - "defaultPostalCode": "10178", - "defaultCountry": "Germany", - "defaultCountryCode": "DE", - "supportedCountries": [ - { - "countryCode": "US", - "countryName": "United States" - }, - { - "countryCode": "DE", - "countryName": "Germany" - } - ], - "commerceApi": { - "proxyPath": "/mobify/proxy/api", - "parameters": { - "shortCode": "8o7m175y", - "clientId": "c9c45bfd-0ed3-4aa2-9971-40f88962b836", - "organizationId": "f_ecom_zzrf_001", - "siteId": "RefArchGlobal", - "locale": "en-GB", - "currency": "USD" - } - } - } - ], - ["@salesforce/extension-starter", {"enabled": true}] - ] + "extensions": [] }, "ssrEnabled": true, "ssrOnly": [ From 19dd0c9e8be790496866ff5a83d6c73145d864fb Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Mon, 5 May 2025 16:19:21 -0700 Subject: [PATCH 8/9] Remove sample override for testing --- .../components/content.tsx | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx diff --git a/packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx b/packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx deleted file mode 100644 index 1a26085991..0000000000 --- a/packages/extension-starter/src/overrides/@salesforce/extension-chakra-store-locator/components/content.tsx +++ /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 - */ - -import React from 'react' - -export const StoreLocatorContent = (): JSX.Element => { - return ( - <> -
hello
- - ) -} From e6b27893f341b6393642f95264562ef921fe3f6d Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 6 May 2025 10:30:45 -0700 Subject: [PATCH 9/9] Revert override --- packages/template-typescript-minimal/.force_overrides | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-typescript-minimal/.force_overrides b/packages/template-typescript-minimal/.force_overrides index aabb0e8213..e24ac593de 100644 --- a/packages/template-typescript-minimal/.force_overrides +++ b/packages/template-typescript-minimal/.force_overrides @@ -8,4 +8,4 @@ // PLACE THE RELATIVE __POSIX__ PATH TO THE EXTENSION FILE YOU WANT TO OVERRIDE STARTING WITH THE EXTENSION PACKAGE NAME. // MULTIPLE OVERRIDES CAN BE ADDED TO THIS FILE, ONE PER LINE.\ // EXAMPLE: -./node_modules/@salesforce/extension-sample/src/pages/home.tsx \ No newline at end of file +// ./node_modules/@salesforce/extension-sample/src/pages/home.tsx \ No newline at end of file