1.0.82 • Published 1 year ago

ts-cactus v1.0.82

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

ts-cactus

Create Typescript types from Open API Specification 3 (OAS3)

Features:

  • ✅ Convert OAS3 to Typescript
  • ✅ Typesafe API
  • ✅ Svelte Adapter
  • ✅ Works in any client ecosystem
  • ✅ Lightweight
  • ✅ IDE Autocompletion

Quick Start

Install ts-cactus 👇

bun add ts-cactus

Add to your package.json 👇 Make sure the "lib" folder exists, if not, create it.

{
  "name": "client-site",
  "private": true,
  "type": "module",
  "scripts": {
    "gen-users": "bun run ./node_modules/.bin/ts-cactus --url OAS3_JSON_URL --to ./src/lib/usersSchema.ts",
    "gen-accounts": "bun run ./node_modules/.bin/ts-cactus --url OAS3_JSON_URL --to ./src/lib/accountsSchema.ts",
    "gen-all": "bun run gen-users && bun run gen-accounts"
  }
}

Generate two schemas 👇

bun run gen-all

Create services.ts file in any place of the src directory 👇

import { createApi } from "ts-cactus";
import { apiSchema as usersSchema } from "./usersSchema.ts";
import { apiSchema as accountsSchema } from "./accountsSchema.ts";

const users = createApi("https://domain.com", usersSchema);
const accounts = createApi("https://domain.com", accountsSchema);

export const services = { users, accounts };

In your api.ts 👇

import { services } from "./services.ts";

const getUsers = async () => {
  const [status, res] = await services.users.get.users({
    page: 1,
    perPage: 20,
  });

  if (status) {
    console.log(res); // response
  } else {
    console.log(res); // error
  }
};

Svelte

Usage, here is an example component with an adapter for svelte, but you can use any other framework 👇

<script lang="ts">
  import { load } from "ts-cactus/svelte";
  import { services } from "./lib/services.ts";

  let params = {
    page: 1,
  };

  const getAccounts = async () => {
    return await services.accounts.get.adminAccounts(params);
  };

  let accounts = load(getAccounts);
</script>

<button
  on:click="{() => {
    $accounts.res = undefined;
    $accounts.reload();
  }}">Reload</button
>

<button
  on:click="{() => {
    params.page += 1;
    $accounts.reload();
  }}">Next</button
>

{#if $accounts?.loading}
  Loading
{/if}

{#each $accounts?.res?.data || [] as account}
  <div>
    <span>{account.clientName}</span>
  </div>
{/each}

Adapter - load function is needed just for convenient data getting, it’s not required to use this function. However, if you use load, you must set the following option in your tsconfig.json: "moduleResolution": "nodenext".

You can also add events for more control 👇

const users = createApi("https://domain.com", usersSchema, {
  beforeRequest: async (request) => {
    console.log(request.headers.get("header"));
    // set request headers: req.headers.append("xxx", "value")
  },
  afterRequest: async (request, response) => {
    // logic
  },
});

Need to abort the request? Easy! 👇

const getAccounts = async () => {
  const controller = new AbortController();
  const signal = controller.signal;

  window.setTimeout(() => {
    controller.abort();
  }, 2000);

  return await services.accounts.get.adminAccounts(params, {
    signal,
  });
};

Any method has options where you can pass a signal.

Upload File 👇

const doc1 = await fetch("doc.pdf");
const doc2 = new File([], "test");

// uploadPassport - multipart/form-data
await services.accounts.post.uploadPassport({
  file: await doc1.blob(), // good type
});

// uploadPassport - multipart/form-data
await services.accounts.post.uploadPassport({
  file: doc2, // good type
});

You don't need to wrap in try/catch 👇

const createUser = async () => {
	const [status, res] = await services.users.post.createUser({...});

	console.log(status, res);
}

Author

Vladislav Yemelyanov

Released under the MIT License.

1.0.82

1 year ago

1.0.81

1 year ago

1.0.73

1 year ago

1.0.72

1 year ago

1.0.71

1 year ago

1.0.77

1 year ago

1.0.76

1 year ago

1.0.75

1 year ago

1.0.74

1 year ago

1.0.79

1 year ago

1.0.78

1 year ago

1.0.62

2 years ago

1.0.61

2 years ago

1.0.60

2 years ago

1.0.65

2 years ago

1.0.64

2 years ago

1.0.69

2 years ago

1.0.68

2 years ago

1.0.67

2 years ago

1.0.70

2 years ago

1.0.39

2 years ago

1.0.40

2 years ago

1.0.44

2 years ago

1.0.43

2 years ago

1.0.42

2 years ago

1.0.41

2 years ago

1.0.48

2 years ago

1.0.47

2 years ago

1.0.46

2 years ago

1.0.45

2 years ago

1.0.49

2 years ago

1.0.51

2 years ago

1.0.50

2 years ago

1.0.55

2 years ago

1.0.54

2 years ago

1.0.53

2 years ago

1.0.52

2 years ago

1.0.59

2 years ago

1.0.58

2 years ago

1.0.57

2 years ago

1.0.56

2 years ago

1.0.38

2 years ago

1.0.37

2 years ago

1.0.36

2 years ago

1.0.35

2 years ago

1.0.34

2 years ago

1.0.33

2 years ago

1.0.32

2 years ago

1.0.31

2 years ago

1.0.30

2 years ago

1.0.29

2 years ago

1.0.28

2 years ago

1.0.27

2 years ago

1.0.26

2 years ago

1.0.25

2 years ago

1.0.24

2 years ago

1.0.23

2 years ago

1.0.22

2 years ago

1.0.21

2 years ago

1.0.20

2 years ago

1.0.19

2 years ago

1.0.18

2 years ago

1.0.17

2 years ago

1.0.16

2 years ago

1.0.15

2 years ago

1.0.14

2 years ago

1.0.13

2 years ago

1.0.12

2 years ago

1.0.11

2 years ago

1.0.10

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago