diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index ad29d71..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], - "extends": [ - "plugin:@typescript-eslint/recommended", - "prettier", - "prettier/@typescript-eslint" - ], - "rules": { - "@typescript-eslint/explicit-member-accessibility": ["off"], - "@typescript-eslint/no-unused-vars": [ - "error", - { "argsIgnorePattern": "^_" } - ], - "@typescript-eslint/no-namespace": ["warn"] - }, - "overrides": [ - { - "files": ["test/*.js"], - "rules": { - "@typescript-eslint/no-var-requires": ["off"] - } - } - ] -} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b1e295..c75b7db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,13 +9,18 @@ jobs: publish-npm: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v4 with: - node-version: 16 + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 22 registry-url: https://registry.npmjs.org/ - - run: yarn --frozen-lockfile - - run: yarn test - - run: npm publish + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: pnpm test + - run: pnpm publish --no-git-checks env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fc1a505..63c0f73 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,12 +11,17 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [ '14', '16', '18', '20'] + node: ['22', '24'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 - name: Setup node - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - - run: yarn --frozen-lockfile - - run: yarn test + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: pnpm test diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..e689001 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,3 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json" +} \ No newline at end of file diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000..da1ea3f --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,9 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript"], + "rules": { + "@typescript-eslint/no-explicit-any": "off", + "no-unused-vars": ["warn", { "caughtErrorsIgnorePattern": "^_", "argsIgnorePattern": "^_" }] + }, + "ignorePatterns": ["node_modules", "built", "pnpm-lock.yaml"] +} diff --git a/README.md b/README.md index 6a76849..2fece78 100644 --- a/README.md +++ b/README.md @@ -68,4 +68,8 @@ const payjp = new Payjp('sk_live_xxx', {maxRetry: 5, retryInitialDelay: 1000, re ``` A delay of retry is calculated based on [Exponential backoff with equal jitter](https://aws.amazon.com/jp/blogs/architecture/exponential-backoff-and-jitter/) algorithm. -Each delay is randomly choiced between "`retryInitialDelay` * 2 ** `retryCount`" and "`retryInitialDelay` * 2 ** `retryCount` / 2" but doesn't exceed `retryMaxDelay`. \ No newline at end of file +Each delay is randomly choiced between "`retryInitialDelay` * 2 ** `retryCount`" and "`retryInitialDelay` * 2 ** `retryCount` / 2" but doesn't exceed `retryMaxDelay`. + +## Contributors + +See the [list of contributors](https://github.com/payjp/payjp-node/graphs/contributors) who participated in this project. diff --git a/example.ts b/example.ts new file mode 100644 index 0000000..5860eb8 --- /dev/null +++ b/example.ts @@ -0,0 +1,78 @@ +import Payjp = require("./built"); + +const PAYJP_SECRET_KEY = process.env.PAYJP_SECRET_KEY; +if (!PAYJP_SECRET_KEY) { + console.error("Please set the PAYJP_SECRET_KEY environment variable"); + console.error("Usage: PAYJP_SECRET_KEY=sk_test_xxx npx ts-node example.ts"); + process.exit(1); +} + +const payjp = Payjp(PAYJP_SECRET_KEY); + +async function main() { + console.log("=== PAY.JP SDK Example ===\n"); + + // 1. Retrieve account information + console.log("1. Retrieving account information..."); + const account = await payjp.accounts.retrieve(); + console.log(` Account ID: ${account.id}`); + console.log(` Email: ${account.email}\n`); + + // 2. Create customer + console.log("2. Creating customer..."); + const customer = await payjp.customers.create({ + email: "test@example.com", + description: "Test customer for SDK verification", + }); + console.log(` Customer ID: ${customer.id}`); + console.log(` Email: ${customer.email}`); + console.log(` Description: ${customer.description}\n`); + + // 3. Retrieve customer + console.log("3. Retrieving customer..."); + const retrievedCustomer = await payjp.customers.retrieve(customer.id); + console.log(` Customer ID: ${retrievedCustomer.id}`); + console.log(` Created at: ${new Date(retrievedCustomer.created * 1000).toLocaleString()}\n`); + + // 4. List customers + console.log("4. Listing customers..."); + const customerList = await payjp.customers.list({ limit: 3 }); + console.log(` Retrieved: ${customerList.data.length}`); + console.log(` Total count: ${customerList.count}\n`); + + // 5. Create plan + console.log("5. Creating plan..."); + const plan = await payjp.plans.create({ + amount: 500, + currency: "jpy", + interval: "month", + name: "Test plan for SDK verification", + }); + console.log(` Plan ID: ${plan.id}`); + console.log(` Amount: ${plan.amount} JPY/${plan.interval}\n`); + + // 6. List charges + console.log("6. Listing charges..."); + const chargeList = await payjp.charges.list({ limit: 3 }); + console.log(` Retrieved: ${chargeList.data.length}`); + console.log(` Total count: ${chargeList.count}\n`); + + // 7. Cleanup + console.log("7. Cleaning up..."); + const deletedPlan = await payjp.plans.delete(plan.id); + console.log(` Plan deleted: ${deletedPlan.deleted ? "success" : "failed"}`); + const deletedCustomer = await payjp.customers.delete(customer.id); + console.log(` Customer deleted: ${deletedCustomer.deleted ? "success" : "failed"}\n`); + + console.log("=== Example completed ==="); +} + +main().catch((error) => { + console.error("An error occurred:"); + if (error.response?.body) { + console.error(JSON.stringify(error.response.body, null, 2)); + } else { + console.error(error.message); + } + process.exit(1); +}); diff --git a/package.json b/package.json index e3608d0..ced6bea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "payjp", - "version": "2.3.0", + "version": "3.0.0", "description": "PAY.JP node.js bindings", "main": "built/index.js", "types": "built/index.d.ts", @@ -16,9 +16,10 @@ "test:debug": "mocha --inspect-brk", "test:typescript": "tsc --noEmit --target esnext --module commonjs test/types/*.ts", "build": "tsc", - "lint": "npm run lint:base -- .", - "lint:base": "eslint --ignore-path .gitignore --ext .js,.ts", - "lint:fix": "npm run lint -- --fix", + "lint": "oxlint .", + "lint:fix": "oxlint --fix .", + "format": "oxfmt .", + "format:check": "oxfmt --check .", "prepublish": "npm run build" }, "repository": { @@ -26,26 +27,15 @@ "url": "git://github.com/payjp/payjp-node.git" }, "author": "PAY.JP (https://pay.jp)", - "contributors": [ - "Daiki Arai ", - "Yoichi Fujimoto " - ], "license": "MIT", "engines": { - "node": ">=12" + "node": ">=22" }, "devDependencies": { - "@types/superagent": "3.8.3", - "@typescript-eslint/eslint-plugin": "^5.17.0", - "@types/prettier": "1.16.1", - "@typescript-eslint/parser": "^5.17.0", - "eslint": "^8.0.0", - "eslint-config-prettier": "4.1.0", + "@types/node": "^22.19.1", "mocha": "^6.0.2", - "typescript": "^4.6.3", - "prettier": "1.17.1" - }, - "dependencies": { - "superagent": "3.8.3" + "oxfmt": "^0.16.0", + "oxlint": "^1.31.0", + "typescript": "^5.7.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..9115ba3 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1687 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/node': + specifier: ^22.19.1 + version: 22.19.1 + mocha: + specifier: ^6.0.2 + version: 6.2.3 + oxfmt: + specifier: ^0.16.0 + version: 0.16.0 + oxlint: + specifier: ^1.31.0 + version: 1.31.0 + typescript: + specifier: ^5.7.2 + version: 5.9.3 + +packages: + + '@oxfmt/darwin-arm64@0.16.0': + resolution: {integrity: sha512-I+Unj7wePcUTK7p/YKtgbm4yer6dw7dTlmCJa0UilFZyge5uD4rwCSfSDx3A+a6Z3A60/SqXMbNR2UyidWF4Cg==} + cpu: [arm64] + os: [darwin] + + '@oxfmt/darwin-x64@0.16.0': + resolution: {integrity: sha512-EfiXFKEOV5gXgEatFK89OOoSmd8E9Xq83TcjPLWQNFBO4cgaQsfKmctpgJmJjQnoUwD7nQsm0ruj3ae7Gva8QA==} + cpu: [x64] + os: [darwin] + + '@oxfmt/linux-arm64-gnu@0.16.0': + resolution: {integrity: sha512-ydcNY9Fn/8TjVswANhdSh+zdgD3tiikNQA68bgXbENHuV3RyYql1qoOM1eGv5xeIVJfkPJme17MKQz3OwMFS4A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/linux-arm64-musl@0.16.0': + resolution: {integrity: sha512-I9WeYe1/YnrfXgXVaKkZITZzil0G0g9IknS2KJbq1lOnpTw3dwViXZ7XMa2cq6Mv7S+4SoDImb7fLQ59AfVX/w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/linux-x64-gnu@0.16.0': + resolution: {integrity: sha512-Szg9lJtZdN5FoCnNbl3N/2pJv8d056NUmk51m60E2tZV7rvwRTrNC8HPc2sVdb1Ti5ogsicpZDYSWA3cwIrJIQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxfmt/linux-x64-musl@0.16.0': + resolution: {integrity: sha512-5koN8nl21ZxOADaMxXHT+mt3YjfXe1nsa23Fanf9aY7B0hcQ6rXYCZ7r5vmpoTtzW/US3aaVcRFZE1cyof+lKw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxfmt/win32-arm64@0.16.0': + resolution: {integrity: sha512-Jaesn+FYn+MudSmWJMPGBAa0PhQXo52Z0ZYeNfzbQP7v2GFbZBI3Cb87+K0aHGlpqK3VEJKXeIaASaTWlkgO1Q==} + cpu: [arm64] + os: [win32] + + '@oxfmt/win32-x64@0.16.0': + resolution: {integrity: sha512-1obVSlb5blwBKgSsE1mNxvcq1pK9I6aXpZDy5d6jjGdrru33dHrH1ASChrcxwCukkToH2SxwYmnzAto0xeuZlw==} + cpu: [x64] + os: [win32] + + '@oxlint/darwin-arm64@1.31.0': + resolution: {integrity: sha512-HqoYNH5WFZRdqGUROTFGOdBcA9y/YdHNoR/ujlyVO53it+q96dujbgKEvlff/WEuo4LbDKBrKLWKTKvOd/VYdg==} + cpu: [arm64] + os: [darwin] + + '@oxlint/darwin-x64@1.31.0': + resolution: {integrity: sha512-gNq+JQXBCkYKQhmJEgSNjuPqmdL8yBEX3v0sueLH3g5ym4OIrNO7ml1M7xzCs0zhINQCR9MsjMJMyBNaF1ed+g==} + cpu: [x64] + os: [darwin] + + '@oxlint/linux-arm64-gnu@1.31.0': + resolution: {integrity: sha512-cRmttpr3yHPwbrvtPNlv+0Zw2Oeh0cU902iMI4fFW9ylbW/vUAcz6DvzGMCYZbII8VDiwQ453SV5AA8xBgMbmw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxlint/linux-arm64-musl@1.31.0': + resolution: {integrity: sha512-0p7vn0hdMdNPIUzemw8f1zZ2rRZ/963EkK3o4P0KUXOPgleo+J9ZIPH7gcHSHtyrNaBifN03wET1rH4SuWQYnA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxlint/linux-x64-gnu@1.31.0': + resolution: {integrity: sha512-vNIbpSwQ4dwN0CUmojG7Y91O3CXOf0Kno7DSTshk/JJR4+u8HNVuYVjX2qBRk0OMc4wscJbEd7wJCl0VJOoCOw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxlint/linux-x64-musl@1.31.0': + resolution: {integrity: sha512-4avnH09FJRTOT2cULdDPG0s14C+Ku4cnbNye6XO7rsiX6Bprz+aQblLA+1WLOr7UfC/0zF+jnZ9K5VyBBJy9Kw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxlint/win32-arm64@1.31.0': + resolution: {integrity: sha512-mQaD5H93OUpxiGjC518t5wLQikf0Ur5mQEKO2VoTlkp01gqmrQ+hyCLOzABlsAIAeDJD58S9JwNOw4KFFnrqdw==} + cpu: [arm64] + os: [win32] + + '@oxlint/win32-x64@1.31.0': + resolution: {integrity: sha512-AS/h58HfloccRlVs7P3zbyZfxNS62JuE8/3fYGjkiRlR1ZoDxdqmz5QgLEn+YxxFUTMmclGAPMFHg9z2Pk315A==} + cpu: [x64] + os: [win32] + + '@types/node@22.19.1': + resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} + + ansi-colors@3.2.3: + resolution: {integrity: sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==} + engines: {node: '>=6'} + + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array.prototype.reduce@1.0.8: + resolution: {integrity: sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + cliui@5.0.0: + resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.6: + resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} + deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + + es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + + flat@4.1.1: + resolution: {integrity: sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==} + hasBin: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + glob@7.1.3: + resolution: {integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==} + deprecated: Glob versions prior to v9 are no longer supported + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@3.13.1: + resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} + hasBin: true + + locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@2.2.0: + resolution: {integrity: sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==} + engines: {node: '>=4'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + minimatch@3.0.4: + resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.4: + resolution: {integrity: sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==} + deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) + hasBin: true + + mocha@6.2.3: + resolution: {integrity: sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==} + engines: {node: '>= 6.0.0'} + hasBin: true + + ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + + node-environment-flags@1.0.5: + resolution: {integrity: sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.0: + resolution: {integrity: sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.getownpropertydescriptors@2.1.8: + resolution: {integrity: sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + oxfmt@0.16.0: + resolution: {integrity: sha512-uRnnBAN0zH07FXSfvSKbIw+Jrohv4Px2RwNiZOGI4/pvns4sx0+k4WSt+tqwd7bDeoWaXiGmhZgnbK63hi6hVQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + oxlint@1.31.0: + resolution: {integrity: sha512-U+Z3VShi1zuLF2Hz/pm4vWJUBm5sDHjwSzj340tz4tS2yXg9H5PTipsZv+Yu/alg6Z7EM2cZPKGNBZAvmdfkQg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=0.8.1' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string-width@3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@6.0.0: + resolution: {integrity: sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==} + engines: {node: '>=6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + wide-align@1.1.3: + resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==} + + wrap-ansi@5.1.0: + resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} + engines: {node: '>=6'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + yargs-parser@13.1.2: + resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} + + yargs-unparser@1.6.0: + resolution: {integrity: sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==} + engines: {node: '>=6'} + + yargs@13.3.2: + resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} + +snapshots: + + '@oxfmt/darwin-arm64@0.16.0': + optional: true + + '@oxfmt/darwin-x64@0.16.0': + optional: true + + '@oxfmt/linux-arm64-gnu@0.16.0': + optional: true + + '@oxfmt/linux-arm64-musl@0.16.0': + optional: true + + '@oxfmt/linux-x64-gnu@0.16.0': + optional: true + + '@oxfmt/linux-x64-musl@0.16.0': + optional: true + + '@oxfmt/win32-arm64@0.16.0': + optional: true + + '@oxfmt/win32-x64@0.16.0': + optional: true + + '@oxlint/darwin-arm64@1.31.0': + optional: true + + '@oxlint/darwin-x64@1.31.0': + optional: true + + '@oxlint/linux-arm64-gnu@1.31.0': + optional: true + + '@oxlint/linux-arm64-musl@1.31.0': + optional: true + + '@oxlint/linux-x64-gnu@1.31.0': + optional: true + + '@oxlint/linux-x64-musl@1.31.0': + optional: true + + '@oxlint/win32-arm64@1.31.0': + optional: true + + '@oxlint/win32-x64@1.31.0': + optional: true + + '@types/node@22.19.1': + dependencies: + undici-types: 6.21.0 + + ansi-colors@3.2.3: {} + + ansi-regex@3.0.1: {} + + ansi-regex@4.1.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array.prototype.reduce@1.0.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-array-method-boxes-properly: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + is-string: 1.1.1 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + balanced-match@1.0.2: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + browser-stdout@1.3.1: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + camelcase@5.3.1: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + cliui@5.0.0: + dependencies: + string-width: 3.1.0 + strip-ansi: 5.2.0 + wrap-ansi: 5.1.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-name@1.1.3: {} + + concat-map@0.0.1: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.6(supports-color@6.0.0): + dependencies: + ms: 2.1.1 + optionalDependencies: + supports-color: 6.0.0 + + decamelize@1.2.0: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + diff@3.5.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + emoji-regex@7.0.3: {} + + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-array-method-boxes-properly@1.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escape-string-regexp@1.0.5: {} + + esprima@4.0.1: {} + + find-up@3.0.0: + dependencies: + locate-path: 3.0.0 + + flat@4.1.1: + dependencies: + is-buffer: 2.0.5 + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + fs.realpath@1.0.0: {} + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + glob@7.1.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + growl@1.10.5: {} + + has-bigints@1.1.0: {} + + has-flag@3.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@2.0.5: {} + + is-callable@1.2.7: {} + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@2.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + js-yaml@3.13.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + locate-path@3.0.0: + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + + lodash@4.17.21: {} + + log-symbols@2.2.0: + dependencies: + chalk: 2.4.2 + + math-intrinsics@1.1.0: {} + + minimatch@3.0.4: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + mkdirp@0.5.4: + dependencies: + minimist: 1.2.8 + + mocha@6.2.3: + dependencies: + ansi-colors: 3.2.3 + browser-stdout: 1.3.1 + debug: 3.2.6(supports-color@6.0.0) + diff: 3.5.0 + escape-string-regexp: 1.0.5 + find-up: 3.0.0 + glob: 7.1.3 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 3.13.1 + log-symbols: 2.2.0 + minimatch: 3.0.4 + mkdirp: 0.5.4 + ms: 2.1.1 + node-environment-flags: 1.0.5 + object.assign: 4.1.0 + strip-json-comments: 2.0.1 + supports-color: 6.0.0 + which: 1.3.1 + wide-align: 1.1.3 + yargs: 13.3.2 + yargs-parser: 13.1.2 + yargs-unparser: 1.6.0 + + ms@2.1.1: {} + + node-environment-flags@1.0.5: + dependencies: + object.getownpropertydescriptors: 2.1.8 + semver: 5.7.2 + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.0: + dependencies: + define-properties: 1.2.1 + function-bind: 1.1.2 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.getownpropertydescriptors@2.1.8: + dependencies: + array.prototype.reduce: 1.0.8 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + gopd: 1.2.0 + safe-array-concat: 1.1.3 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + oxfmt@0.16.0: + optionalDependencies: + '@oxfmt/darwin-arm64': 0.16.0 + '@oxfmt/darwin-x64': 0.16.0 + '@oxfmt/linux-arm64-gnu': 0.16.0 + '@oxfmt/linux-arm64-musl': 0.16.0 + '@oxfmt/linux-x64-gnu': 0.16.0 + '@oxfmt/linux-x64-musl': 0.16.0 + '@oxfmt/win32-arm64': 0.16.0 + '@oxfmt/win32-x64': 0.16.0 + + oxlint@1.31.0: + optionalDependencies: + '@oxlint/darwin-arm64': 1.31.0 + '@oxlint/darwin-x64': 1.31.0 + '@oxlint/linux-arm64-gnu': 1.31.0 + '@oxlint/linux-arm64-musl': 1.31.0 + '@oxlint/linux-x64-gnu': 1.31.0 + '@oxlint/linux-x64-musl': 1.31.0 + '@oxlint/win32-arm64': 1.31.0 + '@oxlint/win32-x64': 1.31.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@3.0.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + path-exists@3.0.0: {} + + path-is-absolute@1.0.1: {} + + possible-typed-array-names@1.1.0: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + semver@5.7.2: {} + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + sprintf-js@1.0.3: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + + string-width@3.1.0: + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + + strip-json-comments@2.0.1: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@6.0.0: + dependencies: + has-flag: 3.0.0 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@5.9.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-module@2.0.1: {} + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + wide-align@1.1.3: + dependencies: + string-width: 2.1.1 + + wrap-ansi@5.1.0: + dependencies: + ansi-styles: 3.2.1 + string-width: 3.1.0 + strip-ansi: 5.2.0 + + wrappy@1.0.2: {} + + y18n@4.0.3: {} + + yargs-parser@13.1.2: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-unparser@1.6.0: + dependencies: + flat: 4.1.1 + lodash: 4.17.21 + yargs: 13.3.2 + + yargs@13.3.2: + dependencies: + cliui: 5.0.0 + find-up: 3.0.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 3.1.0 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 13.1.2 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..7164bc4 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1 @@ +minimumReleaseAge: 20160 # in minutes (2 weeks) diff --git a/src/account.ts b/src/account.ts index 0af3315..457f6c0 100644 --- a/src/account.ts +++ b/src/account.ts @@ -1,16 +1,15 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Accounts extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'accounts'; + this.resource = "accounts"; } retrieve(): Promise { - return this.request('GET', `${this.resource}`); + return this.request("GET", `${this.resource}`); } - } diff --git a/src/balance.ts b/src/balance.ts index aac3935..b2cb992 100644 --- a/src/balance.ts +++ b/src/balance.ts @@ -1,23 +1,23 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Balances extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'balances'; + this.resource = "balances"; } list(query: I.BalanceListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } statementUrls(id: string, query: I.StatementUrlOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/statement_urls`, query); + return this.request("POST", `${this.resource}/${id}/statement_urls`, query); } } diff --git a/src/card.ts b/src/card.ts index 66c8fcf..6091e47 100644 --- a/src/card.ts +++ b/src/card.ts @@ -1,32 +1,31 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Cards extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'cards'; + this.resource = "cards"; } list(customerId: string, query: I.ListOptions = {}): Promise> { - return this.request('GET', `customers/${customerId}/${this.resource}`, query); + return this.request("GET", `customers/${customerId}/${this.resource}`, query); } create(customerId: string, query: object = {}): Promise { - return this.request('POST', `customers/${customerId}/${this.resource}`, query); + return this.request("POST", `customers/${customerId}/${this.resource}`, query); } retrieve(customerId: string, id: string): Promise { - return this.request('GET', `customers/${customerId}/${this.resource}/${id}`); + return this.request("GET", `customers/${customerId}/${this.resource}/${id}`); } update(customerId: string, id: string, query: object = {}): Promise { - return this.request('POST', `customers/${customerId}/${this.resource}/${id}`, query); + return this.request("POST", `customers/${customerId}/${this.resource}/${id}`, query); } delete(customerId: string, id: string): Promise { - return this.request('DELETE', `customers/${customerId}/${this.resource}/${id}`); + return this.request("DELETE", `customers/${customerId}/${this.resource}/${id}`); } - } diff --git a/src/charge.ts b/src/charge.ts index f670c88..b873ee0 100644 --- a/src/charge.ts +++ b/src/charge.ts @@ -1,45 +1,43 @@ -import * as I from './index'; -import Resource from './resource'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Charges extends Resource { - resource: string; constructor(payjp) { super(payjp); - this.resource = 'charges'; + this.resource = "charges"; } list(query: I.ChargeListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } create(query: I.ChargeCreationOptions): Promise { - return this.request('POST', this.resource, query); + return this.request("POST", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } update(id: string, query: I.ChargeUpdateOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}`, query); + return this.request("POST", `${this.resource}/${id}`, query); } refund(id: string, query: I.RefundCreationOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/refund`, query); + return this.request("POST", `${this.resource}/${id}/refund`, query); } reauth(id: string, query: I.ChargeReauthOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/reauth`, query); + return this.request("POST", `${this.resource}/${id}/reauth`, query); } capture(id: string, query: I.ChargeCaptureOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/capture`, query); + return this.request("POST", `${this.resource}/${id}/capture`, query); } tds_finish(id: string): Promise { - return this.request('POST', `${this.resource}/${id}/tds_finish`); + return this.request("POST", `${this.resource}/${id}/tds_finish`); } - } diff --git a/src/customer.ts b/src/customer.ts index 6017692..711b460 100644 --- a/src/customer.ts +++ b/src/customer.ts @@ -1,23 +1,22 @@ -import Resource from './resource'; -import Cards from './card'; -import * as I from './index'; +import Cards from "./card"; +import type * as I from "./index"; +import Resource from "./resource"; class CustomerSubscriptions extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'subscriptions'; + this.resource = "subscriptions"; } list(id: string, query: I.CustomerSubscriptionListOptions = {}): Promise> { - return this.request('GET', `customers/${id}/${this.resource}`, query); + return this.request("GET", `customers/${id}/${this.resource}`, query); } retrieve(id: string, subscriptionId: string): Promise { - return this.request('GET', `customers/${id}/${this.resource}/${subscriptionId}`); + return this.request("GET", `customers/${id}/${this.resource}/${subscriptionId}`); } - } export default class Customers extends Resource { @@ -27,29 +26,28 @@ export default class Customers extends Resource { constructor(payjp) { super(payjp); - this.resource = 'customers'; + this.resource = "customers"; this.cards = new Cards(payjp); this.subscriptions = new CustomerSubscriptions(payjp); } list(query: I.ListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } create(query: I.CustomerCreationOptions = {}): Promise { - return this.request('POST', this.resource, query); + return this.request("POST", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } update(id: string, query: I.CustomerUpdateOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}`, query); + return this.request("POST", `${this.resource}/${id}`, query); } delete(id: string): Promise { - return this.request('DELETE', `${this.resource}/${id}`); + return this.request("DELETE", `${this.resource}/${id}`); } - } diff --git a/src/event.ts b/src/event.ts index 7e96d80..7be3592 100644 --- a/src/event.ts +++ b/src/event.ts @@ -1,20 +1,19 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Events extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'events'; + this.resource = "events"; } list(query: I.EventListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } - } diff --git a/src/index.ts b/src/index.ts index 57ae2a4..7122ffb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,116 +1,114 @@ -import Accounts from './account'; -import Charges from './charge'; -import Customers from './customer'; -import Events from './event'; -import Plans from './plan'; -import Subscriptions from './subscription'; -import Tenants from './tenants'; -import TenantTransfers from './tenantTransfers'; -import Tokens from './token'; -import Transfers from './transfer'; -import Statements from './statement'; -import Terms from "./term"; +import Accounts from "./account"; import Balances from "./balance"; +import Charges from "./charge"; +import Customers from "./customer"; +import Events from "./event"; +import Plans from "./plan"; +import Statements from "./statement"; +import Subscriptions from "./subscription"; +import Tenants from "./tenants"; +import TenantTransfers from "./tenantTransfers"; +import Terms from "./term"; import ThreeDSecureRequests from "./threeDSecureRequest"; +import Tokens from "./token"; +import Transfers from "./transfer"; namespace Payjp { - export interface PayjpStatic { - (apikey: string, options?: PayjpOptions): Payjp; - } + export type PayjpStatic = (apikey: string, options?: PayjpOptions) => Payjp; export interface Payjp { - apikey: string, - config: PayjpOptions, - charges: Charges, - customers: Customers, - plans: Plans, - subscriptions: Subscriptions, - tokens: Tokens, - transfers: Transfers, - events: Events, - accounts: Accounts, - tenants: Tenants, - tenant_transfers: TenantTransfers, - statements: Statements, - terms: Terms, - balances: Balances, - three_d_secure_requests: ThreeDSecureRequests, + apikey: string; + config: PayjpOptions; + charges: Charges; + customers: Customers; + plans: Plans; + subscriptions: Subscriptions; + tokens: Tokens; + transfers: Transfers; + events: Events; + accounts: Accounts; + tenants: Tenants; + tenant_transfers: TenantTransfers; + statements: Statements; + terms: Terms; + balances: Balances; + three_d_secure_requests: ThreeDSecureRequests; } export interface PayjpOptions { - timeout?: number, - apibase?: string, - maxRetry?: number, - retryInitialDelay?: number, - retryMaxDelay?: number, + timeout?: number; + apibase?: string; + maxRetry?: number; + retryInitialDelay?: number; + retryMaxDelay?: number; } export interface PaginationOptions { - limit?: number, - offset?: number, + limit?: number; + offset?: number; } export interface ListOptions extends PaginationOptions { - since?: number, - until?: number, + since?: number; + until?: number; } export interface ChargeListOptions extends TransferChargeListOptions { - subscription?: string, - tenant?: string, - term?: string, + subscription?: string; + tenant?: string; + term?: string; } export interface CustomerSubscriptionListOptions extends ListOptions { - plan?: string, - status?: "trial" | "active" | "canceled" | "paused", + plan?: string; + status?: "trial" | "active" | "canceled" | "paused"; } export interface SubscriptionListOptions extends CustomerSubscriptionListOptions { - customer?: string, + customer?: string; } export interface EventListOptions extends ListOptions { - resource_id?: string, - object?: string, - type?: string, + resource_id?: string; + object?: string; + type?: string; } export interface TransferListOptions extends ListOptions { - status?: "pending" | "paid" | "failed" | "stop" | "carried_over" | "recombination", - since_scheduled_date?: number, - until_scheduled_date?: number, + status?: "pending" | "paid" | "failed" | "stop" | "carried_over" | "recombination"; + since_scheduled_date?: number; + until_scheduled_date?: number; } export interface TransferChargeListOptions extends ListOptions { - customer?: string, + customer?: string; } export interface TenantTransferListOptions extends TransferListOptions { - transfer?: string, - tenant?: string, + transfer?: string; + tenant?: string; } export interface StatementListOptions extends ListOptions { - owner?: "merchant" | "tenant", - source_transfer?: string, - tenant?: string, - term?: string, - type?: "sales" | "service_fee" | "transfer_fee" | "misc", + owner?: "merchant" | "tenant"; + source_transfer?: string; + tenant?: string; + term?: string; + type?: "sales" | "service_fee" | "transfer_fee" | "misc"; } export interface TermListOptions extends PaginationOptions { - since_start_at?: number, - until_start_at?: number, + since_start_at?: number; + until_start_at?: number; } export interface BalanceListOptions extends ListOptions { - since_due_date?: number, - until_due_date?: number, - state?: "collecting" | "transfer" | "claim", - closed?: boolean, - owner?: "merchant" | "tenant", - tenant?: string, + since_due_date?: number; + until_due_date?: number; + state?: "collecting" | "transfer" | "claim"; + closed?: boolean; + owner?: "merchant" | "tenant"; + tenant?: string; } interface OptionsMetadata { @@ -122,197 +120,197 @@ namespace Payjp { } export interface ChargeCreationOptions extends WithMetadata { - amount?: number, - currency?: "jpy", - product?: string, - customer?: string, - card?: string, - description?: string, - capture?: boolean, - expiry_days?: number, - platform_fee?: number, - tenant?: string, - three_d_secure?: boolean, + amount?: number; + currency?: "jpy"; + product?: string; + customer?: string; + card?: string; + description?: string; + capture?: boolean; + expiry_days?: number; + platform_fee?: number; + tenant?: string; + three_d_secure?: boolean; } export interface ChargeUpdateOptions extends WithMetadata { - description?: string, + description?: string; } export interface ChargeReauthOptions { - expiry_days?: number, + expiry_days?: number; } export interface ChargeCaptureOptions { - amount?: number, + amount?: number; } export interface RefundCreationOptions { - amount?: number, - refund_reason?: string, + amount?: number; + refund_reason?: string; } export interface CustomerCreationOptions extends WithMetadata { - email?: string, - description?: string, - id?: string, - card?: string, + email?: string; + description?: string; + id?: string; + card?: string; } export interface CustomerUpdateOptions extends WithMetadata { - email?: string, - description?: string, - default_card?: string, - card?: string, + email?: string; + description?: string; + default_card?: string; + card?: string; } export interface PlanCreationOptions extends WithMetadata { - amount: number, - currency: "jpy", - interval: "month" | "year", - id?: string, - name?: string, - trial_days?: number, - billing_day?: number, + amount: number; + currency: "jpy"; + interval: "month" | "year"; + id?: string; + name?: string; + trial_days?: number; + billing_day?: number; } export interface PlanUpdateOptions extends WithMetadata { - name?: string, + name?: string; } export interface SubscriptionCreationOptions extends WithMetadata { - customer: string, - plan: string, - trial_end?: number | "now", - prorate?: boolean, + customer: string; + plan: string; + trial_end?: number | "now"; + prorate?: boolean; } export interface SubscriptionUpdateOptions extends WithMetadata { - trial_end?: number | "now", - plan?: string, - prorate?: boolean, - next_cycle_plan?: string, + trial_end?: number | "now"; + plan?: string; + prorate?: boolean; + next_cycle_plan?: string; } export interface SubscriptionResumeOptions { - trial_end?: number | "now", - prorate?: boolean, + trial_end?: number | "now"; + prorate?: boolean; } export interface SubscriptionDeleteOptions { - prorate?: boolean, + prorate?: boolean; } export interface TenantCreationOptions extends WithMetadata { - name: string, - id?: string, - platform_fee_rate: string | number, - payjp_fee_included?: boolean, - minimum_transfer_amount?: number, - bank_code?: string, - bank_branch_code?: string, - bank_account_type?: string, - bank_account_number?: string, - bank_account_holder_name?: string, + name: string; + id?: string; + platform_fee_rate: string | number; + payjp_fee_included?: boolean; + minimum_transfer_amount?: number; + bank_code?: string; + bank_branch_code?: string; + bank_account_type?: string; + bank_account_number?: string; + bank_account_holder_name?: string; } export interface TenantUpdateOptions extends WithMetadata { - name?: string, - platform_fee_rate?: string | number, - minimum_transfer_amount?: number, - bank_code?: string, - bank_branch_code?: string, - bank_account_type?: string, - bank_account_number?: string, - bank_account_holder_name?: string, + name?: string; + platform_fee_rate?: string | number; + minimum_transfer_amount?: number; + bank_code?: string; + bank_branch_code?: string; + bank_account_type?: string; + bank_account_number?: string; + bank_account_holder_name?: string; } export interface StatementUrlOptions { - platformer?: boolean, + platformer?: boolean; } export interface List { - object: "list", - count: number, - data: T[], - has_more: boolean, - url: string + object: "list"; + count: number; + data: T[]; + has_more: boolean; + url: string; } - type ThreeDSecureStatus = null | 'unverified' | 'verified' | 'attempted' | 'failed' | 'error'; + type ThreeDSecureStatus = null | "unverified" | "verified" | "attempted" | "failed" | "error"; export interface Charge { - object: "charge", - amount: number, - amount_refunded: number, - captured: boolean, - captured_at: number | null, - card: Card | null, - created: number, - currency: string, - customer: string | null, - description: string | null, - expired_at: number | null, - failure_code: string | null, - failure_message: string | null, - fee_rate: string | null, - id: string, - livemode: boolean, - metadata: OptionsMetadata | null, - paid: boolean, - refund_reason: string | null, - refunded: boolean, - subscription: string | null, - platform_fee?: number | null, - platform_fee_rate?: string | null, - total_platform_fee?: number, - tenant?: string | null, - product?: any, - three_d_secure_status: ThreeDSecureStatus, - term_id: string | null, + object: "charge"; + amount: number; + amount_refunded: number; + captured: boolean; + captured_at: number | null; + card: Card | null; + created: number; + currency: string; + customer: string | null; + description: string | null; + expired_at: number | null; + failure_code: string | null; + failure_message: string | null; + fee_rate: string | null; + id: string; + livemode: boolean; + metadata: OptionsMetadata | null; + paid: boolean; + refund_reason: string | null; + refunded: boolean; + subscription: string | null; + platform_fee?: number | null; + platform_fee_rate?: string | null; + total_platform_fee?: number; + tenant?: string | null; + product?: any; + three_d_secure_status: ThreeDSecureStatus; + term_id: string | null; } export interface Customer { - object: "customer", - cards: List, - created: number, - default_card: string | null, - description: string, - email: string | null, - id: string, - livemode: boolean, - metadata: OptionsMetadata | null, - subscriptions: List, + object: "customer"; + cards: List; + created: number; + default_card: string | null; + description: string; + email: string | null; + id: string; + livemode: boolean; + metadata: OptionsMetadata | null; + subscriptions: List; } export interface Card { - object: "card", - address_city: string | null, - address_line1: string | null, - address_line2: string | null, - address_state: string | null, - address_zip: string | null, - address_zip_check: string, - brand: string, - country: string | null, - created: number, - customer: string | null, - cvc_check: string, - exp_month: number, - exp_year: number, - fingerprint: string, - id: string, - last4: string, - livemode: boolean, - metadata: OptionsMetadata | null, - name: string | null, - three_d_secure_status: ThreeDSecureStatus, - email: string | null, - phone: string | null, + object: "card"; + address_city: string | null; + address_line1: string | null; + address_line2: string | null; + address_state: string | null; + address_zip: string | null; + address_zip_check: string; + brand: string; + country: string | null; + created: number; + customer: string | null; + cvc_check: string; + exp_month: number; + exp_year: number; + fingerprint: string; + id: string; + last4: string; + livemode: boolean; + metadata: OptionsMetadata | null; + name: string | null; + three_d_secure_status: ThreeDSecureStatus; + email: string | null; + phone: string | null; } export interface Plan { - object: "plan", + object: "plan"; amount: number; billing_day: number | null; created: number; @@ -326,145 +324,155 @@ namespace Payjp { } export interface Subscription { - object: "subscription", - canceled_at: number | null, - created: number, - current_period_end: number, - current_period_start: number, - customer: string, - id: string, - livemode: boolean, - metadata: OptionsMetadata | null, - next_cycle_plan: Plan | null, - paused_at: number | null, - plan: Plan, - prorate: boolean, - resumed_at: number | null, - start: number, - status: string, - trial_end: number | null, - trial_start: number | null, + object: "subscription"; + canceled_at: number | null; + created: number; + current_period_end: number; + current_period_start: number; + customer: string; + id: string; + livemode: boolean; + metadata: OptionsMetadata | null; + next_cycle_plan: Plan | null; + paused_at: number | null; + plan: Plan; + prorate: boolean; + resumed_at: number | null; + start: number; + status: string; + trial_end: number | null; + trial_start: number | null; } export interface Token { - object: "token", - card: Card, - created: number, - id: string, - livemode: boolean, - used: boolean, + object: "token"; + card: Card; + created: number; + id: string; + livemode: boolean; + used: boolean; } interface Summary { - charge_count: number, - charge_fee: number, - charge_gross: number, - net: number, - refund_amount: number, - refund_count: number, - dispute_amount: number, - dispute_count: number, + charge_count: number; + charge_fee: number; + charge_gross: number; + net: number; + refund_amount: number; + refund_count: number; + dispute_amount: number; + dispute_count: number; } interface TransferBase { - object: string, - amount: number, - carried_balance: number | null, - charges: List, - created: number, - currency: "jpy", - id: string, - livemode: boolean, - scheduled_date: string, - status: string, - summary: Summary, - term_end: number, - term_start: number, - transfer_amount: number | null, - transfer_date: string | null, + object: string; + amount: number; + carried_balance: number | null; + charges: List; + created: number; + currency: "jpy"; + id: string; + livemode: boolean; + scheduled_date: string; + status: string; + summary: Summary; + term_end: number; + term_start: number; + transfer_amount: number | null; + transfer_date: string | null; } export interface Transfer extends TransferBase { - object: "transfer", - description: string | null, + object: "transfer"; + description: string | null; } export interface Event { - object: "event", - livemode: boolean, - id: string, - data: Charge | Customer | Card | Plan | Subscription | Token | Transfer | Tenant | TenantTransfer, - pending_webhooks: number, - created: number, - type: string, + object: "event"; + livemode: boolean; + id: string; + data: + | Charge + | Customer + | Card + | Plan + | Subscription + | Token + | Transfer + | Tenant + | TenantTransfer; + pending_webhooks: number; + created: number; + type: string; } export interface Account { - object: "account", - created: number, - email: string, - id: string, - merchant: Merchant, - team_id: string, + object: "account"; + created: number; + email: string; + id: string; + merchant: Merchant; + team_id: string; } export interface Merchant { - object: "merchant", - bank_enabled: boolean, - brands_accepted: string[], - business_type: string | null, - charge_type: string[] | null, - country: string | null, - created: number, - currencies_supported: string[], - default_currency: string, - details_submitted: boolean, - id: string, - livemode_activated_at: number | null, - livemode_enabled: boolean, - product_name: string | null, - product_type: string[] | null, - site_published: boolean | null, + object: "merchant"; + bank_enabled: boolean; + brands_accepted: string[]; + business_type: string | null; + charge_type: string[] | null; + country: string | null; + created: number; + currencies_supported: string[]; + default_currency: string; + details_submitted: boolean; + id: string; + livemode_activated_at: number | null; + livemode_enabled: boolean; + product_name: string | null; + product_type: string[] | null; + site_published: boolean | null; } export interface Tenant { - created: number, - name: string, - id: string, - livemode: boolean, - metadata: OptionsMetadata | null, - object: "tenant", - platform_fee_rate: string, - minimum_transfer_amount: number, - bank_account_number: string, - bank_branch_code: string, - bank_code: string, - bank_account_holder_name: string, - bank_account_type: string, - bank_account_status: string, - currencies_supported: string[], - default_currency: "jpy", - payjp_fee_included: boolean, - reviewed_brands: ReviewedBrand[], + created: number; + name: string; + id: string; + livemode: boolean; + metadata: OptionsMetadata | null; + object: "tenant"; + platform_fee_rate: string; + minimum_transfer_amount: number; + bank_account_number: string; + bank_branch_code: string; + bank_code: string; + bank_account_holder_name: string; + bank_account_type: string; + bank_account_status: string; + currencies_supported: string[]; + default_currency: "jpy"; + payjp_fee_included: boolean; + reviewed_brands: ReviewedBrand[]; } export interface Statement { - object: "statement", - livemode: boolean, - id: string, - title: string, - type: "sales" | "service_fee" | "transfer_fee" | "forfeit" | "misc", - created: number, - updated: number, - tenant_id: string | null, - term: Term | null, - balance_id: string | null, - items: StatementItems[], - net: number, + object: "statement"; + livemode: boolean; + id: string; + title: string; + type: "sales" | "service_fee" | "transfer_fee" | "forfeit" | "misc"; + created: number; + updated: number; + tenant_id: string | null; + term: Term | null; + balance_id: string | null; + items: StatementItems[]; + net: number; } export interface StatementItems { - subject: "gross_sales" + subject: + | "gross_sales" | "fee" | "platform_fee" | "gross_refund" @@ -478,50 +486,50 @@ namespace Payjp { | "forfeit" | "reallocation" | "transfer_fee" - | "other", - amount: number, - name: string, - tax_rate: string, + | "other"; + amount: number; + name: string; + tax_rate: string; } export interface StatementUrl { - object: "statement_url", - url: string, - expires: number, + object: "statement_url"; + url: string; + expires: number; } interface ReviewedBrand { - brand: string, - status: string, - available_date: number | null, + brand: string; + status: string; + available_date: number | null; } export interface ApplicationUrl { - object: "application_url", - url: string, - expires: number, + object: "application_url"; + url: string; + expires: number; } export interface TenantTransfer extends TransferBase { - object: "tenant_transfer", - tenant_id: string, - summary: TenantTransferSummary, + object: "tenant_transfer"; + tenant_id: string; + summary: TenantTransferSummary; } interface TenantTransferSummary extends Summary { - total_platform_fee: number, + total_platform_fee: number; } export interface Term { - object: "term", - id: string, - livemode: boolean, - start_at: number, - end_at: number | null, - closed: boolean, - charge_count: number, - refund_count: number, - dispute_count: number, + object: "term"; + id: string; + livemode: boolean; + start_at: number; + end_at: number | null; + closed: boolean; + charge_count: number; + refund_count: number; + dispute_count: number; } export interface BankInfo { @@ -534,83 +542,86 @@ namespace Payjp { } export interface Balance { - object: "balance", - id: string, - livemode: boolean, - created: number, - tenant_id: string | null, - net: number, - statements: Statement[], - state: "collecting" | "transfer" | "claim", - closed: boolean, - closed_date: number | null, - due_date: null | number, - bank_info: null | BankInfo + object: "balance"; + id: string; + livemode: boolean; + created: number; + tenant_id: string | null; + net: number; + statements: Statement[]; + state: "collecting" | "transfer" | "claim"; + closed: boolean; + closed_date: number | null; + due_date: null | number; + bank_info: null | BankInfo; } export interface ThreeDSecureRequest { - object: 'three_d_secure_request', - id: string, - resource_id: string, - livemode: boolean, - created: number, - state: 'created' | 'in_progress' | 'result_received' | 'finished', - started_at: null | number, - result_received_at: null | number, - finished_at: null | number, - expired_at: null | number, - tenant_id: null | string, - three_d_secure_status: ThreeDSecureStatus, + object: "three_d_secure_request"; + id: string; + resource_id: string; + livemode: boolean; + created: number; + state: "created" | "in_progress" | "result_received" | "finished"; + started_at: null | number; + result_received_at: null | number; + finished_at: null | number; + expired_at: null | number; + tenant_id: null | string; + three_d_secure_status: ThreeDSecureStatus; } export interface ThreeDSecureRequestCreationOptions { - resource_id: string, - tenant_id?: string, + resource_id: string; + tenant_id?: string; } export interface ThreeDSecureRequestListOptions extends ListOptions { - resource_id?: string, - tenant_id?: string, + resource_id?: string; + tenant_id?: string; } export interface Deleted { - deleted: boolean, - id: string, - livemode: boolean, + deleted: boolean; + id: string; + livemode: boolean; } export interface PayjpError { error: { - message: string, - type: string, - status: number, - code?: string, - param?: string, - charge?: string, - } + message: string; + type: string; + status: number; + code?: string; + param?: string; + charge?: string; + }; } export interface ResponseError { - status?: number | undefined, - response?: { body?: PayjpError, [propName: string]: any } | undefined, - message: string, - timeout?: number, + status?: number | undefined; + response?: { body?: PayjpError; [propName: string]: any } | undefined; + message: string; + timeout?: number; - [propName: string]: any, + [propName: string]: any; } } -const Payjp: Payjp.PayjpStatic = function (apikey: string, options: Payjp.PayjpOptions = {}): Payjp.Payjp { +const Payjp: Payjp.PayjpStatic = function ( + apikey: string, + options: Payjp.PayjpOptions = {}, +): Payjp.Payjp { if (!apikey) { - throw new Error('Please set apikey.'); - } else if (apikey.indexOf('pk_') === 0) { - throw new Error('You cannot use the public apikey in this SDK.'); + throw new Error("Please set apikey."); + } else if (apikey.indexOf("pk_") === 0) { + throw new Error("You cannot use the public apikey in this SDK."); } const payjpConfig = { apikey, config: { - apibase: options.apibase || 'https://api.pay.jp/v1', + apibase: options.apibase || "https://api.pay.jp/v1", timeout: options.timeout || 0, maxRetry: options.maxRetry || 0, retryInitialDelay: options.retryInitialDelay || 2000, @@ -618,9 +629,7 @@ const Payjp: Payjp.PayjpStatic = function (apikey: string, options: Payjp.PayjpO }, }; return { - apikey, - // todo not using spread operator for Node.js v6 support - config: payjpConfig.config, + ...payjpConfig, charges: new Charges(payjpConfig), customers: new Customers(payjpConfig), plans: new Plans(payjpConfig), @@ -630,12 +639,12 @@ const Payjp: Payjp.PayjpStatic = function (apikey: string, options: Payjp.PayjpO events: new Events(payjpConfig), accounts: new Accounts(payjpConfig), tenants: new Tenants(payjpConfig), - 'tenant_transfers': new TenantTransfers(payjpConfig), + tenant_transfers: new TenantTransfers(payjpConfig), statements: new Statements(payjpConfig), terms: new Terms(payjpConfig), balances: new Balances(payjpConfig), three_d_secure_requests: new ThreeDSecureRequests(payjpConfig), }; -} +}; export = Payjp; diff --git a/src/plan.ts b/src/plan.ts index 47e3ebe..ee38870 100644 --- a/src/plan.ts +++ b/src/plan.ts @@ -1,33 +1,31 @@ -import Resource from './resource'; - -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Plans extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'plans'; + this.resource = "plans"; } list(query: I.ListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } create(query: I.PlanCreationOptions): Promise { - return this.request('POST', this.resource, query); + return this.request("POST", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } update(id: string, query: I.PlanUpdateOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}`, query); + return this.request("POST", `${this.resource}/${id}`, query); } delete(id: string): Promise { - return this.request('DELETE', `${this.resource}/${id}`); + return this.request("DELETE", `${this.resource}/${id}`); } - } diff --git a/src/resource.ts b/src/resource.ts index f7b3f9f..1a0d245 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -1,14 +1,13 @@ /// -import * as superagent from 'superagent'; -import * as I from './index'; +import type * as I from "./index"; interface Config { - apikey: string, - config: I.PayjpOptions, + apikey: string; + config: I.PayjpOptions; } export default class Resource { - payjp: Config + payjp: Config; constructor(payjp: Config) { this.payjp = payjp; @@ -23,50 +22,132 @@ export default class Resource { } private buildHeader(method: string): object { - const encodedKey = Buffer.from(`${this.payjp.apikey}:`).toString('base64'); + const encodedKey = Buffer.from(`${this.payjp.apikey}:`).toString("base64"); const headers = { - Accept: 'application/json', - Authorization: `Basic ${encodedKey}` + Accept: "application/json", + Authorization: `Basic ${encodedKey}`, }; - if (method === 'POST') { - headers['Content-Type'] = 'application/x-www-form-urlencoded'; + if (method === "POST" || method === "PUT") { + headers["Content-Type"] = "application/x-www-form-urlencoded"; } return headers; } private getCurrentDelay(retryCount: number, initialDelay: number, maxDelay: number): number { - const delay = Math.min(initialDelay * 2 ** retryCount, maxDelay) - return Math.ceil(delay / 2 * (1 + Math.random())) + const delay = Math.min(initialDelay * 2 ** retryCount, maxDelay); + return Math.ceil((delay / 2) * (1 + Math.random())); } - protected request(method: string, endpoint: string, query: object = {}, headers: object = {}): Promise { - const url = `${this.payjp.config.apibase}/${endpoint}`; + protected request( + method: string, + endpoint: string, + query: object = {}, + headers: object = {}, + ): Promise { const header: object = Object.assign(this.buildHeader(method), headers); - const doRequest = (): superagent.SuperAgentRequest => { - let request: superagent.SuperAgentRequest = superagent(method, url).set(header); - if (method === 'GET' || method === 'DELETE') { - request = request.query(query); - } else { // (method === 'POST' || method === 'PUT') - request = request.send(query); + const doRequest = async (): Promise => { + let url = `${this.payjp.config.apibase}/${endpoint}`; + const fetchOptions: RequestInit = { + method, + headers: header as HeadersInit, + }; + + // Set query parameters or request body + if (method === "GET" || method === "DELETE") { + // For GET and DELETE, add query parameters to URL + const params = new URLSearchParams(query as Record); + const queryString = params.toString(); + if (queryString) { + url = `${url}?${queryString}`; + } + } else { + // For POST and PUT, send as request body + const body = new URLSearchParams(query as Record); + fetchOptions.body = body.toString(); } + + // Set timeout if (this.payjp.config.timeout > 0) { - request = request.timeout(this.payjp.config.timeout); + const controller = new AbortController(); + fetchOptions.signal = controller.signal; + setTimeout(() => controller.abort(), this.payjp.config.timeout); } - return request - } - let retryCount = 0; - const retry = (resolve: (res: superagent.Response) => void, reject: (reason: any) => void) => doRequest().then(resolve).catch((res: superagent.Response) => { - if (res.status === 429 && retryCount < this.payjp.config.maxRetry) { - const delayWithJitter = this.getCurrentDelay(retryCount, this.payjp.config.retryInitialDelay, this.payjp.config.retryMaxDelay) - retryCount++; - setTimeout(() => retry(resolve, reject), delayWithJitter); - } else { - return reject(res); + try { + const response = await fetch(url, fetchOptions); + + // fetch doesn't reject on HTTP error status, so check manually + if (!response.ok) { + // Parse and return error response + const errorBody = await response.json().catch(() => ({})); + const error = new Error(`HTTP Error ${response.status}`) as any; + error.status = response.status; + error.body = errorBody; + error.message = errorBody.message || `HTTP Error ${response.status}`; + // Set response.body for compatibility with superagent + error.response = { body: errorBody, status: response.status }; + throw error; + } + + return response; + } catch (error: any) { + // Convert timeout error message + if (error.name === "AbortError" || error.name === "TimeoutError") { + const timeoutError = new Error( + `Timeout of ${this.payjp.config.timeout}ms exceeded`, + ) as any; + timeoutError.name = "TimeoutError"; + timeoutError.code = "ETIMEDOUT"; + timeoutError.timeout = this.payjp.config.timeout; + throw timeoutError; + } + // Convert network error message + if (error.cause) { + if (error.cause.code === "ECONNRESET") { + const networkError = new Error("socket hang up") as any; + networkError.code = "ECONNRESET"; + throw networkError; + } + } + // Convert 'fetch failed' error to 'socket hang up' (when connection is terminated) + if (error.message?.includes("fetch failed")) { + const networkError = new Error("socket hang up") as any; + networkError.code = "ECONNRESET"; + throw networkError; + } + throw error; } - }); - return new Promise(retry).then(res => res.body); + }; + + let retryCount = 0; + const retry = (resolve: (body: any) => void, reject: (reason: any) => void) => + doRequest() + .then(async (res: Response) => { + // Try to parse as JSON. If it fails, return empty object + try { + const body = await res.json(); + resolve(body); + } catch (_e) { + // For non-JSON responses (HTML, etc.), return empty object + resolve({} as any); + } + }) + .catch((error: any) => { + // Retry for 429 (Too Many Requests) + if (error.status === 429 && retryCount < this.payjp.config.maxRetry) { + const delayWithJitter = this.getCurrentDelay( + retryCount, + this.payjp.config.retryInitialDelay, + this.payjp.config.retryMaxDelay, + ); + retryCount++; + setTimeout(() => retry(resolve, reject), delayWithJitter); + } else { + return reject(error); + } + }); + return new Promise(retry); } } diff --git a/src/statement.ts b/src/statement.ts index a844b10..d9d26ca 100644 --- a/src/statement.ts +++ b/src/statement.ts @@ -1,23 +1,23 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Statements extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'statements'; + this.resource = "statements"; } list(query: I.StatementListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } statementUrls(id: string, query: I.StatementUrlOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/statement_urls`, query); + return this.request("POST", `${this.resource}/${id}/statement_urls`, query); } } diff --git a/src/subscription.ts b/src/subscription.ts index 14f93ba..4a7bc4a 100644 --- a/src/subscription.ts +++ b/src/subscription.ts @@ -1,44 +1,43 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Subscriptions extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'subscriptions'; + this.resource = "subscriptions"; } list(query: I.SubscriptionListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } create(query: I.SubscriptionCreationOptions): Promise { - return this.request('POST', this.resource, query); + return this.request("POST", this.resource, query); } update(id: string, query: I.SubscriptionUpdateOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}`, query); + return this.request("POST", `${this.resource}/${id}`, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } pause(id: string): Promise { - return this.request('POST', `${this.resource}/${id}/pause`); + return this.request("POST", `${this.resource}/${id}/pause`); } resume(id: string, query: I.SubscriptionResumeOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/resume`, query); + return this.request("POST", `${this.resource}/${id}/resume`, query); } cancel(id: string): Promise { - return this.request('POST', `${this.resource}/${id}/cancel`); + return this.request("POST", `${this.resource}/${id}/cancel`); } delete(id: string, query: I.SubscriptionDeleteOptions = {}): Promise { - return this.request('DELETE', `${this.resource}/${id}`, query); + return this.request("DELETE", `${this.resource}/${id}`, query); } - } diff --git a/src/tenantTransfers.ts b/src/tenantTransfers.ts index b1caee6..81d96fd 100644 --- a/src/tenantTransfers.ts +++ b/src/tenantTransfers.ts @@ -1,27 +1,27 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class TenantTransfers extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'tenant_transfers'; + this.resource = "tenant_transfers"; } list(query: I.TenantTransferListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } charges(id: string, query: I.TransferChargeListOptions = {}): Promise> { - return this.request('GET', `${this.resource}/${id}/charges`, query); + return this.request("GET", `${this.resource}/${id}/charges`, query); } statementUrls(id: string, query: I.StatementUrlOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}/statement_urls`, query); + return this.request("POST", `${this.resource}/${id}/statement_urls`, query); } } diff --git a/src/tenants.ts b/src/tenants.ts index d842e43..71f9ac1 100644 --- a/src/tenants.ts +++ b/src/tenants.ts @@ -1,36 +1,35 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Tenants extends Resource { - resource: string; constructor(payjp) { super(payjp); - this.resource = 'tenants'; + this.resource = "tenants"; } list(query: I.ListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } create(query: I.TenantCreationOptions): Promise { - return this.request('POST', this.resource, query); + return this.request("POST", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } update(id: string, query: I.TenantUpdateOptions = {}): Promise { - return this.request('POST', `${this.resource}/${id}`, query); + return this.request("POST", `${this.resource}/${id}`, query); } delete(id: string): Promise { - return this.request('DELETE', `${this.resource}/${id}`); + return this.request("DELETE", `${this.resource}/${id}`); } applicationUrls(id: string): Promise { - return this.request('POST', `${this.resource}/${id}/application_urls`); + return this.request("POST", `${this.resource}/${id}/application_urls`); } } diff --git a/src/term.ts b/src/term.ts index 265b553..7935be8 100644 --- a/src/term.ts +++ b/src/term.ts @@ -1,19 +1,19 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Terms extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'terms'; + this.resource = "terms"; } list(query: I.TermListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } } diff --git a/src/threeDSecureRequest.ts b/src/threeDSecureRequest.ts index c745286..5dc7a39 100644 --- a/src/threeDSecureRequest.ts +++ b/src/threeDSecureRequest.ts @@ -1,24 +1,23 @@ -import Resource from './resource'; -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class ThreeDSecureRequests extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'three_d_secure_requests'; + this.resource = "three_d_secure_requests"; } list(query: I.ThreeDSecureRequestListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } create(query: I.ThreeDSecureRequestCreationOptions): Promise { - return this.request('POST', this.resource, query); + return this.request("POST", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } - } diff --git a/src/token.ts b/src/token.ts index 6cd1f52..e6858d4 100644 --- a/src/token.ts +++ b/src/token.ts @@ -1,25 +1,23 @@ -import Resource from './resource'; - -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Tokens extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'tokens'; + this.resource = "tokens"; } create(query: object = {}, headers: object = {}): Promise { - return this.request('POST', this.resource, query, headers); + return this.request("POST", this.resource, query, headers); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } tds_finish(id: string): Promise { - return this.request('POST', `${this.resource}/${id}/tds_finish`); + return this.request("POST", `${this.resource}/${id}/tds_finish`); } - } diff --git a/src/transfer.ts b/src/transfer.ts index 210c983..e40c5b6 100644 --- a/src/transfer.ts +++ b/src/transfer.ts @@ -1,25 +1,23 @@ -import Resource from './resource'; - -import * as I from './index'; +import type * as I from "./index"; +import Resource from "./resource"; export default class Transfers extends Resource { resource: string; constructor(payjp) { super(payjp); - this.resource = 'transfers'; + this.resource = "transfers"; } list(query: I.TransferListOptions = {}): Promise> { - return this.request('GET', this.resource, query); + return this.request("GET", this.resource, query); } retrieve(id: string): Promise { - return this.request('GET', `${this.resource}/${id}`); + return this.request("GET", `${this.resource}/${id}`); } charges(id: string, query: I.TransferChargeListOptions = {}): Promise> { - return this.request('GET', `${this.resource}/${id}/charges`, query); + return this.request("GET", `${this.resource}/${id}/charges`, query); } - } diff --git a/test/account.spec.js b/test/account.spec.js index dade9df..2f4f3bf 100644 --- a/test/account.spec.js +++ b/test/account.spec.js @@ -1,16 +1,16 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.accounts.request = (...args) => Promise.resolve(args); -describe('Accounts Resource', () => { - describe('retrieve', () => { - it('Sends the correct request', () => { +describe("Accounts Resource", () => { + describe("retrieve", () => { + it("Sends the correct request", () => { return payjp.accounts.retrieve().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'accounts'); + assert(_method === "GET"); + assert(_endpoint === "accounts"); }); }); }); diff --git a/test/balance.spec.js b/test/balance.spec.js index 753c490..7c20c35 100644 --- a/test/balance.spec.js +++ b/test/balance.spec.js @@ -1,38 +1,37 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.balances.request = (...args) => Promise.resolve(args); -describe('Balance Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { - const query = {limit: 1}; +describe("Balance Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { + const query = { limit: 1 }; return payjp.balances.list(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'balances'); + assert(_method === "GET"); + assert(_endpoint === "balances"); assert.deepStrictEqual(_query, query); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.balances.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'balances/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.balances.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "balances/id123"); }); }); }); - describe('statementUrls', () => { - it('Sends the correct request', () => { - const query = {platformer: false}; - return payjp.balances.statementUrls('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'balances/id123/statement_urls'); + describe("statementUrls", () => { + it("Sends the correct request", () => { + const query = { platformer: false }; + return payjp.balances.statementUrls("id123", query).then(([_method, _endpoint, _query]) => { + assert(_method === "POST"); + assert(_endpoint === "balances/id123/statement_urls"); assert.deepStrictEqual(_query, query); }); }); diff --git a/test/card.spec.js b/test/card.spec.js index 94f2530..c99b2e0 100644 --- a/test/card.spec.js +++ b/test/card.spec.js @@ -1,54 +1,53 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.customers.cards.request = (...args) => Promise.resolve(args); -describe('Cards Resource', () => { - describe('create', () => { - it('Sends the correct request', () => { - return payjp.customers.cards.create('cus_id123', {}).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'customers/cus_id123/cards'); +describe("Cards Resource", () => { + describe("create", () => { + it("Sends the correct request", () => { + return payjp.customers.cards.create("cus_id123", {}).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "customers/cus_id123/cards"); }); }); }); - describe('list', () => { - it('Sends the correct request', () => { - return payjp.customers.cards.list('cus_id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'customers/cus_id123/cards'); + describe("list", () => { + it("Sends the correct request", () => { + return payjp.customers.cards.list("cus_id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "customers/cus_id123/cards"); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.customers.cards.retrieve('cus_id123', 'id456').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'customers/cus_id123/cards/id456'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.customers.cards.retrieve("cus_id123", "id456").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "customers/cus_id123/cards/id456"); }); }); }); - describe('update', () => { - it('Sends the correct request', () => { - return payjp.customers.cards.update('cus_id123', 'id456', {}).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'customers/cus_id123/cards/id456'); + describe("update", () => { + it("Sends the correct request", () => { + return payjp.customers.cards.update("cus_id123", "id456", {}).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "customers/cus_id123/cards/id456"); }); }); }); - describe('delete', () => { - it('Sends the correct request', () => { - return payjp.customers.cards.delete('cus_id123', 'id456').then(([_method, _endpoint]) => { - assert(_method === 'DELETE'); - assert(_endpoint === 'customers/cus_id123/cards/id456'); + describe("delete", () => { + it("Sends the correct request", () => { + return payjp.customers.cards.delete("cus_id123", "id456").then(([_method, _endpoint]) => { + assert(_method === "DELETE"); + assert(_endpoint === "customers/cus_id123/cards/id456"); }); }); }); - }); diff --git a/test/charge.spec.js b/test/charge.spec.js index c9da35f..732662a 100644 --- a/test/charge.spec.js +++ b/test/charge.spec.js @@ -1,77 +1,76 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.charges.request = (...args) => Promise.resolve(args); -describe('Charges Resource', () => { - describe('list', () => { - it('Sends the correct request', () => { +describe("Charges Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { return payjp.charges.list().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'charges'); + assert(_method === "GET"); + assert(_endpoint === "charges"); }); }); }); - describe('create', () => { - it('Sends the correct request', () => { + describe("create", () => { + it("Sends the correct request", () => { const query = { amount: 1000, - currency: 'jpy', - card: 'tok_test' + currency: "jpy", + card: "tok_test", }; return payjp.charges.create(query).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'charges'); + assert(_method === "POST"); + assert(_endpoint === "charges"); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.charges.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'charges/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.charges.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "charges/id123"); }); }); }); - describe('update', () => { - it('Sends the correct request', () => { - return payjp.charges.update('id123', {}).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'charges/id123'); + describe("update", () => { + it("Sends the correct request", () => { + return payjp.charges.update("id123", {}).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "charges/id123"); }); }); }); - describe('capture', () => { - it('Sends the correct request', () => { - return payjp.charges.capture('id123', {}).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'charges/id123/capture'); + describe("capture", () => { + it("Sends the correct request", () => { + return payjp.charges.capture("id123", {}).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "charges/id123/capture"); }); }); }); - describe('refund', () => { - it('Sends the correct request', () => { - return payjp.charges.refund('id123', {}).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'charges/id123/refund'); + describe("refund", () => { + it("Sends the correct request", () => { + return payjp.charges.refund("id123", {}).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "charges/id123/refund"); }); }); }); - describe('tds_finish', () => { - it('Sends the correct request', () => { - return payjp.charges.tds_finish('id123').then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'charges/id123/tds_finish'); + describe("tds_finish", () => { + it("Sends the correct request", () => { + return payjp.charges.tds_finish("id123").then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "charges/id123/tds_finish"); }); }); }); - }); diff --git a/test/config.js b/test/config.js index 480f2e8..44af36d 100644 --- a/test/config.js +++ b/test/config.js @@ -1,4 +1,4 @@ module.exports = { - apikey: 'sk_test', + apikey: "sk_test", config: {}, }; diff --git a/test/customer.spec.js b/test/customer.spec.js index 99d0414..faecb60 100644 --- a/test/customer.spec.js +++ b/test/customer.spec.js @@ -1,78 +1,80 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.customers.request = (...args) => Promise.resolve(args); payjp.customers.subscriptions.request = (...args) => Promise.resolve(args); -describe('Customer Resource', () => { - describe('list', () => { - it('Sends the correct request', () => { +describe("Customer Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { return payjp.customers.list().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'customers'); + assert(_method === "GET"); + assert(_endpoint === "customers"); }); }); }); - describe('create', () => { - it('Sends the correct request', () => { + describe("create", () => { + it("Sends the correct request", () => { const query = { - email: 'payjp-node@example.com' + email: "payjp-node@example.com", }; return payjp.customers.create(query).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'customers'); + assert(_method === "POST"); + assert(_endpoint === "customers"); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.customers.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'customers/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.customers.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "customers/id123"); }); }); }); - describe('update', () => { - it('Sends the correct request', () => { + describe("update", () => { + it("Sends the correct request", () => { const query = { - email: 'payjp-node-updated@example.com' + email: "payjp-node-updated@example.com", }; - return payjp.customers.update('id123', query).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'customers/id123'); + return payjp.customers.update("id123", query).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "customers/id123"); }); }); }); - describe('delete', () => { - it('Sends the correct request', () => { - return payjp.customers.delete('id123').then(([_method, _endpoint]) => { - assert(_method === 'DELETE'); - assert(_endpoint === 'customers/id123'); + describe("delete", () => { + it("Sends the correct request", () => { + return payjp.customers.delete("id123").then(([_method, _endpoint]) => { + assert(_method === "DELETE"); + assert(_endpoint === "customers/id123"); }); }); }); - describe('customer\'s subscription list', () => { - it('Sends the correct request', () => { - return payjp.customers.subscriptions.list('cus_id456').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'customers/cus_id456/subscriptions'); + describe("customer's subscription list", () => { + it("Sends the correct request", () => { + return payjp.customers.subscriptions.list("cus_id456").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "customers/cus_id456/subscriptions"); }); }); }); - describe('customer\'s subscription retrieve', () => { - it('Sends the correct request', () => { - return payjp.customers.subscriptions.retrieve('cus_id456', 'id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'customers/cus_id456/subscriptions/id123'); - }); + describe("customer's subscription retrieve", () => { + it("Sends the correct request", () => { + return payjp.customers.subscriptions + .retrieve("cus_id456", "id123") + .then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "customers/cus_id456/subscriptions/id123"); + }); }); }); }); diff --git a/test/event.spec.js b/test/event.spec.js index 475cdb5..02986f5 100644 --- a/test/event.spec.js +++ b/test/event.spec.js @@ -1,27 +1,25 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.events.request = (...args) => Promise.resolve(args); -describe('Events Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { +describe("Events Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { return payjp.events.list().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'events'); + assert(_method === "GET"); + assert(_endpoint === "events"); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.events.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'events/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.events.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "events/id123"); }); }); }); - }); diff --git a/test/index.spec.js b/test/index.spec.js index 1d6aa1a..ce63ff0 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,17 +1,20 @@ -const assert = require('assert'); -const Payjp = require('../built'); +const assert = require("node:assert"); +const Payjp = require("../built"); -describe('Payjp', () => { - it('can construct myself', () => { - const payjp = Payjp('sk_test'); - assert(payjp.apikey === 'sk_test'); - assert(typeof payjp.charges.create === 'function'); +describe("Payjp", () => { + it("can construct myself", () => { + const payjp = Payjp("sk_test"); + assert(payjp.apikey === "sk_test"); + assert(typeof payjp.charges.create === "function"); - const payjpWithConfig = Payjp('sk_test', {apibase: 'http://localhost:8080/', timeout: 2000}); - assert(payjpWithConfig.config.apibase === 'http://localhost:8080/'); + const payjpWithConfig = Payjp("sk_test", { + apibase: "http://localhost:8080/", + timeout: 2000, + }); + assert(payjpWithConfig.config.apibase === "http://localhost:8080/"); assert(payjpWithConfig.config.timeout === 2000); }); - it('cannot construct myself without apikey', () => { + it("cannot construct myself without apikey", () => { assert.throws(() => { Payjp(); }, /^Error: Please set apikey.$/); @@ -19,12 +22,12 @@ describe('Payjp', () => { Payjp(null); }, /^Error: Please set apikey.$/); assert.throws(() => { - Payjp(''); + Payjp(""); }, /^Error: Please set apikey.$/); }); - it('cannot construct myself with public apikey', () => { + it("cannot construct myself with public apikey", () => { assert.throws(() => { - Payjp('pk_test'); + Payjp("pk_test"); }, /^Error: You cannot use the public apikey in this SDK.$/); }); }); diff --git a/test/plan.spec.js b/test/plan.spec.js index aa061b4..02092b9 100644 --- a/test/plan.spec.js +++ b/test/plan.spec.js @@ -1,64 +1,62 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.plans.request = (...args) => Promise.resolve(args); -describe('Plans Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { +describe("Plans Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { return payjp.plans.list().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'plans'); + assert(_method === "GET"); + assert(_endpoint === "plans"); }); }); }); - describe('create', () => { - it('Sends the correct request', () => { + describe("create", () => { + it("Sends the correct request", () => { const query = { amount: 1000, - currency: 'jpy', - interval: 'month', - name: 'premium plan' + currency: "jpy", + interval: "month", + name: "premium plan", }; return payjp.plans.create(query).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'plans'); + assert(_method === "POST"); + assert(_endpoint === "plans"); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.plans.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'plans/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.plans.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "plans/id123"); }); }); }); - describe('update', () => { - it('Sends the correct request', () => { + describe("update", () => { + it("Sends the correct request", () => { const query = { - name: 'super hyper premium plan' + name: "super hyper premium plan", }; - return payjp.plans.update('id123', query).then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'plans/id123'); + return payjp.plans.update("id123", query).then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "plans/id123"); }); }); }); - describe('delete', () => { - it('Sends the correct request', () => { - return payjp.plans.delete('id123').then(([_method, _endpoint]) => { - assert(_method === 'DELETE'); - assert(_endpoint === 'plans/id123'); + describe("delete", () => { + it("Sends the correct request", () => { + return payjp.plans.delete("id123").then(([_method, _endpoint]) => { + assert(_method === "DELETE"); + assert(_endpoint === "plans/id123"); }); }); }); - }); diff --git a/test/requestor.spec.js b/test/requestor.spec.js index de3a7a2..8233a56 100644 --- a/test/requestor.spec.js +++ b/test/requestor.spec.js @@ -1,172 +1,192 @@ /* global Buffer */ -const assert = require('assert'); -const http = require('http'); -const Payjp = require('../built'); +const assert = require("node:assert"); +const http = require("node:http"); +const Payjp = require("../built"); -function createTestServer (statusCodes) { - return http.createServer((msg, res) => { +function createTestServer(statusCodes) { + return http.createServer((_msg, res) => { const status = statusCodes.next().value[1]; - let obj = {} + const obj = {}; if (status === 200) { - obj['id'] = 'ch_success' + obj.id = "ch_success"; } - const body = JSON.stringify(obj) + const body = JSON.stringify(obj); res.writeHead(status, { - 'Content-Length': Buffer.byteLength(body), - 'Content-Type': 'application/json', + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", }); res.end(body); - }) + }); } -describe('Retry delay', () => { - const r = new Payjp('key', {}).charges - it('multiplies by retryCount', () => { - let got = r['getCurrentDelay'](0, 1000, 2000) - assert.ok(500 <= got) - assert.ok(got <= 1000) +describe("Retry delay", () => { + const r = new Payjp("key", {}).charges; + it("multiplies by retryCount", () => { + let got = r.getCurrentDelay(0, 1000, 2000); + assert.ok(500 <= got); + assert.ok(got <= 1000); - got = r['getCurrentDelay'](2, 1000, 2000) - assert.ok(1000 <= got) - assert.ok(got <= 2000) - }) - it('limited by retryMaxDelay', () => { + got = r.getCurrentDelay(2, 1000, 2000); + assert.ok(1000 <= got); + assert.ok(got <= 2000); + }); + it("limited by retryMaxDelay", () => { // Calcurated range is 500-1000 but the larger end is limited to 600 - let got = r['getCurrentDelay'](0, 1000, 600) - assert.ok(300 <= got) - assert.ok(got <= 600) - }) -}) -describe('HTTP Requestor', () => { - const apikey = 'apikey'; - const encodedKey = Buffer.from(apikey + ':').toString('base64'); - describe('buildHeader', () => { + const got = r.getCurrentDelay(0, 1000, 600); + assert.ok(300 <= got); + assert.ok(got <= 600); + }); +}); +describe("HTTP Requestor", () => { + const apikey = "apikey"; + const encodedKey = Buffer.from(`${apikey}:`).toString("base64"); + describe("buildHeader", () => { const payjp = new Payjp(apikey, {}); - it('GET', () => { - let header = payjp.charges.buildHeader('GET'); - assert(header['Accept'] === 'application/json'); - assert(header['Authorization'] === `Basic ${encodedKey}`); - assert(header['Content-Type'] === undefined); + it("GET", () => { + const header = payjp.charges.buildHeader("GET"); + assert(header.Accept === "application/json"); + assert(header.Authorization === `Basic ${encodedKey}`); + assert(header["Content-Type"] === undefined); + }); + + it("POST", () => { + const header = payjp.charges.buildHeader("POST"); + assert(header.Accept === "application/json"); + assert(header.Authorization === `Basic ${encodedKey}`); + assert(header["Content-Type"] === "application/x-www-form-urlencoded"); }); - it('POST', () => { - let header = payjp.charges.buildHeader('POST'); - assert(header['Accept'] === 'application/json'); - assert(header['Authorization'] === `Basic ${encodedKey}`); - assert(header['Content-Type'] === 'application/x-www-form-urlencoded'); + it("DELETE", () => { + const header = payjp.charges.buildHeader("DELETE"); + assert(header.Accept === "application/json"); + assert(header.Authorization === `Basic ${encodedKey}`); + assert(header["Content-Type"] === undefined); }); - it('DELETE', () => { - let header = payjp.charges.buildHeader('DELETE'); - assert(header['Accept'] === 'application/json'); - assert(header['Authorization'] === `Basic ${encodedKey}`); - assert(header['Content-Type'] === undefined); + it("PUT", () => { + const header = payjp.charges.buildHeader("PUT"); + assert(header.Accept === "application/json"); + assert(header.Authorization === `Basic ${encodedKey}`); + assert(header["Content-Type"] === "application/x-www-form-urlencoded"); }); }); - describe('request', () => { - it('return 200 by POST with checking request headers', (done) => { - const dummy = {amount: 50}; + describe("request", () => { + it("return 200 by POST with checking request headers", (done) => { + const dummy = { amount: 50 }; const status = 200; - const server = http.createServer((msg, res) => { - server.close(); - assert(!!msg.headers.host); - assert.strictEqual(msg.headers['accept-encoding'], 'gzip, deflate'); - assert.strictEqual(msg.headers['user-agent'].indexOf('node-superagent/'), 0); - assert.strictEqual(msg.headers['content-type'], 'application/x-www-form-urlencoded'); - assert(parseInt(msg.headers['content-length'], 10) > 0); - assert.strictEqual(msg.headers.accept, 'application/json'); - assert.strictEqual(msg.headers.authorization, 'Basic ' + encodedKey); - assert.strictEqual(msg.headers.connection, 'close'); - assert.strictEqual(msg.method, 'POST'); - assert.strictEqual(msg.url, '/v1/charges'); - let rawData = ''; - msg.on('data', (chunk) => { rawData += chunk; }); - msg.on('end', () => { - assert.strictEqual(rawData, 'amount=50'); - const body = JSON.stringify(dummy); - res.writeHead(status, { - 'Content-Length': Buffer.byteLength(body), - 'Content-Type': 'application/json', + const server = http + .createServer((msg, res) => { + server.close(); + assert(!!msg.headers.host); + // fetch API uses undici which may have different default headers + // assert.strictEqual(msg.headers['accept-encoding'], 'gzip, deflate'); + assert(!!msg.headers["user-agent"]); // user-agent exists (not checking specific value) + assert.strictEqual(msg.headers["content-type"], "application/x-www-form-urlencoded"); + assert(parseInt(msg.headers["content-length"], 10) > 0); + assert.strictEqual(msg.headers.accept, "application/json"); + assert.strictEqual(msg.headers.authorization, `Basic ${encodedKey}`); + // assert.strictEqual(msg.headers.connection, 'close'); + assert.strictEqual(msg.method, "POST"); + assert.strictEqual(msg.url, "/v1/charges"); + let rawData = ""; + msg.on("data", (chunk) => { + rawData += chunk; + }); + msg.on("end", () => { + assert.strictEqual(rawData, "amount=50"); + const body = JSON.stringify(dummy); + res.writeHead(status, { + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", + }); + res.end(body); + }); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.charges.create(dummy).then((r) => { + assert.deepStrictEqual(r, dummy); + done(); }); - res.end(body); - }); - }).listen(() => { - const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase}); - payjp.charges.create(dummy).then((r) => { - assert.deepStrictEqual(r, dummy); - done(); }); - }); }); - it('return 400 by GET', (done) => { - const dummy = {object: 'payjp'}; + it("return 400 by GET", (done) => { + const dummy = { object: "payjp" }; const status = 400; - const server = http.createServer((msg, res) => { - server.close(); - assert.strictEqual(msg.method, 'GET'); - assert.strictEqual(msg.url, '/v1/charges?object=payjp'); - const body = JSON.stringify({error: { - message: 'test', - status, - type: 'client_error', - }}); - res.writeHead(status, { - 'Content-Length': Buffer.byteLength(body), - 'Content-Type': 'application/json', - }); - res.end(body); - }).listen(() => { - const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase}); - payjp.charges.list(dummy).catch((e) => { - assert.strictEqual(e.status, status); - assert.strictEqual(e.response.body.error.message, 'test'); - assert.strictEqual(e.response.body.error.status, status); - assert.strictEqual(e.response.body.error.type, 'client_error'); - done(); + const server = http + .createServer((msg, res) => { + server.close(); + assert.strictEqual(msg.method, "GET"); + assert.strictEqual(msg.url, "/v1/charges?object=payjp"); + const body = JSON.stringify({ + error: { + message: "test", + status, + type: "client_error", + }, + }); + res.writeHead(status, { + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", + }); + res.end(body); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.charges.list(dummy).catch((e) => { + assert.strictEqual(e.status, status); + assert.strictEqual(e.response.body.error.message, "test"); + assert.strictEqual(e.response.body.error.status, status); + assert.strictEqual(e.response.body.error.type, "client_error"); + done(); + }); }); - }); }); - it('return 200 by DELETE, but not json', (done) => { + it("return 200 by DELETE, but not json", (done) => { const status = 200; - const server = http.createServer((msg, res) => { - server.close(); - assert.strictEqual(msg.method, 'DELETE'); - assert.strictEqual(msg.url, '/v1/plans/hoge'); - res.writeHead(status, {'Content-Type': 'text/plain'}); - res.end(''); - }).listen(() => { - const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase}); - payjp.plans.delete('hoge').then((v) => { - assert.deepStrictEqual(v, {}); - done(); + const server = http + .createServer((msg, res) => { + server.close(); + assert.strictEqual(msg.method, "DELETE"); + assert.strictEqual(msg.url, "/v1/plans/hoge"); + res.writeHead(status, { "Content-Type": "text/plain" }); + res.end(""); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.plans.delete("hoge").then((v) => { + assert.deepStrictEqual(v, {}); + done(); + }); }); - }); }); - it('return Network Error: request ok, but not response', (done) => { - const server = http.createServer((msg, _) => { - server.close(); - return msg.socket.destroy(); - }).listen(() => { - const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase}); - payjp.charges.list().catch((r) => { - assert.strictEqual(r.status, undefined); - assert.strictEqual(r.response, undefined); - assert.strictEqual(r.message, 'socket hang up'); - done(); + it("return Network Error: request ok, but not response", (done) => { + const server = http + .createServer((msg, _) => { + server.close(); + return msg.socket.destroy(); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.charges.list().catch((r) => { + assert.strictEqual(r.status, undefined); + assert.strictEqual(r.response, undefined); + assert.strictEqual(r.message, "socket hang up"); + done(); + }); }); - }); }); - it('return Network Error: url not exists', (done) => { + it("return Network Error: url not exists", (done) => { const server = http.createServer(); server.listen(() => { const apibase = `http://localhost:${server.address().port}/v1`; server.close(); - const payjp = new Payjp(apikey, {apibase}); + const payjp = new Payjp(apikey, { apibase }); payjp.charges.list().catch((r) => { assert.strictEqual(r.status, undefined); assert.strictEqual(r.response, undefined); @@ -175,11 +195,11 @@ describe('HTTP Requestor', () => { }); }); }); - it('return timeout Error', (done) => { + it("return timeout Error", (done) => { const server = http.createServer().listen(() => { const apibase = `http://localhost:${server.address().port}/v1`; const timeout = 50; - const payjp = new Payjp(apikey, {apibase, timeout}); + const payjp = new Payjp(apikey, { apibase, timeout }); payjp.charges.list().catch((r) => { server.close(); assert.strictEqual(r.status, undefined); @@ -190,41 +210,215 @@ describe('HTTP Requestor', () => { }); }); }); - it('retries 429 error and success', (done) => { - const statusCodes = [429, 429, 429, 200].entries() + it("retries 429 error and success", (done) => { + const statusCodes = [429, 429, 429, 200].entries(); const server = createTestServer(statusCodes).listen(() => { const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase, maxRetry: 3, retryInitialDelay: 10}); - payjp.charges.create().then((charge) => { - server.close(); - assert.strictEqual(charge.id, 'ch_success'); - done(); - }).catch((e) => {server.close(); done(e)}); + const payjp = new Payjp(apikey, { + apibase, + maxRetry: 3, + retryInitialDelay: 10, + }); + payjp.charges + .create() + .then((charge) => { + server.close(); + assert.strictEqual(charge.id, "ch_success"); + done(); + }) + .catch((e) => { + server.close(); + done(e); + }); }); }); - it('returns 429 after max retry', (done) => { - const statusCodes = [429, 429, 429, 200].entries() + it("returns 429 after max retry", (done) => { + const statusCodes = [429, 429, 429, 200].entries(); const server = createTestServer(statusCodes).listen(() => { const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase, maxRetry: 2, retryInitialDelay: 10}); - payjp.charges.create().then((res) => {server.close(); done(res);}).catch((e) => { - server.close(); - assert.strictEqual(e.status, 429); - done(); + const payjp = new Payjp(apikey, { + apibase, + maxRetry: 2, + retryInitialDelay: 10, }); + payjp.charges + .create() + .then((res) => { + server.close(); + done(res); + }) + .catch((e) => { + server.close(); + assert.strictEqual(e.status, 429); + done(); + }); }); }); - it('stops retrying when error response that not 429 has received', (done) => { - const statusCodes = [429, 500, 429, 200].entries() + it("stops retrying when error response that not 429 has received", (done) => { + const statusCodes = [429, 500, 429, 200].entries(); const server = createTestServer(statusCodes).listen(() => { const apibase = `http://localhost:${server.address().port}/v1`; - const payjp = new Payjp(apikey, {apibase, maxRetry: 3, retryInitialDelay: 10}); - payjp.charges.create().then((e) => { server.close(); done(e)}).catch((e) => { - server.close(); - assert.strictEqual(e.status, 500); - done(); + const payjp = new Payjp(apikey, { + apibase, + maxRetry: 3, + retryInitialDelay: 10, }); + payjp.charges + .create() + .then((e) => { + server.close(); + done(e); + }) + .catch((e) => { + server.close(); + assert.strictEqual(e.status, 500); + done(); + }); }); }); + it("return 200 by PUT with request body", (done) => { + const dummy = { amount: 100 }; + const status = 200; + const server = http + .createServer((msg, res) => { + server.close(); + assert.strictEqual(msg.method, "PUT"); + assert.strictEqual(msg.url, "/v1/test_resource/test_id"); + assert.strictEqual(msg.headers["content-type"], "application/x-www-form-urlencoded"); + assert(parseInt(msg.headers["content-length"], 10) > 0); + let rawData = ""; + msg.on("data", (chunk) => { + rawData += chunk; + }); + msg.on("end", () => { + assert.strictEqual(rawData, "amount=100"); + const body = JSON.stringify(dummy); + res.writeHead(status, { + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", + }); + res.end(body); + }); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + // Test PUT method by directly calling protected request method + // Since there's no resource using PUT in the codebase, we test it directly + payjp.charges.request("PUT", "test_resource/test_id", dummy).then((v) => { + assert.deepStrictEqual(v, dummy); + done(); + }); + }); + }); + it("does not set timeout when timeout is 0", (done) => { + const status = 200; + let timeoutOccurred = false; + const server = http + .createServer((_msg, res) => { + // Wait longer than typical timeout to ensure no timeout occurs + setTimeout(() => { + if (!timeoutOccurred) { + const body = JSON.stringify({}); + res.writeHead(status, { + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", + }); + res.end(body); + server.close(); + } + }, 100); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const timeout = 0; + const payjp = new Payjp(apikey, { apibase, timeout }); + payjp.charges + .list() + .then(() => { + assert.strictEqual(timeoutOccurred, false); + done(); + }) + .catch((_e) => { + server.close(); + timeoutOccurred = true; + done(new Error("Should not timeout when timeout is 0")); + }); + }); + }); + it("GET request without query string when query is empty", (done) => { + const status = 200; + const server = http + .createServer((msg, res) => { + server.close(); + assert.strictEqual(msg.method, "GET"); + assert.strictEqual(msg.url, "/v1/charges"); + const body = JSON.stringify({}); + res.writeHead(status, { + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", + }); + res.end(body); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.charges.list({}).then(() => { + done(); + }); + }); + }); + it("return 400 with empty body when error response is not JSON", (done) => { + const status = 400; + const server = http + .createServer((_msg, res) => { + server.close(); + res.writeHead(status, { "Content-Type": "text/html" }); + res.end("Bad Request"); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.charges.list().catch((e) => { + assert.strictEqual(e.status, status); + assert.deepStrictEqual(e.body, {}); + assert.deepStrictEqual(e.response.body, {}); + done(); + }); + }); + }); + it("handles various HTTP error status codes (401, 404, 500)", async () => { + const testCases = [ + { status: 401, message: "Unauthorized" }, + { status: 404, message: "Not Found" }, + { status: 500, message: "Internal Server Error" }, + ]; + + for (const testCase of testCases) { + await new Promise((resolve) => { + const server = http + .createServer((_msg, res) => { + server.close(); + const body = JSON.stringify({ + error: { message: testCase.message, status: testCase.status }, + }); + res.writeHead(testCase.status, { + "Content-Length": Buffer.byteLength(body), + "Content-Type": "application/json", + }); + res.end(body); + }) + .listen(() => { + const apibase = `http://localhost:${server.address().port}/v1`; + const payjp = new Payjp(apikey, { apibase }); + payjp.charges.list().catch((e) => { + assert.strictEqual(e.status, testCase.status); + assert.strictEqual(e.response.body.error.message, testCase.message); + resolve(); + }); + }); + }); + } + }); }); }); diff --git a/test/statement.spec.js b/test/statement.spec.js index 689a8e9..5cff858 100644 --- a/test/statement.spec.js +++ b/test/statement.spec.js @@ -1,41 +1,39 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.statements.request = (...args) => Promise.resolve(args); -describe('Statement Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { - const query = {limit: 1}; +describe("Statement Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { + const query = { limit: 1 }; return payjp.statements.list(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'statements'); + assert(_method === "GET"); + assert(_endpoint === "statements"); assert.deepStrictEqual(_query, query); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.statements.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'statements/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.statements.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "statements/id123"); }); }); }); - describe('statementUrls', () => { - it('Sends the correct request', () => { - const query = {platformer: false}; - return payjp.statements.statementUrls('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'statements/id123/statement_urls'); + describe("statementUrls", () => { + it("Sends the correct request", () => { + const query = { platformer: false }; + return payjp.statements.statementUrls("id123", query).then(([_method, _endpoint, _query]) => { + assert(_method === "POST"); + assert(_endpoint === "statements/id123/statement_urls"); assert.deepStrictEqual(_query, query); }); }); }); - }); diff --git a/test/subscription.spec.js b/test/subscription.spec.js index b044a61..5eb8201 100644 --- a/test/subscription.spec.js +++ b/test/subscription.spec.js @@ -1,95 +1,93 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.subscriptions.request = (...args) => Promise.resolve(args); -describe('Subscription Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { +describe("Subscription Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { return payjp.subscriptions.list().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'subscriptions'); + assert(_method === "GET"); + assert(_endpoint === "subscriptions"); }); }); }); - describe('create', () => { - it('Sends the correct request', () => { + describe("create", () => { + it("Sends the correct request", () => { const query = { - customer: 'cus_id456', - plan: 'pln_id789' + customer: "cus_id456", + plan: "pln_id789", }; return payjp.subscriptions.create(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'subscriptions'); + assert(_method === "POST"); + assert(_endpoint === "subscriptions"); assert.deepStrictEqual(_query, query); }); }); }); - describe('update', () => { - it('Sends the correct request', () => { + describe("update", () => { + it("Sends the correct request", () => { const query = { - plan: 'pln_id789' + plan: "pln_id789", }; - return payjp.subscriptions.update('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'subscriptions/id123'); + return payjp.subscriptions.update("id123", query).then(([_method, _endpoint, _query]) => { + assert(_method === "POST"); + assert(_endpoint === "subscriptions/id123"); assert.deepStrictEqual(_query, query); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.subscriptions.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'subscriptions/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.subscriptions.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "subscriptions/id123"); }); }); }); - describe('pause', () => { - it('Sends the correct request', () => { - return payjp.subscriptions.pause('id123').then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'subscriptions/id123/pause'); + describe("pause", () => { + it("Sends the correct request", () => { + return payjp.subscriptions.pause("id123").then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "subscriptions/id123/pause"); }); }); }); - describe('resume', () => { - it('Sends the correct request', () => { - return payjp.subscriptions.resume('id123').then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'subscriptions/id123/resume'); + describe("resume", () => { + it("Sends the correct request", () => { + return payjp.subscriptions.resume("id123").then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "subscriptions/id123/resume"); }); }); }); - describe('cancel', () => { - it('Sends the correct request', () => { - return payjp.subscriptions.cancel('id123').then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'subscriptions/id123/cancel'); + describe("cancel", () => { + it("Sends the correct request", () => { + return payjp.subscriptions.cancel("id123").then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "subscriptions/id123/cancel"); }); }); }); - describe('delete', () => { - it('Sends the correct request', () => { + describe("delete", () => { + it("Sends the correct request", () => { const query = { - prorate: true + prorate: true, }; - return payjp.subscriptions.delete('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'DELETE'); - assert(_endpoint === 'subscriptions/id123'); + return payjp.subscriptions.delete("id123", query).then(([_method, _endpoint, _query]) => { + assert(_method === "DELETE"); + assert(_endpoint === "subscriptions/id123"); assert.deepStrictEqual(_query, query); }); }); }); - }); diff --git a/test/tenantTransfers.spec.js b/test/tenantTransfers.spec.js index d5d5d91..3425495 100644 --- a/test/tenantTransfers.spec.js +++ b/test/tenantTransfers.spec.js @@ -1,44 +1,44 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.tenant_transfers.request = (...args) => Promise.resolve(args); -describe('TenantTransfer Resource', () => { - - it('Sends the correct request on list', () => { - const query = {limit: 1}; +describe("TenantTransfer Resource", () => { + it("Sends the correct request on list", () => { + const query = { limit: 1 }; return payjp.tenant_transfers.list(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'tenant_transfers'); + assert(_method === "GET"); + assert(_endpoint === "tenant_transfers"); assert.deepStrictEqual(_query, query); }); }); - it('Sends the correct request on retrieve', () => { - return payjp.tenant_transfers.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'tenant_transfers/id123'); + it("Sends the correct request on retrieve", () => { + return payjp.tenant_transfers.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "tenant_transfers/id123"); }); }); - - it('Sends the correct request on charges', () => { - const query = {limit: 1}; - return payjp.tenant_transfers.charges('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'tenant_transfers/id123/charges'); + it("Sends the correct request on charges", () => { + const query = { limit: 1 }; + return payjp.tenant_transfers.charges("id123", query).then(([_method, _endpoint, _query]) => { + assert(_method === "GET"); + assert(_endpoint === "tenant_transfers/id123/charges"); assert.deepStrictEqual(_query, query); }); }); - it('Sends the correct request on statementUrls', () => { - const query = {platformer: true}; - return payjp.tenant_transfers.statementUrls('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'tenant_transfers/id123/statement_urls'); - assert.deepStrictEqual(_query, query); - }); + it("Sends the correct request on statementUrls", () => { + const query = { platformer: true }; + return payjp.tenant_transfers + .statementUrls("id123", query) + .then(([_method, _endpoint, _query]) => { + assert(_method === "POST"); + assert(_endpoint === "tenant_transfers/id123/statement_urls"); + assert.deepStrictEqual(_query, query); + }); }); }); diff --git a/test/tenants.spec.js b/test/tenants.spec.js index 3254b52..3d30f3e 100644 --- a/test/tenants.spec.js +++ b/test/tenants.spec.js @@ -1,57 +1,56 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.tenants.request = (...args) => Promise.resolve(args); -describe('Transfer Resource', () => { - it('Sends the correct request on list', () => { - const query = {limit: 1}; +describe("Transfer Resource", () => { + it("Sends the correct request on list", () => { + const query = { limit: 1 }; return payjp.tenants.list(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'tenants'); + assert(_method === "GET"); + assert(_endpoint === "tenants"); assert.deepStrictEqual(_query, query); }); }); - it('Sends the correct request on retrieve', () => { - return payjp.tenants.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'tenants/id123'); + it("Sends the correct request on retrieve", () => { + return payjp.tenants.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "tenants/id123"); }); }); - it('Sends the correct request on create', () => { - const query = {name: 'test', 'platform_fee_rate': '10.00'}; + it("Sends the correct request on create", () => { + const query = { name: "test", platform_fee_rate: "10.00" }; return payjp.tenants.create(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'tenants'); + assert(_method === "POST"); + assert(_endpoint === "tenants"); assert.deepStrictEqual(_query, query); }); }); - it('Sends the correct request on update', () => { - const query = {name: 'test', 'platform_fee_rate': '10.00'}; - return payjp.tenants.update('id123', query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'tenants/id123'); + it("Sends the correct request on update", () => { + const query = { name: "test", platform_fee_rate: "10.00" }; + return payjp.tenants.update("id123", query).then(([_method, _endpoint, _query]) => { + assert(_method === "POST"); + assert(_endpoint === "tenants/id123"); assert.deepStrictEqual(_query, query); }); }); - it('Sends the correct request on delete', () => { - return payjp.tenants.delete('id123').then(([_method, _endpoint]) => { - assert(_method === 'DELETE'); - assert(_endpoint === 'tenants/id123'); + it("Sends the correct request on delete", () => { + return payjp.tenants.delete("id123").then(([_method, _endpoint]) => { + assert(_method === "DELETE"); + assert(_endpoint === "tenants/id123"); }); }); - it('Sends the correct request on applicationUrls', () => { - return payjp.tenants.applicationUrls('id123').then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'tenants/id123/application_urls'); + it("Sends the correct request on applicationUrls", () => { + return payjp.tenants.applicationUrls("id123").then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "tenants/id123/application_urls"); }); }); - }); diff --git a/test/term.spec.js b/test/term.spec.js index 714043b..0ef3b7b 100644 --- a/test/term.spec.js +++ b/test/term.spec.js @@ -1,28 +1,27 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.terms.request = (...args) => Promise.resolve(args); -describe('Term Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { - const query = {limit: 1}; +describe("Term Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { + const query = { limit: 1 }; return payjp.terms.list(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'terms'); + assert(_method === "GET"); + assert(_endpoint === "terms"); assert.deepStrictEqual(_query, query); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.terms.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'terms/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.terms.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "terms/id123"); }); }); }); diff --git a/test/threeDSecureRequest.spec.js b/test/threeDSecureRequest.spec.js index 3c782bf..5f7be1f 100644 --- a/test/threeDSecureRequest.spec.js +++ b/test/threeDSecureRequest.spec.js @@ -1,42 +1,41 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.three_d_secure_requests.request = (...args) => Promise.resolve(args); -describe('ThreeDSecureRequest Resource', () => { - describe('list', () => { - it('Sends the correct request', () => { - const query = {limit: 1}; +describe("ThreeDSecureRequest Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { + const query = { limit: 1 }; return payjp.three_d_secure_requests.list(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'GET'); - assert(_endpoint === 'three_d_secure_requests'); + assert(_method === "GET"); + assert(_endpoint === "three_d_secure_requests"); assert.deepStrictEqual(_query, query); }); }); }); - describe('create', () => { - it('Sends the correct request', () => { + describe("create", () => { + it("Sends the correct request", () => { const query = { - resource_id: 'car_xxxxxxxxxxxxxxxxxxxxxxxxx' + resource_id: "car_xxxxxxxxxxxxxxxxxxxxxxxxx", }; return payjp.three_d_secure_requests.create(query).then(([_method, _endpoint, _query]) => { - assert(_method === 'POST'); - assert(_endpoint === 'three_d_secure_requests'); + assert(_method === "POST"); + assert(_endpoint === "three_d_secure_requests"); assert.deepStrictEqual(_query, query); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.three_d_secure_requests.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'three_d_secure_requests/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.three_d_secure_requests.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "three_d_secure_requests/id123"); }); }); }); - }); diff --git a/test/token.spec.js b/test/token.spec.js index 72a8d39..1c23235 100644 --- a/test/token.spec.js +++ b/test/token.spec.js @@ -1,40 +1,38 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.tokens.request = (...args) => Promise.resolve(args); -describe('Tokens Resource', () => { - - describe('create', () => { - it('Sends the correct request', () => { +describe("Tokens Resource", () => { + describe("create", () => { + it("Sends the correct request", () => { const query = {}; const headers = {}; return payjp.tokens.create(query, headers).then(([_method, _endpoint, _query, _headers]) => { - assert(_method === 'POST'); - assert(_endpoint === 'tokens'); + assert(_method === "POST"); + assert(_endpoint === "tokens"); assert.deepStrictEqual(_query, query); assert.deepStrictEqual(_headers, headers); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.tokens.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'tokens/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.tokens.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "tokens/id123"); }); }); }); - describe('tds_finish', () => { - it('Sends the correct request', () => { - return payjp.tokens.tds_finish('id123').then(([_method, _endpoint]) => { - assert(_method === 'POST'); - assert(_endpoint === 'tokens/id123/tds_finish'); + describe("tds_finish", () => { + it("Sends the correct request", () => { + return payjp.tokens.tds_finish("id123").then(([_method, _endpoint]) => { + assert(_method === "POST"); + assert(_endpoint === "tokens/id123/tds_finish"); }); }); }); - }); diff --git a/test/transfer.spec.js b/test/transfer.spec.js index aac8bcb..1734ba5 100644 --- a/test/transfer.spec.js +++ b/test/transfer.spec.js @@ -1,37 +1,35 @@ -const assert = require('assert'); -const Payjp = require('../built'); -const config = require('./config'); +const assert = require("node:assert"); +const Payjp = require("../built"); +const config = require("./config"); const payjp = Payjp(config.apikey, config); payjp.transfers.request = (...args) => Promise.resolve(args); -describe('Transfer Resource', () => { - - describe('list', () => { - it('Sends the correct request', () => { +describe("Transfer Resource", () => { + describe("list", () => { + it("Sends the correct request", () => { return payjp.transfers.list().then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'transfers'); + assert(_method === "GET"); + assert(_endpoint === "transfers"); }); }); }); - describe('retrieve', () => { - it('Sends the correct request', () => { - return payjp.transfers.retrieve('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'transfers/id123'); + describe("retrieve", () => { + it("Sends the correct request", () => { + return payjp.transfers.retrieve("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "transfers/id123"); }); }); }); - describe('charges', () => { - it('Sends the correct request', () => { - return payjp.transfers.charges('id123').then(([_method, _endpoint]) => { - assert(_method === 'GET'); - assert(_endpoint === 'transfers/id123/charges'); + describe("charges", () => { + it("Sends the correct request", () => { + return payjp.transfers.charges("id123").then(([_method, _endpoint]) => { + assert(_method === "GET"); + assert(_endpoint === "transfers/id123/charges"); }); }); }); - }); diff --git a/test/types/typescript.spec.ts b/test/types/typescript.spec.ts index 1e8cd3a..996d0a3 100644 --- a/test/types/typescript.spec.ts +++ b/test/types/typescript.spec.ts @@ -1,41 +1,41 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import * as Payjp from '../../built' +import * as Payjp from "../../built"; // Payjp.PayjpStatic -const apikey = 'sk_test_xxx' -const payjp = Payjp(apikey) +const apikey = "sk_test_xxx"; +const payjp = Payjp(apikey); -async function main(): Promise { +async function _main(): Promise { // Charge const chargeParams: Payjp.ChargeCreationOptions = { amount: 1000, - currency: 'jpy', - card: 'token_id_by_Checkout_or_payjp.js', - } + currency: "jpy", + card: "token_id_by_Checkout_or_payjp.js", + }; try { - const charge: Payjp.Charge = await payjp.charges.create(chargeParams) - let amount = 1000 - amount = charge.amount - let amount_refunded = 1000 - amount_refunded = charge.amount_refunded + const charge: Payjp.Charge = await payjp.charges.create(chargeParams); + let _amount = 1000; + _amount = charge.amount; + let _amount_refunded = 1000; + _amount_refunded = charge.amount_refunded; // and more... } catch (e) { // Error - const responseError = e as Payjp.ResponseError - let status: number = responseError.status - const payjpError: Payjp.PayjpError = responseError.response.body - const code: string = payjpError.error.code - const message: string = payjpError.error.message - const param: string = payjpError.error.param - status = payjpError.error.status + const responseError = e as Payjp.ResponseError; + let _status: number = responseError.status; + const payjpError: Payjp.PayjpError = responseError.response.body; + const _code: string = payjpError.error.code; + const _message: string = payjpError.error.message; + const _param: string = payjpError.error.param; + _status = payjpError.error.status; } // Transfer try { - const transferId = 'tr_xxx' - const transfer: Payjp.Transfer = await payjp.transfers.retrieve(transferId) - let transferDate = '2020-03-21' - transferDate = transfer.transfer_date + const transferId = "tr_xxx"; + const transfer: Payjp.Transfer = await payjp.transfers.retrieve(transferId); + let _transferDate = "2020-03-21"; + _transferDate = transfer.transfer_date; // and more... - } catch (e) { } + } catch (_e) {} } diff --git a/tsconfig.json b/tsconfig.json index 2a2d2dc..cb76670 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,10 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2024", "module": "commonjs", - "lib": [ - "dom" - ], + "lib": ["ES2024", "dom"], "outDir": "./built", "declaration": true }, - "include": [ - "./src/**/*.ts" - ] + "include": ["./src/**/*.ts"] }