0.21.0 • Published 6 months ago

@sdk-it/generic v0.21.0

Weekly downloads
-
License
-
Repository
-
Last release
6 months ago

@sdk-it/generic

This package provides tools to analyze TypeScript code and generate OpenAPI specifications from it. It can extract route information, parameter types, and response schemas from your TypeScript codebase.

Frameworks specific integrations

Installation

npm install @sdk-it/generic

Usage

Consider the following example:

  • Create a route using your API framework of choice with the @openapi tag and validate middleware.
import z from 'zod';

import { validate } from '@sdk-it/express/runtime';

const app = express();

/**
 * @openapi getAuthor
 * @tags authors
 */
app.get(
  '/authors/:id',
  validate((payload) => ({
    id: {
      select: payload.param.id,
      against: z.string(),
    },
  })),
  async (req, res) => {
    const author = [{ name: 'John Doe' }];
    return res.json(author);
  },
);
  • Use the generate fn to create an OpenAPI spec from your routes.
import { join } from 'node:path';

import { analyze, responseAnalyzer } from '@sdk-it/generic';
import { generate } from '@sdk-it/typescript';

const { paths, components } = await analyze('path/to/tsconfig.json', {
  responseAnalyzer,
});

// Now you can use the generated specification to create an SDK or save it to a file
const spec = {
  info: {
    title: 'My API',
    version: '1.0.0',
  },
  paths,
  components,
};
await generate(spec, {
  output: join(process.cwd(), './client'),
});

!TIP See typescript for more info.

Customizing Operations

You can customize the operations as well as add more through the onOperation fn.

Use file name as tag

Assuming your projects structurd like the following where routes are grouped by representivie file names.

apps/
  backend/
    tsconfig.app.json
    src/
      routes/
        authors.ts

Then you can consider the file name as the tag for the operation which means you don't need to specify the tag in the JSDoc comment or only specify the tag if you want to override the default behavior.

import { basename } from 'node:path';
import { camelcase } from 'stringcase';

import { analyze, responseAnalyzer } from '@sdk-it/generic';

const { paths, components } = await analyze('apps/backend/tsconfig.app.json', {
  responseAnalyzer,
  onOperation(sourceFile, method, path, operation) {
    const fileName = basename(sourceFile.split('/').at(-1), '.ts');
    return {
      [method]: {
        [path]: {
          ...operation,
          tags: [fileName],
        },
      },
    };
  },
});
0.21.0

6 months ago

0.20.0

7 months ago

0.19.1

7 months ago

0.19.0

7 months ago

0.18.0

7 months ago

0.17.0

7 months ago

0.16.0

7 months ago

0.15.0

8 months ago

0.14.5

8 months ago

0.14.4

8 months ago

0.14.3

8 months ago

0.14.2

8 months ago

0.14.0

8 months ago

0.13.0

8 months ago

0.12.11

8 months ago

0.12.10

8 months ago

0.12.9

8 months ago

0.12.8

8 months ago

0.12.7

8 months ago

0.12.6

8 months ago

0.12.5

8 months ago

0.12.4

8 months ago

0.12.3

8 months ago

0.12.2

8 months ago

0.12.1

8 months ago

0.12.0

8 months ago

0.11.3

8 months ago

0.11.2

8 months ago

0.11.1

8 months ago

0.10.2

8 months ago

0.10.0

8 months ago

0.9.0

8 months ago

0.8.2

8 months ago

0.8.1

8 months ago

0.8.0

8 months ago

0.7.0

8 months ago

0.6.0

8 months ago

0.5.1

8 months ago

0.5.0

8 months ago

0.4.0

8 months ago

0.3.1

8 months ago

0.3.0

8 months ago

0.2.0

8 months ago