Skip to content

Node.js API

Node APIは、動的に生成されたスキーマを扱う場合や、より大きなアプリケーションのコンテキスト内で使用する場合に役立ちます。メモリからスキーマをロードするためにJSONフレンドリーなオブジェクトを渡すか、ローカルファイルやリモートURLからスキーマをロードするために文字列を渡します。

セットアップ

bash
npm i --save-dev openapi-typescript typescript

推奨

最適な体験を得るために、 "type": "module"package.json に追加して Node ESM を使用してください(ドキュメント)

使用方法

Node.js APIは、URLstring、またはJSONオブジェクトを入力として受け付けます:

タイプ説明
URLローカルまたはリモートファイルを読み取るawait openapiTS(new URL('./schema.yaml', import.meta.url))
await openapiTS(new URL('https://myapi.com/v1/openapi.yaml'))
string動的なYAMLまたはJSONを読み取るawait openapiTS('openapi: "3.1" … ')
JSON動的なJSONを読み取るawait openapiTS({ openapi: '3.1', … })

また、 Readable ストリームやBuffer 型も受け付け、これらは文字列として解決されます(ドキュメント全体がないと検証、バンドル、型生成ができません)。

Node APIはTypeScript の AST を含む Promise を返します。その後、必要に応じてASTをトラバース、操作、または修正できます。

TypeScript ASTを文字列に変換するには、TypeScriptのprinterのラッパーである astToString() ヘルパーを使用できます:

ts
import fs from "node:fs";
import openapiTS, { astToString } from "openapi-typescript";

const ast = await openapiTS(new URL("./my-schema.yaml", import.meta.url));
const contents = astToString(ast);

// (任意)ファイルに書き込み
fs.writeFileSync("./my-schema.ts", contents);

Redoc config

Redoc configはopenapi-typescriptを使用するために必須ではありません。デフォルトでは "minimal" ビルトイン設定を拡張しますが、デフォルト設定を変更したい場合は、完全に初期化されたRedoc configをNode APIに提供する必要があります。これを行うには、@redocly/openapi-core のヘルパーを使用できます:

ts
import { createConfig, loadConfig } from "@redocly/openapi-core";
import openapiTS from "openapi-typescript";

// オプション1: インメモリ設定を作成
const redocly = await createConfig(
  {
    apis: {
      "core@v2": { … },
      "external@v1": { … },
    },
  },
  { extends: ["recommended"] },
);

// オプション2: redocly.yamlファイルから読み込み
const redocly = await loadConfig({ configPath: "redocly.yaml" });

const ast = await openapiTS(mySchema, { redocly });

オプション

Node APIは、 camelCase 形式でCLI フラグ すべてをサポートしており、以下の追加オプションも利用可能です:

名前タイプデフォルト説明
transformFunction特定の状況でデフォルトのスキーマオブジェクトをTypeScriptにするトランスフォーマーを上書きする
postTransformFunctiontransform と同じだが、TypeScript変換後に実行される
silentbooleanfalse警告メッセージを非表示にする(致命的なエラーは表示されます)
cwdstring | URLprocess.cwd()(オプション)必要に応じてリモート$refの解決を支援するために現在の作業ディレクトリを指定
injectstringファイルの先頭に任意のTypeScript型を注入

transform / postTransform

transform()postTransform() オプションを使用して、デフォルトのスキーマオブジェクト変換を独自のものに上書きできます。これは、スキーマの特定の部分に対して非標準的な変更を提供する場合に役立ちます。

  • transform() はTypeScriptへの 変換前 に実行されます(OpenAPIノードを扱います)
  • postTransform() はTypeScriptへの 変換後 に実行されます(TypeScript ASTを扱います)

例: Date

例えば、スキーマに次のプロパティが含まれているとします:

yaml
properties:
  updated_at:
    type: string
    format: date-time

デフォルトでは、openapiTSはupdated_at?: string;を生成します。これは、"date-time"がどのフォーマットを意味するのかが明確でないためです(フォーマットは標準化されておらず、任意の形式にできるため)。しかし、独自のカスタムフォーマッタを提供することで、これを改善できます。例えば次のようにします:

ts
import openapiTS from "openapi-typescript";
import ts from "typescript";

const DATE = ts.factory.createTypeReferenceNode(
  ts.factory.createIdentifier("Date")
); // `Date`
const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull()); // `null`

const ast = await openapiTS(mySchema, {
  transform(schemaObject, metadata) {
    if (schemaObject.format === "date-time") {
      return schemaObject.nullable
        ? ts.factory.createUnionTypeNode([DATE, NULL])
        : DATE;
    }
  },
});

その結果、以下のようになります:

yaml
updated_at?: string;
updated_at: Date | null;

例: Blob

もう一つの一般的な変換は、リクエストの bodymultipart/form-data で、いくつかの Blob フィールドを持つファイルアップロードの場合です。例えば次のようなスキーマがあります

yaml
Body_file_upload:
  type: object;
  properties:
    file:
      type: string;
      format: binary;

同じパターンを使用して型を変換します:

ts
import openapiTS from "openapi-typescript";
import ts from "typescript";

const BLOB = ts.factory.createTypeReferenceNode(
  ts.factory.createIdentifier("Blob")
); // `Blob`
const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull()); // `null`

const ast = await openapiTS(mySchema, {
  transform(schemaObject, metadata) {
    if (schemaObject.format === "binary") {
      return schemaObject.nullable
        ? ts.factory.createUnionTypeNode([BLOB, NULL])
        : BLOB;
    }
  },
});

fileプロパティが正しく型付けされた差分は次のようになります:

ts
file?: string; 
file: Blob | null; 

例: プロパティに "?" トークンを追加

上記の transform 関数では、オプションの"?"トークンを持つプロパティを作成することはできません。しかし、transform関数は異なる戻りオブジェクトを受け入れることもでき、これを使用してプロパティに”?“トークンを追加することができます。以下はその例です:

yaml
Body_file_upload:
  type: object;
  properties:
    file:
      type: string;
      format: binary;
      required: true;

ここではスキーマプロパティを持つオブジェクトを返しますが、これに加えて questionToken プロパティを追加し、プロパティに"?"トークンを追加します。

ts
import openapiTS from "openapi-typescript";
import ts from "typescript";

const BLOB = ts.factory.createTypeReferenceNode(
  ts.factory.createIdentifier("Blob")
); // `Blob`
const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull()); // `null`

const ast = await openapiTS(mySchema, {
  transform(schemaObject, metadata) {
    if (schemaObject.format === "binary") {
      return {
        schema: schemaObject.nullable
          ? ts.factory.createUnionTypeNode([BLOB, NULL])
          : BLOB,
        questionToken: true,
      };
    }
  },
});

file プロパティが正しく型付けされ、"?"トークンが追加された結果の差分は次のとおりです:

ts
file: Blob; 
file?: Blob | null; 

スキーマ内の任意のSchema Objectは、このフォーマッタを通じて処理されます(リモートのものも含まれます!)。また、追加のコンテキストが役立つ場合があるので、metadata パラメータも必ず確認してください。

formatのチェック以外にも、これを利用する方法は多数あります。この関数は string を返す必要があるため、任意のTypeScriptコード(独自のカスタム型も含む)を生成することができます。