{"id":27001815,"url":"https://github.com/manferlo81/gen-unit","last_synced_at":"2025-04-04T04:20:12.414Z","repository":{"id":38377781,"uuid":"217009582","full_name":"manferlo81/gen-unit","owner":"manferlo81","description":"A generic unit parser/formatter","archived":false,"fork":false,"pushed_at":"2025-03-13T01:48:01.000Z","size":2931,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-13T02:34:00.719Z","etag":null,"topics":["format","formatter","generic","parse","parser","unit","units"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/manferlo81.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-23T08:41:54.000Z","updated_at":"2025-03-13T01:46:55.000Z","dependencies_parsed_at":"2024-08-09T11:11:21.606Z","dependency_job_id":"966dec13-0b93-40ca-ad40-5f39a1268288","html_url":"https://github.com/manferlo81/gen-unit","commit_stats":{"total_commits":815,"total_committers":3,"mean_commits":271.6666666666667,"dds":0.5656441717791412,"last_synced_commit":"559935b4983b31e47c392d7630069b6a348b2737"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manferlo81%2Fgen-unit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manferlo81%2Fgen-unit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manferlo81%2Fgen-unit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manferlo81%2Fgen-unit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manferlo81","download_url":"https://codeload.github.com/manferlo81/gen-unit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247118651,"owners_count":20886591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["format","formatter","generic","parse","parser","unit","units"],"created_at":"2025-04-04T04:20:11.928Z","updated_at":"2025-04-04T04:20:12.397Z","avatar_url":"https://github.com/manferlo81.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gen-unit\n\n[![CI](https://github.com/manferlo81/gen-unit/actions/workflows/ci.yml/badge.svg?branch=main\u0026event=push)](https://github.com/manferlo81/gen-unit/actions/workflows/ci.yml)\n[![npm](https://badgen.net/npm/v/gen-unit)](https://www.npmjs.com/package/gen-unit)\n[![codecov](https://codecov.io/gh/manferlo81/gen-unit/branch/main/graph/badge.svg?token=ktaVkBtlbH)](https://codecov.io/gh/manferlo81/gen-unit)\n[![dependabot](https://badgen.net/github/dependabot/manferlo81/gen-unit)](https://github.com/manferlo81/gen-unit)\n[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/gen-unit/badge?style=rounded)](https://www.jsdelivr.com/package/npm/gen-unit)\n[![Libraries.io dependency status for latest release](https://img.shields.io/librariesio/release/npm/gen-unit)](https://libraries.io/npm/gen-unit)\n[![install size](https://packagephobia.com/badge?p=gen-unit)](https://packagephobia.com/result?p=gen-unit)\n[![bundlephobia](https://badgen.net/bundlephobia/min/gen-unit)](https://bundlephobia.com/result?p=gen-unit)\n[![types](https://img.shields.io/npm/types/gen-unit.svg)](https://github.com/microsoft/typescript)\n[![Known Vulnerabilities](https://snyk.io/test/github/manferlo81/gen-unit/badge.svg?targetFile=package.json)](https://snyk.io/test/github/manferlo81/gen-unit?targetFile=package.json)\n[![license](https://badgen.net/github/license/manferlo81/gen-unit)](LICENSE)\n\nA generic unit parser/formatter\n\n## Install\n\n```bash\n# Using npm\nnpm i gen-unit\n\n# Using yarn\nyarn add gen-unit\n```\n\n## API\n\n- `createParser` [function](#the-createparser-function)\n- `createParser` [options](#createparser-options)\n  - `unit` [option](#the-unit-option)\n  - `match` [option](#the-match-option)\n    - `match` [option as a RegExp](#match-option-as-a-regexp)\n    - `match` [option as a string](#match-option-as-a-string)\n    - `match` [option as a function](#match-option-as-a-function)\n  - `find` [option](#the-find-option)\n    - `find` [option as a number](#find-option-as-a-number)\n    - `find` [option as an array](#find-option-as-an-array)\n    - `find` [option as an object](#find-option-as-an-object)\n    - `find` [option as a function](#find-option-as-a-function)\n- `createFormatter` [function](#the-createformatter-function)\n- `createFormatter` [options](#createformatter-options)\n  - `unit` [option](#the-unit-option-1)\n  - `find` [option](#the-find-option-1)\n    - `find` [option as a number](#find-option-as-a-number-1)\n    - `find` [option as an array](#find-option-as-an-array-1)\n    - `find` [option as an object](#find-option-as-an-object-1)\n    - `find` [option as a function](#find-option-as-a-function-1)\n  - `round` [option](#the-round-option)\n    - `round` [option as an object](#round-option-as-an-object)\n    - `round` [option as a number](#round-option-as-a-number)\n    - `round` [option as a function](#round-option-as-a-function)\n  - `output` [option](#the-output-option)\n    - `output` [option as an object](#output-option-as-an-object)\n    - `output` [option as a function](#output-option-as-a-function)\n- `parse` [function](#the-parse-function)\n- `format` [function](#the-format-function)\n- `MICRO` [constant](#the-micro-constant)\n\n### The `createParser` function\n\nCreates a `parse` function using the given [options](#createparser-options).\n\n```typescript\nfunction createParser(options): Parser;\n\ntype Parser = (input: unknown) =\u003e number;\n```\n\n### `createParser` options\n\n#### The `unit` option\n\nDefines the `unit` to be used during parsing.\n\n```typescript\nunit: string;\n```\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  unit: 'g',\n});\n\nparse('1'); // =\u003e 1\nparse('1 g'); // =\u003e 1\nparse('1 m'); // =\u003e 0.001\nparse('1 mg'); // =\u003e 0.001\nparse('1 k'); // =\u003e 1000\nparse('1 kg'); // =\u003e 1000\nparse('1 ms'); // =\u003e NaN because \"s\" is not recognized as unit\n```\n\n***Precedence***\n\nThis option takes precedence over any `prefix` or `prefixed unit`.\n\n***Examples***\n\n```typescript\nconst parseMeter = createParser({\n  unit: 'm', // Meter\n});\n\nparseMeter('1 m'); // returns 1 (1 meter)\nparseMeter('1 mm'); // returns 0.001 (1 millimeter)\n```\n\n```typescript\nconst parseSecond = createParser({\n  unit: 's' // Seconds\n});\n\nparseSecond('1 m'); // returns 0.001 (1 millisecond)\nparseSecond('1 ms'); // returns 0.001 (1 millisecond)\n```\n\n```typescript\nconst parse = createParser({\n  unit: 'eg', // assuming \"eg\" is the unit... for some reason\n});\n\nparse('1 meg'); // =\u003e 0.001 (not 1000000), it's interpreted as 1 milli-eg\nparse('1 megeg'); // =\u003e 1000000, it's interpreted as 1 mega-eg\nparse('1 Meg'); // =\u003e 1000000, it's interpreted as 1 mega-eg because capital \"M\" parses as mega\n```\n\n#### The `match` option\n\n```typescript\nmatch: RegExp | string | MatchFunction;\n\ntype MatchFunction = (input: string) =\u003e [value: string, unit: string] | null | undefined;\n\ndefault /^\\s*(-?\\d*\\.?\\d*(?:e[+-]?\\d+)?)\\s*([a-z\\xb5]*)\\s*$/i\n```\n\nDefines the first step in the `parse` process, it takes the `input` and should turn it into an `array` with `two elements` with the `value`, and the `unit` to be process further down the road, or `null` (or `undefined`) if the `input` can't be parsed.\n\n##### `match` option as a RegExp\n\n```typescript\nmatch: RegExp;\n\ndefault /^\\s*(-?\\d*\\.?\\d*(?:e[+-]?\\d+)?)\\s*([a-z\\xb5]*)\\s*$/i\n```\n\nA RegExp with `two capturing groups`, the first to be used as `value` and the second as `unit`. If the RegExp has less than `two capturing groups`, parse function will `throw`.\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  match: /^\\s*([\\d.]+)\\s*([a-z]*)\\s*$/i,\n});\n\nparse('1 m'); // =\u003e 0.001\nparse('1 k'); // =\u003e 1000\n```\n\n##### `match` option as a string\n\n```typescript\nmatch: string;\n```\n\nA string to be used to create a RegExp. It is expected to have `two capturing groups`, the first to be used as `value` and the second as `unit`.\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  match: '^\\\\s*([\\\\d.]+)\\\\s*([a-z]*)\\\\s*$',\n});\n\nparse('1 m'); // =\u003e 0.001\nparse('1 k'); // =\u003e 1000\n```\n\n##### `match` option as a function\n\n```typescript\nmatch: (input: string) =\u003e [value: string, unit: string] | null | undefined;\n```\n\nA function which will receive the `input` and should return an `array` of `two elements`, the first to be used as `value` and the second as `unit`, or `null` (or `undefined`) if the input can't be parsed.\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  match(input) {\n    return [input, 'k']\n  },\n});\n\nparse('1'); // =\u003e 1000\nparse('2'); // =\u003e 2000\n```\n\n#### The `find` option\n\nThe `find` option describes how to find the multiplier which is the `number` by which the parsed value should be multiplied.\n\n##### `find` option as a number\n\n```typescript\nfind: number;\n```\n\nA number to be used as `base` during parsing.\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  find: 1024,\n});\n\nparse('2'); // =\u003e 2\nparse('2 k'); // =\u003e 2048\nparse('2 M'); // =\u003e 2097152\nparse('2 G'); // =\u003e 2147483648\n```\n\n##### `find` option as an array\n\n```typescript\nfind: Array\u003c{ pre: string; exp: number }\u003e;\n```\n\nAn `array` of `objects` describing `prefixes` and `exponents` to use with the default `base` (1000) to find the `multiplier` to be used during parsing. Every item should have a unique `pre`, if there are duplicates `createParser` will `throw`.\n\n***notes***\n\nNote that `empty prefix` (`{ pre: '', exp: 0 }`) is not necessary, as an `empty prefix` will result in `multiplier = 1`\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  find: [\n    { pre: 'k', exp: 1 },\n    { pre: 'M', exp: 2 },\n  ],\n});\n\nparse('1.3'); // =\u003e 1.3\nparse('1.3 k'); // =\u003e 1300\nparse('1.3 M'); // =\u003e 1300000\nparse('1.3 G'); // =\u003e NaN because prefix \"G\" can't be found\n```\n\n##### `find` option as an object\n\n```typescript\nfind: {\n  base?: number;\n  items?: Array\u003c{ pre: string; exp: number }\u003e;\n};\n\ndefault: {\n  base: 1000,\n  items: [\n    { pre: 'a', exp: -6 },\n    { pre: 'f', exp: -5 },\n    { pre: 'p', exp: -4 },\n    { pre: 'n', exp: -3 },\n    { pre: 'u', exp: -2 },\n    { pre: 'µ', exp: -2 },\n    { pre: 'm', exp: -1 },\n    { pre: 'k', exp: 1 },\n    { pre: 'K', exp: 1 },\n    { pre: 'meg', exp: 2 },\n    { pre: 'M', exp: 2 },\n    { pre: 'G', exp: 3 },\n    { pre: 'T', exp: 4 },\n    { pre: 'P', exp: 5 },\n    { pre: 'E', exp: 6 },\n  ],\n}\n```\n\nAn object describing the `base` and a series of `objects` describing `prefixes` and `exponents` to find the `multiplier` to be used during parsing. Every item in `items` array should have a unique `pre`, if there are duplicates `createParser` will `throw`.\n\n***Notes***\n\nNote that `empty prefix` (`{ pre: '', exp: 0 }`) is not necessary, as an `empty prefix` will result in `multiplier = 1`\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  find: {\n    base: 1024,\n    items: [\n      { pre: 'K', exp: 1 },\n      { pre: 'M', exp: 2 },\n    ],\n  },\n});\n\nparse('1'); // =\u003e 1\nparse('1 K'); // =\u003e 1024\nparse('1 M'); // =\u003e 1048576\nparse('1 G'); // =\u003e NaN\n```\n\n##### `find` option as a function\n\n```typescript\nfind: (pre: string) =\u003e number | null | undefined;\n```\n\nA function that should return a non-zero `number` by which the parsed value should be multiplied based on the captured prefix. Return `null` (or `undefined`) if multiplier can't be determined. It will cause the parse function to return `NaN`. If your function returns `zero`, `negative number` or any other invalid multiplier, parse function will throw a `TypeError`.\n\n***Example***\n\n```typescript\nconst parse = createParser({\n  find: (unit) =\u003e {\n    if (unit === 'K' || unit === 'k') {\n      return 1024;\n    } else if (unit === 'M') {\n      return 1024 ** 2;\n    }\n    // next line can be omitted\n    // as it will return undefined anyway\n    return null;\n  },\n});\n\nparse('2'); // =\u003e 2\nparse('2 k'); // =\u003e 2048\nparse('2 K'); // =\u003e 2048\nparse('2 M'); // =\u003e 2097152\nparse('2 G'); // =\u003e NaN\n```\n\n***Notes***\n\nPrevious version of this library allow this function to return an object `{ mul: number }` containing the multiplier. This behavior has been removed, it will `throw` instead.\n\n### The `createFormatter` function\n\nCreates a `format` function using the given [options](#createformatter-options).\n\n```typescript\nfunction createFormatter(options): Formatter;\n\ntype Formatter = (input: number) =\u003e string;\n```\n\n### `createFormatter` options\n\n#### The `unit` option\n\nA `string` to be used as main `unit` during formatting.\n\n```typescript\nunit: string;\n```\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  unit: 'm',\n});\n\nformat(100); // =\u003e '100 m'\nformat(0.0012); // =\u003e '1.2 mm'\nformat(1200); // =\u003e '1.2 Km'\n```\n\n#### The `find` option\n\nDescribes how to find the unit `prefix` and `divider` based on input value.\n\n##### `find` option as a number\n\n```typescript\nfind: number;\n```\n\nA `number` to be used as `base` during formatting.\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  find: 1024,\n});\n\nformat(100); // =\u003e '100'\nformat(2048); // =\u003e '2 k'\nformat(2097152); // =\u003e '2 M'\n```\n\n##### `find` option as an array\n\n```typescript\nfind: Array\u003c{ pre: string; exp: number }\u003e;\n```\n\nAn `array` of `objects` describing `prefixes` and `exponents` to use with the default `base` (1000) to find the `prefix` and `multiplier` to be used during formatting. Every item should have a unique `exp`, if there are duplicates `createFormatter` will `throw`.\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  find: [\n    { exp: 0, pre: '' },\n    { exp: 1, pre: 'K' },\n  ],\n});\n\nformat(2); // =\u003e '2'\nformat(2000); // =\u003e '2 K'\nformat(2000000); // =\u003e '2000 K'\n```\n\n##### `find` option as an object\n\n```typescript\nfind: {\n  base?: number;\n  items?: Array\u003c{ exp: number; pre: string }\u003e;\n}\n\ndefault: {\n  base: 1000,\n  items: [\n    { exp: -6, pre: 'a' },\n    { exp: -5, pre: 'f' },\n    { exp: -4, pre: 'p' },\n    { exp: -3, pre: 'n' },\n    { exp: -2, pre: 'µ' },\n    { exp: -1, pre: 'm' },\n    { exp: 0, pre: '' },\n    { exp: 1, pre: 'k' },\n    { exp: 2, pre: 'M' },\n    { exp: 3, pre: 'G' },\n    { exp: 4, pre: 'T' },\n    { exp: 5, pre: 'P' },\n    { exp: 6, pre: 'E' },\n  ],\n}\n```\n\nAn object describing the `base` and a series of `objects` describing `prefixes` and `exponents` to find the `prefix` and `multiplier` to be used during formatting. Every item in `items` array should have a unique `exp`, if there are duplicates `createFormatter` will `throw`.\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  find: {\n    base: 1024,\n    items: [\n      { exp: 0, pre: '' },\n      { exp: 1, pre: 'K' },\n    ],\n  },\n});\n\nformat(100); // =\u003e '100'\nformat(2048); // =\u003e '2 K'\nformat(2097152); // =\u003e '2048 K'\n```\n\n##### `find` option as a function\n\n```typescript\nfind: (value: number) =\u003e { pre: string; mul: number };\n```\n\nA `function` that `returns` an `object` describing the unit `prefix` (`pre`) and `multiplier` (`mul`).\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  find: (value) =\u003e {\n    if (value \u003e= 1000) {\n      return { pre: 'K', mul: 1000 };\n    } else {\n      return { pre: '', mul: 1 };\n    }\n  },\n});\n\nformat(0.2); // =\u003e '0.2'\nformat(2); // =\u003e '2'\nformat(2000); // =\u003e '2 K'\nformat(2000000); // =\u003e '2000 K'\n```\n\n#### The `round` option\n\nDescribes how to `round` the output value before final `format`.\n\n##### `round` option as an object\n\n```typescript\nround: {\n  dec?: number;\n  fixed?: boolean;\n};\n\ndefault: {\n  dec: 2,\n  fixed: false,\n};\n```\n\nAn `object` describing how to `round` the value before final format. Describes the number of decimal (`dec`) and whether or not the output should have a fixed number of decimal (`fixed`).\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  round: {\n    dec: 3,\n    fixed: true,\n  },\n});\n\nformat(1.23); // =\u003e '1.230'\nformat(1230); // =\u003e '1.230 k'\nformat(0.00123); // =\u003e '1.230 m'\n```\n\n##### `round` option as a number\n\n```typescript\nround: number;\n```\n\nA `number` defining the number of decimal places to round to.\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  round: 1,\n});\n\nformat(1.23); // =\u003e '1.2'\nformat(1.28); // =\u003e '1.3'\nformat(1230); // =\u003e '1.2 k'\nformat(0.00123); // =\u003e '1.2 m'\n```\n\n##### `round` option as a function\n\n```typescript\nround: (num: number) =\u003e (string | number);\n```\n\nA `function` which `returns` the rounded value.\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  round: Math.round,\n});\n\nformat(1.23); // =\u003e '1'\nformat(1.75); // =\u003e '2'\nformat(1230); // =\u003e '1 k'\nformat(0.00123); // =\u003e '1 m'\n```\n\n#### The `output` option\n\nDescribes the final output format.\n\n```typescript\noutput: FormatOutputFunction | FormatOutputAdvancedOption;\n\ntype FormatOutputFunction = (value: string | number, prefix: string, unit: string) =\u003e string;\n\ninterface FormatOutputAdvancedOption {\n  space: string;\n}\n```\n\n##### `output` option as an object\n\n```typescript\noutput: {\n  space?: string;\n}\n\ndefault {\n  space: ' ';\n}\n```\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  output: {\n    space: '-', // unrealistic, for demonstration only\n  },\n})\n\nformat(1.23); // =\u003e '1.23'\nformat(1230); // =\u003e '1.23-k'\nformat(0.00123); // =\u003e '1.23-m'\n```\n\n##### `output` option as a function\n\nA `function` to format the final output.\n\n```typescript\noutput: (value: string | number, prefix: string, unit: string) =\u003e string;\n```\n\n***Example***\n\n```typescript\nconst format = createFormatter({\n  unit: 'x',\n  output: (value, pre) =\u003e {\n    // ignore original unit and hardcode one\n    return `${value}${pre}s`;\n  },\n});\n\nformat(1.23); // =\u003e '1.23s'\nformat(1230); // =\u003e '1.23ks'\nformat(0.00123); // =\u003e '1.23ms'\n```\n\n### The `parse` function\n\nA convenient function to parse an `input` in one step. I will internally call `createParser` then will call the newly created parser. See `createParser` [options](#createparser-options).\n\n```typescript\nfunction parse(input, options): number;\n```\n\n### The `format` function\n\nA convenient function to format a `number` in one step. It wil internally call `createFormatter` then will call the newly created formatter. See `createFormatter` [options](#createformatter-options).\n\n```typescript\nfunction format(input, options): string;\n```\n\n### The `MICRO` constant\n\nA constant containing the micro symbol (\"µ\"). Used internally, exported for convenience.\n\n## License\n\n[MIT](LICENSE) \u0026copy; 2019-2024 [Manuel Fernández](https://github.com/manferlo81)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanferlo81%2Fgen-unit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanferlo81%2Fgen-unit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanferlo81%2Fgen-unit/lists"}