@ciderjs/gasbombe 0.1.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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +98 -0
  3. package/README.md +98 -0
  4. package/dist/cli.cjs +59 -0
  5. package/dist/cli.d.cts +4 -0
  6. package/dist/cli.d.mts +4 -0
  7. package/dist/cli.d.ts +4 -0
  8. package/dist/cli.mjs +57 -0
  9. package/dist/index.cjs +108 -0
  10. package/dist/index.d.cts +10 -0
  11. package/dist/index.d.mts +10 -0
  12. package/dist/index.d.ts +10 -0
  13. package/dist/index.mjs +108 -0
  14. package/dist/templates/common/.gitignore.ejs +28 -0
  15. package/dist/templates/react-tsx/.clasp.json.ejs +5 -0
  16. package/dist/templates/react-tsx/.env.ejs +1 -0
  17. package/dist/templates/react-tsx/README.md.ejs +69 -0
  18. package/dist/templates/react-tsx/biome.json.ejs +65 -0
  19. package/dist/templates/react-tsx/gasnuki.config.ts.ejs +7 -0
  20. package/dist/templates/react-tsx/index.html.ejs +13 -0
  21. package/dist/templates/react-tsx/package.json.ejs +48 -0
  22. package/dist/templates/react-tsx/pnpm-lock.yaml.ejs +6015 -0
  23. package/dist/templates/react-tsx/pnpm-workspace.yaml.ejs +3 -0
  24. package/dist/templates/react-tsx/public/vite.svg.ejs +1 -0
  25. package/dist/templates/react-tsx/rolldown.config.ts.ejs +25 -0
  26. package/dist/templates/react-tsx/server/app.ts.ejs +29 -0
  27. package/dist/templates/react-tsx/server/appsscript.json.ejs +12 -0
  28. package/dist/templates/react-tsx/server/modules/hello.ts.ejs +3 -0
  29. package/dist/templates/react-tsx/src/App.css.ejs +42 -0
  30. package/dist/templates/react-tsx/src/App.tsx.ejs +58 -0
  31. package/dist/templates/react-tsx/src/assets/react.svg.ejs +1 -0
  32. package/dist/templates/react-tsx/src/index.css.ejs +68 -0
  33. package/dist/templates/react-tsx/src/lib/parameters.ts.ejs +20 -0
  34. package/dist/templates/react-tsx/src/lib/server.ts.ejs +18 -0
  35. package/dist/templates/react-tsx/src/main.tsx.ejs +11 -0
  36. package/dist/templates/react-tsx/src/vite-env.d.ts.ejs +1 -0
  37. package/dist/templates/react-tsx/tests/server/modules/hello.spec.ts.ejs +9 -0
  38. package/dist/templates/react-tsx/tests/src/lib/server.spec.ts.ejs +8 -0
  39. package/dist/templates/react-tsx/tsconfig.app.json.ejs +31 -0
  40. package/dist/templates/react-tsx/tsconfig.json.ejs +13 -0
  41. package/dist/templates/react-tsx/tsconfig.node.json.ejs +25 -0
  42. package/dist/templates/react-tsx/types/appsscript/client.ts.ejs +57 -0
  43. package/dist/templates/react-tsx/types/appsscript/server.ts.ejs +10 -0
  44. package/dist/templates/react-tsx/vite.config.ts.ejs +20 -0
  45. package/dist/templates/vanilla-ts/.clasp.json.ejs +5 -0
  46. package/dist/templates/vanilla-ts/.env.ejs +1 -0
  47. package/dist/templates/vanilla-ts/README.md.ejs +1 -0
  48. package/dist/templates/vanilla-ts/biome.json.ejs +36 -0
  49. package/dist/templates/vanilla-ts/package.json.ejs +33 -0
  50. package/dist/templates/vanilla-ts/pnpm-lock.yaml.ejs +5300 -0
  51. package/dist/templates/vanilla-ts/pnpm-workspace.yaml.ejs +3 -0
  52. package/dist/templates/vanilla-ts/rolldown.config.ts.ejs +29 -0
  53. package/dist/templates/vanilla-ts/src/main.ts.ejs +5 -0
  54. package/dist/templates/vanilla-ts/src/modules/hello.ts.ejs +3 -0
  55. package/dist/templates/vanilla-ts/tests/main.test.ts.ejs +15 -0
  56. package/dist/templates/vanilla-ts/tsconfig.json.ejs +30 -0
  57. package/dist/templates/vanilla-ts/vitest.config.ts.ejs +11 -0
  58. package/package.json +58 -0
  59. package/src/index.ts +114 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 luth
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.ja.md ADDED
@@ -0,0 +1,98 @@
1
+ # **GasBombe**
2
+
3
+ [![README-en](https://img.shields.io/badge/English-blue?logo=ReadMe)](./README.md)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+ [![npm version](https://img.shields.io/npm/v/@ciderjs/gasbombe.svg)](https://www.npmjs.com/package/@ciderjs/gasbombe)
6
+ [![GitHub issues](https://img.shields.io/github/issues/luthpg/gasbombe.svg)](https://github.com/luthpg/gasbombe/issues)
7
+
8
+ 🛢 「Gasbombe」は、GoogleAppsScriptのためのTypeScriptプロジェクトジェネレーターです。
9
+
10
+ このプロジェクトは、Vanilla TSおよびReactのテンプレートを使用して、Google Apps Script用の新しいTypeScriptプロジェクトを構築するためのコマンドラインインターフェース(CLI)を提供します。
11
+
12
+ ## **機能**
13
+
14
+ * **CLIツール**: 対話型のコマンドラインプロンプトにより、プロジェクトのセットアップをガイドします。
15
+ * **テンプレート**:
16
+ * Vanilla TypeScript
17
+ * React with TSX
18
+ * **パッケージマネージャーのサポート**: npm、Yarn、pnpmに対応しています。
19
+
20
+ ## **使用方法**
21
+
22
+ ### **インストール**
23
+
24
+ `npx`を使用すると、グローバルにインストールせずにCLIを実行できます。
25
+
26
+ ```bash
27
+ npx @ciderjs/gasbombe
28
+ ```
29
+
30
+ または、グローバルにインストールすることもできます。
31
+
32
+ ```bash
33
+ npm install -g @ciderjs/gasbombe
34
+ ```
35
+
36
+ ### **使い方**
37
+
38
+ コマンドを実行し、対話型のプロンプトに従ってください。
39
+
40
+ ```bash
41
+ gasbombe
42
+ ```
43
+
44
+ 以下の項目について質問されます。
45
+
46
+ 1. プロジェクト名
47
+ 2. パッケージマネージャー(npm, yarn, pnpm)
48
+ 3. テンプレート(Vanilla TS, React)
49
+
50
+ このツールは、指定されたプロジェクト名で新しいディレクトリを作成し、テンプレートファイルを生成して、依存関係をインストールします。
51
+
52
+ ### **CLIオプション**
53
+
54
+ コマンドラインオプションを指定することで、対話型のプロンプトを省略できます。これは、スクリプトや自動化に便利です。
55
+
56
+ ```bash
57
+ # 例: pnpmを使用して新しいReactプロジェクトを作成する
58
+ gasbombe --name my-react-app --pkg pnpm --template react-tsx
59
+ ```
60
+
61
+ | オプション | 引数 | 説明 | 選択肢 |
62
+ | :--- | :--- | :--- | :--- |
63
+ | `--name` | `[projectName]` | 生成するプロジェクトの名前。 | - |
64
+ | `--pkg` | `[packageManager]` | 使用するパッケージマネージャー。 | `npm`, `pnpm`, `yarn` |
65
+ | `--template` | `[templateType]` | 使用するプロジェクトテンプレート。 | `vanilla-ts`, `react-tsx` |
66
+
67
+ これらのオプションのいずれかが省略された場合、対話形式で値を入力するよう求められます。
68
+
69
+ ## **開発**
70
+
71
+ ### **前提条件**
72
+
73
+ * [Node.js](https://nodejs.org/)
74
+ * [pnpm](https://pnpm.io/installation)
75
+
76
+ ### **セットアップ**
77
+
78
+ リポジトリをクローンし、依存関係をインストールします。
79
+
80
+ ```bash
81
+ git clone https://github.com/luthpg/gasbombe.git
82
+ cd gasbombe
83
+ pnpm install
84
+ ```
85
+
86
+ ### **ビルド**
87
+
88
+ プロジェクトをローカルでビルドするには:
89
+
90
+ ```bash
91
+ pnpm run build
92
+ ```
93
+
94
+ これにより、必要なファイルが`dist`ディレクトリに生成されます。
95
+
96
+ ## **ライセンス**
97
+
98
+ このプロジェクトはMITライセンスの下で公開されています。詳細は[LICENSE](LICENSE)ファイルをご覧ください。
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # **GasBombe**
2
+
3
+ [![README-ja](https://img.shields.io/badge/English-blue?logo=ReadMe)](./README.ja.md)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+ [![npm version](https://img.shields.io/npm/v/@ciderjs/gasbombe.svg)](https://www.npmjs.com/package/@ciderjs/gasbombe)
6
+ [![GitHub issues](https://img.shields.io/github/issues/luthpg/gasbombe.svg)](https://github.com/luthpg/gasbombe/issues)
7
+
8
+ 🛢 'Gasbombe' the TypeScript Project Generator for GoogleAppsScript.
9
+
10
+ This project provides a command-line interface (CLI) to scaffold new TypeScript projects for Google Apps Script, with templates for Vanilla TS and React.
11
+
12
+ ## **Features**
13
+
14
+ * **CLI Tool**: Interactive command-line prompts to guide you through project setup.
15
+ * **Templates**:
16
+ * Vanilla TypeScript
17
+ * React with TSX
18
+ * **Package Manager Support**: Works with npm, Yarn, and pnpm.
19
+
20
+ ## **Usage**
21
+
22
+ ### **Installation**
23
+
24
+ You can use `npx` to run the CLI without installing it globally:
25
+
26
+ ```bash
27
+ npx @ciderjs/gasbombe
28
+ ```
29
+
30
+ Or, you can install it globally:
31
+
32
+ ```bash
33
+ npm install -g @ciderjs/gasbombe
34
+ ```
35
+
36
+ ### **How to Use**
37
+
38
+ Run the command and follow the interactive prompts:
39
+
40
+ ```bash
41
+ gasbombe
42
+ ```
43
+
44
+ You will be asked for:
45
+
46
+ 1. Project name
47
+ 2. Package manager (npm, yarn, pnpm)
48
+ 3. Template (Vanilla TS, React)
49
+
50
+ The tool will create a new directory with the specified project name, generate the template files, and install the dependencies.
51
+
52
+ ### **CLI Options**
53
+
54
+ You can bypass the interactive prompts by providing command-line options. This is useful for scripting and automation.
55
+
56
+ ```bash
57
+ # Example: Create a new React project with pnpm
58
+ gasbombe --name my-react-app --pkg pnpm --template react-tsx
59
+ ```
60
+
61
+ | Option | Argument | Description | Choices |
62
+ | ---------- | ------------------ | -------------------------------- | ------------------------- |
63
+ | `--name` | `[projectName]` | The name of the project to generate. | - |
64
+ | `--pkg` | `[packageManager]` | The package manager to use. | `npm`, `pnpm`, `yarn` |
65
+ | `--template` | `[templateType]` | The project template to use. | `vanilla-ts`, `react-tsx` |
66
+
67
+ If any of these options are omitted, you will be prompted to enter the value interactively.
68
+
69
+ ## **Development**
70
+
71
+ ### **Prerequisites**
72
+
73
+ * [Node.js](https://nodejs.org/)
74
+ * [pnpm](https://pnpm.io/installation)
75
+
76
+ ### **Setup**
77
+
78
+ Clone the repository and install the dependencies:
79
+
80
+ ```bash
81
+ git clone https://github.com/luthpg/gasbombe.git
82
+ cd gasbombe
83
+ pnpm install
84
+ ```
85
+
86
+ ### **Build**
87
+
88
+ To build the project locally:
89
+
90
+ ```bash
91
+ pnpm run build
92
+ ```
93
+
94
+ This will generate the necessary files in the `dist` directory.
95
+
96
+ ## **License**
97
+
98
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
package/dist/cli.cjs ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const prompts = require('@inquirer/prompts');
5
+ const commander = require('commander');
6
+ const index = require('./index.cjs');
7
+ require('node:child_process');
8
+ require('node:fs/promises');
9
+ require('node:path');
10
+ require('consola');
11
+ require('ejs');
12
+ require('glob');
13
+
14
+ const version = "0.1.0";
15
+
16
+ async function main() {
17
+ const program = new commander.Command();
18
+ program.version(version, "-v, --version");
19
+ program.description("Create project for GoogleAppsScript").option(
20
+ "--name [projectName]",
21
+ "Project name what you want to generate",
22
+ ""
23
+ ).option(
24
+ "--pkg [packageManager]",
25
+ 'Package manager what you want to use ("npm" | "pnpm" | "yarn")',
26
+ ""
27
+ ).option(
28
+ "--template [templateType]",
29
+ 'Project template label ("vanilla-ts" | "react-tsx")',
30
+ ""
31
+ ).action(async (_param, command) => {
32
+ let {
33
+ name: projectName,
34
+ pkg: packageManager,
35
+ template: templateType
36
+ } = command.opts();
37
+ try {
38
+ projectName ||= await prompts.input({
39
+ message: "Input project name what you want to generate..."
40
+ });
41
+ packageManager ||= await prompts.select({
42
+ message: "Choise package manager what you want to use...",
43
+ choices: ["npm", "pnpm", "yarn"]
44
+ });
45
+ templateType ||= await prompts.select({
46
+ message: "Choise project template...",
47
+ choices: ["vanilla-ts", "react-tsx"]
48
+ });
49
+ } catch (e) {
50
+ e.message === "User force closed the prompt with SIGINT" && process.exit(0);
51
+ throw e;
52
+ }
53
+ await index.generateProject({ projectName, packageManager, templateType });
54
+ });
55
+ program.parse(process.argv);
56
+ }
57
+ main();
58
+
59
+ exports.main = main;
package/dist/cli.d.cts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ declare function main(): Promise<void>;
3
+
4
+ export { main };
package/dist/cli.d.mts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ declare function main(): Promise<void>;
3
+
4
+ export { main };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ declare function main(): Promise<void>;
3
+
4
+ export { main };
package/dist/cli.mjs ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import { input, select } from '@inquirer/prompts';
3
+ import { Command } from 'commander';
4
+ import { generateProject } from './index.mjs';
5
+ import 'node:child_process';
6
+ import 'node:fs/promises';
7
+ import 'node:path';
8
+ import 'consola';
9
+ import 'ejs';
10
+ import 'glob';
11
+
12
+ const version = "0.1.0";
13
+
14
+ async function main() {
15
+ const program = new Command();
16
+ program.version(version, "-v, --version");
17
+ program.description("Create project for GoogleAppsScript").option(
18
+ "--name [projectName]",
19
+ "Project name what you want to generate",
20
+ ""
21
+ ).option(
22
+ "--pkg [packageManager]",
23
+ 'Package manager what you want to use ("npm" | "pnpm" | "yarn")',
24
+ ""
25
+ ).option(
26
+ "--template [templateType]",
27
+ 'Project template label ("vanilla-ts" | "react-tsx")',
28
+ ""
29
+ ).action(async (_param, command) => {
30
+ let {
31
+ name: projectName,
32
+ pkg: packageManager,
33
+ template: templateType
34
+ } = command.opts();
35
+ try {
36
+ projectName ||= await input({
37
+ message: "Input project name what you want to generate..."
38
+ });
39
+ packageManager ||= await select({
40
+ message: "Choise package manager what you want to use...",
41
+ choices: ["npm", "pnpm", "yarn"]
42
+ });
43
+ templateType ||= await select({
44
+ message: "Choise project template...",
45
+ choices: ["vanilla-ts", "react-tsx"]
46
+ });
47
+ } catch (e) {
48
+ e.message === "User force closed the prompt with SIGINT" && process.exit(0);
49
+ throw e;
50
+ }
51
+ await generateProject({ projectName, packageManager, templateType });
52
+ });
53
+ program.parse(process.argv);
54
+ }
55
+ main();
56
+
57
+ export { main };
package/dist/index.cjs ADDED
@@ -0,0 +1,108 @@
1
+ 'use strict';
2
+
3
+ const node_child_process = require('node:child_process');
4
+ const fs = require('node:fs/promises');
5
+ const path = require('node:path');
6
+ const consola = require('consola');
7
+ const ejs = require('ejs');
8
+ const glob = require('glob');
9
+
10
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
11
+
12
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
13
+ const path__default = /*#__PURE__*/_interopDefaultCompat(path);
14
+ const ejs__default = /*#__PURE__*/_interopDefaultCompat(ejs);
15
+
16
+ async function runCommand(command, args, cwd) {
17
+ return new Promise((resolve, reject) => {
18
+ const child = node_child_process.spawn(command, args, {
19
+ cwd,
20
+ stdio: "inherit",
21
+ shell: true
22
+ });
23
+ child.on("close", (code) => {
24
+ if (code === 0) {
25
+ resolve();
26
+ } else {
27
+ reject(new Error(`Command failed with exit code ${code}`));
28
+ }
29
+ });
30
+ child.on("error", (err) => {
31
+ reject(err);
32
+ });
33
+ });
34
+ }
35
+ async function generateProject({
36
+ projectName,
37
+ packageManager,
38
+ templateType
39
+ }) {
40
+ const outputDir = path__default.resolve(process.cwd(), projectName);
41
+ const templateBaseDir = path__default.resolve(__dirname, "..", "dist", "templates");
42
+ const commonTemplateDir = path__default.resolve(templateBaseDir, "common");
43
+ const specificTemplateDir = path__default.resolve(templateBaseDir, templateType);
44
+ consola.consola.start(
45
+ `Creating a new Project for GoogleAppsScript in ${outputDir}...`
46
+ );
47
+ try {
48
+ await fs__default.access(outputDir);
49
+ consola.consola.error(`Directory ${projectName} already exists.`);
50
+ process.exit(1);
51
+ } catch {
52
+ }
53
+ await fs__default.mkdir(outputDir, { recursive: true });
54
+ consola.consola.info(`Generating project files from template '${templateType}'...`);
55
+ const ejsData = { projectName };
56
+ const templateDirs = [commonTemplateDir, specificTemplateDir];
57
+ for (const dir of templateDirs) {
58
+ const files = await glob.glob("./**/*", {
59
+ cwd: dir,
60
+ nodir: true,
61
+ dot: true,
62
+ dotRelative: true,
63
+ follow: true,
64
+ windowsPathsNoEscape: true
65
+ });
66
+ for (const file of files) {
67
+ const templatePath = path__default.join(dir, file);
68
+ const outputPath = path__default.join(outputDir, file.replace(".ejs", ""));
69
+ await fs__default.mkdir(path__default.dirname(outputPath), { recursive: true });
70
+ const templateContent = await fs__default.readFile(templatePath, {
71
+ encoding: "utf-8"
72
+ });
73
+ const renderedContent = ejs__default.render(templateContent, ejsData);
74
+ await fs__default.writeFile(outputPath, renderedContent);
75
+ }
76
+ }
77
+ consola.consola.start(`Installing dependencies with ${packageManager}...`);
78
+ try {
79
+ await runCommand(packageManager, ["install"], outputDir);
80
+ consola.consola.success(`Dependencies installed successfully.`);
81
+ } catch (e) {
82
+ consola.consola.fail("Failed to install dependencies.");
83
+ consola.consola.error(e);
84
+ process.exit(1);
85
+ }
86
+ consola.consola.start(`Initializing Git repository...`);
87
+ try {
88
+ await runCommand("git", ["init"], outputDir);
89
+ await runCommand("git", ["add", "-A"], outputDir);
90
+ await runCommand(
91
+ "git",
92
+ ["commit", "-m", '"Initial commit from gasbombe"'],
93
+ outputDir
94
+ );
95
+ consola.consola.success(`Git repository initialized successfully.`);
96
+ } catch {
97
+ consola.consola.fail("Failed to initialize Git repository. Please do it manually.");
98
+ }
99
+ consola.consola.success(`Project '${projectName}' created successfully!`);
100
+ consola.consola.log(`
101
+ To get started, run:
102
+ `);
103
+ projectName !== "." && consola.consola.log(` cd ${projectName}`);
104
+ templateType !== "vanilla-ts" ? consola.consola.log(` ${packageManager} dev`) : consola.consola.log(` ...and write your GAS code!`);
105
+ }
106
+
107
+ exports.generateProject = generateProject;
108
+ exports.runCommand = runCommand;
@@ -0,0 +1,10 @@
1
+ interface ProjectOptions {
2
+ projectName: string;
3
+ packageManager: "npm" | "pnpm" | "yarn";
4
+ templateType: "vanilla-ts" | "react-tsx";
5
+ }
6
+
7
+ declare function runCommand(command: string, args: string[], cwd: string): Promise<void>;
8
+ declare function generateProject({ projectName, packageManager, templateType, }: ProjectOptions): Promise<void>;
9
+
10
+ export { generateProject, runCommand };
@@ -0,0 +1,10 @@
1
+ interface ProjectOptions {
2
+ projectName: string;
3
+ packageManager: "npm" | "pnpm" | "yarn";
4
+ templateType: "vanilla-ts" | "react-tsx";
5
+ }
6
+
7
+ declare function runCommand(command: string, args: string[], cwd: string): Promise<void>;
8
+ declare function generateProject({ projectName, packageManager, templateType, }: ProjectOptions): Promise<void>;
9
+
10
+ export { generateProject, runCommand };
@@ -0,0 +1,10 @@
1
+ interface ProjectOptions {
2
+ projectName: string;
3
+ packageManager: "npm" | "pnpm" | "yarn";
4
+ templateType: "vanilla-ts" | "react-tsx";
5
+ }
6
+
7
+ declare function runCommand(command: string, args: string[], cwd: string): Promise<void>;
8
+ declare function generateProject({ projectName, packageManager, templateType, }: ProjectOptions): Promise<void>;
9
+
10
+ export { generateProject, runCommand };
package/dist/index.mjs ADDED
@@ -0,0 +1,108 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { consola } from 'consola';
5
+ import ejs from 'ejs';
6
+ import { glob } from 'glob';
7
+
8
+
9
+
10
+ // -- Unbuild CommonJS Shims --
11
+ import __cjs_url__ from 'url';
12
+ import __cjs_path__ from 'path';
13
+ import __cjs_mod__ from 'module';
14
+ const __filename = __cjs_url__.fileURLToPath(import.meta.url);
15
+ const __dirname = __cjs_path__.dirname(__filename);
16
+ const require = __cjs_mod__.createRequire(import.meta.url);
17
+ async function runCommand(command, args, cwd) {
18
+ return new Promise((resolve, reject) => {
19
+ const child = spawn(command, args, {
20
+ cwd,
21
+ stdio: "inherit",
22
+ shell: true
23
+ });
24
+ child.on("close", (code) => {
25
+ if (code === 0) {
26
+ resolve();
27
+ } else {
28
+ reject(new Error(`Command failed with exit code ${code}`));
29
+ }
30
+ });
31
+ child.on("error", (err) => {
32
+ reject(err);
33
+ });
34
+ });
35
+ }
36
+ async function generateProject({
37
+ projectName,
38
+ packageManager,
39
+ templateType
40
+ }) {
41
+ const outputDir = path.resolve(process.cwd(), projectName);
42
+ const templateBaseDir = path.resolve(__dirname, "..", "dist", "templates");
43
+ const commonTemplateDir = path.resolve(templateBaseDir, "common");
44
+ const specificTemplateDir = path.resolve(templateBaseDir, templateType);
45
+ consola.start(
46
+ `Creating a new Project for GoogleAppsScript in ${outputDir}...`
47
+ );
48
+ try {
49
+ await fs.access(outputDir);
50
+ consola.error(`Directory ${projectName} already exists.`);
51
+ process.exit(1);
52
+ } catch {
53
+ }
54
+ await fs.mkdir(outputDir, { recursive: true });
55
+ consola.info(`Generating project files from template '${templateType}'...`);
56
+ const ejsData = { projectName };
57
+ const templateDirs = [commonTemplateDir, specificTemplateDir];
58
+ for (const dir of templateDirs) {
59
+ const files = await glob("./**/*", {
60
+ cwd: dir,
61
+ nodir: true,
62
+ dot: true,
63
+ dotRelative: true,
64
+ follow: true,
65
+ windowsPathsNoEscape: true
66
+ });
67
+ for (const file of files) {
68
+ const templatePath = path.join(dir, file);
69
+ const outputPath = path.join(outputDir, file.replace(".ejs", ""));
70
+ await fs.mkdir(path.dirname(outputPath), { recursive: true });
71
+ const templateContent = await fs.readFile(templatePath, {
72
+ encoding: "utf-8"
73
+ });
74
+ const renderedContent = ejs.render(templateContent, ejsData);
75
+ await fs.writeFile(outputPath, renderedContent);
76
+ }
77
+ }
78
+ consola.start(`Installing dependencies with ${packageManager}...`);
79
+ try {
80
+ await runCommand(packageManager, ["install"], outputDir);
81
+ consola.success(`Dependencies installed successfully.`);
82
+ } catch (e) {
83
+ consola.fail("Failed to install dependencies.");
84
+ consola.error(e);
85
+ process.exit(1);
86
+ }
87
+ consola.start(`Initializing Git repository...`);
88
+ try {
89
+ await runCommand("git", ["init"], outputDir);
90
+ await runCommand("git", ["add", "-A"], outputDir);
91
+ await runCommand(
92
+ "git",
93
+ ["commit", "-m", '"Initial commit from gasbombe"'],
94
+ outputDir
95
+ );
96
+ consola.success(`Git repository initialized successfully.`);
97
+ } catch {
98
+ consola.fail("Failed to initialize Git repository. Please do it manually.");
99
+ }
100
+ consola.success(`Project '${projectName}' created successfully!`);
101
+ consola.log(`
102
+ To get started, run:
103
+ `);
104
+ projectName !== "." && consola.log(` cd ${projectName}`);
105
+ templateType !== "vanilla-ts" ? consola.log(` ${packageManager} dev`) : consola.log(` ...and write your GAS code!`);
106
+ }
107
+
108
+ export { generateProject, runCommand };
@@ -0,0 +1,28 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
25
+
26
+ .clasp*.json
27
+ .env*
28
+ coverage
@@ -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