Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(string): adds support for generating ULID #2524

Open
wants to merge 11 commits into
base: next
Choose a base branch
from

Conversation

brunocleite
Copy link

@brunocleite brunocleite commented Nov 3, 2023

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.

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.

@brunocleite brunocleite requested a review from a team as a code owner November 3, 2023 17:26
@xDivisionByZerox xDivisionByZerox added c: feature Request for new feature p: 1-normal Nothing urgent s: awaiting more info Additional information are requested s: needs decision Needs team/maintainer decision m: string Something is referring to the string module labels Nov 3, 2023
@brunocleite
Copy link
Author

Update: improved the description

@xDivisionByZerox
Copy link
Member

Thank you for your contribution. Since this PR doesn't have a relatet issue, please understand that we might need some time to decide on the usability of this feature. Thank you for your patience.

Copy link

codecov bot commented Nov 3, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.94%. Comparing base (a27aafe) to head (f41fd27).

❗ Current head f41fd27 differs from pull request most recent head 6fcba2c. Consider uploading reports for the commit 6fcba2c to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #2524      +/-   ##
==========================================
- Coverage   99.94%   99.94%   -0.01%     
==========================================
  Files        2958     2958              
  Lines      213715   213730      +15     
  Branches      603      952     +349     
==========================================
+ Hits       213595   213602       +7     
- Misses        120      124       +4     
- Partials        0        4       +4     
Files Coverage Δ
src/modules/string/index.ts 100.00% <100.00%> (ø)

... and 5 files with indirect coverage changes

@ST-DDT ST-DDT added this to the vFuture milestone Nov 7, 2023
@ST-DDT ST-DDT added s: waiting for user interest Waiting for more users interested in this feature and removed s: awaiting more info Additional information are requested s: needs decision Needs team/maintainer decision labels Nov 7, 2023
@ST-DDT
Copy link
Member

ST-DDT commented Nov 7, 2023

Team Decision

  • We checked the project activity and downloads and while it has some, we are waiting for more interest from the community before adding it to our official API.

The PR description contains a script that can be used as a workaround.

@ST-DDT ST-DDT added the has workaround Workaround provided or linked label Nov 7, 2023
@matthewmayer
Copy link
Contributor

Can we add a matching issue so it can collect upvotes?

@ant1m4tt3r
Copy link

didn't find any issues related to this, but I would like to state my support for this feature!

@Shinigami92
Copy link
Member

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.

While that might be true, I would be in favor to build it differently and make use of refDate like we do in other functions 🤔

@matthewmayer
Copy link
Contributor

Added #2648 to allow for collecting upvotes (we normally try to get 10 upvotes to indicate sufficient interest) and further promote discussion

@matthewmayer matthewmayer linked an issue Feb 8, 2024 that may be closed by this pull request
@ST-DDT
Copy link
Member

ST-DDT commented Mar 15, 2024

@brunocleite Please fix the failing tests. Probably using pnpm run preflight.

Copy link

netlify bot commented Mar 18, 2024

Deploy Preview for fakerjs ready!

Name Link
🔨 Latest commit 6fcba2c
🔍 Latest deploy log https://app.netlify.com/sites/fakerjs/deploys/65fae9f3e28c54000899f40a
😎 Deploy Preview https://deploy-preview-2524.fakerjs.dev
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

*/
ulid(): string {
return (
this.fromCharacters('012', 1) +
Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps add a comment here that ULIDs starting with 0, 1 or 2 cover the years 1970-5314

Copy link
Author

Choose a reason for hiding this comment

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

I've updated the PR with a new solution proposal addressing the suggestions by @Shinigami92.
It should now generate the timestamp part of the ULID from refDate.

@brunocleite
Copy link
Author

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.

While that might be true, I would be in favor to build it differently and make use of refDate like we do in other functions 🤔

Thanks. I'm looking at the examples on faker.date.anytime() and makes sense to use refDate.
ULIDs objective is to generate IDs that contains current timestamp and are sortable, so I'm seeing your point, as the way it was implemented before would generate ULIDs with extreme dates like year 3000 or 4000. Or even 1970 when ULIDs didn't even exist. So using refDate as an optional argument, falling back to defaultRefDate seems like a good choice.

I've done a proposal implementation and updated this PR to achieve this, though, I have a couple questions:

  1. I needed similar functionality to toDate function , which lives on date/index.ts and it is not exported. Likewise, I've copied the code over to ULID implementation, but just asking if there could be a better way to avoid repetition.
  2. We will need a function encodeTime (see here) to convert a Date to a 10 character string. This 10 character string is the encoded date, which is the beginning of the ULID string. I've stored this function along with ULID implementation.

@matthewmayer
Copy link
Contributor

toDate is currently being rewritten as part of #2757 so probably makes sense to wait for that to be merged first.

Copy link
Member

@ST-DDT ST-DDT left a comment

Choose a reason for hiding this comment

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

Please note that this is still waiting for community interest.

const { refDate } = options;
let date = refDate;

if (date == null) {
Copy link
Member

Choose a reason for hiding this comment

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

I think the comment was more about adding a comment to explain the magic numbers than to add an refDate parameter.
Nevertheless instead of copying the implementation, we should export the toDate function as internal helper and reuse it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: feature Request for new feature has workaround Workaround provided or linked m: string Something is referring to the string module p: 1-normal Nothing urgent s: waiting for user interest Waiting for more users interested in this feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for generating ULID
6 participants