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(open-payments): replace axios with ky #461

Merged
merged 39 commits into from
Apr 29, 2024
Merged

feat(open-payments): replace axios with ky #461

merged 39 commits into from
Apr 29, 2024

Conversation

mkurapov
Copy link
Contributor

@mkurapov mkurapov commented Apr 18, 2024

Changes proposed in this pull request

First part of making the open payments SDK usable in the web extension manifest V3:
Replace axios with a wrapper for native fetch (ky). This is due to the fact that in the web extension we cannot use XMLHttpRequest that axios uses, but native fetch is (of course) supported.

Context

Progress toward #454

Copy link

changeset-bot bot commented Apr 18, 2024

🦋 Changeset detected

Latest commit: 6eb6ade

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@interledger/open-payments Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

netlify bot commented Apr 18, 2024

Deploy Preview for openpayments-preview canceled.

Name Link
🔨 Latest commit 6eb6ade
🔍 Latest deploy log https://app.netlify.com/sites/openpayments-preview/deploys/662fc485e063900008a70b46

@mkurapov mkurapov changed the base branch from main to 458/mk/node-20 April 18, 2024 16:42
… disable openapi schema validation"

This reverts commit b5f986a.

# Conflicts:
#	packages/open-payments/src/client/requests.test.ts
#	packages/open-payments/src/client/requests.ts
@@ -2,7 +2,7 @@

module.exports = {
transform: {
'^.+\\.tsx?$': ['@swc/jest']
'^.+\\.(t|j)sx?$': ['@swc/jest']
Copy link
Contributor Author

@mkurapov mkurapov Apr 18, 2024

Choose a reason for hiding this comment

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

this is so we transpile JS files as well, particularly for the files we need to transform from ESM to CommonJS in transformIgnorePatterns -> node_modules/ky

"openapi-typescript": "^4.5.0",
"typescript": "^4.9.5"
},
"dependencies": {
"@interledger/http-signature-utils": "workspace:2.0.2",
"@interledger/openapi": "workspace:2.0.1",
"axios": "^1.6.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

👋

@@ -32,16 +32,16 @@
"devDependencies": {
"@types/node": "^20.12.7",
"@types/uuid": "^9.0.0",
"nock": "^13.3.0",
"nock": "14.0.0-beta.5",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the version with experimental support for fetch

@mkurapov mkurapov changed the title 454/mk/use ky feat(open-payments): replace axios with ky Apr 18, 2024
Base automatically changed from 458/mk/node-20 to main April 23, 2024 14:43
@@ -24,14 +24,15 @@
"@changesets/cli": "^2.26.1",
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@swc/jest": "^0.2.24",
"@types/jest": "^29.4.4",
"@swc/core": "^1.5.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's recommended to add @swc/core explicitly when using @swc/jest: https://swc.rs/docs/usage/jest

@@ -13,5 +15,6 @@ module.exports = {
modulePaths: [`<rootDir>/packages/${packageName}/src/`],
id: packageName,
displayName: packageName,
rootDir: '../..'
rootDir: '../..',
transformIgnorePatterns: [`node_modules/(?!.pnpm|${esModules.join('|')})`]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

transpile ESM ky package into CommonJS

Copy link
Contributor Author

@mkurapov mkurapov Apr 25, 2024

Choose a reason for hiding this comment

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

This also means we will need to add the same to the rafiki tests (everywhere where we use the @interledger/open-payments library, since rafiki also uses CJS only

Copy link
Contributor

Choose a reason for hiding this comment

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

How does this relate to the problem w/ the new ESM version of adonis which we couldnt get working in jest?

interledger/rafiki#2334 (comment)

Is this going to be a problem in rafiki for the same reason? Does it clarify that problem at all?

Copy link
Contributor Author

@mkurapov mkurapov Apr 26, 2024

Choose a reason for hiding this comment

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

I think what will end up working is doing the same in Rafiki and by adding the Adonis library to the list of esmModules. Have yet to try, but it follows the same principle

export const createHttpClient = async (
args: CreateHttpClientArgs
): Promise<HttpClient> => {
const { default: ky } = await import('ky')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ky is ESM only

status,
body: data || undefined
status: response.status,
body: undefined
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we always expect 204 in our requests which always come w/o body

@mkurapov mkurapov marked this pull request as ready for review April 24, 2024 14:48
@@ -43,7 +43,7 @@
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */

/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
"moduleResolution": "NodeNext" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
Copy link
Contributor Author

@mkurapov mkurapov Apr 25, 2024

Choose a reason for hiding this comment

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

this is so we properly transpile dynamic import:
https://www.typescriptlang.org/tsconfig/#moduleResolution
(without changing this, we incorrectly compile the dynamic import back to require - which ends up breaking for an ESM only module like ky)

@@ -64,7 +66,7 @@ describe('incoming-payment', (): void => {
},
openApiValidators.successfulValidator
)
expect(result).toStrictEqual(incomingPayment)
expect(result).toEqual(incomingPayment)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate on why this was necessary? I changed back to toStrictEqual and it fails with serializes to the same string. Something that changed with nock? or?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought this was odd as well, but I think it's the difference between how a response is returned in axios vs fetch. It's possible the order in which the object keys are returned are different?

Someone has an unaswered question related exactly to this: https://stackoverflow.com/questions/76211440/why-does-jests-tostrictequal-fail-to-match-json-responses-made-using-the-fetch

Copy link
Contributor

Choose a reason for hiding this comment

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

huh, yeah that is interesting. Wonder what the difference is. Seems innocent enough though.

deps.logger.error(
{ status: errorStatus, errorDescription, url, requestType },
errorMessage
)
Copy link
Contributor

@BlairCurrey BlairCurrey Apr 26, 2024

Choose a reason for hiding this comment

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

This is probably quite the edge case, but errorStatus and errorDescription could be undefined if the error is not a validation error, HTTPError, or Error. Just wondering if we can handle that better such as logging the original error or something. Also thought about defaulting these values to something but in that case we'd still be left to wonder what the original "error" was.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, seems quite unlikely, but updated to log in any case 👍

Copy link
Contributor

@BlairCurrey BlairCurrey left a comment

Choose a reason for hiding this comment

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

Beyond the couple suggestions and questions I left, it looks good with the caveat that I couldn't get it to work when plugging this into Rafiki's integration tests. Although perhaps you have more details or already figured it out. When running it I got:

console.error
    TypeError: A dynamic import callback was invoked without --experimental-vm-modules

You mentioned the jest config would need the same transformIgnorePatterns and transform settings as here but after adding those I still see an error:

ReferenceError: esModules is not defined

@mkurapov
Copy link
Contributor Author

(Spoke in slack, but adding for visibility)

is how we can support this change of the open payments library in rafiki tests: interledger/rafiki@main...mk/op-client-ky-tests

@mkurapov mkurapov linked an issue Apr 29, 2024 that may be closed by this pull request
3 tasks
@mkurapov mkurapov merged commit 8950c21 into main Apr 29, 2024
10 checks passed
@mkurapov mkurapov deleted the 454/mk/use-ky branch April 29, 2024 19:46
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.

Prepare @interledger/open-payments lib for use with manifest V3
3 participants