Prisma スキーマを利用したローカル開発
GASsma は clasp+esbuild 等を利用し TypeScript を使ってローカルで GAS を開発する際に、Prisma 形式のスキーマファイルから型安全なクライアントコードを自動生成する機能を提供しています。
この機能を利用すると、リレーション定義や defaults・map 等の設定がスキーマから自動生成されるため、GASsma 独自のコンストラクタオプション(relations、defaults、updatedAt、ignore、map など)を手動で記述する必要がなくなります。Prisma のスキーマ構文さえ知っていれば、Prisma と同じ感覚で開発を始められます。
CLI なし(手動設定):
import { Gassma } from "gassma";
const gassma = new Gassma.GassmaClient({
id: "SPREAD_SHEET_ID",
relations: {
User: {
posts: { type: "oneToMany", to: "Post", field: "id", reference: "authorId", onDelete: "Cascade" },
},
Post: {
author: { type: "manyToOne", to: "User", field: "authorId", reference: "id" },
},
},
defaults: { User: { role: "USER" } },
updatedAt: { Post: "updatedAt" },
map: { User: { firstName: "名前" } },
});
CLI あり(スキーマから自動生成):
import { GassmaClient } from "./generated/gassma/schemaClient";
// リレーション・defaults・updatedAt・map 等すべて自動注入済み
const gassma = new GassmaClient();
前提
以下のコマンドで GASsma の CLI ツールをインストールしてください。
$ npm i gassma
スキーマファイルの作成
プロジェクト内に .prisma ファイルを作成します。デフォルトでは ./gassma ディレクトリ配下が探索されます。
my-project/
├── gassma/
│ └── schema.prisma ← ここにスキーマを記述
├── package.json
└── ...
基本的な書き方
Prisma の文法でモデルを定義します。generator ブロックの output で出力先を指定してください。
generator client {
provider = "prisma-client-js"
output = "./generated/gassma"
}
model User {
id Int @id
name String
email String?
age Int
}
型マッピング
Prisma の型は以下の TypeScript 型に変換されます。
| Prisma 型 | TypeScript 型 |
|---|---|
Int | number |
Float | number |
Decimal | number |
BigInt | number |
String | string |
Boolean | boolean |
DateTime | Date |
Json | string |
Bytes | string |
? を付けるとオプショナルフィールドになります(null が許容されます)。
リレーション定義
Prisma の @relation 属性を使うと、リレーション情報が自動的に抽出され、生成されたクライアントに注入されます。
generator client {
provider = "prisma-client-js"
output = "./generated/gassma"
}
model User {
id Int @id
name String
posts Post[]
}
model Post {
id Int @id
title String
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId Int
}
上記の定義から以下のリレーション設定が自動生成されます。
User.posts: oneToMany(User → Post)Post.author: manyToOne(Post → User、onDelete: Cascade)
暗黙的 Many-to-Many
双方向の配列参照がある場合、暗黙的な Many-to-Many リレーションが自動検出されます。
model Post {
id Int @id
tags Tag[]
}
model Tag {
id Int @id
name String
posts Post[]
}
生成されるクライアントでは、中間テーブル名が _PostToTag(アルファベット順)として自動的に解決されます。
中間テーブル(シート)自体は自動作成されません。スプレッドシート側に _PostToTag という名前のシートを手動で用意する必要があります。
中間テーブル名を変更したい場合は、生成された Client.js 内のリレーション定義を直接編集してください。
enum
Prisma の enum 定義からリテラルユニオン型が自動生成されます。
enum Role {
ADMIN
USER
MODERATOR
}
model User {
id Int @id
role Role
}
生成される型:
"role": "ADMIN" | "USER" | "MODERATOR"
enum の @map
enum メンバーに @map を付けると、コード上の名前とスプレッドシート上の値をマッピングできます。
enum Role {
admin @map("ADMIN")
user @map("USER")
moderator @map("MODERATOR")
}
生成される定数:
const Role = {
admin: "ADMIN",
user: "USER",
moderator: "MODERATOR",
} as const;
型定義には @map の値が使用されます:
"role": "ADMIN" | "USER" | "MODERATOR"
@gassma.addType
Prisma のフィールドコメント(///)に @gassma.addType を記述すると、フィールドの型にユニオン型を追加できます。
model User {
/// @gassma.addType string
id Int @id // 生成型: number | string
/// @gassma.addType string, boolean
score Int // 生成型: number | string | boolean
name String // 生成型: string(コメントなしなら通常通り)
}
@gassma.replaceType
@gassma.addType は基底型とのユニオンですが、@gassma.replaceType は基底型を置換して指定した型のみ生成します。
model User {
/// @gassma.replaceType "admin", "user", "moderator"
role String
}
生成される型:
"role": "admin" | "user" | "moderator" // string を含まない
優先順位: enum > replaceType > addType。enum がある場合は replaceType / addType は無視されます。
@default
@default() が付いたフィールドは、生成される Create 入力型でオプショナル(?)になります。
model User {
id Int @id @default(autoincrement())
name String
isActive Boolean @default(true)
createdAt DateTime @default(now())
}
生成される型:
"isActive"?: boolean // @default(true) → オプショナル
"createdAt"?: Date // @default(now()) → オプショナル
生成されるクライアント JS には defaults 設定が自動的に埋め込まれます。
@default() | 生成される JS |
|---|---|
@default(true) / @default(false) | true / false |
@default(0) (数値) | 0 |
@default("USER") (文字列) | "USER" |
@default(now()) | () => new Date() |
@default(uuid()) | () => Utilities.getUuid() |
@default(autoincrement()) | autoincrement 設定として別途生成 |
@updatedAt
@updatedAt が付いたフィールドは Create 入力型でオプショナルになり、生成されるクライアント JS に updatedAt 設定が埋め込まれます。
model Post {
id Int @id
title String
updatedAt DateTime @updatedAt
}
@ignore
@ignore が付いたフィールドは型定義から完全に除外され、生成されるクライアント JS に ignore 設定が埋め込まれます。
model User {
id Int @id
name String
secret String @ignore // 型定義に含まれない
}
@map
@map("name") でフィールド名のマッピングを定義できます。生成されるクライアント JS に map 設定が埋め込まれます。
model User {
id Int @id
firstName String @map("名前")
lastName String @map("名字")
}
コード上は firstName / lastName で操作し、スプレッドシート上は「名前」「名字」カラムに対応します。
@@ignore
モデルレベルの @@ignore でシート全体を除外できます。生成されるクライアント JS に ignoreSheets 設定が埋め込まれます。
model Logs {
id Int @id
message String
@@ignore
}
@@map
モデルレベルの @@map("name") でシート名をマッピングできます。
model Users {
id Int @id
name String
@@map("ユーザー一覧")
}
コード上は Users でアクセスし、スプレッドシート上は「ユーザー一覧」シートに対応します。
CLI コマンド
gassma generate
型ファイルとクライアントコードを生成します。
$ npx gassma generate
デフォルトでは ./gassma ディレクトリ内の .prisma ファイルが探索されます。--schema オプションで特定のスキーマファイルまたはディレクトリを指定できます(Prisma の prisma generate --schema に相当)。
$ npx gassma generate --schema gassma/user.prisma
$ npx gassma generate --schema ./schemas
--watch オプションでスキーマファイルの変更を監視し、自動で再生成できます。
$ npx gassma generate --watch
--schema との併用も可能です。
gassma init
プロジェクトを初期化し、スキーマファイルと設定ファイルを自動生成します。
$ npx gassma init
以下のファイルが生成されます:
gassma/schema.prisma— 初期スキーマgassma.config.ts— 設定ファイル
| オプション | 説明 |
|---|---|
--output <path> | 生成先パスをカスタマイズ |
--with-model | サンプル User モデルを含むスキーマを生成 |
既に schema.prisma が存在する場合はエラーで安全に停止します。
gassma validate
スキーマファイルの構文チェック・整合性チェックを行います(Prisma の prisma validate に相当)。
$ npx gassma validate
$ npx gassma validate --schema gassma/test.prisma
チェック項目:
- 構文エラー(パーサーエラー検出)
generatorブロックの存在チェックoutputフィールドの必須チェック
成功時は以下のように出力されます:
The schema at /path/to/gassma/test.prisma is valid 🚀
gassma format
.prisma ファイルを Prisma 公式と同じフォーマットで整形します(@prisma/internals の formatSchema を使用)。
$ npx gassma format
| オプション | 説明 |
|---|---|
--schema <path> | 特定ファイルのみ整形 |
--check | フォーマット済みかチェック(CI 用、未整形時は exit 1) |
gassma version
GASsma CLI のバージョンを表示します。
$ npx gassma version
--version / -V フラグでも確認できます。
生成されるファイル
スキーマファイル名をもとに以下のファイルが生成されます。例えば schema.prisma の場合:
| ファイル | 内容 |
|---|---|
schema.d.ts | 型定義(モデル型、クエリ型、共通型) |
schemaClient.js | クライアント実装(リレーション定義の自動注入込み) |
schemaClient.d.ts | クライアントの型定義 |
出力先は generator ブロックの output で指定したディレクトリです。
生成されたクライアントの使い方
生成されたクライアントファイルから GassmaClient をインポートしてそのまま使えます。リレーション定義は自動注入済みです。
import { GassmaClient } from "./generated/gassma/schemaClient";
const gassma = new GassmaClient();
// 型安全にシートへアクセス
const users = gassma.User.findMany({
where: { age: { gte: 20 } },
select: { name: true, email: true },
});
Prisma と同じパターンでインスタンス化できます。
// Prisma
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// GASsma(同じパターン)
import { GassmaClient } from "./generated/gassma/schemaClient";
const gassma = new GassmaClient();
オプション付きの初期化
// スプレッドシートID指定
const gassma = new GassmaClient("SPREAD_SHEET_ID");
// オプションオブジェクト
const gassma = new GassmaClient({
id: "SPREAD_SHEET_ID",
omit: {
User: { password: true },
},
});
設定ファイル(gassma.config.ts)
プロジェクトルートに gassma.config.ts を配置することで、CLI の設定を一元管理できます(Prisma の prisma.config.ts に相当)。
設定インターフェース
設定ファイルの記述方法は 2 つあります。
1. defineConfig ヘルパーを使用(推奨):
import { defineConfig } from "gassma/config";
export default defineConfig({
schema: "gassma/schema.prisma",
datasource: {
url: "https://docs.google.com/spreadsheets/d/XXXXX/edit",
},
});
2. satisfies 演算子を使用:
import type { GassmaConfig } from "gassma";
export default {
schema: "gassma/schema.prisma",
datasource: {
url: "https://docs.google.com/spreadsheets/d/XXXXX/edit",
},
} satisfies GassmaConfig;
GassmaConfig 型は gassma パッケージのルートから import できます。
設定オプション
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
schema | string | いいえ | スキーマファイルまたはディレクトリのパス(デフォルト: ./gassma) |
datasource.url | string | いいえ | スプレッドシートの URL または ID |
env() ヘルパー
env() 関数を使うと、環境変数からスプレッドシート URL を取得できます(Prisma の env() に相当)。
import "dotenv/config";
import { defineConfig, env } from "gassma/config";
export default defineConfig({
schema: "gassma",
datasource: {
url: env("SPREADSHEET_URL"),
},
});
satisfies パターンでも使用できます。
import "dotenv/config";
import type { GassmaConfig } from "gassma";
import { env } from "gassma/config";
export default {
schema: "gassma",
datasource: {
url: env("SPREADSHEET_URL"),
},
} satisfies GassmaConfig;
env() は環境変数が未設定または空文字の場合にエラーをスローします。オプショナルな環境変数には process.env を直接使用してください。
datasource.url
datasource.url にスプレッドシートの URL または ID を指定すると、生成されるクライアント JS に id が自動埋め込みされます。これにより new GassmaClient() だけで対象スプレッドシートに接続できます。
フル URL とスプレッドシート ID の両方に対応しています。
// フル URL
datasource: {
url: "https://docs.google.com/spreadsheets/d/XXXXX/edit",
}
// ID 直接指定
datasource: {
url: "XXXXX",
}
スキーマ内の datasource ブロック
スキーマファイル内に datasource ブロックを記述することでも URL を指定できます。
datasource db {
provider = "google-spreadsheet"
url = "https://docs.google.com/spreadsheets/d/XXXXX/edit"
}
URL 解決の優先順位
- スキーマ内の
datasourceブロック(最優先) gassma.config.tsのdatasource.url
スキーマ解決の優先順位
--schemaオプション(最優先)gassma.config.tsのschema設定- デフォルト
./gassmaディレクトリ
gassma init を実行すると gassma.config.ts も自動生成されます。
マルチファイルスキーマ
同じディレクトリ(およびサブディレクトリ)内に複数の .prisma ファイルを配置すると、自動的に 1 つのスキーマとして統合 されます。Prisma の Multi-file schema と同等の機能です。
gassma/
├── schema.prisma ← generator ブロックをここに記述
├── models/
│ ├── user.prisma ← User, Profile モデル
│ └── post.prisma ← Post, Comment モデル
generator ブロックはいずれか 1 ファイルに記述すれば、全ファイルで共有されます。すべてのモデルが 1 つのクライアント出力にまとめられます。
複数スキーマ(複数スプレッドシート)
異なるスプレッドシートを扱う場合は、スキーマを別々のディレクトリに分けて個別に生成します。型名にはスキーマ名のプレフィックスが付与されるため、同名モデルがあっても衝突しません。
schemas/
├── user/
│ └── schema.prisma → userClient.js, user.d.ts
└── order/
└── schema.prisma → orderClient.js, order.d.ts
import { GassmaClient as UserClient } from "./generated/user/schemaClient";
import { GassmaClient as OrderClient } from "./generated/order/schemaClient";
const userGassma = new UserClient();
const orderGassma = new OrderClient();
生成される型の概要
生成される .d.ts には以下の型が含まれます。
- モデル型: 各フィールドの型定義(
GassmaUserUse等) - クエリ型:
FindData、CreateData、UpdateData、DeleteData、UpsertData等 - Select / Omit 型: フィールド選択・除外の型
- フィルタ型:
WhereUse、FilterConditions(FieldRef対応含む) - OrderBy 型: ソート条件(リレーションソート、
_countソート、nulls 制御含む) - Include 型: リレーション取得の型(
_count含む) - Nested Write 型: リレーション先の作成・接続・更新・削除操作
- 数値操作型:
NumberOperation(increment / decrement / multiply / divide) - 共通型:
FieldRef、GassmaClientOptions、エラークラス群 - 設定型:
DefaultsConfig、UpdatedAtConfig、IgnoreConfig、AutoincrementConfig、MapConfig等 - コントローラー型: 全メソッドの引数・戻り値型