aranea-sdk-cli 0.3.7 → 0.3.9

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.
@@ -149,6 +149,7 @@ exports.knowledgeCommand
149
149
  .action(async (options) => {
150
150
  try {
151
151
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
152
+ (0, config_1.checkStagingAvailability)(env, 'knowledge add --title <title> --category <cat>');
152
153
  (0, config_1.warnIfProduction)(env, 'knowledge add');
153
154
  console.log(chalk_1.default.bold(`\n=== Knowledge Add (${env}) ===\n`));
154
155
  // 認証トークン
@@ -234,6 +235,7 @@ exports.knowledgeCommand
234
235
  .action(async (options) => {
235
236
  try {
236
237
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
238
+ (0, config_1.checkStagingAvailability)(env, 'knowledge search --query <query>');
237
239
  console.log(chalk_1.default.bold(`\n=== Knowledge Search (${env}) ===\n`));
238
240
  const token = options.token || await getAuthToken();
239
241
  if (!token) {
@@ -278,6 +280,7 @@ exports.knowledgeCommand
278
280
  .action(async (options) => {
279
281
  try {
280
282
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
283
+ (0, config_1.checkStagingAvailability)(env, 'knowledge list');
281
284
  console.log(chalk_1.default.bold(`\n=== Knowledge List (${env}) ===\n`));
282
285
  const token = options.token || await getAuthToken();
283
286
  if (!token) {
@@ -320,6 +323,7 @@ exports.knowledgeCommand
320
323
  .action(async (options) => {
321
324
  try {
322
325
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
326
+ (0, config_1.checkStagingAvailability)(env, 'knowledge get --id <id>');
323
327
  console.log(chalk_1.default.bold(`\n=== Knowledge Get (${env}) ===\n`));
324
328
  const token = options.token || await getAuthToken();
325
329
  if (!token) {
@@ -352,6 +356,7 @@ exports.knowledgeCommand
352
356
  .action(async (options) => {
353
357
  try {
354
358
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
359
+ (0, config_1.checkStagingAvailability)(env, 'knowledge delete --id <id>');
355
360
  (0, config_1.warnIfProduction)(env, 'knowledge delete');
356
361
  console.log(chalk_1.default.bold(`\n=== Knowledge Delete (${env}) ===\n`));
357
362
  const token = options.token || await getAuthToken();
@@ -127,6 +127,7 @@ exports.metatronCommand
127
127
  .action(async (question, options) => {
128
128
  try {
129
129
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
130
+ (0, config_1.checkStagingAvailability)(env, 'metatron ask "<question>"');
130
131
  if (!options.raw) {
131
132
  console.log(chalk_1.default.bold(`\n=== AraneaMetatron (${env}) ===\n`));
132
133
  console.log(chalk_1.default.gray(`Q: ${question}`));
@@ -160,6 +161,7 @@ exports.metatronCommand
160
161
  .option('-e, --endpoint <env>', '環境 (staging|production)', 'production')
161
162
  .action(async (options) => {
162
163
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
164
+ (0, config_1.checkStagingAvailability)(env, 'metatron chat');
163
165
  console.log(chalk_1.default.bold(`\n=== AraneaMetatron Chat (${env}) ===\n`));
164
166
  console.log(chalk_1.default.gray('AraneaSDKについて質問してください。'));
165
167
  console.log(chalk_1.default.gray('終了するには "exit" または Ctrl+C を入力\n'));
@@ -165,6 +165,8 @@ exports.schemaCommand
165
165
  .option('-e, --endpoint <env>', 'Environment (staging|production)', 'staging')
166
166
  .action(async (options) => {
167
167
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
168
+ // Check staging availability
169
+ (0, config_1.checkStagingAvailability)(env, 'schema list');
168
170
  const apiBase = getSchemaApiBase(env);
169
171
  const spinner = (0, ora_1.default)(`Fetching schema list from ${env}...`).start();
170
172
  try {
@@ -211,6 +213,8 @@ exports.schemaCommand
211
213
  .option('--json', 'Output as JSON')
212
214
  .action(async (options) => {
213
215
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
216
+ // Check staging availability
217
+ (0, config_1.checkStagingAvailability)(env, 'schema get --type <type>');
214
218
  const apiBase = getSchemaApiBase(env);
215
219
  const spinner = (0, ora_1.default)(`Fetching schema for ${options.type} from ${env}...`).start();
216
220
  try {
@@ -358,6 +362,8 @@ exports.schemaCommand
358
362
  .option('-e, --endpoint <env>', 'Environment (staging|production)', 'staging')
359
363
  .action(async (options) => {
360
364
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
365
+ // Check staging availability
366
+ (0, config_1.checkStagingAvailability)(env, 'schema validate --type <type> --file <file>');
361
367
  const apiBase = getSchemaApiBase(env);
362
368
  const spinner = (0, ora_1.default)('Validating...').start();
363
369
  try {
@@ -553,7 +559,7 @@ exports.schemaCommand
553
559
  .action(async (options) => {
554
560
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
555
561
  // Check staging availability
556
- (0, config_1.checkStagingAvailability)(env, 'schema push --endpoint production');
562
+ (0, config_1.checkStagingAvailability)(env, 'schema push --file <file>');
557
563
  // Require --force for production
558
564
  if (!options.dryRun && !(0, config_1.requireProductionConfirmation)(env, 'schema push', options.force)) {
559
565
  process.exit(1);
@@ -688,6 +694,8 @@ exports.schemaCommand
688
694
  .option('-y, --confirm', 'Skip confirmation prompt')
689
695
  .action(async (options) => {
690
696
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
697
+ // Check staging availability
698
+ (0, config_1.checkStagingAvailability)(env, 'schema promote --type <type>');
691
699
  const apiBase = getSchemaApiBase(env);
692
700
  // Always warn for promote
693
701
  console.log(chalk_1.default.yellow(`\nPromoting schema to PRODUCTION state in ${env} environment\n`));
@@ -794,6 +802,8 @@ exports.schemaCommand
794
802
  .option('--json', 'Output as JSON')
795
803
  .action(async (options) => {
796
804
  const env = (0, config_1.resolveEnvironment)(options.endpoint);
805
+ // Check staging availability
806
+ (0, config_1.checkStagingAvailability)(env, 'schema info --type <type>');
797
807
  const apiBase = getSchemaApiBase(env);
798
808
  const spinner = (0, ora_1.default)(`Fetching schema info: ${options.type} from ${env}...`).start();
799
809
  try {
@@ -870,6 +880,8 @@ exports.schemaCommand
870
880
  console.log(chalk_1.default.gray(` Promote: aranea-sdk schema promote --type ${schema.type} --endpoint ${env}`));
871
881
  }
872
882
  console.log(chalk_1.default.gray(` Get full schema: aranea-sdk schema get --type ${schema.type} --endpoint ${env} --json`));
883
+ console.log(chalk_1.default.gray(` History: aranea-sdk schema history --type ${schema.type} --endpoint ${env}`));
884
+ console.log(chalk_1.default.gray(` Rollback: aranea-sdk schema rollback --type ${schema.type} --version <v> --endpoint ${env}`));
873
885
  console.log('');
874
886
  }
875
887
  catch (error) {
@@ -883,3 +895,193 @@ exports.schemaCommand
883
895
  process.exit(1);
884
896
  }
885
897
  });
898
+ // schema history - show version history
899
+ exports.schemaCommand
900
+ .command('history')
901
+ .description('Show schema version history')
902
+ .requiredOption('-t, --type <type>', 'Type name')
903
+ .option('-e, --endpoint <env>', 'Environment (staging|production)', 'staging')
904
+ .option('-l, --limit <limit>', 'Number of versions to show', '10')
905
+ .action(async (options) => {
906
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
907
+ // Check staging availability
908
+ (0, config_1.checkStagingAvailability)(env, 'schema history --type <type>');
909
+ const apiBase = getSchemaApiBase(env);
910
+ const spinner = (0, ora_1.default)(`Fetching history for ${options.type} from ${env}...`).start();
911
+ try {
912
+ const response = await axios_1.default.get(`${apiBase}`, {
913
+ params: {
914
+ action: 'history',
915
+ type: options.type,
916
+ limit: options.limit,
917
+ },
918
+ });
919
+ spinner.stop();
920
+ if (!response.data.ok) {
921
+ console.log(chalk_1.default.red(`\nFailed to get history: ${response.data.error}`));
922
+ process.exit(1);
923
+ }
924
+ console.log(chalk_1.default.bold(`\n=== Schema History: ${options.type} (${env}) ===\n`));
925
+ const history = response.data.history || [];
926
+ if (history.length === 0) {
927
+ console.log(chalk_1.default.yellow('No version history found.'));
928
+ console.log(chalk_1.default.gray('Version history is created when schema is updated.'));
929
+ console.log('');
930
+ return;
931
+ }
932
+ console.log(chalk_1.default.cyan('Available Versions:'));
933
+ console.log('');
934
+ for (const entry of history) {
935
+ const stateIcon = entry.state === 'production' ? chalk_1.default.green('P') : chalk_1.default.yellow('D');
936
+ console.log(` [${stateIcon}] v${entry.version}`);
937
+ console.log(` State: ${entry.state} | Changed: ${entry.changedAt || 'N/A'}`);
938
+ console.log(` By: ${entry.changedBy || 'system'}`);
939
+ if (entry.changeReason) {
940
+ console.log(` Reason: ${entry.changeReason}`);
941
+ }
942
+ console.log('');
943
+ }
944
+ console.log(chalk_1.default.gray(`Legend: [${chalk_1.default.green('P')}]=Production [${chalk_1.default.yellow('D')}]=Development`));
945
+ console.log('');
946
+ console.log(chalk_1.default.gray('To rollback:'));
947
+ console.log(chalk_1.default.gray(` aranea-sdk schema rollback --type ${options.type} --version <version> --endpoint ${env}`));
948
+ console.log('');
949
+ }
950
+ catch (error) {
951
+ spinner.fail('Failed to fetch history');
952
+ console.log(chalk_1.default.red(`\nError: ${error.message}`));
953
+ process.exit(1);
954
+ }
955
+ });
956
+ // schema rollback - rollback to a previous version
957
+ exports.schemaCommand
958
+ .command('rollback')
959
+ .description('Rollback schema to a previous version')
960
+ .requiredOption('-t, --type <type>', 'Type name to rollback')
961
+ .requiredOption('-v, --version <version>', 'Target version number to rollback to')
962
+ .option('--token <token>', 'Firebase Auth ID token')
963
+ .option('-e, --endpoint <env>', 'Environment (staging|production)', 'staging')
964
+ .option('-d, --dry-run', 'Show what would be rolled back without actually doing it')
965
+ .option('-y, --confirm', 'Skip confirmation prompt')
966
+ .action(async (options) => {
967
+ const env = (0, config_1.resolveEnvironment)(options.endpoint);
968
+ // Check staging availability
969
+ (0, config_1.checkStagingAvailability)(env, 'schema rollback --type <type> --version <v>');
970
+ const apiBase = getSchemaApiBase(env);
971
+ console.log(chalk_1.default.yellow(`\n⚠️ Schema Rollback (${env})\n`));
972
+ const spinner = (0, ora_1.default)(`Fetching schema info: ${options.type}...`).start();
973
+ try {
974
+ // First, fetch current schema info and history
975
+ const [schemaResult, historyResult] = await Promise.all([
976
+ fetchSchema(apiBase, options.type),
977
+ axios_1.default.get(`${apiBase}`, {
978
+ params: { action: 'history', type: options.type, limit: 20 },
979
+ }),
980
+ ]);
981
+ spinner.stop();
982
+ if (!schemaResult.ok) {
983
+ console.log(chalk_1.default.red(`Schema "${options.type}" not found`));
984
+ process.exit(1);
985
+ }
986
+ const schema = schemaResult.schema;
987
+ const history = historyResult.data.history || [];
988
+ const targetVersion = parseInt(options.version, 10);
989
+ // Find target version in history
990
+ const targetEntry = history.find((h) => h.version === targetVersion);
991
+ if (!targetEntry) {
992
+ console.log(chalk_1.default.red(`Version ${targetVersion} not found in history`));
993
+ console.log('');
994
+ console.log(chalk_1.default.yellow('Available versions:'));
995
+ history.forEach((h) => {
996
+ console.log(` v${h.version} (${h.state}) - ${h.changedAt || 'N/A'}`);
997
+ });
998
+ console.log('');
999
+ process.exit(1);
1000
+ }
1001
+ // Show rollback info
1002
+ console.log(chalk_1.default.bold('Current Schema:'));
1003
+ console.log(` Type: ${schema.type}`);
1004
+ console.log(` State: ${schema.state === 'production' ? chalk_1.default.green(schema.state) : chalk_1.default.yellow(schema.state)}`);
1005
+ console.log(` Version: ${schema.version || schema.revisionNumber || 'N/A'}`);
1006
+ console.log('');
1007
+ console.log(chalk_1.default.bold('Rollback Target:'));
1008
+ console.log(` Version: v${targetVersion}`);
1009
+ console.log(` State at time: ${targetEntry.state}`);
1010
+ console.log(` Changed: ${targetEntry.changedAt || 'N/A'}`);
1011
+ console.log(` By: ${targetEntry.changedBy || 'system'}`);
1012
+ if (targetEntry.changeReason) {
1013
+ console.log(` Reason: ${targetEntry.changeReason}`);
1014
+ }
1015
+ console.log('');
1016
+ if (options.dryRun) {
1017
+ console.log(chalk_1.default.bold('=== Dry Run: Would Rollback ===\n'));
1018
+ console.log(` From: current (v${schema.version || schema.revisionNumber || '?'})`);
1019
+ console.log(` To: v${targetVersion}`);
1020
+ console.log('');
1021
+ console.log(chalk_1.default.gray('Remove --dry-run to actually rollback'));
1022
+ return;
1023
+ }
1024
+ // Confirmation step
1025
+ if (!options.confirm) {
1026
+ console.log(chalk_1.default.red('This will rollback the schema to a previous version.'));
1027
+ console.log(chalk_1.default.red('The current version will be saved in history.'));
1028
+ console.log('');
1029
+ const confirmed = await promptConfirm('Are you sure you want to proceed?');
1030
+ if (!confirmed) {
1031
+ console.log(chalk_1.default.yellow('\nRollback cancelled.'));
1032
+ return;
1033
+ }
1034
+ }
1035
+ const token = getAuthToken(options);
1036
+ if (!token) {
1037
+ console.log(chalk_1.default.red('\nAuthentication required'));
1038
+ console.log(chalk_1.default.yellow('Provide a token using one of:'));
1039
+ console.log(' --token <TOKEN>');
1040
+ console.log(' export ARANEA_AUTH_TOKEN=<TOKEN>');
1041
+ process.exit(1);
1042
+ }
1043
+ const rollbackSpinner = (0, ora_1.default)(`Rolling back ${options.type} to v${targetVersion}...`).start();
1044
+ // Call the API to rollback
1045
+ const response = await axios_1.default.post(`${apiBase}`, {
1046
+ action: 'rollback',
1047
+ type: options.type,
1048
+ targetVersion: targetVersion,
1049
+ }, {
1050
+ headers: {
1051
+ 'Content-Type': 'application/json',
1052
+ Authorization: `Bearer ${token}`,
1053
+ },
1054
+ });
1055
+ if (response.data.ok) {
1056
+ rollbackSpinner.succeed(`Schema "${options.type}" rolled back to v${targetVersion}`);
1057
+ console.log('');
1058
+ console.log(` New Version: v${response.data.newVersion || 'N/A'}`);
1059
+ if (response.data.warnings) {
1060
+ response.data.warnings.forEach((w) => {
1061
+ console.log(` ${chalk_1.default.yellow(w)}`);
1062
+ });
1063
+ }
1064
+ console.log('');
1065
+ }
1066
+ else {
1067
+ rollbackSpinner.fail(`Rollback failed: ${response.data.error || 'Unknown error'}`);
1068
+ process.exit(1);
1069
+ }
1070
+ }
1071
+ catch (error) {
1072
+ if (error.response?.status === 401) {
1073
+ console.log(chalk_1.default.red('\nAuthentication failed - invalid or expired token'));
1074
+ console.log(chalk_1.default.yellow('Token is valid for 1 hour. Please refresh your token.'));
1075
+ }
1076
+ else if (error.response?.status === 403) {
1077
+ console.log(chalk_1.default.red('\nPermission denied - insufficient privileges'));
1078
+ }
1079
+ else if (error.response?.data?.error) {
1080
+ console.log(chalk_1.default.red(`\nRollback failed: ${error.response.data.error}`));
1081
+ }
1082
+ else {
1083
+ console.log(chalk_1.default.red(`\nRollback failed: ${error.message}`));
1084
+ }
1085
+ process.exit(1);
1086
+ }
1087
+ });
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ const program = new commander_1.Command();
28
28
  program
29
29
  .name('aranea-sdk')
30
30
  .description('AraneaSDK CLI - デバイス開発支援ツール')
31
- .version('0.3.7');
31
+ .version('0.3.9');
32
32
  // test コマンド
33
33
  program.addCommand(test_1.testCommand);
34
34
  // simulate コマンド
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aranea-sdk-cli",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "AraneaSDK CLI - ESP32 IoTデバイス開発支援ツール",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",