記事「RESTfulAPIで受け取るJSONの型定義を考えてみる」を書いて3年経過してしまいましたが、JSONのTypeScript型定義を自動生成するツールを書いてみました。3年前の内容をベースにし、PowerCMS Xのschemeエンドポイントからモデルの構造を取得して各カラムの型を判定し、ファイルに出力するものです。
全てのカラムを出力する場合
例えばgetエンドポイントで記事オブジェクトを取得する時、cols
パラメータを指定しなければ全てのカラムが含まれた状態でレスポンスが返ってきます。よって、node index.js entry
を実行すると(いずれはパッケージ化したい)以下のような型定義が得られます。
type Entry = {
id: number;
title: string;
text: string;
text_format: string;
assets: Asset[];
text_more: string;
excerpt: string;
keywords: string;
categories: Category[];
tags: Tag[];
extra_path: string;
basename: string;
user_id: User;
previous_owner: number;
allow_comment: boolean;
workspace_id: number;
uuid: string;
attachmentfiles: Attachmentfile[];
og_image: Binary;
page_view: number;
double_check: number;
related_event: Event;
} & StatusType & DateType & RevisionType & AuditType;
StatusType
やAuditType
はPowerCMS Xでモデルを作成する際のオプション「ステータス対応・有効期限対応」「自動監査」を反映したものです。オプションを選択することで決まったカラムがモデルに追加されるため、独自の定義にまとめました。StatusType
は取り得る値も決まっているので、下記のような定義になっています。
export type StatusType = {
status: 0 | 1 | 2 | 3 | 4 | 5;
}
編集タイプが「リレーション」、つまり他のモデルのオブジェクトを選択するカラムの型はCategory[]
のように定義しています。よって、記事モデルの型定義と同時にカテゴリモデルの型定義も生成した方が良いか?と検討しているところです。
colsパラメータを指定した時
cols
パラメータを指定してgetエンドポイントにアクセスすると、レスポンスには選択したカラムのみ含まれるようになります。よって、node index.js entry --cols id,title,text,assets,related_event
を実行すると以下のような型定義が得られます。
type Entry = {
id: number;
title: string;
text: string;
assets: AssetSummary[];
related_event: EventSummary;
};
type AssetSummary = {
id: number;
label: string;
file: Binary;
workspace_id: number;
};
type EventSummary = {
id: number;
name: string;
workspace_id: number;
};
cols
パラメータを指定した場合はリレーション(単一選択・複数選択とも)の出力内容も限定的になるので、AssetSummary
のような定義を同時に出力しています。
課題
カラムの設定ではNullを許容しているけれど、CMSで入力を行えばnull
になることはないカラムの型をどうするか?と考えています。(string | null
のような定義が多発するのもどうかなと。)また、アセットのURLを格納したPermalink
等、カラムが存在しないがレスポンスには含まれるフィールドの出力も検討中です。
ツールの公開
GitHubの「hideki-a/powercmsx-typescript」にて暫定公開しています。