From 638066ff8ea82fb15a5e71be03b04d409ec4c9b2 Mon Sep 17 00:00:00 2001 From: ksplatdev Date: Fri, 3 Sep 2021 12:16:32 -0400 Subject: [PATCH 1/2] Added inject method to Axle object, added FormData type to methods, and more --- README.md | 2 +- examples/README.md | 5 +++ examples/injectData.ts | 18 +++++++++ examples/productionEx.ts | 79 ++++++++++++++++++++++++++++++++++++++++ package-lock.json | 32 ++++++++-------- package.json | 4 +- src/core/delete.ts | 2 +- src/core/inject.ts | 9 +++++ src/core/patch.ts | 2 +- src/core/post.ts | 2 +- src/core/put.ts | 2 +- src/index.ts | 2 + src/models/request.ts | 2 +- src/models/response.ts | 17 ++++++++- 14 files changed, 152 insertions(+), 26 deletions(-) create mode 100644 examples/README.md create mode 100644 examples/injectData.ts create mode 100644 examples/productionEx.ts create mode 100644 src/core/inject.ts diff --git a/README.md b/README.md index 72dca8c..6f6f1ee 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ AxleJS supercharges fetch, with better error handling, easier to use options, ca ### CDN -1. Import from or for minified version . +1. Import from or for minified version . 2. Read the [documentation](https://github.com/ksplatdev/AxleJS/wiki/Documenation). ## Quick Start diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..da9d795 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,5 @@ +# AxleJS Examples + +Examples of the AxleJS API. + +This is **NOT** documentation. For documentation go to diff --git a/examples/injectData.ts b/examples/injectData.ts new file mode 100644 index 0000000..208fb19 --- /dev/null +++ b/examples/injectData.ts @@ -0,0 +1,18 @@ +import Axle from '../dist/index'; + +// inject into json results +Axle.inject({ + someInjectedData: 'injected', +}); + +// inject with middleware, check examples/useMiddleware.ts for more info +Axle.use((req, res) => { + Axle.inject({ timeTook: res.timeTook }); +}); + +(async () => { + const res = await Axle.get('https://someApi.com/documentation'); + const json = await res.json(); + + console.log(json.someInjectedData); // 'injected' +})(); diff --git a/examples/productionEx.ts b/examples/productionEx.ts new file mode 100644 index 0000000..4b67079 --- /dev/null +++ b/examples/productionEx.ts @@ -0,0 +1,79 @@ +// production example + +// types +interface Result { + status: number; + statusMessage: string; + message: string; + sessionToken: string; + regenerated: boolean; +} + +// dependencies +import Axle from '../dist'; + +// constants +const form: HTMLFormElement = document.querySelector('#loginForm'); +const formData = new FormData(form); + +// setup +form.onsubmit = (e) => { + e.preventDefault(); + + loginUser(); +}; + +Axle.use(Axle.middleware.timeTook()); +Axle.useOptions(Axle.middlewareOptions.kneepads()); +Axle.useOptions(Axle.middlewareOptions.cors()); + +// custom middleware to inject regenerated property into json +Axle.use((req, res) => { + if (req.method === 'POST') { + if (Boolean(res.queryParam('regenerateToken')) === true) { + Axle.inject({ + regenerated: true, + }); + } else { + Axle.inject({ + regenerated: false, + }); + } + } +}); + +// Main + +// loginUser function, makes post request to /api/login, sets sessionToken, and follows redirect +async function loginUser(regenerateToken = false) { + const url = `https://example.com/api/login?regenerateToken=${regenerateToken}`; + + const res = await Axle.post(url, formData, { + handleStatus: handleStatus, + }); + const json = await res.json(); + + console.log(json.message); + + // login session token + localStorage.setItem('test-session-token', json.sessionToken); + + // if new token was generated + if (json.regenerated) { + console.log('New token.'); + } + + // follow redirect by Location header + res.finishRedirect(); +} + +// custom handle status +// return true to throw error and reject or false to resolve and continue +function handleStatus(status: number, statusMessage: string) { + if (status >= 500) { + console.log(status, statusMessage); + return true; + } else { + return false; + } +} diff --git a/package-lock.json b/package-lock.json index 303cbea..1d596d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "axlejs", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -211,9 +211,9 @@ "dev": true }, "@types/node": { - "version": "16.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.4.tgz", - "integrity": "sha512-25QXpDsTiDnl2rZGUenagVMwO46way8dOUdvoC3R3p+6TrbpxeJBo/v87BEG1IHI31Jhaa8lPeSHcqwxsVBeYQ==", + "version": "16.7.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz", + "integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==", "dev": true }, "@types/normalize-package-data": { @@ -956,9 +956,9 @@ } }, "electron-to-chromium": { - "version": "1.3.822", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.822.tgz", - "integrity": "sha512-k7jG5oYYHxF4jx6PcqwHX3JVME/OjzolqOZiIogi9xtsfsmTjTdie4x88OakYFPEa8euciTgCCzvVNwvmjHb1Q==", + "version": "1.3.829", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.829.tgz", + "integrity": "sha512-5EXDbvsaLRxS1UOfRr8Hymp3dR42bvBNPgzVuPwUFj3v66bpvDUcNwwUywQUQYn/scz26/3Sgd3fNVGQOlVwvQ==", "dev": true }, "emoji-regex": { @@ -2637,17 +2637,17 @@ } }, "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.3.tgz", + "integrity": "sha512-eDbuaDlXhVaaoKuLD3DTNTozKqln6xOG6Us0SzlKG5tNlazG+/cdl8pm9qiF1Di89iWScTI0HcO+CDcf2dkXiw==", "dev": true, "requires": { - "jest-worker": "^27.0.2", + "jest-worker": "^27.0.6", "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", + "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", "source-map": "^0.6.1", - "terser": "^5.7.0" + "terser": "^5.7.2" } }, "text-table": { @@ -2780,9 +2780,9 @@ } }, "webpack": { - "version": "5.51.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.51.1.tgz", - "integrity": "sha512-xsn3lwqEKoFvqn4JQggPSRxE4dhsRcysWTqYABAZlmavcoTmwlOb9b1N36Inbt/eIispSkuHa80/FJkDTPos1A==", + "version": "5.51.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.51.2.tgz", + "integrity": "sha512-odydxP4WA3XYYzwSQUivPxywdzMlY42bbfxMwCaEtHb+i/N9uzKSHcLgWkXo/Gsa+4Zlzf3Jg0hEHn1FnZpk2Q==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", diff --git a/package.json b/package.json index 6397ceb..48bd1ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "axlejs", - "version": "1.1.1", + "version": "1.2.0", "description": "Fetch, supercharged.", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -47,7 +47,7 @@ "prettier": "^2.3.2", "typescript": "^4.4.2", "uglify-js": "^3.14.1", - "webpack": "^5.51.1", + "webpack": "^5.51.2", "webpack-cli": "^4.8.0" } } diff --git a/src/core/delete.ts b/src/core/delete.ts index 0dd4794..db722c5 100644 --- a/src/core/delete.ts +++ b/src/core/delete.ts @@ -5,7 +5,7 @@ import AxleResponse from '../models/response'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export default async function deleteReq | FormData>( url: string, - data?: t | undefined | null, + data?: t | FormData | undefined | null, options: AxleTypes.AxleOptions = { mode: 'cors', cache: 'default', diff --git a/src/core/inject.ts b/src/core/inject.ts new file mode 100644 index 0000000..6778654 --- /dev/null +++ b/src/core/inject.ts @@ -0,0 +1,9 @@ +const __axle_js__inject_arr: Record[] = []; + +export default function inject(data: Record) { + return __axle_js__inject_arr.push(data); +} + +export function __getInjectedData() { + return __axle_js__inject_arr; +} diff --git a/src/core/patch.ts b/src/core/patch.ts index 4a84560..d238920 100644 --- a/src/core/patch.ts +++ b/src/core/patch.ts @@ -5,7 +5,7 @@ import AxleResponse from '../models/response'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export default async function patch>( url: string, - data?: t | undefined | null, + data?: t | FormData | undefined | null, options: AxleTypes.AxleOptions = { mode: 'cors', cache: 'default', diff --git a/src/core/post.ts b/src/core/post.ts index 3ba1fe4..37ac08f 100644 --- a/src/core/post.ts +++ b/src/core/post.ts @@ -5,7 +5,7 @@ import AxleResponse from '../models/response'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export default async function post>( url: string, - data?: t | undefined | null, + data?: t | FormData | undefined | null, options: AxleTypes.AxleOptions = { mode: 'cors', cache: 'default', diff --git a/src/core/put.ts b/src/core/put.ts index d7b32d9..f3da0dc 100644 --- a/src/core/put.ts +++ b/src/core/put.ts @@ -5,7 +5,7 @@ import AxleResponse from '../models/response'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export default async function put>( url: string, - data?: t | undefined | null, + data?: t | FormData | undefined | null, options: AxleTypes.AxleOptions = { mode: 'cors', cache: 'default', diff --git a/src/index.ts b/src/index.ts index 1fc7558..648e06b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import deleteReq from './core/delete'; import get from './core/get'; import head from './core/head'; +import inject from './core/inject'; import patch from './core/patch'; import post from './core/post'; import put from './core/put'; @@ -76,6 +77,7 @@ const Axle = { cancelMark: AxleCancelMark, use: use, useOptions: useOptions, + inject: inject, middleware: { timeTook: timeTook, }, diff --git a/src/models/request.ts b/src/models/request.ts index b207ba6..4ebf9b7 100644 --- a/src/models/request.ts +++ b/src/models/request.ts @@ -19,7 +19,7 @@ export default class AxleRequest> { constructor( method: string, url: string, - body: t | undefined | null, + body: t | FormData | undefined | null, options: AxleTypes.AxleOptions ) { this.method = method.toUpperCase(); diff --git a/src/models/response.ts b/src/models/response.ts index 12b3ab1..388d52c 100644 --- a/src/models/response.ts +++ b/src/models/response.ts @@ -1,5 +1,6 @@ // Class for converting Response to AxleResponse to supercharge fetch! +import { __getInjectedData } from '../core/inject'; import getQuery from '../utils/getQuery'; import queryParam from '../utils/queryParam'; import AxleHeaders from './headers'; @@ -16,8 +17,20 @@ export default class AxleResponse { this.timeEnd = timeEnd; } - public async json>(): Promise { - const json = await this.res.json(); + public async json>() { + let json: t = await this.res.json(); + + // get injected data + + const injectedData = __getInjectedData(); + + // add injected data + injectedData.forEach((data) => { + json = { + ...json, + ...data, + }; + }); return json; } From cb3711700d61f0f6701e6d03b392612e5c0b63ed Mon Sep 17 00:00:00 2001 From: ksplatdev Date: Thu, 9 Sep 2021 12:08:58 -0400 Subject: [PATCH 2/2] Updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f6f1ee..f71d29c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Fetch, supercharged. The [Fetch Web API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) is great, but it could be better. -AxleJS supercharges fetch, with better error handling, easier to use options, can automatically follow redirects, an easier way to manage and view headers and search queries, custom response and request classes and methods, and a lot more. +AxleJS supercharges fetch, with better error handling, using custom and built-in middleware and options, an easier way to manage and view headers and search queries, custom response and request classes and methods, and a lot more. ## [Documentation](https://github.com/ksplatdev/AxleJS/wiki/Documenation)