Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/pr-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ env:

jobs:
lint:
runs-on: warp-ubuntu-2404-x64-2x
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -25,24 +25,23 @@ jobs:
run: biome ci .

typecheck:
runs-on: warp-ubuntu-2404-x64-2x
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Cache turbo build setup
if: env.skip == 'false'
uses: WarpBuilds/cache@v1
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-

- name: Setup Node.js environment
uses: WarpBuilds/setup-node@v4
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
Expand All @@ -51,9 +50,7 @@ jobs:
run: yarn install --immutable

- name: Type-check
if: ${{ needs.detect-changes.outputs.e2e == 'true' }}
run: yarn typecheck

- name: Build
run: yarn build

925 changes: 0 additions & 925 deletions .yarn/releases/yarn-4.5.0.cjs

This file was deleted.

948 changes: 948 additions & 0 deletions .yarn/releases/yarn-4.9.1.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.5.0.cjs
yarnPath: .yarn/releases/yarn-4.9.1.cjs
35 changes: 15 additions & 20 deletions apps/medusa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,29 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@lambdacurry/medusa-product-reviews": "1.2.0",
"@medusajs/admin-sdk": "2.7.0",
"@medusajs/cli": "2.7.0",
"@medusajs/framework": "2.7.0",
"@medusajs/js-sdk": "2.7.0",
"@medusajs/medusa": "2.7.0",
"@medusajs/types": "2.7.0",
"@mikro-orm/core": "6.4.3",
"@mikro-orm/knex": "6.4.3",
"@mikro-orm/migrations": "6.4.3",
"@mikro-orm/postgresql": "6.4.3",
"awilix": "^8.0.1",
"pg": "^8.13.0"
"@lambdacurry/medusa-product-reviews": "1.3.1",
"@medusajs/admin-sdk": "2.13.1",
"@medusajs/cli": "2.13.1",
"@medusajs/framework": "2.13.1",
"@medusajs/icons": "2.13.1",
"@medusajs/js-sdk": "2.13.1",
"@medusajs/medusa": "2.13.1",
"@medusajs/types": "2.13.1",
"@medusajs/ui": "4.1.1",
"posthog-node": "5.11.0",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@medusajs/test-utils": "2.7.0",
"@mikro-orm/cli": "6.4.3",
"@mikro-orm/core": "6.4.3",
"@mikro-orm/migrations": "6.4.3",
"@mikro-orm/postgresql": "6.4.3",
"@stdlib/number-float64-base-normalize": "0.0.8",
"@swc/core": "1.5.7",
"@medusajs/test-utils": "2.13.1",
"@swc/core": "^1.7.28",
"@swc/jest": "^0.2.36",
"@types/express": "^4.17.13",
"@types/jest": "^29.5.12",
"@types/mime": "1.3.5",
"@types/node": "^17.0.8",
"@types/react": "^18.3.2",
"@types/react-dom": "^18",
"jest": "^29.7.0",
"prop-types": "^15.8.1",
"ts-node": "^10.9.2",
Expand Down
2 changes: 1 addition & 1 deletion apps/storefront/app/components/layout/footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const Footer = () => {
const { region } = useRegion();

const regionOptions = useMemo(() => {
return regions.map((region) => ({
return (regions ?? []).map((region) => ({
label: `${region.name} (${region.currency_code})`,
value: region.id,
}));
Expand Down
3 changes: 2 additions & 1 deletion apps/storefront/app/hooks/useSiteDetails.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { SiteDetailsRootData } from '@libs/types';
import { useRootLoaderData } from './useRootLoaderData';

export const useSiteDetails = () => {
const data = useRootLoaderData();

return data.siteDetails || {};
return data?.siteDetails ?? ({} as SiteDetailsRootData);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, locate and examine the useSiteDetails hook definition
find . -name "useSiteDetails.ts" -o -name "useSiteDetails.tsx"

Repository: lambda-curry/medusa2-starter

Length of output: 117


🏁 Script executed:

#!/bin/bash
# Search for SiteDetailsRootData type definition
rg -nP "type SiteDetailsRootData|interface SiteDetailsRootData" --type=ts --type=tsx -A 10

Repository: lambda-curry/medusa2-starter

Length of output: 99


🏁 Script executed:

#!/bin/bash
# Find all useSiteDetails() calls to understand consumer patterns
rg -nP "useSiteDetails\s*\(" --type=ts --type=tsx -B 2 -A 3

Repository: lambda-curry/medusa2-starter

Length of output: 99


🏁 Script executed:

#!/bin/bash
# Check what properties are accessed from useSiteDetails result
rg -nP "useSiteDetails\(\)[?.]|const\s+\w+\s*=\s*useSiteDetails\(\)" --type=ts --type=tsx -A 5

Repository: lambda-curry/medusa2-starter

Length of output: 99


🏁 Script executed:

#!/bin/bash
# Read the useSiteDetails.ts file to understand the hook and its return type
cat -n ./apps/storefront/app/hooks/useSiteDetails.ts

Repository: lambda-curry/medusa2-starter

Length of output: 378


🏁 Script executed:

#!/bin/bash
# Find SiteDetailsRootData type definition (ts files only)
rg -nP "type SiteDetailsRootData|interface SiteDetailsRootData" --type=ts -A 10

Repository: lambda-curry/medusa2-starter

Length of output: 711


🏁 Script executed:

#!/bin/bash
# Find all useSiteDetails calls using simple pattern (without tsx file type)
rg "useSiteDetails" --type=ts -B 2 -A 3

Repository: lambda-curry/medusa2-starter

Length of output: 5497


🏁 Script executed:

#!/bin/bash
# Find property accesses on useSiteDetails result
rg "useSiteDetails\(\)" --type=ts -A 5

Repository: lambda-curry/medusa2-starter

Length of output: 2372


🏁 Script executed:

#!/bin/bash
# Find useRootLoaderData hook definition
cat -n ./apps/storefront/app/hooks/useRootLoaderData.ts

Repository: lambda-curry/medusa2-starter

Length of output: 152


🏁 Script executed:

#!/bin/bash
# Search for root loader or where data.siteDetails is set
rg "siteDetails" --type=ts -B 2 -A 2

Repository: lambda-curry/medusa2-starter

Length of output: 2275


Remove unsafe empty-object cast and return data?.siteDetails directly.

The cast ({} as SiteDetailsRootData) suppresses type checks. An empty object doesn't provide the required fields (store, settings, headerNavigationItems, footerNavigationItems), yet three of four consumers destructure these fields without null guards:

  • HeaderSideNav.tsx: destructures headerNavigationItems directly
  • Header.tsx: destructures headerNavigationItems directly
  • Footer.tsx: destructures footerNavigationItems and settings directly
  • LogoStoreName.tsx: includes defensive if (!store || !settings) return null;

If the fallback is triggered, these consumers will attempt to use undefined values, causing runtime crashes. The root loader already guarantees siteDetails is populated, so the fallback is unnecessary. Return data?.siteDetails to fail fast if absent and let callers handle optional chaining where needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/storefront/app/hooks/useSiteDetails.ts` at line 7, Replace the unsafe
empty-object cast in useSiteDetails by returning data?.siteDetails directly:
remove the fallback "({} as SiteDetailsRootData)" in the return of the
useSiteDetails hook so the function returns data?.siteDetails (possibly
undefined) instead of a lie-typed empty object; update the return statement in
the useSiteDetails function to reference data?.siteDetails and let callers
handle the optional value.

};
5 changes: 3 additions & 2 deletions apps/storefront/libs/util/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ export const getProductMeta: MetaFunction = ({ data, matches }) => {
const ogDescription = description;
const ogImage = product.thumbnail || product.images?.[0]?.url;
const ogImageAlt = !!ogImage ? `${title} product thumbnail` : undefined;
const currencyCode = region?.currency_code ?? 'usd';

return [
{ title },
Expand All @@ -293,11 +294,11 @@ export const getProductMeta: MetaFunction = ({ data, matches }) => {
{ property: 'og:image', content: ogImage },
{ property: 'og:image:alt', content: ogImageAlt },
{ property: 'og:type', content: 'product' },
{ property: 'product:price:currency', content: region.currency_code },
{ property: 'product:price:currency', content: currencyCode },
{
property: 'product:price:amount',
content: formatPrice(getVariantFinalPrice(defaultVariant), {
currency: region.currency_code,
currency: currencyCode,
}),
},
];
Expand Down
2 changes: 1 addition & 1 deletion apps/storefront/libs/util/server/data/cart.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export const deleteLineItem = withAuthHeaders(async (request, authHeaders, lineI
throw new Error('Missing cart ID when deleting line item');
}

return await sdk.store.cart.deleteLineItem(cartId, lineId, authHeaders).catch(medusaError);
return await sdk.store.cart.deleteLineItem(cartId, lineId, {}, authHeaders).catch(medusaError);
});

export async function enrichLineItems(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const reviewsFileUploadHandler = async (fileUpload: FileUpload) => {

// FileUpload objects are not meant to stick around for very long (they are
// streaming data from the request.body); store them as soon as possible.
await memoryStorage.set(storageKey, fileUpload);
await memoryStorage.set(storageKey, fileUpload as unknown as File);

// Return a File for the FormData object. This is a LazyFile that knows how
// to access the file's content if needed (using e.g. file.stream()) but
Expand Down
2 changes: 1 addition & 1 deletion apps/storefront/libs/util/server/page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { fetchProducts } from './products.server';
export const getProductListData = async (request: Request) => {
const region = await getSelectedRegion(request.headers);

const productsQuery: HttpTypes.StoreProductParams = {
const productsQuery: HttpTypes.FindParams & HttpTypes.StoreProductParams = {
limit: 10,
offset: 0,
};
Expand Down
4 changes: 2 additions & 2 deletions apps/storefront/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"directory": "packages/markethaus-storefront"
},
"devDependencies": {
"@medusajs/types": "2.7.0",
"@medusajs/types": "2.13.1",
"@react-router/dev": "^7.5.3",
"@react-router/fs-routes": "^7.5.3",
"@swc-node/register": "^1.4.2",
Expand Down Expand Up @@ -84,7 +84,7 @@
"@lambdacurry/forms": "^0.15.0",
"@lambdacurry/medusa-plugins-sdk": "0.0.5",
"@loadable/component": "^5.15.3",
"@medusajs/js-sdk": "2.7.0",
"@medusajs/js-sdk": "2.13.1",
"@mjackson/file-storage": "^0.6.1",
"@mjackson/form-data-parser": "^0.7.0",
"@radix-ui/react-slot": "^1.0.2",
Expand Down
63 changes: 60 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,67 @@
"node": ">=20"
},
"resolutions": {
"@medusajs/js-sdk": "2.7.0",
"@medusajs/types": "2.7.0"
"@medusajs/admin-bundler": "2.13.1",
"@medusajs/admin-sdk": "2.13.1",
"@medusajs/admin-shared": "2.13.1",
"@medusajs/admin-vite-plugin": "2.13.1",
"@medusajs/api-key": "2.13.1",
"@medusajs/auth": "2.13.1",
"@medusajs/auth-emailpass": "2.13.1",
"@medusajs/auth-github": "2.13.1",
"@medusajs/auth-google": "2.13.1",
"@medusajs/cache-inmemory": "2.13.1",
"@medusajs/cache-redis": "2.13.1",
"@medusajs/caching-redis": "2.13.1",
"@medusajs/cart": "2.13.1",
"@medusajs/cli": "2.13.1",
"@medusajs/core-flows": "2.13.1",
"@medusajs/currency": "2.13.1",
"@medusajs/customer": "2.13.1",
"@medusajs/event-bus-local": "2.13.1",
"@medusajs/event-bus-redis": "2.13.1",
"@medusajs/file": "2.13.1",
"@medusajs/file-local": "2.13.1",
"@medusajs/file-s3": "2.13.1",
"@medusajs/framework": "2.13.1",
"@medusajs/fulfillment": "2.13.1",
"@medusajs/fulfillment-manual": "2.13.1",
"@medusajs/icons": "2.13.1",
"@medusajs/index": "2.13.1",
"@medusajs/inventory": "2.13.1",
"@medusajs/js-sdk": "2.13.1",
"@medusajs/link-modules": "2.13.1",
"@medusajs/locking": "2.13.1",
"@medusajs/locking-postgres": "2.13.1",
"@medusajs/locking-redis": "2.13.1",
"@medusajs/medusa": "2.13.1",
"@medusajs/modules-sdk": "2.13.1",
"@medusajs/notification": "2.13.1",
"@medusajs/notification-local": "2.13.1",
"@medusajs/notification-sendgrid": "2.13.1",
"@medusajs/orchestration": "2.13.1",
"@medusajs/order": "2.13.1",
"@medusajs/payment": "2.13.1",
"@medusajs/pricing": "2.13.1",
"@medusajs/product": "2.13.1",
"@medusajs/promotion": "2.13.1",
"@medusajs/region": "2.13.1",
"@medusajs/sales-channel": "2.13.1",
"@medusajs/stock-location": "2.13.1",
"@medusajs/store": "2.13.1",
"@medusajs/tax": "2.13.1",
"@medusajs/telemetry": "2.13.1",
"@medusajs/types": "2.13.1",
"@medusajs/user": "2.13.1",
"@medusajs/utils": "2.13.1",
"@medusajs/workflow-engine-inmemory": "2.13.1",
"@medusajs/workflow-engine-redis": "2.13.1",
"@medusajs/workflows-sdk": "2.13.1",
"zod": "3.25.76",
"react": "^19.2.3",
"react-dom": "^19.2.3"
Comment on lines +82 to +83

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Declared React versions in manifests ==="
for file in package.json apps/medusa/package.json apps/storefront/package.json; do
  if [ -f "$file" ]; then
    name=$(jq -r '.name' "$file" 2>/dev/null || echo "unknown")
    react=$(jq -r '.dependencies.react // "n/a"' "$file" 2>/dev/null || echo "error")
    react_dom=$(jq -r '.dependencies["react-dom"] // "n/a"' "$file" 2>/dev/null || echo "error")
    echo "$file ($name): react=$react, react-dom=$react_dom"
  fi
done

echo
echo "=== Root resolutions for React ==="
if [ -f package.json ]; then
  jq -r '.resolutions | keys[] as $k | "\($k)=\(.[$k])"' package.json 2>/dev/null | grep -E "react"
fi

echo
echo "=== Resolved React entries in yarn.lock (first 20 matches) ==="
if [ -f yarn.lock ]; then
  rg -n '^"(react|react-dom)@' yarn.lock -A 1 | head -40
fi

Repository: lambda-curry/medusa2-starter

Length of output: 543


Root React resolutions override workspace package declarations, forcing React 19.2.3+ on apps/medusa which explicitly requires React 18.3.1.

The root-level resolutions field forces React and react-dom to ^19.2.3 globally, overriding the declared 18.3.1 versions in apps/medusa/package.json. The yarn.lock confirms only React 19.2.3+ is installed; the declared React 18.3.1 is never resolved. This creates a major version incompatibility between declared intent and actual runtime, risking hidden compatibility issues and unexpected behavior.

Either align resolutions with workspace requirements, remove the global override, or upgrade apps/medusa to React 19 if compatible.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 82 - 83, The root package.json currently forces
"react" and "react-dom" to ^19.2.3 via the top-level resolutions which overrides
workspace packages (including apps/medusa which declares "react": "18.3.1");
update the root package.json resolutions to either remove the "react" and
"react-dom" entries or change them to match apps/medusa's declared version
(18.3.1) or, if you intend to move medusa to React 19, update
apps/medusa/package.json to "react" and "react-dom": "^19.2.3" and run yarn
install to regenerate yarn.lock so the installed versions match the declarations
and avoid runtime mismatch.

},
"packageManager": "yarn@4.5.0",
"packageManager": "yarn@4.9.1",
"workspaces": [
"apps/*",
"packages/*"
Expand Down
Loading