@goqoo/trunks 1.0.2 → 1.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.
package/README.ja.md CHANGED
@@ -17,6 +17,16 @@
17
17
 
18
18
  ## クイックスタート
19
19
 
20
+ ### init コマンドを使う
21
+
22
+ ```bash
23
+ npx @goqoo/trunks init
24
+ ```
25
+
26
+ 対話形式で `trunks.config.ts` ファイルを作成できます。
27
+
28
+ ### 手動セットアップ
29
+
20
30
  1. プロジェクトルートに設定ファイル `trunks.config.ts` を作成:
21
31
 
22
32
  ```typescript
@@ -159,15 +169,53 @@ pfx: {
159
169
  },
160
170
  ```
161
171
 
162
- ## CLI オプション
172
+ ## CLI
173
+
174
+ ### コマンド
175
+
176
+ ```bash
177
+ trunks init # 対話形式で trunks.config.ts を作成
178
+ trunks generate # 型定義を生成(デフォルトコマンド)
179
+ trunks # 'trunks generate' と同じ
180
+ ```
181
+
182
+ ### オプション
163
183
 
164
184
  ```bash
165
- trunks [options]
185
+ trunks generate [options]
166
186
 
167
187
  Options:
168
- -c, --config <path> 設定ファイルのパス(デフォルト: 自動検出)
169
- -h, --help ヘルプを表示
170
- -V, --version バージョンを表示
188
+ -c, --config <path> 設定ファイルのパス
189
+ -H, --host <host> kintone ホスト(例: example.cybozu.com)
190
+ -a, --app <name:id> 生成するアプリ(複数指定可)
191
+ -A, --auth-type <type> 認証方式: password, api-token, oauth
192
+ -u, --username <username> kintone ユーザー名(password 認証用)
193
+ -p, --password <password> kintone パスワード(password 認証用)
194
+ -t, --api-token <token> kintone API トークン(api-token 認証用)
195
+ --oauth-scope <scope> OAuth スコープ(oauth 認証用)
196
+ -o, --out-dir <dir> 出力ディレクトリ
197
+ --preview プレビュー環境を使用
198
+ -g, --guest-space-id <id> ゲストスペース ID
199
+ -n, --namespace <namespace> TypeScript namespace
200
+ -f, --format Prettier でフォーマット
201
+ --proxy <host:port> プロキシサーバー
202
+ --basic-auth-username <username> Basic 認証ユーザー名
203
+ --basic-auth-password <password> Basic 認証パスワード
204
+ -h, --help ヘルプを表示
205
+ -V, --version バージョンを表示
206
+ ```
207
+
208
+ ### ワンライナー実行
209
+
210
+ 設定ファイルなしで、CLI オプションだけで実行できます:
211
+
212
+ ```bash
213
+ npx @goqoo/trunks \
214
+ -H example.cybozu.com \
215
+ -a customer:123 \
216
+ -a order:456 \
217
+ -A api-token \
218
+ -t "$KINTONE_API_TOKEN"
171
219
  ```
172
220
 
173
221
  ## 生成される出力
package/README.md CHANGED
@@ -17,6 +17,16 @@ A CLI wrapper for [@kintone/dts-gen](https://github.com/kintone/js-sdk/tree/main
17
17
 
18
18
  ## Quick Start
19
19
 
20
+ ### Using init command
21
+
22
+ ```bash
23
+ npx @goqoo/trunks init
24
+ ```
25
+
26
+ This will interactively create a `trunks.config.ts` file.
27
+
28
+ ### Manual setup
29
+
20
30
  1. Create a configuration file `trunks.config.ts` in your project root:
21
31
 
22
32
  ```typescript
@@ -159,15 +169,53 @@ pfx: {
159
169
  },
160
170
  ```
161
171
 
162
- ## CLI Options
172
+ ## CLI
173
+
174
+ ### Commands
175
+
176
+ ```bash
177
+ trunks init # Create trunks.config.ts interactively
178
+ trunks generate # Generate type definitions (default command)
179
+ trunks # Same as 'trunks generate'
180
+ ```
181
+
182
+ ### Options
163
183
 
164
184
  ```bash
165
- trunks [options]
185
+ trunks generate [options]
166
186
 
167
187
  Options:
168
- -c, --config <path> Path to config file (default: auto-detect)
169
- -h, --help Display help
170
- -V, --version Display version
188
+ -c, --config <path> Path to config file
189
+ -H, --host <host> Kintone host (e.g., example.cybozu.com)
190
+ -a, --app <name:id> App to generate (can be repeated)
191
+ -A, --auth-type <type> Auth type: password, api-token, oauth
192
+ -u, --username <username> Kintone username (for password auth)
193
+ -p, --password <password> Kintone password (for password auth)
194
+ -t, --api-token <token> Kintone API token (for api-token auth)
195
+ --oauth-scope <scope> OAuth scope (for oauth auth)
196
+ -o, --out-dir <dir> Output directory
197
+ --preview Use preview environment
198
+ -g, --guest-space-id <id> Guest space ID
199
+ -n, --namespace <namespace> TypeScript namespace
200
+ -f, --format Format output with Prettier
201
+ --proxy <host:port> Proxy server
202
+ --basic-auth-username <username> Basic auth username
203
+ --basic-auth-password <password> Basic auth password
204
+ -h, --help Display help
205
+ -V, --version Display version
206
+ ```
207
+
208
+ ### One-liner execution
209
+
210
+ You can run without a config file by passing all options via CLI:
211
+
212
+ ```bash
213
+ npx @goqoo/trunks \
214
+ -H example.cybozu.com \
215
+ -a customer:123 \
216
+ -a order:456 \
217
+ -A api-token \
218
+ -t "$KINTONE_API_TOKEN"
171
219
  ```
172
220
 
173
221
  ## Generated Output
package/dist/cli.js CHANGED
@@ -5,23 +5,127 @@ import { Command } from 'commander';
5
5
  import chalk from 'chalk';
6
6
  import { loadConfig } from './config.js';
7
7
  import { generate } from './generate.js';
8
+ import { init } from './init.js';
8
9
  // package.jsonからバージョンを取得
9
10
  const require = createRequire(import.meta.url);
10
11
  const { version } = require('../package.json');
11
12
  // .envファイルがあれば環境変数として読み込む
12
13
  loadEnv({ quiet: true });
14
+ // --app オプションをパース(name:id 形式)
15
+ function parseAppOption(value, previous) {
16
+ const [name, idStr] = value.split(':');
17
+ const id = parseInt(idStr, 10);
18
+ if (!name || isNaN(id)) {
19
+ throw new Error(`Invalid app format: "${value}". Expected "name:id" (e.g., "customer:123")`);
20
+ }
21
+ return { ...previous, [name]: id };
22
+ }
23
+ // --proxy オプションをパース(host:port 形式)
24
+ function parseProxyOption(value) {
25
+ const [host, portStr] = value.split(':');
26
+ const port = parseInt(portStr, 10);
27
+ if (!host || isNaN(port)) {
28
+ throw new Error(`Invalid proxy format: "${value}". Expected "host:port" (e.g., "proxy.example.com:8080")`);
29
+ }
30
+ return { host, port };
31
+ }
32
+ // CLIオプションからConfigを構築
33
+ function buildConfigFromOptions(options) {
34
+ // 認証設定の構築
35
+ let auth;
36
+ switch (options.authType) {
37
+ case 'api-token':
38
+ auth = { type: 'api-token', token: options.apiToken };
39
+ break;
40
+ case 'oauth':
41
+ auth = { type: 'oauth', scope: options.oauthScope };
42
+ break;
43
+ default:
44
+ auth = { type: 'password', username: options.username, password: options.password };
45
+ }
46
+ const config = {
47
+ host: options.host,
48
+ apps: options.app,
49
+ auth,
50
+ };
51
+ // オプション設定
52
+ if (options.outDir)
53
+ config.outDir = options.outDir;
54
+ if (options.preview)
55
+ config.preview = true;
56
+ if (options.guestSpaceId)
57
+ config.guestSpaceId = parseInt(options.guestSpaceId, 10);
58
+ if (options.namespace)
59
+ config.namespace = options.namespace;
60
+ if (options.format)
61
+ config.format = true;
62
+ // プロキシ設定
63
+ if (options.proxy) {
64
+ config.proxy = parseProxyOption(options.proxy);
65
+ }
66
+ // Basic認証設定
67
+ if (options.basicAuthUsername && options.basicAuthPassword) {
68
+ config.basicAuth = {
69
+ username: options.basicAuthUsername,
70
+ password: options.basicAuthPassword,
71
+ };
72
+ }
73
+ return config;
74
+ }
13
75
  const program = new Command();
14
76
  program
15
77
  .name('trunks')
16
78
  .description('Generate TypeScript type definitions for multiple Kintone apps')
17
79
  .version(version);
80
+ // init コマンド
81
+ program
82
+ .command('init')
83
+ .description('Create a new trunks.config.ts interactively')
84
+ .action(async () => {
85
+ try {
86
+ await init();
87
+ }
88
+ catch (error) {
89
+ console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);
90
+ process.exit(1);
91
+ }
92
+ });
93
+ // generate コマンド(デフォルト)
18
94
  program
19
95
  .command('generate', { isDefault: true })
20
96
  .description('Generate type definitions for all configured apps')
21
97
  .option('-c, --config <path>', 'Path to config file')
98
+ // ワンライナー実行用オプション
99
+ .option('-H, --host <host>', 'Kintone host (e.g., example.cybozu.com)')
100
+ .option('-a, --app <name:id>', 'App to generate (can be repeated)', parseAppOption, {})
101
+ .option('-A, --auth-type <type>', 'Authentication type: password, api-token, oauth', 'password')
102
+ .option('-u, --username <username>', 'Kintone username (for password auth)')
103
+ .option('-p, --password <password>', 'Kintone password (for password auth)')
104
+ .option('-t, --api-token <token>', 'Kintone API token (for api-token auth)')
105
+ .option('--oauth-scope <scope>', 'OAuth scope (for oauth auth)')
106
+ .option('-o, --out-dir <dir>', 'Output directory')
107
+ .option('--preview', 'Use preview environment')
108
+ .option('-g, --guest-space-id <id>', 'Guest space ID')
109
+ .option('-n, --namespace <namespace>', 'TypeScript namespace')
110
+ .option('-f, --format', 'Format output with Prettier')
111
+ .option('--proxy <host:port>', 'Proxy server')
112
+ .option('--basic-auth-username <username>', 'Basic auth username')
113
+ .option('--basic-auth-password <password>', 'Basic auth password')
22
114
  .action(async (options) => {
23
115
  try {
24
- const config = await loadConfig(options.config ? undefined : process.cwd());
116
+ let config;
117
+ // --hostと--appが指定されている場合はCLIオプションから設定を構築
118
+ if (options.host && Object.keys(options.app).length > 0) {
119
+ config = buildConfigFromOptions(options);
120
+ }
121
+ else if (options.host || Object.keys(options.app).length > 0) {
122
+ // 片方だけ指定されている場合はエラー
123
+ throw new Error('Both --host and --app are required for CLI-only mode');
124
+ }
125
+ else {
126
+ // 設定ファイルから読み込み
127
+ config = await loadConfig(options.config ? undefined : process.cwd());
128
+ }
25
129
  await generate(config);
26
130
  }
27
131
  catch (error) {
package/dist/init.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function init(): Promise<void>;
package/dist/init.js ADDED
@@ -0,0 +1,121 @@
1
+ import * as fs from 'fs';
2
+ import * as readline from 'readline';
3
+ import chalk from 'chalk';
4
+ // 標準入力からテキストを取得
5
+ function prompt(question) {
6
+ const rl = readline.createInterface({
7
+ input: process.stdin,
8
+ output: process.stdout,
9
+ });
10
+ return new Promise((resolve) => {
11
+ rl.question(question, (answer) => {
12
+ rl.close();
13
+ resolve(answer.trim());
14
+ });
15
+ });
16
+ }
17
+ // Yes/No プロンプト
18
+ async function promptYesNo(question, defaultValue = true) {
19
+ const hint = defaultValue ? '[Y/n]' : '[y/N]';
20
+ const answer = await prompt(`${question} ${hint}: `);
21
+ if (answer === '')
22
+ return defaultValue;
23
+ return answer.toLowerCase().startsWith('y');
24
+ }
25
+ // 選択肢プロンプト
26
+ async function promptChoice(question, choices) {
27
+ console.info(question);
28
+ choices.forEach((choice, index) => {
29
+ console.info(` ${index + 1}. ${choice}`);
30
+ });
31
+ const answer = await prompt('Select [1]: ');
32
+ const index = answer === '' ? 0 : parseInt(answer, 10) - 1;
33
+ if (index < 0 || index >= choices.length) {
34
+ return choices[0];
35
+ }
36
+ return choices[index];
37
+ }
38
+ // アプリの入力
39
+ async function promptApps() {
40
+ const apps = [];
41
+ console.info(chalk.cyan('\nAdd kintone apps:'));
42
+ while (true) {
43
+ const name = await prompt(' App name (e.g., customer): ');
44
+ if (!name) {
45
+ if (apps.length === 0) {
46
+ console.info(chalk.yellow(' At least one app is required.'));
47
+ continue;
48
+ }
49
+ break;
50
+ }
51
+ const idStr = await prompt(' App ID: ');
52
+ const id = parseInt(idStr, 10);
53
+ if (isNaN(id) || id <= 0) {
54
+ console.info(chalk.yellow(' Invalid app ID. Please enter a positive number.'));
55
+ continue;
56
+ }
57
+ apps.push({ name, id });
58
+ console.info(chalk.green(` Added: ${name} (ID: ${id})`));
59
+ const addMore = await promptYesNo('\n Add another app?', false);
60
+ if (!addMore)
61
+ break;
62
+ }
63
+ return apps;
64
+ }
65
+ // 設定ファイルの生成
66
+ function generateConfigContent(host, apps, authType) {
67
+ const appsObj = apps.map((app) => ` ${app.name}: ${app.id},`).join('\n');
68
+ let authConfig;
69
+ switch (authType) {
70
+ case 'api-token':
71
+ authConfig = "{ type: 'api-token' }";
72
+ break;
73
+ case 'oauth':
74
+ authConfig = "{ type: 'oauth' }";
75
+ break;
76
+ default:
77
+ authConfig = "{ type: 'password' }";
78
+ }
79
+ return `import { defineConfig } from '@goqoo/trunks';
80
+
81
+ export default defineConfig({
82
+ host: '${host}',
83
+ apps: {
84
+ ${appsObj}
85
+ },
86
+ auth: ${authConfig},
87
+ });
88
+ `;
89
+ }
90
+ // init コマンドの実行
91
+ export async function init() {
92
+ const configPath = 'trunks.config.ts';
93
+ // 既存ファイルの確認
94
+ if (fs.existsSync(configPath)) {
95
+ const overwrite = await promptYesNo(`${configPath} already exists. Overwrite?`, false);
96
+ if (!overwrite) {
97
+ console.info(chalk.yellow('Aborted.'));
98
+ return;
99
+ }
100
+ }
101
+ console.info(chalk.cyan('Creating trunks.config.ts...\n'));
102
+ // ホスト入力
103
+ const host = await prompt('Kintone host (e.g., example.cybozu.com): ');
104
+ if (!host) {
105
+ console.info(chalk.red('Host is required.'));
106
+ return;
107
+ }
108
+ // アプリ入力
109
+ const apps = await promptApps();
110
+ if (apps.length === 0) {
111
+ console.info(chalk.red('At least one app is required.'));
112
+ return;
113
+ }
114
+ // 認証方式選択
115
+ const authType = await promptChoice('\nAuthentication method:', ['password', 'api-token', 'oauth']);
116
+ // ファイル生成
117
+ const content = generateConfigContent(host, apps, authType);
118
+ fs.writeFileSync(configPath, content);
119
+ console.info(chalk.green(`\n✓ Created ${configPath}`));
120
+ console.info(chalk.gray('\nRun `trunks` to generate type definitions.'));
121
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goqoo/trunks",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "A CLI wrapper for @kintone/dts-gen that generates type definitions for multiple Kintone apps",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",