Skip to content

Commit

Permalink
Merge pull request #45 from M-Scott-Lassiter/beta
Browse files Browse the repository at this point in the history
Add Typescript Support
  • Loading branch information
M-Scott-Lassiter committed Jun 11, 2022
2 parents b5f3c9c + b3c253f commit 5633ecd
Show file tree
Hide file tree
Showing 16 changed files with 270 additions and 220 deletions.
45 changes: 30 additions & 15 deletions .cz-config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
const encoderMethods = [
{ name: 'dictionary' },
{ name: 'allowLowerCaseDictionary' },
{ name: 'resetDefaultDictionary' },
{ name: 'encode' },
{ name: 'decode' },
{ name: 'deconstruct' }
]

const documentation = [
{ name: 'contributing' },
{ name: 'code of conduct' },
{ name: 'license' },
{ name: 'readme' },
{ name: 'security' }
]

module.exports = {
types: [
{
value: 'api',
name: 'api: Non-functional changes to code API documentation that help other developers understand how to use a tool or feature (i.e. intellisense)'
},
{
value: 'build',
name: 'build: Changes that affect the build system configuration, package scripts, or dev dependencies (i.e. adds/remove/modify/update)'
Expand All @@ -26,30 +47,24 @@ module.exports = {
{ value: 'test', name: 'test: Add missing tests or correct existing tests' }
],

scopes: [
{ name: 'api' },
{ name: 'contributing' },
{ name: 'license' },
{ name: 'readme' },
{ name: 'security' }
],
scopes: [...encoderMethods, ...documentation],

allowTicketNumber: false,
isTicketNumberRequired: false,
ticketNumberPrefix: 'TICKET-',
ticketNumberRegExp: '\\d{1,5}',

// it needs to match the value for field type. Eg.: 'fix'
/*
scopeOverrides: {
fix: [
{name: 'merge'},
{name: 'style'},
{name: 'e2eTest'},
{name: 'unitTest'}
]
api: encoderMethods,
ci: [{ name: 'publish' }, { name: 'test' }, { name: 'hooks' }],
docs: documentation,
fix: encoderMethods,
perf: encoderMethods,
refactor: encoderMethods,
test: encoderMethods
},
*/

// override the messages, defaults are as follows
messages: {
type: "Select the type of change that you're committing:",
Expand Down
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules
coverage
coverage
CHANGELOG.md
*.d.ts
8 changes: 0 additions & 8 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ body:
attributes:
value: |
Thank you taking the time to fill out this bug report!
- type: input
id: contact
attributes:
label: Contact Details
description: How can I get in touch with you if needed for more info?
placeholder: ex. email@example.com
validations:
required: false
- type: textarea
id: what-happened
attributes:
Expand Down
8 changes: 0 additions & 8 deletions .github/ISSUE_TEMPLATE/documentation_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ body:
attributes:
value: |
Thank you taking the time to fill out this request!
- type: input
id: contact
attributes:
label: Contact Details
description: How can I get in touch with you if needed for more info?
placeholder: ex. email@example.com
validations:
required: false
- type: input
id: component
attributes:
Expand Down
8 changes: 0 additions & 8 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ body:
attributes:
value: |
Thank you taking the time to fill out this request!
- type: input
id: contact
attributes:
label: Contact Details
description: How can I get in touch with you if needed for more info?
placeholder: ex. email@example.com
validations:
required: false
- type: textarea
id: description
attributes:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: CD Build

on:
push:
branches: [main]
branches: [main, beta]

jobs:
publish:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [12.x, 14.x, 16.x, 17.x, 18.x]
node-version: [14.x, 16.x, 17.x, 18.x]
os: [ubuntu-latest, windows-latest, macos-latest]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
coverage
CHANGELOG.md
25 changes: 15 additions & 10 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ A class for encoding and decoding base 10 integers to a custom alphanumeric base

### Parameters

- `configOptions` **[object][21]?** Optional object defining initial settings for the class (optional, default `{}`)
- `configOptions` **[object][21]?** Optional object defining initial settings for the class (optional, default `{allowLowerCaseDictionary:false,dictionary:'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}`)

- `configOptions.allowLowerCaseDictionary` **[boolean][22]?** Whether or not to allow lower case letters in the dictionary
- `configOptions.dictionary` **[string][23]?** Starting dictionary to use. Must contain only letters or numbers. Characters cannot be repeated.
If `allowLowerCaseDictionary = true`, then lower case letters are not considered the same as upper case. (e.g. 'ABCabc' has 6 unique characters.)
- `configOptions.allowLowerCaseDictionary` **[boolean][22]** Whether or not to allow lower case letters in the dictionary (optional, default `false`)
- `configOptions.dictionary` **[string][23]** Starting dictionary to use. Must contain only letters or numbers. Characters cannot be repeated.
If `allowLowerCaseDictionary = true`, then lower case letters are not considered the same as upper case. (e.g. 'ABCabc' has 6 unique characters.) (optional, default `'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`)

### Examples

Expand Down Expand Up @@ -175,7 +175,7 @@ console.log(encoder.encode(undefined)) // undefined

- Throws **[RangeError][24]** if `integerToEncode` exceeds the maximum safe integer for Javascript (`2^53 - 1 = 9007199254740991`).

Returns **[string][23]** Dictionary encoded value
Returns **([string][23] | [undefined][26])** Dictionary encoded value. Returns undefined of passed negative numbers or NaN

### decode

Expand Down Expand Up @@ -221,7 +221,7 @@ Takes any string of letters and numbers and deconstructs it into an array of bas

#### Parameters

- `stringToDeconstruct` **([string][23] | [number][25])** A string of letters and numbers (e.g. `'A7'`, `'AC22'`, `'7C10F'`)
- `stringToDeconstruct` **[string][23]** A string of letters and numbers (e.g. `'A7'`, `'AC22'`, `'7C10F'`)

#### Examples

Expand All @@ -235,11 +235,15 @@ console.log(encoder.deconstruct('7AC!23A1%')) // [7, undefined, 23, 1, 1, undefi
console.log(encoder.deconstruct('')) // undefined
```

- Throws **[Error][26]** if the dictionary contains a number as this function would be unable to differentiate between where a number and dictionary value.
- Throws **[Error][27]** if the dictionary contains a number as this function would be unable to differentiate between where a number and dictionary value.

Returns **[Array][27]<[number][25]>** An array of numbers. Characters not present in the dictionary are treated as letters and return `undefined` for that array value.
Returns **([Array][28]<([number][25] | [undefined][26])> | [undefined][26])** An array of numbers. Characters not present in the dictionary are treated as letters and return `undefined` for that array value.
Passing an empty string (`''`), `null`, or `undefined` will return `undefined` for the whole function.

##

Type: [string][23]

[1]: #alphanumericencoder
[2]: #parameters
[3]: #examples
Expand All @@ -265,5 +269,6 @@ Passing an empty string (`''`), `null`, or `undefined` will return `undefined` f
[23]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
[24]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RangeError
[25]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[26]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
[27]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
[26]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined
[27]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error
[28]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
## [1.6.0-beta.3](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/compare/v1.6.0-beta.2...v1.6.0-beta.3) (2022-06-04)


### :building_construction: Build Changes

* update commitizen configuration for API ([f40be7f](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/commit/f40be7ff983cd7997be370d591b12b04e92e901f))


### :lady_beetle: Bug Fixes

* correct problems with Typescript definitions and JSDoc comments ([b891650](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/commit/b891650b2a0c6891bcb7a265fbd39a06908240cc)), closes [#43](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/issues/43)

## [1.6.0-beta.2](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/compare/v1.6.0-beta.1...v1.6.0-beta.2) (2022-05-20)


### :lady_beetle: Bug Fixes

* add typescript definition file to "files" key ([009460c](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/commit/009460cb87ebc18b5bbbc6fe90db932232afce1b)), closes [#43](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/issues/43)

## [1.6.0-beta.1](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/compare/v1.5.2...v1.6.0-beta.1) (2022-05-20)


### :building_construction: Build Changes

* change the semantic-release configuration to a shared config ([c2a19fa](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/commit/c2a19fa455444bd07af0968b00d2988369f7680c))
* ignore CHANGELOG.md from linting and formatting ([2e3ca94](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/commit/2e3ca941b4343144d551f4e769f1d95b7d64a6ce))


### :gift: Feature Changes

* add typescript bindings to the encoder ([e1cd754](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/commit/e1cd754472567e61b9f0b420bad3899c988afe0c)), closes [#43](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/issues/43)

### [1.5.2](https://github.com/M-Scott-Lassiter/Alphanumeric-Encoder/compare/v1.5.1...v1.5.2) (2022-05-14)


Expand Down
29 changes: 29 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// @ts-check

// Manually generated from https://www.typescriptlang.org/play

declare class AlphanumericEncoder {
constructor(configOptions?: {
allowLowerCaseDictionary?: boolean | undefined
dictionary?: string | undefined
})
private _defaultDictionary
private _dictionaryInUse
private _allowLowerCaseDictionary

set allowLowerCaseDictionary(arg: boolean)
get allowLowerCaseDictionary(): boolean

set dictionary(arg: string)
get dictionary(): string

resetDefaultDictionary(): void

encode(integerToEncode: number): string | undefined

decode(stringToDecode: string): number | undefined

deconstruct(stringToDeconstruct: string): (number | undefined)[] | undefined
}

export = AlphanumericEncoder
33 changes: 25 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
/**
* A class for encoding and decoding base 10 integers to a custom alphanumeric base representation.
* @param {object} [configOptions] Optional object defining initial settings for the class
* @param {boolean} [configOptions.allowLowerCaseDictionary] Whether or not to allow lower case letters in the dictionary
* @param {string} [configOptions.dictionary] Starting dictionary to use. Must contain only letters or numbers. Characters cannot be repeated.
* @param {boolean} [configOptions.allowLowerCaseDictionary=false] Whether or not to allow lower case letters in the dictionary
* @param {string} [configOptions.dictionary='ABCDEFGHIJKLMNOPQRSTUVWXYZ'] Starting dictionary to use. Must contain only letters or numbers. Characters cannot be repeated.
* If `allowLowerCaseDictionary = true`, then lower case letters are not considered the same as upper case. (e.g. 'ABCabc' has 6 unique characters.)
* @example
* // Import into a project
Expand All @@ -26,7 +26,12 @@
* const encoder = new AlphanumericEncoder(configOptions)
*/
class AlphanumericEncoder {
constructor(configOptions = {}) {
constructor(
configOptions = {
allowLowerCaseDictionary: false,
dictionary: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
) {
/**
* @private
* @type {string} Internal value used to initialize and reset the dictionary
Expand Down Expand Up @@ -168,7 +173,7 @@ class AlphanumericEncoder {
* @param {number} integerToEncode Base 10 integer. If passed a non-integer number, decimal values are truncated.
* Passing zero, negative numbers, or non-numbers will return `undefined`.
* @throws {RangeError} if `integerToEncode` exceeds the maximum safe integer for Javascript (`2^53 - 1 = 9007199254740991`).
* @returns {string} Dictionary encoded value
* @returns {string|undefined} Dictionary encoded value. Returns undefined of passed negative numbers or NaN
*
* @example
* const encoder = new AlphanumericEncoder()
Expand Down Expand Up @@ -209,8 +214,15 @@ class AlphanumericEncoder {
)
}

/**
* Takes a letter between 0 and max letter length and returns the corresponding letter
*
* @private
* @param {number} num The index to search for
* @param {string} dictionary The dictionary used to search
* @returns {string} The letter corresponding to this number index
*/
function numToLetter(num, dictionary) {
// Takes a letter between 0 and max letter length and returns the corresponding letter
if (num === 0) {
return undefined
}
Expand Down Expand Up @@ -299,9 +311,9 @@ class AlphanumericEncoder {
/**
* Takes any string of letters and numbers and deconstructs it into an array of base 10 integers based on the defined dictionary.
*
* @param {string|number} stringToDeconstruct A string of letters and numbers (e.g. `'A7'`, `'AC22'`, `'7C10F'`)
* @param {string} stringToDeconstruct A string of letters and numbers (e.g. `'A7'`, `'AC22'`, `'7C10F'`)
* @throws {Error} if the dictionary contains a number as this function would be unable to differentiate between where a number and dictionary value.
* @returns {number[]} An array of numbers. Characters not present in the dictionary are treated as letters and return `undefined` for that array value.
* @returns {(number|undefined)[]|undefined} An array of numbers. Characters not present in the dictionary are treated as letters and return `undefined` for that array value.
* Passing an empty string (`''`), `null`, or `undefined` will return `undefined` for the whole function.
* @example
* const encoder = new AlphanumericEncoder()
Expand Down Expand Up @@ -330,12 +342,17 @@ class AlphanumericEncoder {
}

const safeString = String(stringToDeconstruct) // Force argument to string to process number arguments and prevent slice from throwing an error
/**
* @private
* @type {number[]} Array of numbers after splitting a string.
* Elements include (in order) the number or decoded number from a letter.
*/
const deconstructedArray = []
let character = ''
let componentPart = safeString.slice(0, 1) // Initialize with the first character (which has been guranteed present by above guard functions)

// A helper function to push the final component into the array that gets returned. Numbers get added as is, strings get decoded.
const addDecodedElement = (componentString) => {
const addDecodedElement = (/** @type {string} */ componentString) => {
if (componentString.match(/[0-9]/)) {
deconstructedArray.push(Number.parseInt(componentString, 10)) // Numbers
} else {
Expand Down
10 changes: 8 additions & 2 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

const AlphanumericEncoder = require('./index')

let encoder = new AlphanumericEncoder()
let encoder = new AlphanumericEncoder({
allowLowerCaseDictionary: false,
dictionary: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
})

const numberToEncodedLetters = [
[1, 'A'],
Expand Down Expand Up @@ -77,6 +80,7 @@ describe('Allow Lower Case Dictionaries', () => {
'allowLowerCaseDictionary with truthy value in setup: new AlphanumericEncoder({ allowLowerCaseDictionary: %p })',
(truthyTestValue) => {
const setupEncoder = new AlphanumericEncoder({
// @ts-ignore
allowLowerCaseDictionary: truthyTestValue
})
expect(setupEncoder.allowLowerCaseDictionary).toBeTruthy()
Expand All @@ -96,6 +100,7 @@ describe('Allow Lower Case Dictionaries', () => {
'allowLowerCaseDictionary with falsy value in setup: new AlphanumericEncoder({ allowLowerCaseDictionary: %p })',
(truthyTestValue) => {
const setupEncoder = new AlphanumericEncoder({
// @ts-ignore
allowLowerCaseDictionary: truthyTestValue
})
expect(setupEncoder.allowLowerCaseDictionary).toBeFalsy()
Expand Down Expand Up @@ -158,6 +163,7 @@ describe('Dictionary Validation', () => {
expect(() => {
// eslint-disable-next-line no-unused-vars
const setupEncoder = new AlphanumericEncoder({
// @ts-ignore
dictionary: dictionaryInput
})
}).toThrow()
Expand Down Expand Up @@ -317,7 +323,7 @@ describe('Test Decoding', () => {

test('Expect decoding strings to integers greater than Number.MAX_SAFE_INTEGER throws an error', () => {
expect(() => {
encoder.decode('BKTXHSOGHKKF')
encoder.decode('BKTXHSOGHKKF') // BKTXHSOGHKKE is what max safe integer encodes to under default dictionary
}).toThrow(/maximum safe integer/)
})

Expand Down

0 comments on commit 5633ecd

Please sign in to comment.