# Abstract Core ✨
## Getting started 🏁
### What is this 🤷‍♂️?

Abstract core is a library made for [Next.js Abstract](https://github.com/osnmarket/abstract) allowing it to handle everything regarding http request caching and security issues.

### HTTP Utilities 🌐

In here you'll have 3 http clients:

- `fetcher`
- `useFetch`
- `serverFetch`

Each of them is based on [axios](https://axios-http.com/docs/intro) meaning one can use it like one would use axios. They are made to handle the following

### ⚠️ Abtract Handler

Just for a heads up; here's how abstract works on requests perspective.

First you need to know that we're using `config-yml` in that way you can have:

```yml
# config/development.yml or production.yml at the root of your project
providers:
  keycloak:
    identifier_key: client_id
    password_key: client_secret
    token_type: Bearer
    token_key: access_token
    authentication_path: /{realm}/auth/token
    authorization_key: Authorization
  strapi:
    identifier_key: identifier
    password_key: password
    token_type: Bearer
    token_key: jwt
    authentication_path: /auth/local
    authorization_key: Authorization
    authentication_via_form: true
  auth0:
    identifier_key: client_id
    password_key: client_secret
    token_type: Bearer
    token_key: access_token
    authorization_key: Authorization
  customCentralAuth0:
    identifier_key: app_id
    password_key: app_secret
    token_type: none
    token_key: access_token
    authorization_key: X-Auth-Token

app:
  gateway:
    provider: auth0
    authentication_path: /auth/v1/token
  centralized_content:
    provider: customCentralAuth0
    authentication_path: /x-user/token

caching_sytem: nodeCache
```

That's essential so that abstract knows how to operate when targetting your backend apps. Please have in mind that in the `app` keyword, the key are your backends

Moving to the handler:

- Next.js Page router

```javascript
import { abstractHandler } from 'osnmarket-abstract-core/handlers';

export default async function handler(req, res) {
  const { data, status } = await abstractHandler(req, res);

  return res.status(status).json(data)
}
```

- Next.js App router

```javascript
import { NextResponse } from 'next/server';
import { abstractHandler } from 'osnmarket-abstract-core/handlers';
export const dynamic = 'force-dynamic' // defaults to auto

const handler = async (req, res) => {
  const { data } = await abstractHandler(req, res)

  return NextResponse.json(data)
}

export async function OPTIONS(req, res) {
  return handler(req, res)
}

export async function GET(req, res) {
  return handler(req, res)
}

export async function POST(req, res) {
  return handler(req, res)
}

export async function PUT(req, res) {
  return handler(req, res)
}

export async function PATCH(req, res) {
  return handler(req, res)
}
```

### fetcher

The fetcher is made to handles all runtime client requests. It will send request on `abstractHandler` and safe communication is made available between them

#### Basic usage
```javascript
import { fetcher } from 'osnmarket-abstract-core/client'

fetcher({
  uri: 'https://example.com',
  options: {
    method: 'POST',
    headers: {
      'content-type': 'application/json'
    }
  },
  body: {
    key: 'any',
    value: 'payload'
  },
  target: 'backend', // if not specified it will use the default target
})
```

This represents a basic implementation of the fetcher. Also if one wanted to use special axios methods, one can do this:

```javascript
import { fetcher } from 'osnmarket-abstract-core/client'

fetcher({
  uri: 'https://example.com/form/1',
  options: {
    axs_method: 'getForm'
  }
  // The rest ...
})
```

#### Addons
You'll find special args you can use in the fetcher

- `encrypt`
It's an array which once specified, will encrypt those keys inside the response before it's returned to the client; even if the specified keys are an array or an object.

```javascript
fetcher({
  uri: 'https://example.com/user/1',
  encrypt: ['id', 'uuid', 'customer']
})

// Which response should be this

{
  "id": 1,
  "uuid": "12Ddzad-dazdza-deaeza-212ez",
  "customer": {
    "name": "Doe",
    "surname": "John",
    "adress": "Townville"
  },
  "status": "active"
}

// Would be

{
  "id": "aazoezaezaezaea", // Random gibberish
  "uuid": "aazoezaezaezaea", // Random gibberish
  "customer": "zaeazeazeazeazed", // Random gibberish
  "status": "active"
}
```

When you do that one might ask "Wait 🤔, that's cold 🥶 but how to I consume it on my code!?"

And you're right Meum 🤗, How?

Use `secureContentDecryption` 🥳

```javascript
import { fetcher } from 'osnmarket-abstract-core/client'
import { secureContentDecryption } from 'osnmarket-abstract-core/utils'

const { data } = await fetcher({
  uri: 'https://example.com/user/1',
  encrypt: ['id', 'uuid', 'customer']
})

console.log({
  ...data,
  "customer": JSON.parse(secureContentDecryption(data.customer))
})

// JSON.parse Because objects and arrays are stringified

// Would give

{
  "id": "aazoezaezaezaea", // Random gibberish
  "uuid": "aazoezaezaezaea", // Random gibberish
  "status": "active",
  "customer": {
    "name": "Doe",
    "surname": "John",
    "adress": "Townville"
  }
}
```
- `user_token`

Usually, fetcher will use the backend's token (automatic authentication) but when for example you have an authenticated user, you can specify the token of the user to override the default token.

```javascript
import { fetcher } from 'osnmarket-abstract-core/client'
import { secureContentDecryption } from 'osnmarket-abstract-core/utils'

const { data } = await fetcher({
  uri: 'https://example.com/user/1',
  user_token: 'Bearer token'
})
```

### useFetch
Behind this hook is [SWR](https://swr.vercel.app/docs/getting-started) so use it in the same way; knowing it uses as http client the `fetcher` so what ever is implemented on it is available on it. (Yep Eli it saves me a lot of explanation 🌚)

```javascript
import { useFetch } from 'osnmarket-abstract-core/hook'

const { data } = await useFetch({
  uri: 'https://example.com/user/1'
})
```

#### Addons
- refreshInterval

Sends request periodically

```javascript
import { useFetch } from 'osnmarket-abstract-core/hook'

const { data } = await useFetch({
  uri: 'https://example.com/user/1',
  refreshInterval: 5000 // each five seconds
})
```

### serverFetch
It's the only utility that won't use the `abstractHandler` because it's usable only at server level but it works the same way `fetcher` does (Saves me a lot of explanation too 😅)

```javascript
import { serverFetch } from 'osnmarket-abstract-core/server'

const { data } = await serverFetch({
  uri: 'https://example.com/user/1'
})
```

### MKWYD (Must Know What You Do) Section

- ***extractSavedToken***

Use this method to extract a token from the saved cache.

```javascript
import { extractSavedToken } from 'osnmarket-abstract-core/core'
const accessToken = await extractSavedToken('myTarget');

console.log(accessToken); // { Authorization: "Bearer myAwesomeToken" }
```