diff --git a/.github/actions/app-test/action.yml b/.github/actions/app-test/action.yml new file mode 100644 index 000000000..5613e8e0e --- /dev/null +++ b/.github/actions/app-test/action.yml @@ -0,0 +1,55 @@ +name: 'Start and Test Node.js App' +description: 'Starts Node.js app, runs tests, and shuts it down' +inputs: + port: + description: 'Port on which the Node.js app is running' + required: true + path: + description: 'Path to test with the HTTP request' + required: false + default: "" + method: + description: 'HTTP method to use for the test (GET, POST, etc.)' + required: true + body: + description: 'Request body for POST method (optional)' + required: false + default: "" + working-directory: + description: 'Working directory of the Node.js app' + required: true + channel-access-token: + description: 'Channel access token' + required: true + channel-secret: + description: 'Channel secret' + required: true + + +runs: + using: 'composite' + steps: + - name: Start application + run: | + export CHANNEL_ACCESS_TOKEN=${{ inputs.channel-access-token }} + export CHANNEL_SECRET=${{ inputs.channel-secret }} + npm start & + shell: bash + working-directory: ${{ inputs.working-directory }} + + - name: Wait for application to start + run: sleep 3 + shell: bash + + - name: Test application + run: | + if [ "${{ inputs.method }}" = "POST" ]; then + curl --fail -X POST -d '${{ inputs.body }}' http://localhost:${{ inputs.port }}/${{ inputs.path }} || exit 1 + else + curl --fail -X ${{ inputs.method }} http://localhost:${{ inputs.port }}/${{ inputs.path }} || exit 1 + fi + shell: bash + + - name: Kill application + run: pkill node + shell: bash diff --git a/.github/actions/setup-and-build/action.yml b/.github/actions/setup-and-build/action.yml new file mode 100644 index 000000000..acb69d23a --- /dev/null +++ b/.github/actions/setup-and-build/action.yml @@ -0,0 +1,35 @@ +# .github/actions/setup-and-build/action.yml +name: 'Setup and Build' +description: 'Sets up Java, Node.js, installs dependencies, and builds the project' +inputs: + node-version: + description: 'Node.js version to setup' + required: true + +runs: + using: 'composite' + steps: + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + architecture: x64 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + cache: 'npm' + + - name: Install Dependency + run: npm ci + shell: bash + + - name: Test generator + run: cd generator; mvn package; cd .. + shell: bash + + - name: Generate code + run: python3 generate-code.py + shell: bash diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 888701c06..c038262c6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,51 +16,100 @@ jobs: node: [ '18', '20' ] fail-fast: false - name: Node.js ${{ matrix.node }} + name: Node.js ${{ matrix.node }} - test steps: - uses: actions/checkout@v4 with: submodules: true - - name: actions/setup-java@v3 - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 17 - architecture: x64 - - name: Setup Node.js - uses: actions/setup-node@v4 + - name: Setup and Build + uses: ./.github/actions/setup-and-build with: node-version: ${{ matrix.node }} - cache: 'npm' - - name: Install Dependency - run: npm ci - - name: Test generator - run: cd generator; mvn package; cd .. - - name: Generate code - run: | - python3 generate-code.py + - name: Test Project run: export NODE_OPTIONS=--max-old-space-size=6144; npm test - name: Test building apidocs run: export NODE_OPTIONS=--openssl-legacy-provider; npm run apidocs - name: Test building docs run: export NODE_OPTIONS=--openssl-legacy-provider; npm run docs:build - - name: Test building examples (CJS) + + - name: publint + run: npx publint + - name: validate package + run: npx @arethetypeswrong/cli $(npm pack) + + example: + runs-on: ubuntu-latest + strategy: + matrix: + # https://nodejs.org/en/about/releases/ + node: [ '18', '20' ] + fail-fast: false + name: Node.js ${{ matrix.node }} - example + steps: + - uses: actions/checkout@v4 + with: + submodules: true + # TODO: Enable this again + # - name: Setup and Build + # uses: ./.github/actions/setup-and-build + # with: + # node-version: ${{ matrix.node }} + - name: Test building examples (JS + ESM) + run: | + cd examples/echo-bot-esm + npm run build-sdk + npm install + - name: Test Node.js App (echo-bot-esm) + uses: ./.github/actions/app-test + with: + port: '3000' + method: 'GET' + working-directory: examples/echo-bot-esm + channel-access-token: ${{ secrets.CHANNEL_ACCESS_TOKEN }} + channel-secret: ${{ secrets.CHANNEL_SECRET }} + + - name: Test building examples (TS + CJS) run: | cd examples/echo-bot-ts-cjs npm run build-sdk npm install npm run build - cd - - - name: Test building examples (ESM) + - name: Test Node.js App (echo-bot-ts-cjs) + uses: ./.github/actions/app-test + with: + port: '3000' + method: 'GET' + working-directory: examples/echo-bot-ts-cjs + channel-access-token: ${{ secrets.CHANNEL_ACCESS_TOKEN }} + channel-secret: ${{ secrets.CHANNEL_SECRET }} + + - name: Test building examples (TS + ESM) run: | cd examples/echo-bot-ts-esm npm run build-sdk npm install npm run build - cd - - - name: publint - run: npx publint - - name: validate package - run: npx @arethetypeswrong/cli $(npm pack) + - name: Test Node.js App (echo-bot-ts-esm) + uses: ./.github/actions/app-test + with: + port: '3000' + method: 'GET' + working-directory: examples/echo-bot-ts-esm + channel-access-token: ${{ secrets.CHANNEL_ACCESS_TOKEN }} + channel-secret: ${{ secrets.CHANNEL_SECRET }} + + - name: Test building examples (JS + CJS) + run: | + cd examples/echo-bot + npm run build-sdk + npm install + - name: Test Node.js App (echo-bot) + uses: ./.github/actions/app-test + with: + port: '3000' + method: 'GET' + working-directory: examples/echo-bot + channel-access-token: ${{ secrets.CHANNEL_ACCESS_TOKEN }} + channel-secret: ${{ secrets.CHANNEL_SECRET }} diff --git a/docs/getting-started/requirements.md b/docs/getting-started/requirements.md index 5b4c1a4bb..06ce6a4c8 100644 --- a/docs/getting-started/requirements.md +++ b/docs/getting-started/requirements.md @@ -1,7 +1,7 @@ # Requirements * **Node.js** >= 18. - * It uses ES2015. + * It uses ES2022. * [**npm**](https://www.npmjs.com/), preferably >=10 Other dependencies are installed via npm, and do not need to be pre-installed. diff --git a/examples/echo-bot-esm/README.md b/examples/echo-bot-esm/README.md new file mode 100644 index 000000000..476d01741 --- /dev/null +++ b/examples/echo-bot-esm/README.md @@ -0,0 +1,32 @@ +# Echo Bot (ESM) + +An example LINE bot just to echo messages + +## How to use + +### Install deps + +``` shell +$ npm build-sdk +$ npm install +``` + +### Configuration + +``` shell +$ export CHANNEL_SECRET=YOUR_CHANNEL_SECRET +$ export CHANNEL_ACCESS_TOKEN=YOUR_CHANNEL_ACCESS_TOKEN +$ export PORT=1234 +``` + +### Run + +``` shell +$ node . +``` + +## Webhook URL + +``` +https://your.base.url/callback +``` diff --git a/examples/echo-bot-esm/index.js b/examples/echo-bot-esm/index.js new file mode 100644 index 000000000..c633ae9b5 --- /dev/null +++ b/examples/echo-bot-esm/index.js @@ -0,0 +1,71 @@ +import { messagingApi, middleware } from '@line/bot-sdk'; +import express from 'express'; + +// create LINE SDK config from env variables +const config = { + channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN, + channelSecret: process.env.CHANNEL_SECRET, +}; + +// create LINE SDK client +const client = new messagingApi.MessagingApiClient({ + channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN +}); + +// create Express app +// about Express itself: https://expressjs.com/ +const app = express(); + +app.get( + '/', + async (_, res) => { + const botInfo = await client.getBotInfo() + if (botInfo.displayName.length < 2) { + return res.status(500).json({ + status: 'failure', + message: 'api call failed', + }); + } else { + return res.status(200).json({ + status: 'success', + message: `${JSON.stringify(botInfo)}`, + }); + } + } +); + + +// register a webhook handler with middleware +// about the middleware, please refer to doc +app.post('/callback', middleware(config), (req, res) => { + Promise + .all(req.body.events.map(handleEvent)) + .then((result) => res.json(result)) + .catch((err) => { + console.error(err); + res.status(500).end(); + }); +}); + +// event handler +function handleEvent(event) { + if (event.type !== 'message' || event.message.type !== 'text') { + // ignore non-text-message event + return Promise.resolve(null); + } + + // create an echoing text message + const echo = { type: 'text', text: event.message.text }; + + // use reply API + return client.replyMessage({ + replyToken: event.replyToken, + messages: [echo], + }); +} + +// listen on port +const port = process.env.PORT || 3000; +app.listen(port, () => { + console.log(`listening on ${port}`); +}); diff --git a/examples/echo-bot-esm/package-lock.json b/examples/echo-bot-esm/package-lock.json new file mode 100644 index 000000000..ebac80546 --- /dev/null +++ b/examples/echo-bot-esm/package-lock.json @@ -0,0 +1,640 @@ +{ + "name": "echo-bot", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "echo-bot", + "version": "0.0.0", + "dependencies": { + "@line/bot-sdk": "../../", + "express": "^4.17.3" + } + }, + "../..": { + "name": "@line/bot-sdk", + "version": "__LINE_BOT_SDK_NODEJS_VERSION__", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^20.0.0" + }, + "devDependencies": { + "@types/express": "4.17.21", + "@types/finalhandler": "1.2.3", + "@types/mocha": "10.0.6", + "@vitest/coverage-v8": "^1.4.0", + "express": "4.19.2", + "finalhandler": "1.2.0", + "husky": "9.0.11", + "msw": "2.2.11", + "prettier": "3.2.5", + "ts-node": "10.9.2", + "typedoc": "^0.25.1", + "typedoc-plugin-markdown": "^3.16.0", + "typescript": "5.4.3", + "vite": "^5.2.7", + "vitepress": "^1.0.1", + "vitest": "^1.4.0" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "axios": "^1.0.0" + } + }, + "node_modules/@line/bot-sdk": { + "resolved": "../..", + "link": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/examples/echo-bot-esm/package.json b/examples/echo-bot-esm/package.json new file mode 100644 index 000000000..370eda132 --- /dev/null +++ b/examples/echo-bot-esm/package.json @@ -0,0 +1,15 @@ +{ + "name": "echo-bot", + "version": "0.0.0", + "description": "An example LINE bot just to echo messages", + "main": "index.js", + "scripts": { + "build-sdk": "cd ../../; npm i; npm run build", + "start": "node ." + }, + "dependencies": { + "@line/bot-sdk": "../../", + "express": "^4.17.3" + }, + "type": "module" +} diff --git a/examples/echo-bot-ts-cjs/index.ts b/examples/echo-bot-ts-cjs/index.ts index 193fc4b82..918c1a920 100644 --- a/examples/echo-bot-ts-cjs/index.ts +++ b/examples/echo-bot-ts-cjs/index.ts @@ -59,10 +59,18 @@ const textEventHandler = async (event: webhook.Event): Promise => { - return res.status(200).json({ - status: 'success', - message: 'Connected successfully!', - }); + const botInfo = await client.getBotInfo() + if (botInfo.displayName.length < 2) { + return res.status(500).json({ + status: 'failure', + message: 'api call failed', + }); + } else { + return res.status(200).json({ + status: 'success', + message: `${JSON.stringify(botInfo)}`, + }); + } } ); diff --git a/examples/echo-bot-ts-cjs/package-lock.json b/examples/echo-bot-ts-cjs/package-lock.json index 09d14a044..28dc0caef 100644 --- a/examples/echo-bot-ts-cjs/package-lock.json +++ b/examples/echo-bot-ts-cjs/package-lock.json @@ -15,7 +15,7 @@ "@types/express": "^4.17.17", "@types/node": "^20.6.3", "rimraf": "^5.0.1", - "typescript": "^5.4.3" + "typescript": "^5.2.2" } }, "../..": { diff --git a/examples/echo-bot-ts-cjs/package.json b/examples/echo-bot-ts-cjs/package.json index 7b4941c01..194fbd116 100644 --- a/examples/echo-bot-ts-cjs/package.json +++ b/examples/echo-bot-ts-cjs/package.json @@ -17,6 +17,6 @@ "@types/express": "^4.17.17", "@types/node": "^20.6.3", "rimraf": "^5.0.1", - "typescript": "^5.4.3" + "typescript": "^5.2.2" } } diff --git a/examples/echo-bot-ts-cjs/tsconfig.json b/examples/echo-bot-ts-cjs/tsconfig.json index 40dce4749..49e37f24e 100644 --- a/examples/echo-bot-ts-cjs/tsconfig.json +++ b/examples/echo-bot-ts-cjs/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2017", + "target": "ES2022", "module": "commonjs", "outDir": "./dist", "strict": true, diff --git a/examples/echo-bot-ts-esm/index.ts b/examples/echo-bot-ts-esm/index.ts index 193fc4b82..918c1a920 100644 --- a/examples/echo-bot-ts-esm/index.ts +++ b/examples/echo-bot-ts-esm/index.ts @@ -59,10 +59,18 @@ const textEventHandler = async (event: webhook.Event): Promise => { - return res.status(200).json({ - status: 'success', - message: 'Connected successfully!', - }); + const botInfo = await client.getBotInfo() + if (botInfo.displayName.length < 2) { + return res.status(500).json({ + status: 'failure', + message: 'api call failed', + }); + } else { + return res.status(200).json({ + status: 'success', + message: `${JSON.stringify(botInfo)}`, + }); + } } ); diff --git a/examples/echo-bot-ts-esm/tsconfig.json b/examples/echo-bot-ts-esm/tsconfig.json index 835590bf2..592c51ae6 100644 --- a/examples/echo-bot-ts-esm/tsconfig.json +++ b/examples/echo-bot-ts-esm/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2022", "module": "NodeNext", - "outDir": "./dist", "moduleResolution": "NodeNext", + "outDir": "./dist", "esModuleInterop": true, "forceConsistentCasingInFileNames": true }, diff --git a/examples/echo-bot/index.js b/examples/echo-bot/index.js index eec2fc114..feabfdac2 100644 --- a/examples/echo-bot/index.js +++ b/examples/echo-bot/index.js @@ -18,6 +18,25 @@ const client = new line.messagingApi.MessagingApiClient({ // about Express itself: https://expressjs.com/ const app = express(); +app.get( + '/', + async (_, res) => { + const botInfo = await client.getBotInfo() + if (botInfo.displayName.length < 2) { + return res.status(500).json({ + status: 'failure', + message: 'api call failed', + }); + } else { + return res.status(200).json({ + status: 'success', + message: `${JSON.stringify(botInfo)}`, + }); + } + } +); + + // register a webhook handler with middleware // about the middleware, please refer to doc app.post('/callback', line.middleware(config), (req, res) => { diff --git a/examples/echo-bot/package-lock.json b/examples/echo-bot/package-lock.json index b2ebf36cc..ebac80546 100644 --- a/examples/echo-bot/package-lock.json +++ b/examples/echo-bot/package-lock.json @@ -23,18 +23,19 @@ "@types/express": "4.17.21", "@types/finalhandler": "1.2.3", "@types/mocha": "10.0.6", + "@vitest/coverage-v8": "^1.4.0", "express": "4.19.2", "finalhandler": "1.2.0", "husky": "9.0.11", - "mocha": "10.4.0", "msw": "2.2.11", - "nyc": "15.1.0", "prettier": "3.2.5", "ts-node": "10.9.2", "typedoc": "^0.25.1", "typedoc-plugin-markdown": "^3.16.0", "typescript": "5.4.3", - "vitepress": "^1.0.1" + "vite": "^5.2.7", + "vitepress": "^1.0.1", + "vitest": "^1.4.0" }, "engines": { "node": ">=18" diff --git a/tsconfig.json b/tsconfig.json index 9c302f573..58f20519d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "module": "NodeNext", - "moduleResolution": "NodeNext", + "module": "ESNext", + "moduleResolution": "Bundler", + "target": "ES2022", "esModuleInterop": true, - "target": "ES2018", "noImplicitAny": true, "newLine": "LF", "sourceMap": true,