@ciderjs/gasbombe 0.3.0 → 0.3.2

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.
Files changed (54) hide show
  1. package/dist/cli.cjs +23 -10
  2. package/dist/cli.mjs +23 -10
  3. package/dist/templates/html-js/.clasp.json.ejs +5 -0
  4. package/dist/templates/html-js/.env.ejs +1 -0
  5. package/dist/templates/html-js/README.md.ejs +1 -0
  6. package/dist/templates/html-js/biome.json.ejs +36 -0
  7. package/dist/templates/html-js/index.html.ejs +13 -0
  8. package/dist/templates/html-js/package.json.ejs +33 -0
  9. package/dist/templates/html-js/public/vite.svg.ejs +1 -0
  10. package/dist/templates/html-js/rolldown.config.mjs.ejs +29 -0
  11. package/dist/templates/html-js/server/app.js.ejs +27 -0
  12. package/dist/templates/html-js/server/appsscript.json.ejs +12 -0
  13. package/dist/templates/html-js/server/modules/hello.js.ejs +3 -0
  14. package/dist/templates/html-js/src/counter.js.ejs +9 -0
  15. package/dist/templates/html-js/src/javascript.svg.ejs +1 -0
  16. package/dist/templates/html-js/src/main.js.ejs +27 -0
  17. package/dist/templates/html-js/src/say.js.ejs +23 -0
  18. package/dist/templates/html-js/src/style.css.ejs +96 -0
  19. package/dist/templates/html-js/tsconfig.json.ejs +34 -0
  20. package/dist/templates/html-js/vitest.config.js.ejs +11 -0
  21. package/dist/templates/server-js/.clasp.json.ejs +5 -0
  22. package/dist/templates/vue-ciderjs/.clasp.json.ejs +5 -0
  23. package/dist/templates/vue-ciderjs/.env.ejs +1 -0
  24. package/dist/templates/vue-ciderjs/.github/workflows/appsscript.yml.ejs +45 -0
  25. package/dist/templates/vue-ciderjs/.vscode/extensions.json.ejs +3 -0
  26. package/dist/templates/vue-ciderjs/README.md.ejs +14 -0
  27. package/dist/templates/vue-ciderjs/biome.json.ejs +35 -0
  28. package/dist/templates/vue-ciderjs/index.html.ejs +13 -0
  29. package/dist/templates/vue-ciderjs/package.json.ejs +50 -0
  30. package/dist/templates/vue-ciderjs/public/vite.svg.ejs +1 -0
  31. package/dist/templates/vue-ciderjs/rolldown.config.ts.ejs +25 -0
  32. package/dist/templates/vue-ciderjs/server/app.ts.ejs +29 -0
  33. package/dist/templates/vue-ciderjs/server/appsscript.json.ejs +12 -0
  34. package/dist/templates/vue-ciderjs/server/modules/hello.ts.ejs +3 -0
  35. package/dist/templates/vue-ciderjs/src/App.vue.ejs +7 -0
  36. package/dist/templates/vue-ciderjs/src/assets/vue.svg.ejs +1 -0
  37. package/dist/templates/vue-ciderjs/src/components/HelloWorld.vue.ejs +54 -0
  38. package/dist/templates/vue-ciderjs/src/components/Navigation.vue.ejs +23 -0
  39. package/dist/templates/vue-ciderjs/src/lib/parameters.ts.ejs +20 -0
  40. package/dist/templates/vue-ciderjs/src/lib/server.ts.ejs +18 -0
  41. package/dist/templates/vue-ciderjs/src/main.ts.ejs +13 -0
  42. package/dist/templates/vue-ciderjs/src/pages/_root.vue.ejs +40 -0
  43. package/dist/templates/vue-ciderjs/src/pages/about.vue.ejs +9 -0
  44. package/dist/templates/vue-ciderjs/src/pages/detail/user.vue.ejs +16 -0
  45. package/dist/templates/vue-ciderjs/src/pages/index.vue.ejs +7 -0
  46. package/dist/templates/vue-ciderjs/src/style.css.ejs +79 -0
  47. package/dist/templates/vue-ciderjs/tests/server/modules/hello.spec.ts.ejs +9 -0
  48. package/dist/templates/vue-ciderjs/tests/src/lib/server.spec.ts.ejs +8 -0
  49. package/dist/templates/vue-ciderjs/tsconfig.app.json.ejs +21 -0
  50. package/dist/templates/vue-ciderjs/tsconfig.json.ejs +13 -0
  51. package/dist/templates/vue-ciderjs/tsconfig.node.json.ejs +26 -0
  52. package/dist/templates/vue-ciderjs/types/appsscript/server.ts.ejs +10 -0
  53. package/dist/templates/vue-ciderjs/vite.config.ts.ejs +27 -0
  54. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -11,7 +11,7 @@ require('consola');
11
11
  require('ejs');
12
12
  require('glob');
13
13
 
14
- const version = "0.3.0";
14
+ const version = "0.3.2";
15
15
 
16
16
  async function main() {
17
17
  const program = new commander.Command();
@@ -26,7 +26,7 @@ async function main() {
26
26
  ""
27
27
  ).option(
28
28
  "-t, --template [templateType]",
29
- 'Project template label ("vanilla-ts" | "vanilla-js" | "react-tsx")',
29
+ 'Project template label ("server-ts" | "server-js" | "react" | "react-ciderjs" | "vue" | "vue-ciderjs" | "html-js")',
30
30
  ""
31
31
  ).option(
32
32
  "-c, --clasp [claspSetupCommand]",
@@ -152,14 +152,27 @@ async function main() {
152
152
  if (packageManager === "" && clasp !== "create" && clasp !== "list" && skipInstall) {
153
153
  packageManager = "npm";
154
154
  }
155
- packageManager ||= await prompts.select({
156
- message: "Choice package manager what you want to use...",
157
- choices: [
158
- { name: "npm", value: "npm" },
159
- { name: "pnpm", value: "pnpm" },
160
- { name: "yarn", value: "yarn" }
161
- ]
162
- });
155
+ if (packageManager == null || packageManager === "") {
156
+ const selected = await prompts.select({
157
+ message: "Choice package manager what you want to use...",
158
+ choices: [
159
+ { name: "npm", value: "npm" },
160
+ { name: "pnpm", value: "pnpm" },
161
+ { name: "yarn", value: "yarn" },
162
+ {
163
+ name: "skip",
164
+ value: null,
165
+ description: "Skip installation for now"
166
+ }
167
+ ]
168
+ });
169
+ if (selected === null) {
170
+ skipInstall = true;
171
+ packageManager = "npm";
172
+ } else {
173
+ packageManager = selected;
174
+ }
175
+ }
163
176
  const packageManagers = ["npm", "pnpm", "yarn"];
164
177
  if (!packageManagers.includes(packageManager)) {
165
178
  throw Error("Invalid package manager");
package/dist/cli.mjs CHANGED
@@ -9,7 +9,7 @@ import 'consola';
9
9
  import 'ejs';
10
10
  import 'glob';
11
11
 
12
- const version = "0.3.0";
12
+ const version = "0.3.2";
13
13
 
14
14
  async function main() {
15
15
  const program = new Command();
@@ -24,7 +24,7 @@ async function main() {
24
24
  ""
25
25
  ).option(
26
26
  "-t, --template [templateType]",
27
- 'Project template label ("vanilla-ts" | "vanilla-js" | "react-tsx")',
27
+ 'Project template label ("server-ts" | "server-js" | "react" | "react-ciderjs" | "vue" | "vue-ciderjs" | "html-js")',
28
28
  ""
29
29
  ).option(
30
30
  "-c, --clasp [claspSetupCommand]",
@@ -150,14 +150,27 @@ async function main() {
150
150
  if (packageManager === "" && clasp !== "create" && clasp !== "list" && skipInstall) {
151
151
  packageManager = "npm";
152
152
  }
153
- packageManager ||= await select({
154
- message: "Choice package manager what you want to use...",
155
- choices: [
156
- { name: "npm", value: "npm" },
157
- { name: "pnpm", value: "pnpm" },
158
- { name: "yarn", value: "yarn" }
159
- ]
160
- });
153
+ if (packageManager == null || packageManager === "") {
154
+ const selected = await select({
155
+ message: "Choice package manager what you want to use...",
156
+ choices: [
157
+ { name: "npm", value: "npm" },
158
+ { name: "pnpm", value: "pnpm" },
159
+ { name: "yarn", value: "yarn" },
160
+ {
161
+ name: "skip",
162
+ value: null,
163
+ description: "Skip installation for now"
164
+ }
165
+ ]
166
+ });
167
+ if (selected === null) {
168
+ skipInstall = true;
169
+ packageManager = "npm";
170
+ } else {
171
+ packageManager = selected;
172
+ }
173
+ }
161
174
  const packageManagers = ["npm", "pnpm", "yarn"];
162
175
  if (!packageManagers.includes(packageManager)) {
163
176
  throw Error("Invalid package manager");
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/clasp.json",
3
+ "scriptId": "{{ input your script id of apps-script }}",
4
+ "rootDir": "dist"
5
+ }
@@ -0,0 +1 @@
1
+ GAS_DEPLOYMENT_ID=input your deployment id
@@ -0,0 +1 @@
1
+ # Starter template for Google Apps Script webapp
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.4/schema.json",
3
+ "vcs": {
4
+ "enabled": false,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": false
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false,
10
+ "includes": ["src/**/*", "tests/**/*", "types/**/*", "./*.js", "./*.json"]
11
+ },
12
+ "formatter": {
13
+ "enabled": true,
14
+ "indentStyle": "space",
15
+ "indentWidth": 2
16
+ },
17
+ "linter": {
18
+ "enabled": true,
19
+ "rules": {
20
+ "recommended": true
21
+ }
22
+ },
23
+ "javascript": {
24
+ "formatter": {
25
+ "quoteStyle": "double"
26
+ }
27
+ },
28
+ "assist": {
29
+ "enabled": true,
30
+ "actions": {
31
+ "source": {
32
+ "organizeImports": "on"
33
+ }
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title><%= projectName %></title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.js"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build:server": "rolldown -c && cpy server/*.json dist/",
9
+ "build:front": "vite build",
10
+ "build": "rimraf dist && pnpm run build:front && pnpm run build:server",
11
+ "check": "biome check --write",
12
+ "test": "vitest run --coverage",
13
+ "push": "clasp push",
14
+ "deploy": "clasp create-deployment",
15
+ "update": "dotenv cross-var \"clasp update-deployment $GAS_DEPLOYMENT_ID\"",
16
+ "preview:local": "vite preview",
17
+ "preview:web": "clasp open-web-app"
18
+ },
19
+ "devDependencies": {
20
+ "@biomejs/biome": "^2.3.4",
21
+ "@google/clasp": "^3.1.1",
22
+ "@rollup/plugin-alias": "^6.0.0",
23
+ "@types/google-apps-script": "^2.0.7",
24
+ "@types/node": "^24.10.0",
25
+ "cpy-cli": "^6.0.0",
26
+ "rimraf": "^6.1.0",
27
+ "rolldown": "1.0.0-beta.47",
28
+ "rolldown-plugin-remove-export": "^0.1.3",
29
+ "vite": "^7.1.7",
30
+ "vite-tsconfig-paths": "^5.1.4",
31
+ "vitest": "^4.0.8"
32
+ }
33
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,29 @@
1
+ import path from "node:path";
2
+ import alias from "@rollup/plugin-alias";
3
+ import { defineConfig } from "rolldown";
4
+ import { removeExportPlugin } from "rolldown-plugin-remove-export";
5
+
6
+ const outputFile = "index.js";
7
+
8
+ export default defineConfig({
9
+ input: "src/main.js",
10
+ output: {
11
+ format: "esm",
12
+ file: `dist/${outputFile}`,
13
+ },
14
+ plugins: [
15
+ alias({
16
+ entries: [
17
+ {
18
+ find: "@",
19
+ replacement: path.resolve(import.meta.dirname, "src"),
20
+ },
21
+ {
22
+ find: "~",
23
+ replacement: path.resolve(import.meta.dirname),
24
+ },
25
+ ],
26
+ }),
27
+ removeExportPlugin(outputFile),
28
+ ],
29
+ });
@@ -0,0 +1,27 @@
1
+ export * from "./modules/hello";
2
+
3
+ const SITE_TITLE = "<%= projectName %>";
4
+
5
+ /**
6
+ * Procedure to handle GET requests when published as a web app
7
+ */
8
+ export function doGet(e) {
9
+ const htmlTemplate = HtmlService.createTemplateFromFile("index");
10
+ const title = SITE_TITLE;
11
+ const userAddress = Session.getActiveUser().getEmail();
12
+
13
+ // set initial data for front-end
14
+ htmlTemplate.parameters = JSON.stringify({
15
+ ...e,
16
+ siteTitle: title,
17
+ userAddress: userAddress,
18
+ });
19
+
20
+ const htmlOutput = htmlTemplate.evaluate();
21
+ htmlOutput.setTitle(title);
22
+ htmlOutput.addMetaTag(
23
+ "viewport",
24
+ "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui",
25
+ );
26
+ return htmlOutput;
27
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "timeZone": "Asia/Tokyo",
3
+ "dependencies": {
4
+ "libraries": []
5
+ },
6
+ "exceptionLogging": "STACKDRIVER",
7
+ "runtimeVersion": "V8",
8
+ "webapp": {
9
+ "executeAs": "USER_ACCESSING",
10
+ "access": "ANYONE"
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ export function sayHello(name) {
2
+ return `Hello, ${name}!`;
3
+ }
@@ -0,0 +1,9 @@
1
+ export function setupCounter(element) {
2
+ let counter = 0;
3
+ const setCounter = (count) => {
4
+ counter = count;
5
+ element.innerHTML = `count is ${counter}`;
6
+ };
7
+ element.addEventListener("click", () => setCounter(counter + 1));
8
+ setCounter(0);
9
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#F7DF1E" d="M0 0h256v256H0V0Z"></path><path d="m67.312 213.932l19.59-11.856c3.78 6.701 7.218 12.371 15.465 12.371c7.905 0 12.89-3.092 12.89-15.12v-81.798h24.057v82.138c0 24.917-14.606 36.259-35.916 36.259c-19.245 0-30.416-9.967-36.087-21.996m85.07-2.576l19.588-11.341c5.157 8.421 11.859 14.607 23.715 14.607c9.969 0 16.325-4.984 16.325-11.858c0-8.248-6.53-11.17-17.528-15.98l-6.013-2.58c-17.357-7.387-28.87-16.667-28.87-36.257c0-18.044 13.747-31.792 35.228-31.792c15.294 0 26.292 5.328 34.196 19.247l-18.732 12.03c-4.125-7.389-8.591-10.31-15.465-10.31c-7.046 0-11.514 4.468-11.514 10.31c0 7.217 4.468 10.14 14.778 14.608l6.014 2.577c20.45 8.765 31.963 17.7 31.963 37.804c0 21.654-17.012 33.51-39.867 33.51c-22.339 0-36.774-10.654-43.819-24.574"></path></svg>
@@ -0,0 +1,27 @@
1
+ import "./style.css";
2
+ import viteLogo from "/vite.svg";
3
+ import { setupCounter } from "./counter.js";
4
+ import javascriptLogo from "./javascript.svg";
5
+ import { setupSayHello } from "./say.js";
6
+
7
+ document.querySelector("#app").innerHTML = `
8
+ <div>
9
+ <a href="https://vite.dev" target="_blank">
10
+ <img src="${viteLogo}" class="logo" alt="Vite logo" />
11
+ </a>
12
+ <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" target="_blank">
13
+ <img src="${javascriptLogo}" class="logo vanilla" alt="JavaScript logo" />
14
+ </a>
15
+ <h1>Hello Vite!</h1>
16
+ <div class="card">
17
+ <button id="counter" type="button"></button>
18
+ <button id="say-hello" type="button"></button>
19
+ </div>
20
+ <p class="read-the-docs">
21
+ Click on the Vite logo to learn more
22
+ </p>
23
+ </div>
24
+ `;
25
+
26
+ setupCounter(document.querySelector("#counter"));
27
+ setupSayHello(document.querySelector("#say-hello"));
@@ -0,0 +1,23 @@
1
+ export function setupSayHello(element) {
2
+ let message = "Click to say hello";
3
+ element.innerHTML = message;
4
+ const handleSayHello = () => {
5
+ if (!("google" in globalThis)) {
6
+ message = "Error. `google` is not defined";
7
+ element.innerHTML = message;
8
+ return;
9
+ }
10
+ google.script.run
11
+ .withSuccessHandler((result) => {
12
+ message = result;
13
+ element.innerHTML = message;
14
+ })
15
+ .withFailureHandler((error) => {
16
+ console.error(error);
17
+ message = "Error. Check the console.";
18
+ element.innerHTML = message;
19
+ })
20
+ .sayHello(userAddress);
21
+ };
22
+ element.addEventListener("click", handleSayHello);
23
+ }
@@ -0,0 +1,96 @@
1
+ :root {
2
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ a {
17
+ font-weight: 500;
18
+ color: #646cff;
19
+ text-decoration: inherit;
20
+ }
21
+ a:hover {
22
+ color: #535bf2;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ display: flex;
28
+ place-items: center;
29
+ min-width: 320px;
30
+ min-height: 100vh;
31
+ }
32
+
33
+ h1 {
34
+ font-size: 3.2em;
35
+ line-height: 1.1;
36
+ }
37
+
38
+ #app {
39
+ max-width: 1280px;
40
+ margin: 0 auto;
41
+ padding: 2rem;
42
+ text-align: center;
43
+ }
44
+
45
+ .logo {
46
+ height: 6em;
47
+ padding: 1.5em;
48
+ will-change: filter;
49
+ transition: filter 300ms;
50
+ }
51
+ .logo:hover {
52
+ filter: drop-shadow(0 0 2em #646cffaa);
53
+ }
54
+ .logo.vanilla:hover {
55
+ filter: drop-shadow(0 0 2em #f7df1eaa);
56
+ }
57
+
58
+ .card {
59
+ padding: 2em;
60
+ }
61
+
62
+ .read-the-docs {
63
+ color: #888;
64
+ }
65
+
66
+ button {
67
+ border-radius: 8px;
68
+ border: 1px solid transparent;
69
+ padding: 0.6em 1.2em;
70
+ font-size: 1em;
71
+ font-weight: 500;
72
+ font-family: inherit;
73
+ background-color: #1a1a1a;
74
+ cursor: pointer;
75
+ transition: border-color 0.25s;
76
+ }
77
+ button:hover {
78
+ border-color: #646cff;
79
+ }
80
+ button:focus,
81
+ button:focus-visible {
82
+ outline: 4px auto -webkit-focus-ring-color;
83
+ }
84
+
85
+ @media (prefers-color-scheme: light) {
86
+ :root {
87
+ color: #213547;
88
+ background-color: #ffffff;
89
+ }
90
+ a:hover {
91
+ color: #747bff;
92
+ }
93
+ button {
94
+ background-color: #f9f9f9;
95
+ }
96
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2022",
4
+ "useDefineForClassFields": true,
5
+ "module": "esnext",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "isolatedModules": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedSideEffectImports": true,
22
+
23
+ "allowJs": true,
24
+ "checkJs": false,
25
+ "types": ["node", "google-apps-script"],
26
+
27
+ // Aliases
28
+ "paths": {
29
+ "@/*": ["./src/*"],
30
+ "~/*": ["./*"]
31
+ }
32
+ },
33
+ "include": ["src", "tests", "types", "./*.*js"]
34
+ }
@@ -0,0 +1,11 @@
1
+ import tsconfigPaths from "vite-tsconfig-paths";
2
+ import { defineConfig } from "vitest/config";
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ coverage: {
7
+ include: ["src/**/*"],
8
+ },
9
+ },
10
+ plugins: [tsconfigPaths()],
11
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/clasp.json",
3
+ "scriptId": "{{ input your script id of apps-script }}",
4
+ "rootDir": "dist"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/clasp.json",
3
+ "scriptId": "{{ input your script id of apps-script }}",
4
+ "rootDir": "dist"
5
+ }
@@ -0,0 +1 @@
1
+ GAS_DEPLOYMENT_ID=input your deployment id
@@ -0,0 +1,45 @@
1
+ name: Publish to GoogleAppsScript
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*' # Trigger on tags like v1.0.0, v0.1.2, etc.
7
+ workflow_dispatch: # Trigger manually
8
+
9
+ jobs:
10
+ build-and-publish:
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ contents: read
14
+
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: '20.x'
23
+ registry-url: 'https://registry.npmjs.org'
24
+
25
+ - name: Install pnpm
26
+ uses: pnpm/action-setup@v4
27
+ with:
28
+ version: 10
29
+
30
+ - name: Install dependencies
31
+ run: pnpm install
32
+
33
+ - name: Prebuild
34
+ run: pnpm run check && pnpm run test
35
+
36
+ - name: Build package
37
+ run: pnpm run build
38
+
39
+ - name: Restore clasp credentials
40
+ uses: ciderjs/clasp-auth@v0.1.3
41
+ with:
42
+ json: {{ secrets.CLASPRC_JSON }}
43
+
44
+ - name: Publish to AppsScript
45
+ run: pnpm run push
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["Vue.volar"]
3
+ }
@@ -0,0 +1,14 @@
1
+ # Vue 3 + TypeScript + Vite
2
+
3
+ This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
4
+
5
+ Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
6
+
7
+ ## Using Clasp authentication in CI/CD workflow with @ciderjs/clasp-auth
8
+
9
+ You can upload your Clasp authentication json file to your Github repository, and use it in CI/CD cycle.
10
+
11
+ 0. Log in with @google/clasp, GitHub CLI
12
+ 1. `pnpm run auth repoOwner/repoName` * replace with repository name
13
+ 2. Push code, and set Version Tag in GitHub
14
+ 3. ...and your codes are pushed and deployed to Apps-Script!
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.4/schema.json",
3
+ "vcs": {
4
+ "enabled": true,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": true
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false
10
+ },
11
+ "formatter": {
12
+ "enabled": true,
13
+ "indentStyle": "space",
14
+ "indentWidth": 2
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true
20
+ }
21
+ },
22
+ "javascript": {
23
+ "formatter": {
24
+ "quoteStyle": "double"
25
+ }
26
+ },
27
+ "assist": {
28
+ "enabled": true,
29
+ "actions": {
30
+ "source": {
31
+ "organizeImports": "on"
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title><%= projectName %></title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build:server": "rolldown -c && cpy server/*.json dist/",
9
+ "build:front": "vue-tsc -b && vite build",
10
+ "build": "rimraf dist && pnpm run build:front && pnpm run build:server",
11
+ "check": "biome check --write",
12
+ "generate": "gasnuki",
13
+ "test": "vitest run --coverage",
14
+ "auth": "clasp-auth upload",
15
+ "push": "clasp push",
16
+ "deploy": "clasp create-deployment",
17
+ "update": "dotenv cross-var \"clasp update-deployment $GAS_DEPLOYMENT_ID\"",
18
+ "preview:local": "vite preview",
19
+ "preview:web": "clasp open-web-app"
20
+ },
21
+ "dependencies": {
22
+ "@ciderjs/city-gas": "^0.2.0",
23
+ "@ciderjs/gasnuki": "^0.3.2",
24
+ "vue": "^3.5.22"
25
+ },
26
+ "devDependencies": {
27
+ "@biomejs/biome": "^2.3.4",
28
+ "@ciderjs/clasp-auth": "^0.1.3",
29
+ "@google/clasp": "^3.1.1",
30
+ "@rollup/plugin-alias": "^6.0.0",
31
+ "@types/google-apps-script": "^2.0.7",
32
+ "@types/node": "^24.6.0",
33
+ "@vitejs/plugin-vue": "^6.0.1",
34
+ "@vitest/coverage-v8": "^4.0.8",
35
+ "@vue/tsconfig": "^0.8.1",
36
+ "cpy-cli": "^6.0.0",
37
+ "cross-var": "^1.1.0",
38
+ "dotenv-cli": "^11.0.0",
39
+ "rimraf": "^6.1.0",
40
+ "rolldown": "1.0.0-beta.47",
41
+ "rolldown-plugin-remove-export": "^0.1.3",
42
+ "typescript": "~5.9.3",
43
+ "vite": "^7.1.7",
44
+ "vite-plugin-google-apps-script": "^0.4.0",
45
+ "vite-plugin-singlefile": "^2.3.0",
46
+ "vite-tsconfig-paths": "^5.1.4",
47
+ "vitest": "^4.0.8",
48
+ "vue-tsc": "^3.1.0"
49
+ }
50
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,25 @@
1
+ import path from "node:path";
2
+ import alias from "@rollup/plugin-alias";
3
+ import { defineConfig } from "rolldown";
4
+ import { removeExportPlugin } from "rolldown-plugin-remove-export";
5
+
6
+ const outputFile = "app.js";
7
+
8
+ export default defineConfig({
9
+ input: "server/app.ts",
10
+ output: {
11
+ format: "esm",
12
+ file: `dist/${outputFile}`,
13
+ },
14
+ plugins: [
15
+ alias({
16
+ entries: [
17
+ {
18
+ find: "~",
19
+ replacement: path.resolve(__dirname),
20
+ },
21
+ ],
22
+ }),
23
+ removeExportPlugin(outputFile),
24
+ ],
25
+ });
@@ -0,0 +1,29 @@
1
+ import type { ServerParams, WebAppParams } from "~/types/appsscript/server";
2
+
3
+ export * from "./modules/hello";
4
+
5
+ const SITE_TITLE = "<%= projectName %>";
6
+
7
+ /**
8
+ * Procedure to handle GET requests when published as a web app
9
+ */
10
+ export function doGet(e: WebAppParams) {
11
+ const htmlTemplate = HtmlService.createTemplateFromFile("index");
12
+ const title = SITE_TITLE;
13
+ const userAddress = Session.getActiveUser().getEmail();
14
+
15
+ // set initial data for front-end
16
+ htmlTemplate.parameters = JSON.stringify({
17
+ ...e,
18
+ siteTitle: title,
19
+ userAddress: userAddress,
20
+ } satisfies ServerParams);
21
+
22
+ const htmlOutput = htmlTemplate.evaluate();
23
+ htmlOutput.setTitle(title);
24
+ htmlOutput.addMetaTag(
25
+ "viewport",
26
+ "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui",
27
+ );
28
+ return htmlOutput;
29
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "timeZone": "Asia/Tokyo",
3
+ "dependencies": {
4
+ "libraries": []
5
+ },
6
+ "exceptionLogging": "STACKDRIVER",
7
+ "runtimeVersion": "V8",
8
+ "webapp": {
9
+ "executeAs": "USER_ACCESSING",
10
+ "access": "ANYONE"
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ export function sayHello(name: string): string {
2
+ return `Hello, ${name}!`;
3
+ }
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <RouterOutlet />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { RouterOutlet } from "@ciderjs/city-gas/vue";
7
+ </script>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
@@ -0,0 +1,54 @@
1
+ <script setup lang="ts">
2
+ import { ref } from "vue";
3
+ import { parameters } from "@/lib/parameters";
4
+ import { serverScripts } from "@/lib/server";
5
+
6
+ defineProps<{ msg: string }>();
7
+
8
+ const { userAddress } = parameters;
9
+
10
+ const count = ref(0);
11
+ const message = ref("Click to say hello");
12
+
13
+ const handleHelloButton = async () => {
14
+ message.value = "Waiting...";
15
+ try {
16
+ message.value = await serverScripts.sayHello(userAddress);
17
+ } catch (error) {
18
+ console.error(error);
19
+ message.value = "Error. Check the console.";
20
+ }
21
+ };
22
+ </script>
23
+
24
+ <template>
25
+ <h1>{{ msg }}</h1>
26
+
27
+ <div class="card">
28
+ <button type="button" @click="count++">count is {{ count }}</button>
29
+ <button type="button" @click="handleHelloButton" :style="{ marginLeft: '10px' }">
30
+ {{ message }}
31
+ </button>
32
+ <p>
33
+ Edit
34
+ <code>components/HelloWorld.vue</code> to test HMR
35
+ </p>
36
+ </div>
37
+
38
+ <p>
39
+ Check out
40
+ <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a>, the official Vue + Vite
41
+ starter
42
+ </p>
43
+ <p>
44
+ Learn more about IDE Support for Vue in the
45
+ <a href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support" target="_blank">Vue Docs Scaling up Guide</a>.
46
+ </p>
47
+ <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
48
+ </template>
49
+
50
+ <style scoped>
51
+ .read-the-docs {
52
+ color: #888;
53
+ }
54
+ </style>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <nav>
3
+ <button type="button" @click="goHome">Go Home</button>
4
+ <button type="button" @click="goAbout">Go About</button>
5
+ <button type="button" @click="goUser">Go User 123</button>
6
+ </nav>
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { useNavigate } from "@ciderjs/city-gas/vue";
11
+
12
+ const navigate = useNavigate();
13
+
14
+ const goHome = () => navigate("/");
15
+ const goAbout = () => navigate("/about");
16
+ const goUser = () => navigate("/detail/user", { id: "123" });
17
+ </script>
18
+
19
+ <style scoped>
20
+ button {
21
+ margin-right: 10px;
22
+ }
23
+ </style>
@@ -0,0 +1,20 @@
1
+ import type { ServerParams } from "~/types/appsscript/server";
2
+
3
+ let parameters: ServerParams = {} as ServerParams;
4
+
5
+ try {
6
+ const parametersJson = "<?!= JSON.stringify(parameters) ?>";
7
+ parameters = JSON.parse(
8
+ parametersJson.slice(1, parametersJson.length - 1).replace(/\\"/g, '"'),
9
+ );
10
+ } catch {
11
+ // mockup parameters to simulate as server access
12
+ parameters = {
13
+ ...parameters,
14
+ parameter: {},
15
+ siteTitle: "Mockup Site Title",
16
+ userAddress: "mock-user@example.com",
17
+ };
18
+ }
19
+
20
+ export { parameters };
@@ -0,0 +1,18 @@
1
+ import {
2
+ getPromisedServerScripts,
3
+ type PartialScriptType,
4
+ } from "@ciderjs/gasnuki/promise";
5
+ import type { ServerScripts } from "~/types/appsscript/client";
6
+
7
+ // mockup function to simulate as fetching appsscript time
8
+ export const sleep = (ms: number) =>
9
+ new Promise((resolve) => setTimeout(resolve, ms));
10
+
11
+ const mockup: PartialScriptType<ServerScripts> = {
12
+ sayHello: async (name) => {
13
+ await sleep(1000);
14
+ return `Hello, ${name}!`;
15
+ },
16
+ };
17
+
18
+ export const serverScripts = getPromisedServerScripts<ServerScripts>(mockup);
@@ -0,0 +1,13 @@
1
+ import { createRouter } from "@ciderjs/city-gas";
2
+ import { createRouterPlugin } from "@ciderjs/city-gas/vue";
3
+ import { createApp } from "vue";
4
+ import "@/style.css";
5
+ import App from "@/App.vue";
6
+ import { pages, specialPages } from "@/generated/routes";
7
+
8
+ function main() {
9
+ const router = createRouter(pages, { specialPages });
10
+ createApp(App).use(createRouterPlugin(router)).mount("#app");
11
+ }
12
+
13
+ main();
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div>
3
+ <header>
4
+ <Navigation />
5
+ </header>
6
+ <main>
7
+ <div>
8
+ <a href="https://vite.dev" target="_blank">
9
+ <img src="/vite.svg" class="logo" alt="Vite logo" />
10
+ </a>
11
+ <a href="https://vuejs.org/" target="_blank">
12
+ <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
13
+ </a>
14
+ </div>
15
+ <slot />
16
+ </main>
17
+ <footer>Footer</footer>
18
+ </div>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import Navigation from "@/components/Navigation.vue";
23
+ </script>
24
+
25
+ <style scoped>
26
+ .logo {
27
+ height: 6em;
28
+ padding: 1.5em;
29
+ will-change: filter;
30
+ transition: filter 300ms;
31
+ }
32
+
33
+ .logo:hover {
34
+ filter: drop-shadow(0 0 2em #646cffaa);
35
+ }
36
+
37
+ .logo.vue:hover {
38
+ filter: drop-shadow(0 0 2em #42b883aa);
39
+ }
40
+ </style>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div>
3
+ <h2>About Page</h2>
4
+ <p>This is the about page.</p>
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ </script>
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div>
3
+ <h2>User Show Page</h2>
4
+ <p>User ID: {{ params.id }}</p>
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ import { useParams } from "@ciderjs/city-gas/vue";
10
+
11
+ const params = useParams<"/detail/user">();
12
+ </script>
13
+
14
+ <script lang="ts">
15
+ export const params = { id: 'string' };
16
+ </script>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <HelloWorld msg="Hello CiderJS!" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import HelloWorld from "@/components/HelloWorld.vue";
7
+ </script>
@@ -0,0 +1,79 @@
1
+ :root {
2
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ a {
17
+ font-weight: 500;
18
+ color: #646cff;
19
+ text-decoration: inherit;
20
+ }
21
+ a:hover {
22
+ color: #535bf2;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ display: flex;
28
+ place-items: center;
29
+ min-width: 320px;
30
+ min-height: 100vh;
31
+ }
32
+
33
+ h1 {
34
+ font-size: 3.2em;
35
+ line-height: 1.1;
36
+ }
37
+
38
+ button {
39
+ border-radius: 8px;
40
+ border: 1px solid transparent;
41
+ padding: 0.6em 1.2em;
42
+ font-size: 1em;
43
+ font-weight: 500;
44
+ font-family: inherit;
45
+ background-color: #1a1a1a;
46
+ cursor: pointer;
47
+ transition: border-color 0.25s;
48
+ }
49
+ button:hover {
50
+ border-color: #646cff;
51
+ }
52
+ button:focus,
53
+ button:focus-visible {
54
+ outline: 4px auto -webkit-focus-ring-color;
55
+ }
56
+
57
+ .card {
58
+ padding: 2em;
59
+ }
60
+
61
+ #app {
62
+ max-width: 1280px;
63
+ margin: 0 auto;
64
+ padding: 2rem;
65
+ text-align: center;
66
+ }
67
+
68
+ @media (prefers-color-scheme: light) {
69
+ :root {
70
+ color: #213547;
71
+ background-color: #ffffff;
72
+ }
73
+ a:hover {
74
+ color: #747bff;
75
+ }
76
+ button {
77
+ background-color: #f9f9f9;
78
+ }
79
+ }
@@ -0,0 +1,9 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { sayHello } from "~/server/modules/hello";
3
+
4
+ describe("hello", () => {
5
+ it("should say hello", () => {
6
+ const name = "world";
7
+ expect(sayHello(name)).toBe(`Hello, ${name}!`);
8
+ });
9
+ });
@@ -0,0 +1,8 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { serverScripts } from "@/lib/server";
3
+
4
+ describe("server", () => {
5
+ it("should be defined", () => {
6
+ expect(serverScripts).toBeDefined();
7
+ });
8
+ });
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
3
+ "compilerOptions": {
4
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
5
+ "types": ["vite/client", "@types/google-apps-script"],
6
+
7
+ /* Linting */
8
+ "strict": true,
9
+ "noUnusedLocals": true,
10
+ "noUnusedParameters": true,
11
+ "erasableSyntaxOnly": true,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "noUncheckedSideEffectImports": true,
14
+
15
+ "paths": {
16
+ "@/*": ["./src/*"],
17
+ "~/*": ["./*"]
18
+ }
19
+ },
20
+ "include": ["src", "tests", "server", "types"]
21
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ],
7
+ "compilerOptions": {
8
+ "paths": {
9
+ "@/*": ["./src/*"],
10
+ "~/*": ["./*"]
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2023",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "types": ["node"],
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "verbatimModuleSyntax": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "erasableSyntaxOnly": true,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noUncheckedSideEffectImports": true
24
+ },
25
+ "include": ["rolldown.config.ts", "vite.config.ts"]
26
+ }
@@ -0,0 +1,10 @@
1
+ export interface WebAppParams<T extends string = string>
2
+ extends GoogleAppsScript.Events.DoGet {
3
+ parameter: Record<T, string>;
4
+ parameters: Record<T, string[]>;
5
+ }
6
+
7
+ export type ServerParams = WebAppParams & {
8
+ siteTitle: string;
9
+ userAddress: string;
10
+ };
@@ -0,0 +1,27 @@
1
+ /// <reference types="vitest" />
2
+
3
+ import { cityGasRouter } from "@ciderjs/city-gas/plugin";
4
+ import { gasnuki } from "@ciderjs/gasnuki/vite";
5
+ import vue from "@vitejs/plugin-vue";
6
+ import { defineConfig } from "vite";
7
+ import { gas } from "vite-plugin-google-apps-script";
8
+ import { viteSingleFile } from "vite-plugin-singlefile";
9
+ import tsconfigPaths from "vite-tsconfig-paths";
10
+
11
+ // https://vite.dev/config/
12
+ export default defineConfig({
13
+ plugins: [
14
+ vue(),
15
+ tsconfigPaths({
16
+ loose: true,
17
+ }),
18
+ cityGasRouter(),
19
+ gasnuki({
20
+ srcDir: "server",
21
+ outDir: "types/appsscript",
22
+ outputFile: "client.ts",
23
+ }),
24
+ gas(),
25
+ viteSingleFile(),
26
+ ],
27
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciderjs/gasbombe",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "A TypeScript Project Generator for GoogleAppsScript, available as CLI",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",