From d5011bda282dd08877ddf1af7ee313863033a847 Mon Sep 17 00:00:00 2001 From: Alexander Bjerkan Date: Fri, 24 Jan 2025 12:44:21 +0100 Subject: [PATCH 1/2] init repo --- .changeset/bright-adults-battle.md | 5 +++++ packages/format/README.md | 20 ++++++++++++++++++ packages/format/package.json | 28 ++++++++++++++++++++++++ packages/format/src/format.test.ts | 34 ++++++++++++++++++++++++++++++ packages/format/src/no.ts | 25 ++++++++++++++++++++++ packages/format/src/se.ts | 14 ++++++++++++ packages/format/tsconfig.json | 7 ++++++ 7 files changed, 133 insertions(+) create mode 100644 .changeset/bright-adults-battle.md create mode 100644 packages/format/README.md create mode 100644 packages/format/package.json create mode 100644 packages/format/src/format.test.ts create mode 100644 packages/format/src/no.ts create mode 100644 packages/format/src/se.ts create mode 100644 packages/format/tsconfig.json diff --git a/.changeset/bright-adults-battle.md b/.changeset/bright-adults-battle.md new file mode 100644 index 0000000..adeadd7 --- /dev/null +++ b/.changeset/bright-adults-battle.md @@ -0,0 +1,5 @@ +--- +"@obosbbl/format": minor +--- + +initial release diff --git a/packages/format/README.md b/packages/format/README.md new file mode 100644 index 0000000..c6677db --- /dev/null +++ b/packages/format/README.md @@ -0,0 +1,20 @@ +# @obosbbl/format + +[![npm canary version](https://img.shields.io/npm/v/@obosbbl%2Fformat/canary.svg)](https://www.npmjs.com/package/@obosbbl/format) + +Formatting functions for both πŸ‡³πŸ‡΄ and πŸ‡ΈπŸ‡ͺ with zero dependencies. + +## Install + +```sh +# npm +npm install @obosbbl/format + +# pnpm +pnpm add @obosbbl/format +``` + +## Methods + +* organizationNumberFormatter +* obosMembershipNumberFormatter diff --git a/packages/format/package.json b/packages/format/package.json new file mode 100644 index 0000000..2b8057a --- /dev/null +++ b/packages/format/package.json @@ -0,0 +1,28 @@ +{ + "name": "@obosbbl/format", + "version": "0.0.0", + "description": "A collection of formatting methods for OBOS", + "repository": { + "url": "https://github.com/code-obos/public-frontend-modules" + }, + "license": "MIT", + "sideEffects": false, + "type": "module", + "exports": { + "./no": { + "types": "./dist/no.d.mts", + "default": "./dist/no.mjs" + }, + "./se": { + "types": "./dist/se.d.mts", + "default": "./dist/se.mjs" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "bunchee" + }, + "dependencies": {} +} diff --git a/packages/format/src/format.test.ts b/packages/format/src/format.test.ts new file mode 100644 index 0000000..2c1b5f8 --- /dev/null +++ b/packages/format/src/format.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test } from 'vitest'; +import { formatOrganizationNumber, formatPhoneNumber } from '.'; + +describe('no', () => { + test.each([ + ['22865500', '22 86 55 00'], + ['80000000', '800 00 000'], + ])('formatPhoneNumber(%s) -> %s', (input, expected) => { + expect(formatPhoneNumber(input, 'no')).toBe(expected); + }); + + test.each([['000000000', '000 000 000']])( + 'formatOrganizationNumber(%s) -> %s', + (input, expected) => { + expect(formatOrganizationNumber(input, 'no')).toBe(expected); + }, + ); +}); + +describe('se', () => { + test.each([['0701234567', '070-123 45 67']])( + 'formatPhoneNumber(%s) -> %s', + (input, expected) => { + expect(formatPhoneNumber(input, 'se')).toBe(expected); + }, + ); + + test.each([['0000000000', '000000-0000']])( + 'formatOrganizationNumber(%s) -> %s', + (input, expected) => { + expect(formatOrganizationNumber(input, 'se')).toBe(expected); + }, + ); +}); diff --git a/packages/format/src/no.ts b/packages/format/src/no.ts new file mode 100644 index 0000000..cae5f36 --- /dev/null +++ b/packages/format/src/no.ts @@ -0,0 +1,25 @@ +const ORG_NUMBER_FORMAT = /^(\d{3})(\d{3})(\d{3})$/; + +/** + * Format an organization number + * @example + * ``` + * formatOrganizationNumber('000000000') // => '000 000 000' + * ``` + */ +export function formatOrganizationNumber(number: string): string { + return number.replace(ORG_NUMBER_FORMAT, '$1 $2 $3'); +} + +const OBOS_MEMBERSHIP_NUMBER_FORMAT = /^(\d{3})(\d{2})(\d{2})$/; + +/** + * Format an OBOS membership number + * @example + * ``` + * formatObosMembershipNumber('0000000') // => '000 00 00' + * ``` + */ +export function formatObosMembershipNumber(number: string): string { + return number.replace(OBOS_MEMBERSHIP_NUMBER_FORMAT, '$1 $2 $3'); +} diff --git a/packages/format/src/se.ts b/packages/format/src/se.ts new file mode 100644 index 0000000..135d82c --- /dev/null +++ b/packages/format/src/se.ts @@ -0,0 +1,14 @@ +// Ensures feature parity with the Norwegian format module +export { formatObosMembershipNumber } from './no'; + +const ORG_NUMBER_FORMAT = /^(\d{6})(\d{4})$/; +/** + * Format an organization number + * @example + * ``` + * formatOrganizationNumber('0000000000') // => '000000-0000' + * ``` + */ +export function formatOrganizationNumber(number: string): string { + return number.replace(ORG_NUMBER_FORMAT, '$1-$2'); +} diff --git a/packages/format/tsconfig.json b/packages/format/tsconfig.json new file mode 100644 index 0000000..dcbf63f --- /dev/null +++ b/packages/format/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["./src/*"], + "compilerOptions": { + "outDir": "dist" + } +} From 944ee1c4cc6082577b2d2eef3a496c73fe31c6d4 Mon Sep 17 00:00:00 2001 From: Alexander Bjerkan Date: Fri, 24 Jan 2025 14:13:25 +0100 Subject: [PATCH 2/2] format package --- packages/format/README.md | 27 ++++++++++++++++--- packages/format/src/format.test.ts | 43 +++++++++++++----------------- packages/format/src/no.ts | 19 +++---------- packages/format/src/se.ts | 8 +++--- packages/format/src/utils.ts | 12 +++++++++ 5 files changed, 61 insertions(+), 48 deletions(-) create mode 100644 packages/format/src/utils.ts diff --git a/packages/format/README.md b/packages/format/README.md index c6677db..05d87b2 100644 --- a/packages/format/README.md +++ b/packages/format/README.md @@ -1,8 +1,9 @@ # @obosbbl/format -[![npm canary version](https://img.shields.io/npm/v/@obosbbl%2Fformat/canary.svg)](https://www.npmjs.com/package/@obosbbl/format) +[![NPM Version](https://img.shields.io/npm/v/%40obosbbl%2Fformat)](https://www.npmjs.com/package/@obosbbl/format) -Formatting functions for both πŸ‡³πŸ‡΄ and πŸ‡ΈπŸ‡ͺ with zero dependencies. + +A collection of formatting functions for both πŸ‡³πŸ‡΄ and πŸ‡ΈπŸ‡ͺ with zero dependencies. ## Install @@ -14,7 +15,25 @@ npm install @obosbbl/format pnpm add @obosbbl/format ``` +## Usage + +The package has two entrypoints, one for `no` and one for `se`. That allows you to import for only the locale you need. + +Note that the methods are very lenient when attempting to format the input. It will strip all characters that aren't digits or letters before it applies the formatting. +That way any existing format of the input won't affect the formatted output + +If unable to format the input, the method will return the (cleaned) input as is. + +```js +// πŸ‡³πŸ‡΄ example +import { formatOrganizationNumber } from '@obosbbl/format/no'; +formatOrganizationNumber('000000000') // => '000 000 000' + +// πŸ‡ΈπŸ‡ͺ example +import { formatOrganizationNumber } from '@obosbbl/format/se'; +formatOrganizationNumber('0000000000') // => '000000-0000' +``` + ## Methods -* organizationNumberFormatter -* obosMembershipNumberFormatter +* formatOrganizationNumber diff --git a/packages/format/src/format.test.ts b/packages/format/src/format.test.ts index 2c1b5f8..919cbd9 100644 --- a/packages/format/src/format.test.ts +++ b/packages/format/src/format.test.ts @@ -1,34 +1,27 @@ import { describe, expect, test } from 'vitest'; -import { formatOrganizationNumber, formatPhoneNumber } from '.'; +import { formatOrganizationNumber as formatOrganizationNumberNo } from './no'; +import { formatOrganizationNumber as formatOrganizationNumberSe } from './se'; describe('no', () => { test.each([ - ['22865500', '22 86 55 00'], - ['80000000', '800 00 000'], - ])('formatPhoneNumber(%s) -> %s', (input, expected) => { - expect(formatPhoneNumber(input, 'no')).toBe(expected); + ['000000000', '000 000 000'], + ['000 000 000', '000 000 000'], + ['000-000-000', '000 000 000'], + ['abc', 'abc'], + ])('formatOrganizationNumber(%s) -> %s', (input, expected) => { + expect(formatOrganizationNumberNo(input)).toBe(expected); }); - - test.each([['000000000', '000 000 000']])( - 'formatOrganizationNumber(%s) -> %s', - (input, expected) => { - expect(formatOrganizationNumber(input, 'no')).toBe(expected); - }, - ); }); describe('se', () => { - test.each([['0701234567', '070-123 45 67']])( - 'formatPhoneNumber(%s) -> %s', - (input, expected) => { - expect(formatPhoneNumber(input, 'se')).toBe(expected); - }, - ); - - test.each([['0000000000', '000000-0000']])( - 'formatOrganizationNumber(%s) -> %s', - (input, expected) => { - expect(formatOrganizationNumber(input, 'se')).toBe(expected); - }, - ); + test.each([ + ['0000000000', '000000-0000'], + ['000000-0000', '000000-0000'], + ['000000 0000', '000000-0000'], + [' 000000 0000 ', '000000-0000'], + ['000', '000'], + ['abc', 'abc'], + ])('formatOrganizationNumber(%s) -> %s', (input, expected) => { + expect(formatOrganizationNumberSe(input)).toBe(expected); + }); }); diff --git a/packages/format/src/no.ts b/packages/format/src/no.ts index cae5f36..c2e823f 100644 --- a/packages/format/src/no.ts +++ b/packages/format/src/no.ts @@ -1,3 +1,5 @@ +import { replaceIfMatch } from './utils'; + const ORG_NUMBER_FORMAT = /^(\d{3})(\d{3})(\d{3})$/; /** @@ -7,19 +9,6 @@ const ORG_NUMBER_FORMAT = /^(\d{3})(\d{3})(\d{3})$/; * formatOrganizationNumber('000000000') // => '000 000 000' * ``` */ -export function formatOrganizationNumber(number: string): string { - return number.replace(ORG_NUMBER_FORMAT, '$1 $2 $3'); -} - -const OBOS_MEMBERSHIP_NUMBER_FORMAT = /^(\d{3})(\d{2})(\d{2})$/; - -/** - * Format an OBOS membership number - * @example - * ``` - * formatObosMembershipNumber('0000000') // => '000 00 00' - * ``` - */ -export function formatObosMembershipNumber(number: string): string { - return number.replace(OBOS_MEMBERSHIP_NUMBER_FORMAT, '$1 $2 $3'); +export function formatOrganizationNumber(input: string): string { + return replaceIfMatch(input, ORG_NUMBER_FORMAT, '$1 $2 $3'); } diff --git a/packages/format/src/se.ts b/packages/format/src/se.ts index 135d82c..363ce12 100644 --- a/packages/format/src/se.ts +++ b/packages/format/src/se.ts @@ -1,7 +1,7 @@ -// Ensures feature parity with the Norwegian format module -export { formatObosMembershipNumber } from './no'; +import { replaceIfMatch } from './utils'; const ORG_NUMBER_FORMAT = /^(\d{6})(\d{4})$/; + /** * Format an organization number * @example @@ -9,6 +9,6 @@ const ORG_NUMBER_FORMAT = /^(\d{6})(\d{4})$/; * formatOrganizationNumber('0000000000') // => '000000-0000' * ``` */ -export function formatOrganizationNumber(number: string): string { - return number.replace(ORG_NUMBER_FORMAT, '$1-$2'); +export function formatOrganizationNumber(input: string): string { + return replaceIfMatch(input, ORG_NUMBER_FORMAT, '$1-$2'); } diff --git a/packages/format/src/utils.ts b/packages/format/src/utils.ts new file mode 100644 index 0000000..80e96ee --- /dev/null +++ b/packages/format/src/utils.ts @@ -0,0 +1,12 @@ +export function replaceIfMatch( + input: string, + regex: RegExp, + replacerPattern: string, +): string { + // We're extremely lenient when attemtping to format the input. + // We remove everything that isn't a letter or a number, that way we can get rid of any + // formatting that might already be present in the input, eg spaces, hyphens or dots + const cleaned = input.replace(/[^a-zA-Z0-9]/g, ''); + + return cleaned.replace(regex, replacerPattern); +}