@gasboost/vite 1.1.0 → 1.2.0
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/README.md +146 -0
- package/dist/gasboost.d.ts +1 -0
- package/dist/index.js +59 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -603,6 +603,152 @@ URL encoded な RPC 名も decode されます。
|
|
|
603
603
|
|
|
604
604
|
---
|
|
605
605
|
|
|
606
|
+
## Client Transport
|
|
607
|
+
|
|
608
|
+
`@gasboost/client` を利用している場合、dev plugin はローカル開発時の transport を自動で Local RPC に切り替えます。
|
|
609
|
+
|
|
610
|
+
アプリケーション側では development / production を判定する必要はありません。
|
|
611
|
+
|
|
612
|
+
```ts
|
|
613
|
+
import { appsScriptClient } from "@gasboost/client";
|
|
614
|
+
import type { App } from "./server";
|
|
615
|
+
|
|
616
|
+
const { client } = appsScriptClient<App>();
|
|
617
|
+
|
|
618
|
+
const result = await client.sum(1, 2);
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
Vite Dev Server 上では、`appsScriptClient()` に transport が指定されていない場合、dev plugin が自動的に `FetchTransport` を適用します。
|
|
622
|
+
|
|
623
|
+
```text
|
|
624
|
+
appsScriptClient()
|
|
625
|
+
↓
|
|
626
|
+
FetchTransport
|
|
627
|
+
↓
|
|
628
|
+
POST /__gasboost/{rpcName}
|
|
629
|
+
↓
|
|
630
|
+
AppsScript.dispatch()
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
そのため、ローカル開発用に transport を切り替えるコードを書く必要はありません。
|
|
634
|
+
|
|
635
|
+
```ts
|
|
636
|
+
// 不要
|
|
637
|
+
appsScriptClient({
|
|
638
|
+
transport: import.meta.env.DEV
|
|
639
|
+
? new FetchTransport({
|
|
640
|
+
endpoint: "/__gasboost",
|
|
641
|
+
})
|
|
642
|
+
: new AppsScriptTransport(),
|
|
643
|
+
});
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
production build では dev plugin による差し替えは行われません。
|
|
647
|
+
|
|
648
|
+
GAS 上では `appsScriptClient()` のデフォルトである `AppsScriptTransport` がそのまま利用されます。
|
|
649
|
+
|
|
650
|
+
```text
|
|
651
|
+
appsScriptClient()
|
|
652
|
+
↓
|
|
653
|
+
AppsScriptTransport
|
|
654
|
+
↓
|
|
655
|
+
google.script.run
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
つまり、同じ application code のまま local development と GAS production の両方で利用できます。
|
|
659
|
+
|
|
660
|
+
```ts
|
|
661
|
+
const { client } = appsScriptClient<App>();
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
また、明示的に `transport` を指定した場合はその transport が優先されます。
|
|
665
|
+
|
|
666
|
+
```ts
|
|
667
|
+
const { client } = appsScriptClient<App>({
|
|
668
|
+
transport: customTransport,
|
|
669
|
+
});
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
dev plugin が明示指定された transport を上書きすることはありません。
|
|
673
|
+
|
|
674
|
+
---
|
|
675
|
+
|
|
676
|
+
## HtmlTemplate variables
|
|
677
|
+
|
|
678
|
+
GAS の `HtmlTemplate` では、`<?= variable ?>` を使用してサーバー側の値を HTML に埋め込めます。
|
|
679
|
+
|
|
680
|
+
```html
|
|
681
|
+
<script>
|
|
682
|
+
const variables = "<?= variables ?>";
|
|
683
|
+
</script>
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
GAS 上では `HtmlTemplate` によって評価されますが、Vite Dev Server では GAS のテンプレート処理が実行されません。
|
|
687
|
+
|
|
688
|
+
`@gasboost/vite` では、`template` オプションを指定することで、開発時にこれらの template variables を置換できます。
|
|
689
|
+
|
|
690
|
+
```ts
|
|
691
|
+
import { gasboost } from "@gasboost/vite";
|
|
692
|
+
import { defineConfig } from "vite";
|
|
693
|
+
|
|
694
|
+
export default defineConfig({
|
|
695
|
+
plugins: [
|
|
696
|
+
gasboost({
|
|
697
|
+
entry: "./src/backend/main.ts",
|
|
698
|
+
template: {
|
|
699
|
+
variables: JSON.stringify({
|
|
700
|
+
scriptId: "local-script-id",
|
|
701
|
+
isSetupCompleted: true,
|
|
702
|
+
isTermsAccepted: true,
|
|
703
|
+
}),
|
|
704
|
+
},
|
|
705
|
+
}).dev,
|
|
706
|
+
],
|
|
707
|
+
});
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
例えば、次の HTML は、
|
|
711
|
+
|
|
712
|
+
```html
|
|
713
|
+
<script>
|
|
714
|
+
const variables = "<?= variables ?>";
|
|
715
|
+
</script>
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Vite の開発環境では次のように変換されます。
|
|
719
|
+
|
|
720
|
+
```html
|
|
721
|
+
<script>
|
|
722
|
+
const variables =
|
|
723
|
+
'{"scriptId":"local-script-id","isSetupCompleted":true,"isTermsAccepted":true}';
|
|
724
|
+
</script>
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
複数の template variable も指定できます。
|
|
728
|
+
|
|
729
|
+
```ts
|
|
730
|
+
gasboost({
|
|
731
|
+
entry: "./src/backend/main.ts",
|
|
732
|
+
template: {
|
|
733
|
+
environment: "development",
|
|
734
|
+
userName: "Tiger",
|
|
735
|
+
},
|
|
736
|
+
});
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
```html
|
|
740
|
+
<p>Environment: <?= environment ?></p>
|
|
741
|
+
<p>User: <?= userName ?></p>
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
`template` の型は `Record<string, string>` です。
|
|
745
|
+
|
|
746
|
+
値の serialize は `@gasboost/vite` では行いません。オブジェクトなどを埋め込む場合は、利用側で `JSON.stringify()` などを使用して文字列へ変換してください。
|
|
747
|
+
|
|
748
|
+
`template` による置換は Vite Dev Server でのみ行われます。production build では値を埋め込まず、GAS 上で実際の `HtmlTemplate` が template expression を評価します。
|
|
749
|
+
|
|
750
|
+
---
|
|
751
|
+
|
|
606
752
|
# build と dev の責務
|
|
607
753
|
|
|
608
754
|
```text
|
package/dist/gasboost.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -105,25 +105,58 @@ var v = class extends Error {
|
|
|
105
105
|
constructor(e) {
|
|
106
106
|
super(e), this.name = "InvalidRpcRequestError";
|
|
107
107
|
}
|
|
108
|
-
};
|
|
109
|
-
function
|
|
110
|
-
let { runtime: t } = e;
|
|
108
|
+
}, y = "@gasboost/client", b = "\0gasboost:client", x = "/__gasboost";
|
|
109
|
+
function S(e) {
|
|
110
|
+
let { runtime: t, template: r } = e, i;
|
|
111
111
|
return {
|
|
112
112
|
name: "gasboost:dev",
|
|
113
113
|
apply: "serve",
|
|
114
|
+
enforce: "pre",
|
|
115
|
+
async resolveId(e, t, n) {
|
|
116
|
+
if (e !== y || this.environment.config.consumer !== "client") return null;
|
|
117
|
+
let r = await this.resolve(e, t, {
|
|
118
|
+
...n,
|
|
119
|
+
skipSelf: !0
|
|
120
|
+
});
|
|
121
|
+
return r ? (i = r.id, b) : null;
|
|
122
|
+
},
|
|
123
|
+
load(e) {
|
|
124
|
+
if (e !== b) return null;
|
|
125
|
+
if (!i) throw Error("@gasboost/client could not be resolved.");
|
|
126
|
+
let t = JSON.stringify(i);
|
|
127
|
+
return `
|
|
128
|
+
import {
|
|
129
|
+
appsScriptClient as originalAppsScriptClient,
|
|
130
|
+
FetchTransport,
|
|
131
|
+
} from ${t};
|
|
132
|
+
|
|
133
|
+
export * from ${t};
|
|
134
|
+
|
|
135
|
+
export function appsScriptClient(options = {}) {
|
|
136
|
+
return originalAppsScriptClient({
|
|
137
|
+
...options,
|
|
138
|
+
transport:
|
|
139
|
+
options.transport ??
|
|
140
|
+
new FetchTransport({
|
|
141
|
+
endpoint: ${JSON.stringify(x)},
|
|
142
|
+
}),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
`;
|
|
146
|
+
},
|
|
114
147
|
configureServer(r) {
|
|
115
148
|
h(t), r.middlewares.use(async (t, i, a) => {
|
|
116
149
|
if (!t.url) {
|
|
117
150
|
a();
|
|
118
151
|
return;
|
|
119
152
|
}
|
|
120
|
-
let o = t.url.split("?")[0]
|
|
121
|
-
if (!o.startsWith(
|
|
153
|
+
let o = t.url.split("?")[0], s = `${x}/`;
|
|
154
|
+
if (!o.startsWith(s)) {
|
|
122
155
|
a();
|
|
123
156
|
return;
|
|
124
157
|
}
|
|
125
|
-
let
|
|
126
|
-
if (!
|
|
158
|
+
let c = o.slice(s.length);
|
|
159
|
+
if (!c || c.includes("/")) {
|
|
127
160
|
a();
|
|
128
161
|
return;
|
|
129
162
|
}
|
|
@@ -135,10 +168,10 @@ function y(e) {
|
|
|
135
168
|
return;
|
|
136
169
|
}
|
|
137
170
|
try {
|
|
138
|
-
let { args: a } = await
|
|
171
|
+
let { args: a } = await w(t), o = r.environments.ssr;
|
|
139
172
|
if (!n(o)) throw Error("Vite SSR environment is not runnable.");
|
|
140
|
-
let
|
|
141
|
-
i.statusCode = 200, i.setHeader("Content-Type", "application/json; charset=utf-8"), i.end(
|
|
173
|
+
let s = await (await o.runner.import(e.entry)).default.dispatch(decodeURIComponent(c), ...a);
|
|
174
|
+
i.statusCode = 200, i.setHeader("Content-Type", "application/json; charset=utf-8"), i.end(s.contents);
|
|
142
175
|
} catch (e) {
|
|
143
176
|
i.statusCode = e instanceof v ? 400 : 500, i.setHeader("Content-Type", "application/json; charset=utf-8"), i.end(JSON.stringify({ error: e instanceof Error ? {
|
|
144
177
|
name: e.name,
|
|
@@ -150,10 +183,22 @@ function y(e) {
|
|
|
150
183
|
} }));
|
|
151
184
|
}
|
|
152
185
|
});
|
|
186
|
+
},
|
|
187
|
+
transformIndexHtml(e) {
|
|
188
|
+
if (!r) return e;
|
|
189
|
+
let t = e;
|
|
190
|
+
for (let [e, n] of Object.entries(r)) {
|
|
191
|
+
let r = RegExp(`<\\?=\\s*${C(e)}\\s*\\?>`, "g");
|
|
192
|
+
t = t.replace(r, () => n);
|
|
193
|
+
}
|
|
194
|
+
return t;
|
|
153
195
|
}
|
|
154
196
|
};
|
|
155
197
|
}
|
|
156
|
-
function
|
|
198
|
+
function C(e) {
|
|
199
|
+
return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
200
|
+
}
|
|
201
|
+
function w(e) {
|
|
157
202
|
return new Promise((t, n) => {
|
|
158
203
|
let r = [];
|
|
159
204
|
e.on("data", (e) => {
|
|
@@ -181,11 +226,11 @@ function b(e) {
|
|
|
181
226
|
}
|
|
182
227
|
//#endregion
|
|
183
228
|
//#region src/gasboost.ts
|
|
184
|
-
function
|
|
229
|
+
function T(e) {
|
|
185
230
|
return {
|
|
186
231
|
build: _(e),
|
|
187
|
-
dev:
|
|
232
|
+
dev: S(e)
|
|
188
233
|
};
|
|
189
234
|
}
|
|
190
235
|
//#endregion
|
|
191
|
-
export {
|
|
236
|
+
export { T as gasboost };
|