Compare commits

...

5 commits

Author SHA1 Message Date
5d6b4a4675
fix: set Content-Type headers for requests with payload (#7) 2023-11-09 13:15:49 +01:00
04e9c7ec84 fix: no request body on GET requests (#5) 2023-11-09 11:56:18 +01:00
87a5fd4cb9 fix: tailing slash for domain name (#4) 2023-11-09 11:56:18 +01:00
278868984d
fix: ESM exports (#2)
* wip: 2023-09-20T13:43:23+0200 (1695210203)

* wip: 2023-09-20T12:53:34+0200 (1695207214)

* wip: 2023-09-20T12:53:34+0200 (1695207214)

* wip: 2023-11-07T14:37:18+0100 (1699364238)
2023-11-09 10:51:01 +01:00
e7810249aa
feat(doc): add README 2023-09-26 16:15:40 +02:00
5 changed files with 144 additions and 11 deletions

52
.npmignore Normal file
View file

@ -0,0 +1,52 @@
/src
# Bootstrapping #
#################
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.ini
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
public/robots.txt
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
.directory
# Tool specific files #
#######################
# vim
*~
*.swp
*.swo
# sublime text & textmate
*.sublime-*
*.stTheme.cache
*.tmlanguage.cache
*.tmPreferences.cache
# Eclipse
.settings/*
# JetBrains, aka PHPStorm, IntelliJ IDEA
.idea/*
# NetBeans
nbproject/*
# Visual Studio Code
.vscode
# Sass preprocessor
.sass-cache/

56
README.md Normal file
View file

@ -0,0 +1,56 @@
# Reflect API client for JavaScript
Make requests to an API built using the [Reflect API](https://github.com/VictorWesterlund/reflect) framework over HTTP with JavaScript.
---
```js
import { Client, Method } from "./reflect-client/Reflect.js
const api = new Client("<api_url>", "<optional_api_key");
// Make an API request with Client.call() which returns a normal JavaScript Response object
api.call("my/endpoint", Method.GET); // obj<Respone>
```
## Supported browsers/environments:
![Chrome-icon](https://user-images.githubusercontent.com/35688133/230028928-dca1467d-8c63-4e69-9524-78e5751eaf24.png)<br>Chrome|![Firefox_logo,_2019 svg](https://user-images.githubusercontent.com/35688133/230029200-624d0126-9640-4b78-9eb5-a2e4be4e51be.png)<br>Firefox|![Safari_browser_logo svg](https://user-images.githubusercontent.com/35688133/230029381-e7162ba1-e9ef-4b34-803f-043b5d16d365.png)<br>Safari|![image](https://github.com/VictorWesterlund/reflect-client-js/assets/35688133/36ac25a9-cc69-415b-b3c8-7f328d80c16d)<br>NodeJS|![deno](https://github.com/VictorWesterlund/reflect-client-js/assets/35688133/beb98cb4-702b-45f1-a496-1aa66ef97130)<br>Deno
--|--|--|--|--
✅ 80+|✅ 75+|✅ 14.1+|✅ 20.7.0+|✅ 1.37.0+
## How to use
1. **Install with npm**
```
npm i reflect-client
```
2. **Initialize the class**
```js
import { Client, Method } from "./reflect-client/Reflect.js
const api = new Client("<api_url>", "<optional_api_key");
```
3. **Make API request**
Use the `call()` method to perform a request
```js
api.call("my/endpoint", Method.GET);
```
Argument index|Type|Required|Description
--|--|--|--
0|string|Yes|Fully qualified pathname and query params of the endpoint to call
1|Method\|string|Yes|A supported [Reflect HTTP method](https://github.com/VictorWesterlund/reflect/wiki/Supported-technologies#http-request-methods) (eg. `Method.GET`) or a string represnetation of a supported method (eg. "GET")
2|array|No|An optional indexed, associative, or multidimensional array that will be sent as the request body as `Content-Type: application/json`
The `call()` function will return a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object
# Development
NodeJS required version: 20.7.0+
TypeScript required version: 5.2.2+

View file

@ -1,7 +1,16 @@
{
"name": "reflect-client",
"version": "1.0.0",
"version": "1.1.2",
"main": "build/Reflect.js",
"type": "module",
"exports": {
".": {
"import": {
"types": "./src/Reflect.ts",
"default": "./build/Reflect.js"
}
}
},
"devDependencies": {
"typescript": "^5.2.2"
}

View file

@ -1,4 +1,7 @@
import { Method } from "./Method";
import { Method } from "./Method.js";
// Export Method as importable directly from the Reflect.js ESM
export { Method };
// Connect to a Reflect API instance over HTTP
export default class Client {
@ -6,7 +9,8 @@ export default class Client {
private headers: object = {};
constructor(url: string, key: string|null = null) {
this.url = url;
// Append tailing slash if omitted from URL string
this.url = url.substring(url.length - 1) === "/" ? url : url + "/";
// Use API key with requests if defined
if (key) {
@ -14,9 +18,22 @@ export default class Client {
}
}
// Set request header
private setHeader(name, value): void {
return this.headers[name] = value;
}
// Set API key to use for all requests
private setApiKey(key: string): void {
this.headers["Authentication"] = `Bearer ${key}`;
return this.setHeader("Authorization", `Bearer ${key}`);
}
// Get fully qualified URL to endpoint
private getEndpoint(endpoint: string): string {
// Remove leading slash if provided for pathname. It's already set on the domain name
endpoint = endpoint.substring(0, 1) !== "/" ? endpoint : endpoint.substring(1, endpoint.length);
return this.url + endpoint;
}
// Call a Reflect API endpoint with method and optional payload
@ -26,12 +43,13 @@ export default class Client {
headers: this.headers
}
// JSON stringify and append body to request if provided
if (payload) {
// JSON stringify and append body to request if provided and is not a GET request
if (payload && method !== Method.GET) {
this.setHeader("Content-Type", "application/json");
options["body"] = JSON.stringify(payload);
}
// Fetch and return Response object
return await fetch(endpoint, options);
return await fetch(this.getEndpoint(endpoint), options);
}
}

View file

@ -2,9 +2,7 @@
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "amd",
"target": "ES6",
"rootDir": "./src",
"outFile": "./build/Reflect.js"
"module": "NodeNext",
"outDir": "./build"
}
}