Skip to content

[build-utils] add state property to NodeVersion #12883

Merged
erikareads merged 12 commits intomainfrom
erikarowland/add-state-property-to-node-version-type
Jan 23, 2025
Merged

[build-utils] add state property to NodeVersion #12883
erikareads merged 12 commits intomainfrom
erikarowland/add-state-property-to-node-version-type

Conversation

@erikareads
Copy link
Copy Markdown
Contributor

@erikareads erikareads commented Jan 18, 2025

Overview

This PR adds a state property to the NodeVersion type. One of 'active' | 'deprecated' | 'discontinued'. This changes NodeVersion from an interface with optional fields to a tagged union with state as a discriminator.

Now discontinueDate is a required field only on DeprecatedNodeVersion and not a field on the other two alternatives.

Goal

The state property makes it clear at a glance what state a given NodeVersion in NODE_VERSIONS is in.

Previously, code assumed that if a discontinueDate had been set, a version was deprecated, but this assumption was not explicit in the code.

This PR makes that assumption explicit.

Work Done

  • Updated the NodeVersion type to be a type union of tagged alternatives, one of each state.
  • Updated NODE_VERSIONS to include the state property.
  • Updated the helper functions node-version.ts to account for the state property.
  • Updated some language in the warnings printed by node-version.ts to use our newly considered terminology around deprecation and discontinuation.
  • Updated project list --updated-required to use the state property.
  • Updated RubyVersion which depended directly on NodeVersion being an extensible interface instead of a type union.

Questions

  • Do we want another field name besides state? If so, what?
  • Do we want RubyVersion to still be dependent on NodeVersion?
  • Is there any reason to include discontinueDate for discontinue state Node Versions?

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jan 18, 2025

🦋 Changeset detected

Latest commit: bf70539

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@vercel/build-utils Minor
vercel Patch
@vercel/ruby Minor
@vercel/client Patch
@vercel/gatsby-plugin-vercel-builder Patch
@vercel/node Patch
@vercel/static-build Patch
@vercel-internals/types Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@erikareads erikareads changed the title [cli] update warning in ls --update-required for clarity [build-utils] add state property to NodeVersion Jan 18, 2025
@erikareads erikareads marked this pull request as ready for review January 21, 2025 18:03
@erikareads erikareads force-pushed the erikarowland/add-state-property-to-node-version-type branch from 95eb6b2 to 7608117 Compare January 21, 2025 18:48
Copy link
Copy Markdown
Contributor

@EndangeredMassa EndangeredMassa left a comment

Choose a reason for hiding this comment

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

I left comments, but nothing blocking.

}

function isDiscontinued({ discontinueDate }: NodeVersion): boolean {
function isDiscontinued(nodeVersion: NodeVersion): boolean {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (non-blocking): Is there a better way to model the fact that a state of deprecated with a discontinueDate in the past is essentially the same state of discontinued?

Ideally, we wouldn't need logic to check that nodeVersion.state === 'deprecated' && nodeVersion.discontinueDate.getTime() <= today because the moment those dates crossed paths, the system would udpate the state to discontinued. If we were storing this data in a database, we could set up a cron or other trigger to make that happen.

Because we don't have a database for this data (and I'm not suggesting adding one with API calls to access it), the state situation gets messy.‏

The best way to accomplish something similar here (in my opinion) is to use an object with a isDiscontinued() function or an explicit state getter that would literally translate "a state of deprecated with a discontinueDate in the past" into a state of `discontinued.

Copy link
Copy Markdown
Contributor Author

@erikareads erikareads Jan 22, 2025

Choose a reason for hiding this comment

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

This awkwardness around dates is something I've been debating since I started considering this change.

The problem here is that we have CLI users that won't be updating the instant we mark something as discontinued, so we need to check the date for users that have a version of build-utils that isn't yet updated to mark a version as discontinued.

There are a few alternatives we could use here:

1 Call an API to check latest up-to-date information about a Node Version

Upsides:

  • This gives us centralized control of when a version is deprecated or discontinued, across all users regardless of CLI version (post API change)
  • Allows us to dispense with date checking entirely.

Downsides:

  • Adds an extra API call to a fairly elemental operation, likely to balloon to a significant number of API calls if we don't cache this value appropriately in the same API change.

2 Add a state property to NodeVersion

Upsides:

  • Gives us a clear indicator in the code, where the data lives, when we update the state of a Node Version
  • Makes explicit any assumptions about version deprecation
  • Allows us to use type alternatives that eliminate unneeded fields in the active case

Downsides:

  • We still need to care about the passage of time
  • This information has to be remembered and updated as part of the deprecation and discontinuation processes
  • This information can drift relative to what's supported on the Vercel platform

3 Exported versionState function that returns one of 'active' | 'deprecated' | 'discontinued'

Upsides:

  • Allows us to isolate the date calculation in one place
  • Reflects the true reality that true state of version depends on the current date
  • Allows elimination of some booleans

Downsides:

  • Moves the logic about current state away from the NODE_VERSIONS constant

4 Do 2 and 3

Upsides:

  • Upsides of both 2 and 3

Downsides:

  • Removes the single point of truth from NODE_VERSIONS constant
  • Could allow people to directly access the state property, thereby potentially incorrectly getting the current state if the date is late enough

5 Turn NodeVersion into a class with a get implementation for state

Upsides:

  • Upsides of both 2 and 3
  • Remove ambiguity created by 4

Downsides:

  • There may be consequences for turning NodeVersion into a Class

There is another scenario I hadn't considered yet, and I'm not certain we handle their case gracefully: a user who has a sufficiently old version of build-utils that their version hasn't even marked a Node Version as deprecated when that version is discontinued.

Do we have appropriate error handling and communication for this case?

@erikareads erikareads added this pull request to the merge queue Jan 23, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 23, 2025
@erikareads erikareads added this pull request to the merge queue Jan 23, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 23, 2025
@erikareads erikareads added this pull request to the merge queue Jan 23, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 23, 2025
@erikareads erikareads added this pull request to the merge queue Jan 23, 2025
Merged via the queue into main with commit 3a5507f Jan 23, 2025
@erikareads erikareads deleted the erikarowland/add-state-property-to-node-version-type branch January 23, 2025 23:10
EndangeredMassa pushed a commit that referenced this pull request Jan 28, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @vercel/[email protected]

### Major Changes

- Initial release
([#12903](#12903))

## @vercel/[email protected]

### Minor Changes

- Add `useWebApi` property to `NodejsLambda` class
([#12873](#12873))

- [build-utils] convert NodeVersion to class and add state getter
([#12883](#12883))
    [ruby] convert RubyVersion to class and add state getter

## [email protected]

### Minor Changes

- [cli] add Node Version to project list output table
([#12895](#12895))

### Patch Changes

- Enable executable bit for `src/vc.js` script
([#12863](#12863))

- Add video integration category to the integration install CLI
([#12870](#12870))

- [cli] update warning in ls --update-required for clarity
([#12864](#12864))

- Added headers for user-supplied rewrites
([#12847](#12847))

- [cli] refactor confirm component to use `client.input.confirm`
interface ([#12846](#12846))

- [build-utils] convert NodeVersion to class and add state getter
([#12883](#12883))
    [ruby] convert RubyVersion to class and add state getter

- Updated dependencies
\[[`56f72ffefb828c3001f7c82259ed0f71db4f629e`](56f72ff),
[`745404610a836fa6c2068c5c192d2f3e8b86918f`](7454046),
[`b6bb709370d2565121808340d43d0a9d90b53de1`](b6bb709),
[`85a64db8d9b6a6e9f7c6a019d51777930a806584`](85a64db),
[`ac6a62eff7db3b3e2713adc1f5bd6a1331d838ce`](ac6a62e),
[`f65ea2245382dd2449c96f695ed692d419a83868`](f65ea22),
[`7af40c1e9d9916cbe8287359662fc940f1d24fce`](7af40c1),
[`06307180c20ca07b65f7cb5e93b65c977b9ccd70`](0630718),
[`3a5507fd1459c77b4491f1c9c3a64ad42e4ff009`](3a5507f),
[`cefda60a603d60cc35e4697c36e751cca411e6bb`](cefda60),
[`003866c4c93e893edb7a5e89b519fc8879b370c0`](003866c)]:
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]

## @vercel/[email protected]

### Minor Changes

- Make vite detection supersede ionic-react
([#12880](#12880))

## @vercel/functions@1.6.0

### Minor Changes

- Add middleware-related helper functions
([#12938](#12938))

## @vercel/[email protected]

### Minor Changes

- Add support for React Router v7
([#12904](#12904))

- Enable `nativeFetch` when `v3_singleFetch` future flag is enabled
([#12918](#12918))

### Patch Changes

- [remix] Create an interface for differences remix vs react-router
([#12925](#12925))

## @vercel/[email protected]

### Minor Changes

- [build-utils] convert NodeVersion to class and add state getter
([#12883](#12883))
    [ruby] convert RubyVersion to class and add state getter

## @vercel/[email protected]

### Patch Changes

- Updated dependencies
\[[`745404610a836fa6c2068c5c192d2f3e8b86918f`](7454046),
[`3a5507fd1459c77b4491f1c9c3a64ad42e4ff009`](3a5507f)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- Bump next from 14.2.10 to 14.2.21
([#12842](#12842))

## @vercel/[email protected]

### Patch Changes

- Fix local file system readdir to not throw on special file system stat
types ([#12915](#12915))

- Updated dependencies
\[[`d645bdd4312730b10bef89ad9e18e111500849fc`](d645bdd)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- Updated dependencies
\[[`745404610a836fa6c2068c5c192d2f3e8b86918f`](7454046),
[`3a5507fd1459c77b4491f1c9c3a64ad42e4ff009`](3a5507f)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- ensure defaultLocale rewrite doesn't conflict with user-defined
redirects ([#12916](#12916))

- Added headers for user-supplied rewrites
([#12847](#12847))

## @vercel/[email protected]

### Patch Changes

- Fix requests failing due to the presence of `Transfer-Encoding` header
in edge-function dev server.
([#10701](#10701))

- Split `build()`, `prepareCache()` and `startDevServer()` into separate
files ([#12872](#12872))

- Updated dependencies
\[[`745404610a836fa6c2068c5c192d2f3e8b86918f`](7454046),
[`3a5507fd1459c77b4491f1c9c3a64ad42e4ff009`](3a5507f)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- Remove support for VERCEL_IPC_FD
([#12908](#12908))

- Add `supportsResponseStreaming` to build output
([#12884](#12884))

## @vercel/[email protected]

### Patch Changes

-   Updated dependencies \[]:
    -   @vercel/[email protected]

## @vercel-internals/[email protected]

### Patch Changes

- Updated dependencies
\[[`745404610a836fa6c2068c5c192d2f3e8b86918f`](7454046),
[`3a5507fd1459c77b4491f1c9c3a64ad42e4ff009`](3a5507f)]:
    -   @vercel/[email protected]

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
QuietCraftsmanship pushed a commit to QuietCraftsmanship/Vercel that referenced this pull request Jul 6, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @vercel/[email protected]

### Major Changes

- Initial release
([#12903](vercel/vercel#12903))

## @vercel/[email protected]

### Minor Changes

- Add `useWebApi` property to `NodejsLambda` class
([#12873](vercel/vercel#12873))

- [build-utils] convert NodeVersion to class and add state getter
([#12883](vercel/vercel#12883))
    [ruby] convert RubyVersion to class and add state getter

## [email protected]

### Minor Changes

- [cli] add Node Version to project list output table
([#12895](vercel/vercel#12895))

### Patch Changes

- Enable executable bit for `src/vc.js` script
([#12863](vercel/vercel#12863))

- Add video integration category to the integration install CLI
([#12870](vercel/vercel#12870))

- [cli] update warning in ls --update-required for clarity
([#12864](vercel/vercel#12864))

- Added headers for user-supplied rewrites
([#12847](vercel/vercel#12847))

- [cli] refactor confirm component to use `client.input.confirm`
interface ([#12846](vercel/vercel#12846))

- [build-utils] convert NodeVersion to class and add state getter
([#12883](vercel/vercel#12883))
    [ruby] convert RubyVersion to class and add state getter

- Updated dependencies
\[[`97e4eb3c468b4c35c4b930137215ecd018707121`](vercel/vercel@97e4eb3),
[`0aea17613bd7c4b0cbf174f654efa0cf3abee363`](vercel/vercel@0aea176),
[`c8b8fdca6333c3d4503be696d046f57b2f221431`](vercel/vercel@c8b8fdc),
[`e7536c62bebab05ea989cf10de28c9dc311be2e8`](vercel/vercel@e7536c6),
[`33c6e67f14854ef680db612944063fc405843827`](vercel/vercel@33c6e67),
[`0ded32e2d5ae1d9812d70eb281b226e057b016a9`](vercel/vercel@0ded32e),
[`e1e6b58819ad8606ed4e963af5e1e58984cf02d7`](vercel/vercel@e1e6b58),
[`44dd8ccf5235c7019c14d2a8e34c4c0733ce110d`](vercel/vercel@44dd8cc),
[`1a4f0521f984ce891a3e9847d31e569f407c4319`](vercel/vercel@1a4f052),
[`ff43e4bf3f15a8875afe6f3cc9e22a37110f3751`](vercel/vercel@ff43e4b),
[`a376e638ffe384b962b14685293bccfb4507ab90`](vercel/vercel@a376e63)]:
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]
    -   @vercel/[email protected]

## @vercel/[email protected]

### Minor Changes

- Make vite detection supersede ionic-react
([#12880](vercel/vercel#12880))

## @vercel/[email protected]

### Minor Changes

- Add middleware-related helper functions
([#12938](vercel/vercel#12938))

## @vercel/[email protected]

### Minor Changes

- Add support for React Router v7
([#12904](vercel/vercel#12904))

- Enable `nativeFetch` when `v3_singleFetch` future flag is enabled
([#12918](vercel/vercel#12918))

### Patch Changes

- [remix] Create an interface for differences remix vs react-router
([#12925](vercel/vercel#12925))

## @vercel/[email protected]

### Minor Changes

- [build-utils] convert NodeVersion to class and add state getter
([#12883](vercel/vercel#12883))
    [ruby] convert RubyVersion to class and add state getter

## @vercel/[email protected]

### Patch Changes

- Updated dependencies
\[[`0aea17613bd7c4b0cbf174f654efa0cf3abee363`](vercel/vercel@0aea176),
[`1a4f0521f984ce891a3e9847d31e569f407c4319`](vercel/vercel@1a4f052)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- Bump next from 14.2.10 to 14.2.21
([#12842](vercel/vercel#12842))

## @vercel/[email protected]

### Patch Changes

- Fix local file system readdir to not throw on special file system stat
types ([#12915](vercel/vercel#12915))

- Updated dependencies
\[[`ac4318615e248752ad20ca031f7c903e76e52899`](vercel/vercel@ac43186)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- Updated dependencies
\[[`0aea17613bd7c4b0cbf174f654efa0cf3abee363`](vercel/vercel@0aea176),
[`1a4f0521f984ce891a3e9847d31e569f407c4319`](vercel/vercel@1a4f052)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- ensure defaultLocale rewrite doesn't conflict with user-defined
redirects ([#12916](vercel/vercel#12916))

- Added headers for user-supplied rewrites
([#12847](vercel/vercel#12847))

## @vercel/[email protected]

### Patch Changes

- Fix requests failing due to the presence of `Transfer-Encoding` header
in edge-function dev server.
([#10701](vercel/vercel#10701))

- Split `build()`, `prepareCache()` and `startDevServer()` into separate
files ([#12872](vercel/vercel#12872))

- Updated dependencies
\[[`0aea17613bd7c4b0cbf174f654efa0cf3abee363`](vercel/vercel@0aea176),
[`1a4f0521f984ce891a3e9847d31e569f407c4319`](vercel/vercel@1a4f052)]:
    -   @vercel/[email protected]

## @vercel/[email protected]

### Patch Changes

- Remove support for VERCEL_IPC_FD
([#12908](vercel/vercel#12908))

- Add `supportsResponseStreaming` to build output
([#12884](vercel/vercel#12884))

## @vercel/[email protected]

### Patch Changes

-   Updated dependencies \[]:
    -   @vercel/[email protected]

## @vercel-internals/[email protected]

### Patch Changes

- Updated dependencies
\[[`0aea17613bd7c4b0cbf174f654efa0cf3abee363`](vercel/vercel@0aea176),
[`1a4f0521f984ce891a3e9847d31e569f407c4319`](vercel/vercel@1a4f052)]:
    -   @vercel/[email protected]

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants