aranea-sdk-cli 0.3.8 → 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.
@@ -880,6 +880,8 @@ exports.schemaCommand
880
880
  console.log(chalk_1.default.gray(` Promote: aranea-sdk schema promote --type ${schema.type} --endpoint ${env}`));
881
881
  }
882
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}`));
883
885
  console.log('');
884
886
  }
885
887
  catch (error) {
@@ -893,3 +895,193 @@ exports.schemaCommand
893
895
  process.exit(1);
894
896
  }
895
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.8');
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.8",
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",