faker icon indicating copy to clipboard operation
faker copied to clipboard

Add support for generating ULID

Open matthewmayer opened this issue 1 year ago • 9 comments

Clear and concise description of the problem

There is another type of unique identifier other than UUID that is called ULID Universally Unique Lexicographically Sortable Identifier. This type of identifier has the benefit of maintaining a sortable order and is useful as primary keys on databases (mainly NoSQL) to get free date-time sorting out of the box. More information here

ULID is a 26 characters string which the first 10 characters are the timestamp as millis from the epoch and the other 16 are the randomness. The allowed characters are from Crockford's Base32 which excludes letters I, L, and O to avoid confusion with digits.

Suggested solution

ulid(): string {
    return (
      this.fromCharacters('012', 1) +
      this.fromCharacters('0123456789ABCDEFGHJKMNPQRSTVWXYZ', 25)
    );
  }

On the code excerpt above it is using the first character as [012] because that would already generate dates up to year 5314 which is more than enough. To confirm this behavior you can go here and try using 2ZZZZZZZZZWZYF0EJ600G2SZHA as an ULID.

Alternative

Allow it to use a refDate() like the methods in faker.date?

Additional context

Originally proposed by brunocleite at https://github.com/faker-js/faker/pull/2524#issuecomment-1932416156

Creating an issue here to allow it to collect upvotes, and discuss possible implementation strategies.

matthewmayer avatar Feb 08 '24 00:02 matthewmayer

Thank you for your feature proposal.

We marked it as "waiting for user interest" for now to gather some feedback from our community:

  • If you would like to see this feature be implemented, please react to the description with an up-vote (:+1:).
  • If you have a suggestion or want to point out some special cases that need to be considered, please leave a comment, so we are aware about them.

We would also like to hear about other community members' use cases for the feature to give us a better understanding of their potential implicit or explicit requirements.

We will start the implementation based on:

  • the number of votes (:+1:) and comments
  • the relevance for the ecosystem
  • availability of alternatives and workarounds
  • and the complexity of the requested feature

We do this because:

  • There are plenty of languages/countries out there and we would like to ensure that every method can cover all or almost all of them.
  • Every feature we add to faker has "costs" associated to it:
    • initial costs: design, implementation, reviews, documentation
    • running costs: awareness of the feature itself, more complex module structure, increased bundle size, more work during refactors

View more issues which are waiting for user interest

github-actions[bot] avatar Feb 08 '24 00:02 github-actions[bot]

i would tend to agree with @Shinigami92 that, given that one of the key points of ULID is that it embeds a date, having more control over the range of dates embedded in the ULID would be useful. Either you pass it a specific date and it just adds the random part, or you can pass a range of dates and it creates within that range?

matthewmayer avatar Feb 08 '24 00:02 matthewmayer

The question is, is the timestamp relevant for our users? If it is and they already use ulids, then they could generate a date and pass it to their ulid library. IMO we should start with random ulids, if users need time based ones, then they should open a new issue. Note we also don't have a time based uuid.

ST-DDT avatar Feb 08 '24 16:02 ST-DDT

Note we also don't have a time based uuid.

That's because we only provide UUID v4 right now. Until now there was never a feature request to support timed UUIDs like v1, v2, v6 and v7.

Shinigami92 avatar Feb 09 '24 17:02 Shinigami92

Until now there was never a feature request to support timed UUIDs like v1, v2, v6 and v7.

IMO random ulids and time based ulids are two different feature requests. Yes, you could implement them together, but if there is no real interest in time based ones, I don't see a point adding them. If there was an interest in time based stuff, I would have expected a feature request for time based uuids as well, but so far there aren't any.

ST-DDT avatar Feb 09 '24 17:02 ST-DDT

Do you have a need for time based ulids or are you asking for them just because the are in the standard?

ST-DDT avatar Feb 09 '24 17:02 ST-DDT

I think just wait until we have a few more upvotes on this. We don't have enough information on how this would be used to make a sensible decision yet.

matthewmayer avatar Feb 10 '24 01:02 matthewmayer

Team Decision

This has gathered enough interest. Additionally, we consider it useful for inclusion in faker v9.x.

We will review brunocleite's PR in the near future:

  • https://github.com/faker-js/faker/pull/2524

PS: @brunocleite, could you please leave a comment here, so we can assign this issue to you?

ST-DDT avatar Jul 04 '24 15:07 ST-DDT

@ST-DDT Yes, you can assign it to me, please. I have updated the PR with a more elaborated solution including support for refDate.

brunocleite avatar Jul 04 '24 19:07 brunocleite