@gasboost/vite 0.1.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 gasboost
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # @gasboost/vite
2
2
 
3
- `@gasboost/app` で構築したアプリケーションを Google Apps Script 向けにビルドするための Vite プラグインです。
3
+ `@gasboost/app` で構築した Google Apps Script アプリケーションを、Vite でビルド・ローカル開発するためのプラグインです。
4
4
 
5
- アプリケーションの entry file を静的解析し、`AppsScript` に登録されたハンドラを検出して、Google Apps Script が認識するためのグローバル関数宣言を生成します。
5
+ `@gasboost/vite` は用途ごとに2つの Vite Plugin を提供します。
6
+
7
+ - `build` — Google Apps Script 向けの production build
8
+ - `dev` — ローカル開発時の RPC 実行
6
9
 
7
10
  ## インストール
8
11
 
@@ -18,119 +21,175 @@ npm install @gasboost/app
18
21
  npm install -D @gasboost/vite vite
19
22
  ```
20
23
 
21
- ## 使い方
24
+ ## Quick Start
22
25
 
23
- まず通常の Gasboost アプリケーションを作成します。
26
+ まず `@gasboost/app` でバックエンドを定義します。
24
27
 
25
28
  ```ts
26
- // src/main.ts
29
+ // src/server.ts
27
30
 
28
31
  import { AppsScript } from "@gasboost/app";
29
32
 
30
33
  const app = new AppsScript()
31
- .get((request) => {
34
+ .get(() => {
32
35
  return HtmlService.createHtmlOutput("Hello");
33
36
  })
34
37
  .post((request) => {
35
38
  return ContentService.createTextOutput(request.text());
36
39
  })
37
- .call("sum", (a: number, b: number) => a + b);
40
+ .call("sum", (a: number, b: number) => a + b)
41
+ .call("getUser", async (id: string) => ({
42
+ id,
43
+ name: "Taro",
44
+ }));
38
45
 
39
46
  export default app;
40
47
  ```
41
48
 
42
- Vite を設定します。
49
+ `gasboost()` から `build` と `dev` を取得し、1つの `vite.config.ts` の中で mode に応じて使い分けます。
50
+
51
+ frontend と backend は成果物と build graph が異なるため、同時に1つの Vite build へ混在させません。
43
52
 
44
53
  ```ts
45
54
  // vite.config.ts
46
55
 
56
+ import react from "@vitejs/plugin-react";
47
57
  import { defineConfig } from "vite";
58
+ import { viteSingleFile } from "vite-plugin-singlefile";
48
59
  import { gasboost } from "@gasboost/vite";
49
60
 
50
- export default defineConfig({
51
- plugins: [
52
- gasboost({
53
- entry: "src/main.ts",
54
- }),
55
- ],
61
+ const { build, dev } = gasboost({
62
+ entry: "src/server.ts",
63
+ envDir: ".env",
56
64
  });
57
- ```
58
65
 
59
- 通常通りビルドできます。
66
+ export default defineConfig(({ mode }) => {
67
+ if (mode === "server") {
68
+ return {
69
+ plugins: [build],
70
+ build: {
71
+ outDir: "dist",
72
+ emptyOutDir: false,
73
+ },
74
+ };
75
+ }
76
+
77
+ return {
78
+ plugins: [react(), viteSingleFile(), dev],
79
+ build: {
80
+ outDir: "dist",
81
+ },
82
+ };
83
+ });
84
+ ```
60
85
 
61
- ```bash
62
- vite build
86
+ この例では、frontend build と backend build を mode で分離します。
87
+
88
+ ```json
89
+ {
90
+ "scripts": {
91
+ "dev": "vite",
92
+ "build:client": "vite build --mode client",
93
+ "build:server": "vite build --mode server",
94
+ "build": "pnpm build:client && pnpm build:server"
95
+ }
96
+ }
63
97
  ```
64
98
 
65
- ## オプション
99
+ ```text
100
+ vite
101
+
102
+ gasboost:dev
66
103
 
67
- ### `entry`
104
+ vite build --mode client
105
+
106
+ frontend build
68
107
 
69
- 必須です。
108
+ vite build --mode server
109
+
110
+ gasboost:build
111
+ ```
112
+
113
+ frontend 側の React、single-file 化などの設定は利用側プロジェクトの責務です。
70
114
 
71
- `AppsScript` アプリケーションを定義している entry file のパスを指定します。
115
+ ## gasboost()
72
116
 
73
117
  ```ts
74
- gasboost({
75
- entry: "src/main.ts",
118
+ const { build, dev } = gasboost({
119
+ entry: "src/server.ts",
120
+ envDir: "config",
76
121
  });
77
122
  ```
78
123
 
79
- entry file には1つの `AppsScript` インスタンスを定義し、そのインスタンスを default export する必要があります。
124
+ 戻り値:
80
125
 
81
126
  ```ts
82
- const app = new AppsScript();
83
-
84
- export default app;
127
+ {
128
+ build: Plugin;
129
+ dev: Plugin;
130
+ }
85
131
  ```
86
132
 
87
- チェーン形式の登録に対応しています。
88
-
89
- ```ts
90
- const app = new AppsScript()
91
- .get(...)
92
- .post(...)
93
- .call("getUser", ...);
133
+ ### `entry`
94
134
 
95
- export default app;
96
- ```
135
+ 必須です。
97
136
 
98
- インスタンス生成後に登録する形式にも対応しています。
137
+ `AppsScript` を定義して default export している entry file を指定します。
99
138
 
100
139
  ```ts
101
- const app = new AppsScript();
102
-
103
- app.get(...);
104
- app.call("getUser", ...);
105
-
106
- export default app;
140
+ gasboost({
141
+ entry: "src/server.ts",
142
+ });
107
143
  ```
108
144
 
109
145
  ### `envDir`
110
146
 
111
147
  任意です。
112
148
 
113
- Vite が環境変数ファイルを読み込むディレクトリを指定します。
149
+ build 時に Vite が環境変数ファイルを読み込むディレクトリを指定します。
114
150
 
115
151
  ```ts
116
152
  gasboost({
117
- entry: "src/main.ts",
153
+ entry: "src/server.ts",
118
154
  envDir: "config",
119
155
  });
120
156
  ```
121
157
 
122
- 例えば以下の構成を利用できます。
158
+ ---
123
159
 
124
- ```text
125
- config/
126
- ├── .env
127
- ├── .env.development
128
- └── .env.production
160
+ # Build Plugin
161
+
162
+ `build` は `vite build` のときだけ動作し、GAS backend build を担当します。
163
+
164
+ frontend / backend を同じ `vite.config.ts` で扱う場合は、server 用 mode のときだけ `plugins` に含めてください。
165
+
166
+ ```ts
167
+ const { build } = gasboost({
168
+ entry: "src/server.ts",
169
+ });
170
+
171
+ export default defineConfig(({ mode }) => {
172
+ if (mode === "server") {
173
+ return {
174
+ plugins: [build],
175
+ };
176
+ }
177
+
178
+ return {
179
+ plugins: [],
180
+ };
181
+ });
129
182
  ```
130
183
 
131
- ## 生成されるグローバル関数
184
+ `build` plugin は次の処理を担当します。
132
185
 
133
- Google Apps Script はトップレベルのグローバル関数を entry point として認識します。
186
+ - entry file の静的解析
187
+ - `AppsScript` に登録された GET / POST / RPC の検出
188
+ - GAS が認識するグローバル関数宣言の生成
189
+ - GAS 向け Vite build configuration
190
+ - 環境変数の読み込み
191
+
192
+ ## グローバル関数の生成
134
193
 
135
194
  例えば次のアプリケーションを定義した場合:
136
195
 
@@ -144,7 +203,7 @@ const app = new AppsScript()
144
203
  export default app;
145
204
  ```
146
205
 
147
- ビルド結果には以下に対応するグローバル関数宣言が生成されます。
206
+ build plugin は GAS が認識するためのグローバル関数宣言を生成します。
148
207
 
149
208
  ```js
150
209
  function doGet() {}
@@ -153,56 +212,51 @@ function getUser() {}
153
212
  function sum() {}
154
213
  ```
155
214
 
156
- これらの宣言は Google Apps Script に関数名を認識させるためのものです。
157
-
158
- 実際の dispatch 処理は行いません。
159
-
160
- ハンドラの実体は `@gasboost/app` がランタイム上で登録します。
215
+ これらは関数名を Google Apps Script に認識させるための宣言です。
161
216
 
162
- 責務は次のように分離されています。
217
+ 実際のハンドラ登録と dispatch は `@gasboost/app` がランタイム上で行います。
163
218
 
164
219
  ```text
165
- @gasboost/app
166
- runtime registration
167
- handler dispatch
168
- globalThis implementation
169
-
170
220
  @gasboost/vite
171
221
  static analysis
172
- GAS build configuration
173
222
  global function declarations
223
+
224
+ @gasboost/app
225
+ runtime registration
226
+ dispatch
174
227
  ```
175
228
 
176
229
  ## 静的解析
177
230
 
178
- プラグインは指定された entry file を静的解析します。
179
-
180
- 対象となる `AppsScript` インスタンスに対する登録を検出します。
231
+ entry file には1つの `AppsScript` インスタンスを定義し、default export します。
181
232
 
182
233
  ```ts
234
+ const app = new AppsScript();
235
+
183
236
  app.get(...);
184
- app.post(...);
185
237
  app.call("getUser", ...);
238
+
239
+ export default app;
186
240
  ```
187
241
 
188
- 別オブジェクトの同名メソッドは無視されます。
242
+ チェーン形式にも対応しています。
189
243
 
190
244
  ```ts
191
- other.get(...);
192
- other.call("something", ...);
193
- ```
245
+ const app = new AppsScript()
246
+ .get(...)
247
+ .post(...)
248
+ .call("getUser", ...);
194
249
 
195
- ### RPC
250
+ export default app;
251
+ ```
196
252
 
197
253
  RPC 名は文字列リテラルで指定する必要があります。
198
254
 
199
- 対応:
200
-
201
255
  ```ts
202
256
  app.call("getUser", handler);
203
257
  ```
204
258
 
205
- 非対応:
259
+ 次のような動的な名前は静的解析の対象外です。
206
260
 
207
261
  ```ts
208
262
  const name = "getUser";
@@ -210,123 +264,390 @@ const name = "getUser";
210
264
  app.call(name, handler);
211
265
  ```
212
266
 
213
- ビルド時に生成する GAS グローバル関数名を静的に確定するため、この制約があります。
267
+ build 時に GAS のグローバル関数名を確定する必要があるためです。
214
268
 
215
- ### 重複登録
269
+ ## 検証
216
270
 
217
- 以下の曖昧な登録はエラーになります。
271
+ 静的解析時には、曖昧なアプリケーション定義をエラーとして扱います。
218
272
 
219
273
  - GET ハンドラの重複
220
274
  - POST ハンドラの重複
221
275
  - RPC 名の重複
222
- - entry 内に複数の `AppsScript` インスタンスが存在する場合
223
-
224
- `AppsScript` インスタンスは default export されている必要があります。
225
-
226
- ## GAS 向けビルド設定
276
+ - entry 内の複数 `AppsScript` インスタンス
277
+ - default export されていない `AppsScript`
227
278
 
228
- `gasboost()` Google Apps Script 向けの Vite build configuration を提供します。
279
+ ## GAS 向け build configuration
229
280
 
230
- 現在は以下の設定を利用します。
281
+ 現在の build 設定:
231
282
 
232
283
  - target: ECMAScript 2019
233
284
  - output format: CommonJS
234
285
  - output directory: `dist`
235
- - `entry` で指定されたファイルを build input として利用
236
-
237
- 利用側の Vite config で GAS 固有の build setting を重複して定義する必要はありません。
286
+ - `entry` build input として利用
238
287
 
239
288
  ## 環境変数
240
289
 
241
- 環境変数は Vite 標準の仕組みを利用します。
242
-
243
- 例えば:
290
+ Vite 標準の環境変数機構を利用します。
244
291
 
245
292
  ```text
246
- config/.env
247
- ```
248
-
249
- ```env
250
- VITE_API_URL=https://example.com
293
+ config/
294
+ ├── .env
295
+ ├── .env.development
296
+ └── .env.production
251
297
  ```
252
298
 
253
- `envDir` を設定します。
254
-
255
299
  ```ts
256
- gasboost({
257
- entry: "src/main.ts",
300
+ const { build } = gasboost({
301
+ entry: "src/server.ts",
258
302
  envDir: "config",
259
303
  });
260
304
  ```
261
305
 
262
- アプリケーションから通常通り参照できます。
306
+ アプリケーションでは通常の Vite と同様に参照できます。
263
307
 
264
308
  ```ts
265
309
  const apiUrl = import.meta.env.VITE_API_URL;
266
310
  ```
267
311
 
268
- mode ごとの環境変数ファイルにも対応します。
312
+ ---
269
313
 
270
- ```bash
271
- vite build --mode production
314
+ # Dev Plugin
315
+
316
+ `dev` は Vite Dev Server 上でのみ動作します。
317
+
318
+ frontend の開発用 Vite config に追加して利用します。
319
+
320
+ ```ts
321
+ const { dev } = gasboost({
322
+ entry: "src/server.ts",
323
+ });
324
+
325
+ export default defineConfig({
326
+ plugins: [dev],
327
+ });
272
328
  ```
273
329
 
274
- `envDir: "config"` の場合、例えば以下が読み込まれます。
330
+ `dev` plugin は、GAS にデプロイしなくてもローカル環境から `AppsScript` の RPC を実行できるエンドポイントを Vite Dev Server に追加します。
331
+
332
+ ## Local RPC
333
+
334
+ ローカル RPC のエンドポイントは次の形式です。
275
335
 
276
336
  ```text
277
- config/.env.production
337
+ POST /__gasboost/{rpcName}
338
+ ```
339
+
340
+ 例えば、
341
+
342
+ ```ts
343
+ const app = new AppsScript().call("sum", (a: number, b: number) => a + b);
344
+
345
+ export default app;
346
+ ```
347
+
348
+ に対して、
349
+
350
+ ```http
351
+ POST /__gasboost/sum
352
+ Content-Type: application/json
353
+ ```
354
+
355
+ ```json
356
+ {
357
+ "args": [1, 2]
358
+ }
278
359
  ```
279
360
 
280
- ## 責務
361
+ を送信すると、内部では次の dispatch が実行されます。
362
+
363
+ ```ts
364
+ app.dispatch("sum", 1, 2);
365
+ ```
366
+
367
+ レスポンス:
368
+
369
+ ```json
370
+ 3
371
+ ```
281
372
 
282
- `@gasboost/vite` はビルド時の処理のみを担当します。
373
+ ## RPC Request
283
374
 
284
- 主な責務:
375
+ Request Body は次の形式です。
285
376
 
286
- - `AppsScript` 登録内容の静的解析
287
- - Google Apps Script 向け Vite configuration
288
- - GAS グローバル関数宣言の生成
289
- - Vite 環境変数との統合
377
+ ```ts
378
+ {
379
+ args: unknown[];
380
+ }
381
+ ```
382
+
383
+ 例えば複数の引数を持つ RPC:
384
+
385
+ ```ts
386
+ app.call(
387
+ "example",
388
+ (id: number, name: string, active: boolean, options: { value: number }) => {
389
+ // ...
390
+ },
391
+ );
392
+ ```
290
393
 
291
- 以下は担当しません。
394
+ に対して、
395
+
396
+ ```json
397
+ {
398
+ "args": [
399
+ 1,
400
+ "Taro",
401
+ true,
402
+ {
403
+ "value": 4
404
+ }
405
+ ]
406
+ }
407
+ ```
292
408
 
293
- - GET ハンドラの実行
294
- - POST ハンドラの実行
295
- - RPC dispatch
296
- - ハンドラ実体のランタイム登録
297
- - Google Apps Script API 自体の抽象化
409
+ のように送信できます。
298
410
 
299
- これらの runtime responsibility は `@gasboost/app` が担当します。
411
+ ### 引数なし RPC
300
412
 
301
- ## 現在の制約
413
+ Request Body が空の場合は、引数なし RPC として扱われます。
302
414
 
303
- Analyzer は、意図的にシンプルな entry file 構造のみを対象としています。
415
+ ```http
416
+ POST /__gasboost/noArgs
417
+ ```
304
418
 
305
- 以下のような alias を介した default export は現在対象外です。
419
+ 内部では次のように dispatch されます。
306
420
 
307
421
  ```ts
308
- const app = new AppsScript();
309
- const exported = app;
422
+ app.dispatch("noArgs");
423
+ ```
310
424
 
311
- export default exported;
425
+ 明示的に送る場合は次でも構いません。
426
+
427
+ ```json
428
+ {
429
+ "args": []
430
+ }
312
431
  ```
313
432
 
314
- 別関数の内部に登録処理を隠す形式も対象外です。
433
+ ## RPC Response
434
+
435
+ `@gasboost/app` の `dispatch()` が返す `AppsScriptResponse.contents` を、そのまま HTTP Response Body として返します。
436
+
437
+ 例えば、
315
438
 
316
439
  ```ts
317
- registerHandlers(app);
440
+ app.call("getUser", () => ({
441
+ id: 1,
442
+ name: "Taro",
443
+ }));
444
+ ```
445
+
446
+ に対するレスポンスは:
447
+
448
+ ```json
449
+ {
450
+ "id": 1,
451
+ "name": "Taro"
452
+ }
453
+ ```
454
+
455
+ となります。
456
+
457
+ Response の Content-Type は:
458
+
459
+ ```text
460
+ application/json; charset=utf-8
461
+ ```
462
+
463
+ です。
464
+
465
+ ## Async RPC
466
+
467
+ 非同期 RPC にも対応しています。
468
+
469
+ ```ts
470
+ app.call("loadUser", async (id: string) => {
471
+ const user = await loadUser(id);
472
+
473
+ return user;
474
+ });
475
+ ```
476
+
477
+ dev plugin は `dispatch()` の完了を待ってからレスポンスを返します。
478
+
479
+ ## 開発中の module loading
480
+
481
+ RPC リクエストごとに、指定された `entry` を Vite の `ssrLoadModule()` で読み込みます。
482
+
483
+ ```text
484
+ POST /__gasboost/sum
485
+
486
+ ssrLoadModule("src/server.ts")
487
+
488
+ AppsScript.dispatch("sum", ...)
489
+ ```
490
+
491
+ そのため、Vite Dev Server 上の最新のサーバーコードを利用して RPC を実行できます。
492
+
493
+ ## Error Response
494
+
495
+ ### 不正な Request Body
496
+
497
+ JSON として不正な body や、`args` が配列でない body は `400` を返します。
498
+
499
+ ```json
500
+ {
501
+ "args": "invalid"
502
+ }
503
+ ```
504
+
505
+ レスポンス例:
506
+
507
+ ```json
508
+ {
509
+ "error": {
510
+ "name": "InvalidRpcRequestError",
511
+ "message": "Invalid RPC request body. Expected { args: unknown[] }."
512
+ }
513
+ }
318
514
  ```
319
515
 
320
- 別ファイルに登録処理を分散する形式も現在対象外です。
516
+ JSON 自体が不正な場合も `400` です。
517
+
518
+ ### POST 以外
519
+
520
+ Local RPC endpoint は POST のみ受け付けます。
521
+
522
+ ```http
523
+ GET /__gasboost/sum
524
+ ```
525
+
526
+ は `405` になります。
527
+
528
+ ```json
529
+ {
530
+ "error": {
531
+ "name": "MethodNotAllowedError",
532
+ "message": "Only POST is allowed."
533
+ }
534
+ }
535
+ ```
536
+
537
+ ### 未登録 RPC
538
+
539
+ 存在しない RPC を呼び出した場合は `500` を返します。
540
+
541
+ ```text
542
+ POST /__gasboost/unknown
543
+ ```
544
+
545
+ ```json
546
+ {
547
+ "error": {
548
+ "name": "Error",
549
+ "message": "Function unknown is not registered."
550
+ }
551
+ }
552
+ ```
553
+
554
+ ### Handler Error
555
+
556
+ RPC handler 内で例外が発生した場合も `500` として JSON で返されます。
557
+
558
+ ```json
559
+ {
560
+ "error": {
561
+ "name": "TypeError",
562
+ "message": "handler failed"
563
+ }
564
+ }
565
+ ```
566
+
567
+ ## Local RPC の対象 path
568
+
569
+ 次の形式だけを RPC として扱います。
570
+
571
+ ```text
572
+ /__gasboost/{rpcName}
573
+ ```
574
+
575
+ 例えば以下は対象です。
576
+
577
+ ```text
578
+ /__gasboost/getUser
579
+ /__gasboost/sum
580
+ ```
581
+
582
+ 一方、次のような path は RPC として扱いません。
583
+
584
+ ```text
585
+ /__gasboost/
586
+ /__gasboost/foo/bar
587
+ /api/users
588
+ ```
589
+
590
+ 通常の Vite middleware chain に処理を渡します。
591
+
592
+ query string が付いていても RPC 名は正しく解決されます。
593
+
594
+ ```text
595
+ /__gasboost/hello?foo=bar
596
+ ```
597
+
598
+ URL encoded な RPC 名も decode されます。
599
+
600
+ ```text
601
+ /__gasboost/hello%20world
602
+ ```
603
+
604
+ ---
605
+
606
+ # build と dev の責務
607
+
608
+ ```text
609
+ gasboost()
610
+
611
+ ├─ build
612
+ │ ├─ AppsScript の静的解析
613
+ │ ├─ GAS グローバル関数生成
614
+ │ ├─ GAS 向け build config
615
+ │ └─ backend production build
616
+
617
+ └─ dev
618
+ ├─ Vite Dev Server middleware
619
+ ├─ Local RPC endpoint
620
+ ├─ entry の ssrLoadModule
621
+ └─ AppsScript.dispatch
622
+ ```
623
+
624
+ frontend と backend を1つの `vite.config.ts` で扱う場合は、mode で分岐します。
321
625
 
322
626
  ```ts
323
- import { registerHandlers } from "./handlers";
627
+ const { build, dev } = gasboost({
628
+ entry: "src/server.ts",
629
+ });
630
+
631
+ export default defineConfig(({ mode }) => {
632
+ if (mode === "server") {
633
+ return {
634
+ plugins: [build],
635
+ };
636
+ }
324
637
 
325
- registerHandlers(app);
638
+ return {
639
+ plugins: [dev],
640
+ };
641
+ });
326
642
  ```
327
643
 
328
- 登録内容を entry file から静的に確定できるようにすることで、生成する GAS グローバル関数を決定的にしています。
644
+ `build` を通常の frontend build に含めると、server entry Vite build input になるため、frontend と backend の build は分離してください。
329
645
 
330
646
  ## 関連パッケージ
331
647
 
332
- アプリケーションの runtime と handler registration には `@gasboost/app` を利用してください。
648
+ - `@gasboost/app` — GAS バックエンドランタイムと RPC 定義
649
+ - `@gasboost/client` — フロントエンド側の型安全 RPC クライアント
650
+
651
+ ## License
652
+
653
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "vite";
2
+ import type { GasboostOptions } from "./gasboost";
3
+ export declare function createBuildPlugin(options: GasboostOptions): Plugin;
package/dist/dev.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "vite";
2
+ export declare function createDevPlugin(entry: string): Plugin;
@@ -3,4 +3,7 @@ export interface GasboostOptions {
3
3
  entry: string;
4
4
  envDir?: string;
5
5
  }
6
- export declare function gasboost(options: GasboostOptions): Plugin;
6
+ export declare function gasboost(options: GasboostOptions): {
7
+ build: Plugin;
8
+ dev: Plugin;
9
+ };
package/dist/index.js CHANGED
@@ -114,11 +114,12 @@ function b(e) {
114
114
  return t.join("\n");
115
115
  }
116
116
  //#endregion
117
- //#region src/gasboost.ts
117
+ //#region src/build.ts
118
118
  function x(e) {
119
119
  let t;
120
120
  return {
121
- name: "gasboost",
121
+ name: "gasboost:build",
122
+ apply: "build",
122
123
  config() {
123
124
  return _(e);
124
125
  },
@@ -132,4 +133,89 @@ function x(e) {
132
133
  };
133
134
  }
134
135
  //#endregion
135
- export { x as gasboost };
136
+ //#region src/dev.ts
137
+ var S = class extends Error {
138
+ constructor(e) {
139
+ super(e), this.name = "InvalidRpcRequestError";
140
+ }
141
+ };
142
+ function C(e) {
143
+ return {
144
+ name: "gasboost:dev",
145
+ apply: "serve",
146
+ configureServer(t) {
147
+ t.middlewares.use(async (n, r, i) => {
148
+ if (!n.url) {
149
+ i();
150
+ return;
151
+ }
152
+ let a = n.url.split("?")[0];
153
+ if (!a.startsWith("/__gasboost/")) {
154
+ i();
155
+ return;
156
+ }
157
+ let o = a.slice(12);
158
+ if (!o || o.includes("/")) {
159
+ i();
160
+ return;
161
+ }
162
+ if (n.method !== "POST") {
163
+ r.statusCode = 405, r.setHeader("Content-Type", "application/json; charset=utf-8"), r.end(JSON.stringify({ error: {
164
+ name: "MethodNotAllowedError",
165
+ message: "Only POST is allowed."
166
+ } }));
167
+ return;
168
+ }
169
+ try {
170
+ let { args: i } = await w(n), a = await (await t.ssrLoadModule(e)).default.dispatch(decodeURIComponent(o), ...i);
171
+ r.statusCode = 200, r.setHeader("Content-Type", "application/json; charset=utf-8"), r.end(a.contents);
172
+ } catch (e) {
173
+ r.statusCode = e instanceof S ? 400 : 500, r.setHeader("Content-Type", "application/json; charset=utf-8"), r.end(JSON.stringify({ error: e instanceof Error ? {
174
+ name: e.name,
175
+ message: e.message,
176
+ stack: e.stack
177
+ } : {
178
+ name: "UnknownError",
179
+ message: String(e)
180
+ } }));
181
+ }
182
+ });
183
+ }
184
+ };
185
+ }
186
+ function w(e) {
187
+ return new Promise((t, n) => {
188
+ let r = [];
189
+ e.on("data", (e) => {
190
+ r.push(typeof e == "string" ? Buffer.from(e) : e);
191
+ }), e.on("error", n), e.on("end", () => {
192
+ let e = Buffer.concat(r).toString("utf-8");
193
+ if (!e) {
194
+ t({ args: [] });
195
+ return;
196
+ }
197
+ let i;
198
+ try {
199
+ i = JSON.parse(e);
200
+ } catch {
201
+ n(new S("Invalid RPC request body. Expected valid JSON."));
202
+ return;
203
+ }
204
+ if (typeof i != "object" || !i || !("args" in i) || !Array.isArray(i.args)) {
205
+ n(new S("Invalid RPC request body. Expected { args: unknown[] }."));
206
+ return;
207
+ }
208
+ t({ args: i.args });
209
+ });
210
+ });
211
+ }
212
+ //#endregion
213
+ //#region src/gasboost.ts
214
+ function T(e) {
215
+ return {
216
+ build: x(e),
217
+ dev: C(e.entry)
218
+ };
219
+ }
220
+ //#endregion
221
+ export { T as gasboost };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gasboost/vite",
3
- "version": "0.1.0",
3
+ "version": "1.0.1",
4
4
  "description": "A Vite plugin for building @gasboost/app applications for Google Apps Script.",
5
5
  "keywords": [
6
6
  "google-apps-script",
@@ -36,7 +36,11 @@
36
36
  "vite": "^8.2.2"
37
37
  },
38
38
  "dependencies": {
39
- "typescript": "^7.0.2"
39
+ "typescript": "^7.0.2",
40
+ "@gasboost/app": "1.0.1"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
40
44
  },
41
45
  "scripts": {
42
46
  "typecheck": "tsc -p tsconfig.json --noEmit",