@goqoo/trunks 1.0.2 → 1.1.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/README.ja.md +44 -4
- package/README.md +44 -4
- package/dist/cli.js +110 -7
- package/dist/init.d.ts +1 -0
- package/dist/init.js +121 -0
- package/package.json +1 -1
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,45 @@ pfx: {
|
|
|
159
169
|
},
|
|
160
170
|
```
|
|
161
171
|
|
|
162
|
-
## CLI
|
|
172
|
+
## CLI
|
|
173
|
+
|
|
174
|
+
### オプション
|
|
163
175
|
|
|
164
176
|
```bash
|
|
165
177
|
trunks [options]
|
|
166
178
|
|
|
167
179
|
Options:
|
|
168
|
-
-c, --config <path>
|
|
169
|
-
-
|
|
170
|
-
-
|
|
180
|
+
-c, --config <path> 設定ファイルのパス
|
|
181
|
+
-H, --host <host> kintone ホスト(例: example.cybozu.com)
|
|
182
|
+
-a, --app <name:id> 生成するアプリ(複数指定可)
|
|
183
|
+
-A, --auth-type <type> 認証方式: password, api-token, oauth
|
|
184
|
+
-u, --username <username> kintone ユーザー名(password 認証用)
|
|
185
|
+
-p, --password <password> kintone パスワード(password 認証用)
|
|
186
|
+
-t, --api-token <token> kintone API トークン(api-token 認証用)
|
|
187
|
+
--oauth-scope <scope> OAuth スコープ(oauth 認証用)
|
|
188
|
+
-o, --out-dir <dir> 出力ディレクトリ
|
|
189
|
+
--preview プレビュー環境を使用
|
|
190
|
+
-g, --guest-space-id <id> ゲストスペース ID
|
|
191
|
+
-n, --namespace <namespace> TypeScript namespace
|
|
192
|
+
-f, --format Prettier でフォーマット
|
|
193
|
+
--proxy <host:port> プロキシサーバー
|
|
194
|
+
--basic-auth-username <username> Basic 認証ユーザー名
|
|
195
|
+
--basic-auth-password <password> Basic 認証パスワード
|
|
196
|
+
-h, --help ヘルプを表示
|
|
197
|
+
-V, --version バージョンを表示
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### ワンライナー実行
|
|
201
|
+
|
|
202
|
+
設定ファイルなしで、CLI オプションだけで実行できます:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npx @goqoo/trunks \
|
|
206
|
+
-H example.cybozu.com \
|
|
207
|
+
-a customer:123 \
|
|
208
|
+
-a order:456 \
|
|
209
|
+
-A api-token \
|
|
210
|
+
-t "$KINTONE_API_TOKEN"
|
|
171
211
|
```
|
|
172
212
|
|
|
173
213
|
## 生成される出力
|
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,45 @@ pfx: {
|
|
|
159
169
|
},
|
|
160
170
|
```
|
|
161
171
|
|
|
162
|
-
## CLI
|
|
172
|
+
## CLI
|
|
173
|
+
|
|
174
|
+
### Options
|
|
163
175
|
|
|
164
176
|
```bash
|
|
165
177
|
trunks [options]
|
|
166
178
|
|
|
167
179
|
Options:
|
|
168
|
-
-c, --config <path>
|
|
169
|
-
-
|
|
170
|
-
-
|
|
180
|
+
-c, --config <path> Path to config file
|
|
181
|
+
-H, --host <host> Kintone host (e.g., example.cybozu.com)
|
|
182
|
+
-a, --app <name:id> App to generate (can be repeated)
|
|
183
|
+
-A, --auth-type <type> Auth type: password, api-token, oauth
|
|
184
|
+
-u, --username <username> Kintone username (for password auth)
|
|
185
|
+
-p, --password <password> Kintone password (for password auth)
|
|
186
|
+
-t, --api-token <token> Kintone API token (for api-token auth)
|
|
187
|
+
--oauth-scope <scope> OAuth scope (for oauth auth)
|
|
188
|
+
-o, --out-dir <dir> Output directory
|
|
189
|
+
--preview Use preview environment
|
|
190
|
+
-g, --guest-space-id <id> Guest space ID
|
|
191
|
+
-n, --namespace <namespace> TypeScript namespace
|
|
192
|
+
-f, --format Format output with Prettier
|
|
193
|
+
--proxy <host:port> Proxy server
|
|
194
|
+
--basic-auth-username <username> Basic auth username
|
|
195
|
+
--basic-auth-password <password> Basic auth password
|
|
196
|
+
-h, --help Display help
|
|
197
|
+
-V, --version Display version
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### One-liner execution
|
|
201
|
+
|
|
202
|
+
You can run without a config file by passing all options via CLI:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npx @goqoo/trunks \
|
|
206
|
+
-H example.cybozu.com \
|
|
207
|
+
-a customer:123 \
|
|
208
|
+
-a order:456 \
|
|
209
|
+
-A api-token \
|
|
210
|
+
-t "$KINTONE_API_TOKEN"
|
|
171
211
|
```
|
|
172
212
|
|
|
173
213
|
## Generated Output
|
package/dist/cli.js
CHANGED
|
@@ -5,24 +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
|
+
}
|
|
75
|
+
// 型定義生成のアクション
|
|
76
|
+
async function generateAction(options) {
|
|
77
|
+
try {
|
|
78
|
+
let config;
|
|
79
|
+
// --hostと--appが指定されている場合はCLIオプションから設定を構築
|
|
80
|
+
if (options.host && Object.keys(options.app).length > 0) {
|
|
81
|
+
config = buildConfigFromOptions(options);
|
|
82
|
+
}
|
|
83
|
+
else if (options.host || Object.keys(options.app).length > 0) {
|
|
84
|
+
// 片方だけ指定されている場合はエラー
|
|
85
|
+
throw new Error('Both --host and --app are required for CLI-only mode');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// 設定ファイルから読み込み
|
|
89
|
+
config = await loadConfig(options.config ? undefined : process.cwd());
|
|
90
|
+
}
|
|
91
|
+
await generate(config);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
13
98
|
const program = new Command();
|
|
14
99
|
program
|
|
15
100
|
.name('trunks')
|
|
16
101
|
.description('Generate TypeScript type definitions for multiple Kintone apps')
|
|
17
|
-
.version(version)
|
|
18
|
-
|
|
19
|
-
.command('generate', { isDefault: true })
|
|
20
|
-
.description('Generate type definitions for all configured apps')
|
|
102
|
+
.version(version)
|
|
103
|
+
// 設定ファイル
|
|
21
104
|
.option('-c, --config <path>', 'Path to config file')
|
|
22
|
-
|
|
105
|
+
// ワンライナー実行用オプション
|
|
106
|
+
.option('-H, --host <host>', 'Kintone host (e.g., example.cybozu.com)')
|
|
107
|
+
.option('-a, --app <name:id>', 'App to generate (can be repeated)', parseAppOption, {})
|
|
108
|
+
.option('-A, --auth-type <type>', 'Authentication type: password, api-token, oauth', 'password')
|
|
109
|
+
.option('-u, --username <username>', 'Kintone username (for password auth)')
|
|
110
|
+
.option('-p, --password <password>', 'Kintone password (for password auth)')
|
|
111
|
+
.option('-t, --api-token <token>', 'Kintone API token (for api-token auth)')
|
|
112
|
+
.option('--oauth-scope <scope>', 'OAuth scope (for oauth auth)')
|
|
113
|
+
.option('-o, --out-dir <dir>', 'Output directory')
|
|
114
|
+
.option('--preview', 'Use preview environment')
|
|
115
|
+
.option('-g, --guest-space-id <id>', 'Guest space ID')
|
|
116
|
+
.option('-n, --namespace <namespace>', 'TypeScript namespace')
|
|
117
|
+
.option('-f, --format', 'Format output with Prettier')
|
|
118
|
+
.option('--proxy <host:port>', 'Proxy server')
|
|
119
|
+
.option('--basic-auth-username <username>', 'Basic auth username')
|
|
120
|
+
.option('--basic-auth-password <password>', 'Basic auth password')
|
|
121
|
+
.action(generateAction);
|
|
122
|
+
// init コマンド
|
|
123
|
+
program
|
|
124
|
+
.command('init')
|
|
125
|
+
.description('Create a new trunks.config.ts interactively')
|
|
126
|
+
.action(async () => {
|
|
23
127
|
try {
|
|
24
|
-
|
|
25
|
-
await generate(config);
|
|
128
|
+
await init();
|
|
26
129
|
}
|
|
27
130
|
catch (error) {
|
|
28
131
|
console.error(chalk.red('Error:'), error instanceof Error ? error.message : 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
|
+
}
|