@apps-in-toss/cli 0.0.0-dev.1757056983098 → 0.0.0-dev.1757939087965

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.
Files changed (3) hide show
  1. package/dist/index.cjs +391 -125
  2. package/dist/index.js +390 -124
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -193,11 +193,11 @@ var require_common = __commonJS({
193
193
  let enableOverride = null;
194
194
  let namespacesCache;
195
195
  let enabledCache;
196
- function debug5(...args) {
197
- if (!debug5.enabled) {
196
+ function debug6(...args) {
197
+ if (!debug6.enabled) {
198
198
  return;
199
199
  }
200
- const self = debug5;
200
+ const self = debug6;
201
201
  const curr = Number(/* @__PURE__ */ new Date());
202
202
  const ms = curr - (prevTime || curr);
203
203
  self.diff = ms;
@@ -227,12 +227,12 @@ var require_common = __commonJS({
227
227
  const logFn = self.log || createDebug.log;
228
228
  logFn.apply(self, args);
229
229
  }
230
- debug5.namespace = namespace;
231
- debug5.useColors = createDebug.useColors();
232
- debug5.color = createDebug.selectColor(namespace);
233
- debug5.extend = extend;
234
- debug5.destroy = createDebug.destroy;
235
- Object.defineProperty(debug5, "enabled", {
230
+ debug6.namespace = namespace;
231
+ debug6.useColors = createDebug.useColors();
232
+ debug6.color = createDebug.selectColor(namespace);
233
+ debug6.extend = extend;
234
+ debug6.destroy = createDebug.destroy;
235
+ Object.defineProperty(debug6, "enabled", {
236
236
  enumerable: true,
237
237
  configurable: false,
238
238
  get: () => {
@@ -250,9 +250,9 @@ var require_common = __commonJS({
250
250
  }
251
251
  });
252
252
  if (typeof createDebug.init === "function") {
253
- createDebug.init(debug5);
253
+ createDebug.init(debug6);
254
254
  }
255
- return debug5;
255
+ return debug6;
256
256
  }
257
257
  function extend(namespace, delimiter) {
258
258
  const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
@@ -666,11 +666,11 @@ var require_node = __commonJS({
666
666
  function load() {
667
667
  return process.env.DEBUG;
668
668
  }
669
- function init(debug5) {
670
- debug5.inspectOpts = {};
669
+ function init(debug6) {
670
+ debug6.inspectOpts = {};
671
671
  const keys = Object.keys(exports.inspectOpts);
672
672
  for (let i = 0; i < keys.length; i++) {
673
- debug5.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
673
+ debug6.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
674
674
  }
675
675
  }
676
676
  module.exports = require_common()(exports);
@@ -704,10 +704,10 @@ var require_picocolors = __commonJS({
704
704
  "../../.yarn/cache/picocolors-npm-1.1.1-b0c45fa35e-e2e3e8170a.zip/node_modules/picocolors/picocolors.js"(exports, module) {
705
705
  "use strict";
706
706
  init_esm_shims();
707
- var p4 = process || {};
708
- var argv = p4.argv || [];
709
- var env = p4.env || {};
710
- var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p4.platform === "win32" || (p4.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
707
+ var p5 = process || {};
708
+ var argv = p5.argv || [];
709
+ var env = p5.env || {};
710
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p5.platform === "win32" || (p5.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
711
711
  var formatter = (open, close, replace = open) => (input) => {
712
712
  let string = "" + input, index = string.indexOf(close, open.length);
713
713
  return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
@@ -775,19 +775,73 @@ var require_picocolors = __commonJS({
775
775
 
776
776
  // src/index.ts
777
777
  init_esm_shims();
778
- import { Cli } from "clipanion";
778
+ import { Cli, Builtins } from "clipanion";
779
779
 
780
780
  // src/DeployCommand.ts
781
781
  init_esm_shims();
782
782
  var import_debug3 = __toESM(require_src(), 1);
783
783
  var import_picocolors = __toESM(require_picocolors(), 1);
784
784
  import assert from "assert";
785
- import fs2 from "fs";
786
- import path from "path";
785
+ import fs3 from "fs";
786
+ import path2 from "path";
787
787
  import * as p from "@clack/prompts";
788
788
  import { getPackageRoot, readZipContent } from "@granite-js/utils";
789
789
  import { Command, Option } from "clipanion";
790
790
 
791
+ // src/utils/TokenStorage.ts
792
+ init_esm_shims();
793
+ import fs from "fs";
794
+ import os from "os";
795
+ import path from "path";
796
+ var TokenStorage = class {
797
+ static get path() {
798
+ const home = os.homedir();
799
+ const dir = path.join(home, ".ait");
800
+ if (!fs.existsSync(dir)) {
801
+ fs.mkdirSync(dir, { recursive: true });
802
+ }
803
+ return path.join(dir, "credentials");
804
+ }
805
+ static read() {
806
+ const file = this.path;
807
+ if (!fs.existsSync(file)) {
808
+ return {};
809
+ }
810
+ const raw = fs.readFileSync(file, "utf8");
811
+ try {
812
+ const parsed = JSON.parse(raw);
813
+ if (parsed && typeof parsed === "object") {
814
+ return parsed;
815
+ }
816
+ } catch {
817
+ }
818
+ return {};
819
+ }
820
+ static write(map) {
821
+ const file = this.path;
822
+ const content = JSON.stringify(map, null, 2);
823
+ fs.writeFileSync(file, content, { encoding: "utf8" });
824
+ }
825
+ static set(workspace, token) {
826
+ const creds = this.read();
827
+ creds[workspace] = token;
828
+ this.write(creds);
829
+ }
830
+ static delete(workspace) {
831
+ const creds = this.read();
832
+ if (workspace in creds) {
833
+ delete creds[workspace];
834
+ this.write(creds);
835
+ return true;
836
+ }
837
+ return false;
838
+ }
839
+ static get(workspace) {
840
+ const creds = this.read();
841
+ return creds[workspace];
842
+ }
843
+ };
844
+
791
845
  // src/utils/constants.ts
792
846
  init_esm_shims();
793
847
  var APP_MANIFEST_NAME = "app.json";
@@ -796,7 +850,19 @@ var DEFAULT_API_BASE_URL = "https://apps-in-toss.toss.im/console";
796
850
  // src/utils/upload.ts
797
851
  init_esm_shims();
798
852
  var import_debug2 = __toESM(require_src(), 1);
799
- import fs from "fs";
853
+ import fs2 from "fs";
854
+
855
+ // src/utils/flowAsync.ts
856
+ init_esm_shims();
857
+ function flowAsync(...funcs) {
858
+ return async function(...args) {
859
+ let result = funcs.length ? await funcs[0].apply(this, args) : args[0];
860
+ for (let i = 1; i < funcs.length; i++) {
861
+ result = await funcs[i]?.call(this, result);
862
+ }
863
+ return result;
864
+ };
865
+ }
800
866
 
801
867
  // src/utils/handleFetchResponse.ts
802
868
  init_esm_shims();
@@ -811,29 +877,139 @@ async function handleFetchResponse(response) {
811
877
  debug("response", data);
812
878
  if (data.resultType !== "SUCCESS") {
813
879
  const errorCode = data?.error?.errorCode ?? "-1";
814
- const errorReason = data?.error.reason ?? "unknown";
880
+ const errorReason = data?.error?.reason ?? "unknown";
815
881
  throw new Error(`${errorReason} (Code: ${errorCode})`);
816
882
  }
883
+ return data.success;
884
+ }
885
+
886
+ // src/utils/withRetry.ts
887
+ init_esm_shims();
888
+ import { setTimeout as sleep } from "node:timers/promises";
889
+ async function withRetry(fn, options = {}) {
890
+ const { maxRetries = 60, delayMs = 1e4, shouldRetryOnResult, shouldRetryOnError, onRetry } = options;
891
+ let attempt = 0;
892
+ while (attempt < maxRetries) {
893
+ try {
894
+ const result = await fn();
895
+ if (shouldRetryOnResult && shouldRetryOnResult(result)) {
896
+ onRetry?.(attempt + 1, { result });
897
+ await sleep(delayMs);
898
+ attempt++;
899
+ continue;
900
+ }
901
+ return result;
902
+ } catch (error) {
903
+ const retryable = shouldRetryOnError ? shouldRetryOnError(error) : false;
904
+ if (!retryable) {
905
+ throw error;
906
+ }
907
+ onRetry?.(attempt + 1, { error });
908
+ await sleep(delayMs);
909
+ attempt++;
910
+ }
911
+ }
912
+ throw new Error("\uCD5C\uB300 \uB300\uAE30\uC2DC\uAC04\uC744 \uCD08\uACFC\uD588\uC5B4\uC694.");
817
913
  }
818
914
 
819
915
  // src/utils/upload.ts
820
916
  var debug2 = (0, import_debug2.default)("cli:deploy");
821
917
  async function uploadArtifact(config) {
822
918
  debug2("uploadArtifact", config);
823
- const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
824
- const response = await fetch(
825
- `${baseUrl}/api-public/v3/appsintossconsole/bundles/${config.appName}/deployments/${config.deploymentId}/upload`,
826
- {
919
+ return flowAsync(uploadStart(), uploadArtifactToRemote(), uploadComplete(), checkBundleStatus())(config);
920
+ }
921
+ function uploadStart() {
922
+ return async (config) => {
923
+ debug2("uploadStart", config);
924
+ const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
925
+ const response = await fetch(`${baseUrl}/api-public/v3/openapi/bundles/${config.appName}/upload-start`, {
827
926
  method: "POST",
828
927
  headers: {
829
- "Content-Type": "application/octet-stream",
830
- "X-Ait-Console-Api-Key": config.apiKey
928
+ "Content-Type": "application/json",
929
+ Authorization: `Bearer ${config.apiKey}`
831
930
  },
832
- body: fs.createReadStream(config.artifactPath),
931
+ body: JSON.stringify({
932
+ deploymentId: config.deploymentId
933
+ })
934
+ });
935
+ return {
936
+ config,
937
+ output: await handleFetchResponse(response)
938
+ };
939
+ };
940
+ }
941
+ function uploadArtifactToRemote() {
942
+ return async (params) => {
943
+ const { config, output } = params;
944
+ debug2("uploadArtifactToRemote", config, output);
945
+ const stat = await fs2.promises.stat(config.artifactPath);
946
+ const stream = fs2.createReadStream(config.artifactPath);
947
+ const response = await fetch(output.uploadUrl, {
948
+ method: "PUT",
949
+ headers: {
950
+ "Content-Type": "application/zip",
951
+ "Content-Length": String(stat.size)
952
+ },
953
+ body: stream,
833
954
  duplex: "half"
955
+ });
956
+ if (!response.ok) {
957
+ throw new Error("\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.");
834
958
  }
835
- );
836
- return handleFetchResponse(response);
959
+ return config;
960
+ };
961
+ }
962
+ function uploadComplete() {
963
+ return async (config) => {
964
+ debug2("uploadComplete", config);
965
+ const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
966
+ const response = await fetch(`${baseUrl}/api-public/v3/openapi/bundles/${config.appName}/upload-complete`, {
967
+ method: "POST",
968
+ headers: {
969
+ "Content-Type": "application/json",
970
+ Authorization: `Bearer ${config.apiKey}`
971
+ },
972
+ body: JSON.stringify({
973
+ deploymentId: config.deploymentId
974
+ })
975
+ });
976
+ await handleFetchResponse(response);
977
+ return config;
978
+ };
979
+ }
980
+ function checkBundleStatus(delayMs = 1e4, maxRetries = 10) {
981
+ return async (config) => {
982
+ const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
983
+ function assertBuildNotFailed(config2, reviewStatus2) {
984
+ if (reviewStatus2 === "BUILD_FAILED") {
985
+ throw new Error(
986
+ `\uBE4C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uCF58\uC194\uC5D0\uC11C \uBE4C\uB4DC \uC2E4\uD328 \uC0AC\uC720\uB97C \uD655\uC778\uD574\uC8FC\uC138\uC694.(deploymentId: ${config2.deploymentId})`
987
+ );
988
+ }
989
+ }
990
+ async function pollBundleStatus() {
991
+ const response = await fetch(
992
+ `${baseUrl}/api-public/v3/openapi/bundles/${config.appName}/deployments/${config.deploymentId}`,
993
+ {
994
+ method: "GET",
995
+ headers: {
996
+ "Content-Type": "application/json",
997
+ Authorization: `Bearer ${config.apiKey}`
998
+ }
999
+ }
1000
+ );
1001
+ const { reviewStatus: reviewStatus2 } = await handleFetchResponse(response);
1002
+ return reviewStatus2;
1003
+ }
1004
+ const reviewStatus = await withRetry(pollBundleStatus, {
1005
+ maxRetries,
1006
+ delayMs,
1007
+ shouldRetryOnResult: (reviewStatus2) => reviewStatus2 === "BUILDING" || reviewStatus2 === "PREPARE",
1008
+ shouldRetryOnError: () => false,
1009
+ onRetry: (attempt, info) => debug2("checkBundleStatus: retry", { attempt, ...info })
1010
+ });
1011
+ assertBuildNotFailed(config, reviewStatus);
1012
+ };
837
1013
  }
838
1014
 
839
1015
  // src/DeployCommand.ts
@@ -844,30 +1020,27 @@ var DeployCommand = class extends Command {
844
1020
  required: false,
845
1021
  description: "\uC54C\uD30C \uBC30\uD3EC\uB97C \uC704\uD55C API \uD0A4"
846
1022
  });
1023
+ workspace = Option.String("--workspace", {
1024
+ required: false,
1025
+ description: "\uD1A0\uD070 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uC774\uB984"
1026
+ });
847
1027
  baseUrl = Option.String("--base-url", {
848
1028
  description: "API Base URL"
849
1029
  });
850
1030
  async execute() {
851
1031
  const baseUrl = this.baseUrl;
852
- const apiKey = this.apiKey || await p.password({
853
- message: "\uC571\uC778\uD1A0\uC2A4 \uBC30\uD3EC API \uD0A4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",
854
- validate: (value) => {
855
- if (value.length === 0) {
856
- return "API \uD0A4\uB294 \uD544\uC218 \uC785\uB825 \uD56D\uBAA9\uC785\uB2C8\uB2E4.";
857
- }
858
- return;
859
- }
860
- });
1032
+ const workspace = this.workspace || "default";
1033
+ const apiKey = await this.getApiKey(workspace);
861
1034
  if (p.isCancel(apiKey)) {
862
1035
  return;
863
1036
  }
864
1037
  try {
865
1038
  const packageRoot = getPackageRoot();
866
- const artifactFile = fs2.readdirSync(packageRoot).find((file) => file.endsWith(".ait"));
1039
+ const artifactFile = fs3.readdirSync(packageRoot).find((file) => file.endsWith(".ait"));
867
1040
  if (!artifactFile) {
868
1041
  throw new Error("\uBC30\uD3EC\uD560 .ait \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
869
1042
  }
870
- const resolvedArtifactPath = path.resolve(packageRoot, artifactFile);
1043
+ const resolvedArtifactPath = path2.resolve(packageRoot, artifactFile);
871
1044
  const { appName, deploymentId } = await readZipContent(resolvedArtifactPath, APP_MANIFEST_NAME).then((rawAppManifest) => {
872
1045
  const appManifest = JSON.parse(rawAppManifest);
873
1046
  const appName2 = appManifest.appName;
@@ -905,12 +1078,27 @@ var DeployCommand = class extends Command {
905
1078
  process.exit(1);
906
1079
  }
907
1080
  }
1081
+ async getApiKey(workspace) {
1082
+ const token = TokenStorage.get(workspace) || this.apiKey;
1083
+ if (token) {
1084
+ return token;
1085
+ }
1086
+ return await p.password({
1087
+ message: "\uC571\uC778\uD1A0\uC2A4 \uBC30\uD3EC API \uD0A4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",
1088
+ validate: (value) => {
1089
+ if (value.length === 0) {
1090
+ return "API \uD0A4\uB294 \uD544\uC218 \uC785\uB825 \uD56D\uBAA9\uC785\uB2C8\uB2E4.";
1091
+ }
1092
+ return;
1093
+ }
1094
+ });
1095
+ }
908
1096
  };
909
1097
 
910
1098
  // src/InitCommand.ts
911
1099
  init_esm_shims();
912
- import fs3 from "fs";
913
- import path2 from "path";
1100
+ import fs4 from "fs";
1101
+ import path3 from "path";
914
1102
  import * as p2 from "@clack/prompts";
915
1103
  import { getPackageRoot as getPackageRoot2 } from "@granite-js/utils";
916
1104
  import { Command as Command2, Option as Option2 } from "clipanion";
@@ -1012,7 +1200,7 @@ function transformTemplate(templateString, values) {
1012
1200
 
1013
1201
  // src/InitCommand.ts
1014
1202
  async function templateWebFramework({ appName, cwd, skipInput }) {
1015
- const packageJson = await fs3.promises.readFile(path2.join(cwd, "package.json"), {
1203
+ const packageJson = await fs4.promises.readFile(path3.join(cwd, "package.json"), {
1016
1204
  encoding: "utf-8"
1017
1205
  });
1018
1206
  const scripts = JSON.parse(packageJson);
@@ -1023,11 +1211,11 @@ async function templateWebFramework({ appName, cwd, skipInput }) {
1023
1211
  scripts.scripts.dev = "granite dev";
1024
1212
  scripts.scripts.build = "granite build";
1025
1213
  scripts.scripts.deploy = "ait deploy";
1026
- await fs3.promises.writeFile(path2.join(cwd, "package.json"), JSON.stringify(scripts, null, 2), {
1214
+ await fs4.promises.writeFile(path3.join(cwd, "package.json"), JSON.stringify(scripts, null, 2), {
1027
1215
  encoding: "utf-8"
1028
1216
  });
1029
1217
  p2.log.step(".gitignore \uD30C\uC77C\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911...");
1030
- await fs3.promises.appendFile(path2.join(cwd, ".gitignore"), "\n.granite\n");
1218
+ await fs4.promises.appendFile(path3.join(cwd, ".gitignore"), "\n.granite\n");
1031
1219
  const placeholder = {
1032
1220
  dev: originalScripts.dev === "granite dev" ? "" : originalScripts.dev,
1033
1221
  build: originalScripts.build === "granite build" ? "" : originalScripts.build
@@ -1067,7 +1255,7 @@ async function templateWebFramework({ appName, cwd, skipInput }) {
1067
1255
  webDevCommand: scriptInputs.dev === "granite dev" ? "" : scriptInputs.dev,
1068
1256
  webBuildCommand: scriptInputs.build === "granite build" ? "" : scriptInputs.build
1069
1257
  });
1070
- await fs3.promises.writeFile(path2.join(cwd, "granite.config.ts"), config, {
1258
+ await fs4.promises.writeFile(path3.join(cwd, "granite.config.ts"), config, {
1071
1259
  encoding: "utf-8"
1072
1260
  });
1073
1261
  }
@@ -1076,11 +1264,11 @@ async function templateReactNative({ appName, cwd }) {
1076
1264
  const config = transformTemplate(REACT_NATIVE_FRAMEWORK_CONFIG_TEMPLATE, {
1077
1265
  appName
1078
1266
  });
1079
- await fs3.promises.writeFile(path2.join(cwd, "granite.config.ts"), config, {
1267
+ await fs4.promises.writeFile(path3.join(cwd, "granite.config.ts"), config, {
1080
1268
  encoding: "utf-8"
1081
1269
  });
1082
1270
  p2.log.step("src/_app.tsx \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1083
- await fs3.promises.writeFile(path2.join(cwd, "src", "_app.tsx"), APP_TEMPLATE, {
1271
+ await fs4.promises.writeFile(path3.join(cwd, "src", "_app.tsx"), APP_TEMPLATE, {
1084
1272
  encoding: "utf-8"
1085
1273
  });
1086
1274
  }
@@ -1198,24 +1386,24 @@ init_esm_shims();
1198
1386
 
1199
1387
  // src/MigrateCommand/fs/fileProcessor.ts
1200
1388
  init_esm_shims();
1201
- import { promises as fs4 } from "fs";
1389
+ import { promises as fs5 } from "fs";
1202
1390
  async function readFile(filePath) {
1203
1391
  try {
1204
- return await fs4.readFile(filePath, "utf-8");
1392
+ return await fs5.readFile(filePath, "utf-8");
1205
1393
  } catch {
1206
1394
  throw new Error(`Failed to read file: ${filePath}`);
1207
1395
  }
1208
1396
  }
1209
1397
  async function writeFile(filePath, content) {
1210
1398
  try {
1211
- await fs4.writeFile(filePath, content, "utf-8");
1399
+ await fs5.writeFile(filePath, content, "utf-8");
1212
1400
  } catch {
1213
1401
  throw new Error(`Failed to write file: ${filePath}`);
1214
1402
  }
1215
1403
  }
1216
1404
  async function fileExists(filePath) {
1217
1405
  try {
1218
- await fs4.access(filePath);
1406
+ await fs5.access(filePath);
1219
1407
  return true;
1220
1408
  } catch {
1221
1409
  return false;
@@ -1223,7 +1411,7 @@ async function fileExists(filePath) {
1223
1411
  }
1224
1412
  async function renameFile(oldPath, newPath) {
1225
1413
  try {
1226
- await fs4.rename(oldPath, newPath);
1414
+ await fs5.rename(oldPath, newPath);
1227
1415
  } catch {
1228
1416
  throw new Error(`Failed to rename file: ${oldPath} -> ${newPath}`);
1229
1417
  }
@@ -1231,27 +1419,27 @@ async function renameFile(oldPath, newPath) {
1231
1419
 
1232
1420
  // src/MigrateCommand/presets/granite/configProcessor.ts
1233
1421
  var configTransformer = (root, { j }) => {
1234
- root.find(j.ImportDeclaration).forEach((path5) => {
1235
- const source = path5.value.source;
1422
+ root.find(j.ImportDeclaration).forEach((path6) => {
1423
+ const source = path6.value.source;
1236
1424
  if (j.StringLiteral.check(source) && source.value === "react-native-bedrock/config") {
1237
- const defineConfigName = path5.value.specifiers?.find(
1425
+ const defineConfigName = path6.value.specifiers?.find(
1238
1426
  (specifier) => j.ImportSpecifier.check(specifier) && specifier.imported.name === "defineConfig"
1239
1427
  )?.local?.name;
1240
1428
  if (!defineConfigName) {
1241
1429
  return;
1242
1430
  }
1243
- root.find(j.CallExpression).forEach((path6) => {
1244
- const callee = path6.value.callee;
1245
- if (j.Identifier.check(callee) && callee.name === defineConfigName && path6.value.arguments.length > 0 && j.ObjectExpression.check(path6.value.arguments[0])) {
1246
- const obj = path6.value.arguments[0];
1431
+ root.find(j.CallExpression).forEach((path7) => {
1432
+ const callee = path7.value.callee;
1433
+ if (j.Identifier.check(callee) && callee.name === defineConfigName && path7.value.arguments.length > 0 && j.ObjectExpression.check(path7.value.arguments[0])) {
1434
+ const obj = path7.value.arguments[0];
1247
1435
  const hasScheme = obj.properties.some(
1248
1436
  (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "scheme"
1249
1437
  );
1250
1438
  if (!hasScheme) {
1251
1439
  obj.properties.unshift(j.objectProperty(j.identifier("scheme"), j.stringLiteral("intoss")));
1252
1440
  }
1253
- const routerImport = root.find(j.ImportDeclaration).filter((path7) => {
1254
- const source2 = path7.value.source;
1441
+ const routerImport = root.find(j.ImportDeclaration).filter((path8) => {
1442
+ const source2 = path8.value.source;
1255
1443
  return j.StringLiteral.check(source2) && source2.value === "@granite-js/plugin-router";
1256
1444
  });
1257
1445
  if (routerImport.length === 0) {
@@ -1400,12 +1588,12 @@ var identifierReplacementsTransformer = (root, { j }) => {
1400
1588
  }
1401
1589
  });
1402
1590
  });
1403
- root.find(j.Identifier).forEach((path5) => {
1404
- const name = path5.value.name;
1591
+ root.find(j.Identifier).forEach((path6) => {
1592
+ const name = path6.value.name;
1405
1593
  if (importedVariables.has(name)) {
1406
- const newName = toGraniteName(path5.value.name);
1594
+ const newName = toGraniteName(path6.value.name);
1407
1595
  if (newName) {
1408
- path5.value.name = newName;
1596
+ path6.value.name = newName;
1409
1597
  }
1410
1598
  }
1411
1599
  });
@@ -1414,11 +1602,11 @@ var identifierReplacementsTransformer = (root, { j }) => {
1414
1602
 
1415
1603
  // src/MigrateCommand/presets/granite/isBedrockProject.ts
1416
1604
  init_esm_shims();
1417
- import * as fs5 from "fs";
1605
+ import * as fs6 from "fs";
1418
1606
  var BASE_NAME = "bedrock.config";
1419
1607
  var EXTENSIONS = ["ts", "mts", "js", "cjs"];
1420
1608
  async function isBedrockProject(cwd) {
1421
- const files = fs5.readdirSync(cwd);
1609
+ const files = fs6.readdirSync(cwd);
1422
1610
  return files.some(isBedrockConfigFile);
1423
1611
  }
1424
1612
  function isBedrockConfigFile(file) {
@@ -1458,8 +1646,8 @@ var packageImportsTransformer = (root, { j }, { fileName = "<unknown>" }) => {
1458
1646
  }
1459
1647
  return value;
1460
1648
  }
1461
- root.find(j.ImportDeclaration).forEach((path5) => {
1462
- const source = path5.value.source;
1649
+ root.find(j.ImportDeclaration).forEach((path6) => {
1650
+ const source = path6.value.source;
1463
1651
  if (j.StringLiteral.check(source)) {
1464
1652
  const transformed = transformPackageName(source.value);
1465
1653
  if (transformed !== source.value) {
@@ -1469,8 +1657,8 @@ var packageImportsTransformer = (root, { j }, { fileName = "<unknown>" }) => {
1469
1657
  });
1470
1658
  root.find(j.CallExpression, {
1471
1659
  callee: { name: "require" }
1472
- }).forEach((path5) => {
1473
- const args = path5.value.arguments;
1660
+ }).forEach((path6) => {
1661
+ const args = path6.value.arguments;
1474
1662
  if (args.length > 0 && j.StringLiteral.check(args[0])) {
1475
1663
  const transformed = transformPackageName(args[0].value);
1476
1664
  if (transformed !== args[0].value) {
@@ -1478,8 +1666,8 @@ var packageImportsTransformer = (root, { j }, { fileName = "<unknown>" }) => {
1478
1666
  }
1479
1667
  }
1480
1668
  });
1481
- root.find(j.ImportExpression).forEach((path5) => {
1482
- const source = path5.value.source;
1669
+ root.find(j.ImportExpression).forEach((path6) => {
1670
+ const source = path6.value.source;
1483
1671
  if (j.StringLiteral.check(source)) {
1484
1672
  const transformed = transformPackageName(source.value);
1485
1673
  if (transformed !== source.value) {
@@ -1577,14 +1765,14 @@ var APPS_IN_TOSS_FRAMEWORK_EXPORTS = [
1577
1765
  ];
1578
1766
  var toAppsInTossFrameworkImport = (root, { j }, { fileName = "<unknown>" }) => {
1579
1767
  const appsInTossFrameworkMembers = [];
1580
- root.find(j.ImportDeclaration).forEach((path5) => {
1581
- const source = path5.node.source.value;
1768
+ root.find(j.ImportDeclaration).forEach((path6) => {
1769
+ const source = path6.node.source.value;
1582
1770
  if (typeof source !== "string") {
1583
1771
  return;
1584
1772
  }
1585
1773
  if (source === "@granite-js/react-native") {
1586
- if (Array.isArray(path5.node.specifiers)) {
1587
- path5.node.specifiers = path5.node.specifiers.filter((specifier) => {
1774
+ if (Array.isArray(path6.node.specifiers)) {
1775
+ path6.node.specifiers = path6.node.specifiers.filter((specifier) => {
1588
1776
  if (shouldImportFromAppsInTossFramework(fileName, specifier)) {
1589
1777
  appsInTossFrameworkMembers.push(specifier);
1590
1778
  return false;
@@ -1592,8 +1780,8 @@ var toAppsInTossFrameworkImport = (root, { j }, { fileName = "<unknown>" }) => {
1592
1780
  return true;
1593
1781
  });
1594
1782
  }
1595
- if (path5.node.specifiers?.length === 0) {
1596
- j(path5).remove();
1783
+ if (path6.node.specifiers?.length === 0) {
1784
+ j(path6).remove();
1597
1785
  }
1598
1786
  }
1599
1787
  });
@@ -1746,24 +1934,98 @@ var MigrateCommand = class extends Command3 {
1746
1934
  }
1747
1935
  };
1748
1936
 
1937
+ // src/TokenCommand.ts
1938
+ init_esm_shims();
1939
+ var import_debug4 = __toESM(require_src(), 1);
1940
+ import * as p3 from "@clack/prompts";
1941
+ import { Command as Command4, Option as Option4 } from "clipanion";
1942
+ var debug4 = (0, import_debug4.default)("cli:token");
1943
+ var TokenCommand = class extends Command4 {
1944
+ static paths = [["token"]];
1945
+ static usage = Command4.Usage({
1946
+ description: "\uD1A0\uD070 \uAD00\uB828 \uD558\uC704 \uBA85\uB839\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4.",
1947
+ examples: [
1948
+ ["\uD1A0\uD070 \uCD94\uAC00", "ait token add <workspace?>"],
1949
+ ["\uD1A0\uD070 \uC0AD\uC81C", "ait token remove <workspace?>"]
1950
+ ]
1951
+ });
1952
+ async execute() {
1953
+ debug4("execute");
1954
+ }
1955
+ };
1956
+ var TokenAddCommand = class extends Command4 {
1957
+ static paths = [["token", "add"]];
1958
+ static usage = Command4.Usage({
1959
+ description: "\uC2DC\uD06C\uB9BF \uD1A0\uD070\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.",
1960
+ examples: [
1961
+ ["\uAE30\uBCF8 \uBCC4\uCE6D\uC73C\uB85C \uD1A0\uD070 \uCD94\uAC00", "ait token add"],
1962
+ ["\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC5EC \uD1A0\uD070 \uCD94\uAC00", "ait token add dev"]
1963
+ ]
1964
+ });
1965
+ workspace = Option4.String({ required: false });
1966
+ apiKey = Option4.String("--api-key", { required: false });
1967
+ async execute() {
1968
+ const workspace = this.workspace || "default";
1969
+ const secret = this.apiKey ? this.apiKey : await p3.password({
1970
+ message: "Enter secret token:",
1971
+ validate: (value) => {
1972
+ if (value.length === 0) {
1973
+ return "\uD1A0\uD070\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.";
1974
+ }
1975
+ return;
1976
+ }
1977
+ });
1978
+ if (p3.isCancel(secret)) {
1979
+ return;
1980
+ }
1981
+ TokenStorage.set(workspace, secret);
1982
+ debug4("token add", { workspace });
1983
+ this.context.stdout.write(`${workspace} \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uB85C\uC758 \uC694\uCCAD\uC740 \uC774\uC81C \uBE44\uBC00 \uD1A0\uD070\uC744 \uC0AC\uC6A9\uD558\uC5EC \uC778\uC99D\uB429\uB2C8\uB2E4.
1984
+ `);
1985
+ }
1986
+ };
1987
+ var TokenRemoveCommand = class extends Command4 {
1988
+ static paths = [["token", "remove"]];
1989
+ static usage = Command4.Usage({
1990
+ description: "\uC2DC\uD06C\uB9BF \uD1A0\uD070\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4.",
1991
+ examples: [
1992
+ ["\uAE30\uBCF8 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uC758 \uD1A0\uD070 \uC0AD\uC81C", "ait token remove"],
1993
+ ["\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC5EC \uD1A0\uD070 \uC0AD\uC81C", "ait token remove dev"]
1994
+ ]
1995
+ });
1996
+ workspace = Option4.String({ required: false });
1997
+ async execute() {
1998
+ const workspace = this.workspace || "default";
1999
+ const removed = TokenStorage.delete(workspace);
2000
+ debug4("token remove", { workspace });
2001
+ if (removed) {
2002
+ this.context.stdout.write(`\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uC758 \uD1A0\uD070\uC744 \uC81C\uAC70\uD588\uC2B5\uB2C8\uB2E4: ${workspace}.
2003
+ `);
2004
+ } else {
2005
+ this.context.stdout.write(`\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uC758 \uD1A0\uD070\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${workspace}.
2006
+ `);
2007
+ }
2008
+ }
2009
+ };
2010
+
1749
2011
  // src/integrations/UploadSentrySourcemap/index.ts
1750
2012
  init_esm_shims();
1751
2013
 
1752
2014
  // src/integrations/UploadSentrySourcemap/UploadSentrySourcemap.ts
1753
2015
  init_esm_shims();
1754
- import * as fs9 from "fs/promises";
1755
- import * as p3 from "@clack/prompts";
1756
- import { Command as Command4, Option as Option4 } from "clipanion";
2016
+ import * as fs10 from "fs/promises";
2017
+ import * as p4 from "@clack/prompts";
2018
+ import { Command as Command5, Option as Option5 } from "clipanion";
1757
2019
 
1758
2020
  // src/integrations/UploadSentrySourcemap/downloadArtifacts.ts
1759
2021
  init_esm_shims();
1760
- var import_debug4 = __toESM(require_src(), 1);
1761
- import * as fs6 from "fs";
1762
- import * as os from "os";
1763
- import * as path3 from "path";
2022
+ var import_debug5 = __toESM(require_src(), 1);
2023
+ import * as fs7 from "fs";
2024
+ import * as os2 from "os";
2025
+ import * as path4 from "path";
1764
2026
  import { pipeline } from "stream";
1765
2027
  import { promisify } from "util";
1766
- var debug4 = (0, import_debug4.default)("integrations:sentry");
2028
+ var debug5 = (0, import_debug5.default)("integrations:sentry");
1767
2029
  var streamPipeline = promisify(pipeline);
1768
2030
  async function downloadArtifacts(options) {
1769
2031
  const { appName, deploymentId, apiKey, baseUrl = DEFAULT_API_BASE_URL } = options;
@@ -1772,7 +2034,7 @@ async function downloadArtifacts(options) {
1772
2034
  deploymentId
1773
2035
  });
1774
2036
  const requestUrl = `${baseUrl}/api-public/v3/openapi/bundles/download?${params.toString()}`;
1775
- debug4("Request URL", { requestUrl });
2037
+ debug5("Request URL", { requestUrl });
1776
2038
  const response = await fetch(`${baseUrl}/api-public/v3/openapi/bundles/download?${params.toString()}`, {
1777
2039
  method: "GET",
1778
2040
  headers: {
@@ -1788,36 +2050,36 @@ async function downloadArtifacts(options) {
1788
2050
  }
1789
2051
  const tmpDir = await createTempDirectory();
1790
2052
  const tmpFile = `${deploymentId}.zip`;
1791
- const tmpFilePath = path3.join(tmpDir.path, tmpFile);
1792
- const fileStream = fs6.createWriteStream(tmpFilePath);
2053
+ const tmpFilePath = path4.join(tmpDir.path, tmpFile);
2054
+ const fileStream = fs7.createWriteStream(tmpFilePath);
1793
2055
  await streamPipeline(response.body, fileStream);
1794
- debug4("Artifacts downloaded", { tmpFilePath });
2056
+ debug5("Artifacts downloaded", { tmpFilePath });
1795
2057
  return tmpFilePath;
1796
2058
  }
1797
2059
  function createTempDirectory() {
1798
- const tempDir = path3.join(os.tmpdir(), "apps-in-toss", "sentry-integration");
1799
- fs6.mkdirSync(tempDir, { recursive: true });
1800
- debug4("Temp directory created", { tempDir });
2060
+ const tempDir = path4.join(os2.tmpdir(), "apps-in-toss", "sentry-integration");
2061
+ fs7.mkdirSync(tempDir, { recursive: true });
2062
+ debug5("Temp directory created", { tempDir });
1801
2063
  return {
1802
2064
  path: tempDir,
1803
2065
  cleanup: () => {
1804
- fs6.rmSync(tempDir, { recursive: true, force: true });
2066
+ fs7.rmSync(tempDir, { recursive: true, force: true });
1805
2067
  }
1806
2068
  };
1807
2069
  }
1808
2070
 
1809
2071
  // src/integrations/UploadSentrySourcemap/extractSentryDebugId.ts
1810
2072
  init_esm_shims();
1811
- import fs7 from "fs/promises";
2073
+ import fs8 from "fs/promises";
1812
2074
  async function extractSentryDebugId(bundlePath) {
1813
- const bundleContent = await fs7.readFile(bundlePath, "utf-8");
2075
+ const bundleContent = await fs8.readFile(bundlePath, "utf-8");
1814
2076
  return bundleContent.match(/SENTRY_DEBUG_ID=([\w-]+)/)?.[1];
1815
2077
  }
1816
2078
 
1817
2079
  // src/integrations/UploadSentrySourcemap/extractSources.ts
1818
2080
  init_esm_shims();
1819
- import * as fs8 from "fs";
1820
- import * as path4 from "path";
2081
+ import * as fs9 from "fs";
2082
+ import * as path5 from "path";
1821
2083
  import { pipeline as pipeline2 } from "stream";
1822
2084
  import { promisify as promisify2 } from "util";
1823
2085
  import * as zlib from "zlib";
@@ -1838,12 +2100,12 @@ async function extractSources(zipPath) {
1838
2100
  hermesSourceMap: ""
1839
2101
  }
1840
2102
  };
1841
- await fs8.createReadStream(zipPath).pipe(unzipper.Parse()).on("entry", async (entry) => {
2103
+ await fs9.createReadStream(zipPath).pipe(unzipper.Parse()).on("entry", async (entry) => {
1842
2104
  const isRoot = !entry.path.includes("/");
1843
- const fileName = path4.basename(entry.path);
1844
- const outputPath = path4.join(path4.dirname(zipPath), fileName);
2105
+ const fileName = path5.basename(entry.path);
2106
+ const outputPath = path5.join(path5.dirname(zipPath), fileName);
1845
2107
  if (isRoot) {
1846
- entry.pipe(fs8.createWriteStream(outputPath));
2108
+ entry.pipe(fs9.createWriteStream(outputPath));
1847
2109
  const platform = fileName.includes("android") ? "android" : "ios";
1848
2110
  if (fileName.endsWith(".js")) {
1849
2111
  sources[platform].packagerBundle = outputPath;
@@ -1871,7 +2133,7 @@ async function extractSources(zipPath) {
1871
2133
  }
1872
2134
  async function decompressGzip(gzFile) {
1873
2135
  const outfile = gzFile.replace(/\.gz$/g, "");
1874
- await pipe(fs8.createReadStream(gzFile), zlib.createGunzip(), fs8.createWriteStream(outfile));
2136
+ await pipe(fs9.createReadStream(gzFile), zlib.createGunzip(), fs9.createWriteStream(outfile));
1875
2137
  return outfile;
1876
2138
  }
1877
2139
 
@@ -1902,33 +2164,33 @@ function uploadSourcemap(bundlePath, sourcemapPath, options) {
1902
2164
  }
1903
2165
 
1904
2166
  // src/integrations/UploadSentrySourcemap/UploadSentrySourcemap.ts
1905
- var UploadSentrySourcemap = class extends Command4 {
2167
+ var UploadSentrySourcemap = class extends Command5 {
1906
2168
  static paths = [["sentry", "upload-sourcemap"]];
1907
- apiKey = Option4.String("--api-key", {
2169
+ apiKey = Option5.String("--api-key", {
1908
2170
  required: false,
1909
2171
  description: "\uC778\uC99D API \uD0A4"
1910
2172
  });
1911
- appName = Option4.String("--app-name", {
2173
+ appName = Option5.String("--app-name", {
1912
2174
  required: false,
1913
2175
  description: "\uC571 \uC774\uB984"
1914
2176
  });
1915
- deploymentId = Option4.String("--deployment-id", {
2177
+ deploymentId = Option5.String("--deployment-id", {
1916
2178
  required: false,
1917
2179
  description: "\uBC30\uD3EC ID"
1918
2180
  });
1919
- sentryAuthToken = Option4.String("--sentry-auth-token", {
2181
+ sentryAuthToken = Option5.String("--sentry-auth-token", {
1920
2182
  required: false,
1921
2183
  description: "Sentry \uC778\uC99D\uD0A4"
1922
2184
  });
1923
- sentryOrg = Option4.String("--sentry-org", {
2185
+ sentryOrg = Option5.String("--sentry-org", {
1924
2186
  required: false,
1925
2187
  description: "Sentry \uC870\uC9C1"
1926
2188
  });
1927
- sentryProject = Option4.String("--sentry-project", {
2189
+ sentryProject = Option5.String("--sentry-project", {
1928
2190
  required: false,
1929
2191
  description: "Sentry \uD504\uB85C\uC81D\uD2B8"
1930
2192
  });
1931
- baseUrl = Option4.String("--base-url", {
2193
+ baseUrl = Option5.String("--base-url", {
1932
2194
  description: "API Base URL"
1933
2195
  });
1934
2196
  async execute() {
@@ -1942,7 +2204,7 @@ var UploadSentrySourcemap = class extends Command4 {
1942
2204
  try {
1943
2205
  const zipPath = await downloadArtifacts({ apiKey, appName, deploymentId, baseUrl });
1944
2206
  const sources = await extractSources(zipPath);
1945
- await p3.tasks([
2207
+ await p4.tasks([
1946
2208
  {
1947
2209
  title: "Android \uC18C\uC2A4\uB9F5 \uC5C5\uB85C\uB4DC \uC911...",
1948
2210
  task: async () => {
@@ -1968,10 +2230,10 @@ var UploadSentrySourcemap = class extends Command4 {
1968
2230
  }
1969
2231
  }
1970
2232
  ]);
1971
- p3.outro("Sentry \uC18C\uC2A4\uB9F5 \uC5C5\uB85C\uB4DC \uC644\uB8CC");
2233
+ p4.outro("Sentry \uC18C\uC2A4\uB9F5 \uC5C5\uB85C\uB4DC \uC644\uB8CC");
1972
2234
  } catch (error) {
1973
2235
  if (error instanceof Error) {
1974
- p3.log.error(error.message);
2236
+ p4.log.error(error.message);
1975
2237
  } else {
1976
2238
  console.error(error);
1977
2239
  }
@@ -1984,14 +2246,14 @@ var UploadSentrySourcemap = class extends Command4 {
1984
2246
  throw new Error("Sentry Debug ID\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1985
2247
  }
1986
2248
  const mergedSourceMap = await mergeSourceMaps(
1987
- await fs9.readFile(sources.packagerSourceMap, "utf-8"),
1988
- await fs9.readFile(sources.hermesSourceMap, "utf-8")
2249
+ await fs10.readFile(sources.packagerSourceMap, "utf-8"),
2250
+ await fs10.readFile(sources.hermesSourceMap, "utf-8")
1989
2251
  );
1990
2252
  const injectedSourceMap = injectSentryDebugId(mergedSourceMap, debugId);
1991
- await fs9.writeFile(sources.hermesSourceMap, JSON.stringify(injectedSourceMap, null, 2), "utf-8");
2253
+ await fs10.writeFile(sources.hermesSourceMap, JSON.stringify(injectedSourceMap, null, 2), "utf-8");
1992
2254
  }
1993
2255
  async promptRequiredValue(type, message, validateMessage) {
1994
- const result = await p3[type]({
2256
+ const result = await p4[type]({
1995
2257
  message,
1996
2258
  validate: (value) => {
1997
2259
  if (value.length === 0) {
@@ -2000,7 +2262,7 @@ var UploadSentrySourcemap = class extends Command4 {
2000
2262
  return;
2001
2263
  }
2002
2264
  });
2003
- if (p3.isCancel(result)) {
2265
+ if (p4.isCancel(result)) {
2004
2266
  throw new Error("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694.");
2005
2267
  }
2006
2268
  return result;
@@ -2017,6 +2279,10 @@ function initialize() {
2017
2279
  cli.register(InitCommand);
2018
2280
  cli.register(MigrateCommand);
2019
2281
  cli.register(UploadSentrySourcemap);
2282
+ cli.register(TokenCommand);
2283
+ cli.register(TokenAddCommand);
2284
+ cli.register(TokenRemoveCommand);
2285
+ cli.register(Builtins.HelpCommand);
2020
2286
  cli.runExit(process.argv.slice(2));
2021
2287
  }
2022
2288
  export {