Skip to content

Barrel import still requires the optional peer date-fns (UniversalFilter), breaking clean-install consumers #1735

Description

@marblom007

Summary

src/custom/UniversalFilter.tsx:3 imports date-fns at module scope, but date-fns is declared an optional peer dependency. UniversalFilter is reachable from the package barrel, so import { anything } from '@sistent/sistent' executes a top-level require('date-fns') and throws for any consumer that has not installed it.

This is the same root cause #1732 fixed for @mui/x-date-pickers. That PR resolved one instance and revealed this one behind it.

Reproduction (against published 0.21.39)

mkdir /tmp/repro && cd /tmp/repro && npm init -y
npm i @sistent/sistent@0.21.39 react react-dom @mui/material @mui/system @emotion/react @emotion/styled
node -e "require('@sistent/sistent')"
Error: Cannot find module 'date-fns'
Require stack:
- /tmp/repro/node_modules/@sistent/sistent/dist/index.js

Installing date-fns makes it resolve cleanly, confirming it is the only remaining instance.

Before #1732 the same reproduction failed on Cannot find module '@mui/x-date-pickers/AdapterDateFns', so this is not a regression - it is the next optional peer in line.

Impact

layer5labs/meshery-extensions (ui/package.json) depends on @sistent/sistent and has neither date-fns nor @mui/x-date-pickers. Any test or module there that imports anything from the barrel still fails on a clean install, with a message that names sistent rather than the missing peer - the diagnostic problem #1732 set out to remove.

meshery/meshery (ui/package.json) has both (date-fns@^4.4.0, @mui/x-date-pickers@^9.6.0) and is unaffected.

Root cause

The declaration and the usage disagree. date-fns is marked optional:

"peerDependenciesMeta": { "date-fns": { "optional": true } }

but UniversalFilter uses it unconditionally. An optional dependency has to be either used conditionally or declared honestly - right now it is neither.

Scope

Exactly one instance remains. @mui/x-date-pickers is fully resolved (only type-only imports, erased at runtime, plus dynamic import()):

File Import Runtime require?
src/custom/UniversalFilter.tsx:3 import { subDays, subMonths, subYears } from 'date-fns' yes - the bug
src/base/DateTimePicker/DateTimePicker.tsx:1 import type ... no
src/base/DateTimePicker/index.tsx:1 import type ... no
src/base/DateTimePicker/DateTimePicker.tsx:21-23 dynamic import() no

Options

A. Declare date-fns a real dependency. One line in package.json; makes the declaration match the unconditional usage. Adds a dependency for every consumer.

B. Drop date-fns here in favour of moment, which is already a hard dependency of sistent (^2.30.1), so it is always installed. The usage is three calls inside lazily-invoked getRange closures:

{ label: 'Last 7 days',   getRange: () => ({ startDate: subDays(new Date(), 7),    endDate: new Date() }) },
{ label: 'Last 3 months', getRange: () => ({ startDate: subMonths(new Date(), 3),  endDate: new Date() }) },
{ label: 'Last 1 year',   getRange: () => ({ startDate: subYears(new Date(), 1),   endDate: new Date() }) },

moment().subtract(n, 'days'|'months'|'years').toDate() is equivalent for these, including the end-of-month clamping subMonths does. Zero new dependencies, and it removes an optional peer from the barrel's runtime graph entirely.

B is preferable on dependency hygiene. Flagging that UniversalFilter.tsx may have work in flight, so B is best folded into whoever is already touching it rather than landed in parallel.

Suggested guard

Whichever option is taken, the failure mode is invisible to this repo's CI because the repo always has its own devDependencies installed. A check that imports the built barrel with only the required peers present would catch the next instance:

node -e "require('./dist/index.js')"   # in a dir without the optional peers

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions