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

Convert to Typescript #39

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

nicu-chiciuc
Copy link

@nicu-chiciuc nicu-chiciuc commented Jan 11, 2023

The main goal of this PR is to update all its dependencies (there are several high-severity dependencies at the moment) and to use Typescript so that there are well maintained type definitions.

Steps that have been done

Upgrade to @babel 7

I've updated all the packages to the latest versions.

I've had to update the .babelrc to the latest version by using the @babel/preset-env preset.

Replacing standard

standard cannot parse Typescript code, I've tried to use ts-standard instead, but a big issue seems to be that the fixes that it applies can break the code.

For example this:

  const encodedBytesCount = (str.match(/=[\da-fA-F]{2}/g) || []).length

was transformed to this:

  const encodedBytesCount = ((str.match(/=[\da-fA-F]{2}/g) != null) || []).length

Screenshot 2023-01-11 at 16 29 25

I opted to use prettier, and I also changed some of its options so that there are minimal changes to how the code looks.

Completely replacing standard with eslint

I've adopted typescript-eslint since it's better supported.
I've tried using the eslint-config-standard-with-typescript config, so that we have the same rules as before, but that package required too many peer dependencies, so I decided to rely on the default typescript-eslint rules.

Renaming test files from *-unit.js to *.unit.js

For some reason the babel --ignore option didn't want to work when the delimiter is -.
The simplest solution was to replace - with ., and the pattern matcher works.

Fix test 'should Fold flowed text'

The call

    expect(outputStr).to.equal(foldLines(inputStr, 76, true))

was changed to

    expect(outputStr).to.equal(foldLines(inputStr, true))

since the foldLines function doesn't accept a number (a constant value is used internally).

Emitting the type declarations ".d.ts"

Relying on babel for this doesn't seem to be an option.
I've added another tsconfig.types.json file and a npm run build.types script to specifically generate the type declarations.

The inline source maps

I'm not sure if they bring value, since they are created after the typescript transformation step.

I think for the future it would make more sense to rely on something like https://tsdx.io/ so we don't have to maintain all the boilerplate.

Testing steps

  1. The existing tests should pass npm run test
  2. I've imported this package using npm link in a different project and checked if it still worked

npm-debug.log
.DS_Store
package-lock.json
Copy link
Author

Choose a reason for hiding this comment

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

I think it's recommended to have the package-lock inside the source code

@@ -0,0 +1,6 @@
{
"semi": false,
Copy link
Author

Choose a reason for hiding this comment

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

I based these on the way standard was formatting the code

"runtimeArgs": [
"--nolazy"
],
"args": ["./src/${fileBasename}", "--require", "@babel/register", "--reporter", "spec", "--no-timeouts"],
Copy link
Author

Choose a reason for hiding this comment

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

will run just the currently selected test file

@@ -0,0 +1,5 @@
declare module 'emailjs-base64' {
export function encode(input: string | Uint8Array): string
Copy link
Author

Choose a reason for hiding this comment

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

since emailjs-base64 doesn't yet have type declaration, I've declared them temporarily here

@@ -16,38 +17,36 @@
],
"author": "Andris Reinman <[email protected]>",
"scripts": {
"build": "./scripts/build.sh",
"lint": "$(npm bin)/standard",
"build": "rm -rf ./dist/ && npm run build.types && npm run babel.compile",
Copy link
Author

Choose a reason for hiding this comment

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

the ./scripts/build.sh did too much, automatically creating a commit doesn't seem easy to work with

const CHUNK_SZ = 0x8000
const strs = []

for (let i = 0; i < arr.length; i += CHUNK_SZ) {
strs.push(String.fromCharCode.apply(null, arr.subarray(i, i + CHUNK_SZ)))
strs.push(String.fromCharCode.apply(null, Array.from(arr.subarray(i, i + CHUNK_SZ))))
Copy link
Author

Choose a reason for hiding this comment

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

This is one of the places I've had to change the code and add Array.from()

import { encode, decode, convert } from './charset'

describe('#charset', function () {
describe('#encode', function () {
it('should encode UTF-8 to ArrayBuffer', function () {
const str = '신'
const encoded = new Uint8Array([0xEC, 0x8B, 0xA0])
const encoded = new Uint8Array([0xec, 0x8b, 0xa0])
Copy link
Author

Choose a reason for hiding this comment

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

prettier automatically lower-cases the hex codes. There doesn't seem to be a prettier option around this.
An option would be to use prettier-eslint but that comes with other issues (mostly editor integration) and speed of formatting

Copy link
Author

Choose a reason for hiding this comment

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

}
}

// convert single value arrays to single values
const headersObj = Object.fromEntries(
Copy link
Author

Choose a reason for hiding this comment

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

It was hard to work around TS requirements, and it was simpler to do another pass

}

// handle parameter value continuations
// https://tools.ietf.org/html/rfc2231#section-3

const processedParams: Record<
Copy link
Author

Choose a reason for hiding this comment

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

This part had the most actual code changes. Instead of working in the same object, I've split each step to create a new object, so that it can be statically analyzed by TS

}
}
})

return response
const responseParams = { ...initialParams, ...concatenatedParams }
Copy link
Author

Choose a reason for hiding this comment

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

and here I put both values in the same object to get the same result

@nicu-chiciuc nicu-chiciuc marked this pull request as ready for review January 13, 2023 13:50
@nicu-chiciuc
Copy link
Author

@felixhammerl I can't assign someone as a reviewer.

I managed to update the package, while maintain as much of the original source code as possible.

2 things remain to be done:

  1. Choosing a good version number
  2. Figuring out the deployment strategy for NPM

We could rely on Github Actions (instead of Travis) for adding the CI and publishing pipeline, but first we'd need to decide if the direction I was going with this PR is correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant