@bifos/nhncloud-cli 0.12.0 → 0.13.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/dist/index.js CHANGED
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/index.ts
27
- var import_commander53 = require("commander");
28
- var import_chalk18 = __toESM(require("chalk"));
27
+ var import_commander57 = require("commander");
28
+ var import_chalk17 = __toESM(require("chalk"));
29
29
 
30
30
  // src/utils/spinner.ts
31
31
  var import_ora = __toESM(require("ora"));
@@ -66,6 +66,68 @@ var NhnCloudCliError = class extends Error {
66
66
  exitCode;
67
67
  };
68
68
 
69
+ // src/api/timeout.ts
70
+ var SYNC_FLOOR_MS = 6e5;
71
+ var DEFAULT_TIMEOUT_MS = 3e4;
72
+ var SYNC_TIMEOUT_MS = SYNC_FLOOR_MS;
73
+ function setRequestTimeoutMs(ms) {
74
+ if (!Number.isInteger(ms) || ms < 1) {
75
+ throw new Error(`setRequestTimeoutMs: 1 \uC774\uC0C1\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${String(ms)}).`);
76
+ }
77
+ DEFAULT_TIMEOUT_MS = ms;
78
+ SYNC_TIMEOUT_MS = Math.max(ms, SYNC_FLOOR_MS);
79
+ }
80
+ function getRequestTimeoutMs() {
81
+ return DEFAULT_TIMEOUT_MS;
82
+ }
83
+
84
+ // src/utils/exit-codes.ts
85
+ var EXIT_API_ERROR = 1;
86
+ var EXIT_AUTH_ERROR = 2;
87
+ var EXIT_PARAM_ERROR = 3;
88
+ var EXIT_CONFIG_ERROR = 4;
89
+
90
+ // src/commands/parse-options.ts
91
+ var POSITIVE_INTEGER_PATTERN = /^[1-9]\d*$/;
92
+ var NON_NEGATIVE_INTEGER_PATTERN = /^(0|[1-9]\d*)$/;
93
+ function parseRequiredArgument(value, label) {
94
+ const trimmed = value.trim();
95
+ if (!trimmed) {
96
+ throw new NhnCloudCliError(`${label} \uC778\uC218\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
97
+ }
98
+ return trimmed;
99
+ }
100
+ function describeRange({ min, max }) {
101
+ if (min !== void 0 && max !== void 0) return `${min} \uC774\uC0C1 ${max} \uC774\uD558\uC758 \uC815\uC218`;
102
+ if (min !== void 0) return `${min} \uC774\uC0C1\uC758 \uC815\uC218`;
103
+ if (max !== void 0) return `${max} \uC774\uD558\uC758 \uC815\uC218`;
104
+ return "0 \uC774\uC0C1\uC758 \uC815\uC218";
105
+ }
106
+ function throwIntegerOptionError(value, flag, range) {
107
+ throw new NhnCloudCliError(
108
+ `${flag} \uB294 ${describeRange(range)}\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
109
+ EXIT_PARAM_ERROR
110
+ );
111
+ }
112
+ function parseIntegerOption(value, flag, range) {
113
+ if (value === void 0) return void 0;
114
+ const pattern = range.min !== void 0 && range.min > 0 ? POSITIVE_INTEGER_PATTERN : NON_NEGATIVE_INTEGER_PATTERN;
115
+ if (!pattern.test(value)) {
116
+ throwIntegerOptionError(value, flag, range);
117
+ }
118
+ const parsed = Number(value);
119
+ if (!Number.isInteger(parsed) || range.min !== void 0 && parsed < range.min || range.max !== void 0 && parsed > range.max) {
120
+ throwIntegerOptionError(value, flag, range);
121
+ }
122
+ return parsed;
123
+ }
124
+ function parsePositiveIntegerOption(value, flag) {
125
+ return parseIntegerOption(value, flag, { min: 1 });
126
+ }
127
+ function parseNonNegativeIntegerOption(value, flag) {
128
+ return parseIntegerOption(value, flag, { min: 0 });
129
+ }
130
+
69
131
  // src/commands/configure.ts
70
132
  var import_commander = require("commander");
71
133
  var import_chalk = __toESM(require("chalk"));
@@ -75,14 +137,6 @@ var import_core = require("@inquirer/core");
75
137
  var import_promises = require("fs/promises");
76
138
  var import_node_os = require("os");
77
139
  var import_node_path = require("path");
78
-
79
- // src/utils/exit-codes.ts
80
- var EXIT_API_ERROR = 1;
81
- var EXIT_AUTH_ERROR = 2;
82
- var EXIT_PARAM_ERROR = 3;
83
- var EXIT_CONFIG_ERROR = 4;
84
-
85
- // src/config/credentials.ts
86
140
  var CREDENTIALS_PATH = (0, import_node_path.join)((0, import_node_os.homedir)(), ".nhncloud", "credentials.json");
87
141
  var CONFIG_PATH = (0, import_node_path.join)((0, import_node_os.homedir)(), ".nhncloud", "config.json");
88
142
  function isCredentials(value) {
@@ -417,6 +471,13 @@ function toNhnCloudCliError(err) {
417
471
  exitCode
418
472
  );
419
473
  }
474
+ if (err instanceof import_ky.TimeoutError) {
475
+ const timeoutSec = getRequestTimeoutMs() / 1e3;
476
+ return new NhnCloudCliError(
477
+ `HTTP \uC694\uCCAD\uC774 ${timeoutSec}\uCD08 \uC0C1\uD55C\uC744 \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4: ${err.message}. --request-timeout <\uCD08>\uB85C \uC0C1\uD55C\uC744 \uB298\uB9B4 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`,
478
+ EXIT_API_ERROR
479
+ );
480
+ }
420
481
  if (err instanceof Error) {
421
482
  return new NhnCloudCliError(err.message, EXIT_API_ERROR);
422
483
  }
@@ -447,7 +508,8 @@ async function getAccessToken(profile, uakId, uakSecret, forceRefresh = false) {
447
508
  "Content-Type": "application/x-www-form-urlencoded"
448
509
  },
449
510
  body: "grant_type=client_credentials",
450
- retry: 0
511
+ retry: 0,
512
+ timeout: DEFAULT_TIMEOUT_MS
451
513
  }).json();
452
514
  } catch (err) {
453
515
  throw toNhnCloudCliError(err);
@@ -593,15 +655,30 @@ function ncsHost(region) {
593
655
  }
594
656
  return host;
595
657
  }
658
+ var APIGATEWAY_HOST = {
659
+ kr1: "kr1-apigateway.api.nhncloudservice.com",
660
+ kr2: "kr2-apigateway.api.nhncloudservice.com",
661
+ kr3: "kr3-apigateway.api.nhncloudservice.com"
662
+ };
663
+ function apigatewayHost(region) {
664
+ const host = APIGATEWAY_HOST[region];
665
+ if (!host) {
666
+ throw new NhnCloudCliError(
667
+ `\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 API Gateway region \uC785\uB2C8\uB2E4: "${region}". \uC0AC\uC6A9 \uAC00\uB2A5\uD55C region: ${Object.keys(APIGATEWAY_HOST).join(", ")}`,
668
+ EXIT_PARAM_ERROR
669
+ );
670
+ }
671
+ return host;
672
+ }
596
673
 
597
674
  // src/api/keystone.ts
598
675
  function isKeystoneTokenResponse(val) {
599
676
  if (typeof val !== "object" || val === null) return false;
600
677
  const obj = val;
601
678
  if (typeof obj["access"] !== "object" || obj["access"] === null) return false;
602
- const access4 = obj["access"];
603
- if (typeof access4["token"] !== "object" || access4["token"] === null) return false;
604
- const token = access4["token"];
679
+ const access = obj["access"];
680
+ if (typeof access["token"] !== "object" || access["token"] === null) return false;
681
+ const token = access["token"];
605
682
  return typeof token["id"] === "string" && typeof token["expires"] === "string";
606
683
  }
607
684
  async function getIaasToken(profile, iaas, forceRefresh = false) {
@@ -639,7 +716,8 @@ async function getIaasToken(profile, iaas, forceRefresh = false) {
639
716
  }
640
717
  }
641
718
  },
642
- retry: 0
719
+ retry: 0,
720
+ timeout: DEFAULT_TIMEOUT_MS
643
721
  }).json();
644
722
  } catch (err) {
645
723
  throw toNhnCloudCliError(err);
@@ -701,7 +779,9 @@ var LogncrashClient = class {
701
779
  sort: { logTime: "DESC" },
702
780
  ...params.pageSize !== void 0 ? { pageSize: params.pageSize } : {},
703
781
  ...params.cursor !== void 0 ? { cursor: params.cursor } : {}
704
- }
782
+ },
783
+ retry: 0,
784
+ timeout: DEFAULT_TIMEOUT_MS
705
785
  }).json();
706
786
  return unwrap(res);
707
787
  } catch (err) {
@@ -722,7 +802,9 @@ var LogncrashClient = class {
722
802
  query: params.query,
723
803
  from: params.from,
724
804
  to: params.to
725
- }
805
+ },
806
+ retry: 0,
807
+ timeout: DEFAULT_TIMEOUT_MS
726
808
  }).json();
727
809
  return unwrap(res);
728
810
  } catch (err) {
@@ -738,7 +820,9 @@ var LogncrashClient = class {
738
820
  const url = `${endpoint}/v3/${encodeURIComponent(this.appkey)}/logs/scroll/${encodeURIComponent(scrollKey)}`;
739
821
  try {
740
822
  const res = await import_ky4.default.post(url, {
741
- headers
823
+ headers,
824
+ retry: 0,
825
+ timeout: DEFAULT_TIMEOUT_MS
742
826
  }).json();
743
827
  return unwrap(res);
744
828
  } catch (err) {
@@ -776,7 +860,9 @@ var LogncrashClient = class {
776
860
  try {
777
861
  const res = await import_ky4.default.post(url, {
778
862
  headers: { "Content-Type": "application/json" },
779
- json: payload
863
+ json: payload,
864
+ retry: 0,
865
+ timeout: DEFAULT_TIMEOUT_MS
780
866
  }).json();
781
867
  unwrapHeader(res);
782
868
  } catch (err) {
@@ -804,7 +890,6 @@ function isArtifact(val) {
804
890
  }
805
891
 
806
892
  // src/services/ncr/client.ts
807
- var DEFAULT_TIMEOUT_MS = 3e4;
808
893
  var NcrClient = class {
809
894
  uakId;
810
895
  uakSecret;
@@ -938,7 +1023,6 @@ function isNcsMalwareReport(val) {
938
1023
  }
939
1024
 
940
1025
  // src/services/ncs/client.ts
941
- var DEFAULT_TIMEOUT_MS2 = 3e4;
942
1026
  var DEFAULT_WAIT_POLL_INTERVAL_MS = 5e3;
943
1027
  var NcsClient = class {
944
1028
  accessToken;
@@ -973,7 +1057,7 @@ var NcsClient = class {
973
1057
  headers: this.authHeaders(),
974
1058
  searchParams,
975
1059
  retry: 0,
976
- timeout: DEFAULT_TIMEOUT_MS2
1060
+ timeout: DEFAULT_TIMEOUT_MS
977
1061
  });
978
1062
  const body = await res.json();
979
1063
  unwrapHeader(body);
@@ -1004,7 +1088,7 @@ var NcsClient = class {
1004
1088
  const res = await import_ky6.default.get(url, {
1005
1089
  headers: this.authHeaders(),
1006
1090
  retry: 0,
1007
- timeout: DEFAULT_TIMEOUT_MS2
1091
+ timeout: DEFAULT_TIMEOUT_MS
1008
1092
  });
1009
1093
  const body = await res.json();
1010
1094
  unwrapHeader(body);
@@ -1038,7 +1122,7 @@ var NcsClient = class {
1038
1122
  headers: this.authHeaders(),
1039
1123
  searchParams,
1040
1124
  retry: 0,
1041
- timeout: DEFAULT_TIMEOUT_MS2
1125
+ timeout: DEFAULT_TIMEOUT_MS
1042
1126
  });
1043
1127
  const body = await res.json();
1044
1128
  unwrapHeader(body);
@@ -1069,7 +1153,7 @@ var NcsClient = class {
1069
1153
  const res = await import_ky6.default.get(url, {
1070
1154
  headers: this.authHeaders(),
1071
1155
  retry: 0,
1072
- timeout: DEFAULT_TIMEOUT_MS2
1156
+ timeout: DEFAULT_TIMEOUT_MS
1073
1157
  });
1074
1158
  const body = await res.json();
1075
1159
  unwrapHeader(body);
@@ -1102,7 +1186,7 @@ var NcsClient = class {
1102
1186
  headers: this.authHeaders(),
1103
1187
  searchParams,
1104
1188
  retry: 0,
1105
- timeout: DEFAULT_TIMEOUT_MS2
1189
+ timeout: DEFAULT_TIMEOUT_MS
1106
1190
  });
1107
1191
  const body = await res.json();
1108
1192
  unwrapHeader(body);
@@ -1133,7 +1217,7 @@ var NcsClient = class {
1133
1217
  const res = await import_ky6.default.get(url, {
1134
1218
  headers: this.authHeaders(),
1135
1219
  retry: 0,
1136
- timeout: DEFAULT_TIMEOUT_MS2
1220
+ timeout: DEFAULT_TIMEOUT_MS
1137
1221
  });
1138
1222
  const body = await res.json();
1139
1223
  unwrapHeader(body);
@@ -1174,7 +1258,7 @@ var NcsClient = class {
1174
1258
  headers: this.authHeaders(),
1175
1259
  searchParams,
1176
1260
  retry: 0,
1177
- timeout: DEFAULT_TIMEOUT_MS2
1261
+ timeout: DEFAULT_TIMEOUT_MS
1178
1262
  });
1179
1263
  const body = await res.json();
1180
1264
  unwrapHeader(body);
@@ -1212,7 +1296,7 @@ var NcsClient = class {
1212
1296
  headers: this.authHeaders(),
1213
1297
  searchParams,
1214
1298
  retry: 0,
1215
- timeout: DEFAULT_TIMEOUT_MS2
1299
+ timeout: DEFAULT_TIMEOUT_MS
1216
1300
  });
1217
1301
  const body = await res.json();
1218
1302
  unwrapHeader(body);
@@ -1249,7 +1333,7 @@ var NcsClient = class {
1249
1333
  headers: this.authHeaders(),
1250
1334
  searchParams,
1251
1335
  retry: 0,
1252
- timeout: DEFAULT_TIMEOUT_MS2
1336
+ timeout: DEFAULT_TIMEOUT_MS
1253
1337
  });
1254
1338
  const body = await res.json();
1255
1339
  unwrapHeader(body);
@@ -1280,7 +1364,7 @@ var NcsClient = class {
1280
1364
  const res = await import_ky6.default.get(url, {
1281
1365
  headers: this.authHeaders(),
1282
1366
  retry: 0,
1283
- timeout: DEFAULT_TIMEOUT_MS2
1367
+ timeout: DEFAULT_TIMEOUT_MS
1284
1368
  });
1285
1369
  const body = await res.json();
1286
1370
  unwrapHeader(body);
@@ -1308,7 +1392,7 @@ var NcsClient = class {
1308
1392
  const res = await import_ky6.default.get(url, {
1309
1393
  headers: this.authHeaders(),
1310
1394
  retry: 0,
1311
- timeout: DEFAULT_TIMEOUT_MS2
1395
+ timeout: DEFAULT_TIMEOUT_MS
1312
1396
  });
1313
1397
  const body = await res.json();
1314
1398
  unwrapHeader(body);
@@ -1338,7 +1422,7 @@ var NcsClient = class {
1338
1422
  headers: this.authHeaders(),
1339
1423
  json: body,
1340
1424
  retry: 0,
1341
- timeout: DEFAULT_TIMEOUT_MS2
1425
+ timeout: DEFAULT_TIMEOUT_MS
1342
1426
  });
1343
1427
  const resBody = await res.json();
1344
1428
  unwrapHeader(resBody);
@@ -1364,7 +1448,7 @@ var NcsClient = class {
1364
1448
  const res = await import_ky6.default.delete(url, {
1365
1449
  headers: this.authHeaders(),
1366
1450
  retry: 0,
1367
- timeout: DEFAULT_TIMEOUT_MS2
1451
+ timeout: DEFAULT_TIMEOUT_MS
1368
1452
  });
1369
1453
  unwrapHeader(await res.json());
1370
1454
  } catch (err) {
@@ -1386,7 +1470,7 @@ var NcsClient = class {
1386
1470
  headers: this.authHeaders(),
1387
1471
  json: body,
1388
1472
  retry: 0,
1389
- timeout: DEFAULT_TIMEOUT_MS2
1473
+ timeout: DEFAULT_TIMEOUT_MS
1390
1474
  });
1391
1475
  const resBody = await res.json();
1392
1476
  unwrapHeader(resBody);
@@ -1412,7 +1496,7 @@ var NcsClient = class {
1412
1496
  const res = await import_ky6.default.delete(url, {
1413
1497
  headers: this.authHeaders(),
1414
1498
  retry: 0,
1415
- timeout: DEFAULT_TIMEOUT_MS2
1499
+ timeout: DEFAULT_TIMEOUT_MS
1416
1500
  });
1417
1501
  unwrapHeader(await res.json());
1418
1502
  } catch (err) {
@@ -1430,7 +1514,7 @@ var NcsClient = class {
1430
1514
  const res = await import_ky6.default.post(url, {
1431
1515
  headers: this.authHeaders(),
1432
1516
  retry: 0,
1433
- timeout: DEFAULT_TIMEOUT_MS2
1517
+ timeout: DEFAULT_TIMEOUT_MS
1434
1518
  });
1435
1519
  unwrapHeader(await res.json());
1436
1520
  } catch (err) {
@@ -1448,7 +1532,7 @@ var NcsClient = class {
1448
1532
  const res = await import_ky6.default.post(url, {
1449
1533
  headers: this.authHeaders(),
1450
1534
  retry: 0,
1451
- timeout: DEFAULT_TIMEOUT_MS2
1535
+ timeout: DEFAULT_TIMEOUT_MS
1452
1536
  });
1453
1537
  unwrapHeader(await res.json());
1454
1538
  } catch (err) {
@@ -1466,7 +1550,7 @@ var NcsClient = class {
1466
1550
  const res = await import_ky6.default.post(url, {
1467
1551
  headers: this.authHeaders(),
1468
1552
  retry: 0,
1469
- timeout: DEFAULT_TIMEOUT_MS2
1553
+ timeout: DEFAULT_TIMEOUT_MS
1470
1554
  });
1471
1555
  unwrapHeader(await res.json());
1472
1556
  } catch (err) {
@@ -1487,7 +1571,7 @@ var NcsClient = class {
1487
1571
  headers: this.authHeaders(),
1488
1572
  json: body,
1489
1573
  retry: 0,
1490
- timeout: DEFAULT_TIMEOUT_MS2
1574
+ timeout: DEFAULT_TIMEOUT_MS
1491
1575
  });
1492
1576
  const resBody = await res.json();
1493
1577
  unwrapHeader(resBody);
@@ -1515,7 +1599,7 @@ var NcsClient = class {
1515
1599
  headers: this.authHeaders(),
1516
1600
  json: body,
1517
1601
  retry: 0,
1518
- timeout: DEFAULT_TIMEOUT_MS2
1602
+ timeout: DEFAULT_TIMEOUT_MS
1519
1603
  });
1520
1604
  const resBody = await res.json();
1521
1605
  unwrapHeader(resBody);
@@ -1545,7 +1629,7 @@ var NcsClient = class {
1545
1629
  headers: { ...this.authHeaders(), "Content-Type": "application/json-patch+json" },
1546
1630
  json: patch,
1547
1631
  retry: 0,
1548
- timeout: DEFAULT_TIMEOUT_MS2
1632
+ timeout: DEFAULT_TIMEOUT_MS
1549
1633
  });
1550
1634
  const resBody = await res.json();
1551
1635
  unwrapHeader(resBody);
@@ -1596,7 +1680,7 @@ var NcsClient = class {
1596
1680
  const res = await import_ky6.default.delete(url, {
1597
1681
  headers: this.authHeaders(),
1598
1682
  retry: 0,
1599
- timeout: DEFAULT_TIMEOUT_MS2
1683
+ timeout: DEFAULT_TIMEOUT_MS
1600
1684
  });
1601
1685
  unwrapHeader(await res.json());
1602
1686
  } catch (err) {
@@ -1615,7 +1699,7 @@ var NcsClient = class {
1615
1699
  const res = await import_ky6.default.get(url, {
1616
1700
  headers: this.authHeaders(),
1617
1701
  retry: 0,
1618
- timeout: DEFAULT_TIMEOUT_MS2
1702
+ timeout: DEFAULT_TIMEOUT_MS
1619
1703
  });
1620
1704
  const body = await res.json();
1621
1705
  unwrapHeader(body);
@@ -1645,7 +1729,7 @@ var NcsClient = class {
1645
1729
  headers: this.authHeaders(),
1646
1730
  json: { enabled },
1647
1731
  retry: 0,
1648
- timeout: DEFAULT_TIMEOUT_MS2
1732
+ timeout: DEFAULT_TIMEOUT_MS
1649
1733
  });
1650
1734
  const body = await res.json();
1651
1735
  unwrapHeader(body);
@@ -1674,7 +1758,7 @@ var NcsClient = class {
1674
1758
  const res = await import_ky6.default.get(url, {
1675
1759
  headers: this.authHeaders(),
1676
1760
  retry: 0,
1677
- timeout: DEFAULT_TIMEOUT_MS2
1761
+ timeout: DEFAULT_TIMEOUT_MS
1678
1762
  });
1679
1763
  const body = await res.json();
1680
1764
  unwrapHeader(body);
@@ -1771,7 +1855,7 @@ async function verifyLogncrash(uak, appkey) {
1771
1855
  }
1772
1856
 
1773
1857
  // src/commands/configure.ts
1774
- async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, doVerify, logncrashUak = uak) {
1858
+ async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, apigateway, doVerify, logncrashUak = uak) {
1775
1859
  if (doVerify) {
1776
1860
  if (uak) {
1777
1861
  const ok = await verifyUserAccessKey(uak);
@@ -1868,6 +1952,9 @@ async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, doVeri
1868
1952
  if (ncs) {
1869
1953
  await setServiceCredential(profileName, "ncs", ncs);
1870
1954
  }
1955
+ if (apigateway) {
1956
+ await setServiceCredential(profileName, "apigateway", apigateway);
1957
+ }
1871
1958
  process.stderr.write(import_chalk.default.green(`
1872
1959
  \u2713 profile "${profileName}" \uC124\uC815\uC774 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
1873
1960
  `));
@@ -1981,7 +2068,7 @@ async function runInteractive(opts) {
1981
2068
  }
1982
2069
  if (opts.verify) {
1983
2070
  try {
1984
- await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, true, uak);
2071
+ await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, true, uak);
1985
2072
  } catch (err) {
1986
2073
  if (err instanceof NhnCloudCliError && err.exitCode === EXIT_AUTH_ERROR) {
1987
2074
  process.stderr.write(import_chalk.default.red(` \u2717 ${err.message}
@@ -1994,13 +2081,13 @@ async function runInteractive(opts) {
1994
2081
  process.stderr.write(import_chalk.default.yellow("\uC800\uC7A5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
1995
2082
  return;
1996
2083
  }
1997
- await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, false, uak);
2084
+ await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, false, uak);
1998
2085
  } else {
1999
2086
  throw err;
2000
2087
  }
2001
2088
  }
2002
2089
  } else {
2003
- await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, false, uak);
2090
+ await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, false, uak);
2004
2091
  }
2005
2092
  }
2006
2093
  async function runNonInteractive(opts) {
@@ -2021,6 +2108,9 @@ async function runNonInteractive(opts) {
2021
2108
  if (opts.logncrashAppkey !== void 0 && opts.logncrashAppkey.trim().length === 0) {
2022
2109
  throw new NhnCloudCliError("--logncrash-appkey \uAC12\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
2023
2110
  }
2111
+ if (opts.apigatewayAppkey !== void 0 && opts.apigatewayAppkey.trim().length === 0) {
2112
+ throw new NhnCloudCliError("--apigateway-appkey \uAC12\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
2113
+ }
2024
2114
  if (opts.logncrashSecret !== void 0) {
2025
2115
  process.stderr.write(
2026
2116
  import_chalk.default.yellow(
@@ -2039,9 +2129,10 @@ async function runNonInteractive(opts) {
2039
2129
  } : void 0;
2040
2130
  const ncr = opts.ncrAppkey?.trim() ? { appkey: opts.ncrAppkey.trim() } : void 0;
2041
2131
  const ncs = opts.ncsAppkey?.trim() ? { appkey: opts.ncsAppkey.trim() } : void 0;
2042
- if (!uak && !logncrash && !iaas && !ncr && !ncs) {
2132
+ const apigateway = opts.apigatewayAppkey?.trim() ? { appkey: opts.apigatewayAppkey.trim() } : void 0;
2133
+ if (!uak && !logncrash && !iaas && !ncr && !ncs && !apigateway) {
2043
2134
  throw new NhnCloudCliError(
2044
- "\uBE44\uB300\uD654\uD615 \uBAA8\uB4DC: --uak-id + UAK secret, --logncrash-appkey,\n--iaas-tenant-id + --iaas-username + iaas password,\n--ncr-appkey, \uB610\uB294 --ncs-appkey \uC911 \uD558\uB098\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\nsecret/password \uB294 \uB178\uCD9C \uBC29\uC9C0\uB97C \uC704\uD574 \uD658\uACBD\uBCC0\uC218 \uAD8C\uC7A5:\nNHNCLOUD_UAK_SECRET / NHNCLOUD_IAAS_PASSWORD.",
2135
+ "\uBE44\uB300\uD654\uD615 \uBAA8\uB4DC: --uak-id + UAK secret, --logncrash-appkey,\n--iaas-tenant-id + --iaas-username + iaas password,\n--ncr-appkey, --ncs-appkey, \uB610\uB294 --apigateway-appkey \uC911 \uD558\uB098\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\nsecret/password \uB294 \uB178\uCD9C \uBC29\uC9C0\uB97C \uC704\uD574 \uD658\uACBD\uBCC0\uC218 \uAD8C\uC7A5:\nNHNCLOUD_UAK_SECRET / NHNCLOUD_IAAS_PASSWORD.",
2045
2136
  EXIT_PARAM_ERROR
2046
2137
  );
2047
2138
  }
@@ -2059,6 +2150,7 @@ async function runNonInteractive(opts) {
2059
2150
  iaas,
2060
2151
  ncr,
2061
2152
  ncs,
2153
+ apigateway,
2062
2154
  opts.verify,
2063
2155
  logncrashUak
2064
2156
  );
@@ -2066,8 +2158,8 @@ async function runNonInteractive(opts) {
2066
2158
  var configureCommand = new import_commander.Command("configure").description("\uC790\uACA9\uC99D\uBA85 \uC124\uC815 \uB9C8\uBC95\uC0AC (\uB300\uD654\uD615 + flag)").option("--profile <name>", "\uB300\uC0C1 profile \uC774\uB984 (\uAE30\uBCF8: default)").option("--uak-id <id>", "\uAC1C\uC778 UAK ID (\uBE44\uB300\uD654\uD615)").option("--uak-secret <secret>", "\uAC1C\uC778 UAK Secret (\uBE44\uB300\uD654\uD615, \uB178\uCD9C \uBC29\uC9C0\uB85C env NHNCLOUD_UAK_SECRET \uAD8C\uC7A5)").option("--logncrash-appkey <key>", "logncrash appkey (\uBE44\uB300\uD654\uD615)").option("--logncrash-secret <secret>", "\uD3D0\uAE30 \uC608\uC815: Search v3\uC5D0\uC11C\uB294 \uC0AC\uC6A9\xB7\uC800\uC7A5\uD558\uC9C0 \uC54A\uC74C").option("--iaas-tenant-id <id>", "iaas tenantId / \uD504\uB85C\uC81D\uD2B8 ID (\uBE44\uB300\uD654\uD615)").option("--iaas-username <user>", "iaas IAM username (\uBE44\uB300\uD654\uD615)").option(
2067
2159
  "--iaas-password <pass>",
2068
2160
  "iaas API \uBE44\uBC00\uBC88\uD638 (\uBE44\uB300\uD654\uD615, \uB178\uCD9C \uBC29\uC9C0\uB85C env NHNCLOUD_IAAS_PASSWORD \uAD8C\uC7A5)"
2069
- ).option("--iaas-region <region>", "iaas region (\uAE30\uBCF8: kr1)", "kr1").option("--ncr-appkey <key>", "ncr appkey (\uBE44\uB300\uD654\uD615)").option("--ncs-appkey <key>", "ncs appkey (\uBE44\uB300\uD654\uD615)").option("--no-verify", "\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC0DD\uB7B5").action(async (opts) => {
2070
- const hasFlag = opts.uakId !== void 0 || opts.uakSecret !== void 0 || opts.logncrashAppkey !== void 0 || opts.logncrashSecret !== void 0 || opts.iaasTenantId !== void 0 || opts.iaasUsername !== void 0 || opts.iaasPassword !== void 0 || opts.ncrAppkey !== void 0 || opts.ncsAppkey !== void 0;
2161
+ ).option("--iaas-region <region>", "iaas region (\uAE30\uBCF8: kr1)", "kr1").option("--ncr-appkey <key>", "ncr appkey (\uBE44\uB300\uD654\uD615)").option("--ncs-appkey <key>", "ncs appkey (\uBE44\uB300\uD654\uD615)").option("--apigateway-appkey <key>", "API Gateway appkey (\uBE44\uB300\uD654\uD615)").option("--no-verify", "\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC0DD\uB7B5").action(async (opts) => {
2162
+ const hasFlag = opts.uakId !== void 0 || opts.uakSecret !== void 0 || opts.logncrashAppkey !== void 0 || opts.logncrashSecret !== void 0 || opts.iaasTenantId !== void 0 || opts.iaasUsername !== void 0 || opts.iaasPassword !== void 0 || opts.ncrAppkey !== void 0 || opts.ncsAppkey !== void 0 || opts.apigatewayAppkey !== void 0;
2071
2163
  try {
2072
2164
  if (hasFlag) {
2073
2165
  await runNonInteractive(opts);
@@ -2085,206 +2177,922 @@ var configureCommand = new import_commander.Command("configure").description("\u
2085
2177
 
2086
2178
  // src/commands/skills.ts
2087
2179
  var import_commander2 = require("commander");
2088
- var import_chalk2 = __toESM(require("chalk"));
2089
- var import_promises4 = require("fs/promises");
2090
2180
 
2091
- // src/utils/skill-install.ts
2181
+ // src/skill/context.ts
2182
+ var import_node_fs = require("fs");
2092
2183
  var import_node_os3 = require("os");
2093
2184
  var import_node_path3 = __toESM(require("path"));
2094
- var import_promises3 = require("fs/promises");
2095
- var SKILL_NAME = "nhncloud-cli";
2096
- function claudeDir() {
2097
- return import_node_path3.default.join((0, import_node_os3.homedir)(), ".claude");
2098
- }
2099
- function skillDestPath() {
2100
- return import_node_path3.default.join(claudeDir(), "skills", SKILL_NAME);
2101
- }
2102
- function skillSourceFrom(bundleDir) {
2103
- return import_node_path3.default.resolve(bundleDir, "..", "skills", SKILL_NAME);
2104
- }
2105
- function isNpxRuntime(bundleDir) {
2106
- return /_npx[/\\]/.test(bundleDir) || /\.npm[/\\]_npx/.test(bundleDir) || /npx-/.test(bundleDir);
2185
+ var PACKAGE_NAME = "@bifos/nhncloud-cli";
2186
+ function isPackageMetadata(value) {
2187
+ return typeof value === "object" && value !== null && !Array.isArray(value) && "name" in value && value.name === PACKAGE_NAME && "version" in value && typeof value.version === "string" && value.version.length > 0;
2107
2188
  }
2108
- async function getSkillStatus(dst) {
2109
- let stat;
2189
+ function parsePackageMetadata(packageRoot) {
2190
+ const packagePath = import_node_path3.default.join(packageRoot, "package.json");
2110
2191
  try {
2111
- stat = await (0, import_promises3.lstat)(dst);
2112
- } catch {
2113
- return { state: "not-installed" };
2192
+ return JSON.parse((0, import_node_fs.readFileSync)(packagePath, "utf8"));
2193
+ } catch (error) {
2194
+ const reason = error instanceof Error ? error.message : String(error);
2195
+ throw new NhnCloudCliError(
2196
+ `\uD328\uD0A4\uC9C0 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${packagePath} (${reason})`,
2197
+ EXIT_PARAM_ERROR
2198
+ );
2114
2199
  }
2115
- if (!stat.isSymbolicLink()) {
2116
- return { state: "installed-copy" };
2200
+ }
2201
+ function findPackageRoot(bundleDir) {
2202
+ let candidate = import_node_path3.default.resolve(bundleDir);
2203
+ while (true) {
2204
+ const packagePath = import_node_path3.default.join(candidate, "package.json");
2205
+ if ((0, import_node_fs.existsSync)(packagePath)) {
2206
+ const metadata = parsePackageMetadata(candidate);
2207
+ if (isPackageMetadata(metadata)) {
2208
+ return candidate;
2209
+ }
2210
+ }
2211
+ const parent = import_node_path3.default.dirname(candidate);
2212
+ if (parent === candidate) {
2213
+ throw new NhnCloudCliError(
2214
+ `${PACKAGE_NAME} \uD328\uD0A4\uC9C0 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${bundleDir}`,
2215
+ EXIT_PARAM_ERROR
2216
+ );
2217
+ }
2218
+ candidate = parent;
2117
2219
  }
2118
- const raw = await (0, import_promises3.readlink)(dst);
2119
- const target = import_node_path3.default.isAbsolute(raw) ? raw : import_node_path3.default.resolve(import_node_path3.default.dirname(dst), raw);
2120
- const targetExists = await (0, import_promises3.access)(target).then(() => true).catch(() => false);
2121
- return targetExists ? { state: "installed-link", target } : { state: "broken-link", target };
2122
2220
  }
2123
- async function installSkillSymlink(src, dst, force) {
2124
- const srcExists = await (0, import_promises3.access)(src).then(() => true).catch(() => false);
2125
- if (!srcExists) {
2126
- throw new NhnCloudCliError(`skill \uC6D0\uBCF8\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${src}`, EXIT_PARAM_ERROR);
2221
+ function resolveSkillDataRoot(homeDir, xdgDataHome) {
2222
+ if (xdgDataHome && import_node_path3.default.isAbsolute(xdgDataHome)) {
2223
+ return import_node_path3.default.join(xdgDataHome, "nhncloud-cli");
2127
2224
  }
2128
- const status = await getSkillStatus(dst);
2129
- if (status.state === "installed-copy" && !force) {
2225
+ return import_node_path3.default.join(homeDir, ".local", "share", "nhncloud-cli");
2226
+ }
2227
+ function readPackageVersion(packageRoot) {
2228
+ const metadata = parsePackageMetadata(packageRoot);
2229
+ if (!isPackageMetadata(metadata)) {
2130
2230
  throw new NhnCloudCliError(
2131
- `${dst} \uC5D0 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uAC00 \uC544\uB2CC \uC2E4\uC81C \uD56D\uBAA9\uC774 \uC788\uC2B5\uB2C8\uB2E4. --force \uB85C \uB36E\uC5B4\uC4F0\uC138\uC694.`,
2231
+ `package.json\uC758 name\uACFC version\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${import_node_path3.default.join(packageRoot, "package.json")}`,
2132
2232
  EXIT_PARAM_ERROR
2133
2233
  );
2134
2234
  }
2135
- let result = "linked";
2136
- if (status.state === "installed-copy") {
2137
- await (0, import_promises3.rm)(dst, { recursive: true, force: true });
2138
- result = "replaced-copy";
2139
- } else if (status.state !== "not-installed") {
2140
- await (0, import_promises3.rm)(dst, { force: true });
2141
- result = "relinked";
2142
- }
2143
- await (0, import_promises3.mkdir)(import_node_path3.default.dirname(dst), { recursive: true });
2144
- await (0, import_promises3.symlink)(src, dst);
2145
- return result;
2146
- }
2147
- async function uninstallSkill(dst) {
2148
- const status = await getSkillStatus(dst);
2149
- if (status.state === "not-installed") {
2150
- return "absent";
2235
+ return metadata.version;
2236
+ }
2237
+ function createSkillManagerContext() {
2238
+ const homeDir = (0, import_node_os3.homedir)();
2239
+ const packageRoot = findPackageRoot(__dirname);
2240
+ return {
2241
+ homeDir,
2242
+ packageRoot,
2243
+ currentVersion: readPackageVersion(packageRoot),
2244
+ dataRoot: resolveSkillDataRoot(homeDir, process.env.XDG_DATA_HOME)
2245
+ };
2246
+ }
2247
+
2248
+ // src/skill/manager.ts
2249
+ var import_node_crypto3 = require("crypto");
2250
+ var import_promises3 = require("fs/promises");
2251
+ var import_node_path5 = __toESM(require("path"));
2252
+
2253
+ // src/skill/manifest.ts
2254
+ var import_node_crypto2 = require("crypto");
2255
+ var import_node_fs2 = require("fs");
2256
+ var import_node_path4 = __toESM(require("path"));
2257
+ var MANIFEST_FILE_NAME = ".nhncloud-skill.json";
2258
+ var HASH_PREFIX = Buffer.from("nhncloud-skill-content-v1\0", "utf8");
2259
+ var PACKAGE_NAME2 = "@bifos/nhncloud-cli";
2260
+ var SKILL_NAME = "nhncloud-cli";
2261
+ var CONTENT_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
2262
+ function isUtcIsoTimestamp(value) {
2263
+ if (typeof value !== "string") {
2264
+ return false;
2265
+ }
2266
+ try {
2267
+ return new Date(value).toISOString() === value;
2268
+ } catch {
2269
+ return false;
2270
+ }
2271
+ }
2272
+ function isNhnCloudSkillManifest(value) {
2273
+ return typeof value === "object" && value !== null && !Array.isArray(value) && "schemaVersion" in value && value.schemaVersion === 1 && "skillName" in value && value.skillName === SKILL_NAME && "packageName" in value && value.packageName === PACKAGE_NAME2 && "packageVersion" in value && typeof value.packageVersion === "string" && value.packageVersion.length > 0 && "contentDigest" in value && typeof value.contentDigest === "string" && CONTENT_DIGEST_PATTERN.test(value.contentDigest) && "installedAt" in value && isUtcIsoTimestamp(value.installedAt) && "managedBy" in value && value.managedBy === PACKAGE_NAME2;
2274
+ }
2275
+ function createSkillManifest(packageVersion, contentDigest, installedAt = (/* @__PURE__ */ new Date()).toISOString()) {
2276
+ const candidate = {
2277
+ schemaVersion: 1,
2278
+ skillName: SKILL_NAME,
2279
+ packageName: PACKAGE_NAME2,
2280
+ packageVersion,
2281
+ contentDigest,
2282
+ installedAt,
2283
+ managedBy: PACKAGE_NAME2
2284
+ };
2285
+ if (!isNhnCloudSkillManifest(candidate)) {
2286
+ throw new NhnCloudCliError("\uC2A4\uD0AC \uB9E4\uB2C8\uD398\uC2A4\uD2B8 \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
2151
2287
  }
2152
- if (status.state === "installed-copy") {
2288
+ return candidate;
2289
+ }
2290
+ function readSkillManifest(skillRoot) {
2291
+ const manifestPath = import_node_path4.default.join(skillRoot, MANIFEST_FILE_NAME);
2292
+ let parsed;
2293
+ try {
2294
+ parsed = JSON.parse((0, import_node_fs2.readFileSync)(manifestPath, "utf8"));
2295
+ } catch (error) {
2296
+ const reason = error instanceof Error ? error.message : String(error);
2153
2297
  throw new NhnCloudCliError(
2154
- `${dst} \uB294 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uAC00 \uC544\uB2C8\uB77C \uC2E4\uC81C \uB514\uB809\uD130\uB9AC\uC785\uB2C8\uB2E4. \uC9C1\uC811 \uD655\uC778 \uD6C4 \uC81C\uAC70\uD558\uC138\uC694.`,
2298
+ `\uC2A4\uD0AC \uB9E4\uB2C8\uD398\uC2A4\uD2B8\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${manifestPath} (${reason})`,
2155
2299
  EXIT_PARAM_ERROR
2156
2300
  );
2157
2301
  }
2158
- await (0, import_promises3.rm)(dst, { force: true });
2159
- return "removed";
2302
+ if (!isNhnCloudSkillManifest(parsed)) {
2303
+ throw new NhnCloudCliError(`\uC2A4\uD0AC \uB9E4\uB2C8\uD398\uC2A4\uD2B8 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${manifestPath}`, EXIT_PARAM_ERROR);
2304
+ }
2305
+ return parsed;
2160
2306
  }
2161
-
2162
- // src/commands/skills.ts
2163
- function describeStatus(status) {
2164
- switch (status.state) {
2165
- case "installed-link":
2166
- return import_chalk2.default.green(`\u2713 \uC124\uCE58\uB428 (\uC2EC\uBCFC\uB9AD \uB9C1\uD06C \u2192 ${status.target})`);
2167
- case "broken-link":
2168
- return import_chalk2.default.yellow(`\u26A0 \uB9C1\uD06C \uAE68\uC9D0 (${status.target} \uC5C6\uC74C) \u2014 skills install \uB85C \uC7AC\uC124\uCE58`);
2169
- case "installed-copy":
2170
- return import_chalk2.default.green("\u2713 \uC124\uCE58\uB428 (\uC2E4\uC81C \uBCF5\uC0AC\uBCF8)");
2171
- case "not-installed":
2172
- return import_chalk2.default.gray("\uBBF8\uC124\uCE58 \u2014 nhncloud skills install \uB85C \uC124\uCE58");
2173
- }
2174
- }
2175
- var installCommand = new import_commander2.Command("install").description("Claude Code \uC2A4\uD0AC\uC744 ~/.claude/skills \uC5D0 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB85C \uC124\uCE58\uD55C\uB2E4").option("--force", "\uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uAC00 \uC544\uB2CC \uAE30\uC874 \uD56D\uBAA9\uB3C4 \uB36E\uC5B4\uC4F4\uB2E4").action(async (opts) => {
2176
- const hasClaude = await (0, import_promises4.access)(claudeDir()).then(() => true).catch(() => false);
2177
- if (!hasClaude) {
2307
+ function compareByCodePoint(left, right) {
2308
+ const leftPoints = Array.from(left, (character) => character.codePointAt(0) ?? 0);
2309
+ const rightPoints = Array.from(right, (character) => character.codePointAt(0) ?? 0);
2310
+ const limit = Math.min(leftPoints.length, rightPoints.length);
2311
+ for (let index = 0; index < limit; index += 1) {
2312
+ const difference = leftPoints[index] - rightPoints[index];
2313
+ if (difference !== 0) {
2314
+ return difference;
2315
+ }
2316
+ }
2317
+ return leftPoints.length - rightPoints.length;
2318
+ }
2319
+ function ensureRegularFile(filePath) {
2320
+ let stat2;
2321
+ try {
2322
+ stat2 = (0, import_node_fs2.lstatSync)(filePath);
2323
+ } catch (error) {
2324
+ const reason = error instanceof Error ? error.message : String(error);
2325
+ throw new NhnCloudCliError(`\uC2A4\uD0AC \uD30C\uC77C\uC744 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${filePath} (${reason})`, EXIT_PARAM_ERROR);
2326
+ }
2327
+ if (stat2.isSymbolicLink() || !stat2.isFile()) {
2328
+ throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uB294 \uC815\uADDC \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
2329
+ }
2330
+ }
2331
+ function collectReferenceFiles(referencesRoot, currentDir, files) {
2332
+ let entries;
2333
+ try {
2334
+ entries = (0, import_node_fs2.readdirSync)(currentDir, { withFileTypes: true });
2335
+ } catch (error) {
2336
+ const reason = error instanceof Error ? error.message : String(error);
2178
2337
  throw new NhnCloudCliError(
2179
- `Claude Code \uC124\uC815 \uB514\uB809\uD130\uB9AC(${claudeDir()})\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. Claude Code \uC124\uCE58 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.`,
2338
+ `\uC2A4\uD0AC references\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${currentDir} (${reason})`,
2180
2339
  EXIT_PARAM_ERROR
2181
2340
  );
2182
2341
  }
2183
- if (isNpxRuntime(__dirname)) {
2342
+ for (const entry of entries) {
2343
+ const entryPath = import_node_path4.default.join(currentDir, entry.name);
2344
+ let stat2;
2345
+ try {
2346
+ stat2 = (0, import_node_fs2.lstatSync)(entryPath);
2347
+ } catch (error) {
2348
+ const reason = error instanceof Error ? error.message : String(error);
2349
+ throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${entryPath} (${reason})`, EXIT_PARAM_ERROR);
2350
+ }
2351
+ if (stat2.isSymbolicLink()) {
2352
+ throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uC5D0 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${entryPath}`, EXIT_PARAM_ERROR);
2353
+ }
2354
+ if (stat2.isDirectory()) {
2355
+ collectReferenceFiles(referencesRoot, entryPath, files);
2356
+ continue;
2357
+ }
2358
+ if (!stat2.isFile()) {
2359
+ throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uB294 \uC815\uADDC \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${entryPath}`, EXIT_PARAM_ERROR);
2360
+ }
2361
+ files.push(`references/${import_node_path4.default.relative(referencesRoot, entryPath).split(import_node_path4.default.sep).join("/")}`);
2362
+ }
2363
+ }
2364
+ function writeLength(hash, length) {
2365
+ const encodedLength = Buffer.alloc(8);
2366
+ encodedLength.writeBigUInt64BE(BigInt(length));
2367
+ hash.update(encodedLength);
2368
+ }
2369
+ function calculateSkillContentDigest(skillRoot) {
2370
+ const skillPath = import_node_path4.default.join(skillRoot, "SKILL.md");
2371
+ const referencesRoot = import_node_path4.default.join(skillRoot, "references");
2372
+ ensureRegularFile(skillPath);
2373
+ let referencesStat;
2374
+ try {
2375
+ referencesStat = (0, import_node_fs2.lstatSync)(referencesRoot);
2376
+ } catch (error) {
2377
+ const reason = error instanceof Error ? error.message : String(error);
2184
2378
  throw new NhnCloudCliError(
2185
- "npx \uD658\uACBD\uC5D0\uC11C\uB294 \uC2A4\uD0AC \uC124\uCE58\uAC00 \uBD88\uAC00\uD569\uB2C8\uB2E4(\uC784\uC2DC \uACBD\uB85C). npm i -g @bifos/nhncloud-cli \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.",
2379
+ `\uC2A4\uD0AC references\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${referencesRoot} (${reason})`,
2186
2380
  EXIT_PARAM_ERROR
2187
2381
  );
2188
2382
  }
2189
- const src = skillSourceFrom(__dirname);
2190
- const dst = skillDestPath();
2191
- const result = await installSkillSymlink(src, dst, opts.force ?? false);
2192
- if (result === "replaced-copy") {
2193
- console.error(import_chalk2.default.yellow(`\uAE30\uC874 \uC2E4\uC81C \uB514\uB809\uD130\uB9AC\uB97C \uC81C\uAC70\uD558\uACE0 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB85C \uAD50\uCCB4\uD588\uC2B5\uB2C8\uB2E4: ${dst}`));
2383
+ if (referencesStat.isSymbolicLink() || !referencesStat.isDirectory()) {
2384
+ throw new NhnCloudCliError(`\uC2A4\uD0AC references\uB294 \uC2E4\uC81C \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${referencesRoot}`, EXIT_PARAM_ERROR);
2194
2385
  }
2195
- console.log(import_chalk2.default.green(`\u2713 \uC2A4\uD0AC ${result === "linked" ? "\uC124\uCE58" : "\uC7AC\uC124\uCE58"} \uC644\uB8CC: ${dst}`));
2196
- });
2197
- var uninstallCommand = new import_commander2.Command("uninstall").description("\uC124\uCE58\uB41C Claude Code \uC2A4\uD0AC \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB97C \uC81C\uAC70\uD55C\uB2E4").action(async () => {
2198
- const dst = skillDestPath();
2199
- const result = await uninstallSkill(dst);
2200
- if (result === "absent") {
2201
- console.log(import_chalk2.default.gray("\uC124\uCE58\uB41C \uC2A4\uD0AC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
2202
- return;
2386
+ const relativePaths = ["SKILL.md"];
2387
+ collectReferenceFiles(referencesRoot, referencesRoot, relativePaths);
2388
+ relativePaths.sort(compareByCodePoint);
2389
+ const hash = (0, import_node_crypto2.createHash)("sha256");
2390
+ hash.update(HASH_PREFIX);
2391
+ for (const relativePath of relativePaths) {
2392
+ const pathBytes = Buffer.from(relativePath, "utf8");
2393
+ const content = (0, import_node_fs2.readFileSync)(import_node_path4.default.join(skillRoot, ...relativePath.split("/")));
2394
+ writeLength(hash, pathBytes.length);
2395
+ hash.update(pathBytes);
2396
+ writeLength(hash, content.length);
2397
+ hash.update(content);
2203
2398
  }
2204
- console.log(import_chalk2.default.green(`\u2713 \uC2A4\uD0AC \uC81C\uAC70 \uC644\uB8CC: ${dst}`));
2205
- });
2206
- var skillsCommand = new import_commander2.Command("skills").description(`Claude Code \uC2A4\uD0AC(${SKILL_NAME}) \uC124\uCE58 \uAD00\uB9AC`).addCommand(installCommand).addCommand(uninstallCommand).action(async () => {
2207
- const status = await getSkillStatus(skillDestPath());
2208
- console.log(`Claude Code \uC2A4\uD0AC (${SKILL_NAME}): ${describeStatus(status)}`);
2209
- });
2399
+ return `sha256:${hash.digest("hex")}`;
2400
+ }
2210
2401
 
2211
- // src/commands/doctor.ts
2212
- var import_commander3 = require("commander");
2213
- var import_chalk3 = __toESM(require("chalk"));
2214
- var import_promises5 = require("fs/promises");
2215
- var import_node_os4 = require("os");
2216
- var import_node_path4 = __toESM(require("path"));
2217
- var CREDENTIALS_PATH2 = import_node_path4.default.join((0, import_node_os4.homedir)(), ".nhncloud", "credentials.json");
2218
- var CONFIG_PATH2 = import_node_path4.default.join((0, import_node_os4.homedir)(), ".nhncloud", "config.json");
2219
- async function readProfiles() {
2220
- let raw;
2402
+ // src/skill/manager.ts
2403
+ var PACKAGE_NAME3 = "@bifos/nhncloud-cli";
2404
+ var SKILL_NAME2 = "nhncloud-cli";
2405
+ var DIGEST_HEX_PATTERN = /^[0-9a-f]{64}$/;
2406
+ var defaultOperations = { rename: import_promises3.rename };
2407
+ function sourcePath(context) {
2408
+ return import_node_path5.default.join(context.packageRoot, "skills", SKILL_NAME2);
2409
+ }
2410
+ function destinationPath(context) {
2411
+ return import_node_path5.default.join(context.homeDir, ".claude", "skills", SKILL_NAME2);
2412
+ }
2413
+ function resolveLinkTarget(linkPath, rawTarget) {
2414
+ return import_node_path5.default.isAbsolute(rawTarget) ? import_node_path5.default.normalize(rawTarget) : import_node_path5.default.resolve(import_node_path5.default.dirname(linkPath), rawTarget);
2415
+ }
2416
+ function repositoryRoot(context) {
2417
+ return import_node_path5.default.join(context.dataRoot, "skills");
2418
+ }
2419
+ function isSafePathSegment(value) {
2420
+ return value.length > 0 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\");
2421
+ }
2422
+ function repositoryPath(context, digest) {
2423
+ if (!isSafePathSegment(context.currentVersion)) {
2424
+ throw managerError(`\uD328\uD0A4\uC9C0 \uBC84\uC804\uC744 \uAD00\uB9AC \uC800\uC7A5\uC18C \uACBD\uB85C\uB85C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${context.currentVersion}`);
2425
+ }
2426
+ return import_node_path5.default.join(repositoryRoot(context), `${context.currentVersion}-${digest.slice("sha256:".length)}`);
2427
+ }
2428
+ function toReason(error) {
2429
+ return error instanceof Error ? error.message : String(error);
2430
+ }
2431
+ function isNodeError(error, ...codes) {
2432
+ return error instanceof Error && "code" in error && typeof error.code === "string" && codes.includes(error.code);
2433
+ }
2434
+ function managerError(message, error) {
2435
+ const suffix = error === void 0 ? "" : ` (${toReason(error)})`;
2436
+ return new NhnCloudCliError(`${message}${suffix}`, EXIT_PARAM_ERROR);
2437
+ }
2438
+ async function optionalLstat(targetPath) {
2221
2439
  try {
2222
- raw = await (0, import_promises5.readFile)(CREDENTIALS_PATH2, "utf-8");
2223
- } catch {
2224
- return { profiles: [], parseError: false, missing: true };
2440
+ return await (0, import_promises3.lstat)(targetPath);
2441
+ } catch (error) {
2442
+ if (isNodeError(error, "ENOENT")) {
2443
+ return void 0;
2444
+ }
2445
+ throw managerError(`\uC2A4\uD0AC \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${targetPath}`, error);
2446
+ }
2447
+ }
2448
+ function parseRepositoryName(targetPath) {
2449
+ const name = import_node_path5.default.basename(targetPath);
2450
+ const digestHex = name.slice(-64);
2451
+ const separatorIndex = name.length - digestHex.length - 1;
2452
+ const version = name.slice(0, separatorIndex);
2453
+ if (separatorIndex <= 0 || name[separatorIndex] !== "-" || !isSafePathSegment(version) || !DIGEST_HEX_PATTERN.test(digestHex)) {
2454
+ return void 0;
2455
+ }
2456
+ return {
2457
+ version,
2458
+ digest: `sha256:${digestHex}`
2459
+ };
2460
+ }
2461
+ function managedRepositoryName(context, targetPath) {
2462
+ const resolvedRoot = import_node_path5.default.resolve(repositoryRoot(context));
2463
+ const resolvedTarget = import_node_path5.default.resolve(targetPath);
2464
+ if (import_node_path5.default.dirname(resolvedTarget) !== resolvedRoot) {
2465
+ return void 0;
2225
2466
  }
2467
+ return parseRepositoryName(resolvedTarget);
2468
+ }
2469
+ function isManagedRepositoryLocation(context, targetPath) {
2470
+ return import_node_path5.default.dirname(import_node_path5.default.resolve(targetPath)) === import_node_path5.default.resolve(repositoryRoot(context));
2471
+ }
2472
+ function isLegacyPackageTargetShape(targetPath) {
2473
+ const segments = import_node_path5.default.resolve(targetPath).split(import_node_path5.default.sep);
2474
+ return segments.length >= 5 && segments.at(-1) === SKILL_NAME2 && segments.at(-2) === "skills" && segments.at(-3) === "nhncloud-cli" && segments.at(-4) === "@bifos";
2475
+ }
2476
+ async function readLegacyPackageMetadata(targetPath) {
2477
+ if (import_node_path5.default.basename(targetPath) !== SKILL_NAME2 || import_node_path5.default.basename(import_node_path5.default.dirname(targetPath)) !== "skills") {
2478
+ return void 0;
2479
+ }
2480
+ const packagePath = import_node_path5.default.join(targetPath, "..", "..", "package.json");
2481
+ let parsed;
2226
2482
  try {
2227
- const parsed = JSON.parse(raw);
2228
- return { profiles: Object.keys(parsed.profiles ?? {}), parseError: false, missing: false };
2483
+ parsed = JSON.parse(await (0, import_promises3.readFile)(packagePath, "utf8"));
2229
2484
  } catch {
2230
- return { profiles: [], parseError: true, missing: false };
2485
+ return void 0;
2231
2486
  }
2487
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && "name" in parsed && parsed.name === PACKAGE_NAME3) {
2488
+ return {
2489
+ installedVersion: "version" in parsed && typeof parsed.version === "string" ? parsed.version : void 0
2490
+ };
2491
+ }
2492
+ return void 0;
2232
2493
  }
2233
- async function readDefaultProfile() {
2494
+ async function inspectRepository(targetPath, expected) {
2495
+ const targetStat = await optionalLstat(targetPath);
2496
+ if (!targetStat) {
2497
+ return { status: "missing" };
2498
+ }
2499
+ if (targetStat.isSymbolicLink() || !targetStat.isDirectory()) {
2500
+ return { status: "corrupt", installedVersion: expected?.version };
2501
+ }
2502
+ let manifest;
2234
2503
  try {
2235
- const raw = await (0, import_promises5.readFile)(CONFIG_PATH2, "utf-8");
2236
- const parsed = JSON.parse(raw);
2237
- return parsed.defaultProfile ?? null;
2504
+ manifest = readSkillManifest(targetPath);
2238
2505
  } catch {
2239
- return null;
2506
+ return { status: "corrupt", installedVersion: expected?.version };
2240
2507
  }
2241
- }
2242
- var doctorCommand = new import_commander3.Command("doctor").description("\uC790\uACA9\uC99D\uBA85\xB7\uC2A4\uD0AC \uC124\uCE58 \uC0C1\uD0DC\uB97C \uC9C4\uB2E8\uD55C\uB2E4(\uC624\uD504\uB77C\uC778 \u2014 \uC5F0\uACB0 \uD14C\uC2A4\uD2B8\uB294 configure \uB85C)").action(async () => {
2243
- console.log(import_chalk3.default.bold("\n\u{1F50D} nhncloud-cli \uC9C4\uB2E8\n"));
2244
- const creds = await readProfiles();
2245
- const defaultProfile = await readDefaultProfile();
2246
- console.log(import_chalk3.default.bold("\uC790\uACA9\uC99D\uBA85"));
2247
- if (creds.missing) {
2248
- console.log(` ${import_chalk3.default.red("\u274C \uBBF8\uC124\uC815")} \u2014 ${CREDENTIALS_PATH2} \uC5C6\uC74C. nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
2249
- } else if (creds.parseError) {
2250
- console.log(` ${import_chalk3.default.red("\u274C \uD30C\uC2F1 \uC624\uB958")} \u2014 ${CREDENTIALS_PATH2} \uAC00 \uC62C\uBC14\uB978 JSON \uC778\uC9C0 \uD655\uC778\uD558\uC138\uC694.`);
2251
- } else if (creds.profiles.length === 0) {
2252
- console.log(` ${import_chalk3.default.yellow("\u26A0 profile \uC5C6\uC74C")} \u2014 nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
2253
- } else {
2254
- console.log(` ${import_chalk3.default.green("\u2713 \uC124\uC815\uB428")} \u2014 profile: ${creds.profiles.join(", ")}`);
2255
- console.log(` \uAE30\uBCF8 profile: ${defaultProfile ? import_chalk3.default.green(defaultProfile) : import_chalk3.default.gray("\uBBF8\uC9C0\uC815 (default \uC0AC\uC6A9)")}`);
2508
+ if (expected && (manifest.packageVersion !== expected.version || manifest.contentDigest !== expected.digest)) {
2509
+ return { status: "corrupt", installedVersion: manifest.packageVersion };
2256
2510
  }
2257
- console.log(import_chalk3.default.bold("\nClaude Code \uC2A4\uD0AC"));
2258
- const hasClaude = await (0, import_promises5.access)(claudeDir()).then(() => true).catch(() => false);
2259
- if (!hasClaude) {
2260
- console.log(` ${import_chalk3.default.gray("Claude Code \uBBF8\uC124\uCE58")} \u2014 ${claudeDir()} \uC5C6\uC74C`);
2261
- } else {
2262
- const status = await getSkillStatus(skillDestPath());
2263
- switch (status.state) {
2264
- case "installed-link":
2265
- console.log(` ${SKILL_NAME}: ${import_chalk3.default.green("\u2713 \uC124\uCE58\uB428 (\uC2EC\uBCFC\uB9AD \uB9C1\uD06C)")}`);
2266
- break;
2267
- case "broken-link":
2268
- console.log(` ${SKILL_NAME}: ${import_chalk3.default.yellow("\u26A0 \uB9C1\uD06C \uAE68\uC9D0 \u2014 nhncloud skills install \uB85C \uC7AC\uC124\uCE58")}`);
2269
- break;
2270
- case "installed-copy":
2271
- console.log(` ${SKILL_NAME}: ${import_chalk3.default.green("\u2713 \uC124\uCE58\uB428 (\uC2E4\uC81C \uBCF5\uC0AC\uBCF8)")}`);
2272
- break;
2273
- case "not-installed":
2274
- console.log(` ${SKILL_NAME}: ${import_chalk3.default.gray("\uBBF8\uC124\uCE58 \u2014 nhncloud skills install \uB85C \uC124\uCE58")}`);
2275
- break;
2276
- }
2511
+ let actualDigest;
2512
+ try {
2513
+ actualDigest = calculateSkillContentDigest(targetPath);
2514
+ } catch {
2515
+ return { status: "corrupt", installedVersion: manifest.packageVersion };
2277
2516
  }
2278
- console.log();
2279
- if (!creds.missing && !creds.parseError && creds.profiles.length > 0) {
2280
- console.log(import_chalk3.default.green("\u2713 \uAE30\uBCF8 \uC124\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
2281
- } else {
2282
- console.log(import_chalk3.default.yellow("\u26A0 \uC124\uC815\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: nhncloud configure"));
2517
+ if (actualDigest !== manifest.contentDigest) {
2518
+ return { status: "modified", installedVersion: manifest.packageVersion };
2283
2519
  }
2284
- console.log();
2285
- });
2286
-
2287
- // src/commands/logncrash/search.ts
2520
+ return { status: "valid", installedVersion: manifest.packageVersion };
2521
+ }
2522
+ function statusBase(context) {
2523
+ return {
2524
+ schemaVersion: 1,
2525
+ destination: destinationPath(context),
2526
+ source: sourcePath(context),
2527
+ currentVersion: context.currentVersion
2528
+ };
2529
+ }
2530
+ async function inspectSkill(context) {
2531
+ const base = statusBase(context);
2532
+ const destinationStat = await optionalLstat(base.destination);
2533
+ if (!destinationStat) {
2534
+ return { ...base, status: "missing", managed: false };
2535
+ }
2536
+ if (!destinationStat.isSymbolicLink()) {
2537
+ return { ...base, status: "unmanaged", managed: false };
2538
+ }
2539
+ let rawTarget;
2540
+ try {
2541
+ rawTarget = await (0, import_promises3.readlink)(base.destination);
2542
+ } catch (error) {
2543
+ throw managerError(`\uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${base.destination}`, error);
2544
+ }
2545
+ const linkTarget = resolveLinkTarget(base.destination, rawTarget);
2546
+ const repositoryName = managedRepositoryName(context, linkTarget);
2547
+ const targetStat = await (0, import_promises3.stat)(linkTarget).catch((error) => {
2548
+ if (isNodeError(error, "ENOENT")) {
2549
+ return void 0;
2550
+ }
2551
+ throw managerError(`\uC2A4\uD0AC \uB9C1\uD06C \uB300\uC0C1\uC744 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${linkTarget}`, error);
2552
+ });
2553
+ if (!targetStat) {
2554
+ const managed = isManagedRepositoryLocation(context, linkTarget) || isLegacyPackageTargetShape(linkTarget);
2555
+ return {
2556
+ ...base,
2557
+ status: managed ? "broken" : "unmanaged",
2558
+ installedVersion: repositoryName?.version,
2559
+ linkTarget,
2560
+ managed
2561
+ };
2562
+ }
2563
+ if (isManagedRepositoryLocation(context, linkTarget)) {
2564
+ if (!repositoryName) {
2565
+ return { ...base, status: "corrupt", linkTarget, managed: true };
2566
+ }
2567
+ const repository = await inspectRepository(linkTarget, repositoryName);
2568
+ if (repository.status === "modified" || repository.status === "corrupt") {
2569
+ return {
2570
+ ...base,
2571
+ status: repository.status,
2572
+ installedVersion: repository.installedVersion ?? repositoryName.version,
2573
+ linkTarget,
2574
+ managed: true
2575
+ };
2576
+ }
2577
+ if (repository.status === "missing") {
2578
+ return {
2579
+ ...base,
2580
+ status: "broken",
2581
+ installedVersion: repositoryName.version,
2582
+ linkTarget,
2583
+ managed: true
2584
+ };
2585
+ }
2586
+ const currentDigest = calculateSkillContentDigest(base.source);
2587
+ const expectedPath = repositoryPath(context, currentDigest);
2588
+ const isCurrent = repositoryName.version === context.currentVersion && repositoryName.digest === currentDigest && import_node_path5.default.resolve(linkTarget) === import_node_path5.default.resolve(expectedPath);
2589
+ return {
2590
+ ...base,
2591
+ status: isCurrent ? "current" : "outdated",
2592
+ installedVersion: repository.installedVersion,
2593
+ linkTarget,
2594
+ managed: true
2595
+ };
2596
+ }
2597
+ const legacyPackage = targetStat.isDirectory() ? await readLegacyPackageMetadata(linkTarget) : void 0;
2598
+ if (legacyPackage) {
2599
+ return {
2600
+ ...base,
2601
+ status: "outdated",
2602
+ ...legacyPackage.installedVersion ? { installedVersion: legacyPackage.installedVersion } : {},
2603
+ linkTarget,
2604
+ managed: true
2605
+ };
2606
+ }
2607
+ return { ...base, status: "unmanaged", linkTarget, managed: false };
2608
+ }
2609
+ function utcBackupSuffix() {
2610
+ return `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}-${(0, import_node_crypto3.randomUUID)()}`;
2611
+ }
2612
+ async function backupPath(targetPath, operations) {
2613
+ const backup = `${targetPath}.backup-${utcBackupSuffix()}`;
2614
+ try {
2615
+ await operations.rename(targetPath, backup);
2616
+ } catch (error) {
2617
+ throw managerError(`\uAE30\uC874 \uC2A4\uD0AC \uD56D\uBAA9\uC744 \uBC31\uC5C5\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${targetPath}`, error);
2618
+ }
2619
+ return backup;
2620
+ }
2621
+ async function restoreBackup(backup, targetPath, operations, originalError) {
2622
+ try {
2623
+ await operations.rename(backup, targetPath);
2624
+ } catch (restoreError) {
2625
+ throw managerError(
2626
+ `\uC2A4\uD0AC \uC804\uD658\uC5D0 \uC2E4\uD328\uD588\uACE0 \uBC31\uC5C5 \uBCF5\uC6D0\uB3C4 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4: ${targetPath}; \uC804\uD658 \uC624\uB958: ${toReason(originalError)}`,
2627
+ restoreError
2628
+ );
2629
+ }
2630
+ throw managerError(`\uC2A4\uD0AC \uC804\uD658\uC5D0 \uC2E4\uD328\uD574 \uBC31\uC5C5\uC744 \uBCF5\uC6D0\uD588\uC2B5\uB2C8\uB2E4: ${targetPath}`, originalError);
2631
+ }
2632
+ async function createStagingRepository(context, digest) {
2633
+ const root = repositoryRoot(context);
2634
+ await (0, import_promises3.mkdir)(root, { recursive: true });
2635
+ const staging = await (0, import_promises3.mkdtemp)(import_node_path5.default.join(root, ".staging-"));
2636
+ try {
2637
+ const source = sourcePath(context);
2638
+ await (0, import_promises3.cp)(import_node_path5.default.join(source, "SKILL.md"), import_node_path5.default.join(staging, "SKILL.md"));
2639
+ await (0, import_promises3.cp)(import_node_path5.default.join(source, "references"), import_node_path5.default.join(staging, "references"), { recursive: true });
2640
+ const stagedDigest = calculateSkillContentDigest(staging);
2641
+ if (stagedDigest !== digest) {
2642
+ throw managerError("\uBCF5\uC0AC \uC911 \uC2A4\uD0AC \uC6D0\uBCF8\uC774 \uBCC0\uACBD\uB418\uC5B4 \uC124\uCE58\uB97C \uC911\uB2E8\uD588\uC2B5\uB2C8\uB2E4.");
2643
+ }
2644
+ const manifest = createSkillManifest(context.currentVersion, digest);
2645
+ await (0, import_promises3.writeFile)(import_node_path5.default.join(staging, MANIFEST_FILE_NAME), `${JSON.stringify(manifest, null, 2)}
2646
+ `, "utf8");
2647
+ return staging;
2648
+ } catch (error) {
2649
+ await (0, import_promises3.rm)(staging, { recursive: true, force: true });
2650
+ if (error instanceof NhnCloudCliError) {
2651
+ throw error;
2652
+ }
2653
+ throw managerError(`\uC2A4\uD0AC \uAD00\uB9AC \uC800\uC7A5\uC18C\uB97C \uC900\uBE44\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${staging}`, error);
2654
+ }
2655
+ }
2656
+ async function prepareRepository(context, force, operations) {
2657
+ const source = sourcePath(context);
2658
+ const digest = calculateSkillContentDigest(source);
2659
+ const repository = repositoryPath(context, digest);
2660
+ const expected = { version: context.currentVersion, digest };
2661
+ let existing = await inspectRepository(repository, expected);
2662
+ if (existing.status === "valid") {
2663
+ return { repository, backupPaths: [] };
2664
+ }
2665
+ if ((existing.status === "modified" || existing.status === "corrupt") && !force) {
2666
+ throw managerError(`\uAD00\uB9AC \uC800\uC7A5\uC18C\uAC00 ${existing.status === "modified" ? "\uC218\uC815" : "\uC190\uC0C1"}\uB418\uC5C8\uC2B5\uB2C8\uB2E4. --force\uB85C \uBCF5\uAD6C\uD558\uC138\uC694: ${repository}`);
2667
+ }
2668
+ const staging = await createStagingRepository(context, digest);
2669
+ const backupPaths = [];
2670
+ try {
2671
+ if (existing.status === "missing") {
2672
+ try {
2673
+ await operations.rename(staging, repository);
2674
+ return { repository, backupPaths };
2675
+ } catch (error) {
2676
+ if (!isNodeError(error, "EEXIST", "ENOTEMPTY")) {
2677
+ throw error;
2678
+ }
2679
+ existing = await inspectRepository(repository, expected);
2680
+ if (existing.status === "valid") {
2681
+ return { repository, backupPaths };
2682
+ }
2683
+ if (!force) {
2684
+ throw managerError(`\uB3D9\uC2DC\uC5D0 \uC0DD\uC131\uB41C \uAD00\uB9AC \uC800\uC7A5\uC18C\uAC00 \uC190\uC0C1\uB418\uC5C8\uC2B5\uB2C8\uB2E4. --force\uB85C \uBCF5\uAD6C\uD558\uC138\uC694: ${repository}`);
2685
+ }
2686
+ }
2687
+ }
2688
+ const backup = await backupPath(repository, operations);
2689
+ backupPaths.push(backup);
2690
+ try {
2691
+ await operations.rename(staging, repository);
2692
+ } catch (error) {
2693
+ return await restoreBackup(backup, repository, operations, error);
2694
+ }
2695
+ return { repository, backupPaths };
2696
+ } catch (error) {
2697
+ if (error instanceof NhnCloudCliError) {
2698
+ throw error;
2699
+ }
2700
+ throw managerError(`\uC2A4\uD0AC \uAD00\uB9AC \uC800\uC7A5\uC18C\uB97C \uC804\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${repository}`, error);
2701
+ } finally {
2702
+ await (0, import_promises3.rm)(staging, { recursive: true, force: true });
2703
+ }
2704
+ }
2705
+ async function switchActiveLink(context, repository, previousStatus, force, operations) {
2706
+ const destination = destinationPath(context);
2707
+ const parent = import_node_path5.default.dirname(destination);
2708
+ await (0, import_promises3.mkdir)(parent, { recursive: true });
2709
+ const temporaryLink = import_node_path5.default.join(parent, `.${SKILL_NAME2}.link-${(0, import_node_crypto3.randomUUID)()}`);
2710
+ const backupPaths = [];
2711
+ await (0, import_promises3.symlink)(repository, temporaryLink);
2712
+ try {
2713
+ if (previousStatus.status === "unmanaged") {
2714
+ if (!force) {
2715
+ throw managerError(`\uAD00\uB9AC\uB418\uC9C0 \uC54A\uC740 \uC2A4\uD0AC \uD56D\uBAA9\uC774 \uC788\uC2B5\uB2C8\uB2E4. --force\uB85C \uBC31\uC5C5 \uD6C4 \uAD50\uCCB4\uD558\uC138\uC694: ${destination}`);
2716
+ }
2717
+ const backup = await backupPath(destination, operations);
2718
+ backupPaths.push(backup);
2719
+ try {
2720
+ await operations.rename(temporaryLink, destination);
2721
+ } catch (error) {
2722
+ return await restoreBackup(backup, destination, operations, error);
2723
+ }
2724
+ return backupPaths;
2725
+ }
2726
+ try {
2727
+ await operations.rename(temporaryLink, destination);
2728
+ } catch (error) {
2729
+ throw managerError(`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC804\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${destination}`, error);
2730
+ }
2731
+ return backupPaths;
2732
+ } finally {
2733
+ await (0, import_promises3.rm)(temporaryLink, { force: true });
2734
+ }
2735
+ }
2736
+ function installAction(status) {
2737
+ switch (status) {
2738
+ case "missing":
2739
+ return "installed";
2740
+ case "outdated":
2741
+ return "updated";
2742
+ case "unmanaged":
2743
+ return "replaced";
2744
+ case "broken":
2745
+ case "modified":
2746
+ case "corrupt":
2747
+ return "recovered";
2748
+ case "current":
2749
+ return "unchanged";
2750
+ }
2751
+ }
2752
+ async function installSkillInternal(context, options = {}, operations = defaultOperations) {
2753
+ const force = options.force ?? false;
2754
+ const previousStatus = await inspectSkill(context);
2755
+ const sourceDigest = calculateSkillContentDigest(sourcePath(context));
2756
+ const expectedRepository = repositoryPath(context, sourceDigest);
2757
+ if (previousStatus.status === "current") {
2758
+ return {
2759
+ schemaVersion: 1,
2760
+ action: "unchanged",
2761
+ changed: false,
2762
+ previousStatus,
2763
+ status: previousStatus,
2764
+ repositoryPath: expectedRepository,
2765
+ backupPaths: []
2766
+ };
2767
+ }
2768
+ if ((previousStatus.status === "unmanaged" || previousStatus.status === "modified" || previousStatus.status === "corrupt") && !force) {
2769
+ throw managerError(`\uC2A4\uD0AC \uC0C1\uD0DC\uAC00 ${previousStatus.status}\uC785\uB2C8\uB2E4. --force\uB85C \uBC31\uC5C5 \uD6C4 \uAD50\uCCB4\uD558\uC138\uC694: ${previousStatus.destination}`);
2770
+ }
2771
+ const prepared = await prepareRepository(context, force, operations);
2772
+ const linkBackups = await switchActiveLink(context, prepared.repository, previousStatus, force, operations);
2773
+ const status = await inspectSkill(context);
2774
+ if (status.status !== "current") {
2775
+ throw managerError(`\uC2A4\uD0AC \uC124\uCE58 \uD6C4 \uC0C1\uD0DC\uAC00 current\uAC00 \uC544\uB2D9\uB2C8\uB2E4: ${status.status}`);
2776
+ }
2777
+ return {
2778
+ schemaVersion: 1,
2779
+ action: installAction(previousStatus.status),
2780
+ changed: true,
2781
+ previousStatus,
2782
+ status,
2783
+ repositoryPath: prepared.repository,
2784
+ backupPaths: [...prepared.backupPaths, ...linkBackups]
2785
+ };
2786
+ }
2787
+ async function installSkill(context, options = {}, operations = defaultOperations) {
2788
+ try {
2789
+ return await installSkillInternal(context, options, operations);
2790
+ } catch (error) {
2791
+ if (error instanceof NhnCloudCliError) {
2792
+ throw error;
2793
+ }
2794
+ throw managerError("\uC2A4\uD0AC\uC744 \uC124\uCE58\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", error);
2795
+ }
2796
+ }
2797
+ async function restoreUninstallCandidate(candidate, destination, operations, originalError) {
2798
+ if (await optionalLstat(destination)) {
2799
+ throw managerError(
2800
+ `\uD65C\uC131 \uC2A4\uD0AC \uACBD\uB85C\uAC00 \uB3D9\uC2DC\uC5D0 \uBCC0\uACBD\uB418\uC5B4 \uC81C\uAC70\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC774\uB3D9\uB41C \uD56D\uBAA9\uC744 \uBCF4\uC874\uD588\uC2B5\uB2C8\uB2E4: ${candidate}`,
2801
+ originalError
2802
+ );
2803
+ }
2804
+ try {
2805
+ await operations.rename(candidate, destination);
2806
+ } catch (restoreError) {
2807
+ throw managerError(
2808
+ `\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD558\uC9C0 \uBABB\uD588\uACE0 \uC6D0\uB798 \uC704\uCE58\uB85C \uBCF5\uC6D0\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC774\uB3D9\uB41C \uD56D\uBAA9: ${candidate}; \uC81C\uAC70 \uC624\uB958: ${toReason(originalError)}`,
2809
+ restoreError
2810
+ );
2811
+ }
2812
+ throw managerError(`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD558\uC9C0 \uC54A\uACE0 \uC6D0\uB798 \uC704\uCE58\uB85C \uBCF5\uC6D0\uD588\uC2B5\uB2C8\uB2E4: ${destination}`, originalError);
2813
+ }
2814
+ async function uninstallSkill(context, operations = defaultOperations) {
2815
+ const destination = destinationPath(context);
2816
+ const status = await inspectSkill(context);
2817
+ if (status.status === "missing") {
2818
+ return "absent";
2819
+ }
2820
+ if (!status.managed || !status.linkTarget) {
2821
+ throw managerError(`\uAD00\uB9AC\uB418\uC9C0 \uC54A\uC740 \uC2A4\uD0AC \uD56D\uBAA9\uC774\uBBC0\uB85C \uC81C\uAC70\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: ${destination}`);
2822
+ }
2823
+ const candidate = import_node_path5.default.join(import_node_path5.default.dirname(destination), `.${SKILL_NAME2}.uninstall-${(0, import_node_crypto3.randomUUID)()}`);
2824
+ try {
2825
+ await operations.rename(destination, candidate);
2826
+ } catch (error) {
2827
+ if (isNodeError(error, "ENOENT")) {
2828
+ return "absent";
2829
+ }
2830
+ throw managerError(`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uC6A9 \uC784\uC2DC \uACBD\uB85C\uB85C \uC774\uB3D9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${destination}`, error);
2831
+ }
2832
+ let candidateTarget;
2833
+ try {
2834
+ const candidateStat = await (0, import_promises3.lstat)(candidate);
2835
+ if (!candidateStat.isSymbolicLink()) {
2836
+ return await restoreUninstallCandidate(
2837
+ candidate,
2838
+ destination,
2839
+ operations,
2840
+ new Error("\uAC80\uC0AC \uD6C4 \uD65C\uC131 \uACBD\uB85C\uAC00 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uAC00 \uC544\uB2CC \uD56D\uBAA9\uC73C\uB85C \uBCC0\uACBD\uB418\uC5C8\uC2B5\uB2C8\uB2E4.")
2841
+ );
2842
+ }
2843
+ candidateTarget = resolveLinkTarget(destination, await (0, import_promises3.readlink)(candidate));
2844
+ } catch (error) {
2845
+ if (error instanceof NhnCloudCliError) {
2846
+ throw error;
2847
+ }
2848
+ return await restoreUninstallCandidate(candidate, destination, operations, error);
2849
+ }
2850
+ if (candidateTarget !== status.linkTarget) {
2851
+ return await restoreUninstallCandidate(
2852
+ candidate,
2853
+ destination,
2854
+ operations,
2855
+ new Error("\uAC80\uC0AC \uD6C4 \uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C \uB300\uC0C1\uC774 \uBCC0\uACBD\uB418\uC5C8\uC2B5\uB2C8\uB2E4.")
2856
+ );
2857
+ }
2858
+ try {
2859
+ await (0, import_promises3.rm)(candidate);
2860
+ } catch (error) {
2861
+ return await restoreUninstallCandidate(candidate, destination, operations, error);
2862
+ }
2863
+ return "removed";
2864
+ }
2865
+
2866
+ // src/formatters/table.ts
2867
+ var import_cli_table3 = __toESM(require("cli-table3"));
2868
+ function truncate(text, maxLen = 50) {
2869
+ const oneLine = text.replace(/[\r\n]+/g, " ").trim();
2870
+ return oneLine.length > maxLen ? oneLine.slice(0, maxLen) + "\u2026" : oneLine;
2871
+ }
2872
+ function printTable(headers, rows) {
2873
+ if (rows.length === 0) {
2874
+ process.stdout.write("\uACB0\uACFC \uC5C6\uC74C\n");
2875
+ return;
2876
+ }
2877
+ const table = new import_cli_table3.default({ head: headers });
2878
+ for (const row of rows) {
2879
+ table.push(row);
2880
+ }
2881
+ process.stdout.write(table.toString() + "\n");
2882
+ }
2883
+ function printJson(data) {
2884
+ process.stdout.write(JSON.stringify(data, null, 2) + "\n");
2885
+ }
2886
+ function printQuiet(ids) {
2887
+ if (ids.length === 0) return;
2888
+ process.stdout.write(ids.join("\n") + "\n");
2889
+ }
2890
+ function output(opts, data) {
2891
+ if (opts.json) {
2892
+ printJson(data.raw);
2893
+ } else if (opts.quiet) {
2894
+ printQuiet(data.ids);
2895
+ } else {
2896
+ printTable(data.headers, data.rows);
2897
+ }
2898
+ }
2899
+
2900
+ // src/commands/skills-output.ts
2901
+ function terminalText(value) {
2902
+ return value === void 0 ? "-" : value.replace(/[\x00-\x1F\x7F]/g, "?");
2903
+ }
2904
+ function installActionText(action) {
2905
+ switch (action) {
2906
+ case "unchanged":
2907
+ return "\uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC";
2908
+ case "installed":
2909
+ return "\uC124\uCE58 \uC644\uB8CC";
2910
+ case "updated":
2911
+ return "\uAC31\uC2E0 \uC644\uB8CC";
2912
+ case "recovered":
2913
+ return "\uBCF5\uAD6C \uC644\uB8CC";
2914
+ case "replaced":
2915
+ return "\uBC31\uC5C5 \uD6C4 \uAD50\uCCB4 \uC644\uB8CC";
2916
+ }
2917
+ }
2918
+ function skillRecoveryCommand(status) {
2919
+ switch (status) {
2920
+ case "current":
2921
+ return void 0;
2922
+ case "missing":
2923
+ return "nhncloud skills install";
2924
+ case "outdated":
2925
+ case "broken":
2926
+ return "nhncloud skills update";
2927
+ case "unmanaged":
2928
+ case "modified":
2929
+ case "corrupt":
2930
+ return "nhncloud skills update --force";
2931
+ }
2932
+ }
2933
+ function outputSkillStatus(opts, status) {
2934
+ output(opts, {
2935
+ headers: ["\uD56D\uBAA9", "\uAC12"],
2936
+ rows: [
2937
+ ["\uC0C1\uD0DC", status.status],
2938
+ ["\uD604\uC7AC \uBC84\uC804", status.currentVersion],
2939
+ ["\uC124\uCE58 \uBC84\uC804", terminalText(status.installedVersion)],
2940
+ ["\uC124\uCE58 \uACBD\uB85C", terminalText(status.destination)],
2941
+ ["\uB9C1\uD06C \uB300\uC0C1", terminalText(status.linkTarget)],
2942
+ ["\uBCF5\uAD6C \uBA85\uB839", skillRecoveryCommand(status.status) ?? "\uC870\uCE58 \uC5C6\uC74C"]
2943
+ ],
2944
+ raw: status,
2945
+ ids: [status.status]
2946
+ });
2947
+ }
2948
+ function outputSkillInstallResult(opts, result) {
2949
+ output(opts, {
2950
+ headers: ["\uD56D\uBAA9", "\uAC12"],
2951
+ rows: [
2952
+ ["\uC791\uC5C5", installActionText(result.action)],
2953
+ ["\uBCC0\uACBD \uC5EC\uBD80", result.changed ? "\uBCC0\uACBD\uB428" : "\uBCC0\uACBD \uC5C6\uC74C"],
2954
+ ["\uC774\uC804 \uC0C1\uD0DC", result.previousStatus.status],
2955
+ ["\uD604\uC7AC \uC0C1\uD0DC", result.status.status],
2956
+ ["\uC124\uCE58 \uACBD\uB85C", terminalText(result.status.destination)],
2957
+ ["\uAD00\uB9AC \uC800\uC7A5\uC18C", terminalText(result.repositoryPath)],
2958
+ [
2959
+ "\uBC31\uC5C5 \uACBD\uB85C",
2960
+ result.backupPaths.length > 0 ? result.backupPaths.map(terminalText).join("\n") : "\uC5C6\uC74C"
2961
+ ]
2962
+ ],
2963
+ raw: result,
2964
+ ids: [result.status.status]
2965
+ });
2966
+ }
2967
+ function outputSkillUninstallResult(opts, result) {
2968
+ output(opts, {
2969
+ headers: ["\uD56D\uBAA9", "\uAC12"],
2970
+ rows: [
2971
+ ["\uC791\uC5C5", result.action === "removed" ? "\uD65C\uC131 \uB9C1\uD06C \uC81C\uAC70 \uC644\uB8CC" : "\uD65C\uC131 \uB9C1\uD06C \uC5C6\uC74C"],
2972
+ ["\uC124\uCE58 \uACBD\uB85C", terminalText(result.destination)],
2973
+ ["\uAD00\uB9AC \uC800\uC7A5\uC18C", "\uBCF4\uC874\uB428"]
2974
+ ],
2975
+ raw: result,
2976
+ ids: [result.status]
2977
+ });
2978
+ }
2979
+
2980
+ // src/commands/skills.ts
2981
+ var SKILL_NAME3 = "nhncloud-cli";
2982
+ var defaultDependencies = {
2983
+ createContext: createSkillManagerContext,
2984
+ inspect: inspectSkill,
2985
+ install: installSkill,
2986
+ uninstall: uninstallSkill
2987
+ };
2988
+ async function showStatus(cmd, dependencies) {
2989
+ const opts = cmd.optsWithGlobals();
2990
+ const context = dependencies.createContext();
2991
+ outputSkillStatus(opts, await dependencies.inspect(context));
2992
+ }
2993
+ function createInstallCommand(name, dependencies) {
2994
+ return new import_commander2.Command(name).description(
2995
+ name === "install" ? "Claude Code \uC2A4\uD0AC\uC744 \uAD00\uB9AC \uC800\uC7A5\uC18C\uC5D0 \uC124\uCE58\uD55C\uB2E4" : "Claude Code \uC2A4\uD0AC\uC744 \uD604\uC7AC CLI \uBC84\uC804\uC73C\uB85C \uAC31\uC2E0\uD55C\uB2E4"
2996
+ ).option("--force", "\uC0AC\uC6A9\uC790 \uD56D\uBAA9\uC774\uB098 \uC218\uC815\xB7\uC190\uC0C1\uB41C \uAD00\uB9AC \uC800\uC7A5\uC18C\uB97C \uBC31\uC5C5 \uD6C4 \uAD50\uCCB4\uD55C\uB2E4").action(async (_localOpts, cmd) => {
2997
+ const opts = cmd.optsWithGlobals();
2998
+ const context = dependencies.createContext();
2999
+ const result = await dependencies.install(context, { force: opts.force ?? false });
3000
+ outputSkillInstallResult(opts, result);
3001
+ });
3002
+ }
3003
+ function createSkillsCommand(dependencies = defaultDependencies) {
3004
+ const statusCommand = new import_commander2.Command("status").description("Claude Code \uC2A4\uD0AC\uC758 \uAD00\uB9AC \uC0C1\uD0DC\uB97C \uC870\uD68C\uD55C\uB2E4").action(async (_opts, cmd) => showStatus(cmd, dependencies));
3005
+ const uninstallCommand = new import_commander2.Command("uninstall").description("\uD65C\uC131 Claude Code \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD55C\uB2E4").action(async (_opts, cmd) => {
3006
+ const opts = cmd.optsWithGlobals();
3007
+ const context = dependencies.createContext();
3008
+ const previousStatus = await dependencies.inspect(context);
3009
+ const action = await dependencies.uninstall(context);
3010
+ const result = {
3011
+ schemaVersion: 1,
3012
+ action,
3013
+ changed: action === "removed",
3014
+ status: "missing",
3015
+ destination: previousStatus.destination,
3016
+ repositoryPreserved: true
3017
+ };
3018
+ outputSkillUninstallResult(opts, result);
3019
+ });
3020
+ return new import_commander2.Command("skills").description(`Claude Code \uC2A4\uD0AC(${SKILL_NAME3}) \uC124\uCE58 \uAD00\uB9AC`).addCommand(statusCommand).addCommand(createInstallCommand("install", dependencies)).addCommand(createInstallCommand("update", dependencies)).addCommand(uninstallCommand).action(async (_opts, cmd) => showStatus(cmd, dependencies));
3021
+ }
3022
+ var skillsCommand = createSkillsCommand();
3023
+
3024
+ // src/commands/doctor.ts
3025
+ var import_commander3 = require("commander");
3026
+ var import_chalk2 = __toESM(require("chalk"));
3027
+ var import_promises4 = require("fs/promises");
3028
+ var import_node_os4 = require("os");
3029
+ var import_node_path6 = __toESM(require("path"));
3030
+ var SKILL_NAME4 = "nhncloud-cli";
3031
+ var CREDENTIALS_PATH2 = import_node_path6.default.join((0, import_node_os4.homedir)(), ".nhncloud", "credentials.json");
3032
+ var CONFIG_PATH2 = import_node_path6.default.join((0, import_node_os4.homedir)(), ".nhncloud", "config.json");
3033
+ async function readProfiles() {
3034
+ let raw;
3035
+ try {
3036
+ raw = await (0, import_promises4.readFile)(CREDENTIALS_PATH2, "utf-8");
3037
+ } catch {
3038
+ return { profiles: [], parseError: false, missing: true };
3039
+ }
3040
+ try {
3041
+ const parsed = JSON.parse(raw);
3042
+ return { profiles: Object.keys(parsed.profiles ?? {}), parseError: false, missing: false };
3043
+ } catch {
3044
+ return { profiles: [], parseError: true, missing: false };
3045
+ }
3046
+ }
3047
+ async function readDefaultProfile() {
3048
+ try {
3049
+ const raw = await (0, import_promises4.readFile)(CONFIG_PATH2, "utf-8");
3050
+ const parsed = JSON.parse(raw);
3051
+ return parsed.defaultProfile ?? null;
3052
+ } catch {
3053
+ return null;
3054
+ }
3055
+ }
3056
+ var doctorCommand = new import_commander3.Command("doctor").description("\uC790\uACA9\uC99D\uBA85\xB7\uC2A4\uD0AC \uC124\uCE58 \uC0C1\uD0DC\uB97C \uC9C4\uB2E8\uD55C\uB2E4(\uC624\uD504\uB77C\uC778 \u2014 \uC5F0\uACB0 \uD14C\uC2A4\uD2B8\uB294 configure \uB85C)").action(async () => {
3057
+ console.log(import_chalk2.default.bold("\n\u{1F50D} nhncloud-cli \uC9C4\uB2E8\n"));
3058
+ const creds = await readProfiles();
3059
+ const defaultProfile = await readDefaultProfile();
3060
+ console.log(import_chalk2.default.bold("\uC790\uACA9\uC99D\uBA85"));
3061
+ if (creds.missing) {
3062
+ console.log(` ${import_chalk2.default.red("\u274C \uBBF8\uC124\uC815")} \u2014 ${CREDENTIALS_PATH2} \uC5C6\uC74C. nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
3063
+ } else if (creds.parseError) {
3064
+ console.log(` ${import_chalk2.default.red("\u274C \uD30C\uC2F1 \uC624\uB958")} \u2014 ${CREDENTIALS_PATH2} \uAC00 \uC62C\uBC14\uB978 JSON \uC778\uC9C0 \uD655\uC778\uD558\uC138\uC694.`);
3065
+ } else if (creds.profiles.length === 0) {
3066
+ console.log(` ${import_chalk2.default.yellow("\u26A0 profile \uC5C6\uC74C")} \u2014 nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
3067
+ } else {
3068
+ console.log(` ${import_chalk2.default.green("\u2713 \uC124\uC815\uB428")} \u2014 profile: ${creds.profiles.join(", ")}`);
3069
+ console.log(` \uAE30\uBCF8 profile: ${defaultProfile ? import_chalk2.default.green(defaultProfile) : import_chalk2.default.gray("\uBBF8\uC9C0\uC815 (default \uC0AC\uC6A9)")}`);
3070
+ }
3071
+ console.log(import_chalk2.default.bold("\nClaude Code \uC2A4\uD0AC"));
3072
+ const skillStatus = await inspectSkill(createSkillManagerContext());
3073
+ if (skillStatus.status === "current") {
3074
+ console.log(
3075
+ ` ${SKILL_NAME4}: ${import_chalk2.default.green(`\u2713 current (${skillStatus.installedVersion ?? skillStatus.currentVersion})`)}`
3076
+ );
3077
+ } else if (skillStatus.status === "missing") {
3078
+ console.log(
3079
+ ` ${SKILL_NAME4}: ${import_chalk2.default.gray(`\uBBF8\uC124\uCE58 \u2014 ${skillRecoveryCommand(skillStatus.status)}`)}`
3080
+ );
3081
+ } else {
3082
+ console.log(
3083
+ ` ${SKILL_NAME4}: ${import_chalk2.default.yellow(`\u26A0 ${skillStatus.status}`)} \u2014 ${skillRecoveryCommand(skillStatus.status)}`
3084
+ );
3085
+ }
3086
+ console.log();
3087
+ if (!creds.missing && !creds.parseError && creds.profiles.length > 0) {
3088
+ console.log(import_chalk2.default.green("\u2713 \uAE30\uBCF8 \uC124\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
3089
+ } else {
3090
+ console.log(import_chalk2.default.yellow("\u26A0 \uC124\uC815\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: nhncloud configure"));
3091
+ }
3092
+ console.log();
3093
+ });
3094
+
3095
+ // src/commands/logncrash/search.ts
2288
3096
  var import_commander4 = require("commander");
2289
3097
 
2290
3098
  // src/utils/time.ts
@@ -2353,92 +3161,24 @@ function assertSearchRange(fromIso, toIso) {
2353
3161
  }
2354
3162
  }
2355
3163
 
2356
- // src/formatters/table.ts
2357
- var import_cli_table3 = __toESM(require("cli-table3"));
2358
- function truncate(text, maxLen = 50) {
2359
- const oneLine = text.replace(/[\r\n]+/g, " ").trim();
2360
- return oneLine.length > maxLen ? oneLine.slice(0, maxLen) + "\u2026" : oneLine;
2361
- }
2362
- function printTable(headers, rows) {
2363
- if (rows.length === 0) {
2364
- process.stdout.write("\uACB0\uACFC \uC5C6\uC74C\n");
2365
- return;
2366
- }
2367
- const table = new import_cli_table3.default({ head: headers });
2368
- for (const row of rows) {
2369
- table.push(row);
3164
+ // src/commands/logncrash/helpers.ts
3165
+ async function resolveLogncrashClient(profile) {
3166
+ const profileName = await resolveProfileName(profile);
3167
+ const credential = await getServiceCredential("logncrash", profileName);
3168
+ if (typeof credential.appkey !== "string" || credential.appkey.length === 0) {
3169
+ throw new NhnCloudCliError(
3170
+ `profile "${profileName}"\uC758 logncrash \uC790\uACA9\uC99D\uBA85\uC5D0 appkey\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. nhncloud configure\uB85C appkey\uB97C \uC124\uC815\uD558\uC138\uC694.`,
3171
+ EXIT_CONFIG_ERROR
3172
+ );
2370
3173
  }
2371
- process.stdout.write(table.toString() + "\n");
3174
+ const uak = await getUserAccessKey(profileName);
3175
+ const accessToken = await getAccessToken(profileName, uak.id, uak.secret);
3176
+ return new LogncrashClient(credential.appkey, accessToken);
2372
3177
  }
2373
- function printJson(data) {
2374
- process.stdout.write(JSON.stringify(data, null, 2) + "\n");
2375
- }
2376
- function printQuiet(ids) {
2377
- if (ids.length === 0) return;
2378
- process.stdout.write(ids.join("\n") + "\n");
2379
- }
2380
- function output(opts, data) {
2381
- if (opts.json) {
2382
- printJson(data.raw);
2383
- } else if (opts.quiet) {
2384
- printQuiet(data.ids);
2385
- } else {
2386
- printTable(data.headers, data.rows);
2387
- }
2388
- }
2389
-
2390
- // src/commands/parse-options.ts
2391
- var POSITIVE_INTEGER_PATTERN = /^[1-9]\d*$/;
2392
- var NON_NEGATIVE_INTEGER_PATTERN = /^(0|[1-9]\d*)$/;
2393
- function describeRange({ min, max }) {
2394
- if (min !== void 0 && max !== void 0) return `${min} \uC774\uC0C1 ${max} \uC774\uD558\uC758 \uC815\uC218`;
2395
- if (min !== void 0) return `${min} \uC774\uC0C1\uC758 \uC815\uC218`;
2396
- if (max !== void 0) return `${max} \uC774\uD558\uC758 \uC815\uC218`;
2397
- return "0 \uC774\uC0C1\uC758 \uC815\uC218";
2398
- }
2399
- function throwIntegerOptionError(value, flag, range) {
2400
- throw new NhnCloudCliError(
2401
- `${flag} \uB294 ${describeRange(range)}\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
2402
- EXIT_PARAM_ERROR
2403
- );
2404
- }
2405
- function parseIntegerOption(value, flag, range) {
2406
- if (value === void 0) return void 0;
2407
- const pattern = range.min !== void 0 && range.min > 0 ? POSITIVE_INTEGER_PATTERN : NON_NEGATIVE_INTEGER_PATTERN;
2408
- if (!pattern.test(value)) {
2409
- throwIntegerOptionError(value, flag, range);
2410
- }
2411
- const parsed = Number(value);
2412
- if (!Number.isInteger(parsed) || range.min !== void 0 && parsed < range.min || range.max !== void 0 && parsed > range.max) {
2413
- throwIntegerOptionError(value, flag, range);
2414
- }
2415
- return parsed;
2416
- }
2417
- function parsePositiveIntegerOption(value, flag) {
2418
- return parseIntegerOption(value, flag, { min: 1 });
2419
- }
2420
- function parseNonNegativeIntegerOption(value, flag) {
2421
- return parseIntegerOption(value, flag, { min: 0 });
2422
- }
2423
-
2424
- // src/commands/logncrash/helpers.ts
2425
- async function resolveLogncrashClient(profile) {
2426
- const profileName = await resolveProfileName(profile);
2427
- const credential = await getServiceCredential("logncrash", profileName);
2428
- if (typeof credential.appkey !== "string" || credential.appkey.length === 0) {
2429
- throw new NhnCloudCliError(
2430
- `profile "${profileName}"\uC758 logncrash \uC790\uACA9\uC99D\uBA85\uC5D0 appkey\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. nhncloud configure\uB85C appkey\uB97C \uC124\uC815\uD558\uC138\uC694.`,
2431
- EXIT_CONFIG_ERROR
2432
- );
2433
- }
2434
- const uak = await getUserAccessKey(profileName);
2435
- const accessToken = await getAccessToken(profileName, uak.id, uak.secret);
2436
- return new LogncrashClient(credential.appkey, accessToken);
2437
- }
2438
-
2439
- // src/commands/logncrash/search.ts
2440
- function getString(value) {
2441
- return typeof value === "string" ? value : String(value ?? "");
3178
+
3179
+ // src/commands/logncrash/search.ts
3180
+ function getString(value) {
3181
+ return typeof value === "string" ? value : String(value ?? "");
2442
3182
  }
2443
3183
  function formatLogRow(log) {
2444
3184
  const logTime = getString(log["logTime"] ?? log["time"] ?? "");
@@ -2446,7 +3186,7 @@ function formatLogRow(log) {
2446
3186
  const body = truncate(getString(log["logBody"] ?? log["body"] ?? log["message"] ?? ""), 60);
2447
3187
  return [logTime, logType, body];
2448
3188
  }
2449
- var searchCommand = new import_commander4.Command("search").description("Log & Crash \uB85C\uADF8 \uAC80\uC0C9").option("--query <lucene>", "Lucene \uC9C8\uC758 \uBB38\uC790\uC5F4 (\uD544\uC218)").option("--from <time>", "\uAC80\uC0C9 \uC2DC\uC791: ISO8601 \uB610\uB294 \uC0C1\uB300\uC2DC\uAC04 (1h/30m/2d/now) (\uD544\uC218)").option("--to <time>", "\uAC80\uC0C9 \uB05D: ISO8601 \uB610\uB294 \uC0C1\uB300\uC2DC\uAC04 (\uD544\uC218)").option("--page <n>", "pageNumber (\uAE30\uBCF8 0)", "0").option("--size <n>", "pageSize (\uAE30\uBCF8 10, \uCD5C\uB300 100)", "10").option("--cursor <value>", "\uB2E4\uC74C \uD398\uC774\uC9C0 \uC870\uD68C\uC6A9 opaque cursor").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
3189
+ var searchCommand = new import_commander4.Command("search").description("Log & Crash \uB85C\uADF8 \uAC80\uC0C9").option("--query <lucene>", "Lucene \uC9C8\uC758 \uBB38\uC790\uC5F4 (\uD544\uC218)").option("--from <time>", "\uAC80\uC0C9 \uC2DC\uC791: ISO8601 \uB610\uB294 \uC0C1\uB300\uC2DC\uAC04 (1h/30m/2d/now) (\uD544\uC218)").option("--to <time>", "\uAC80\uC0C9 \uB05D: ISO8601 \uB610\uB294 \uC0C1\uB300\uC2DC\uAC04 (\uD544\uC218)").option("--page <n>", "\uC804\uD658 \uD638\uD658\uC6A9 pageNumber. 0\uB9CC \uD5C8\uC6A9 (\uB2E4\uC74C \uD398\uC774\uC9C0\uB294 --cursor)", "0").option("--size <n>", "pageSize (\uAE30\uBCF8 10, \uCD5C\uB300 100)", "10").option("--cursor <value>", "\uB2E4\uC74C \uD398\uC774\uC9C0 \uC870\uD68C\uC6A9 opaque cursor").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
2450
3190
  const opts = cmd.optsWithGlobals();
2451
3191
  if (!opts.query) {
2452
3192
  throw new NhnCloudCliError(`--query \uC635\uC158\uC740 \uD544\uC218\uC785\uB2C8\uB2E4. \uC608: --query 'logType:"NORMAL"'`, EXIT_PARAM_ERROR);
@@ -2505,32 +3245,32 @@ var searchCommand = new import_commander4.Command("search").description("Log & C
2505
3245
 
2506
3246
  // src/commands/logncrash/send.ts
2507
3247
  var import_commander5 = require("commander");
2508
- var import_node_fs = require("fs");
3248
+ var import_node_fs3 = require("fs");
2509
3249
  var MAX_LOG_BYTES = 8 * 1024 * 1024;
2510
3250
  var VALID_LEVELS = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"];
2511
3251
  function resolveBody(opts) {
2512
3252
  if (opts.body !== void 0) return opts.body;
2513
3253
  if (opts.file !== void 0) {
2514
- let stat;
3254
+ let stat2;
2515
3255
  try {
2516
- stat = (0, import_node_fs.statSync)(opts.file);
3256
+ stat2 = (0, import_node_fs3.statSync)(opts.file);
2517
3257
  } catch (e) {
2518
3258
  const reason = e.code ?? (e instanceof Error ? e.message : String(e));
2519
3259
  throw new NhnCloudCliError(`\uB85C\uADF8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${opts.file} (${reason})`, EXIT_PARAM_ERROR);
2520
3260
  }
2521
- if (!stat.isFile()) {
3261
+ if (!stat2.isFile()) {
2522
3262
  throw new NhnCloudCliError(`\uB85C\uADF8 \uD30C\uC77C\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${opts.file}`, EXIT_PARAM_ERROR);
2523
3263
  }
2524
- if (stat.size > MAX_LOG_BYTES) {
3264
+ if (stat2.size > MAX_LOG_BYTES) {
2525
3265
  throw new NhnCloudCliError(
2526
- `\uB85C\uADF8 \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${stat.size} \uBC14\uC774\uD2B8 (\uD55C\uB3C4 ${MAX_LOG_BYTES} \uBC14\uC774\uD2B8).`,
3266
+ `\uB85C\uADF8 \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${stat2.size} \uBC14\uC774\uD2B8 (\uD55C\uB3C4 ${MAX_LOG_BYTES} \uBC14\uC774\uD2B8).`,
2527
3267
  EXIT_PARAM_ERROR
2528
3268
  );
2529
3269
  }
2530
- return (0, import_node_fs.readFileSync)(opts.file, "utf-8");
3270
+ return (0, import_node_fs3.readFileSync)(opts.file, "utf-8");
2531
3271
  }
2532
3272
  if (!process.stdin.isTTY) {
2533
- return (0, import_node_fs.readFileSync)(0, "utf-8");
3273
+ return (0, import_node_fs3.readFileSync)(0, "utf-8");
2534
3274
  }
2535
3275
  throw new NhnCloudCliError(
2536
3276
  "\uB85C\uADF8 \uBCF8\uBB38\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. --body <text> \uB610\uB294 --file <path> \uB610\uB294 \uD45C\uC900\uC785\uB825(\uD30C\uC774\uD504)\uC73C\uB85C \uC804\uB2EC\uD558\uC138\uC694.",
@@ -2593,21 +3333,21 @@ credentials.json \uC5D0 "appkey": "<appkey>" \uB97C \uCD94\uAC00\uD558\uC138\uC6
2593
3333
 
2594
3334
  // src/commands/logncrash/export.ts
2595
3335
  var import_commander6 = require("commander");
2596
- var import_promises6 = require("fs/promises");
2597
- var import_node_fs2 = require("fs");
2598
- var import_node_crypto2 = require("crypto");
3336
+ var import_promises5 = require("fs/promises");
3337
+ var import_node_fs4 = require("fs");
3338
+ var import_node_crypto4 = require("crypto");
2599
3339
  var MAX_TOTAL = 1e5;
2600
- function assertWritable(path3, force) {
3340
+ function assertWritable(path5, force) {
2601
3341
  if (force) return;
2602
3342
  try {
2603
- (0, import_node_fs2.statSync)(path3);
3343
+ (0, import_node_fs4.statSync)(path5);
2604
3344
  } catch (e) {
2605
3345
  if (e.code === "ENOENT") return;
2606
3346
  const reason = e.code ?? (e instanceof Error ? e.message : String(e));
2607
- throw new NhnCloudCliError(`--output \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path3} (${reason})`, EXIT_PARAM_ERROR);
3347
+ throw new NhnCloudCliError(`--output \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path5} (${reason})`, EXIT_PARAM_ERROR);
2608
3348
  }
2609
3349
  throw new NhnCloudCliError(
2610
- `--output \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path3}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC4F0\uC138\uC694.`,
3350
+ `--output \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path5}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC4F0\uC138\uC694.`,
2611
3351
  EXIT_PARAM_ERROR
2612
3352
  );
2613
3353
  }
@@ -2646,8 +3386,8 @@ var exportCommand = new import_commander6.Command("export").description("Log & C
2646
3386
  assertSearchRange(fromIso, toIso);
2647
3387
  assertWritable(opts.output, opts.force ?? false);
2648
3388
  const client = await resolveLogncrashClient(opts.profile);
2649
- const tmp = opts.output + "." + (0, import_node_crypto2.randomBytes)(4).toString("hex") + ".tmp";
2650
- const stream = (0, import_node_fs2.createWriteStream)(tmp, { encoding: "utf-8" });
3389
+ const tmp = opts.output + "." + (0, import_node_crypto4.randomBytes)(4).toString("hex") + ".tmp";
3390
+ const stream = (0, import_node_fs4.createWriteStream)(tmp, { encoding: "utf-8" });
2651
3391
  const spinner = startSpinner("\uB85C\uADF8 \uCD94\uCD9C \uC911...");
2652
3392
  let count = 0;
2653
3393
  let total = 0;
@@ -2683,16 +3423,23 @@ var exportCommand = new import_commander6.Command("export").description("Log & C
2683
3423
  });
2684
3424
  } catch (err) {
2685
3425
  stopSpinner(false);
2686
- stream.destroy();
2687
- await (0, import_promises6.rm)(tmp, { force: true }).catch(() => {
3426
+ await new Promise((resolve) => {
3427
+ if (stream.destroyed && stream.closed) {
3428
+ resolve();
3429
+ return;
3430
+ }
3431
+ stream.once("close", () => resolve());
3432
+ stream.destroy();
3433
+ });
3434
+ await (0, import_promises5.rm)(tmp, { force: true }).catch(() => {
2688
3435
  });
2689
3436
  throw err;
2690
3437
  }
2691
3438
  stopSpinner(true, `${count}\uAC74 \uCD94\uCD9C \uC644\uB8CC`);
2692
3439
  try {
2693
- await (0, import_promises6.rename)(tmp, opts.output);
3440
+ await (0, import_promises5.rename)(tmp, opts.output);
2694
3441
  } catch (err) {
2695
- await (0, import_promises6.rm)(tmp, { force: true }).catch(() => {
3442
+ await (0, import_promises5.rm)(tmp, { force: true }).catch(() => {
2696
3443
  });
2697
3444
  const reason = err.code ?? (err instanceof Error ? err.message : String(err));
2698
3445
  throw new NhnCloudCliError(`\uCD9C\uB825 \uD30C\uC77C\uC744 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${opts.output} (${reason})`, EXIT_PARAM_ERROR);
@@ -2739,8 +3486,6 @@ function isBinary(val) {
2739
3486
  const binarySizeType = typeof obj["binarySize"];
2740
3487
  return (binaryKeyType === "number" || binaryKeyType === "string") && (binarySizeType === "number" || binarySizeType === "string");
2741
3488
  }
2742
- var SYNC_TIMEOUT_MS = 6e5;
2743
- var DEFAULT_TIMEOUT_MS3 = 3e4;
2744
3489
  var DeployClient = class {
2745
3490
  accessToken;
2746
3491
  baseUrl;
@@ -2779,7 +3524,7 @@ var DeployClient = class {
2779
3524
  },
2780
3525
  json: payload,
2781
3526
  retry: 0,
2782
- timeout: isAsync ? DEFAULT_TIMEOUT_MS3 : SYNC_TIMEOUT_MS
3527
+ timeout: isAsync ? DEFAULT_TIMEOUT_MS : SYNC_TIMEOUT_MS
2783
3528
  }).json();
2784
3529
  return unwrap(res);
2785
3530
  } catch (err) {
@@ -2795,7 +3540,7 @@ var DeployClient = class {
2795
3540
  const res = await import_ky7.default.get(url, {
2796
3541
  headers: this.authHeaders(),
2797
3542
  retry: 0,
2798
- timeout: DEFAULT_TIMEOUT_MS3
3543
+ timeout: DEFAULT_TIMEOUT_MS
2799
3544
  }).json();
2800
3545
  return unwrap(res);
2801
3546
  } catch (err) {
@@ -2811,7 +3556,7 @@ var DeployClient = class {
2811
3556
  const res = await import_ky7.default.get(url, {
2812
3557
  headers: this.authHeaders(),
2813
3558
  retry: 0,
2814
- timeout: DEFAULT_TIMEOUT_MS3
3559
+ timeout: DEFAULT_TIMEOUT_MS
2815
3560
  }).json();
2816
3561
  return unwrap(res);
2817
3562
  } catch (err) {
@@ -2827,7 +3572,7 @@ var DeployClient = class {
2827
3572
  const res = await import_ky7.default.get(url, {
2828
3573
  headers: this.authHeaders(),
2829
3574
  retry: 0,
2830
- timeout: DEFAULT_TIMEOUT_MS3
3575
+ timeout: DEFAULT_TIMEOUT_MS
2831
3576
  }).json();
2832
3577
  return unwrap(res);
2833
3578
  } catch (err) {
@@ -2843,7 +3588,7 @@ var DeployClient = class {
2843
3588
  const res = await import_ky7.default.get(url, {
2844
3589
  headers: this.authHeaders(),
2845
3590
  retry: 0,
2846
- timeout: DEFAULT_TIMEOUT_MS3
3591
+ timeout: DEFAULT_TIMEOUT_MS
2847
3592
  }).json();
2848
3593
  const body = unwrap(res);
2849
3594
  const list = body.binaryGroups;
@@ -2874,7 +3619,7 @@ var DeployClient = class {
2874
3619
  headers: this.authHeaders(),
2875
3620
  searchParams,
2876
3621
  retry: 0,
2877
- timeout: DEFAULT_TIMEOUT_MS3
3622
+ timeout: DEFAULT_TIMEOUT_MS
2878
3623
  }).json();
2879
3624
  const body = unwrap(res);
2880
3625
  const list = body.binaries;
@@ -3188,8 +3933,8 @@ var binariesCommand = new import_commander12.Command("binaries").description("\u
3188
3933
 
3189
3934
  // src/commands/deploy/upload.ts
3190
3935
  var import_commander13 = require("commander");
3191
- var import_node_fs3 = require("fs");
3192
- var import_node_path5 = require("path");
3936
+ var import_node_fs5 = require("fs");
3937
+ var import_node_path7 = require("path");
3193
3938
  var MAX_UPLOAD_BYTES = 512 * 1024 * 1024;
3194
3939
  function parsePositiveInt2(value, flag) {
3195
3940
  if (value === void 0) return void 0;
@@ -3208,9 +3953,9 @@ var uploadCommand = new import_commander13.Command("upload").description("\uB85C
3208
3953
  throw new NhnCloudCliError("--binary-group \uC774 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
3209
3954
  }
3210
3955
  const filePath = opts.file;
3211
- let stat;
3956
+ let stat2;
3212
3957
  try {
3213
- stat = (0, import_node_fs3.statSync)(filePath);
3958
+ stat2 = (0, import_node_fs5.statSync)(filePath);
3214
3959
  } catch (e) {
3215
3960
  const reason = e.code ?? (e instanceof Error ? e.message : String(e));
3216
3961
  throw new NhnCloudCliError(
@@ -3218,17 +3963,17 @@ var uploadCommand = new import_commander13.Command("upload").description("\uB85C
3218
3963
  EXIT_PARAM_ERROR
3219
3964
  );
3220
3965
  }
3221
- if (!stat.isFile()) {
3966
+ if (!stat2.isFile()) {
3222
3967
  throw new NhnCloudCliError(`--file \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
3223
3968
  }
3224
- if (stat.size > MAX_UPLOAD_BYTES) {
3969
+ if (stat2.size > MAX_UPLOAD_BYTES) {
3225
3970
  throw new NhnCloudCliError(
3226
- `--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat.size} \uBC14\uC774\uD2B8). \uC5C5\uB85C\uB4DC \uD55C\uB3C4 ${MAX_UPLOAD_BYTES} \uBC14\uC774\uD2B8.`,
3971
+ `--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat2.size} \uBC14\uC774\uD2B8). \uC5C5\uB85C\uB4DC \uD55C\uB3C4 ${MAX_UPLOAD_BYTES} \uBC14\uC774\uD2B8.`,
3227
3972
  EXIT_PARAM_ERROR
3228
3973
  );
3229
3974
  }
3230
- const fileBuffer = (0, import_node_fs3.readFileSync)(filePath);
3231
- const fileName = (0, import_node_path5.basename)(filePath);
3975
+ const fileBuffer = (0, import_node_fs5.readFileSync)(filePath);
3976
+ const fileName = (0, import_node_path7.basename)(filePath);
3232
3977
  const target = await getDeployTarget(targetName);
3233
3978
  const appKey = opts.appKey ?? target.appKey;
3234
3979
  const artifactId = opts.artifactId ?? target.artifactId;
@@ -3264,8 +4009,8 @@ var uploadCommand = new import_commander13.Command("upload").description("\uB85C
3264
4009
 
3265
4010
  // src/commands/deploy/download.ts
3266
4011
  var import_commander14 = require("commander");
3267
- var import_node_fs4 = require("fs");
3268
- var import_chalk4 = __toESM(require("chalk"));
4012
+ var import_node_fs6 = require("fs");
4013
+ var import_chalk3 = __toESM(require("chalk"));
3269
4014
  function parsePositiveInt3(value, flag) {
3270
4015
  if (value === void 0) return void 0;
3271
4016
  if (!/^[1-9]\d*$/.test(value)) {
@@ -3276,20 +4021,20 @@ function parsePositiveInt3(value, flag) {
3276
4021
  }
3277
4022
  return Number(value);
3278
4023
  }
3279
- function assertWritable2(path3, force) {
4024
+ function assertWritable2(path5, force) {
3280
4025
  if (force) return;
3281
4026
  try {
3282
- (0, import_node_fs4.statSync)(path3);
4027
+ (0, import_node_fs6.statSync)(path5);
3283
4028
  } catch (e) {
3284
4029
  if (e.code === "ENOENT") return;
3285
4030
  const reason = e.code ?? (e instanceof Error ? e.message : String(e));
3286
4031
  throw new NhnCloudCliError(
3287
- `-o \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path3} (${reason})`,
4032
+ `-o \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path5} (${reason})`,
3288
4033
  EXIT_PARAM_ERROR
3289
4034
  );
3290
4035
  }
3291
4036
  throw new NhnCloudCliError(
3292
- `-o \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path3}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC4F0\uC138\uC694.`,
4037
+ `-o \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path5}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC4F0\uC138\uC694.`,
3293
4038
  EXIT_PARAM_ERROR
3294
4039
  );
3295
4040
  }
@@ -3309,14 +4054,14 @@ var downloadCommand = new import_commander14.Command("download").description("\u
3309
4054
  startSpinner("\uBC14\uC774\uB108\uB9AC \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
3310
4055
  try {
3311
4056
  const buffer = await client.downloadBinary(appKey, artifactId, binaryGroupKey, binaryKey);
3312
- (0, import_node_fs4.writeFileSync)(outPath, buffer);
4057
+ (0, import_node_fs6.writeFileSync)(outPath, buffer);
3313
4058
  } catch (err) {
3314
4059
  stopSpinner(false);
3315
4060
  throw err;
3316
4061
  }
3317
4062
  stopSpinner(true);
3318
4063
  if (!opts.quiet) {
3319
- process.stderr.write(import_chalk4.default.green(` \uC800\uC7A5\uB428: ${outPath}
4064
+ process.stderr.write(import_chalk3.default.green(` \uC800\uC7A5\uB428: ${outPath}
3320
4065
  `));
3321
4066
  }
3322
4067
  });
@@ -3335,7 +4080,6 @@ async function resolveIaasTokenContext(opts) {
3335
4080
 
3336
4081
  // src/services/instance/client.ts
3337
4082
  var import_ky8 = __toESM(require("ky"));
3338
- var DEFAULT_TIMEOUT_MS4 = 3e4;
3339
4083
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
3340
4084
  function isServer(val) {
3341
4085
  if (typeof val !== "object" || val === null) return false;
@@ -3467,7 +4211,7 @@ var InstanceClient = class {
3467
4211
  const raw = await import_ky8.default.get(url, {
3468
4212
  headers: this.authHeaders(),
3469
4213
  retry: 0,
3470
- timeout: DEFAULT_TIMEOUT_MS4
4214
+ timeout: DEFAULT_TIMEOUT_MS
3471
4215
  }).json();
3472
4216
  if (!isServersResponse(raw)) {
3473
4217
  throw new NhnCloudCliError(
@@ -3489,7 +4233,7 @@ var InstanceClient = class {
3489
4233
  const raw = await import_ky8.default.get(url, {
3490
4234
  headers: this.authHeaders(),
3491
4235
  retry: 0,
3492
- timeout: DEFAULT_TIMEOUT_MS4
4236
+ timeout: DEFAULT_TIMEOUT_MS
3493
4237
  }).json();
3494
4238
  if (!isServerResponse(raw)) {
3495
4239
  throw new NhnCloudCliError(
@@ -3549,7 +4293,7 @@ var InstanceClient = class {
3549
4293
  headers: this.authHeaders(),
3550
4294
  json: { server: serverBody },
3551
4295
  retry: 0,
3552
- timeout: DEFAULT_TIMEOUT_MS4
4296
+ timeout: DEFAULT_TIMEOUT_MS
3553
4297
  }).json();
3554
4298
  } catch (err) {
3555
4299
  throw toNhnCloudCliError(err);
@@ -3571,7 +4315,7 @@ var InstanceClient = class {
3571
4315
  await import_ky8.default.delete(url, {
3572
4316
  headers: this.authHeaders(),
3573
4317
  retry: 0,
3574
- timeout: DEFAULT_TIMEOUT_MS4
4318
+ timeout: DEFAULT_TIMEOUT_MS
3575
4319
  });
3576
4320
  } catch (err) {
3577
4321
  throw toNhnCloudCliError(err);
@@ -3590,7 +4334,7 @@ var InstanceClient = class {
3590
4334
  headers: this.authHeaders(),
3591
4335
  json: payload,
3592
4336
  retry: 0,
3593
- timeout: DEFAULT_TIMEOUT_MS4
4337
+ timeout: DEFAULT_TIMEOUT_MS
3594
4338
  });
3595
4339
  } catch (err) {
3596
4340
  throw toNhnCloudCliError(err);
@@ -3625,8 +4369,8 @@ var InstanceClient = class {
3625
4369
  return this.serverAction(id, { revertResize: null });
3626
4370
  }
3627
4371
  async listFlavors(params = {}) {
3628
- const path3 = params.detail ? "/flavors/detail" : "/flavors";
3629
- const url = `${this.computeEndpoint}${path3}`;
4372
+ const path5 = params.detail ? "/flavors/detail" : "/flavors";
4373
+ const url = `${this.computeEndpoint}${path5}`;
3630
4374
  const searchParams = {};
3631
4375
  if (params.minDisk !== void 0) searchParams["minDisk"] = params.minDisk;
3632
4376
  if (params.minRam !== void 0) searchParams["minRam"] = params.minRam;
@@ -3635,7 +4379,7 @@ var InstanceClient = class {
3635
4379
  headers: this.authHeaders(),
3636
4380
  searchParams,
3637
4381
  retry: 0,
3638
- timeout: DEFAULT_TIMEOUT_MS4
4382
+ timeout: DEFAULT_TIMEOUT_MS
3639
4383
  }).json();
3640
4384
  if (params.detail) {
3641
4385
  if (!isFlavorDetailsResponse(raw)) {
@@ -3667,7 +4411,7 @@ var InstanceClient = class {
3667
4411
  const raw = await import_ky8.default.get(url, {
3668
4412
  headers: this.authHeaders(),
3669
4413
  retry: 0,
3670
- timeout: DEFAULT_TIMEOUT_MS4
4414
+ timeout: DEFAULT_TIMEOUT_MS
3671
4415
  }).json();
3672
4416
  if (!isAvailabilityZonesResponse(raw)) {
3673
4417
  throw new NhnCloudCliError(
@@ -3684,7 +4428,7 @@ var InstanceClient = class {
3684
4428
  async listKeypairs() {
3685
4429
  const url = `${this.computeEndpoint}/os-keypairs`;
3686
4430
  try {
3687
- const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS4 }).json();
4431
+ const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
3688
4432
  if (!isKeypairsResponse(raw)) {
3689
4433
  throw new NhnCloudCliError(
3690
4434
  "instance keypairs \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 keypairs \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -3700,7 +4444,7 @@ var InstanceClient = class {
3700
4444
  async getKeypair(name) {
3701
4445
  const url = `${this.computeEndpoint}/os-keypairs/${encodeURIComponent(name)}`;
3702
4446
  try {
3703
- const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS4 }).json();
4447
+ const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
3704
4448
  if (!isKeypairDetailResponse(raw)) {
3705
4449
  throw new NhnCloudCliError(
3706
4450
  `instance keypair get(${name}) \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 keypair \uC0C1\uC138 \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`,
@@ -3729,7 +4473,7 @@ var InstanceClient = class {
3729
4473
  headers: this.authHeaders(),
3730
4474
  json: { keypair: keypairBody },
3731
4475
  retry: 0,
3732
- timeout: DEFAULT_TIMEOUT_MS4
4476
+ timeout: DEFAULT_TIMEOUT_MS
3733
4477
  }).json();
3734
4478
  } catch (err) {
3735
4479
  throw toNhnCloudCliError(err);
@@ -3754,7 +4498,7 @@ var InstanceClient = class {
3754
4498
  async deleteKeypair(name) {
3755
4499
  const url = `${this.computeEndpoint}/os-keypairs/${encodeURIComponent(name)}`;
3756
4500
  try {
3757
- await import_ky8.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS4 });
4501
+ await import_ky8.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS });
3758
4502
  } catch (err) {
3759
4503
  throw toNhnCloudCliError(err);
3760
4504
  }
@@ -3778,7 +4522,7 @@ var InstanceClient = class {
3778
4522
  headers: this.authHeaders(),
3779
4523
  searchParams,
3780
4524
  retry: 0,
3781
- timeout: DEFAULT_TIMEOUT_MS4
4525
+ timeout: DEFAULT_TIMEOUT_MS
3782
4526
  }).json();
3783
4527
  if (!isImagesResponse(raw)) {
3784
4528
  throw new NhnCloudCliError(
@@ -3798,7 +4542,7 @@ var InstanceClient = class {
3798
4542
  async listVolumeAttachments(serverId) {
3799
4543
  const url = `${this.computeEndpoint}/servers/${encodeURIComponent(serverId)}/os-volume_attachments`;
3800
4544
  try {
3801
- const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS4 }).json();
4545
+ const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
3802
4546
  if (!isVolumeAttachmentsResponse(raw)) {
3803
4547
  throw new NhnCloudCliError(
3804
4548
  "instance volumes \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 volumeAttachments \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -3821,7 +4565,7 @@ var InstanceClient = class {
3821
4565
  headers: this.authHeaders(),
3822
4566
  json: { volumeAttachment: { volumeId } },
3823
4567
  retry: 0,
3824
- timeout: DEFAULT_TIMEOUT_MS4
4568
+ timeout: DEFAULT_TIMEOUT_MS
3825
4569
  });
3826
4570
  if (res.status === 202 || res.headers.get("content-length") === "0") {
3827
4571
  return { id: volumeId, volumeId, serverId, device: "" };
@@ -3845,7 +4589,7 @@ var InstanceClient = class {
3845
4589
  async detachVolume(serverId, volumeId) {
3846
4590
  const url = `${this.computeEndpoint}/servers/${encodeURIComponent(serverId)}/os-volume_attachments/${encodeURIComponent(volumeId)}`;
3847
4591
  try {
3848
- await import_ky8.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS4 });
4592
+ await import_ky8.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS });
3849
4593
  } catch (err) {
3850
4594
  throw toNhnCloudCliError(err);
3851
4595
  }
@@ -3913,7 +4657,6 @@ var import_commander16 = require("commander");
3913
4657
 
3914
4658
  // src/services/blockstorage/client.ts
3915
4659
  var import_ky9 = __toESM(require("ky"));
3916
- var DEFAULT_TIMEOUT_MS5 = 3e4;
3917
4660
  function isVolume(val) {
3918
4661
  if (typeof val !== "object" || val === null) return false;
3919
4662
  const obj = val;
@@ -3944,7 +4687,7 @@ var BlockStorageClient = class {
3944
4687
  if (params?.offset !== void 0) searchParams["offset"] = params.offset;
3945
4688
  if (params?.marker !== void 0) searchParams["marker"] = params.marker;
3946
4689
  try {
3947
- const raw = await import_ky9.default.get(url, { headers: this.authHeaders(), searchParams, retry: 0, timeout: DEFAULT_TIMEOUT_MS5 }).json();
4690
+ const raw = await import_ky9.default.get(url, { headers: this.authHeaders(), searchParams, retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
3948
4691
  if (typeof raw !== "object" || raw === null) {
3949
4692
  throw new NhnCloudCliError(
3950
4693
  "volume list \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 volumes \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -3972,7 +4715,7 @@ var BlockStorageClient = class {
3972
4715
  async get(id) {
3973
4716
  const url = `${this.endpoint}/volumes/${encodeURIComponent(id)}`;
3974
4717
  try {
3975
- const raw = await import_ky9.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS5 }).json();
4718
+ const raw = await import_ky9.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
3976
4719
  if (!isVolumeResponse(raw)) {
3977
4720
  throw new NhnCloudCliError(
3978
4721
  "volume get \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 volume \uAC1D\uCCB4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -3997,7 +4740,7 @@ var BlockStorageClient = class {
3997
4740
  headers: this.authHeaders(),
3998
4741
  json: { volume: volumeBody },
3999
4742
  retry: 0,
4000
- timeout: DEFAULT_TIMEOUT_MS5
4743
+ timeout: DEFAULT_TIMEOUT_MS
4001
4744
  }).json();
4002
4745
  if (!isVolumeResponse(raw)) {
4003
4746
  throw new NhnCloudCliError(
@@ -4095,7 +4838,7 @@ var getCommand = new import_commander17.Command("get").description("\uB2E8\uC77C
4095
4838
 
4096
4839
  // src/commands/volume/create.ts
4097
4840
  var import_commander18 = require("commander");
4098
- var import_chalk5 = __toESM(require("chalk"));
4841
+ var import_chalk4 = __toESM(require("chalk"));
4099
4842
  var createCommand = new import_commander18.Command("create").description("\uBCFC\uB968\uC744 \uBC1C\uAE09\uD55C\uB2E4").requiredOption("--size <gb>", "\uBCFC\uB968 \uD06C\uAE30(GB) \u2014 \uD544\uC218").option("--name <name>", "\uBCFC\uB968 \uC774\uB984").option("--description <text>", "\uBCFC\uB968 \uC124\uBA85").option("--volume-type <type>", "\uBCFC\uB968 \uD0C0\uC785").option("--availability-zone <az>", "\uAC00\uC6A9\uC131 \uC601\uC5ED(AZ). instance availability-zones \uB85C \uC870\uD68C\uD55C zoneName \uC9C0\uC815").option("--snapshot-id <id>", "\uC2A4\uB0C5\uC0F7 ID (\uC2A4\uB0C5\uC0F7\uC5D0\uC11C \uBCFC\uB968 \uC0DD\uC131)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
4100
4843
  const opts = cmd.optsWithGlobals();
4101
4844
  if (!/^[1-9]\d*$/.test(opts.size)) {
@@ -4129,7 +4872,7 @@ var createCommand = new import_commander18.Command("create").description("\uBCFC
4129
4872
  throw err;
4130
4873
  }
4131
4874
  stopSpinner(true);
4132
- process.stderr.write(import_chalk5.default.green(`\uBCFC\uB968 \uBC1C\uAE09 \uC694\uCCAD \uC644\uB8CC (id: ${volume.id}, status: ${volume.status})
4875
+ process.stderr.write(import_chalk4.default.green(`\uBCFC\uB968 \uBC1C\uAE09 \uC694\uCCAD \uC644\uB8CC (id: ${volume.id}, status: ${volume.status})
4133
4876
  `));
4134
4877
  const rows = [
4135
4878
  ["id", volume.id],
@@ -4153,7 +4896,6 @@ var import_commander19 = require("commander");
4153
4896
 
4154
4897
  // src/services/network/client.ts
4155
4898
  var import_ky10 = __toESM(require("ky"));
4156
- var DEFAULT_TIMEOUT_MS6 = 3e4;
4157
4899
  function isVpc(val) {
4158
4900
  if (typeof val !== "object" || val === null) return false;
4159
4901
  const obj = val;
@@ -4209,7 +4951,7 @@ var NetworkClient = class {
4209
4951
  const raw = await import_ky10.default.get(url, {
4210
4952
  headers: this.authHeaders(),
4211
4953
  retry: 0,
4212
- timeout: DEFAULT_TIMEOUT_MS6
4954
+ timeout: DEFAULT_TIMEOUT_MS
4213
4955
  }).json();
4214
4956
  if (!isVpcsResponse(raw)) {
4215
4957
  throw new NhnCloudCliError(
@@ -4231,7 +4973,7 @@ var NetworkClient = class {
4231
4973
  const raw = await import_ky10.default.get(url, {
4232
4974
  headers: this.authHeaders(),
4233
4975
  retry: 0,
4234
- timeout: DEFAULT_TIMEOUT_MS6
4976
+ timeout: DEFAULT_TIMEOUT_MS
4235
4977
  }).json();
4236
4978
  if (!isSubnetsResponse(raw)) {
4237
4979
  throw new NhnCloudCliError(
@@ -4248,7 +4990,7 @@ var NetworkClient = class {
4248
4990
  async listFloatingIps() {
4249
4991
  const url = `${this.networkEndpoint}/floatingips`;
4250
4992
  try {
4251
- const raw = await import_ky10.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS6 }).json();
4993
+ const raw = await import_ky10.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
4252
4994
  if (!isFloatingIpsResponse(raw)) {
4253
4995
  throw new NhnCloudCliError(
4254
4996
  "floatingip list \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 floatingips \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -4268,7 +5010,7 @@ var NetworkClient = class {
4268
5010
  headers: this.authHeaders(),
4269
5011
  json: { floatingip: { floating_network_id: params.floating_network_id } },
4270
5012
  retry: 0,
4271
- timeout: DEFAULT_TIMEOUT_MS6
5013
+ timeout: DEFAULT_TIMEOUT_MS
4272
5014
  }).json();
4273
5015
  if (!isFloatingIpResponse(raw)) {
4274
5016
  throw new NhnCloudCliError(
@@ -4285,7 +5027,7 @@ var NetworkClient = class {
4285
5027
  async deleteFloatingIp(id) {
4286
5028
  const url = `${this.networkEndpoint}/floatingips/${encodeURIComponent(id)}`;
4287
5029
  try {
4288
- await import_ky10.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS6 });
5030
+ await import_ky10.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS });
4289
5031
  } catch (err) {
4290
5032
  throw toNhnCloudCliError(err);
4291
5033
  }
@@ -4303,7 +5045,7 @@ var NetworkClient = class {
4303
5045
  headers: this.authHeaders(),
4304
5046
  searchParams: { "router:external": "true" },
4305
5047
  retry: 0,
4306
- timeout: DEFAULT_TIMEOUT_MS6
5048
+ timeout: DEFAULT_TIMEOUT_MS
4307
5049
  }).json();
4308
5050
  if (typeof raw !== "object" || raw === null) return null;
4309
5051
  const vpcs = raw["vpcs"];
@@ -4408,7 +5150,7 @@ var listCommand4 = new import_commander21.Command("list").description("Floating
4408
5150
 
4409
5151
  // src/commands/floatingip/create.ts
4410
5152
  var import_commander22 = require("commander");
4411
- var import_chalk6 = __toESM(require("chalk"));
5153
+ var import_chalk5 = __toESM(require("chalk"));
4412
5154
  var createCommand2 = new import_commander22.Command("create").description("Floating IP \uB97C \uBC1C\uAE09\uD55C\uB2E4 (--network \uBBF8\uC9C0\uC815 \uC2DC \uC678\uBD80 VPC \uC790\uB3D9 \uC870\uD68C)").option("--network <id>", "\uC678\uBD80 \uB124\uD2B8\uC6CC\uD06C(VPC) id (\uBBF8\uC9C0\uC815 \uC2DC router:external=true \uC790\uB3D9 \uC870\uD68C)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
4413
5155
  const opts = cmd.optsWithGlobals();
4414
5156
  const { client } = await resolveNetworkClient(opts);
@@ -4440,7 +5182,7 @@ var createCommand2 = new import_commander22.Command("create").description("Float
4440
5182
  }
4441
5183
  stopSpinner(true);
4442
5184
  process.stderr.write(
4443
- import_chalk6.default.green(`\u2713 Floating IP "${fip.floating_ip_address}" \uB97C \uBC1C\uAE09\uD588\uC2B5\uB2C8\uB2E4 (id: ${fip.id}).
5185
+ import_chalk5.default.green(`\u2713 Floating IP "${fip.floating_ip_address}" \uB97C \uBC1C\uAE09\uD588\uC2B5\uB2C8\uB2E4 (id: ${fip.id}).
4444
5186
  `)
4445
5187
  );
4446
5188
  output(opts, {
@@ -4453,7 +5195,7 @@ var createCommand2 = new import_commander22.Command("create").description("Float
4453
5195
 
4454
5196
  // src/commands/floatingip/delete.ts
4455
5197
  var import_commander23 = require("commander");
4456
- var import_chalk7 = __toESM(require("chalk"));
5198
+ var import_chalk6 = __toESM(require("chalk"));
4457
5199
  var deleteCommand = new import_commander23.Command("delete").description("Floating IP \uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "Floating IP ID").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
4458
5200
  const opts = cmd.optsWithGlobals();
4459
5201
  const isTTY = process.stdin.isTTY;
@@ -4470,7 +5212,7 @@ var deleteCommand = new import_commander23.Command("delete").description("Floati
4470
5212
  default: false
4471
5213
  });
4472
5214
  if (!ok) {
4473
- process.stderr.write(import_chalk7.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
5215
+ process.stderr.write(import_chalk6.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
4474
5216
  return;
4475
5217
  }
4476
5218
  }
@@ -4483,7 +5225,7 @@ var deleteCommand = new import_commander23.Command("delete").description("Floati
4483
5225
  throw err;
4484
5226
  }
4485
5227
  stopSpinner(true);
4486
- process.stderr.write(import_chalk7.default.green(`\u2713 Floating IP "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
5228
+ process.stderr.write(import_chalk6.default.green(`\u2713 Floating IP "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
4487
5229
  `));
4488
5230
  });
4489
5231
 
@@ -4594,8 +5336,8 @@ var getCommand2 = new import_commander26.Command("get").description("\uB2E8\uC77
4594
5336
 
4595
5337
  // src/commands/instance/create.ts
4596
5338
  var import_commander27 = require("commander");
4597
- var import_node_fs5 = require("fs");
4598
- var import_chalk8 = __toESM(require("chalk"));
5339
+ var import_node_fs7 = require("fs");
5340
+ var import_chalk7 = __toESM(require("chalk"));
4599
5341
  function getFirstIp(server) {
4600
5342
  for (const list of Object.values(server.addresses)) {
4601
5343
  for (const addr of list) {
@@ -4618,9 +5360,9 @@ var createCommand3 = new import_commander27.Command("create").description("\uC77
4618
5360
  }
4619
5361
  let userDataBase64;
4620
5362
  if (opts.userData !== void 0) {
4621
- let stat;
5363
+ let stat2;
4622
5364
  try {
4623
- stat = (0, import_node_fs5.statSync)(opts.userData);
5365
+ stat2 = (0, import_node_fs7.statSync)(opts.userData);
4624
5366
  } catch (e) {
4625
5367
  const reason = e.code ?? (e instanceof Error ? e.message : String(e));
4626
5368
  throw new NhnCloudCliError(
@@ -4628,19 +5370,19 @@ var createCommand3 = new import_commander27.Command("create").description("\uC77
4628
5370
  EXIT_PARAM_ERROR
4629
5371
  );
4630
5372
  }
4631
- if (!stat.isFile()) {
5373
+ if (!stat2.isFile()) {
4632
5374
  throw new NhnCloudCliError(
4633
5375
  `--user-data \uAC00 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${opts.userData}`,
4634
5376
  EXIT_PARAM_ERROR
4635
5377
  );
4636
5378
  }
4637
- if (stat.size > 49149) {
5379
+ if (stat2.size > 49149) {
4638
5380
  throw new NhnCloudCliError(
4639
- `--user-data \uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat.size} \uBC14\uC774\uD2B8). base64 \uC778\uCF54\uB529 \uD6C4 65535 \uBC14\uC774\uD2B8 \uD55C\uB3C4\uB77C raw 49149 \uBC14\uC774\uD2B8\uAE4C\uC9C0\uB9CC \uD5C8\uC6A9\uB429\uB2C8\uB2E4.`,
5381
+ `--user-data \uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat2.size} \uBC14\uC774\uD2B8). base64 \uC778\uCF54\uB529 \uD6C4 65535 \uBC14\uC774\uD2B8 \uD55C\uB3C4\uB77C raw 49149 \uBC14\uC774\uD2B8\uAE4C\uC9C0\uB9CC \uD5C8\uC6A9\uB429\uB2C8\uB2E4.`,
4640
5382
  EXIT_PARAM_ERROR
4641
5383
  );
4642
5384
  }
4643
- const raw = (0, import_node_fs5.readFileSync)(opts.userData);
5385
+ const raw = (0, import_node_fs7.readFileSync)(opts.userData);
4644
5386
  userDataBase64 = raw.toString("base64");
4645
5387
  if (userDataBase64.length > 65535) {
4646
5388
  throw new NhnCloudCliError(
@@ -4689,7 +5431,7 @@ var createCommand3 = new import_commander27.Command("create").description("\uC77
4689
5431
  return;
4690
5432
  }
4691
5433
  if (opts.wait) {
4692
- process.stderr.write(import_chalk8.default.green(` IP: ${getIps3(server)}
5434
+ process.stderr.write(import_chalk7.default.green(` IP: ${getIps3(server)}
4693
5435
  `));
4694
5436
  }
4695
5437
  const rows = [
@@ -4710,7 +5452,7 @@ var createCommand3 = new import_commander27.Command("create").description("\uC77
4710
5452
 
4711
5453
  // src/commands/instance/delete.ts
4712
5454
  var import_commander28 = require("commander");
4713
- var import_chalk9 = __toESM(require("chalk"));
5455
+ var import_chalk8 = __toESM(require("chalk"));
4714
5456
  var deleteCommand2 = new import_commander28.Command("delete").description("\uC778\uC2A4\uD134\uC2A4\uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
4715
5457
  const opts = cmd.optsWithGlobals();
4716
5458
  const isTTY = process.stdin.isTTY;
@@ -4727,7 +5469,7 @@ var deleteCommand2 = new import_commander28.Command("delete").description("\uC77
4727
5469
  default: false
4728
5470
  });
4729
5471
  if (!ok) {
4730
- process.stderr.write(import_chalk9.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
5472
+ process.stderr.write(import_chalk8.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
4731
5473
  return;
4732
5474
  }
4733
5475
  }
@@ -4740,13 +5482,13 @@ var deleteCommand2 = new import_commander28.Command("delete").description("\uC77
4740
5482
  throw err;
4741
5483
  }
4742
5484
  stopSpinner(true);
4743
- process.stderr.write(import_chalk9.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
5485
+ process.stderr.write(import_chalk8.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
4744
5486
  `));
4745
5487
  });
4746
5488
 
4747
5489
  // src/commands/instance/power.ts
4748
5490
  var import_commander29 = require("commander");
4749
- var import_chalk10 = __toESM(require("chalk"));
5491
+ var import_chalk9 = __toESM(require("chalk"));
4750
5492
  var startCommand = new import_commander29.Command("start").description("\uC778\uC2A4\uD134\uC2A4\uB97C \uC2DC\uC791\uD55C\uB2E4 (SHUTOFF \u2192 ACTIVE)").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
4751
5493
  const opts = cmd.optsWithGlobals();
4752
5494
  const { client } = await resolveInstanceClient(opts);
@@ -4758,7 +5500,7 @@ var startCommand = new import_commander29.Command("start").description("\uC778\u
4758
5500
  throw err;
4759
5501
  }
4760
5502
  stopSpinner(true);
4761
- process.stderr.write(import_chalk10.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uC2DC\uC791\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 ACTIVE).
5503
+ process.stderr.write(import_chalk9.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uC2DC\uC791\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 ACTIVE).
4762
5504
  `));
4763
5505
  });
4764
5506
  var stopCommand = new import_commander29.Command("stop").description("\uC778\uC2A4\uD134\uC2A4\uB97C \uC815\uC9C0\uD55C\uB2E4 (ACTIVE/ERROR \u2192 SHUTOFF)").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
@@ -4772,7 +5514,7 @@ var stopCommand = new import_commander29.Command("stop").description("\uC778\uC2
4772
5514
  throw err;
4773
5515
  }
4774
5516
  stopSpinner(true);
4775
- process.stderr.write(import_chalk10.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uC815\uC9C0\uB97C \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 SHUTOFF).
5517
+ process.stderr.write(import_chalk9.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uC815\uC9C0\uB97C \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 SHUTOFF).
4776
5518
  `));
4777
5519
  });
4778
5520
  var rebootCommand = new import_commander29.Command("reboot").description("\uC778\uC2A4\uD134\uC2A4\uB97C \uC7AC\uBD80\uD305\uD55C\uB2E4 (\uAE30\uBCF8 SOFT, --hard \uB85C HARD)").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").option("--hard", "HARD \uC7AC\uBD80\uD305 (\uAC15\uC81C \uC804\uC6D0 cycle, \uAE30\uBCF8\uC740 SOFT)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
@@ -4787,13 +5529,13 @@ var rebootCommand = new import_commander29.Command("reboot").description("\uC778
4787
5529
  throw err;
4788
5530
  }
4789
5531
  stopSpinner(true);
4790
- process.stderr.write(import_chalk10.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" ${type} \uC7AC\uBD80\uD305\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4.
5532
+ process.stderr.write(import_chalk9.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" ${type} \uC7AC\uBD80\uD305\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4.
4791
5533
  `));
4792
5534
  });
4793
5535
 
4794
5536
  // src/commands/instance/resize.ts
4795
5537
  var import_commander30 = require("commander");
4796
- var import_chalk11 = __toESM(require("chalk"));
5538
+ var import_chalk10 = __toESM(require("chalk"));
4797
5539
  var resizeCommand = new import_commander30.Command("resize").description("\uC778\uC2A4\uD134\uC2A4 \uD0C0\uC785(flavor)\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").requiredOption("--flavor <id>", "\uBCC0\uACBD\uD560 flavor ID (instance flavors \uB85C \uD6C4\uBCF4 \uC870\uD68C)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
4798
5540
  const opts = cmd.optsWithGlobals();
4799
5541
  const { client } = await resolveInstanceClient(opts);
@@ -4806,7 +5548,7 @@ var resizeCommand = new import_commander30.Command("resize").description("\uC778
4806
5548
  }
4807
5549
  stopSpinner(true);
4808
5550
  process.stderr.write(
4809
- import_chalk11.default.green(
5551
+ import_chalk10.default.green(
4810
5552
  `\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" \uD0C0\uC785 \uBCC0\uACBD(flavor: ${opts.flavor}) \uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 VERIFY_RESIZE, instance get \uC73C\uB85C \uD655\uC778 \uD6C4 resize-confirm/resize-revert).
4811
5553
  `
4812
5554
  )
@@ -4823,7 +5565,7 @@ var resizeConfirmCommand = new import_commander30.Command("resize-confirm").desc
4823
5565
  throw err;
4824
5566
  }
4825
5567
  stopSpinner(true);
4826
- process.stderr.write(import_chalk11.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" resize \uD655\uC815\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 ACTIVE).
5568
+ process.stderr.write(import_chalk10.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" resize \uD655\uC815\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\u2192 ACTIVE).
4827
5569
  `));
4828
5570
  });
4829
5571
  var resizeRevertCommand = new import_commander30.Command("resize-revert").description("resize \uB97C \uB864\uBC31\uD55C\uB2E4 (VERIFY_RESIZE \u2192 ACTIVE, \uC774\uC804 flavor \uB85C \uBCF5\uADC0)").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
@@ -4838,7 +5580,7 @@ var resizeRevertCommand = new import_commander30.Command("resize-revert").descri
4838
5580
  }
4839
5581
  stopSpinner(true);
4840
5582
  process.stderr.write(
4841
- import_chalk11.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" resize \uB864\uBC31\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\uC774\uC804 flavor \uB85C \uBCF5\uADC0).
5583
+ import_chalk10.default.green(`\u2713 \uC778\uC2A4\uD134\uC2A4 "${id}" resize \uB864\uBC31\uC744 \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4 (\uC774\uC804 flavor \uB85C \uBCF5\uADC0).
4842
5584
  `)
4843
5585
  );
4844
5586
  });
@@ -4917,13 +5659,13 @@ var keypairsCommand = new import_commander32.Command("keypairs").description("\u
4917
5659
 
4918
5660
  // src/commands/instance/keypair.ts
4919
5661
  var import_commander33 = require("commander");
4920
- var import_node_fs6 = require("fs");
4921
- var import_node_crypto3 = require("crypto");
4922
- var import_chalk12 = __toESM(require("chalk"));
5662
+ var import_node_fs8 = require("fs");
5663
+ var import_node_crypto5 = require("crypto");
5664
+ var import_chalk11 = __toESM(require("chalk"));
4923
5665
  function resolvePublicKey(value) {
4924
- let stat;
5666
+ let stat2;
4925
5667
  try {
4926
- stat = (0, import_node_fs6.statSync)(value);
5668
+ stat2 = (0, import_node_fs8.statSync)(value);
4927
5669
  } catch (e) {
4928
5670
  const err = e;
4929
5671
  if (err.code && err.code !== "ENOENT") {
@@ -4934,22 +5676,22 @@ function resolvePublicKey(value) {
4934
5676
  }
4935
5677
  return value;
4936
5678
  }
4937
- if (!stat.isFile()) {
5679
+ if (!stat2.isFile()) {
4938
5680
  throw new NhnCloudCliError(`--public-key \uAC00 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${value}`, EXIT_PARAM_ERROR);
4939
5681
  }
4940
- return (0, import_node_fs6.readFileSync)(value, "utf-8").trim();
5682
+ return (0, import_node_fs8.readFileSync)(value, "utf-8").trim();
4941
5683
  }
4942
5684
  function savePrivateKey(filePath, privateKey) {
4943
- const tmp = `${filePath}.${(0, import_node_crypto3.randomBytes)(4).toString("hex")}.tmp`;
5685
+ const tmp = `${filePath}.${(0, import_node_crypto5.randomBytes)(4).toString("hex")}.tmp`;
4944
5686
  const content = privateKey.endsWith("\n") ? privateKey : privateKey + "\n";
4945
5687
  try {
4946
- (0, import_node_fs6.writeFileSync)(tmp, content, { encoding: "utf-8", mode: 384 });
4947
- (0, import_node_fs6.renameSync)(tmp, filePath);
5688
+ (0, import_node_fs8.writeFileSync)(tmp, content, { encoding: "utf-8", mode: 384 });
5689
+ (0, import_node_fs8.renameSync)(tmp, filePath);
4948
5690
  } catch (e) {
4949
5691
  const reason = e.code ?? (e instanceof Error ? e.message : String(e));
4950
5692
  let tmpNote = "";
4951
5693
  try {
4952
- (0, import_node_fs6.unlinkSync)(tmp);
5694
+ (0, import_node_fs8.unlinkSync)(tmp);
4953
5695
  } catch {
4954
5696
  tmpNote = ` \u2014 0600 \uC784\uC2DC \uD30C\uC77C\uC774 \uB0A8\uC558\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4: ${tmp}`;
4955
5697
  }
@@ -5013,19 +5755,19 @@ var createKeypairCmd = new import_commander33.Command("create").description("\uD
5013
5755
  if (opts.output !== void 0) {
5014
5756
  try {
5015
5757
  savePrivateKey(opts.output, result.private_key);
5016
- process.stderr.write(import_chalk12.default.green(` private_key \uB97C ${opts.output} \uC5D0 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4 (mode 0600).
5758
+ process.stderr.write(import_chalk11.default.green(` private_key \uB97C ${opts.output} \uC5D0 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4 (mode 0600).
5017
5759
  `));
5018
5760
  } catch (saveErr) {
5019
5761
  const reason = saveErr instanceof Error ? saveErr.message : String(saveErr);
5020
5762
  process.stderr.write(
5021
- import_chalk12.default.red(` \u26A0 private_key \uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328 (${reason}). \uC720\uC2E4 \uBC29\uC9C0\uB97C \uC704\uD574 \uC544\uB798\uC5D0 \uCD9C\uB825\uD569\uB2C8\uB2E4 \u2014 \uC989\uC2DC \uC548\uC804\uD55C \uACF3\uC5D0 \uBCF4\uAD00\uD558\uC138\uC694.
5763
+ import_chalk11.default.red(` \u26A0 private_key \uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328 (${reason}). \uC720\uC2E4 \uBC29\uC9C0\uB97C \uC704\uD574 \uC544\uB798\uC5D0 \uCD9C\uB825\uD569\uB2C8\uB2E4 \u2014 \uC989\uC2DC \uC548\uC804\uD55C \uACF3\uC5D0 \uBCF4\uAD00\uD558\uC138\uC694.
5022
5764
  `)
5023
5765
  );
5024
5766
  process.stdout.write(result.private_key + "\n");
5025
5767
  }
5026
5768
  } else {
5027
5769
  process.stderr.write(
5028
- import_chalk12.default.yellow(" \u26A0 private_key \uB294 \uC9C0\uAE08 \uD55C \uBC88\uB9CC \uD45C\uC2DC\uB429\uB2C8\uB2E4. \uBD84\uC2E4 \uC2DC \uBCF5\uAD6C \uBD88\uAC00 \u2014 \uC548\uC804\uD55C \uACF3\uC5D0 \uBCF4\uAD00\uD558\uC138\uC694.\n")
5770
+ import_chalk11.default.yellow(" \u26A0 private_key \uB294 \uC9C0\uAE08 \uD55C \uBC88\uB9CC \uD45C\uC2DC\uB429\uB2C8\uB2E4. \uBD84\uC2E4 \uC2DC \uBCF5\uAD6C \uBD88\uAC00 \u2014 \uC548\uC804\uD55C \uACF3\uC5D0 \uBCF4\uAD00\uD558\uC138\uC694.\n")
5029
5771
  );
5030
5772
  process.stdout.write(result.private_key + "\n");
5031
5773
  }
@@ -5054,14 +5796,14 @@ var deleteKeypairCmd = new import_commander33.Command("delete").description("\uD
5054
5796
  throw err;
5055
5797
  }
5056
5798
  stopSpinner(true);
5057
- process.stderr.write(import_chalk12.default.green(`\u2713 \uD0A4\uD398\uC5B4 "${name}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
5799
+ process.stderr.write(import_chalk11.default.green(`\u2713 \uD0A4\uD398\uC5B4 "${name}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
5058
5800
  `));
5059
5801
  });
5060
5802
  var keypairCommand = new import_commander33.Command("keypair").description("\uD0A4\uD398\uC5B4 \uB2E8\uAC74 \uAD00\uB9AC (get / create / delete)").addCommand(getKeypairCmd).addCommand(createKeypairCmd).addCommand(deleteKeypairCmd);
5061
5803
 
5062
5804
  // src/commands/instance/volume.ts
5063
5805
  var import_commander34 = require("commander");
5064
- var import_chalk13 = __toESM(require("chalk"));
5806
+ var import_chalk12 = __toESM(require("chalk"));
5065
5807
  var attachCommand = new import_commander34.Command("attach").description("\uBCFC\uB968\uC744 \uC778\uC2A4\uD134\uC2A4\uC5D0 \uC5F0\uACB0\uD55C\uB2E4").argument("<id>", "\uC778\uC2A4\uD134\uC2A4 ID").requiredOption("--volume <volumeId>", "\uC5F0\uACB0\uD560 \uBCFC\uB968 ID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
5066
5808
  const opts = cmd.optsWithGlobals();
5067
5809
  const { client } = await resolveInstanceClient(opts);
@@ -5075,7 +5817,7 @@ var attachCommand = new import_commander34.Command("attach").description("\uBCFC
5075
5817
  }
5076
5818
  stopSpinner(true);
5077
5819
  process.stderr.write(
5078
- import_chalk13.default.green(`\uBCFC\uB968 \uC5F0\uACB0 \uC644\uB8CC (volumeId: ${att.volumeId}, device: ${att.device})
5820
+ import_chalk12.default.green(`\uBCFC\uB968 \uC5F0\uACB0 \uC644\uB8CC (volumeId: ${att.volumeId}, device: ${att.device})
5079
5821
  `)
5080
5822
  );
5081
5823
  output(opts, {
@@ -5102,7 +5844,7 @@ var detachCommand = new import_commander34.Command("detach").description("\uBCFC
5102
5844
  }
5103
5845
  stopSpinner(true);
5104
5846
  process.stderr.write(
5105
- import_chalk13.default.green(`\uBCFC\uB968 \uC5F0\uACB0 \uD574\uC81C \uC694\uCCAD \uC644\uB8CC (volumeId: ${volumeId})
5847
+ import_chalk12.default.green(`\uBCFC\uB968 \uC5F0\uACB0 \uD574\uC81C \uC694\uCCAD \uC644\uB8CC (volumeId: ${volumeId})
5106
5848
  `)
5107
5849
  );
5108
5850
  });
@@ -5139,7 +5881,6 @@ var import_commander36 = require("commander");
5139
5881
 
5140
5882
  // src/services/ncr/harbor-client.ts
5141
5883
  var import_ky11 = __toESM(require("ky"));
5142
- var DEFAULT_TIMEOUT_MS7 = 3e4;
5143
5884
  var PAGE_SIZE = 100;
5144
5885
  var MAX_PAGES = 1e3;
5145
5886
  var HarborClient = class {
@@ -5162,16 +5903,16 @@ var HarborClient = class {
5162
5903
  * ky.get() 이 Response 를 반환하므로 .json() 과 .headers.get("link") 를 함께 사용한다
5163
5904
  * (체이닝하면 헤더를 못 본다 — 기존 NCR client 의 .json<T>() 체이닝 패턴과 다름).
5164
5905
  */
5165
- async getAllPages(path3) {
5906
+ async getAllPages(path5) {
5166
5907
  const acc = [];
5167
5908
  let page = 1;
5168
5909
  try {
5169
5910
  for (; ; ) {
5170
- const url = `https://${this.host}${path3}?page=${page}&page_size=${PAGE_SIZE}`;
5911
+ const url = `https://${this.host}${path5}?page=${page}&page_size=${PAGE_SIZE}`;
5171
5912
  const res = await import_ky11.default.get(url, {
5172
5913
  headers: this.basicAuthHeaders(),
5173
5914
  retry: 0,
5174
- timeout: DEFAULT_TIMEOUT_MS7
5915
+ timeout: DEFAULT_TIMEOUT_MS
5175
5916
  });
5176
5917
  const data = await res.json();
5177
5918
  if (!Array.isArray(data)) {
@@ -5417,15 +6158,15 @@ function commandPath(command) {
5417
6158
  return names.join(" ");
5418
6159
  }
5419
6160
  function collectCommand(command) {
5420
- const path3 = commandPath(command);
5421
- if (!path3 || path3 === "help") return null;
6161
+ const path5 = commandPath(command);
6162
+ if (!path5 || path5 === "help") return null;
5422
6163
  return {
5423
- path: path3,
6164
+ path: path5,
5424
6165
  description: command.description() || command.summary() || "",
5425
6166
  arguments: command.registeredArguments.map((arg) => arg.name()),
5426
6167
  options: command.options.filter((option) => !option.hidden).map((option) => option.flags),
5427
6168
  subcommands: command.commands.map((subcommand) => subcommand.name()).filter((name) => name !== "help"),
5428
- ...path3 === "commands" ? { metadata: true } : {}
6169
+ ...path5 === "commands" ? { metadata: true } : {}
5429
6170
  };
5430
6171
  }
5431
6172
  function collectCommandCatalog(program2) {
@@ -5464,7 +6205,7 @@ function createCommandsCommand(program2) {
5464
6205
  var import_commander41 = require("commander");
5465
6206
 
5466
6207
  // src/commands/nks/helpers.ts
5467
- var import_promises7 = require("fs/promises");
6208
+ var import_promises6 = require("fs/promises");
5468
6209
 
5469
6210
  // src/services/nks/client.ts
5470
6211
  var import_ky12 = __toESM(require("ky"));
@@ -5527,7 +6268,6 @@ function isNksUuidResponse(val) {
5527
6268
  }
5528
6269
 
5529
6270
  // src/services/nks/client.ts
5530
- var DEFAULT_TIMEOUT_MS8 = 3e4;
5531
6271
  function isArrayFieldResponse(key, val, itemGuard) {
5532
6272
  if (typeof val !== "object" || val === null) return false;
5533
6273
  const field = val[key];
@@ -5573,7 +6313,7 @@ var NksClient = class {
5573
6313
  const raw = await import_ky12.default.get(url, {
5574
6314
  headers: this.authHeaders(),
5575
6315
  retry: 0,
5576
- timeout: DEFAULT_TIMEOUT_MS8
6316
+ timeout: DEFAULT_TIMEOUT_MS
5577
6317
  }).json();
5578
6318
  if (!isNksSupports(raw)) {
5579
6319
  throw new NhnCloudCliError(
@@ -5593,7 +6333,7 @@ var NksClient = class {
5593
6333
  const raw = await import_ky12.default.get(url, {
5594
6334
  headers: this.authHeaders(),
5595
6335
  retry: 0,
5596
- timeout: DEFAULT_TIMEOUT_MS8
6336
+ timeout: DEFAULT_TIMEOUT_MS
5597
6337
  }).json();
5598
6338
  if (!isClustersResponse(raw)) {
5599
6339
  throw new NhnCloudCliError(
@@ -5887,7 +6627,7 @@ var NksClient = class {
5887
6627
  async removeClusterAddon(cluster, addon) {
5888
6628
  const url = `${this.nksEndpoint}/clusters/${encodeURIComponent(cluster)}/addons/${encodeURIComponent(addon)}`;
5889
6629
  try {
5890
- const raw = await import_ky12.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS8 }).json();
6630
+ const raw = await import_ky12.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS }).json();
5891
6631
  if (!isNksUuidResponse(raw)) {
5892
6632
  throw new NhnCloudCliError(
5893
6633
  "nks cluster addon remove \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 uuid \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -5899,56 +6639,56 @@ var NksClient = class {
5899
6639
  throw toNhnCloudCliError(err);
5900
6640
  }
5901
6641
  }
5902
- async getNamedResourceArray(key, path3, errorMessage) {
5903
- const raw = await this.getJson(path3);
6642
+ async getNamedResourceArray(key, path5, errorMessage) {
6643
+ const raw = await this.getJson(path5);
5904
6644
  if (!isNamedResourceArrayResponse(key, raw)) {
5905
6645
  throw new NhnCloudCliError(errorMessage, EXIT_API_ERROR);
5906
6646
  }
5907
6647
  return raw[key];
5908
6648
  }
5909
- async getFlatNamedResource(path3, errorMessage) {
5910
- const raw = await this.getJson(path3);
6649
+ async getFlatNamedResource(path5, errorMessage) {
6650
+ const raw = await this.getJson(path5);
5911
6651
  if (!isNksNamedResource(raw)) {
5912
6652
  throw new NhnCloudCliError(errorMessage, EXIT_API_ERROR);
5913
6653
  }
5914
6654
  return raw;
5915
6655
  }
5916
- async getJson(path3, searchParams) {
5917
- const url = `${this.nksEndpoint}${path3}`;
6656
+ async getJson(path5, searchParams) {
6657
+ const url = `${this.nksEndpoint}${path5}`;
5918
6658
  try {
5919
6659
  return await import_ky12.default.get(url, {
5920
6660
  headers: this.authHeaders(),
5921
6661
  searchParams,
5922
6662
  retry: 0,
5923
- timeout: DEFAULT_TIMEOUT_MS8
6663
+ timeout: DEFAULT_TIMEOUT_MS
5924
6664
  }).json();
5925
6665
  } catch (err) {
5926
6666
  throw toNhnCloudCliError(err);
5927
6667
  }
5928
6668
  }
5929
- async requestUuid(method, path3, payload, errorMessage) {
5930
- const raw = await this.requestJson(method, path3, payload);
6669
+ async requestUuid(method, path5, payload, errorMessage) {
6670
+ const raw = await this.requestJson(method, path5, payload);
5931
6671
  if (!isNksUuidResponse(raw)) {
5932
6672
  throw new NhnCloudCliError(errorMessage, EXIT_API_ERROR);
5933
6673
  }
5934
6674
  return raw;
5935
6675
  }
5936
- async requestNoBody(method, path3, payload) {
5937
- const url = `${this.nksEndpoint}${path3}`;
6676
+ async requestNoBody(method, path5, payload) {
6677
+ const url = `${this.nksEndpoint}${path5}`;
5938
6678
  try {
5939
6679
  if (method === "delete") {
5940
- await import_ky12.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS8 });
6680
+ await import_ky12.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS });
5941
6681
  return;
5942
6682
  }
5943
- await import_ky12.default.post(url, { headers: this.authHeaders(), json: payload, retry: 0, timeout: DEFAULT_TIMEOUT_MS8 });
6683
+ await import_ky12.default.post(url, { headers: this.authHeaders(), json: payload, retry: 0, timeout: DEFAULT_TIMEOUT_MS });
5944
6684
  } catch (err) {
5945
6685
  throw toNhnCloudCliError(err);
5946
6686
  }
5947
6687
  }
5948
- async requestJson(method, path3, payload) {
5949
- const url = `${this.nksEndpoint}${path3}`;
6688
+ async requestJson(method, path5, payload) {
6689
+ const url = `${this.nksEndpoint}${path5}`;
5950
6690
  try {
5951
- const options = { headers: this.authHeaders(), json: payload, retry: 0, timeout: DEFAULT_TIMEOUT_MS8 };
6691
+ const options = { headers: this.authHeaders(), json: payload, retry: 0, timeout: DEFAULT_TIMEOUT_MS };
5952
6692
  return method === "post" ? await import_ky12.default.post(url, options).json() : await import_ky12.default.patch(url, options).json();
5953
6693
  } catch (err) {
5954
6694
  throw toNhnCloudCliError(err);
@@ -5969,13 +6709,13 @@ async function resolveNksClient(opts) {
5969
6709
  const { profileName, tokenId, nksEndpoint } = await resolveIaasTokenContext(opts);
5970
6710
  return { client: new NksClient(tokenId, nksEndpoint), profileName };
5971
6711
  }
5972
- async function readJsonFile(path3) {
6712
+ async function readJsonFile(path5) {
5973
6713
  let raw;
5974
6714
  try {
5975
- raw = await (0, import_promises7.readFile)(path3, "utf-8");
6715
+ raw = await (0, import_promises6.readFile)(path5, "utf-8");
5976
6716
  } catch (err) {
5977
6717
  const message = err instanceof Error ? err.message : String(err);
5978
- throw new NhnCloudCliError(`JSON \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path3} (${message})`, EXIT_PARAM_ERROR);
6718
+ throw new NhnCloudCliError(`JSON \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path5} (${message})`, EXIT_PARAM_ERROR);
5979
6719
  }
5980
6720
  try {
5981
6721
  const parsed = JSON.parse(raw);
@@ -5985,15 +6725,15 @@ async function readJsonFile(path3) {
5985
6725
  return parsed;
5986
6726
  } catch (err) {
5987
6727
  const message = err instanceof Error ? err.message : String(err);
5988
- throw new NhnCloudCliError(`JSON \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${path3} (${message})`, EXIT_PARAM_ERROR);
6728
+ throw new NhnCloudCliError(`JSON \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${path5} (${message})`, EXIT_PARAM_ERROR);
5989
6729
  }
5990
6730
  }
5991
- async function readTextFile(path3) {
6731
+ async function readTextFile(path5) {
5992
6732
  try {
5993
- return await (0, import_promises7.readFile)(path3, "utf-8");
6733
+ return await (0, import_promises6.readFile)(path5, "utf-8");
5994
6734
  } catch (err) {
5995
6735
  const message = err instanceof Error ? err.message : String(err);
5996
- throw new NhnCloudCliError(`\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path3} (${message})`, EXIT_PARAM_ERROR);
6736
+ throw new NhnCloudCliError(`\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path5} (${message})`, EXIT_PARAM_ERROR);
5997
6737
  }
5998
6738
  }
5999
6739
  function parsePositiveInteger(value, optionName) {
@@ -6034,9 +6774,9 @@ var supportsCommand = new import_commander41.Command("supports").description("NK
6034
6774
  });
6035
6775
 
6036
6776
  // src/commands/nks/cluster.ts
6037
- var import_promises8 = require("fs/promises");
6777
+ var import_promises7 = require("fs/promises");
6038
6778
  var import_commander42 = require("commander");
6039
- var import_chalk14 = __toESM(require("chalk"));
6779
+ var import_chalk13 = __toESM(require("chalk"));
6040
6780
  var listCommand6 = new import_commander42.Command("list").description("NKS \uD074\uB7EC\uC2A4\uD130 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
6041
6781
  const opts = cmd.optsWithGlobals();
6042
6782
  const { client } = await resolveNksClient(opts);
@@ -6090,7 +6830,7 @@ function clusterIpAclRow(ipAcl) {
6090
6830
  ];
6091
6831
  }
6092
6832
  function uuidOutput(opts, result, label) {
6093
- process.stderr.write(import_chalk14.default.green(`\u2713 ${label} \uC694\uCCAD \uC644\uB8CC (uuid: ${result.uuid})
6833
+ process.stderr.write(import_chalk13.default.green(`\u2713 ${label} \uC694\uCCAD \uC644\uB8CC (uuid: ${result.uuid})
6094
6834
  `));
6095
6835
  output(opts, {
6096
6836
  headers: ["field", "value"],
@@ -6111,22 +6851,22 @@ async function confirmDangerousAction(message, yes) {
6111
6851
  const { confirm } = await import("@inquirer/prompts");
6112
6852
  const ok = await confirm({ message, default: false });
6113
6853
  if (!ok) {
6114
- process.stderr.write(import_chalk14.default.yellow("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
6854
+ process.stderr.write(import_chalk13.default.yellow("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
6115
6855
  }
6116
6856
  return ok;
6117
6857
  }
6118
- async function writeKubeconfigFile(path3, contents, force) {
6858
+ async function writeKubeconfigFile(path5, contents, force) {
6119
6859
  try {
6120
- await (0, import_promises8.writeFile)(path3, contents, {
6860
+ await (0, import_promises7.writeFile)(path5, contents, {
6121
6861
  encoding: "utf-8",
6122
6862
  mode: 384,
6123
6863
  flag: force ? "w" : "wx"
6124
6864
  });
6125
- await (0, import_promises8.chmod)(path3, 384);
6865
+ await (0, import_promises7.chmod)(path5, 384);
6126
6866
  } catch (err) {
6127
6867
  if (err instanceof Error && "code" in err && err.code === "EEXIST") {
6128
6868
  throw new NhnCloudCliError(
6129
- `\uD30C\uC77C\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path3}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC9C0\uC815\uD558\uC138\uC694.`,
6869
+ `\uD30C\uC77C\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path5}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC9C0\uC815\uD558\uC138\uC694.`,
6130
6870
  EXIT_PARAM_ERROR
6131
6871
  );
6132
6872
  }
@@ -6161,7 +6901,7 @@ var deleteCommand3 = new import_commander42.Command("delete").description("NKS \
6161
6901
  throw err;
6162
6902
  }
6163
6903
  stopSpinner(true);
6164
- process.stderr.write(import_chalk14.default.green(`\u2713 NKS \uD074\uB7EC\uC2A4\uD130 "${cluster}" \uC0AD\uC81C \uC694\uCCAD \uC644\uB8CC
6904
+ process.stderr.write(import_chalk13.default.green(`\u2713 NKS \uD074\uB7EC\uC2A4\uD130 "${cluster}" \uC0AD\uC81C \uC694\uCCAD \uC644\uB8CC
6165
6905
  `));
6166
6906
  });
6167
6907
  var resizeCommand2 = new import_commander42.Command("resize").description("NKS \uD074\uB7EC\uC2A4\uD130 \uB178\uB4DC \uADF8\uB8F9 \uD06C\uAE30\uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--nodegroup <name-or-uuid>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--node-count <n>", "\uBCC0\uACBD\uD560 \uB178\uB4DC \uC218").option("--nodes-to-remove <csv>", "\uC0AD\uC81C\uD560 \uB178\uB4DC \uC774\uB984/ID CSV").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (cluster, _opts, cmd) => {
@@ -6169,7 +6909,7 @@ var resizeCommand2 = new import_commander42.Command("resize").description("NKS \
6169
6909
  const nodeCount = parsePositiveInteger(opts.nodeCount, "--node-count");
6170
6910
  const nodesToRemove = opts.nodesToRemove?.split(",").map((node) => node.trim()).filter(Boolean);
6171
6911
  if (!nodesToRemove || nodesToRemove.length === 0) {
6172
- process.stderr.write(import_chalk14.default.yellow("\uC8FC\uC758: --nodes-to-remove \uAC00 \uC5C6\uC73C\uBA74 \uAC10\uCD95 \uC2DC API\uAC00 \uC0AD\uC81C \uB178\uB4DC\uB97C \uC120\uD0DD\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
6912
+ process.stderr.write(import_chalk13.default.yellow("\uC8FC\uC758: --nodes-to-remove \uAC00 \uC5C6\uC73C\uBA74 \uAC10\uCD95 \uC2DC API\uAC00 \uC0AD\uC81C \uB178\uB4DC\uB97C \uC120\uD0DD\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n"));
6173
6913
  }
6174
6914
  const { client } = await resolveNksClient(opts);
6175
6915
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 resize \uC694\uCCAD \uC911...");
@@ -6321,7 +7061,7 @@ var kubeconfigCommand = new import_commander42.Command("kubeconfig").description
6321
7061
  stopSpinner(true);
6322
7062
  if (opts.output) {
6323
7063
  await writeKubeconfigFile(opts.output, kubeconfig, opts.force);
6324
- process.stderr.write(import_chalk14.default.green(`\u2713 kubeconfig \uB97C \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4: ${opts.output}
7064
+ process.stderr.write(import_chalk13.default.green(`\u2713 kubeconfig \uB97C \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4: ${opts.output}
6325
7065
  `));
6326
7066
  return;
6327
7067
  }
@@ -6451,7 +7191,7 @@ var clusterCommand = new import_commander42.Command("cluster").description("NKS
6451
7191
 
6452
7192
  // src/commands/nks/nodegroup.ts
6453
7193
  var import_commander43 = require("commander");
6454
- var import_chalk15 = __toESM(require("chalk"));
7194
+ var import_chalk14 = __toESM(require("chalk"));
6455
7195
  function nodeGroupRow(nodegroup) {
6456
7196
  return [
6457
7197
  nodegroup.uuid,
@@ -6468,7 +7208,7 @@ function rawObjectRows(resource) {
6468
7208
  ]);
6469
7209
  }
6470
7210
  function uuidOutput2(opts, result, label) {
6471
- process.stderr.write(import_chalk15.default.green(`\u2713 ${label} \uC694\uCCAD \uC644\uB8CC (uuid: ${result.uuid})
7211
+ process.stderr.write(import_chalk14.default.green(`\u2713 ${label} \uC694\uCCAD \uC644\uB8CC (uuid: ${result.uuid})
6472
7212
  `));
6473
7213
  output(opts, {
6474
7214
  headers: ["field", "value"],
@@ -6501,7 +7241,7 @@ async function confirmDangerousAction2(message, yes) {
6501
7241
  if (!isTTY || yes) return true;
6502
7242
  const { confirm } = await import("@inquirer/prompts");
6503
7243
  const ok = await confirm({ message, default: false });
6504
- if (!ok) process.stderr.write(import_chalk15.default.yellow("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7244
+ if (!ok) process.stderr.write(import_chalk14.default.yellow("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
6505
7245
  return ok;
6506
7246
  }
6507
7247
  var listCommand7 = new import_commander43.Command("list").description("NKS \uB178\uB4DC \uADF8\uB8F9 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (cluster, _opts, cmd) => {
@@ -6570,7 +7310,7 @@ var deleteCommand4 = new import_commander43.Command("delete").description("NKS \
6570
7310
  throw err;
6571
7311
  }
6572
7312
  stopSpinner(true);
6573
- process.stderr.write(import_chalk15.default.green(`\u2713 NKS \uB178\uB4DC \uADF8\uB8F9 "${nodegroup}" \uC0AD\uC81C \uC694\uCCAD \uC644\uB8CC
7313
+ process.stderr.write(import_chalk14.default.green(`\u2713 NKS \uB178\uB4DC \uADF8\uB8F9 "${nodegroup}" \uC0AD\uC81C \uC694\uCCAD \uC644\uB8CC
6574
7314
  `));
6575
7315
  });
6576
7316
  function nodeActionCommand(name) {
@@ -6811,10 +7551,10 @@ var addonCommand = new import_commander44.Command("addon").description("NKS \uC5
6811
7551
 
6812
7552
  // src/commands/ncs/template.ts
6813
7553
  var import_commander45 = require("commander");
6814
- var import_chalk16 = __toESM(require("chalk"));
7554
+ var import_chalk15 = __toESM(require("chalk"));
6815
7555
 
6816
7556
  // src/commands/ncs/helpers.ts
6817
- var import_node_fs7 = require("fs");
7557
+ var import_node_fs9 = require("fs");
6818
7558
  var MAX_JSON_PAYLOAD_BYTES = 1e6;
6819
7559
  var NCS_RFC3339_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|([+-])(\d{2}):(\d{2}))$/;
6820
7560
  var NCS_RELATIVE_TIME_PATTERN = /^(\d+)(m|h|d)$/;
@@ -6939,9 +7679,9 @@ async function resolveNcsClient(opts) {
6939
7679
  return { client: new NcsClient(accessToken, region, appKey), profileName };
6940
7680
  }
6941
7681
  function readJsonPayload(filePath) {
6942
- let stat;
7682
+ let stat2;
6943
7683
  try {
6944
- stat = (0, import_node_fs7.statSync)(filePath);
7684
+ stat2 = (0, import_node_fs9.statSync)(filePath);
6945
7685
  } catch (err) {
6946
7686
  const reason = err.code ?? (err instanceof Error ? err.message : String(err));
6947
7687
  throw new NhnCloudCliError(
@@ -6949,16 +7689,16 @@ function readJsonPayload(filePath) {
6949
7689
  EXIT_PARAM_ERROR
6950
7690
  );
6951
7691
  }
6952
- if (!stat.isFile()) {
7692
+ if (!stat2.isFile()) {
6953
7693
  throw new NhnCloudCliError(`--file \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
6954
7694
  }
6955
- if (stat.size > MAX_JSON_PAYLOAD_BYTES) {
7695
+ if (stat2.size > MAX_JSON_PAYLOAD_BYTES) {
6956
7696
  throw new NhnCloudCliError(
6957
- `--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat.size} \uBC14\uC774\uD2B8). JSON spec \uD55C\uB3C4 ${MAX_JSON_PAYLOAD_BYTES} \uBC14\uC774\uD2B8.`,
7697
+ `--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat2.size} \uBC14\uC774\uD2B8). JSON spec \uD55C\uB3C4 ${MAX_JSON_PAYLOAD_BYTES} \uBC14\uC774\uD2B8.`,
6958
7698
  EXIT_PARAM_ERROR
6959
7699
  );
6960
7700
  }
6961
- const raw = (0, import_node_fs7.readFileSync)(filePath, "utf-8");
7701
+ const raw = (0, import_node_fs9.readFileSync)(filePath, "utf-8");
6962
7702
  try {
6963
7703
  return JSON.parse(raw);
6964
7704
  } catch (err) {
@@ -7082,7 +7822,7 @@ var deleteCommand5 = new import_commander45.Command("delete").description("NCS \
7082
7822
  requireNonEmpty(id, "id");
7083
7823
  const ok = await confirmDestructive(`NCS \uC124\uACC4\uB3C4 "${id}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
7084
7824
  if (!ok) {
7085
- process.stderr.write(import_chalk16.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7825
+ process.stderr.write(import_chalk15.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7086
7826
  return;
7087
7827
  }
7088
7828
  const { client } = await resolveNcsClient(opts);
@@ -7094,7 +7834,7 @@ var deleteCommand5 = new import_commander45.Command("delete").description("NCS \
7094
7834
  throw err;
7095
7835
  }
7096
7836
  stopSpinner(true);
7097
- process.stderr.write(import_chalk16.default.green(`\u2713 NCS \uC124\uACC4\uB3C4 "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7837
+ process.stderr.write(import_chalk15.default.green(`\u2713 NCS \uC124\uACC4\uB3C4 "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7098
7838
  `));
7099
7839
  });
7100
7840
  var versionListCommand = new import_commander45.Command("list").description("NCS \uC124\uACC4\uB3C4(template) \uC758 \uBC84\uC804 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "template ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--q <query>", "\uAC80\uC0C9\uC5B4").option("--sort <sort>", "\uC815\uB82C \uC870\uAC74").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 10)").action(async (id, _opts, cmd) => {
@@ -7181,7 +7921,7 @@ var versionDeleteCommand = new import_commander45.Command("delete").description(
7181
7921
  opts.yes
7182
7922
  );
7183
7923
  if (!ok) {
7184
- process.stderr.write(import_chalk16.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7924
+ process.stderr.write(import_chalk15.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7185
7925
  return;
7186
7926
  }
7187
7927
  const { client } = await resolveNcsClient(opts);
@@ -7194,7 +7934,7 @@ var versionDeleteCommand = new import_commander45.Command("delete").description(
7194
7934
  }
7195
7935
  stopSpinner(true);
7196
7936
  process.stderr.write(
7197
- import_chalk16.default.green(`\u2713 NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 "${version}" \uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7937
+ import_chalk15.default.green(`\u2713 NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 "${version}" \uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7198
7938
  `)
7199
7939
  );
7200
7940
  });
@@ -7203,7 +7943,7 @@ var templateCommand = new import_commander45.Command("template").description("NC
7203
7943
 
7204
7944
  // src/commands/ncs/workload.ts
7205
7945
  var import_commander46 = require("commander");
7206
- var import_chalk17 = __toESM(require("chalk"));
7946
+ var import_chalk16 = __toESM(require("chalk"));
7207
7947
  function workloadRows(w) {
7208
7948
  return [
7209
7949
  [
@@ -7444,254 +8184,1029 @@ var scheduleHistoryCommand = new import_commander46.Command("schedule-history").
7444
8184
  }
7445
8185
  stopSpinner(true);
7446
8186
  output(opts, {
7447
- headers: ["id", "status", "createdAt", "finishedAt"],
7448
- rows: scheduleHistory.map((s) => [s.id, s.status, s.createdAt, s.finishedAt ?? ""]),
7449
- raw: { scheduleHistory },
7450
- ids: scheduleHistory.map((s) => s.id)
8187
+ headers: ["id", "status", "createdAt", "finishedAt"],
8188
+ rows: scheduleHistory.map((s) => [s.id, s.status, s.createdAt, s.finishedAt ?? ""]),
8189
+ raw: { scheduleHistory },
8190
+ ids: scheduleHistory.map((s) => s.id)
8191
+ });
8192
+ });
8193
+ var createCommand7 = new import_commander46.Command("create").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uB97C \uC0DD\uC131\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC)").requiredOption("--file <path>", "workload \uC0DD\uC131 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--wait", "workload \uAC00 Running \uC0C1\uD0DC\uAC00 \uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30").option("--timeout <sec>", "wait \uD0C0\uC784\uC544\uC6C3 (\uCD08, \uAE30\uBCF8 300)", "300").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
8194
+ const opts = cmd.optsWithGlobals();
8195
+ const payload = readJsonPayload(opts.file);
8196
+ const timeoutMs = parsePositiveIntegerOption(opts.timeout ?? "300", "--timeout") * 1e3;
8197
+ const { client } = await resolveNcsClient(opts);
8198
+ startSpinner("NCS workload \uC0DD\uC131 \uC911...");
8199
+ let workload;
8200
+ try {
8201
+ workload = await client.createWorkload(payload);
8202
+ } catch (err) {
8203
+ stopSpinner(false);
8204
+ throw err;
8205
+ }
8206
+ stopSpinner(true);
8207
+ if (opts.wait) {
8208
+ startSpinner(`NCS workload "${workload.id}" Running \uB300\uAE30 \uC911...`);
8209
+ try {
8210
+ workload = await client.waitForRunning(workload.id, { timeoutMs });
8211
+ } catch (err) {
8212
+ stopSpinner(false);
8213
+ throw err;
8214
+ }
8215
+ stopSpinner(true, `Running \uD655\uC778 (id: ${workload.id})`);
8216
+ }
8217
+ output(opts, {
8218
+ headers: WORKLOAD_HEADERS,
8219
+ rows: workloadRows(workload),
8220
+ raw: workload,
8221
+ ids: [workload.id]
8222
+ });
8223
+ });
8224
+ var updateCommand = new import_commander46.Command("update").description("NCS workload \uB97C \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC, PUT)").argument("<id>", "workload ID").requiredOption("--file <path>", "workload \uAD50\uCCB4 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
8225
+ const opts = cmd.optsWithGlobals();
8226
+ requireNonEmpty(id, "id");
8227
+ const payload = readJsonPayload(opts.file);
8228
+ const { client } = await resolveNcsClient(opts);
8229
+ startSpinner(`NCS workload "${id}" \uAD50\uCCB4 \uC911...`);
8230
+ let workload;
8231
+ try {
8232
+ workload = await client.updateWorkload(id, payload);
8233
+ } catch (err) {
8234
+ stopSpinner(false);
8235
+ throw err;
8236
+ }
8237
+ stopSpinner(true);
8238
+ output(opts, {
8239
+ headers: WORKLOAD_HEADERS,
8240
+ rows: workloadRows(workload),
8241
+ raw: workload,
8242
+ ids: [workload.id]
8243
+ });
8244
+ });
8245
+ var patchCommand = new import_commander46.Command("patch").description("NCS workload \uB97C \uBD80\uBD84 \uBCC0\uACBD\uD55C\uB2E4 (--file \uB85C JSON Patch \uBC30\uC5F4 \uC804\uB2EC, RFC 6902)").argument("<id>", "workload ID").requiredOption("--file <path>", "JSON Patch \uBC30\uC5F4(op/path/value)\uC774 \uB2F4\uAE34 \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
8246
+ const opts = cmd.optsWithGlobals();
8247
+ requireNonEmpty(id, "id");
8248
+ const payload = readJsonPayload(opts.file);
8249
+ const { client } = await resolveNcsClient(opts);
8250
+ startSpinner(`NCS workload "${id}" \uBD80\uBD84 \uBCC0\uACBD \uC911...`);
8251
+ let workload;
8252
+ try {
8253
+ workload = await client.patchWorkload(id, payload);
8254
+ } catch (err) {
8255
+ stopSpinner(false);
8256
+ throw err;
8257
+ }
8258
+ stopSpinner(true);
8259
+ output(opts, {
8260
+ headers: WORKLOAD_HEADERS,
8261
+ rows: workloadRows(workload),
8262
+ raw: workload,
8263
+ ids: [workload.id]
8264
+ });
8265
+ });
8266
+ var pauseCommand = new import_commander46.Command("pause").description("NCS workload \uB97C \uC77C\uC2DC\uC815\uC9C0\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
8267
+ const opts = cmd.optsWithGlobals();
8268
+ requireNonEmpty(id, "id");
8269
+ const { client } = await resolveNcsClient(opts);
8270
+ startSpinner(`NCS workload "${id}" \uC77C\uC2DC\uC815\uC9C0 \uC911...`);
8271
+ try {
8272
+ await client.pauseWorkload(id);
8273
+ } catch (err) {
8274
+ stopSpinner(false);
8275
+ throw err;
8276
+ }
8277
+ stopSpinner(true);
8278
+ process.stderr.write(import_chalk16.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC77C\uC2DC\uC815\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
8279
+ `));
8280
+ });
8281
+ var resumeCommand = new import_commander46.Command("resume").description("NCS workload \uB97C \uC7AC\uAC1C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
8282
+ const opts = cmd.optsWithGlobals();
8283
+ requireNonEmpty(id, "id");
8284
+ const { client } = await resolveNcsClient(opts);
8285
+ startSpinner(`NCS workload "${id}" \uC7AC\uAC1C \uC911...`);
8286
+ try {
8287
+ await client.resumeWorkload(id);
8288
+ } catch (err) {
8289
+ stopSpinner(false);
8290
+ throw err;
8291
+ }
8292
+ stopSpinner(true);
8293
+ process.stderr.write(import_chalk16.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC7AC\uAC1C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
8294
+ `));
8295
+ });
8296
+ var restartCommand = new import_commander46.Command("restart").description("NCS workload task \uB97C \uC7AC\uC2DC\uC791\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--task <taskId>", "task ID (\uD544\uC218)").action(async (id, _opts, cmd) => {
8297
+ const opts = cmd.optsWithGlobals();
8298
+ requireNonEmpty(id, "id");
8299
+ if (!opts.task || !opts.task.trim()) {
8300
+ throw new NhnCloudCliError(
8301
+ "--task \uC635\uC158\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. task ID \uB97C \uC9C0\uC815\uD558\uC138\uC694.",
8302
+ EXIT_PARAM_ERROR
8303
+ );
8304
+ }
8305
+ const { client } = await resolveNcsClient(opts);
8306
+ startSpinner(`NCS workload "${id}" task "${opts.task}" \uC7AC\uC2DC\uC791 \uC911...`);
8307
+ try {
8308
+ await client.restartWorkloadTask(id, opts.task);
8309
+ } catch (err) {
8310
+ stopSpinner(false);
8311
+ throw err;
8312
+ }
8313
+ stopSpinner(true);
8314
+ process.stderr.write(
8315
+ import_chalk16.default.green(`\u2713 NCS workload "${id}" task "${opts.task}" \uAC00 \uC7AC\uC2DC\uC791\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
8316
+ `)
8317
+ );
8318
+ });
8319
+ var deleteCommand6 = new import_commander46.Command("delete").description("NCS workload \uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "workload ID").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
8320
+ const opts = cmd.optsWithGlobals();
8321
+ requireNonEmpty(id, "id");
8322
+ const ok = await confirmDestructive(`NCS workload "${id}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
8323
+ if (!ok) {
8324
+ process.stderr.write(import_chalk16.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
8325
+ return;
8326
+ }
8327
+ const { client } = await resolveNcsClient(opts);
8328
+ startSpinner(`NCS workload \uC0AD\uC81C \uC911... (id: ${id})`);
8329
+ try {
8330
+ await client.deleteWorkload(id);
8331
+ } catch (err) {
8332
+ stopSpinner(false);
8333
+ throw err;
8334
+ }
8335
+ stopSpinner(true);
8336
+ process.stderr.write(import_chalk16.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
8337
+ `));
8338
+ });
8339
+ var workloadCommand = new import_commander46.Command("workload").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uAD00\uB9AC").addCommand(listCommand9).addCommand(getCommand7).addCommand(logsCommand).addCommand(eventsCommand2).addCommand(historyCommand).addCommand(scheduleHistoryCommand).addCommand(createCommand7).addCommand(updateCommand).addCommand(patchCommand).addCommand(pauseCommand).addCommand(resumeCommand).addCommand(restartCommand).addCommand(deleteCommand6);
8340
+
8341
+ // src/commands/ncs/malware.ts
8342
+ var import_commander47 = require("commander");
8343
+ function parseEnabledOption(value) {
8344
+ if (value === "true") return true;
8345
+ if (value === "false") return false;
8346
+ throw new NhnCloudCliError(
8347
+ `--enabled \uB294 true \uB610\uB294 false \uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
8348
+ EXIT_PARAM_ERROR
8349
+ );
8350
+ }
8351
+ var configGetCommand = new import_commander47.Command("get").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
8352
+ const opts = cmd.optsWithGlobals();
8353
+ const { client } = await resolveNcsClient(opts);
8354
+ startSpinner("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uC870\uD68C \uC911...");
8355
+ let config;
8356
+ try {
8357
+ config = await client.getMalwareConfig();
8358
+ } catch (err) {
8359
+ stopSpinner(false);
8360
+ throw err;
8361
+ }
8362
+ stopSpinner(true);
8363
+ output(opts, {
8364
+ headers: ["enabled"],
8365
+ rows: [[String(config.enabled)]],
8366
+ raw: config,
8367
+ ids: []
8368
+ });
8369
+ });
8370
+ var configSetCommand = new import_commander47.Command("set").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").requiredOption("--enabled <true|false>", "\uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC0AC\uC6A9 \uC5EC\uBD80").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
8371
+ const opts = cmd.optsWithGlobals();
8372
+ const enabled = parseEnabledOption(opts.enabled);
8373
+ const { client } = await resolveNcsClient(opts);
8374
+ startSpinner("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uBCC0\uACBD \uC911...");
8375
+ let config;
8376
+ try {
8377
+ config = await client.setMalwareConfig(enabled);
8378
+ } catch (err) {
8379
+ stopSpinner(false);
8380
+ throw err;
8381
+ }
8382
+ stopSpinner(true);
8383
+ output(opts, {
8384
+ headers: ["enabled"],
8385
+ rows: [[String(config.enabled)]],
8386
+ raw: config,
8387
+ ids: []
8388
+ });
8389
+ });
8390
+ var configCommand = new import_commander47.Command("config").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uAD00\uB9AC").addCommand(configGetCommand).addCommand(configSetCommand);
8391
+ var resultCommand = new import_commander47.Command("result").description("NCS workload \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC\uC758 \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uACB0\uACFC\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<workloadId>", "workload ID").argument("<historyId>", "\uD788\uC2A4\uD1A0\uB9AC ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (workloadId, historyId, _opts, cmd) => {
8392
+ const opts = cmd.optsWithGlobals();
8393
+ requireNonEmpty(workloadId, "workloadId");
8394
+ requireNonEmpty(historyId, "historyId");
8395
+ const { client } = await resolveNcsClient(opts);
8396
+ startSpinner(
8397
+ `NCS workload "${workloadId}" \uD788\uC2A4\uD1A0\uB9AC "${historyId}" \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uACB0\uACFC \uC870\uD68C \uC911...`
8398
+ );
8399
+ let result;
8400
+ try {
8401
+ result = await client.getMalwareResult(workloadId, historyId);
8402
+ } catch (err) {
8403
+ stopSpinner(false);
8404
+ throw err;
8405
+ }
8406
+ stopSpinner(true);
8407
+ output(opts, {
8408
+ headers: ["scannedAt", "infectedFiles", "scannedDirectories", "scannedFiles", "reports"],
8409
+ rows: [
8410
+ [
8411
+ result.scannedAt ?? "",
8412
+ String(result.infectedFiles ?? ""),
8413
+ String(result.scannedDirectories ?? ""),
8414
+ String(result.scannedFiles ?? ""),
8415
+ String(result.reports?.length ?? 0)
8416
+ ]
8417
+ ],
8418
+ raw: result,
8419
+ ids: []
8420
+ });
8421
+ });
8422
+ var malwareCommand = new import_commander47.Command("malware").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uAD00\uB9AC").addCommand(configCommand).addCommand(resultCommand);
8423
+
8424
+ // src/commands/apigateway/service.ts
8425
+ var import_commander48 = require("commander");
8426
+
8427
+ // src/services/apigateway/client.ts
8428
+ var import_ky13 = __toESM(require("ky"));
8429
+
8430
+ // src/services/apigateway/types.ts
8431
+ function isApiGatewayService(value) {
8432
+ if (typeof value !== "object" || value === null) return false;
8433
+ const obj = value;
8434
+ return typeof obj["apigwServiceId"] === "string" && typeof obj["apigwServiceAlias"] === "string" && typeof obj["apigwServiceName"] === "string" && typeof obj["apigwServiceDescription"] === "string" && typeof obj["apigwDomain"] === "string" && typeof obj["appKey"] === "string" && typeof obj["regionCode"] === "string" && typeof obj["serverGroupId"] === "string" && (typeof obj["dedicatedId"] === "string" || obj["dedicatedId"] === null) && typeof obj["createdAt"] === "string" && typeof obj["updatedAt"] === "string" && typeof obj["apigwServiceTypeCode"] === "string";
8435
+ }
8436
+ function isApiGatewayPaging(value) {
8437
+ if (typeof value !== "object" || value === null) return false;
8438
+ const obj = value;
8439
+ return typeof obj["limit"] === "number" && Number.isInteger(obj["limit"]) && obj["limit"] > 0 && typeof obj["page"] === "number" && Number.isInteger(obj["page"]) && obj["page"] > 0 && typeof obj["totalCount"] === "number" && Number.isInteger(obj["totalCount"]) && obj["totalCount"] >= 0;
8440
+ }
8441
+ function isNullableString(value) {
8442
+ return typeof value === "string" || value === null;
8443
+ }
8444
+ function isResourceRequestBody(value) {
8445
+ if (typeof value !== "object" || value === null) return false;
8446
+ const obj = value;
8447
+ return isNullableString(obj["name"]) && isNullableString(obj["description"]) && isNullableString(obj["modelId"]);
8448
+ }
8449
+ function isResource(value) {
8450
+ if (typeof value !== "object" || value === null) return false;
8451
+ const obj = value;
8452
+ return typeof obj["resourceId"] === "string" && typeof obj["apigwServiceId"] === "string" && isNullableString(obj["parentPath"]) && typeof obj["path"] === "string" && isNullableString(obj["methodType"]) && isNullableString(obj["methodName"]) && isNullableString(obj["methodDescription"]) && typeof obj["createdAt"] === "string" && typeof obj["updatedAt"] === "string" && Array.isArray(obj["resourcePluginList"]);
8453
+ }
8454
+ function isResourceParameters(value) {
8455
+ if (typeof value !== "object" || value === null) return false;
8456
+ const obj = value;
8457
+ return Array.isArray(obj["queryStringList"]) && Array.isArray(obj["headerList"]) && Array.isArray(obj["formDataList"]) && isResourceRequestBody(obj["requestBody"]) && Array.isArray(obj["contentTypeList"]);
8458
+ }
8459
+ function isResourceResponses(value) {
8460
+ if (typeof value !== "object" || value === null) return false;
8461
+ const obj = value;
8462
+ return Array.isArray(obj["responseList"]) && Array.isArray(obj["contentTypeList"]);
8463
+ }
8464
+ function isRecord(value) {
8465
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8466
+ }
8467
+ function isStageCustomDomain(value) {
8468
+ if (!isRecord(value)) return false;
8469
+ return typeof value["customDomain"] === "string" && typeof value["createdAt"] === "string";
8470
+ }
8471
+ function isStageAliasDomain(value) {
8472
+ if (!isRecord(value)) return false;
8473
+ return typeof value["aliasDomain"] === "string" && typeof value["createdAt"] === "string";
8474
+ }
8475
+ function isStage(value) {
8476
+ if (!isRecord(value)) return false;
8477
+ return typeof value["stageId"] === "string" && typeof value["apigwServiceId"] === "string" && typeof value["regionCode"] === "string" && isNullableString(value["stageName"]) && typeof value["stageDescription"] === "string" && typeof value["stageUrl"] === "string" && typeof value["backendEndpointUrl"] === "string" && typeof value["resourceUpdatedAt"] === "string" && typeof value["createdAt"] === "string" && typeof value["updatedAt"] === "string" && typeof value["stageCustomUrl"] === "string" && Array.isArray(value["stageCustomDomainList"]) && value["stageCustomDomainList"].every(isStageCustomDomain) && Array.isArray(value["stageAliasDomainList"]) && value["stageAliasDomainList"].every(isStageAliasDomain);
8478
+ }
8479
+ function isStageResourcePlugin(value) {
8480
+ return isRecord(value);
8481
+ }
8482
+ function isStageResource(value) {
8483
+ if (!isRecord(value)) return false;
8484
+ return typeof value["stageResourceId"] === "string" && typeof value["path"] === "string" && isNullableString(value["methodType"]) && isNullableString(value["methodName"]) && isNullableString(value["methodDescription"]) && isNullableString(value["customBackendEndpointUrl"]) && typeof value["updatedAt"] === "string" && Array.isArray(value["stageResourcePluginList"]) && value["stageResourcePluginList"].every(isStageResourcePlugin);
8485
+ }
8486
+ function isDeployHistory(value) {
8487
+ if (!isRecord(value)) return false;
8488
+ return typeof value["deployId"] === "string" && typeof value["stageId"] === "string" && typeof value["deployedAt"] === "string" && isNullableString(value["rollbackAt"]) && typeof value["deployDescription"] === "string" && typeof value["isBase"] === "boolean";
8489
+ }
8490
+ function isLatestDeployResult(value) {
8491
+ if (!isDeployHistory(value)) return false;
8492
+ return typeof value["deployStatus"] === "string" && Array.isArray(value["stageResourceList"]) && value["stageResourceList"].every(isStageResource);
8493
+ }
8494
+ function isSwaggerData(value) {
8495
+ return isRecord(value);
8496
+ }
8497
+
8498
+ // src/services/apigateway/client.ts
8499
+ var ApiGatewayClient = class {
8500
+ accessToken;
8501
+ baseUrl;
8502
+ constructor(accessToken, region, appKey) {
8503
+ this.accessToken = accessToken;
8504
+ this.baseUrl = `https://${apigatewayHost(region)}/v2.0/appkeys/${encodeURIComponent(appKey)}`;
8505
+ }
8506
+ authHeaders() {
8507
+ return { "X-NHN-Authorization": `Bearer ${this.accessToken}` };
8508
+ }
8509
+ /** paging.totalCount 를 기준으로 API Gateway service 전체를 수집한다. */
8510
+ async listServices(params = {}) {
8511
+ const services = [];
8512
+ const limit = params.limit ?? 1e3;
8513
+ let page = params.page ?? 1;
8514
+ try {
8515
+ while (true) {
8516
+ const response = await import_ky13.default.get(`${this.baseUrl}/services`, {
8517
+ headers: this.authHeaders(),
8518
+ searchParams: { page, limit },
8519
+ retry: 0,
8520
+ timeout: DEFAULT_TIMEOUT_MS
8521
+ }).json();
8522
+ unwrapHeader(response);
8523
+ if (!Array.isArray(response.apigwServiceList) || !response.apigwServiceList.every(isApiGatewayService)) {
8524
+ throw new NhnCloudCliError(
8525
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: apigwServiceList \uAC00 \uC62C\uBC14\uB978 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
8526
+ EXIT_API_ERROR
8527
+ );
8528
+ }
8529
+ if (!isApiGatewayPaging(response.paging)) {
8530
+ throw new NhnCloudCliError(
8531
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: paging \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8532
+ EXIT_API_ERROR
8533
+ );
8534
+ }
8535
+ services.push(...response.apigwServiceList);
8536
+ if (response.paging.page * response.paging.limit >= response.paging.totalCount) {
8537
+ break;
8538
+ }
8539
+ if (response.apigwServiceList.length === 0) {
8540
+ throw new NhnCloudCliError(
8541
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: paging.totalCount \uC804\uC5D0 \uBE48 service \uD398\uC774\uC9C0\uAC00 \uBC18\uD658\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
8542
+ EXIT_API_ERROR
8543
+ );
8544
+ }
8545
+ page = response.paging.page + 1;
8546
+ }
8547
+ return services;
8548
+ } catch (err) {
8549
+ if (err instanceof NhnCloudCliError) throw err;
8550
+ throw toNhnCloudCliError(err);
8551
+ }
8552
+ }
8553
+ /** API Gateway service 한 건을 조회한다. */
8554
+ async getService(apigwServiceId) {
8555
+ try {
8556
+ const response = await import_ky13.default.get(`${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}`, {
8557
+ headers: this.authHeaders(),
8558
+ retry: 0,
8559
+ timeout: DEFAULT_TIMEOUT_MS
8560
+ }).json();
8561
+ unwrapHeader(response);
8562
+ if (!isApiGatewayService(response.apigwService)) {
8563
+ throw new NhnCloudCliError(
8564
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: apigwService \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8565
+ EXIT_API_ERROR
8566
+ );
8567
+ }
8568
+ return response.apigwService;
8569
+ } catch (err) {
8570
+ if (err instanceof NhnCloudCliError) throw err;
8571
+ throw toNhnCloudCliError(err);
8572
+ }
8573
+ }
8574
+ /** paging 없이 API Gateway resource 전체를 한 번에 조회한다. */
8575
+ async listResources(apigwServiceId) {
8576
+ try {
8577
+ const response = await import_ky13.default.get(
8578
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/resources`,
8579
+ {
8580
+ headers: this.authHeaders(),
8581
+ retry: 0,
8582
+ timeout: DEFAULT_TIMEOUT_MS
8583
+ }
8584
+ ).json();
8585
+ unwrapHeader(response);
8586
+ if (!Array.isArray(response.resourceList) || !response.resourceList.every(isResource)) {
8587
+ throw new NhnCloudCliError(
8588
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: resourceList \uAC00 \uC62C\uBC14\uB978 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
8589
+ EXIT_API_ERROR
8590
+ );
8591
+ }
8592
+ return response.resourceList;
8593
+ } catch (err) {
8594
+ if (err instanceof NhnCloudCliError) throw err;
8595
+ throw toNhnCloudCliError(err);
8596
+ }
8597
+ }
8598
+ /** API Gateway resource 요청 parameter를 조회한다. */
8599
+ async getResourceParameters(apigwServiceId, resourceId2) {
8600
+ try {
8601
+ const response = await import_ky13.default.get(
8602
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/resources/${encodeURIComponent(resourceId2)}/parameters`,
8603
+ {
8604
+ headers: this.authHeaders(),
8605
+ retry: 0,
8606
+ timeout: DEFAULT_TIMEOUT_MS
8607
+ }
8608
+ ).json();
8609
+ unwrapHeader(response);
8610
+ if (!isResourceParameters(response)) {
8611
+ throw new NhnCloudCliError(
8612
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: resource parameter \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8613
+ EXIT_API_ERROR
8614
+ );
8615
+ }
8616
+ return {
8617
+ queryStringList: response.queryStringList,
8618
+ headerList: response.headerList,
8619
+ formDataList: response.formDataList,
8620
+ requestBody: response.requestBody,
8621
+ contentTypeList: response.contentTypeList
8622
+ };
8623
+ } catch (err) {
8624
+ if (err instanceof NhnCloudCliError) throw err;
8625
+ throw toNhnCloudCliError(err);
8626
+ }
8627
+ }
8628
+ /** API Gateway resource 응답 정의를 조회한다. */
8629
+ async getResourceResponses(apigwServiceId, resourceId2) {
8630
+ try {
8631
+ const response = await import_ky13.default.get(
8632
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/resources/${encodeURIComponent(resourceId2)}/responses`,
8633
+ {
8634
+ headers: this.authHeaders(),
8635
+ retry: 0,
8636
+ timeout: DEFAULT_TIMEOUT_MS
8637
+ }
8638
+ ).json();
8639
+ unwrapHeader(response);
8640
+ if (!isResourceResponses(response)) {
8641
+ throw new NhnCloudCliError(
8642
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: resource response \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8643
+ EXIT_API_ERROR
8644
+ );
8645
+ }
8646
+ return {
8647
+ responseList: response.responseList,
8648
+ contentTypeList: response.contentTypeList
8649
+ };
8650
+ } catch (err) {
8651
+ if (err instanceof NhnCloudCliError) throw err;
8652
+ throw toNhnCloudCliError(err);
8653
+ }
8654
+ }
8655
+ /** paging.totalCount 를 기준으로 API Gateway stage 전체를 수집한다. */
8656
+ async listStages(apigwServiceId) {
8657
+ const stages = [];
8658
+ const limit = 1e3;
8659
+ let page = 1;
8660
+ try {
8661
+ while (true) {
8662
+ const response = await import_ky13.default.get(
8663
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/stages`,
8664
+ {
8665
+ headers: this.authHeaders(),
8666
+ searchParams: { page, limit },
8667
+ retry: 0,
8668
+ timeout: DEFAULT_TIMEOUT_MS
8669
+ }
8670
+ ).json();
8671
+ unwrapHeader(response);
8672
+ if (!Array.isArray(response.stageList) || !response.stageList.every(isStage)) {
8673
+ throw new NhnCloudCliError(
8674
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: stageList \uAC00 \uC62C\uBC14\uB978 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
8675
+ EXIT_API_ERROR
8676
+ );
8677
+ }
8678
+ if (!isApiGatewayPaging(response.paging)) {
8679
+ throw new NhnCloudCliError(
8680
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: paging \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8681
+ EXIT_API_ERROR
8682
+ );
8683
+ }
8684
+ stages.push(...response.stageList);
8685
+ if (response.paging.page * response.paging.limit >= response.paging.totalCount) {
8686
+ break;
8687
+ }
8688
+ if (response.stageList.length === 0) {
8689
+ throw new NhnCloudCliError(
8690
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: paging.totalCount \uC804\uC5D0 \uBE48 stage \uD398\uC774\uC9C0\uAC00 \uBC18\uD658\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
8691
+ EXIT_API_ERROR
8692
+ );
8693
+ }
8694
+ page = response.paging.page + 1;
8695
+ }
8696
+ return stages;
8697
+ } catch (err) {
8698
+ if (err instanceof NhnCloudCliError) throw err;
8699
+ throw toNhnCloudCliError(err);
8700
+ }
8701
+ }
8702
+ /** 사용자 정의 Swagger 객체를 내부 해석 없이 반환한다. */
8703
+ async getStageSwagger(apigwServiceId, stageId) {
8704
+ try {
8705
+ const response = await import_ky13.default.get(
8706
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/stages/${encodeURIComponent(stageId)}/swagger`,
8707
+ {
8708
+ headers: this.authHeaders(),
8709
+ retry: 0,
8710
+ timeout: DEFAULT_TIMEOUT_MS
8711
+ }
8712
+ ).json();
8713
+ unwrapHeader(response);
8714
+ if (!isSwaggerData(response.swaggerData)) {
8715
+ throw new NhnCloudCliError(
8716
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: swaggerData \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4.",
8717
+ EXIT_API_ERROR
8718
+ );
8719
+ }
8720
+ return response.swaggerData;
8721
+ } catch (err) {
8722
+ if (err instanceof NhnCloudCliError) throw err;
8723
+ throw toNhnCloudCliError(err);
8724
+ }
8725
+ }
8726
+ /** paging 없이 배포된 API Gateway stage resource 전체를 한 번에 조회한다. */
8727
+ async listStageResources(apigwServiceId, stageId) {
8728
+ try {
8729
+ const response = await import_ky13.default.get(
8730
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/stages/${encodeURIComponent(stageId)}/resources`,
8731
+ {
8732
+ headers: this.authHeaders(),
8733
+ retry: 0,
8734
+ timeout: DEFAULT_TIMEOUT_MS
8735
+ }
8736
+ ).json();
8737
+ unwrapHeader(response);
8738
+ if (!Array.isArray(response.stageResourceList) || !response.stageResourceList.every(isStageResource)) {
8739
+ throw new NhnCloudCliError(
8740
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: stageResourceList \uAC00 \uC62C\uBC14\uB978 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
8741
+ EXIT_API_ERROR
8742
+ );
8743
+ }
8744
+ return response.stageResourceList;
8745
+ } catch (err) {
8746
+ if (err instanceof NhnCloudCliError) throw err;
8747
+ throw toNhnCloudCliError(err);
8748
+ }
8749
+ }
8750
+ /** paging.totalCount 를 기준으로 API Gateway stage 배포 이력 전체를 수집한다. */
8751
+ async listDeploys(apigwServiceId, stageId) {
8752
+ const deploys = [];
8753
+ const limit = 1e3;
8754
+ let page = 1;
8755
+ try {
8756
+ while (true) {
8757
+ const response = await import_ky13.default.get(
8758
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/stages/${encodeURIComponent(stageId)}/deploys`,
8759
+ {
8760
+ headers: this.authHeaders(),
8761
+ searchParams: { page, limit },
8762
+ retry: 0,
8763
+ timeout: DEFAULT_TIMEOUT_MS
8764
+ }
8765
+ ).json();
8766
+ unwrapHeader(response);
8767
+ if (!Array.isArray(response.stageDeployHistoryList) || !response.stageDeployHistoryList.every(isDeployHistory)) {
8768
+ throw new NhnCloudCliError(
8769
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: stageDeployHistoryList \uAC00 \uC62C\uBC14\uB978 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
8770
+ EXIT_API_ERROR
8771
+ );
8772
+ }
8773
+ if (!isApiGatewayPaging(response.paging)) {
8774
+ throw new NhnCloudCliError(
8775
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: paging \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8776
+ EXIT_API_ERROR
8777
+ );
8778
+ }
8779
+ deploys.push(...response.stageDeployHistoryList);
8780
+ if (response.paging.page * response.paging.limit >= response.paging.totalCount) {
8781
+ break;
8782
+ }
8783
+ if (response.stageDeployHistoryList.length === 0) {
8784
+ throw new NhnCloudCliError(
8785
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: paging.totalCount \uC804\uC5D0 \uBE48 deploy \uD398\uC774\uC9C0\uAC00 \uBC18\uD658\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
8786
+ EXIT_API_ERROR
8787
+ );
8788
+ }
8789
+ page = response.paging.page + 1;
8790
+ }
8791
+ return deploys;
8792
+ } catch (err) {
8793
+ if (err instanceof NhnCloudCliError) throw err;
8794
+ throw toNhnCloudCliError(err);
8795
+ }
8796
+ }
8797
+ /** API Gateway stage 최신 배포 결과를 조회한다. */
8798
+ async getLatestDeploy(apigwServiceId, stageId) {
8799
+ try {
8800
+ const response = await import_ky13.default.get(
8801
+ `${this.baseUrl}/services/${encodeURIComponent(apigwServiceId)}/stages/${encodeURIComponent(stageId)}/deploys/latest`,
8802
+ {
8803
+ headers: this.authHeaders(),
8804
+ retry: 0,
8805
+ timeout: DEFAULT_TIMEOUT_MS
8806
+ }
8807
+ ).json();
8808
+ unwrapHeader(response);
8809
+ if (!isLatestDeployResult(response.latestStageDeployResult)) {
8810
+ throw new NhnCloudCliError(
8811
+ "API Gateway \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: latestStageDeployResult \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
8812
+ EXIT_API_ERROR
8813
+ );
8814
+ }
8815
+ return response.latestStageDeployResult;
8816
+ } catch (err) {
8817
+ if (err instanceof NhnCloudCliError) throw err;
8818
+ throw toNhnCloudCliError(err);
8819
+ }
8820
+ }
8821
+ };
8822
+
8823
+ // src/commands/apigateway/helpers.ts
8824
+ function sanitizeForTerminal(value) {
8825
+ return value.replace(/[\x00-\x1F\x7F]/g, "?");
8826
+ }
8827
+ async function resolveApiGatewayAppKey(profileName, appKeyOption) {
8828
+ if (appKeyOption?.trim()) return appKeyOption.trim();
8829
+ let credential;
8830
+ try {
8831
+ credential = await getServiceCredential("apigateway", profileName);
8832
+ } catch (err) {
8833
+ if (!(err instanceof NhnCloudCliError) || err.exitCode !== EXIT_CONFIG_ERROR) {
8834
+ throw err;
8835
+ }
8836
+ }
8837
+ if (!credential?.appkey) {
8838
+ throw new NhnCloudCliError(
8839
+ "API Gateway appKey\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. nhncloud configure --apigateway-appkey <key>\uB85C \uC124\uC815\uD558\uAC70\uB098\n--app-key\uB85C \uC9C1\uC811 \uB118\uAE30\uC138\uC694.",
8840
+ EXIT_CONFIG_ERROR
8841
+ );
8842
+ }
8843
+ return credential.appkey;
8844
+ }
8845
+ async function resolveApiGatewayClient(opts) {
8846
+ const profileName = await resolveProfileName(opts.profile);
8847
+ const uak = await getUserAccessKey(profileName);
8848
+ const accessToken = await getAccessToken(profileName, uak.id, uak.secret);
8849
+ const appKey = await resolveApiGatewayAppKey(profileName, opts.appKey);
8850
+ return {
8851
+ client: new ApiGatewayClient(accessToken, opts.region ?? "kr1", appKey),
8852
+ profileName
8853
+ };
8854
+ }
8855
+
8856
+ // src/commands/apigateway/service.ts
8857
+ var listCommand10 = new import_commander48.Command("list").description("API Gateway service \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "API Gateway region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "API Gateway appKey (profile \uC758 apigateway.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, command) => {
8858
+ const opts = command.optsWithGlobals();
8859
+ const { client } = await resolveApiGatewayClient(opts);
8860
+ startSpinner("API Gateway service \uBAA9\uB85D \uC870\uD68C \uC911...");
8861
+ let services;
8862
+ try {
8863
+ services = await client.listServices();
8864
+ } catch (err) {
8865
+ stopSpinner(false);
8866
+ throw err;
8867
+ }
8868
+ stopSpinner(true);
8869
+ output(opts, {
8870
+ headers: [
8871
+ "apigwServiceId",
8872
+ "apigwServiceName",
8873
+ "apigwDomain",
8874
+ "regionCode",
8875
+ "createdAt"
8876
+ ],
8877
+ rows: services.map((service) => [
8878
+ sanitizeForTerminal(service.apigwServiceId),
8879
+ sanitizeForTerminal(service.apigwServiceName),
8880
+ sanitizeForTerminal(service.apigwDomain),
8881
+ sanitizeForTerminal(service.regionCode),
8882
+ sanitizeForTerminal(service.createdAt)
8883
+ ]),
8884
+ raw: services,
8885
+ ids: services.map((service) => sanitizeForTerminal(service.apigwServiceId))
7451
8886
  });
7452
8887
  });
7453
- var createCommand7 = new import_commander46.Command("create").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uB97C \uC0DD\uC131\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC)").requiredOption("--file <path>", "workload \uC0DD\uC131 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--wait", "workload \uAC00 Running \uC0C1\uD0DC\uAC00 \uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30").option("--timeout <sec>", "wait \uD0C0\uC784\uC544\uC6C3 (\uCD08, \uAE30\uBCF8 300)", "300").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
7454
- const opts = cmd.optsWithGlobals();
7455
- const payload = readJsonPayload(opts.file);
7456
- const timeoutMs = parsePositiveIntegerOption(opts.timeout ?? "300", "--timeout") * 1e3;
7457
- const { client } = await resolveNcsClient(opts);
7458
- startSpinner("NCS workload \uC0DD\uC131 \uC911...");
7459
- let workload;
7460
- try {
7461
- workload = await client.createWorkload(payload);
8888
+ var getCommand8 = new import_commander48.Command("get").description("API Gateway service \uD55C \uAC74\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<service-id>", "API Gateway service ID").option("--region <region>", "API Gateway region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "API Gateway appKey (profile \uC758 apigateway.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (serviceId, _opts, command) => {
8889
+ const opts = command.optsWithGlobals();
8890
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
8891
+ const displayServiceId = sanitizeForTerminal(parsedServiceId);
8892
+ const { client } = await resolveApiGatewayClient(opts);
8893
+ startSpinner(`API Gateway service "${displayServiceId}" \uC870\uD68C \uC911...`);
8894
+ let service;
8895
+ try {
8896
+ service = await client.getService(parsedServiceId);
7462
8897
  } catch (err) {
7463
8898
  stopSpinner(false);
7464
8899
  throw err;
7465
8900
  }
7466
8901
  stopSpinner(true);
7467
- if (opts.wait) {
7468
- startSpinner(`NCS workload "${workload.id}" Running \uB300\uAE30 \uC911...`);
7469
- try {
7470
- workload = await client.waitForRunning(workload.id, { timeoutMs });
7471
- } catch (err) {
7472
- stopSpinner(false);
7473
- throw err;
7474
- }
7475
- stopSpinner(true, `Running \uD655\uC778 (id: ${workload.id})`);
7476
- }
7477
8902
  output(opts, {
7478
- headers: WORKLOAD_HEADERS,
7479
- rows: workloadRows(workload),
7480
- raw: workload,
7481
- ids: [workload.id]
8903
+ headers: [
8904
+ "apigwServiceId",
8905
+ "apigwServiceName",
8906
+ "apigwDomain",
8907
+ "regionCode",
8908
+ "createdAt"
8909
+ ],
8910
+ rows: [[
8911
+ sanitizeForTerminal(service.apigwServiceId),
8912
+ sanitizeForTerminal(service.apigwServiceName),
8913
+ sanitizeForTerminal(service.apigwDomain),
8914
+ sanitizeForTerminal(service.regionCode),
8915
+ sanitizeForTerminal(service.createdAt)
8916
+ ]],
8917
+ raw: service,
8918
+ ids: [sanitizeForTerminal(service.apigwServiceId)]
7482
8919
  });
7483
8920
  });
7484
- var updateCommand = new import_commander46.Command("update").description("NCS workload \uB97C \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC, PUT)").argument("<id>", "workload ID").requiredOption("--file <path>", "workload \uAD50\uCCB4 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7485
- const opts = cmd.optsWithGlobals();
7486
- requireNonEmpty(id, "id");
7487
- const payload = readJsonPayload(opts.file);
7488
- const { client } = await resolveNcsClient(opts);
7489
- startSpinner(`NCS workload "${id}" \uAD50\uCCB4 \uC911...`);
7490
- let workload;
7491
- try {
7492
- workload = await client.updateWorkload(id, payload);
8921
+ var serviceCommand = new import_commander48.Command("service").description("API Gateway service \uC870\uD68C \uBA85\uB839").addCommand(listCommand10).addCommand(getCommand8);
8922
+
8923
+ // src/commands/apigateway/resource.ts
8924
+ var import_commander49 = require("commander");
8925
+ function addApiGatewayOptions(command) {
8926
+ return command.option("--region <region>", "API Gateway region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "API Gateway appKey (profile \uC758 apigateway.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984");
8927
+ }
8928
+ function displayUnknown(value) {
8929
+ const serialized = JSON.stringify(value);
8930
+ return serialized ?? String(value);
8931
+ }
8932
+ var listCommand11 = addApiGatewayOptions(
8933
+ new import_commander49.Command("list").description("API Gateway resource \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<service-id>", "API Gateway service ID")
8934
+ ).action(async (serviceId, _opts, command) => {
8935
+ const opts = command.optsWithGlobals();
8936
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
8937
+ const displayServiceId = sanitizeForTerminal(parsedServiceId);
8938
+ const { client } = await resolveApiGatewayClient(opts);
8939
+ startSpinner(`API Gateway service "${displayServiceId}" resource \uBAA9\uB85D \uC870\uD68C \uC911...`);
8940
+ let resources;
8941
+ try {
8942
+ resources = await client.listResources(parsedServiceId);
7493
8943
  } catch (err) {
7494
8944
  stopSpinner(false);
7495
8945
  throw err;
7496
8946
  }
7497
8947
  stopSpinner(true);
7498
8948
  output(opts, {
7499
- headers: WORKLOAD_HEADERS,
7500
- rows: workloadRows(workload),
7501
- raw: workload,
7502
- ids: [workload.id]
8949
+ headers: ["resourceId", "path", "methodType", "methodName", "updatedAt"],
8950
+ rows: resources.map((resource) => [
8951
+ sanitizeForTerminal(resource.resourceId),
8952
+ sanitizeForTerminal(resource.path),
8953
+ resource.methodType === null ? "-" : sanitizeForTerminal(resource.methodType),
8954
+ resource.methodName === null ? "-" : sanitizeForTerminal(resource.methodName),
8955
+ sanitizeForTerminal(resource.updatedAt)
8956
+ ]),
8957
+ raw: resources,
8958
+ ids: resources.map((resource) => sanitizeForTerminal(resource.resourceId))
7503
8959
  });
7504
8960
  });
7505
- var patchCommand = new import_commander46.Command("patch").description("NCS workload \uB97C \uBD80\uBD84 \uBCC0\uACBD\uD55C\uB2E4 (--file \uB85C JSON Patch \uBC30\uC5F4 \uC804\uB2EC, RFC 6902)").argument("<id>", "workload ID").requiredOption("--file <path>", "JSON Patch \uBC30\uC5F4(op/path/value)\uC774 \uB2F4\uAE34 \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7506
- const opts = cmd.optsWithGlobals();
7507
- requireNonEmpty(id, "id");
7508
- const payload = readJsonPayload(opts.file);
7509
- const { client } = await resolveNcsClient(opts);
7510
- startSpinner(`NCS workload "${id}" \uBD80\uBD84 \uBCC0\uACBD \uC911...`);
7511
- let workload;
7512
- try {
7513
- workload = await client.patchWorkload(id, payload);
8961
+ var parametersCommand = addApiGatewayOptions(
8962
+ new import_commander49.Command("parameters").description("API Gateway resource \uC694\uCCAD parameter\uB97C \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<service-id>", "API Gateway service ID").argument("<resource-id>", "API Gateway resource ID")
8963
+ ).action(async (serviceId, resourceId2, _opts, command) => {
8964
+ const opts = command.optsWithGlobals();
8965
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
8966
+ const parsedResourceId = parseRequiredArgument(resourceId2, "resource-id");
8967
+ const displayResourceId = sanitizeForTerminal(parsedResourceId);
8968
+ const { client } = await resolveApiGatewayClient(opts);
8969
+ startSpinner(`API Gateway resource "${displayResourceId}" parameter \uC870\uD68C \uC911...`);
8970
+ let parameters;
8971
+ try {
8972
+ parameters = await client.getResourceParameters(parsedServiceId, parsedResourceId);
7514
8973
  } catch (err) {
7515
8974
  stopSpinner(false);
7516
8975
  throw err;
7517
8976
  }
7518
8977
  stopSpinner(true);
7519
8978
  output(opts, {
7520
- headers: WORKLOAD_HEADERS,
7521
- rows: workloadRows(workload),
7522
- raw: workload,
7523
- ids: [workload.id]
8979
+ headers: ["type", "count"],
8980
+ rows: [
8981
+ ["queryString", String(parameters.queryStringList.length)],
8982
+ ["header", String(parameters.headerList.length)],
8983
+ ["formData", String(parameters.formDataList.length)],
8984
+ ["contentType", String(parameters.contentTypeList.length)]
8985
+ ],
8986
+ raw: parameters,
8987
+ ids: []
7524
8988
  });
7525
8989
  });
7526
- var pauseCommand = new import_commander46.Command("pause").description("NCS workload \uB97C \uC77C\uC2DC\uC815\uC9C0\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7527
- const opts = cmd.optsWithGlobals();
7528
- requireNonEmpty(id, "id");
7529
- const { client } = await resolveNcsClient(opts);
7530
- startSpinner(`NCS workload "${id}" \uC77C\uC2DC\uC815\uC9C0 \uC911...`);
7531
- try {
7532
- await client.pauseWorkload(id);
8990
+ var responsesCommand = addApiGatewayOptions(
8991
+ new import_commander49.Command("responses").description("API Gateway resource \uC751\uB2F5 \uC815\uC758\uB97C \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<service-id>", "API Gateway service ID").argument("<resource-id>", "API Gateway resource ID")
8992
+ ).action(async (serviceId, resourceId2, _opts, command) => {
8993
+ const opts = command.optsWithGlobals();
8994
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
8995
+ const parsedResourceId = parseRequiredArgument(resourceId2, "resource-id");
8996
+ const displayResourceId = sanitizeForTerminal(parsedResourceId);
8997
+ const { client } = await resolveApiGatewayClient(opts);
8998
+ startSpinner(`API Gateway resource "${displayResourceId}" \uC751\uB2F5 \uC815\uC758 \uC870\uD68C \uC911...`);
8999
+ let responses;
9000
+ try {
9001
+ responses = await client.getResourceResponses(parsedServiceId, parsedResourceId);
7533
9002
  } catch (err) {
7534
9003
  stopSpinner(false);
7535
9004
  throw err;
7536
9005
  }
7537
9006
  stopSpinner(true);
7538
- process.stderr.write(import_chalk17.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC77C\uC2DC\uC815\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7539
- `));
9007
+ output(opts, {
9008
+ headers: ["response"],
9009
+ rows: responses.responseList.map((response) => [
9010
+ sanitizeForTerminal(displayUnknown(response))
9011
+ ]),
9012
+ raw: responses,
9013
+ ids: []
9014
+ });
7540
9015
  });
7541
- var resumeCommand = new import_commander46.Command("resume").description("NCS workload \uB97C \uC7AC\uAC1C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7542
- const opts = cmd.optsWithGlobals();
7543
- requireNonEmpty(id, "id");
7544
- const { client } = await resolveNcsClient(opts);
7545
- startSpinner(`NCS workload "${id}" \uC7AC\uAC1C \uC911...`);
7546
- try {
7547
- await client.resumeWorkload(id);
7548
- } catch (err) {
9016
+ var resourceCommand = new import_commander49.Command("resource").description("API Gateway resource \uC870\uD68C \uBA85\uB839").addCommand(listCommand11).addCommand(parametersCommand).addCommand(responsesCommand);
9017
+
9018
+ // src/commands/apigateway/stage.ts
9019
+ var import_promises8 = require("fs/promises");
9020
+ var import_commander51 = require("commander");
9021
+
9022
+ // src/commands/apigateway/deploy.ts
9023
+ var import_commander50 = require("commander");
9024
+ function addApiGatewayOptions2(command) {
9025
+ return command.option("--region <region>", "API Gateway region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "API Gateway appKey (profile \uC758 apigateway.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984");
9026
+ }
9027
+ var listCommand12 = addApiGatewayOptions2(
9028
+ new import_commander50.Command("list").description("API Gateway stage \uBC30\uD3EC \uC774\uB825 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<service-id>", "API Gateway service ID").argument("<stage-id>", "API Gateway stage ID")
9029
+ ).action(async (serviceId, stageId, _opts, command) => {
9030
+ const opts = command.optsWithGlobals();
9031
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
9032
+ const parsedStageId = parseRequiredArgument(stageId, "stage-id");
9033
+ const displayStageId = sanitizeForTerminal(parsedStageId);
9034
+ const { client } = await resolveApiGatewayClient(opts);
9035
+ startSpinner(`API Gateway stage "${displayStageId}" \uBC30\uD3EC \uC774\uB825 \uC870\uD68C \uC911...`);
9036
+ let deploys;
9037
+ try {
9038
+ deploys = await client.listDeploys(parsedServiceId, parsedStageId);
9039
+ } catch (error) {
7549
9040
  stopSpinner(false);
7550
- throw err;
9041
+ throw error;
7551
9042
  }
7552
9043
  stopSpinner(true);
7553
- process.stderr.write(import_chalk17.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC7AC\uAC1C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7554
- `));
9044
+ output(opts, {
9045
+ headers: ["deployId", "deployedAt", "isBase", "deployDescription"],
9046
+ rows: deploys.map((deploy) => [
9047
+ sanitizeForTerminal(deploy.deployId),
9048
+ sanitizeForTerminal(deploy.deployedAt),
9049
+ String(deploy.isBase),
9050
+ sanitizeForTerminal(deploy.deployDescription)
9051
+ ]),
9052
+ raw: deploys,
9053
+ ids: deploys.map((deploy) => sanitizeForTerminal(deploy.deployId))
9054
+ });
7555
9055
  });
7556
- var restartCommand = new import_commander46.Command("restart").description("NCS workload task \uB97C \uC7AC\uC2DC\uC791\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--task <taskId>", "task ID (\uD544\uC218)").action(async (id, _opts, cmd) => {
7557
- const opts = cmd.optsWithGlobals();
7558
- requireNonEmpty(id, "id");
7559
- if (!opts.task || !opts.task.trim()) {
7560
- throw new NhnCloudCliError(
7561
- "--task \uC635\uC158\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. task ID \uB97C \uC9C0\uC815\uD558\uC138\uC694.",
7562
- EXIT_PARAM_ERROR
7563
- );
7564
- }
7565
- const { client } = await resolveNcsClient(opts);
7566
- startSpinner(`NCS workload "${id}" task "${opts.task}" \uC7AC\uC2DC\uC791 \uC911...`);
7567
- try {
7568
- await client.restartWorkloadTask(id, opts.task);
7569
- } catch (err) {
9056
+ var latestCommand = addApiGatewayOptions2(
9057
+ new import_commander50.Command("latest").description("API Gateway stage \uCD5C\uC2E0 \uBC30\uD3EC \uACB0\uACFC\uB97C \uC870\uD68C\uD55C\uB2E4 (resource \uC804\uCCB4\uB294 --json)").argument("<service-id>", "API Gateway service ID").argument("<stage-id>", "API Gateway stage ID")
9058
+ ).action(async (serviceId, stageId, _opts, command) => {
9059
+ const opts = command.optsWithGlobals();
9060
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
9061
+ const parsedStageId = parseRequiredArgument(stageId, "stage-id");
9062
+ const displayStageId = sanitizeForTerminal(parsedStageId);
9063
+ const { client } = await resolveApiGatewayClient(opts);
9064
+ startSpinner(`API Gateway stage "${displayStageId}" \uCD5C\uC2E0 \uBC30\uD3EC \uACB0\uACFC \uC870\uD68C \uC911...`);
9065
+ let deploy;
9066
+ try {
9067
+ deploy = await client.getLatestDeploy(parsedServiceId, parsedStageId);
9068
+ } catch (error) {
7570
9069
  stopSpinner(false);
7571
- throw err;
9070
+ throw error;
7572
9071
  }
7573
9072
  stopSpinner(true);
7574
- process.stderr.write(
7575
- import_chalk17.default.green(`\u2713 NCS workload "${id}" task "${opts.task}" \uAC00 \uC7AC\uC2DC\uC791\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7576
- `)
7577
- );
9073
+ output(opts, {
9074
+ headers: ["deployId", "deployStatus", "deployedAt", "isBase", "stageResourceCount"],
9075
+ rows: [[
9076
+ sanitizeForTerminal(deploy.deployId),
9077
+ sanitizeForTerminal(deploy.deployStatus),
9078
+ sanitizeForTerminal(deploy.deployedAt),
9079
+ String(deploy.isBase),
9080
+ String(deploy.stageResourceList.length)
9081
+ ]],
9082
+ raw: deploy,
9083
+ ids: [sanitizeForTerminal(deploy.deployId)]
9084
+ });
7578
9085
  });
7579
- var deleteCommand6 = new import_commander46.Command("delete").description("NCS workload \uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "workload ID").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7580
- const opts = cmd.optsWithGlobals();
7581
- requireNonEmpty(id, "id");
7582
- const ok = await confirmDestructive(`NCS workload "${id}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
7583
- if (!ok) {
7584
- process.stderr.write(import_chalk17.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7585
- return;
9086
+ var deployCommand = new import_commander50.Command("deploy").description("API Gateway stage \uBC30\uD3EC \uC774\uB825 \uC870\uD68C \uBA85\uB839").addCommand(listCommand12).addCommand(latestCommand);
9087
+
9088
+ // src/commands/apigateway/stage.ts
9089
+ function addApiGatewayOptions3(command) {
9090
+ return command.option("--region <region>", "API Gateway region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "API Gateway appKey (profile \uC758 apigateway.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984");
9091
+ }
9092
+ function fileErrorReason(error) {
9093
+ if (typeof error === "object" && error !== null && "code" in error) {
9094
+ const code = error.code;
9095
+ if (typeof code === "string") return code;
7586
9096
  }
7587
- const { client } = await resolveNcsClient(opts);
7588
- startSpinner(`NCS workload \uC0AD\uC81C \uC911... (id: ${id})`);
9097
+ return error instanceof Error ? error.message : String(error);
9098
+ }
9099
+ async function writeStageSwaggerFile(path5, swagger, force) {
7589
9100
  try {
7590
- await client.deleteWorkload(id);
7591
- } catch (err) {
7592
- stopSpinner(false);
7593
- throw err;
9101
+ await (0, import_promises8.writeFile)(path5, JSON.stringify(swagger, null, 2) + "\n", {
9102
+ encoding: "utf-8",
9103
+ flag: force ? "w" : "wx"
9104
+ });
9105
+ } catch (error) {
9106
+ const reason = fileErrorReason(error);
9107
+ const guidance = reason === "EEXIST" ? " \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC9C0\uC815\uD558\uC138\uC694." : "";
9108
+ throw new NhnCloudCliError(
9109
+ `Swagger \uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${JSON.stringify(path5)} (${JSON.stringify(reason)}).${guidance}`,
9110
+ EXIT_PARAM_ERROR
9111
+ );
7594
9112
  }
7595
- stopSpinner(true);
7596
- process.stderr.write(import_chalk17.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7597
- `));
7598
- });
7599
- var workloadCommand = new import_commander46.Command("workload").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uAD00\uB9AC").addCommand(listCommand9).addCommand(getCommand7).addCommand(logsCommand).addCommand(eventsCommand2).addCommand(historyCommand).addCommand(scheduleHistoryCommand).addCommand(createCommand7).addCommand(updateCommand).addCommand(patchCommand).addCommand(pauseCommand).addCommand(resumeCommand).addCommand(restartCommand).addCommand(deleteCommand6);
7600
-
7601
- // src/commands/ncs/malware.ts
7602
- var import_commander47 = require("commander");
7603
- function parseEnabledOption(value) {
7604
- if (value === "true") return true;
7605
- if (value === "false") return false;
7606
- throw new NhnCloudCliError(
7607
- `--enabled \uB294 true \uB610\uB294 false \uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
7608
- EXIT_PARAM_ERROR
7609
- );
7610
9113
  }
7611
- var configGetCommand = new import_commander47.Command("get").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
7612
- const opts = cmd.optsWithGlobals();
7613
- const { client } = await resolveNcsClient(opts);
7614
- startSpinner("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uC870\uD68C \uC911...");
7615
- let config;
9114
+ var listCommand13 = addApiGatewayOptions3(
9115
+ new import_commander51.Command("list").description("API Gateway stage \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (resourceUpdatedAt\uC740 \uB9AC\uC18C\uC2A4 \uBC18\uC601 \uC2DC\uAC01)").argument("<service-id>", "API Gateway service ID")
9116
+ ).action(async (serviceId, _opts, command) => {
9117
+ const opts = command.optsWithGlobals();
9118
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
9119
+ const displayServiceId = sanitizeForTerminal(parsedServiceId);
9120
+ const { client } = await resolveApiGatewayClient(opts);
9121
+ startSpinner(`API Gateway service "${displayServiceId}" stage \uBAA9\uB85D \uC870\uD68C \uC911...`);
9122
+ let stages;
7616
9123
  try {
7617
- config = await client.getMalwareConfig();
7618
- } catch (err) {
9124
+ stages = await client.listStages(parsedServiceId);
9125
+ } catch (error) {
7619
9126
  stopSpinner(false);
7620
- throw err;
9127
+ throw error;
7621
9128
  }
7622
9129
  stopSpinner(true);
7623
9130
  output(opts, {
7624
- headers: ["enabled"],
7625
- rows: [[String(config.enabled)]],
7626
- raw: config,
7627
- ids: []
9131
+ headers: ["stageId", "stageName", "stageUrl", "backendEndpointUrl", "resourceUpdatedAt"],
9132
+ rows: stages.map((stage) => [
9133
+ sanitizeForTerminal(stage.stageId),
9134
+ stage.stageName === null ? "-" : sanitizeForTerminal(stage.stageName),
9135
+ sanitizeForTerminal(stage.stageUrl),
9136
+ sanitizeForTerminal(stage.backendEndpointUrl),
9137
+ sanitizeForTerminal(stage.resourceUpdatedAt)
9138
+ ]),
9139
+ raw: stages,
9140
+ ids: stages.map((stage) => sanitizeForTerminal(stage.stageId))
7628
9141
  });
7629
9142
  });
7630
- var configSetCommand = new import_commander47.Command("set").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").requiredOption("--enabled <true|false>", "\uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC0AC\uC6A9 \uC5EC\uBD80").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
7631
- const opts = cmd.optsWithGlobals();
7632
- const enabled = parseEnabledOption(opts.enabled);
7633
- const { client } = await resolveNcsClient(opts);
7634
- startSpinner("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uBCC0\uACBD \uC911...");
7635
- let config;
7636
- try {
7637
- config = await client.setMalwareConfig(enabled);
7638
- } catch (err) {
9143
+ var swaggerCommand = addApiGatewayOptions3(
9144
+ new import_commander51.Command("swagger").description("API Gateway stage Swagger\uB97C \uCD9C\uB825\uD558\uAC70\uB098 \uC800\uC7A5\uD55C\uB2E4").argument("<service-id>", "API Gateway service ID").argument("<stage-id>", "API Gateway stage ID").option("--output <file>", "Swagger JSON \uC800\uC7A5 \uACBD\uB85C").option("--force", "\uAE30\uC874 \uD30C\uC77C \uB36E\uC5B4\uC4F0\uAE30")
9145
+ ).action(async (serviceId, stageId, _opts, command) => {
9146
+ const opts = command.optsWithGlobals();
9147
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
9148
+ const parsedStageId = parseRequiredArgument(stageId, "stage-id");
9149
+ const displayStageId = sanitizeForTerminal(parsedStageId);
9150
+ const { client } = await resolveApiGatewayClient(opts);
9151
+ startSpinner(`API Gateway stage "${displayStageId}" Swagger \uC870\uD68C \uC911...`);
9152
+ let swagger;
9153
+ try {
9154
+ swagger = await client.getStageSwagger(parsedServiceId, parsedStageId);
9155
+ } catch (error) {
7639
9156
  stopSpinner(false);
7640
- throw err;
9157
+ throw error;
7641
9158
  }
7642
9159
  stopSpinner(true);
7643
- output(opts, {
7644
- headers: ["enabled"],
7645
- rows: [[String(config.enabled)]],
7646
- raw: config,
7647
- ids: []
7648
- });
9160
+ if (opts.output !== void 0) {
9161
+ await writeStageSwaggerFile(opts.output, swagger, opts.force);
9162
+ process.stdout.write(sanitizeForTerminal(opts.output) + "\n");
9163
+ return;
9164
+ }
9165
+ printJson(swagger);
7649
9166
  });
7650
- var configCommand = new import_commander47.Command("config").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uAD00\uB9AC").addCommand(configGetCommand).addCommand(configSetCommand);
7651
- var resultCommand = new import_commander47.Command("result").description("NCS workload \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC\uC758 \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uACB0\uACFC\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<workloadId>", "workload ID").argument("<historyId>", "\uD788\uC2A4\uD1A0\uB9AC ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (workloadId, historyId, _opts, cmd) => {
7652
- const opts = cmd.optsWithGlobals();
7653
- requireNonEmpty(workloadId, "workloadId");
7654
- requireNonEmpty(historyId, "historyId");
7655
- const { client } = await resolveNcsClient(opts);
7656
- startSpinner(
7657
- `NCS workload "${workloadId}" \uD788\uC2A4\uD1A0\uB9AC "${historyId}" \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uACB0\uACFC \uC870\uD68C \uC911...`
7658
- );
7659
- let result;
7660
- try {
7661
- result = await client.getMalwareResult(workloadId, historyId);
7662
- } catch (err) {
9167
+ var resourcesCommand = addApiGatewayOptions3(
9168
+ new import_commander51.Command("resources").description("\uBC30\uD3EC\uB41C API Gateway stage resource \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<service-id>", "API Gateway service ID").argument("<stage-id>", "API Gateway stage ID")
9169
+ ).action(async (serviceId, stageId, _opts, command) => {
9170
+ const opts = command.optsWithGlobals();
9171
+ const parsedServiceId = parseRequiredArgument(serviceId, "service-id");
9172
+ const parsedStageId = parseRequiredArgument(stageId, "stage-id");
9173
+ const displayStageId = sanitizeForTerminal(parsedStageId);
9174
+ const { client } = await resolveApiGatewayClient(opts);
9175
+ startSpinner(`API Gateway stage "${displayStageId}" resource \uBAA9\uB85D \uC870\uD68C \uC911...`);
9176
+ let resources;
9177
+ try {
9178
+ resources = await client.listStageResources(parsedServiceId, parsedStageId);
9179
+ } catch (error) {
7663
9180
  stopSpinner(false);
7664
- throw err;
9181
+ throw error;
7665
9182
  }
7666
9183
  stopSpinner(true);
7667
9184
  output(opts, {
7668
- headers: ["scannedAt", "infectedFiles", "scannedDirectories", "scannedFiles", "reports"],
7669
- rows: [
7670
- [
7671
- result.scannedAt ?? "",
7672
- String(result.infectedFiles ?? ""),
7673
- String(result.scannedDirectories ?? ""),
7674
- String(result.scannedFiles ?? ""),
7675
- String(result.reports?.length ?? 0)
7676
- ]
7677
- ],
7678
- raw: result,
7679
- ids: []
9185
+ headers: ["stageResourceId", "path", "methodType", "customBackendEndpointUrl", "updatedAt"],
9186
+ rows: resources.map((resource) => [
9187
+ sanitizeForTerminal(resource.stageResourceId),
9188
+ sanitizeForTerminal(resource.path),
9189
+ resource.methodType === null ? "-" : sanitizeForTerminal(resource.methodType),
9190
+ resource.customBackendEndpointUrl === null ? "-" : sanitizeForTerminal(resource.customBackendEndpointUrl),
9191
+ sanitizeForTerminal(resource.updatedAt)
9192
+ ]),
9193
+ raw: resources,
9194
+ ids: resources.map((resource) => sanitizeForTerminal(resource.stageResourceId))
7680
9195
  });
7681
9196
  });
7682
- var malwareCommand = new import_commander47.Command("malware").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uAD00\uB9AC").addCommand(configCommand).addCommand(resultCommand);
9197
+ var stageCommand = new import_commander51.Command("stage").description("API Gateway stage \uC870\uD68C \uBA85\uB839").addCommand(listCommand13).addCommand(swaggerCommand).addCommand(resourcesCommand).addCommand(deployCommand);
7683
9198
 
7684
9199
  // src/commands/loadbalancer/list.ts
7685
- var import_commander48 = require("commander");
9200
+ var import_commander52 = require("commander");
7686
9201
 
7687
9202
  // src/commands/loadbalancer/helpers.ts
7688
9203
  var import_node_net = require("net");
7689
9204
 
7690
9205
  // src/services/loadbalancer/client.ts
7691
- var import_ky13 = __toESM(require("ky"));
9206
+ var import_ky14 = __toESM(require("ky"));
7692
9207
 
7693
9208
  // src/services/loadbalancer/types.ts
7694
- function isRecord(value) {
9209
+ function isRecord2(value) {
7695
9210
  return typeof value === "object" && value !== null;
7696
9211
  }
7697
9212
  function isNonEmptyString(value) {
@@ -7701,30 +9216,29 @@ function isIpAclAction(value) {
7701
9216
  return value === "ALLOW" || value === "DENY";
7702
9217
  }
7703
9218
  function isLoadBalancerIpAclGroup(value) {
7704
- return isRecord(value) && isNonEmptyString(value["ipacl_group_id"]);
9219
+ return isRecord2(value) && isNonEmptyString(value["ipacl_group_id"]);
7705
9220
  }
7706
9221
  function isIpAclGroupLoadBalancer(value) {
7707
- return isRecord(value) && isNonEmptyString(value["loadbalancer_id"]);
9222
+ return isRecord2(value) && isNonEmptyString(value["loadbalancer_id"]);
7708
9223
  }
7709
9224
  function isLoadBalancer(value) {
7710
- if (!isRecord(value)) return false;
9225
+ if (!isRecord2(value)) return false;
7711
9226
  return isNonEmptyString(value["id"]) && typeof value["name"] === "string" && typeof value["vip_address"] === "string" && typeof value["provisioning_status"] === "string" && typeof value["operating_status"] === "string" && (value["ipacl_group_action"] === null || isIpAclAction(value["ipacl_group_action"])) && Array.isArray(value["ipacl_groups"]) && value["ipacl_groups"].every(isLoadBalancerIpAclGroup);
7712
9227
  }
7713
9228
  function isIpAclGroup(value) {
7714
- if (!isRecord(value)) return false;
9229
+ if (!isRecord2(value)) return false;
7715
9230
  return isNonEmptyString(value["id"]) && typeof value["name"] === "string" && isIpAclAction(value["action"]) && typeof value["ipacl_target_count"] === "string" && Array.isArray(value["loadbalancers"]) && value["loadbalancers"].every(isIpAclGroupLoadBalancer);
7716
9231
  }
7717
9232
  function isIpAclTarget(value) {
7718
- if (!isRecord(value)) return false;
9233
+ if (!isRecord2(value)) return false;
7719
9234
  return isNonEmptyString(value["id"]) && typeof value["cidr_address"] === "string" && typeof value["description"] === "string" && isNonEmptyString(value["ipacl_group_id"]);
7720
9235
  }
7721
9236
  function isIpAclBinding(value) {
7722
- return isRecord(value) && isNonEmptyString(value["loadbalancer_id"]) && isNonEmptyString(value["ipacl_group_id"]);
9237
+ return isRecord2(value) && isNonEmptyString(value["loadbalancer_id"]) && isNonEmptyString(value["ipacl_group_id"]);
7723
9238
  }
7724
9239
 
7725
9240
  // src/services/loadbalancer/client.ts
7726
- var DEFAULT_TIMEOUT_MS9 = 3e4;
7727
- function isRecord2(value) {
9241
+ function isRecord3(value) {
7728
9242
  return typeof value === "object" && value !== null;
7729
9243
  }
7730
9244
  function requireNonEmptyId(id, label) {
@@ -7735,7 +9249,7 @@ function requireNonEmptyId(id, label) {
7735
9249
  return normalized;
7736
9250
  }
7737
9251
  function readArrayField(response, key, itemGuard, missingKeyMessage, invalidItemMessage) {
7738
- if (!isRecord2(response) || !Array.isArray(response[key])) {
9252
+ if (!isRecord3(response) || !Array.isArray(response[key])) {
7739
9253
  throw new NhnCloudCliError(missingKeyMessage, EXIT_API_ERROR);
7740
9254
  }
7741
9255
  const items = response[key];
@@ -7745,7 +9259,7 @@ function readArrayField(response, key, itemGuard, missingKeyMessage, invalidItem
7745
9259
  return items;
7746
9260
  }
7747
9261
  function readObjectField(response, key, itemGuard, missingKeyMessage, invalidItemMessage) {
7748
- if (!isRecord2(response) || !(key in response)) {
9262
+ if (!isRecord3(response) || !(key in response)) {
7749
9263
  throw new NhnCloudCliError(missingKeyMessage, EXIT_API_ERROR);
7750
9264
  }
7751
9265
  const item = response[key];
@@ -7883,52 +9397,52 @@ var LoadBalancerClient = class {
7883
9397
  }
7884
9398
  return raw;
7885
9399
  }
7886
- async getJson(path3, searchParams) {
7887
- const url = `${this.endpoint}${path3}`;
9400
+ async getJson(path5, searchParams) {
9401
+ const url = `${this.endpoint}${path5}`;
7888
9402
  try {
7889
- return await import_ky13.default.get(url, {
9403
+ return await import_ky14.default.get(url, {
7890
9404
  headers: this.authHeaders(),
7891
9405
  searchParams,
7892
9406
  retry: 0,
7893
- timeout: DEFAULT_TIMEOUT_MS9
9407
+ timeout: DEFAULT_TIMEOUT_MS
7894
9408
  }).json();
7895
9409
  } catch (error) {
7896
9410
  throw toNhnCloudCliError(error);
7897
9411
  }
7898
9412
  }
7899
- async postJson(path3, json) {
7900
- const url = `${this.endpoint}${path3}`;
9413
+ async postJson(path5, json) {
9414
+ const url = `${this.endpoint}${path5}`;
7901
9415
  try {
7902
- return await import_ky13.default.post(url, {
9416
+ return await import_ky14.default.post(url, {
7903
9417
  headers: this.authHeaders(),
7904
9418
  json,
7905
9419
  retry: 0,
7906
- timeout: DEFAULT_TIMEOUT_MS9
9420
+ timeout: DEFAULT_TIMEOUT_MS
7907
9421
  }).json();
7908
9422
  } catch (error) {
7909
9423
  throw toNhnCloudCliError(error);
7910
9424
  }
7911
9425
  }
7912
- async putJson(path3, json) {
7913
- const url = `${this.endpoint}${path3}`;
9426
+ async putJson(path5, json) {
9427
+ const url = `${this.endpoint}${path5}`;
7914
9428
  try {
7915
- return await import_ky13.default.put(url, {
9429
+ return await import_ky14.default.put(url, {
7916
9430
  headers: this.authHeaders(),
7917
9431
  json,
7918
9432
  retry: 0,
7919
- timeout: DEFAULT_TIMEOUT_MS9
9433
+ timeout: DEFAULT_TIMEOUT_MS
7920
9434
  }).json();
7921
9435
  } catch (error) {
7922
9436
  throw toNhnCloudCliError(error);
7923
9437
  }
7924
9438
  }
7925
- async deleteNoContent(path3) {
7926
- const url = `${this.endpoint}${path3}`;
9439
+ async deleteNoContent(path5) {
9440
+ const url = `${this.endpoint}${path5}`;
7927
9441
  try {
7928
- await import_ky13.default.delete(url, {
9442
+ await import_ky14.default.delete(url, {
7929
9443
  headers: this.authHeaders(),
7930
9444
  retry: 0,
7931
- timeout: DEFAULT_TIMEOUT_MS9
9445
+ timeout: DEFAULT_TIMEOUT_MS
7932
9446
  });
7933
9447
  } catch (error) {
7934
9448
  throw toNhnCloudCliError(error);
@@ -8056,7 +9570,7 @@ async function resolveLoadBalancerClient(opts) {
8056
9570
  }
8057
9571
 
8058
9572
  // src/commands/loadbalancer/list.ts
8059
- var listCommand10 = new import_commander48.Command("list").description("Load Balancer \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
9573
+ var listCommand14 = new import_commander52.Command("list").description("Load Balancer \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
8060
9574
  const opts = cmd.optsWithGlobals();
8061
9575
  const { client } = await resolveLoadBalancerClient(opts);
8062
9576
  startSpinner("Load Balancer \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -8094,8 +9608,8 @@ var listCommand10 = new import_commander48.Command("list").description("Load Bal
8094
9608
  });
8095
9609
 
8096
9610
  // src/commands/loadbalancer/get.ts
8097
- var import_commander49 = require("commander");
8098
- var getCommand8 = new import_commander49.Command("get").description("Load Balancer\uB97C \uC774\uB984 \uB610\uB294 UUID\uB85C \uC870\uD68C\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (loadBalancerInput, _opts, cmd) => {
9611
+ var import_commander53 = require("commander");
9612
+ var getCommand9 = new import_commander53.Command("get").description("Load Balancer\uB97C \uC774\uB984 \uB610\uB294 UUID\uB85C \uC870\uD68C\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (loadBalancerInput, _opts, cmd) => {
8099
9613
  const opts = cmd.optsWithGlobals();
8100
9614
  const input = requireResourceInput(loadBalancerInput, "Load Balancer");
8101
9615
  const { client } = await resolveLoadBalancerClient(opts);
@@ -8132,13 +9646,13 @@ var getCommand8 = new import_commander49.Command("get").description("Load Balanc
8132
9646
  });
8133
9647
 
8134
9648
  // src/commands/loadbalancer/ipacl.ts
8135
- var import_commander51 = require("commander");
9649
+ var import_commander55 = require("commander");
8136
9650
 
8137
9651
  // src/commands/loadbalancer/target.ts
8138
- var import_commander50 = require("commander");
9652
+ var import_commander54 = require("commander");
8139
9653
 
8140
9654
  // src/commands/loadbalancer/rebind.ts
8141
- function sanitizeForTerminal(value) {
9655
+ function sanitizeForTerminal2(value) {
8142
9656
  return value.replace(/[\x00-\x1F\x7F]/g, "?");
8143
9657
  }
8144
9658
  function shellQuote(value) {
@@ -8251,9 +9765,9 @@ function writeTargetWarnings(group, result) {
8251
9765
  `
8252
9766
  );
8253
9767
  for (const failure of result.rebind.failed) {
8254
- process.stderr.write(`${sanitizeForTerminal(failure.retry_command)}
9768
+ process.stderr.write(`${sanitizeForTerminal2(failure.retry_command)}
8255
9769
  `);
8256
- process.stderr.write(` \uC624\uB958: ${sanitizeForTerminal(failure.error)}
9770
+ process.stderr.write(` \uC624\uB958: ${sanitizeForTerminal2(failure.error)}
8257
9771
  `);
8258
9772
  }
8259
9773
  }
@@ -8269,7 +9783,7 @@ function targetWriteResult(operation, target, rebind) {
8269
9783
  rebind
8270
9784
  };
8271
9785
  }
8272
- var listCommand11 = new import_commander50.Command("list").description("IP ACL \uB300\uC0C1 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
9786
+ var listCommand15 = new import_commander54.Command("list").description("IP ACL \uB300\uC0C1 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
8273
9787
  const opts = cmd.optsWithGlobals();
8274
9788
  const input = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
8275
9789
  const { client } = await resolveLoadBalancerClient(opts);
@@ -8298,7 +9812,7 @@ var listCommand11 = new import_commander50.Command("list").description("IP ACL \
8298
9812
  ids: targets.map((target) => target.id)
8299
9813
  });
8300
9814
  });
8301
- var addCommand = new import_commander50.Command("add").description("IP ACL \uB300\uC0C1\uC744 \uCD94\uAC00\uD558\uACE0 \uC5F0\uACB0\uB41C Load Balancer\uB97C \uC7AC\uBC14\uC778\uB529\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").requiredOption("--cidr <ip-or-cidr>", "\uCD94\uAC00\uD560 IP \uC8FC\uC18C \uB610\uB294 CIDR").option("--description <text>", "IP ACL \uB300\uC0C1 \uC124\uBA85").option("--no-rebind", "\uB300\uC0C1 \uCD94\uAC00 \uD6C4 Load Balancer \uC7AC\uBC14\uC778\uB529 \uC0DD\uB7B5").option("--yes", "\uB300\uC0C1 \uCD94\uAC00 \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
9815
+ var addCommand = new import_commander54.Command("add").description("IP ACL \uB300\uC0C1\uC744 \uCD94\uAC00\uD558\uACE0 \uC5F0\uACB0\uB41C Load Balancer\uB97C \uC7AC\uBC14\uC778\uB529\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").requiredOption("--cidr <ip-or-cidr>", "\uCD94\uAC00\uD560 IP \uC8FC\uC18C \uB610\uB294 CIDR").option("--description <text>", "IP ACL \uB300\uC0C1 \uC124\uBA85").option("--no-rebind", "\uB300\uC0C1 \uCD94\uAC00 \uD6C4 Load Balancer \uC7AC\uBC14\uC778\uB529 \uC0DD\uB7B5").option("--yes", "\uB300\uC0C1 \uCD94\uAC00 \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
8302
9816
  const opts = cmd.optsWithGlobals();
8303
9817
  requireYes(opts.yes, "IP ACL \uB300\uC0C1 \uCD94\uAC00");
8304
9818
  const parsedGroup = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
@@ -8335,7 +9849,7 @@ var addCommand = new import_commander50.Command("add").description("IP ACL \uB30
8335
9849
  writeTargetWarnings(group, result);
8336
9850
  if (result.status === "partial") process.exitCode = EXIT_API_ERROR;
8337
9851
  });
8338
- var removeCommand = new import_commander50.Command("remove").description("IP ACL \uB300\uC0C1\uC744 \uC0AD\uC81C\uD558\uACE0 \uC5F0\uACB0\uB41C Load Balancer\uB97C \uC7AC\uBC14\uC778\uB529\uD55C\uB2E4").argument("<target-id>", "\uC0AD\uC81C\uD560 IP ACL \uB300\uC0C1 UUID").option("--no-rebind", "\uB300\uC0C1 \uC0AD\uC81C \uD6C4 Load Balancer \uC7AC\uBC14\uC778\uB529 \uC0DD\uB7B5").option("--yes", "\uB300\uC0C1 \uC0AD\uC81C \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (targetInput, _opts, cmd) => {
9852
+ var removeCommand = new import_commander54.Command("remove").description("IP ACL \uB300\uC0C1\uC744 \uC0AD\uC81C\uD558\uACE0 \uC5F0\uACB0\uB41C Load Balancer\uB97C \uC7AC\uBC14\uC778\uB529\uD55C\uB2E4").argument("<target-id>", "\uC0AD\uC81C\uD560 IP ACL \uB300\uC0C1 UUID").option("--no-rebind", "\uB300\uC0C1 \uC0AD\uC81C \uD6C4 Load Balancer \uC7AC\uBC14\uC778\uB529 \uC0DD\uB7B5").option("--yes", "\uB300\uC0C1 \uC0AD\uC81C \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (targetInput, _opts, cmd) => {
8339
9853
  const opts = cmd.optsWithGlobals();
8340
9854
  requireYes(opts.yes, "IP ACL \uB300\uC0C1 \uC0AD\uC81C");
8341
9855
  const parsedTargetId = requireResourceInput(targetInput, "IP ACL \uB300\uC0C1");
@@ -8366,13 +9880,13 @@ var removeCommand = new import_commander50.Command("remove").description("IP ACL
8366
9880
  writeTargetWarnings(group, result);
8367
9881
  if (result.status === "partial") process.exitCode = EXIT_API_ERROR;
8368
9882
  });
8369
- var targetCommand = new import_commander50.Command("target").description("IP ACL \uB300\uC0C1 \uC870\uD68C\xB7\uAD00\uB9AC");
8370
- targetCommand.addCommand(listCommand11);
9883
+ var targetCommand = new import_commander54.Command("target").description("IP ACL \uB300\uC0C1 \uC870\uD68C\xB7\uAD00\uB9AC");
9884
+ targetCommand.addCommand(listCommand15);
8371
9885
  targetCommand.addCommand(addCommand);
8372
9886
  targetCommand.addCommand(removeCommand);
8373
9887
 
8374
9888
  // src/commands/loadbalancer/ipacl.ts
8375
- var listCommand12 = new import_commander51.Command("list").description("IP ACL \uADF8\uB8F9 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
9889
+ var listCommand16 = new import_commander55.Command("list").description("IP ACL \uADF8\uB8F9 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
8376
9890
  const opts = cmd.optsWithGlobals();
8377
9891
  const { client } = await resolveLoadBalancerClient(opts);
8378
9892
  startSpinner("IP ACL \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -8400,7 +9914,7 @@ var listCommand12 = new import_commander51.Command("list").description("IP ACL \
8400
9914
  ids: groups.map((group) => group.id)
8401
9915
  });
8402
9916
  });
8403
- var getCommand9 = new import_commander51.Command("get").description("IP ACL \uADF8\uB8F9\uC744 \uC774\uB984 \uB610\uB294 UUID\uB85C \uC870\uD68C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
9917
+ var getCommand10 = new import_commander55.Command("get").description("IP ACL \uADF8\uB8F9\uC744 \uC774\uB984 \uB610\uB294 UUID\uB85C \uC870\uD68C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
8404
9918
  const opts = cmd.optsWithGlobals();
8405
9919
  const input = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
8406
9920
  const { client } = await resolveLoadBalancerClient(opts);
@@ -8433,7 +9947,7 @@ var getCommand9 = new import_commander51.Command("get").description("IP ACL \uAD
8433
9947
  ids: [group.id]
8434
9948
  });
8435
9949
  });
8436
- var createCommand8 = new import_commander51.Command("create").description("IP ACL \uADF8\uB8F9\uC744 \uC0DD\uC131\uD55C\uB2E4").requiredOption("--name <name>", "IP ACL \uADF8\uB8F9 \uC774\uB984").requiredOption("--action <ALLOW|DENY>", "IP \uC811\uADFC \uC81C\uC5B4 \uB3D9\uC791").option("--description <text>", "IP ACL \uADF8\uB8F9 \uC124\uBA85").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
9950
+ var createCommand8 = new import_commander55.Command("create").description("IP ACL \uADF8\uB8F9\uC744 \uC0DD\uC131\uD55C\uB2E4").requiredOption("--name <name>", "IP ACL \uADF8\uB8F9 \uC774\uB984").requiredOption("--action <ALLOW|DENY>", "IP \uC811\uADFC \uC81C\uC5B4 \uB3D9\uC791").option("--description <text>", "IP ACL \uADF8\uB8F9 \uC124\uBA85").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
8437
9951
  const opts = cmd.optsWithGlobals();
8438
9952
  const parsedName = requireResourceInput(opts.name ?? "", "IP ACL \uADF8\uB8F9");
8439
9953
  const parsedAction = parseIpAclAction(opts.action ?? "");
@@ -8464,7 +9978,7 @@ var createCommand8 = new import_commander51.Command("create").description("IP AC
8464
9978
  ids: [group.id]
8465
9979
  });
8466
9980
  });
8467
- var deleteCommand7 = new import_commander51.Command("delete").description("IP ACL \uADF8\uB8F9\uACFC \uD558\uC704 \uB300\uC0C1\uC744 \uC0AD\uC81C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--yes", "\uC0AD\uC81C\uC640 \uC5F0\uACB0 \uADDC\uCE59 \uC81C\uAC70 \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
9981
+ var deleteCommand7 = new import_commander55.Command("delete").description("IP ACL \uADF8\uB8F9\uACFC \uD558\uC704 \uB300\uC0C1\uC744 \uC0AD\uC81C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--yes", "\uC0AD\uC81C\uC640 \uC5F0\uACB0 \uADDC\uCE59 \uC81C\uAC70 \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
8468
9982
  const opts = cmd.optsWithGlobals();
8469
9983
  const confirmedYes = requireYes(opts.yes, "IP ACL \uADF8\uB8F9 \uC0AD\uC81C");
8470
9984
  const parsedGroup = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
@@ -8496,9 +10010,9 @@ var deleteCommand7 = new import_commander51.Command("delete").description("IP AC
8496
10010
  ids: [groupId]
8497
10011
  });
8498
10012
  });
8499
- var ipaclCommand = new import_commander51.Command("ipacl").description("IP ACL \uADF8\uB8F9\xB7\uB300\uC0C1 \uC870\uD68C");
8500
- ipaclCommand.addCommand(listCommand12);
8501
- ipaclCommand.addCommand(getCommand9);
10013
+ var ipaclCommand = new import_commander55.Command("ipacl").description("IP ACL \uADF8\uB8F9\xB7\uB300\uC0C1 \uC870\uD68C");
10014
+ ipaclCommand.addCommand(listCommand16);
10015
+ ipaclCommand.addCommand(getCommand10);
8502
10016
  ipaclCommand.addCommand(createCommand8);
8503
10017
  ipaclCommand.addCommand(deleteCommand7);
8504
10018
  ipaclCommand.addCommand(targetCommand);
@@ -8512,7 +10026,7 @@ function configureLoadBalancerHelp(command) {
8512
10026
  }
8513
10027
 
8514
10028
  // src/commands/loadbalancer/binding.ts
8515
- var import_commander52 = require("commander");
10029
+ var import_commander56 = require("commander");
8516
10030
  function bindingResult(operation, loadBalancerId, groupIds) {
8517
10031
  return {
8518
10032
  operation,
@@ -8534,7 +10048,7 @@ function outputBindingResult(opts, result) {
8534
10048
  ids: [result.loadbalancer_id]
8535
10049
  });
8536
10050
  }
8537
- var setIpAclCommand2 = new import_commander52.Command("set-ipacl").description("Load Balancer\uC758 IP ACL \uADF8\uB8F9 \uC5F0\uACB0\uC744 \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").requiredOption(
10051
+ var setIpAclCommand2 = new import_commander56.Command("set-ipacl").description("Load Balancer\uC758 IP ACL \uADF8\uB8F9 \uC5F0\uACB0\uC744 \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").requiredOption(
8538
10052
  "--group <group>",
8539
10053
  "\uC801\uC6A9\uD560 IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID (\uBC18\uBCF5 \uAC00\uB2A5)",
8540
10054
  collectOption
@@ -8574,7 +10088,7 @@ var setIpAclCommand2 = new import_commander52.Command("set-ipacl").description("
8574
10088
  bindingResult("loadbalancer-set-ipacl", loadBalancerId, groupIds)
8575
10089
  );
8576
10090
  });
8577
- var clearIpAclCommand = new import_commander52.Command("clear-ipacl").description("Load Balancer\uC758 \uBAA8\uB4E0 IP ACL \uADF8\uB8F9 \uC5F0\uACB0\uC744 \uD574\uC81C\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").option("--yes", "\uBAA8\uB4E0 IP ACL \uC5F0\uACB0 \uD574\uC81C \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (loadBalancerInput, _opts, cmd) => {
10091
+ var clearIpAclCommand = new import_commander56.Command("clear-ipacl").description("Load Balancer\uC758 \uBAA8\uB4E0 IP ACL \uADF8\uB8F9 \uC5F0\uACB0\uC744 \uD574\uC81C\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").option("--yes", "\uBAA8\uB4E0 IP ACL \uC5F0\uACB0 \uD574\uC81C \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (loadBalancerInput, _opts, cmd) => {
8578
10092
  const opts = cmd.optsWithGlobals();
8579
10093
  const confirmedYes = requireYes(opts.yes, "Load Balancer IP ACL \uC5F0\uACB0 \uD574\uC81C");
8580
10094
  const parsedLoadBalancer = requireResourceInput(loadBalancerInput, "Load Balancer");
@@ -8662,34 +10176,44 @@ Agent workflow:
8662
10176
  2. nhncloud ncs workload list --json
8663
10177
  3. nhncloud ncs workload get <id> --json
8664
10178
  `;
8665
- var program = new import_commander53.Command();
8666
- program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version("0.12.0").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "\uCD5C\uC18C \uCD9C\uB825 (\uC790\uB3D9\uD654\uC6A9)").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654").addHelpText("after", rootAgentHints);
10179
+ var program = new import_commander57.Command();
10180
+ program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version("0.13.0").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "\uCD5C\uC18C \uCD9C\uB825 (\uC790\uB3D9\uD654\uC6A9)").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654").option("--request-timeout <sec>", "HTTP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3 (\uCD08, \uAE30\uBCF8 30, \uBC94\uC704 1~3600). NHNCLOUD_REQUEST_TIMEOUT \uB85C\uB3C4 \uC9C0\uC815").addHelpText("after", rootAgentHints);
8667
10181
  program.hook("preAction", () => {
8668
10182
  const opts = program.opts();
10183
+ const rawTimeout = opts.requestTimeout ?? process.env["NHNCLOUD_REQUEST_TIMEOUT"];
10184
+ const timeoutValue = rawTimeout === "" ? void 0 : rawTimeout;
10185
+ const timeoutSec = timeoutValue === void 0 ? void 0 : parseIntegerOption(
10186
+ timeoutValue,
10187
+ opts.requestTimeout !== void 0 ? "--request-timeout" : "NHNCLOUD_REQUEST_TIMEOUT",
10188
+ { min: 1, max: 3600 }
10189
+ );
8669
10190
  if (!opts.color || process.env["NO_COLOR"]) {
8670
- import_chalk18.default.level = 0;
10191
+ import_chalk17.default.level = 0;
8671
10192
  }
8672
10193
  if (opts.json || opts.quiet) {
8673
10194
  setQuiet(true);
8674
10195
  }
10196
+ if (timeoutSec !== void 0) {
10197
+ setRequestTimeoutMs(timeoutSec * 1e3);
10198
+ }
8675
10199
  });
8676
10200
  program.addCommand(configureCommand);
8677
- var logncrashCommand = new import_commander53.Command("logncrash").description("Log & Crash \uAD00\uB828 \uBA85\uB839").addHelpText("after", logncrashAgentWorkflow);
10201
+ var logncrashCommand = new import_commander57.Command("logncrash").description("Log & Crash \uAD00\uB828 \uBA85\uB839").addHelpText("after", logncrashAgentWorkflow);
8678
10202
  logncrashCommand.addCommand(searchCommand);
8679
10203
  logncrashCommand.addCommand(sendCommand);
8680
10204
  logncrashCommand.addCommand(exportCommand);
8681
10205
  program.addCommand(logncrashCommand);
8682
- var deployCommand = new import_commander53.Command("deploy").description("NHN Cloud Deploy \uAD00\uB828 \uBA85\uB839").addHelpText("after", deployAgentWorkflow);
8683
- deployCommand.addCommand(runCommand);
8684
- deployCommand.addCommand(artifactsCommand);
8685
- deployCommand.addCommand(serverGroupsCommand);
8686
- deployCommand.addCommand(historiesCommand);
8687
- deployCommand.addCommand(binaryGroupsCommand);
8688
- deployCommand.addCommand(binariesCommand);
8689
- deployCommand.addCommand(uploadCommand);
8690
- deployCommand.addCommand(downloadCommand);
8691
- program.addCommand(deployCommand);
8692
- var instanceCommand = new import_commander53.Command("instance").description("Compute \uC778\uC2A4\uD134\uC2A4 \uAD00\uB828 \uBA85\uB839").addHelpText("after", instanceAgentWorkflow);
10206
+ var deployCommand2 = new import_commander57.Command("deploy").description("NHN Cloud Deploy \uAD00\uB828 \uBA85\uB839").addHelpText("after", deployAgentWorkflow);
10207
+ deployCommand2.addCommand(runCommand);
10208
+ deployCommand2.addCommand(artifactsCommand);
10209
+ deployCommand2.addCommand(serverGroupsCommand);
10210
+ deployCommand2.addCommand(historiesCommand);
10211
+ deployCommand2.addCommand(binaryGroupsCommand);
10212
+ deployCommand2.addCommand(binariesCommand);
10213
+ deployCommand2.addCommand(uploadCommand);
10214
+ deployCommand2.addCommand(downloadCommand);
10215
+ program.addCommand(deployCommand2);
10216
+ var instanceCommand = new import_commander57.Command("instance").description("Compute \uC778\uC2A4\uD134\uC2A4 \uAD00\uB828 \uBA85\uB839").addHelpText("after", instanceAgentWorkflow);
8693
10217
  instanceCommand.addCommand(listCommand);
8694
10218
  instanceCommand.addCommand(flavorsCommand);
8695
10219
  instanceCommand.addCommand(availabilityZonesCommand);
@@ -8708,54 +10232,59 @@ instanceCommand.addCommand(keypairCommand);
8708
10232
  instanceCommand.addCommand(volumeCommand);
8709
10233
  instanceCommand.addCommand(volumesCommand);
8710
10234
  program.addCommand(instanceCommand);
8711
- var networkCommand = new import_commander53.Command("network").description("VPC\xB7\uC11C\uBE0C\uB137 \uC870\uD68C").addHelpText("after", networkAgentWorkflow);
10235
+ var networkCommand = new import_commander57.Command("network").description("VPC\xB7\uC11C\uBE0C\uB137 \uC870\uD68C").addHelpText("after", networkAgentWorkflow);
8712
10236
  networkCommand.addCommand(listCommand3);
8713
10237
  networkCommand.addCommand(subnetCommand);
8714
10238
  program.addCommand(networkCommand);
8715
- var volumeCommand2 = new import_commander53.Command("volume").description("Block Storage \uBCFC\uB968 \uAD00\uB828 \uBA85\uB839").addHelpText("after", volumeAgentWorkflow);
10239
+ var volumeCommand2 = new import_commander57.Command("volume").description("Block Storage \uBCFC\uB968 \uAD00\uB828 \uBA85\uB839").addHelpText("after", volumeAgentWorkflow);
8716
10240
  volumeCommand2.addCommand(listCommand2);
8717
10241
  volumeCommand2.addCommand(getCommand);
8718
10242
  volumeCommand2.addCommand(createCommand);
8719
10243
  program.addCommand(volumeCommand2);
8720
- var floatingipCommand = new import_commander53.Command("floatingip").description(
10244
+ var floatingipCommand = new import_commander57.Command("floatingip").description(
8721
10245
  "Floating IP(\uC778\uC2A4\uD134\uC2A4 \uACF5\uC778 IP) \uAD00\uB9AC"
8722
10246
  ).addHelpText("after", floatingIpAgentWorkflow);
8723
10247
  floatingipCommand.addCommand(listCommand4);
8724
10248
  floatingipCommand.addCommand(createCommand2);
8725
10249
  floatingipCommand.addCommand(deleteCommand);
8726
10250
  program.addCommand(floatingipCommand);
8727
- var loadbalancerCommand = new import_commander53.Command("loadbalancer").description("Load Balancer\xB7IP ACL \uC870\uD68C\xB7\uAD00\uB9AC").addHelpText("after", loadbalancerAgentWorkflow);
8728
- loadbalancerCommand.addCommand(listCommand10);
8729
- loadbalancerCommand.addCommand(getCommand8);
10251
+ var loadbalancerCommand = new import_commander57.Command("loadbalancer").description("Load Balancer\xB7IP ACL \uC870\uD68C\xB7\uAD00\uB9AC").addHelpText("after", loadbalancerAgentWorkflow);
10252
+ loadbalancerCommand.addCommand(listCommand14);
10253
+ loadbalancerCommand.addCommand(getCommand9);
8730
10254
  loadbalancerCommand.addCommand(ipaclCommand);
8731
10255
  loadbalancerCommand.addCommand(setIpAclCommand2);
8732
10256
  loadbalancerCommand.addCommand(clearIpAclCommand);
8733
10257
  configureLoadBalancerHelp(loadbalancerCommand);
8734
10258
  program.addCommand(loadbalancerCommand);
8735
- var ncrCommand = new import_commander53.Command("ncr").description("NHN Container Registry \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncrAgentWorkflow);
10259
+ var ncrCommand = new import_commander57.Command("ncr").description("NHN Container Registry \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncrAgentWorkflow);
8736
10260
  ncrCommand.addCommand(listCommand5);
8737
10261
  ncrCommand.addCommand(getCommand3);
8738
10262
  ncrCommand.addCommand(imagesCommand2);
8739
10263
  ncrCommand.addCommand(tagsCommand);
8740
10264
  program.addCommand(ncrCommand);
8741
- var nksCommand = new import_commander53.Command("nks").description("NHN Kubernetes Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", nksAgentWorkflow);
10265
+ var nksCommand = new import_commander57.Command("nks").description("NHN Kubernetes Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", nksAgentWorkflow);
8742
10266
  nksCommand.addCommand(supportsCommand);
8743
10267
  nksCommand.addCommand(clusterCommand);
8744
10268
  nksCommand.addCommand(nodegroupCommand);
8745
10269
  nksCommand.addCommand(addonTypeCommand);
8746
10270
  nksCommand.addCommand(addonCommand);
8747
10271
  program.addCommand(nksCommand);
8748
- var ncsCommand = new import_commander53.Command("ncs").description("NHN Container Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncsAgentWorkflow);
10272
+ var ncsCommand = new import_commander57.Command("ncs").description("NHN Container Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncsAgentWorkflow);
8749
10273
  ncsCommand.addCommand(templateCommand);
8750
10274
  ncsCommand.addCommand(workloadCommand);
8751
10275
  ncsCommand.addCommand(malwareCommand);
8752
10276
  program.addCommand(ncsCommand);
10277
+ var apiGatewayCommand = new import_commander57.Command("apigateway").description("NHN API Gateway \uC870\uD68C \uBA85\uB839");
10278
+ apiGatewayCommand.addCommand(serviceCommand);
10279
+ apiGatewayCommand.addCommand(resourceCommand);
10280
+ apiGatewayCommand.addCommand(stageCommand);
10281
+ program.addCommand(apiGatewayCommand);
8753
10282
  program.addCommand(skillsCommand);
8754
10283
  program.addCommand(doctorCommand);
8755
10284
  program.addCommand(createCommandsCommand(program));
8756
10285
  program.parseAsync().catch((err) => {
8757
10286
  const message = err instanceof Error ? err.message : String(err);
8758
10287
  const exitCode = err instanceof NhnCloudCliError ? err.exitCode : 1;
8759
- process.stderr.write(import_chalk18.default.red(`\uC624\uB958: ${message}`) + "\n");
10288
+ process.stderr.write(import_chalk17.default.red(`\uC624\uB958: ${message}`) + "\n");
8760
10289
  process.exit(exitCode);
8761
10290
  });