aranea-sdk-cli 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.
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ /**
3
+ * schema コマンド
4
+ *
5
+ * Usage:
6
+ * aranea-sdk schema get --type "aranea_ar-is04a"
7
+ * aranea-sdk schema list
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.schemaCommand = void 0;
14
+ const commander_1 = require("commander");
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ const ora_1 = __importDefault(require("ora"));
17
+ // 組み込みスキーマ定義
18
+ // 実際の運用ではFirestoreから取得するが、CLIツールでは組み込み版を使用
19
+ const BUILTIN_SCHEMAS = {
20
+ 'aranea_ar-is01': {
21
+ type: 'aranea_ar-is01',
22
+ displayName: 'AraneaSDK Basic Sensor',
23
+ description: '基本センサーデバイス',
24
+ productType: '001',
25
+ stateFields: {
26
+ Trigger1: { type: 'boolean', description: '汎用トリガー1' },
27
+ Trigger2: { type: 'boolean', description: '汎用トリガー2' },
28
+ RSSI: { type: 'number', description: 'WiFi信号強度 (dBm)' },
29
+ },
30
+ commandFields: {},
31
+ },
32
+ 'aranea_ar-is04a': {
33
+ type: 'aranea_ar-is04a',
34
+ displayName: 'Network Scanner',
35
+ description: 'ネットワークスキャナー (ESP32)',
36
+ productType: '004',
37
+ stateFields: {
38
+ scanMode: { type: 'string', description: 'スキャンモード (arp/ping/passive)' },
39
+ discoveredHosts: { type: 'number', description: '発見ホスト数' },
40
+ lastScanAt: { type: 'string', description: '最終スキャン時刻 (ISO8601)' },
41
+ RSSI: { type: 'number', description: 'WiFi信号強度 (dBm)' },
42
+ },
43
+ commandFields: {
44
+ startScan: { type: 'boolean', description: 'スキャン開始' },
45
+ setScanMode: { type: 'string', description: 'スキャンモード設定' },
46
+ },
47
+ },
48
+ 'aranea_ar-is05a': {
49
+ type: 'aranea_ar-is05a',
50
+ displayName: 'Environment Sensor',
51
+ description: '環境センサー (ESP32)',
52
+ productType: '005',
53
+ stateFields: {
54
+ temperature: { type: 'number', description: '温度 (℃)' },
55
+ humidity: { type: 'number', description: '湿度 (%)' },
56
+ pressure: { type: 'number', description: '気圧 (hPa)' },
57
+ co2: { type: 'number', description: 'CO2濃度 (ppm)' },
58
+ RSSI: { type: 'number', description: 'WiFi信号強度 (dBm)' },
59
+ },
60
+ commandFields: {
61
+ calibrate: { type: 'boolean', description: 'センサーキャリブレーション' },
62
+ },
63
+ },
64
+ 'aranea_ar-is06a': {
65
+ type: 'aranea_ar-is06a',
66
+ displayName: 'Power Monitor',
67
+ description: '電力モニター (ESP32)',
68
+ productType: '006',
69
+ stateFields: {
70
+ voltage: { type: 'number', description: '電圧 (V)' },
71
+ current: { type: 'number', description: '電流 (A)' },
72
+ power: { type: 'number', description: '電力 (W)' },
73
+ energy: { type: 'number', description: '積算電力量 (Wh)' },
74
+ RSSI: { type: 'number', description: 'WiFi信号強度 (dBm)' },
75
+ },
76
+ commandFields: {
77
+ resetEnergy: { type: 'boolean', description: '積算電力量リセット' },
78
+ },
79
+ },
80
+ 'aranea_ar-is10': {
81
+ type: 'aranea_ar-is10',
82
+ displayName: 'Router Inspector',
83
+ description: 'OpenWrt/AsusWRT ルーターインスペクター',
84
+ productType: '010',
85
+ stateFields: {
86
+ routerType: { type: 'string', description: 'ルータータイプ (openwrt/asuswrt)' },
87
+ connectedClients: { type: 'number', description: '接続クライアント数' },
88
+ wanStatus: { type: 'string', description: 'WAN状態' },
89
+ uptime: { type: 'number', description: '稼働時間 (秒)' },
90
+ },
91
+ commandFields: {
92
+ refresh: { type: 'boolean', description: '状態更新' },
93
+ },
94
+ },
95
+ };
96
+ exports.schemaCommand = new commander_1.Command('schema')
97
+ .description('Type スキーマの取得・表示');
98
+ // schema list
99
+ exports.schemaCommand
100
+ .command('list')
101
+ .description('利用可能なTypeスキーマ一覧')
102
+ .action(() => {
103
+ console.log(chalk_1.default.bold('\n=== AraneaDevice Type スキーマ一覧 ===\n'));
104
+ const types = Object.keys(BUILTIN_SCHEMAS).sort();
105
+ console.log(chalk_1.default.cyan('登録済みType:'));
106
+ console.log('');
107
+ types.forEach((type) => {
108
+ const schema = BUILTIN_SCHEMAS[type];
109
+ console.log(` ${chalk_1.default.green(type)}`);
110
+ console.log(` ${schema.displayName} - ${schema.description}`);
111
+ console.log(` ProductType: ${schema.productType}`);
112
+ console.log('');
113
+ });
114
+ console.log(chalk_1.default.gray(`合計: ${types.length} 件`));
115
+ console.log('');
116
+ });
117
+ // schema get
118
+ exports.schemaCommand
119
+ .command('get')
120
+ .description('特定Typeのスキーマ詳細を取得')
121
+ .requiredOption('-t, --type <type>', '取得するType名')
122
+ .option('--json', 'JSON形式で出力')
123
+ .action((options) => {
124
+ const type = options.type;
125
+ const schema = BUILTIN_SCHEMAS[type];
126
+ if (!schema) {
127
+ console.error(chalk_1.default.red(`\nType "${type}" のスキーマが見つかりません`));
128
+ console.log('');
129
+ console.log(chalk_1.default.yellow('利用可能なType:'));
130
+ Object.keys(BUILTIN_SCHEMAS).forEach((t) => {
131
+ console.log(` - ${t}`);
132
+ });
133
+ console.log('');
134
+ process.exit(1);
135
+ }
136
+ if (options.json) {
137
+ console.log(JSON.stringify(schema, null, 2));
138
+ return;
139
+ }
140
+ console.log(chalk_1.default.bold(`\n=== ${schema.type} スキーマ ===\n`));
141
+ console.log(`DisplayName: ${chalk_1.default.cyan(schema.displayName)}`);
142
+ console.log(`Description: ${schema.description}`);
143
+ console.log(`ProductType: ${schema.productType}`);
144
+ console.log('');
145
+ // State Fields
146
+ console.log(chalk_1.default.bold('State Fields (状態レポート):'));
147
+ const stateFields = Object.entries(schema.stateFields);
148
+ if (stateFields.length === 0) {
149
+ console.log(chalk_1.default.gray(' (なし)'));
150
+ }
151
+ else {
152
+ stateFields.forEach(([name, field]) => {
153
+ console.log(` ${chalk_1.default.green(name)}: ${chalk_1.default.yellow(field.type)}`);
154
+ console.log(` ${field.description}`);
155
+ });
156
+ }
157
+ console.log('');
158
+ // Command Fields
159
+ console.log(chalk_1.default.bold('Command Fields (コマンド):'));
160
+ const commandFields = Object.entries(schema.commandFields);
161
+ if (commandFields.length === 0) {
162
+ console.log(chalk_1.default.gray(' (なし)'));
163
+ }
164
+ else {
165
+ commandFields.forEach(([name, field]) => {
166
+ console.log(` ${chalk_1.default.green(name)}: ${chalk_1.default.yellow(field.type)}`);
167
+ console.log(` ${field.description}`);
168
+ });
169
+ }
170
+ console.log('');
171
+ // サンプルリクエスト生成
172
+ console.log(chalk_1.default.bold('サンプル状態レポート:'));
173
+ const sampleState = {};
174
+ Object.entries(schema.stateFields).forEach(([name, field]) => {
175
+ switch (field.type) {
176
+ case 'boolean':
177
+ sampleState[name] = true;
178
+ break;
179
+ case 'number':
180
+ sampleState[name] = name === 'RSSI' ? -65 : 0;
181
+ break;
182
+ case 'string':
183
+ sampleState[name] = `sample_${name}`;
184
+ break;
185
+ default:
186
+ sampleState[name] = null;
187
+ }
188
+ });
189
+ const sampleRequest = {
190
+ auth: {
191
+ tid: 'T9999999999999999999',
192
+ lacisId: '3004AABBCCDDEEFF0001',
193
+ cic: '******',
194
+ },
195
+ report: {
196
+ type: schema.type,
197
+ state: sampleState,
198
+ },
199
+ };
200
+ console.log(chalk_1.default.gray(JSON.stringify(sampleRequest, null, 2)));
201
+ console.log('');
202
+ });
203
+ // schema validate
204
+ exports.schemaCommand
205
+ .command('validate')
206
+ .description('状態レポートJSONをスキーマに対して検証')
207
+ .requiredOption('-t, --type <type>', 'Type名')
208
+ .requiredOption('-f, --file <path>', 'JSONファイルパス')
209
+ .action((options) => {
210
+ const spinner = (0, ora_1.default)('検証中...').start();
211
+ try {
212
+ const fs = require('fs');
213
+ const path = require('path');
214
+ const type = options.type;
215
+ const schema = BUILTIN_SCHEMAS[type];
216
+ if (!schema) {
217
+ spinner.fail(`Type "${type}" のスキーマが見つかりません`);
218
+ process.exit(1);
219
+ }
220
+ const filePath = path.resolve(options.file);
221
+ if (!fs.existsSync(filePath)) {
222
+ spinner.fail(`ファイルが見つかりません: ${filePath}`);
223
+ process.exit(1);
224
+ }
225
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
226
+ const data = JSON.parse(fileContent);
227
+ spinner.stop();
228
+ console.log(chalk_1.default.bold(`\n=== スキーマ検証: ${type} ===\n`));
229
+ const issues = [];
230
+ const warnings = [];
231
+ // state フィールドの検証
232
+ const state = data.report?.state || data.state || data;
233
+ Object.entries(schema.stateFields).forEach(([fieldName, fieldDef]) => {
234
+ if (!(fieldName in state)) {
235
+ warnings.push(`フィールド "${fieldName}" が存在しません`);
236
+ }
237
+ else {
238
+ const value = state[fieldName];
239
+ const actualType = typeof value;
240
+ const expectedType = fieldDef.type;
241
+ if (expectedType === 'number' && actualType !== 'number') {
242
+ issues.push(`"${fieldName}": number型が期待されますが ${actualType}型です`);
243
+ }
244
+ else if (expectedType === 'string' && actualType !== 'string') {
245
+ issues.push(`"${fieldName}": string型が期待されますが ${actualType}型です`);
246
+ }
247
+ else if (expectedType === 'boolean' && actualType !== 'boolean') {
248
+ issues.push(`"${fieldName}": boolean型が期待されますが ${actualType}型です`);
249
+ }
250
+ }
251
+ });
252
+ // 未定義フィールドのチェック
253
+ Object.keys(state).forEach((key) => {
254
+ if (!(key in schema.stateFields)) {
255
+ warnings.push(`未定義フィールド "${key}" が含まれています (無視されます)`);
256
+ }
257
+ });
258
+ // 結果表示
259
+ if (issues.length === 0) {
260
+ console.log(chalk_1.default.green('✓ スキーマ検証に成功しました'));
261
+ }
262
+ else {
263
+ console.log(chalk_1.default.red('✗ スキーマ検証エラー:'));
264
+ issues.forEach((issue) => {
265
+ console.log(chalk_1.default.red(` - ${issue}`));
266
+ });
267
+ }
268
+ if (warnings.length > 0) {
269
+ console.log('');
270
+ console.log(chalk_1.default.yellow('警告:'));
271
+ warnings.forEach((warning) => {
272
+ console.log(chalk_1.default.yellow(` - ${warning}`));
273
+ });
274
+ }
275
+ console.log('');
276
+ }
277
+ catch (error) {
278
+ spinner.fail(`検証エラー: ${error.message}`);
279
+ process.exit(1);
280
+ }
281
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * simulate コマンド
3
+ *
4
+ * Usage:
5
+ * aranea-sdk simulate state-report --file test.json --dry-run
6
+ * aranea-sdk simulate state-report --tid T999... --lacis-id 3004... --cic 123456
7
+ */
8
+ import { Command } from 'commander';
9
+ export declare const simulateCommand: Command;
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /**
3
+ * simulate コマンド
4
+ *
5
+ * Usage:
6
+ * aranea-sdk simulate state-report --file test.json --dry-run
7
+ * aranea-sdk simulate state-report --tid T999... --lacis-id 3004... --cic 123456
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ var __importDefault = (this && this.__importDefault) || function (mod) {
43
+ return (mod && mod.__esModule) ? mod : { "default": mod };
44
+ };
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.simulateCommand = void 0;
47
+ const commander_1 = require("commander");
48
+ const chalk_1 = __importDefault(require("chalk"));
49
+ const ora_1 = __importDefault(require("ora"));
50
+ const node_fetch_1 = __importDefault(require("node-fetch"));
51
+ const fs = __importStar(require("fs"));
52
+ const path = __importStar(require("path"));
53
+ const config_1 = require("../config");
54
+ exports.simulateCommand = new commander_1.Command('simulate')
55
+ .description('デバイス動作のシミュレーション');
56
+ // simulate state-report
57
+ exports.simulateCommand
58
+ .command('state-report')
59
+ .description('状態レポート送信のシミュレーション')
60
+ .option('-f, --file <path>', 'JSONファイルからリクエストを読み込み')
61
+ .option('-t, --tid <tid>', 'テナントID')
62
+ .option('-l, --lacis-id <lacisId>', 'デバイスLacisID')
63
+ .option('-c, --cic <cic>', 'デバイスCIC')
64
+ .option('--type <type>', 'デバイスType', 'aranea_ar-is04a')
65
+ .option('-d, --dry-run', '実際には送信せずリクエスト内容を表示')
66
+ .option('-e, --endpoint <env>', '環境 (production/staging)', 'production')
67
+ .action(async (options) => {
68
+ try {
69
+ let requestBody;
70
+ if (options.file) {
71
+ // ファイルから読み込み
72
+ const filePath = path.resolve(options.file);
73
+ if (!fs.existsSync(filePath)) {
74
+ console.error(chalk_1.default.red(`ファイルが見つかりません: ${filePath}`));
75
+ process.exit(1);
76
+ }
77
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
78
+ requestBody = JSON.parse(fileContent);
79
+ }
80
+ else if (options.tid && options.lacisId && options.cic) {
81
+ // コマンドラインオプションから構築
82
+ requestBody = {
83
+ auth: {
84
+ tid: options.tid,
85
+ lacisId: options.lacisId,
86
+ cic: options.cic,
87
+ },
88
+ report: {
89
+ type: options.type,
90
+ state: {
91
+ // サンプル状態
92
+ Trigger1: true,
93
+ Trigger2: false,
94
+ RSSI: -65,
95
+ simulatedAt: new Date().toISOString(),
96
+ },
97
+ },
98
+ };
99
+ }
100
+ else {
101
+ console.error(chalk_1.default.red('--file または --tid, --lacis-id, --cic を指定してください'));
102
+ process.exit(1);
103
+ }
104
+ console.log(chalk_1.default.bold('\n=== 状態レポート シミュレーション ===\n'));
105
+ // リクエスト内容を表示
106
+ console.log(chalk_1.default.cyan('リクエスト内容:'));
107
+ console.log(JSON.stringify(requestBody, null, 2));
108
+ console.log('');
109
+ if (options.dryRun) {
110
+ console.log(chalk_1.default.yellow('(dry-run モード: 実際には送信されません)'));
111
+ return;
112
+ }
113
+ // 実際に送信
114
+ const spinner = (0, ora_1.default)('状態レポート送信中...').start();
115
+ const endpoint = (0, config_1.getEndpoint)(options.endpoint);
116
+ const response = await (0, node_fetch_1.default)(endpoint.state, {
117
+ method: 'POST',
118
+ headers: { 'Content-Type': 'application/json' },
119
+ body: JSON.stringify(requestBody),
120
+ });
121
+ const result = await response.json();
122
+ spinner.stop();
123
+ console.log(chalk_1.default.cyan('レスポンス:'));
124
+ console.log(JSON.stringify(result, null, 2));
125
+ console.log('');
126
+ if (result.ok) {
127
+ if (result.duplicate) {
128
+ console.log(chalk_1.default.yellow('⚠ 重複検出 (dedup)'));
129
+ }
130
+ else {
131
+ console.log(chalk_1.default.green('✓ 状態レポート送信成功'));
132
+ }
133
+ if (result.typeWarning) {
134
+ console.log(chalk_1.default.yellow(`⚠ Type警告: ${result.typeWarning.warning}`));
135
+ if (result.typeWarning.suggestedType) {
136
+ console.log(` 推奨Type: ${result.typeWarning.suggestedType}`);
137
+ }
138
+ }
139
+ }
140
+ else {
141
+ console.log(chalk_1.default.red(`✗ 送信失敗: ${result.error}`));
142
+ }
143
+ console.log('');
144
+ }
145
+ catch (error) {
146
+ console.error(chalk_1.default.red(`エラー: ${error.message}`));
147
+ process.exit(1);
148
+ }
149
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * test コマンド
3
+ *
4
+ * Usage:
5
+ * aranea-sdk test connection --endpoint staging
6
+ * aranea-sdk test auth --tid T999... --lacis-id 173... --cic 022029
7
+ */
8
+ import { Command } from 'commander';
9
+ export declare const testCommand: Command;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * test コマンド
4
+ *
5
+ * Usage:
6
+ * aranea-sdk test connection --endpoint staging
7
+ * aranea-sdk test auth --tid T999... --lacis-id 173... --cic 022029
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.testCommand = void 0;
14
+ const commander_1 = require("commander");
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ const ora_1 = __importDefault(require("ora"));
17
+ const node_fetch_1 = __importDefault(require("node-fetch"));
18
+ const config_1 = require("../config");
19
+ exports.testCommand = new commander_1.Command('test')
20
+ .description('接続・認証テスト');
21
+ // test connection
22
+ exports.testCommand
23
+ .command('connection')
24
+ .description('エンドポイントへの接続テスト')
25
+ .option('-e, --endpoint <env>', '環境 (production/staging)', 'production')
26
+ .action(async (options) => {
27
+ const spinner = (0, ora_1.default)('接続テスト中...').start();
28
+ try {
29
+ const endpoint = (0, config_1.getEndpoint)(options.endpoint);
30
+ // Gate エンドポイントにOPTIONSリクエスト (CORS preflight)
31
+ const gateResponse = await (0, node_fetch_1.default)(endpoint.gate, { method: 'OPTIONS' });
32
+ const stateResponse = await (0, node_fetch_1.default)(endpoint.state, { method: 'OPTIONS' });
33
+ spinner.stop();
34
+ console.log(chalk_1.default.bold('\n=== 接続テスト結果 ===\n'));
35
+ console.log(`環境: ${chalk_1.default.cyan(options.endpoint)}`);
36
+ console.log('');
37
+ if (gateResponse.ok || gateResponse.status === 204) {
38
+ console.log(`Gate: ${chalk_1.default.green('✓')} ${endpoint.gate}`);
39
+ }
40
+ else {
41
+ console.log(`Gate: ${chalk_1.default.red('✗')} ${endpoint.gate} (${gateResponse.status})`);
42
+ }
43
+ if (stateResponse.ok || stateResponse.status === 204) {
44
+ console.log(`State: ${chalk_1.default.green('✓')} ${endpoint.state}`);
45
+ }
46
+ else {
47
+ console.log(`State: ${chalk_1.default.red('✗')} ${endpoint.state} (${stateResponse.status})`);
48
+ }
49
+ console.log('');
50
+ }
51
+ catch (error) {
52
+ spinner.fail('接続テスト失敗');
53
+ console.error(chalk_1.default.red(`エラー: ${error.message}`));
54
+ process.exit(1);
55
+ }
56
+ });
57
+ // test auth
58
+ exports.testCommand
59
+ .command('auth')
60
+ .description('認証テスト (Tenant Primary の認証情報を検証)')
61
+ .option('-t, --tid <tid>', 'テナントID', config_1.TEST_TENANT.tid)
62
+ .option('-l, --lacis-id <lacisId>', 'Tenant Primary LacisID', config_1.TEST_TENANT.primaryLacisId)
63
+ .option('-u, --user-id <userId>', 'Tenant Primary Email', config_1.TEST_TENANT.primaryEmail)
64
+ .option('-c, --cic <cic>', 'Tenant Primary CIC', config_1.TEST_TENANT.primaryCic)
65
+ .option('-e, --endpoint <env>', '環境 (production/staging)', 'production')
66
+ .action(async (options) => {
67
+ const spinner = (0, ora_1.default)('認証テスト中...').start();
68
+ try {
69
+ const endpoint = (0, config_1.getEndpoint)(options.endpoint);
70
+ // ダミーデバイス登録リクエストを送信 (MACアドレスはランダム)
71
+ const testMac = Array.from({ length: 12 }, () => Math.floor(Math.random() * 16).toString(16).toUpperCase()).join('');
72
+ const requestBody = {
73
+ lacisOath: {
74
+ lacisId: options.lacisId,
75
+ userId: options.userId,
76
+ cic: options.cic,
77
+ method: 'register',
78
+ },
79
+ userObject: {
80
+ tid: options.tid,
81
+ typeDomain: 'araneaDevice',
82
+ type: 'aranea_ar-is04a',
83
+ },
84
+ deviceMeta: {
85
+ macAddress: testMac,
86
+ productType: '004',
87
+ productCode: '0001',
88
+ },
89
+ };
90
+ const response = await (0, node_fetch_1.default)(endpoint.gate, {
91
+ method: 'POST',
92
+ headers: { 'Content-Type': 'application/json' },
93
+ body: JSON.stringify(requestBody),
94
+ });
95
+ const result = await response.json();
96
+ spinner.stop();
97
+ console.log(chalk_1.default.bold('\n=== 認証テスト結果 ===\n'));
98
+ console.log(`環境: ${chalk_1.default.cyan(options.endpoint)}`);
99
+ console.log(`TID: ${options.tid}`);
100
+ console.log(`LacisID: ${options.lacisId}`);
101
+ console.log(`Email: ${options.userId}`);
102
+ console.log(`CIC: ${options.cic.substring(0, 2)}****`);
103
+ console.log('');
104
+ if (result.ok) {
105
+ console.log(chalk_1.default.green('✓ 認証成功'));
106
+ console.log('');
107
+ console.log(`デバイスLacisID: ${result.lacisId}`);
108
+ console.log(`デバイスCIC: ${result.userObject?.cic_code}`);
109
+ if (result.typeWarning) {
110
+ console.log('');
111
+ console.log(chalk_1.default.yellow('⚠ Type警告:'));
112
+ console.log(` 受信Type: ${result.typeWarning.receivedType}`);
113
+ console.log(` 推奨Type: ${result.typeWarning.suggestedType}`);
114
+ }
115
+ }
116
+ else {
117
+ console.log(chalk_1.default.red('✗ 認証失敗'));
118
+ console.log(`エラー: ${result.error}`);
119
+ }
120
+ console.log('');
121
+ }
122
+ catch (error) {
123
+ spinner.fail('認証テスト失敗');
124
+ console.error(chalk_1.default.red(`エラー: ${error.message}`));
125
+ process.exit(1);
126
+ }
127
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * validate コマンド
3
+ *
4
+ * Usage:
5
+ * aranea-sdk validate type --type "aranea_ar-is04a"
6
+ * aranea-sdk validate lacis-id --lacis-id "3004AABBCCDDEEFF0001"
7
+ */
8
+ import { Command } from 'commander';
9
+ export declare const validateCommand: Command;