@apps-in-toss/cli 1.14.1 → 2.0.1

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
@@ -46,10 +46,10 @@ var require_picocolors = __commonJS({
46
46
  "../../../.yarn/cache/picocolors-npm-1.1.1-b0c45fa35e-e2e3e8170a.zip/node_modules/picocolors/picocolors.js"(exports, module) {
47
47
  "use strict";
48
48
  init_esm_shims();
49
- var p5 = process || {};
50
- var argv = p5.argv || [];
51
- var env = p5.env || {};
52
- 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);
49
+ var p8 = process || {};
50
+ var argv = p8.argv || [];
51
+ var env = p8.env || {};
52
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p8.platform === "win32" || (p8.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
53
53
  var formatter = (open, close, replace = open) => (input) => {
54
54
  let string = "" + input, index = string.indexOf(close, open.length);
55
55
  return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
@@ -233,9 +233,9 @@ var require_ms = __commonJS({
233
233
  }
234
234
  });
235
235
 
236
- // ../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/common.js
236
+ // ../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/common.js
237
237
  var require_common = __commonJS({
238
- "../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/common.js"(exports, module) {
238
+ "../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/common.js"(exports, module) {
239
239
  "use strict";
240
240
  init_esm_shims();
241
241
  function setup(env) {
@@ -412,9 +412,9 @@ var require_common = __commonJS({
412
412
  }
413
413
  });
414
414
 
415
- // ../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/browser.js
415
+ // ../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/browser.js
416
416
  var require_browser = __commonJS({
417
- "../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/browser.js"(exports, module) {
417
+ "../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/browser.js"(exports, module) {
418
418
  "use strict";
419
419
  init_esm_shims();
420
420
  exports.formatArgs = formatArgs;
@@ -584,15 +584,15 @@ var require_browser = __commonJS({
584
584
  }
585
585
  });
586
586
 
587
- // ../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/node.js
587
+ // ../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/node.js
588
588
  var require_node = __commonJS({
589
- "../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/node.js"(exports, module) {
589
+ "../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/node.js"(exports, module) {
590
590
  "use strict";
591
591
  init_esm_shims();
592
592
  var tty = __require("tty");
593
593
  var util = __require("util");
594
594
  exports.init = init;
595
- exports.log = log4;
595
+ exports.log = log7;
596
596
  exports.formatArgs = formatArgs;
597
597
  exports.save = save;
598
598
  exports.load = load;
@@ -727,7 +727,7 @@ var require_node = __commonJS({
727
727
  }
728
728
  return (/* @__PURE__ */ new Date()).toISOString() + " ";
729
729
  }
730
- function log4(...args) {
730
+ function log7(...args) {
731
731
  return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + "\n");
732
732
  }
733
733
  function save(namespaces) {
@@ -760,9 +760,9 @@ var require_node = __commonJS({
760
760
  }
761
761
  });
762
762
 
763
- // ../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/index.js
763
+ // ../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/index.js
764
764
  var require_src = __commonJS({
765
- "../../../.yarn/__virtual__/debug-virtual-5f733de965/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/index.js"(exports, module) {
765
+ "../../../.yarn/__virtual__/debug-virtual-4a69f763f8/0/cache/debug-npm-4.4.0-f1ca372596-db94f1a182.zip/node_modules/debug/src/index.js"(exports, module) {
766
766
  "use strict";
767
767
  init_esm_shims();
768
768
  if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) {
@@ -777,37 +777,687 @@ var require_src = __commonJS({
777
777
  init_esm_shims();
778
778
  import { Cli, Builtins } from "clipanion";
779
779
 
780
+ // src/BuildCommand.ts
781
+ init_esm_shims();
782
+ import path7 from "path";
783
+ import * as p3 from "@clack/prompts";
784
+ import { getPackageRoot } from "@granite-js/utils";
785
+ import { Command } from "clipanion";
786
+
787
+ // src/build/buildArtifact/index.ts
788
+ init_esm_shims();
789
+ import * as p2 from "@clack/prompts";
790
+
791
+ // src/build/buildArtifact/defaultBuildDeps.ts
792
+ init_esm_shims();
793
+ import { collectDependencyVersions, createArtifact, getSdkVersion } from "@apps-in-toss/plugins";
794
+ import { uuidv7 } from "uuidv7";
795
+
796
+ // src/build/buildArtifact/utils.ts
797
+ init_esm_shims();
798
+ import fs from "fs/promises";
799
+ import path from "path";
800
+
801
+ // src/build/buildArtifact/constants.ts
802
+ init_esm_shims();
803
+ var RUNTIME_BUILD_DEFINITIONS = [
804
+ { runtimeVersion: "0.84.0" },
805
+ { runtimeVersion: "0.72.6", configTargetVersion: "0.72.6" }
806
+ ];
807
+ var DIST_DIRECTORY = "dist";
808
+
809
+ // src/build/buildArtifact/utils.ts
810
+ async function clearBuildCache(packageRoot) {
811
+ await fs.rm(path.join(packageRoot, DIST_DIRECTORY), { recursive: true, force: true });
812
+ }
813
+ async function ensureGraniteConfigExists(graniteConfigPath) {
814
+ try {
815
+ await fs.access(graniteConfigPath);
816
+ } catch {
817
+ throw new Error(`Cannot find granite config: ${graniteConfigPath}`);
818
+ }
819
+ }
820
+ async function resolveArtifactOptions(strategy, context) {
821
+ if (strategy.getArtifactOptions == null) {
822
+ return { isGame: context.appType === "game" };
823
+ }
824
+ return strategy.getArtifactOptions(context);
825
+ }
826
+ async function readAppManifest(appJsonPath) {
827
+ const appJsonRaw = await fs.readFile(appJsonPath, "utf8");
828
+ const appJson = JSON.parse(appJsonRaw);
829
+ if (typeof appJson.appName !== "string" || appJson.appName.length === 0) {
830
+ throw new Error(`Invalid appName in ${appJsonPath}`);
831
+ }
832
+ return {
833
+ appName: appJson.appName,
834
+ appType: appJson.appType ?? void 0
835
+ };
836
+ }
837
+
838
+ // src/build/resolveBuildStrategy.ts
839
+ init_esm_shims();
840
+ import fs2 from "fs/promises";
841
+ async function resolveBuildStrategy(graniteConfigPath, strategyFactories) {
842
+ const graniteConfigSource = await fs2.readFile(graniteConfigPath, "utf8");
843
+ for (const strategy of strategyFactories) {
844
+ if (await strategy.match({ graniteConfigPath, graniteConfigSource })) {
845
+ return strategy;
846
+ }
847
+ }
848
+ throw new Error(`Cannot resolve build strategy: ${graniteConfigPath}`);
849
+ }
850
+
851
+ // src/build/buildArtifact/defaultBuildDeps.ts
852
+ var defaultBuildDeps = {
853
+ clearBuildCache,
854
+ resolveStrategy: resolveBuildStrategy,
855
+ collectDependencyVersions,
856
+ createArtifact,
857
+ getSdkVersion,
858
+ generateDeploymentId: uuidv7
859
+ };
860
+
861
+ // src/build/buildArtifact/prepareArtifact.ts
862
+ init_esm_shims();
863
+ import path2 from "path";
864
+
865
+ // src/utils/constants.ts
866
+ init_esm_shims();
867
+ var APP_MANIFEST_NAME = "app.json";
868
+ var DEFAULT_API_BASE_URL = "https://apps-in-toss.toss.im/console";
869
+
870
+ // src/build/buildArtifact/prepareArtifact.ts
871
+ async function prepareArtifact({
872
+ packageRoot,
873
+ preparation,
874
+ services
875
+ }) {
876
+ const appJsonPath = path2.join(packageRoot, ".granite", APP_MANIFEST_NAME);
877
+ const { appName, appType } = await readAppManifest(appJsonPath);
878
+ const outfile = path2.join(packageRoot, `${appName}.ait`);
879
+ const { dependencies, devDependencies } = await services.collectDependencyVersions(packageRoot);
880
+ const sdkVersion = services.getSdkVersion();
881
+ const artifactOptions = await resolveArtifactOptions(preparation.strategy, {
882
+ ...preparation.context,
883
+ appName,
884
+ appType
885
+ });
886
+ return {
887
+ appJsonPath,
888
+ appName,
889
+ appType,
890
+ outfile,
891
+ sdkVersion,
892
+ dependencies,
893
+ devDependencies,
894
+ artifactOptions
895
+ };
896
+ }
897
+
898
+ // src/build/buildArtifact/prepareBuild.ts
899
+ init_esm_shims();
900
+ import path3 from "path";
901
+ async function prepareBuild({
902
+ packageRoot,
903
+ services,
904
+ strategies
905
+ }) {
906
+ const graniteConfigPath = path3.join(packageRoot, "granite.config.ts");
907
+ const deploymentId = services.generateDeploymentId();
908
+ await ensureGraniteConfigExists(graniteConfigPath);
909
+ await services.clearBuildCache(packageRoot);
910
+ const strategy = await services.resolveStrategy(graniteConfigPath, strategies);
911
+ const buildInput = {
912
+ runtimeBuildDefinitions: RUNTIME_BUILD_DEFINITIONS
913
+ };
914
+ if (buildInput.runtimeBuildDefinitions.length === 0) {
915
+ throw new Error("No runtime build definitions provided");
916
+ }
917
+ return {
918
+ strategy,
919
+ context: { packageRoot, deploymentId, graniteConfigPath },
920
+ buildInput,
921
+ primaryRuntimeVersion: buildInput.runtimeBuildDefinitions[0].runtimeVersion
922
+ };
923
+ }
924
+
925
+ // src/build/buildArtifact/runStrategyBuild.ts
926
+ init_esm_shims();
927
+ import * as p from "@clack/prompts";
928
+ async function runStrategyBuild(preparation) {
929
+ const buildResults = await preparation.strategy.build(preparation.buildInput, preparation.context);
930
+ const bundleFiles = [];
931
+ for (let i = 0; i < buildResults.length; i++) {
932
+ const result = buildResults[i];
933
+ bundleFiles.push(...result.bundleFiles);
934
+ p.log.step(`[${i + 1}/${buildResults.length}] Built for RN ${result.runtimeVersion}`);
935
+ }
936
+ return bundleFiles;
937
+ }
938
+
939
+ // src/build/RNBuildStrategy.ts
940
+ init_esm_shims();
941
+ import fs4 from "fs/promises";
942
+ import path5 from "path";
943
+ import { getPackageManager } from "@apps-in-toss/web-config";
944
+ import { execa } from "execa";
945
+
946
+ // src/build/createRuntimeBundleFiles.ts
947
+ init_esm_shims();
948
+ import fs3 from "fs/promises";
949
+ import path4 from "path";
950
+ async function createRuntimeBundleFiles({
951
+ packageRoot,
952
+ runtimeVersion,
953
+ bundleOutputDir
954
+ }) {
955
+ const distPath = path4.isAbsolute(bundleOutputDir) ? bundleOutputDir : path4.join(packageRoot, bundleOutputDir);
956
+ const platforms = ["ios", "android"];
957
+ const runtimeName = runtimeVersion.replace(/\./g, "_");
958
+ const bundleFiles = [];
959
+ for (const platform of platforms) {
960
+ const sourceJsPath = path4.join(distPath, `bundle.${platform}.js`);
961
+ const sourceMapPath = path4.join(distPath, `bundle.${platform}.js.map`);
962
+ const targetJsPath = path4.join(distPath, `bundle.${platform}.${runtimeName}.js`);
963
+ const targetMapPath = path4.join(distPath, `bundle.${platform}.${runtimeName}.js.map`);
964
+ await copyRequiredFile(sourceJsPath, targetJsPath);
965
+ await copyRequiredFile(sourceMapPath, targetMapPath);
966
+ bundleFiles.push({
967
+ path: targetJsPath,
968
+ platform,
969
+ runtimeVersion
970
+ });
971
+ bundleFiles.push({
972
+ path: targetMapPath,
973
+ platform,
974
+ runtimeVersion
975
+ });
976
+ }
977
+ return bundleFiles;
978
+ }
979
+ async function copyRequiredFile(sourcePath, targetPath) {
980
+ try {
981
+ await fs3.copyFile(sourcePath, targetPath);
982
+ } catch {
983
+ throw new Error(`Missing build output file: ${sourcePath}`);
984
+ }
985
+ }
986
+
987
+ // src/utils/injectAppsInTossTarget.ts
988
+ init_esm_shims();
989
+
990
+ // src/MigrateCommand/codemod/index.ts
991
+ init_esm_shims();
992
+
993
+ // src/MigrateCommand/codemod/transform.ts
994
+ init_esm_shims();
995
+ import jscodeshift from "jscodeshift";
996
+ function transform(source, { transformers: transformers2, options = {} }) {
997
+ const j = jscodeshift.withParser("tsx");
998
+ const report = [];
999
+ const stats = /* @__PURE__ */ new Map();
1000
+ const context = {
1001
+ j,
1002
+ jscodeshift: j,
1003
+ stats: (name, quantity = 1) => {
1004
+ if (quantity === 0) {
1005
+ return;
1006
+ }
1007
+ stats.set(name, (stats.get(name) ?? 0) + quantity);
1008
+ },
1009
+ report: (message) => {
1010
+ report.push(message);
1011
+ }
1012
+ };
1013
+ const root = transformers2.reduce((root2, transformer) => transformer(root2, context, options), j(source));
1014
+ return root.toSource();
1015
+ }
1016
+
1017
+ // src/utils/injectAppsInTossTarget.ts
1018
+ var TARGET_IMPORTS = [
1019
+ { source: "@apps-in-toss/framework/plugins", importName: "appsInToss" },
1020
+ { source: "@apps-in-toss/plugins", importName: "appsInToss" },
1021
+ { source: "@apps-in-toss/framework/internal", importName: "appsInTossHost" },
1022
+ { source: "@apps-in-toss/plugins/internal", importName: "appsInTossHost" }
1023
+ ];
1024
+ function createAppsInTossTargetTransformer(stats) {
1025
+ return (root, { j }, options) => {
1026
+ const fileName = options?.fileName ?? "<unknown>";
1027
+ const targetVersion = options?.targetVersion;
1028
+ if (typeof targetVersion !== "string" || targetVersion.length === 0) {
1029
+ return root;
1030
+ }
1031
+ const localNames = /* @__PURE__ */ new Set();
1032
+ let warnedForUnsupportedArg = false;
1033
+ for (const targetImport of TARGET_IMPORTS) {
1034
+ root.find(j.ImportDeclaration, {
1035
+ source: { value: targetImport.source }
1036
+ }).forEach((importPath) => {
1037
+ for (const specifier of importPath.node.specifiers ?? []) {
1038
+ if (specifier.type === "ImportSpecifier" && specifier.imported.type === "Identifier" && specifier.imported.name === targetImport.importName) {
1039
+ localNames.add(specifier.local?.name ?? targetImport.importName);
1040
+ }
1041
+ }
1042
+ });
1043
+ }
1044
+ if (localNames.size === 0) {
1045
+ return root;
1046
+ }
1047
+ root.find(j.CallExpression).forEach((path13) => {
1048
+ const callee = path13.node.callee;
1049
+ if (!j.Identifier.check(callee) || !localNames.has(callee.name)) {
1050
+ return;
1051
+ }
1052
+ stats.matchedCallCount += 1;
1053
+ const firstArg = path13.node.arguments[0];
1054
+ if (firstArg == null) {
1055
+ path13.node.arguments = [
1056
+ j.objectExpression([j.objectProperty(j.identifier("target"), j.stringLiteral(targetVersion))])
1057
+ ];
1058
+ stats.updatedCallCount += 1;
1059
+ return;
1060
+ }
1061
+ if (!j.ObjectExpression.check(firstArg)) {
1062
+ stats.hadUnsupportedArgument = true;
1063
+ if (!warnedForUnsupportedArg) {
1064
+ warnedForUnsupportedArg = true;
1065
+ options?.onUnsupportedArgument?.(fileName);
1066
+ }
1067
+ return;
1068
+ }
1069
+ const targetProp = firstArg.properties.find((property) => {
1070
+ if (!j.ObjectProperty.check(property)) {
1071
+ return false;
1072
+ }
1073
+ if (j.Identifier.check(property.key)) {
1074
+ return property.key.name === "target";
1075
+ }
1076
+ return j.StringLiteral.check(property.key) && property.key.value === "target";
1077
+ });
1078
+ if (targetProp != null && j.ObjectProperty.check(targetProp)) {
1079
+ targetProp.value = j.stringLiteral(targetVersion);
1080
+ stats.updatedCallCount += 1;
1081
+ return;
1082
+ }
1083
+ firstArg.properties.unshift(j.objectProperty(j.identifier("target"), j.stringLiteral(targetVersion)));
1084
+ stats.updatedCallCount += 1;
1085
+ });
1086
+ return root;
1087
+ };
1088
+ }
1089
+ function injectAppsInTossTargetWithResult(source, options) {
1090
+ const stats = {
1091
+ matchedCallCount: 0,
1092
+ updatedCallCount: 0,
1093
+ hadUnsupportedArgument: false
1094
+ };
1095
+ const code = transform(source, {
1096
+ transformers: [createAppsInTossTargetTransformer(stats)],
1097
+ options
1098
+ });
1099
+ return {
1100
+ code,
1101
+ ...stats
1102
+ };
1103
+ }
1104
+
1105
+ // src/build/RNBuildStrategy.ts
1106
+ var GRANITE_DIRECTORY = ".granite";
1107
+ var TEMP_CONFIG_FILE_PREFIX = ".ait-runtime";
1108
+ var BUNDLE_OUTPUT_DIRECTORY = "dist";
1109
+ var RNBuildStrategy = class {
1110
+ name = "rn";
1111
+ match(context) {
1112
+ return true;
1113
+ }
1114
+ async build(input, context) {
1115
+ const results = [];
1116
+ const graniteCommand = resolveGraniteCommand();
1117
+ for (const definition of input.runtimeBuildDefinitions) {
1118
+ const graniteBuildArgs = await resolveGraniteBuildArgs(definition, context);
1119
+ const tempConfigPath = graniteBuildArgs.tempConfigPath;
1120
+ const commandArgs = [...graniteCommand.prefixArgs, "build", ...graniteBuildArgs.args];
1121
+ try {
1122
+ await execa(graniteCommand.executable, commandArgs, {
1123
+ cwd: context.packageRoot,
1124
+ env: {
1125
+ ...process.env,
1126
+ AIT_DEPLOYMENT_ID: context.deploymentId
1127
+ },
1128
+ stdio: "inherit"
1129
+ });
1130
+ } catch (error) {
1131
+ throw new Error(`granite build failed: ${graniteCommand.executable} ${commandArgs.join(" ")}`, {
1132
+ cause: error
1133
+ });
1134
+ } finally {
1135
+ if (tempConfigPath != null) {
1136
+ await fs4.rm(tempConfigPath, { force: true });
1137
+ }
1138
+ }
1139
+ results.push({
1140
+ runtimeVersion: definition.runtimeVersion,
1141
+ bundleFiles: await createRuntimeBundleFiles({
1142
+ packageRoot: context.packageRoot,
1143
+ runtimeVersion: definition.runtimeVersion,
1144
+ bundleOutputDir: BUNDLE_OUTPUT_DIRECTORY
1145
+ })
1146
+ });
1147
+ }
1148
+ return results;
1149
+ }
1150
+ async getArtifactOptions(context) {
1151
+ return {
1152
+ isGame: context.appType === "game"
1153
+ };
1154
+ }
1155
+ };
1156
+ function resolveGraniteCommand() {
1157
+ const { packageManager } = getPackageManager({ isExecutor: true });
1158
+ return {
1159
+ executable: packageManager,
1160
+ prefixArgs: ["granite"]
1161
+ };
1162
+ }
1163
+ async function resolveGraniteBuildArgs(definition, context) {
1164
+ if (definition.configTargetVersion == null) {
1165
+ return { args: ["--no-cache"] };
1166
+ }
1167
+ const targetVersion = definition.configTargetVersion;
1168
+ const tempConfigRelativePath = createTempConfigRelativePath(targetVersion);
1169
+ const tempConfigPath = path5.join(context.packageRoot, tempConfigRelativePath);
1170
+ try {
1171
+ await writeRuntimeConfig(context.graniteConfigPath, tempConfigPath, targetVersion);
1172
+ return {
1173
+ args: ["--config", tempConfigRelativePath, "--no-cache"],
1174
+ tempConfigPath
1175
+ };
1176
+ } catch {
1177
+ return { args: ["--no-cache"], tempConfigPath };
1178
+ }
1179
+ }
1180
+ function createTempConfigRelativePath(targetVersion) {
1181
+ const runtimeName = targetVersion.replace(/\./g, "_");
1182
+ return path5.join(GRANITE_DIRECTORY, `${TEMP_CONFIG_FILE_PREFIX}-${runtimeName}.config.ts`);
1183
+ }
1184
+ async function writeRuntimeConfig(graniteConfigPath, tempConfigPath, targetVersion) {
1185
+ const source = await fs4.readFile(graniteConfigPath, "utf8");
1186
+ const transformed = injectAppsInTossTargetWithResult(source, {
1187
+ fileName: graniteConfigPath,
1188
+ targetVersion
1189
+ });
1190
+ if (transformed.matchedCallCount === 0) {
1191
+ throw new Error(
1192
+ `Cannot inject target (${targetVersion}) into ${graniteConfigPath}: appsInToss/appsInTossHost call not found`
1193
+ );
1194
+ }
1195
+ if (transformed.hadUnsupportedArgument) {
1196
+ throw new Error(
1197
+ `Cannot inject target (${targetVersion}) into ${graniteConfigPath}: unsupported plugin argument shape detected`
1198
+ );
1199
+ }
1200
+ await fs4.mkdir(path5.dirname(tempConfigPath), { recursive: true });
1201
+ await fs4.writeFile(tempConfigPath, transformed.code, "utf8");
1202
+ }
1203
+
1204
+ // src/build/WebBuildStrategy.ts
1205
+ init_esm_shims();
1206
+ import fs5 from "fs/promises";
1207
+ import { createRequire as createRequireFromPath } from "module";
1208
+ import path6 from "path";
1209
+ import { babelBuild, getPackageManager as getPackageManager2, loadConfig, writeBundle } from "@apps-in-toss/web-config";
1210
+ import { execa as execa2 } from "execa";
1211
+ var APP_MANIFEST_NAME2 = "app.json";
1212
+ var WebBuildStrategy = class {
1213
+ name = "web";
1214
+ config;
1215
+ prepared = false;
1216
+ match({ graniteConfigSource }) {
1217
+ return graniteConfigSource.includes("@apps-in-toss/web-framework");
1218
+ }
1219
+ async build(input, context) {
1220
+ const config = await this.ensurePrepared(context);
1221
+ const results = [];
1222
+ for (const definition of input.runtimeBuildDefinitions) {
1223
+ for (const platform of ["ios", "android"]) {
1224
+ const buildResult = await buildRuntimeBundle({
1225
+ config,
1226
+ runtimeVersion: definition.runtimeVersion,
1227
+ deploymentId: context.deploymentId,
1228
+ packageRoot: context.packageRoot,
1229
+ platform
1230
+ });
1231
+ await writeBundle(buildResult, { platform, config, cwd: context.packageRoot });
1232
+ }
1233
+ results.push({
1234
+ runtimeVersion: definition.runtimeVersion,
1235
+ bundleFiles: await createRuntimeBundleFiles({
1236
+ packageRoot: context.packageRoot,
1237
+ runtimeVersion: definition.runtimeVersion,
1238
+ bundleOutputDir: config.outdir
1239
+ })
1240
+ });
1241
+ }
1242
+ return results;
1243
+ }
1244
+ async getArtifactOptions(context) {
1245
+ const config = await this.ensureConfig();
1246
+ const isGame = config.webViewProps?.type === "game";
1247
+ const extra = {
1248
+ brand: config.brand,
1249
+ ...config.navigationBar != null ? { navigationBar: config.navigationBar } : {},
1250
+ ...config.webViewProps != null ? { webViewProps: config.webViewProps } : {}
1251
+ };
1252
+ const webDistDir = path6.join(context.packageRoot, config.outdir, "web");
1253
+ const additionalFilesToZip = await getWebDistFiles(webDistDir);
1254
+ return { isGame, additionalFilesToZip, extra };
1255
+ }
1256
+ async ensurePrepared(context) {
1257
+ const config = await this.ensureConfig();
1258
+ if (this.prepared) {
1259
+ return config;
1260
+ }
1261
+ const outdir = path6.join(context.packageRoot, config.outdir);
1262
+ const webDistDir = path6.join(context.packageRoot, config.outdir, "web");
1263
+ try {
1264
+ const files = await fs5.readdir(webDistDir);
1265
+ if (files.includes("index.html")) {
1266
+ await this.writeAppJson(context);
1267
+ this.prepared = true;
1268
+ return config;
1269
+ }
1270
+ } catch {
1271
+ }
1272
+ const { packageManager } = getPackageManager2({ isExecutor: true });
1273
+ await fs5.rm(outdir, { recursive: true, force: true });
1274
+ await execa2(packageManager, config.web.commands.build.split(" "), {
1275
+ cwd: context.packageRoot,
1276
+ stdio: "inherit",
1277
+ shell: true
1278
+ });
1279
+ await fs5.mkdir(webDistDir, { recursive: true });
1280
+ const items = await fs5.readdir(outdir);
1281
+ for (const item of items) {
1282
+ const src = path6.join(outdir, item);
1283
+ const dest = path6.join(webDistDir, item);
1284
+ if (src === webDistDir) {
1285
+ continue;
1286
+ }
1287
+ await fs5.rename(src, dest);
1288
+ }
1289
+ const webDistFiles = await fs5.readdir(webDistDir);
1290
+ if (webDistFiles.length === 0) {
1291
+ throw new Error(
1292
+ `Web build output is empty. Check that your outdir path and web.commands.build output path match in granite.config.ts.`
1293
+ );
1294
+ }
1295
+ if (!webDistFiles.includes("index.html")) {
1296
+ throw new Error(
1297
+ `Web build output requires ${config.outdir}/web/index.html. Currently only CSR / SSG environments are supported.`
1298
+ );
1299
+ }
1300
+ await this.writeAppJson(context);
1301
+ this.prepared = true;
1302
+ return config;
1303
+ }
1304
+ async writeAppJson(context) {
1305
+ const config = await this.ensureConfig();
1306
+ const graniteDir = path6.join(context.packageRoot, ".granite");
1307
+ await fs5.mkdir(graniteDir, { recursive: true });
1308
+ await fs5.writeFile(
1309
+ path6.join(graniteDir, APP_MANIFEST_NAME2),
1310
+ JSON.stringify(
1311
+ {
1312
+ appName: config.appName,
1313
+ permissions: config.permissions
1314
+ },
1315
+ null,
1316
+ 2
1317
+ ),
1318
+ "utf8"
1319
+ );
1320
+ }
1321
+ async ensureConfig() {
1322
+ if (this.config) {
1323
+ return this.config;
1324
+ }
1325
+ const config = await loadConfig();
1326
+ if (!config) {
1327
+ throw new Error("Cannot find granite config");
1328
+ }
1329
+ this.config = config;
1330
+ return this.config;
1331
+ }
1332
+ };
1333
+ async function buildRuntimeBundle({
1334
+ config,
1335
+ runtimeVersion,
1336
+ deploymentId,
1337
+ packageRoot,
1338
+ platform = "ios"
1339
+ }) {
1340
+ const buildNumber = getBuildNumber();
1341
+ const projectRequire = createRequireFromPath(path6.join(packageRoot, "package.json"));
1342
+ const rnSuffix = runtimeVersion.startsWith("0.72") ? "rn72" : "rn84";
1343
+ const prebuiltPath = projectRequire.resolve(`@apps-in-toss/web-framework/prebuilt/prod/${platform}/${rnSuffix}`);
1344
+ return babelBuild({
1345
+ config,
1346
+ platform,
1347
+ buildNumber,
1348
+ deploymentId,
1349
+ prebuiltPath
1350
+ });
1351
+ }
1352
+ function getBuildNumber() {
1353
+ const date = /* @__PURE__ */ new Date();
1354
+ const year = date.getFullYear();
1355
+ const month = String(date.getMonth() + 1).padStart(2, "0");
1356
+ const day = String(date.getDate()).padStart(2, "0");
1357
+ const hours = String(date.getHours()).padStart(2, "0");
1358
+ const minutes = String(date.getMinutes()).padStart(2, "0");
1359
+ const seconds = String(date.getSeconds()).padStart(2, "0");
1360
+ return `${year}${month}${day}${hours}${minutes}${seconds}`;
1361
+ }
1362
+ async function getWebDistFiles(webDistDir) {
1363
+ const additionalFilesToZip = [];
1364
+ try {
1365
+ const allFiles = await fs5.readdir(webDistDir, { recursive: true });
1366
+ const webFiles = await Promise.all(
1367
+ allFiles.map(async (file) => {
1368
+ const filePath = path6.join(webDistDir, String(file));
1369
+ const stat = await fs5.stat(filePath);
1370
+ return stat.isFile() ? String(file) : null;
1371
+ })
1372
+ ).then((files) => files.filter((file) => file !== null));
1373
+ additionalFilesToZip.push(
1374
+ ...webFiles.map((file) => ({
1375
+ path: path6.join(webDistDir, file),
1376
+ name: path6.join("web", file)
1377
+ }))
1378
+ );
1379
+ } catch {
1380
+ }
1381
+ return additionalFilesToZip;
1382
+ }
1383
+
1384
+ // src/build/buildArtifact/index.ts
1385
+ async function buildArtifact(packageRoot, deps = {}) {
1386
+ const services = {
1387
+ ...defaultBuildDeps,
1388
+ ...deps
1389
+ };
1390
+ const strategies = [new WebBuildStrategy(), new RNBuildStrategy()];
1391
+ const preparation = await prepareBuild({ packageRoot, services, strategies });
1392
+ const bundleFiles = await runStrategyBuild(preparation);
1393
+ const artifact = await prepareArtifact({ packageRoot, preparation, services });
1394
+ p2.log.step("Creating .ait artifact...");
1395
+ await services.createArtifact({
1396
+ reactNativeVersion: preparation.primaryRuntimeVersion,
1397
+ sdkVersion: artifact.sdkVersion,
1398
+ isGame: artifact.artifactOptions.isGame,
1399
+ isWeb: preparation.strategy.name === "web",
1400
+ appJsonPath: artifact.appJsonPath,
1401
+ deploymentId: preparation.context.deploymentId,
1402
+ packageJson: {
1403
+ dependencies: artifact.dependencies,
1404
+ devDependencies: artifact.devDependencies
1405
+ },
1406
+ bundleFiles,
1407
+ outfile: artifact.outfile,
1408
+ ...artifact.artifactOptions.additionalFilesToZip != null ? { additionalFilesToZip: artifact.artifactOptions.additionalFilesToZip } : {},
1409
+ ...artifact.artifactOptions.extra != null ? { extra: artifact.artifactOptions.extra } : {}
1410
+ });
1411
+ return { outfile: artifact.outfile, deploymentId: preparation.context.deploymentId };
1412
+ }
1413
+
1414
+ // src/BuildCommand.ts
1415
+ var BuildCommand = class extends Command {
1416
+ static paths = [["build"]];
1417
+ static usage = Command.Usage({
1418
+ category: "Build",
1419
+ description: "Build Apps In Toss artifact",
1420
+ examples: [["Build artifact", "ait build"]]
1421
+ });
1422
+ async execute() {
1423
+ const packageRoot = getPackageRoot();
1424
+ const buildResult = await buildArtifact(packageRoot);
1425
+ p3.log.success(`AIT build completed (${path7.basename(buildResult.outfile)})`);
1426
+ p3.log.info(`deploymentId: ${buildResult.deploymentId}`);
1427
+ }
1428
+ };
1429
+
780
1430
  // src/DeployCommand.ts
781
1431
  init_esm_shims();
782
1432
  var import_picocolors = __toESM(require_picocolors(), 1);
783
1433
  import assert from "assert";
784
- import fs3 from "fs";
785
- import path2 from "path";
1434
+ import fs8 from "fs";
1435
+ import path9 from "path";
786
1436
  import { AppsInTossBundle } from "@apps-in-toss/ait-format";
787
- import * as p from "@clack/prompts";
788
- import { getPackageRoot, readZipContent } from "@granite-js/utils";
789
- import { Command, Option } from "clipanion";
1437
+ import * as p4 from "@clack/prompts";
1438
+ import { getPackageRoot as getPackageRoot2, readZipContent } from "@granite-js/utils";
1439
+ import { Command as Command2, Option } from "clipanion";
790
1440
 
791
1441
  // src/utils/TokenStorage.ts
792
1442
  init_esm_shims();
793
- import fs from "fs";
1443
+ import fs6 from "fs";
794
1444
  import os from "os";
795
- import path from "path";
1445
+ import path8 from "path";
796
1446
  var TokenStorage = class {
797
1447
  static get path() {
798
1448
  const home = os.homedir();
799
- const dir = path.join(home, ".ait");
800
- if (!fs.existsSync(dir)) {
801
- fs.mkdirSync(dir, { recursive: true });
1449
+ const dir = path8.join(home, ".ait");
1450
+ if (!fs6.existsSync(dir)) {
1451
+ fs6.mkdirSync(dir, { recursive: true });
802
1452
  }
803
- return path.join(dir, "credentials");
1453
+ return path8.join(dir, "credentials");
804
1454
  }
805
1455
  static read() {
806
1456
  const file = this.path;
807
- if (!fs.existsSync(file)) {
1457
+ if (!fs6.existsSync(file)) {
808
1458
  return {};
809
1459
  }
810
- const raw = fs.readFileSync(file, "utf8");
1460
+ const raw = fs6.readFileSync(file, "utf8");
811
1461
  try {
812
1462
  const parsed = JSON.parse(raw);
813
1463
  if (parsed && typeof parsed === "object") {
@@ -820,7 +1470,7 @@ var TokenStorage = class {
820
1470
  static write(map) {
821
1471
  const file = this.path;
822
1472
  const content = JSON.stringify(map, null, 2);
823
- fs.writeFileSync(file, content, { encoding: "utf8" });
1473
+ fs6.writeFileSync(file, content, { encoding: "utf8" });
824
1474
  }
825
1475
  static set(workspace, token) {
826
1476
  const creds = this.read();
@@ -842,15 +1492,10 @@ var TokenStorage = class {
842
1492
  }
843
1493
  };
844
1494
 
845
- // src/utils/constants.ts
846
- init_esm_shims();
847
- var APP_MANIFEST_NAME = "app.json";
848
- var DEFAULT_API_BASE_URL = "https://apps-in-toss.toss.im/console";
849
-
850
1495
  // src/utils/upload.ts
851
1496
  init_esm_shims();
852
1497
  var import_debug2 = __toESM(require_src(), 1);
853
- import fs2 from "fs";
1498
+ import fs7 from "fs";
854
1499
 
855
1500
  // src/utils/flowAsync.ts
856
1501
  init_esm_shims();
@@ -942,8 +1587,8 @@ function uploadArtifactToRemote() {
942
1587
  return async (params) => {
943
1588
  const { config, output } = params;
944
1589
  debug2("uploadArtifactToRemote", config, output);
945
- const stat = await fs2.promises.stat(config.artifactPath);
946
- const stream = fs2.createReadStream(config.artifactPath);
1590
+ const stat = await fs7.promises.stat(config.artifactPath);
1591
+ const stream = fs7.createReadStream(config.artifactPath);
947
1592
  const response = await fetch(output.uploadUrl, {
948
1593
  method: "PUT",
949
1594
  headers: {
@@ -1013,7 +1658,7 @@ function checkBundleStatus(delayMs = 1e4, maxRetries = 10) {
1013
1658
  }
1014
1659
 
1015
1660
  // src/DeployCommand.ts
1016
- var DeployCommand = class extends Command {
1661
+ var DeployCommand = class extends Command2 {
1017
1662
  static paths = [["deploy"]];
1018
1663
  apiKey = Option.String("--api-key", {
1019
1664
  required: false,
@@ -1043,15 +1688,15 @@ var DeployCommand = class extends Command {
1043
1688
  const baseUrl = this.baseUrl;
1044
1689
  const profile = this.profile || this.workspace || "default";
1045
1690
  if (this.workspace) {
1046
- p.log.warn("(deprecated) --workspace \uC635\uC158\uC740 \uC774\uC81C \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC544\uC694. \uC774 \uC635\uC158 \uB300\uC2E0 --profile \uC635\uC158\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694.");
1691
+ p4.log.warn("(deprecated) --workspace \uC635\uC158\uC740 \uC774\uC81C \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC544\uC694. \uC774 \uC635\uC158 \uB300\uC2E0 --profile \uC635\uC158\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694.");
1047
1692
  }
1048
1693
  const apiKey = await this.getApiKey(profile);
1049
- if (p.isCancel(apiKey)) {
1694
+ if (p4.isCancel(apiKey)) {
1050
1695
  return;
1051
1696
  }
1052
1697
  try {
1053
1698
  const resolvedArtifactPath = this.getArtifactPath(this.location);
1054
- const buffer = fs3.readFileSync(resolvedArtifactPath);
1699
+ const buffer = fs8.readFileSync(resolvedArtifactPath);
1055
1700
  const format = AppsInTossBundle.detect(buffer);
1056
1701
  const { appName, deploymentId } = await (async () => {
1057
1702
  if (format === AppsInTossBundle.Format.AIT) {
@@ -1083,7 +1728,7 @@ var DeployCommand = class extends Command {
1083
1728
  baseUrl
1084
1729
  });
1085
1730
  } else {
1086
- await p.tasks([
1731
+ await p4.tasks([
1087
1732
  {
1088
1733
  title: `${colorAppName} \uC571 \uBC30\uD3EC \uC911...`,
1089
1734
  task: async () => {
@@ -1121,7 +1766,7 @@ var DeployCommand = class extends Command {
1121
1766
  this.context.stdout.write(`${result}
1122
1767
  `);
1123
1768
  } else {
1124
- p.note(this.decorate(result, import_picocolors.default.green));
1769
+ p4.note(this.decorate(result, import_picocolors.default.green));
1125
1770
  }
1126
1771
  }
1127
1772
  printError(error) {
@@ -1129,7 +1774,7 @@ var DeployCommand = class extends Command {
1129
1774
  this.context.stdout.write(`${error.message}
1130
1775
  `);
1131
1776
  } else {
1132
- p.log.error(error.message);
1777
+ p4.log.error(error.message);
1133
1778
  }
1134
1779
  }
1135
1780
  async getApiKey(profile) {
@@ -1137,7 +1782,7 @@ var DeployCommand = class extends Command {
1137
1782
  if (token) {
1138
1783
  return token;
1139
1784
  }
1140
- return await p.password({
1785
+ return await p4.password({
1141
1786
  message: "\uC571\uC778\uD1A0\uC2A4 \uBC30\uD3EC API \uD0A4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",
1142
1787
  validate: (value) => {
1143
1788
  if (value.length === 0) {
@@ -1152,24 +1797,24 @@ var DeployCommand = class extends Command {
1152
1797
  if (!location.endsWith(".ait")) {
1153
1798
  throw new Error("\uBC30\uD3EC\uD560 \uD30C\uC77C\uC740 .ait \uD655\uC7A5\uC790\uC5EC\uC57C \uD569\uB2C8\uB2E4.");
1154
1799
  }
1155
- return path2.resolve(location);
1800
+ return path9.resolve(location);
1156
1801
  }
1157
- const packageRoot = getPackageRoot();
1158
- const artifactFile = fs3.readdirSync(packageRoot).find((file) => file.endsWith(".ait"));
1802
+ const packageRoot = getPackageRoot2();
1803
+ const artifactFile = fs8.readdirSync(packageRoot).find((file) => file.endsWith(".ait"));
1159
1804
  if (!artifactFile) {
1160
1805
  throw new Error("\uBC30\uD3EC\uD560 .ait \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
1161
1806
  }
1162
- return path2.resolve(packageRoot, artifactFile);
1807
+ return path9.resolve(packageRoot, artifactFile);
1163
1808
  }
1164
1809
  };
1165
1810
 
1166
1811
  // src/InitCommand.ts
1167
1812
  init_esm_shims();
1168
- import fs4 from "fs";
1169
- import path3 from "path";
1170
- import * as p2 from "@clack/prompts";
1171
- import { getPackageRoot as getPackageRoot2 } from "@granite-js/utils";
1172
- import { Command as Command2, Option as Option2 } from "clipanion";
1813
+ import fs9 from "fs";
1814
+ import path10 from "path";
1815
+ import * as p5 from "@clack/prompts";
1816
+ import { getPackageRoot as getPackageRoot3 } from "@granite-js/utils";
1817
+ import { Command as Command3, Option as Option2 } from "clipanion";
1173
1818
 
1174
1819
  // ../../../.yarn/cache/es-toolkit-npm-1.32.0-019fc7c155-56ba965570.zip/node_modules/es-toolkit/dist/index.mjs
1175
1820
  init_esm_shims();
@@ -1266,7 +1911,7 @@ function transformTemplate(templateString, values) {
1266
1911
 
1267
1912
  // src/InitCommand.ts
1268
1913
  async function templateWebFramework({ appName, cwd, skipInput }) {
1269
- const packageJson = await fs4.promises.readFile(path3.join(cwd, "package.json"), {
1914
+ const packageJson = await fs9.promises.readFile(path10.join(cwd, "package.json"), {
1270
1915
  encoding: "utf-8"
1271
1916
  });
1272
1917
  const scripts = JSON.parse(packageJson);
@@ -1275,25 +1920,25 @@ async function templateWebFramework({ appName, cwd, skipInput }) {
1275
1920
  build: scripts?.scripts?.build
1276
1921
  };
1277
1922
  scripts.scripts.dev = "granite dev";
1278
- scripts.scripts.build = "granite build";
1923
+ scripts.scripts.build = "ait build";
1279
1924
  scripts.scripts.deploy = "ait deploy";
1280
- await fs4.promises.writeFile(path3.join(cwd, "package.json"), JSON.stringify(scripts, null, 2), {
1925
+ await fs9.promises.writeFile(path10.join(cwd, "package.json"), JSON.stringify(scripts, null, 2), {
1281
1926
  encoding: "utf-8"
1282
1927
  });
1283
- p2.log.step(".gitignore \uD30C\uC77C\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911...");
1284
- await fs4.promises.appendFile(path3.join(cwd, ".gitignore"), "\n.granite\n");
1928
+ p5.log.step(".gitignore \uD30C\uC77C\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911...");
1929
+ await fs9.promises.appendFile(path10.join(cwd, ".gitignore"), "\n.granite\n");
1285
1930
  const placeholder = {
1286
1931
  dev: originalScripts.dev === "granite dev" ? "" : originalScripts.dev,
1287
- build: originalScripts.build === "granite build" ? "" : originalScripts.build
1932
+ build: originalScripts.build === "ait build" ? "" : originalScripts.build
1288
1933
  };
1289
- const scriptInputs = skipInput ? placeholder : await p2.group(
1934
+ const scriptInputs = skipInput ? placeholder : await p5.group(
1290
1935
  {
1291
- dev: () => p2.text({
1936
+ dev: () => p5.text({
1292
1937
  message: "\uC6F9 \uBC88\uB4E4\uB7EC\uC758 dev \uBA85\uB839\uC5B4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.",
1293
1938
  defaultValue: placeholder.dev,
1294
1939
  placeholder: placeholder.dev
1295
1940
  }),
1296
- build: () => p2.text({
1941
+ build: () => p5.text({
1297
1942
  message: "\uC6F9 \uBC88\uB4E4\uB7EC\uC758 build \uBA85\uB839\uC5B4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.",
1298
1943
  defaultValue: placeholder.build,
1299
1944
  placeholder: placeholder.build
@@ -1301,44 +1946,56 @@ async function templateWebFramework({ appName, cwd, skipInput }) {
1301
1946
  },
1302
1947
  {
1303
1948
  onCancel: () => {
1304
- p2.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
1949
+ p5.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
1305
1950
  }
1306
1951
  }
1307
1952
  );
1308
- p2.log.step("granite.config.ts \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1309
- const webPort = skipInput ? "5173" : await p2.text({
1953
+ p5.log.step("granite.config.ts \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1954
+ const webPort = skipInput ? "5173" : await p5.text({
1310
1955
  message: "Enter web port",
1311
1956
  placeholder: "5173",
1312
1957
  defaultValue: "5173"
1313
1958
  });
1314
- if (p2.isCancel(webPort)) {
1315
- p2.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
1959
+ if (p5.isCancel(webPort)) {
1960
+ p5.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
1316
1961
  return;
1317
1962
  }
1318
1963
  const config = transformTemplate(WEB_FRAMEWORK_CONFIG_TEMPLATE, {
1319
1964
  appName,
1320
1965
  webPort,
1321
1966
  webDevCommand: scriptInputs.dev === "granite dev" ? "" : scriptInputs.dev,
1322
- webBuildCommand: scriptInputs.build === "granite build" ? "" : scriptInputs.build
1967
+ webBuildCommand: scriptInputs.build === "ait build" ? "" : scriptInputs.build
1323
1968
  });
1324
- await fs4.promises.writeFile(path3.join(cwd, "granite.config.ts"), config, {
1969
+ await fs9.promises.writeFile(path10.join(cwd, "granite.config.ts"), config, {
1325
1970
  encoding: "utf-8"
1326
1971
  });
1327
1972
  }
1328
1973
  async function templateReactNative({ appName, cwd }) {
1329
- p2.log.step("granite.config.ts \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1974
+ const packageJsonPath = path10.join(cwd, "package.json");
1975
+ const packageJsonRaw = await fs9.promises.readFile(packageJsonPath, {
1976
+ encoding: "utf-8"
1977
+ });
1978
+ const packageJson = JSON.parse(packageJsonRaw);
1979
+ packageJson.scripts ||= {};
1980
+ packageJson.scripts.dev = "granite dev";
1981
+ packageJson.scripts.build = "ait build";
1982
+ packageJson.scripts.deploy = "ait deploy";
1983
+ await fs9.promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), {
1984
+ encoding: "utf-8"
1985
+ });
1986
+ p5.log.step("granite.config.ts \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1330
1987
  const config = transformTemplate(REACT_NATIVE_FRAMEWORK_CONFIG_TEMPLATE, {
1331
1988
  appName
1332
1989
  });
1333
- await fs4.promises.writeFile(path3.join(cwd, "granite.config.ts"), config, {
1990
+ await fs9.promises.writeFile(path10.join(cwd, "granite.config.ts"), config, {
1334
1991
  encoding: "utf-8"
1335
1992
  });
1336
- p2.log.step("src/_app.tsx \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1337
- await fs4.promises.writeFile(path3.join(cwd, "src", "_app.tsx"), APP_TEMPLATE, {
1993
+ p5.log.step("src/_app.tsx \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
1994
+ await fs9.promises.writeFile(path10.join(cwd, "src", "_app.tsx"), APP_TEMPLATE, {
1338
1995
  encoding: "utf-8"
1339
1996
  });
1340
1997
  }
1341
- var InitCommand = class extends Command2 {
1998
+ var InitCommand = class extends Command3 {
1342
1999
  static paths = [[`init`]];
1343
2000
  template = Option2.String("--template", { required: false });
1344
2001
  appName = Option2.String("--app-name", { required: false });
@@ -1346,7 +2003,7 @@ var InitCommand = class extends Command2 {
1346
2003
  async execute() {
1347
2004
  const template = await ensureSelect({
1348
2005
  value: this.template,
1349
- prompt: async () => p2.select({
2006
+ prompt: async () => p5.select({
1350
2007
  message: "\uD504\uB85C\uC81D\uD2B8\uB97C \uCD08\uAE30\uD654\uD560 \uD15C\uD50C\uB9BF\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694.",
1351
2008
  options: [
1352
2009
  {
@@ -1362,14 +2019,14 @@ var InitCommand = class extends Command2 {
1362
2019
  ]
1363
2020
  })
1364
2021
  });
1365
- if (p2.isCancel(template)) {
2022
+ if (p5.isCancel(template)) {
1366
2023
  process.exit(0);
1367
2024
  }
1368
- const cwd = getPackageRoot2();
1369
- p2.intro("\u{1F680} \uC571 \uCD08\uAE30\uD654\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4");
2025
+ const cwd = getPackageRoot3();
2026
+ p5.intro("\u{1F680} \uC571 \uCD08\uAE30\uD654\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4");
1370
2027
  const appName = await ensureSelect({
1371
2028
  value: this.appName,
1372
- prompt: async () => p2.text({
2029
+ prompt: async () => p5.text({
1373
2030
  message: "Enter app name",
1374
2031
  validate: (value) => {
1375
2032
  if (!value) {
@@ -1383,11 +2040,11 @@ var InitCommand = class extends Command2 {
1383
2040
  }
1384
2041
  })
1385
2042
  });
1386
- if (p2.isCancel(appName)) {
1387
- p2.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
2043
+ if (p5.isCancel(appName)) {
2044
+ p5.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
1388
2045
  return;
1389
2046
  }
1390
- p2.log.step(`\uC571 \uC774\uB984\uC774 '${appName}'\uC73C\uB85C \uC124\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4`);
2047
+ p5.log.step(`\uC571 \uC774\uB984\uC774 '${appName}'\uC73C\uB85C \uC124\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4`);
1391
2048
  switch (template) {
1392
2049
  case "web-framework": {
1393
2050
  await templateWebFramework({
@@ -1405,7 +2062,7 @@ var InitCommand = class extends Command2 {
1405
2062
  break;
1406
2063
  }
1407
2064
  }
1408
- p2.outro("\u2728 \uCD08\uAE30\uD654\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!");
2065
+ p5.outro("\u2728 \uCD08\uAE30\uD654\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!");
1409
2066
  }
1410
2067
  };
1411
2068
 
@@ -1414,7 +2071,7 @@ init_esm_shims();
1414
2071
 
1415
2072
  // src/MigrateCommand/MigrateCommand.ts
1416
2073
  init_esm_shims();
1417
- import { Command as Command3, Option as Option3 } from "clipanion";
2074
+ import { Command as Command4, Option as Option3 } from "clipanion";
1418
2075
 
1419
2076
  // src/MigrateCommand/logger/index.ts
1420
2077
  init_esm_shims();
@@ -1452,24 +2109,24 @@ init_esm_shims();
1452
2109
 
1453
2110
  // src/MigrateCommand/fs/fileProcessor.ts
1454
2111
  init_esm_shims();
1455
- import { promises as fs5 } from "fs";
2112
+ import { promises as fs10 } from "fs";
1456
2113
  async function readFile(filePath) {
1457
2114
  try {
1458
- return await fs5.readFile(filePath, "utf-8");
2115
+ return await fs10.readFile(filePath, "utf-8");
1459
2116
  } catch {
1460
2117
  throw new Error(`Failed to read file: ${filePath}`);
1461
2118
  }
1462
2119
  }
1463
2120
  async function writeFile(filePath, content) {
1464
2121
  try {
1465
- await fs5.writeFile(filePath, content, "utf-8");
2122
+ await fs10.writeFile(filePath, content, "utf-8");
1466
2123
  } catch {
1467
2124
  throw new Error(`Failed to write file: ${filePath}`);
1468
2125
  }
1469
2126
  }
1470
2127
  async function fileExists(filePath) {
1471
2128
  try {
1472
- await fs5.access(filePath);
2129
+ await fs10.access(filePath);
1473
2130
  return true;
1474
2131
  } catch {
1475
2132
  return false;
@@ -1477,7 +2134,7 @@ async function fileExists(filePath) {
1477
2134
  }
1478
2135
  async function renameFile(oldPath, newPath) {
1479
2136
  try {
1480
- await fs5.rename(oldPath, newPath);
2137
+ await fs10.rename(oldPath, newPath);
1481
2138
  } catch {
1482
2139
  throw new Error(`Failed to rename file: ${oldPath} -> ${newPath}`);
1483
2140
  }
@@ -1485,27 +2142,27 @@ async function renameFile(oldPath, newPath) {
1485
2142
 
1486
2143
  // src/MigrateCommand/presets/granite/configProcessor.ts
1487
2144
  var configTransformer = (root, { j }) => {
1488
- root.find(j.ImportDeclaration).forEach((path6) => {
1489
- const source = path6.value.source;
2145
+ root.find(j.ImportDeclaration).forEach((path13) => {
2146
+ const source = path13.value.source;
1490
2147
  if (j.StringLiteral.check(source) && source.value === "react-native-bedrock/config") {
1491
- const defineConfigName = path6.value.specifiers?.find(
2148
+ const defineConfigName = path13.value.specifiers?.find(
1492
2149
  (specifier) => j.ImportSpecifier.check(specifier) && specifier.imported.name === "defineConfig"
1493
2150
  )?.local?.name;
1494
2151
  if (!defineConfigName) {
1495
2152
  return;
1496
2153
  }
1497
- root.find(j.CallExpression).forEach((path7) => {
1498
- const callee = path7.value.callee;
1499
- if (j.Identifier.check(callee) && callee.name === defineConfigName && path7.value.arguments.length > 0 && j.ObjectExpression.check(path7.value.arguments[0])) {
1500
- const obj = path7.value.arguments[0];
2154
+ root.find(j.CallExpression).forEach((path14) => {
2155
+ const callee = path14.value.callee;
2156
+ if (j.Identifier.check(callee) && callee.name === defineConfigName && path14.value.arguments.length > 0 && j.ObjectExpression.check(path14.value.arguments[0])) {
2157
+ const obj = path14.value.arguments[0];
1501
2158
  const hasScheme = obj.properties.some(
1502
2159
  (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "scheme"
1503
2160
  );
1504
2161
  if (!hasScheme) {
1505
2162
  obj.properties.unshift(j.objectProperty(j.identifier("scheme"), j.stringLiteral("intoss")));
1506
2163
  }
1507
- const routerImport = root.find(j.ImportDeclaration).filter((path8) => {
1508
- const source2 = path8.value.source;
2164
+ const routerImport = root.find(j.ImportDeclaration).filter((path15) => {
2165
+ const source2 = path15.value.source;
1509
2166
  return j.StringLiteral.check(source2) && source2.value === "@granite-js/plugin-router";
1510
2167
  });
1511
2168
  if (routerImport.length === 0) {
@@ -1654,12 +2311,12 @@ var identifierReplacementsTransformer = (root, { j }) => {
1654
2311
  }
1655
2312
  });
1656
2313
  });
1657
- root.find(j.Identifier).forEach((path6) => {
1658
- const name = path6.value.name;
2314
+ root.find(j.Identifier).forEach((path13) => {
2315
+ const name = path13.value.name;
1659
2316
  if (importedVariables.has(name)) {
1660
- const newName = toGraniteName(path6.value.name);
2317
+ const newName = toGraniteName(path13.value.name);
1661
2318
  if (newName) {
1662
- path6.value.name = newName;
2319
+ path13.value.name = newName;
1663
2320
  }
1664
2321
  }
1665
2322
  });
@@ -1668,11 +2325,11 @@ var identifierReplacementsTransformer = (root, { j }) => {
1668
2325
 
1669
2326
  // src/MigrateCommand/presets/granite/isBedrockProject.ts
1670
2327
  init_esm_shims();
1671
- import * as fs6 from "fs";
2328
+ import * as fs11 from "fs";
1672
2329
  var BASE_NAME = "bedrock.config";
1673
2330
  var EXTENSIONS = ["ts", "mts", "js", "cjs"];
1674
2331
  async function isBedrockProject(cwd) {
1675
- const files = fs6.readdirSync(cwd);
2332
+ const files = fs11.readdirSync(cwd);
1676
2333
  return files.some(isBedrockConfigFile);
1677
2334
  }
1678
2335
  function isBedrockConfigFile(file) {
@@ -1712,8 +2369,8 @@ var packageImportsTransformer = (root, { j }, { fileName = "<unknown>" }) => {
1712
2369
  }
1713
2370
  return value;
1714
2371
  }
1715
- root.find(j.ImportDeclaration).forEach((path6) => {
1716
- const source = path6.value.source;
2372
+ root.find(j.ImportDeclaration).forEach((path13) => {
2373
+ const source = path13.value.source;
1717
2374
  if (j.StringLiteral.check(source)) {
1718
2375
  const transformed = transformPackageName(source.value);
1719
2376
  if (transformed !== source.value) {
@@ -1723,8 +2380,8 @@ var packageImportsTransformer = (root, { j }, { fileName = "<unknown>" }) => {
1723
2380
  });
1724
2381
  root.find(j.CallExpression, {
1725
2382
  callee: { name: "require" }
1726
- }).forEach((path6) => {
1727
- const args = path6.value.arguments;
2383
+ }).forEach((path13) => {
2384
+ const args = path13.value.arguments;
1728
2385
  if (args.length > 0 && j.StringLiteral.check(args[0])) {
1729
2386
  const transformed = transformPackageName(args[0].value);
1730
2387
  if (transformed !== args[0].value) {
@@ -1732,8 +2389,8 @@ var packageImportsTransformer = (root, { j }, { fileName = "<unknown>" }) => {
1732
2389
  }
1733
2390
  }
1734
2391
  });
1735
- root.find(j.ImportExpression).forEach((path6) => {
1736
- const source = path6.value.source;
2392
+ root.find(j.ImportExpression).forEach((path13) => {
2393
+ const source = path13.value.source;
1737
2394
  if (j.StringLiteral.check(source)) {
1738
2395
  const transformed = transformPackageName(source.value);
1739
2396
  if (transformed !== source.value) {
@@ -1794,9 +2451,19 @@ var processPackageJson = async (cwd, config) => {
1794
2451
  if (packageJson.scripts) {
1795
2452
  const scripts = packageJson.scripts;
1796
2453
  for (const [key, value] of Object.entries(scripts)) {
1797
- if (typeof value === "string" && value.includes("bedrock")) {
1798
- scripts[key] = value.replace(/\bbedrock\b/g, "granite");
1799
- modified ||= true;
2454
+ if (typeof value !== "string") {
2455
+ continue;
2456
+ }
2457
+ let nextValue = value;
2458
+ if (nextValue.includes("bedrock")) {
2459
+ nextValue = nextValue.replace(/\bbedrock\b/g, "granite");
2460
+ }
2461
+ if (nextValue.includes("granite build")) {
2462
+ nextValue = nextValue.replace(/granite build/g, "ait build");
2463
+ }
2464
+ if (nextValue !== value) {
2465
+ scripts[key] = nextValue;
2466
+ modified = true;
1800
2467
  }
1801
2468
  }
1802
2469
  }
@@ -1831,14 +2498,14 @@ var APPS_IN_TOSS_FRAMEWORK_EXPORTS = [
1831
2498
  ];
1832
2499
  var toAppsInTossFrameworkImport = (root, { j }, { fileName = "<unknown>" }) => {
1833
2500
  const appsInTossFrameworkMembers = [];
1834
- root.find(j.ImportDeclaration).forEach((path6) => {
1835
- const source = path6.node.source.value;
2501
+ root.find(j.ImportDeclaration).forEach((path13) => {
2502
+ const source = path13.node.source.value;
1836
2503
  if (typeof source !== "string") {
1837
2504
  return;
1838
2505
  }
1839
2506
  if (source === "@granite-js/react-native") {
1840
- if (Array.isArray(path6.node.specifiers)) {
1841
- path6.node.specifiers = path6.node.specifiers.filter((specifier) => {
2507
+ if (Array.isArray(path13.node.specifiers)) {
2508
+ path13.node.specifiers = path13.node.specifiers.filter((specifier) => {
1842
2509
  if (shouldImportFromAppsInTossFramework(fileName, specifier)) {
1843
2510
  appsInTossFrameworkMembers.push(specifier);
1844
2511
  return false;
@@ -1846,8 +2513,8 @@ var toAppsInTossFrameworkImport = (root, { j }, { fileName = "<unknown>" }) => {
1846
2513
  return true;
1847
2514
  });
1848
2515
  }
1849
- if (path6.node.specifiers?.length === 0) {
1850
- j(path6).remove();
2516
+ if (path13.node.specifiers?.length === 0) {
2517
+ j(path13).remove();
1851
2518
  }
1852
2519
  }
1853
2520
  });
@@ -1869,33 +2536,6 @@ function shouldImportFromAppsInTossFramework(fileName, specifier) {
1869
2536
  }
1870
2537
  }
1871
2538
 
1872
- // src/MigrateCommand/codemod/index.ts
1873
- init_esm_shims();
1874
-
1875
- // src/MigrateCommand/codemod/transform.ts
1876
- init_esm_shims();
1877
- import jscodeshift from "jscodeshift";
1878
- function transform(source, { transformers: transformers2, options = {} }) {
1879
- const j = jscodeshift.withParser("tsx");
1880
- const report = [];
1881
- const stats = /* @__PURE__ */ new Map();
1882
- const context = {
1883
- j,
1884
- jscodeshift: j,
1885
- stats: (name, quantity = 1) => {
1886
- if (quantity === 0) {
1887
- return;
1888
- }
1889
- stats.set(name, (stats.get(name) ?? 0) + quantity);
1890
- },
1891
- report: (message) => {
1892
- report.push(message);
1893
- }
1894
- };
1895
- const root = transformers2.reduce((root2, transformer) => transformer(root2, context, options), j(source));
1896
- return root.toSource();
1897
- }
1898
-
1899
2539
  // src/MigrateCommand/fs/fileScanner.ts
1900
2540
  init_esm_shims();
1901
2541
  import glob from "fast-glob";
@@ -1960,26 +2600,239 @@ var migrateGranite = async (cwd, config) => {
1960
2600
  `);
1961
2601
  };
1962
2602
 
2603
+ // src/MigrateCommand/presets/react-native-0-84-0/index.ts
2604
+ init_esm_shims();
2605
+
2606
+ // src/MigrateCommand/presets/react-native-0-84-0/migrateReactNative0840.ts
2607
+ init_esm_shims();
2608
+ import dedent2 from "dedent";
2609
+ var TARGET_DEPENDENCY_VERSIONS = {
2610
+ react: "19.2.3",
2611
+ "react-dom": "19.2.3",
2612
+ "react-native": "0.84.0",
2613
+ "@types/react": "19.2.3",
2614
+ "@types/react-dom": "19.2.3",
2615
+ "react-test-renderer": "19.2.3",
2616
+ "babel-preset-granite": "1.0.3",
2617
+ "@babel/plugin-transform-flow-strip-types": "7.27.1",
2618
+ "@granite-js/react-native": "1.0.4",
2619
+ "@granite-js/native": "1.0.4",
2620
+ "@granite-js/plugin-core": "1.0.4",
2621
+ "@granite-js/plugin-env": "1.0.4",
2622
+ "@granite-js/plugin-hermes": "1.0.4",
2623
+ "@granite-js/plugin-router": "1.0.4",
2624
+ "@granite-js/plugin-micro-frontend": "1.0.4",
2625
+ "@granite-js/plugin-sentry": "1.0.4",
2626
+ "@toss/tds-react-native": "2.0.2",
2627
+ "brick-module": "0.5.0"
2628
+ };
2629
+ var BABEL_CONFIG_TEMPLATE = `module.exports = {
2630
+ presets: ['babel-preset-granite'],
2631
+ };
2632
+ `;
2633
+ var REQUIRED_DEPENDENCIES_BY_FIELD = {
2634
+ dependencies: {
2635
+ "brick-module": TARGET_DEPENDENCY_VERSIONS["brick-module"]
2636
+ },
2637
+ devDependencies: {
2638
+ "babel-preset-granite": TARGET_DEPENDENCY_VERSIONS["babel-preset-granite"]
2639
+ }
2640
+ };
2641
+ var DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "peerDependencies"];
2642
+ function processDependencyMap(deps, frameworkVersion) {
2643
+ let modified = false;
2644
+ for (const [name, version] of Object.entries(deps)) {
2645
+ if (name.startsWith("@apps-in-toss/")) {
2646
+ if (name === "@apps-in-toss/framework" || frameworkVersion == null) {
2647
+ continue;
2648
+ }
2649
+ if (version !== frameworkVersion) {
2650
+ deps[name] = frameworkVersion;
2651
+ modified = true;
2652
+ }
2653
+ continue;
2654
+ }
2655
+ const targetVersion = TARGET_DEPENDENCY_VERSIONS[name];
2656
+ if (targetVersion == null || version === targetVersion) {
2657
+ continue;
2658
+ }
2659
+ if (version !== targetVersion) {
2660
+ deps[name] = targetVersion;
2661
+ modified = true;
2662
+ }
2663
+ }
2664
+ return modified;
2665
+ }
2666
+ function findDependencyVersion(packageJson, dependencyName) {
2667
+ for (const field of DEPENDENCY_FIELDS) {
2668
+ const deps = packageJson[field];
2669
+ if (deps?.[dependencyName] != null) {
2670
+ return deps[dependencyName];
2671
+ }
2672
+ }
2673
+ return void 0;
2674
+ }
2675
+ function hasReactNativeDependency(packageJson) {
2676
+ return findDependencyVersion(packageJson, "react-native") != null;
2677
+ }
2678
+ function processScriptMap(scripts) {
2679
+ let modified = false;
2680
+ for (const [scriptName, scriptValue] of Object.entries(scripts)) {
2681
+ if (!scriptValue.includes("granite build")) {
2682
+ continue;
2683
+ }
2684
+ const nextScriptValue = scriptValue.replace(/granite build/g, "ait build");
2685
+ if (nextScriptValue !== scriptValue) {
2686
+ scripts[scriptName] = nextScriptValue;
2687
+ modified = true;
2688
+ }
2689
+ }
2690
+ return modified;
2691
+ }
2692
+ function ensureRequiredDependencies(packageJson) {
2693
+ let modified = false;
2694
+ for (const field of DEPENDENCY_FIELDS) {
2695
+ const requiredDependencies = REQUIRED_DEPENDENCIES_BY_FIELD[field];
2696
+ if (requiredDependencies == null) {
2697
+ continue;
2698
+ }
2699
+ packageJson[field] ??= {};
2700
+ const deps = packageJson[field];
2701
+ if (deps == null) {
2702
+ continue;
2703
+ }
2704
+ for (const [dependencyName, requiredVersion] of Object.entries(requiredDependencies)) {
2705
+ if (deps[dependencyName] === requiredVersion) {
2706
+ continue;
2707
+ }
2708
+ deps[dependencyName] = requiredVersion;
2709
+ modified = true;
2710
+ }
2711
+ }
2712
+ return modified;
2713
+ }
2714
+ async function processPackageJson2(cwd, config) {
2715
+ logger.log("Processing package.json...");
2716
+ const packageJsonPath = `${cwd}/package.json`;
2717
+ if (!await fileExists(packageJsonPath)) {
2718
+ logger.log("No package.json found");
2719
+ return false;
2720
+ }
2721
+ try {
2722
+ const content = await readFile(packageJsonPath);
2723
+ const packageJson = JSON.parse(content);
2724
+ if (!hasReactNativeDependency(packageJson)) {
2725
+ logger.log("Skipping migration: react-native dependency not found in package.json");
2726
+ return false;
2727
+ }
2728
+ const appsInTossFrameworkVersion = findDependencyVersion(packageJson, "@apps-in-toss/framework");
2729
+ let modified = false;
2730
+ for (const field of DEPENDENCY_FIELDS) {
2731
+ if (packageJson[field] == null) {
2732
+ continue;
2733
+ }
2734
+ modified = processDependencyMap(packageJson[field], appsInTossFrameworkVersion) || modified;
2735
+ }
2736
+ modified = ensureRequiredDependencies(packageJson) || modified;
2737
+ if (packageJson.scripts != null) {
2738
+ modified = processScriptMap(packageJson.scripts) || modified;
2739
+ }
2740
+ if (!modified) {
2741
+ logger.log("No changes needed in package.json");
2742
+ return true;
2743
+ }
2744
+ if (config.dryRun === true) {
2745
+ logger.log("Skipping package.json write in dry run mode");
2746
+ return true;
2747
+ }
2748
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
2749
+ logger.success("Updated package.json");
2750
+ return true;
2751
+ } catch (error) {
2752
+ logger.error(`Failed to process package.json: ${error}`);
2753
+ return false;
2754
+ }
2755
+ }
2756
+ function isTargetBabelConfig(content) {
2757
+ return content.trim() === BABEL_CONFIG_TEMPLATE.trim();
2758
+ }
2759
+ async function processBabelConfig(cwd, config) {
2760
+ logger.log("Processing babel.config.js...");
2761
+ const babelConfigPath = `${cwd}/babel.config.js`;
2762
+ if (!await fileExists(babelConfigPath)) {
2763
+ logger.log("No babel.config.js found");
2764
+ return;
2765
+ }
2766
+ try {
2767
+ const content = await readFile(babelConfigPath);
2768
+ if (isTargetBabelConfig(content)) {
2769
+ logger.log("No changes needed in babel.config.js");
2770
+ return;
2771
+ }
2772
+ if (config.dryRun === true) {
2773
+ logger.log("Skipping babel.config.js write in dry run mode");
2774
+ return;
2775
+ }
2776
+ await writeFile(babelConfigPath, BABEL_CONFIG_TEMPLATE);
2777
+ logger.success("Updated babel.config.js");
2778
+ } catch (error) {
2779
+ logger.error(`Failed to process babel.config.js: ${error}`);
2780
+ }
2781
+ }
2782
+ var migrateReactNative0840 = async (cwd, config) => {
2783
+ const isReactNativeProject = await processPackageJson2(cwd, config);
2784
+ if (!isReactNativeProject) {
2785
+ logger.log("Skipping remaining migration steps");
2786
+ return;
2787
+ }
2788
+ await processBabelConfig(cwd, config);
2789
+ logger.log(dedent2`
2790
+ Please check the following steps:
2791
+
2792
+ - Install dependencies
2793
+ - Run type checks
2794
+ - Run lint checks
2795
+ - Run tests
2796
+ - Review migration warnings manually (if any)\n
2797
+ `);
2798
+ };
2799
+
1963
2800
  // src/MigrateCommand/presets/index.ts
1964
2801
  var MIGRATE_PRESETS = {
1965
- granite: migrateGranite
2802
+ granite: migrateGranite,
2803
+ "react-native-0-84-0": migrateReactNative0840
1966
2804
  };
1967
2805
 
1968
2806
  // src/MigrateCommand/MigrateCommand.ts
1969
- var MigrateCommand = class extends Command3 {
2807
+ function getAvailablePresetTargets() {
2808
+ return Object.keys(MIGRATE_PRESETS).sort();
2809
+ }
2810
+ function logAvailablePresets(level = "log") {
2811
+ const output = level === "error" ? logger.error.bind(logger) : logger.log.bind(logger);
2812
+ output("Available migration presets:");
2813
+ for (const target of getAvailablePresetTargets()) {
2814
+ output(`- ${target}`);
2815
+ }
2816
+ }
2817
+ var MigrateCommand = class extends Command4 {
1970
2818
  static paths = [[`migrate`]];
1971
- static usage = Command3.Usage({
2819
+ static usage = Command4.Usage({
1972
2820
  category: "Migration",
1973
2821
  description: "Run migration",
1974
2822
  examples: [
1975
2823
  ["Run migration", "ait migrate <target>"],
1976
- ["Check migration availability", "ait migrate <target> --dryRun"]
2824
+ ["Check migration availability", "ait migrate"],
2825
+ ["Dry run migration", "ait migrate <target> --dry-run"]
1977
2826
  ]
1978
2827
  });
1979
- target = Option3.String({ required: true });
2828
+ target = Option3.String({ required: false });
1980
2829
  dryRun = Option3.Boolean("--dry-run", { required: false });
1981
2830
  async execute() {
1982
2831
  try {
2832
+ if (this.target == null) {
2833
+ logAvailablePresets();
2834
+ return 0;
2835
+ }
1983
2836
  const cwd = process.cwd();
1984
2837
  const config = {
1985
2838
  dryRun: this.dryRun
@@ -1988,7 +2841,9 @@ var MigrateCommand = class extends Command3 {
1988
2841
  logger.log(`Working directory: ${cwd}`);
1989
2842
  const migrate = MIGRATE_PRESETS[this.target];
1990
2843
  if (migrate == null) {
1991
- throw new Error(`Unknown target: ${this.target}`);
2844
+ logger.error(`Unknown target: ${this.target}`);
2845
+ logAvailablePresets("error");
2846
+ return 1;
1992
2847
  }
1993
2848
  await migrate(cwd, config);
1994
2849
  logger.success("Migration completed successfully!");
@@ -2003,12 +2858,12 @@ var MigrateCommand = class extends Command3 {
2003
2858
  // src/TokenCommand.ts
2004
2859
  init_esm_shims();
2005
2860
  var import_debug3 = __toESM(require_src(), 1);
2006
- import * as p3 from "@clack/prompts";
2007
- import { Command as Command4, Option as Option4 } from "clipanion";
2861
+ import * as p6 from "@clack/prompts";
2862
+ import { Command as Command5, Option as Option4 } from "clipanion";
2008
2863
  var debug3 = (0, import_debug3.default)("cli:token");
2009
- var TokenCommand = class extends Command4 {
2864
+ var TokenCommand = class extends Command5 {
2010
2865
  static paths = [["token"]];
2011
- static usage = Command4.Usage({
2866
+ static usage = Command5.Usage({
2012
2867
  description: "\uD1A0\uD070 \uAD00\uB828 \uD558\uC704 \uBA85\uB839\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4.",
2013
2868
  examples: [
2014
2869
  ["\uD1A0\uD070 \uCD94\uAC00", "ait token add <profile?>"],
@@ -2019,9 +2874,9 @@ var TokenCommand = class extends Command4 {
2019
2874
  debug3("execute");
2020
2875
  }
2021
2876
  };
2022
- var TokenAddCommand = class extends Command4 {
2877
+ var TokenAddCommand = class extends Command5 {
2023
2878
  static paths = [["token", "add"]];
2024
- static usage = Command4.Usage({
2879
+ static usage = Command5.Usage({
2025
2880
  description: "\uC2DC\uD06C\uB9BF \uD1A0\uD070\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.",
2026
2881
  examples: [
2027
2882
  ["\uAE30\uBCF8 \uBCC4\uCE6D\uC73C\uB85C \uD1A0\uD070 \uCD94\uAC00", "ait token add"],
@@ -2032,7 +2887,7 @@ var TokenAddCommand = class extends Command4 {
2032
2887
  apiKey = Option4.String("--api-key", { required: false });
2033
2888
  async execute() {
2034
2889
  const profile = this.profile || "default";
2035
- const secret = this.apiKey ? this.apiKey : await p3.password({
2890
+ const secret = this.apiKey ? this.apiKey : await p6.password({
2036
2891
  message: "Enter secret token:",
2037
2892
  validate: (value) => {
2038
2893
  if (value.length === 0) {
@@ -2041,7 +2896,7 @@ var TokenAddCommand = class extends Command4 {
2041
2896
  return;
2042
2897
  }
2043
2898
  });
2044
- if (p3.isCancel(secret)) {
2899
+ if (p6.isCancel(secret)) {
2045
2900
  return;
2046
2901
  }
2047
2902
  TokenStorage.set(profile, secret);
@@ -2050,9 +2905,9 @@ var TokenAddCommand = class extends Command4 {
2050
2905
  `);
2051
2906
  }
2052
2907
  };
2053
- var TokenRemoveCommand = class extends Command4 {
2908
+ var TokenRemoveCommand = class extends Command5 {
2054
2909
  static paths = [["token", "remove"]];
2055
- static usage = Command4.Usage({
2910
+ static usage = Command5.Usage({
2056
2911
  description: "\uC2DC\uD06C\uB9BF \uD1A0\uD070\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4.",
2057
2912
  examples: [
2058
2913
  ["\uAE30\uBCF8 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uC758 \uD1A0\uD070 \uC0AD\uC81C", "ait token remove"],
@@ -2079,16 +2934,16 @@ init_esm_shims();
2079
2934
 
2080
2935
  // src/integrations/UploadSentrySourcemap/UploadSentrySourcemap.ts
2081
2936
  init_esm_shims();
2082
- import * as fs10 from "fs/promises";
2083
- import * as p4 from "@clack/prompts";
2084
- import { Command as Command5, Option as Option5 } from "clipanion";
2937
+ import * as fs15 from "fs/promises";
2938
+ import * as p7 from "@clack/prompts";
2939
+ import { Command as Command6, Option as Option5 } from "clipanion";
2085
2940
 
2086
2941
  // src/integrations/UploadSentrySourcemap/downloadArtifacts.ts
2087
2942
  init_esm_shims();
2088
2943
  var import_debug4 = __toESM(require_src(), 1);
2089
- import * as fs7 from "fs";
2944
+ import * as fs12 from "fs";
2090
2945
  import * as os2 from "os";
2091
- import * as path4 from "path";
2946
+ import * as path11 from "path";
2092
2947
  import { pipeline } from "stream";
2093
2948
  import { promisify } from "util";
2094
2949
  var debug4 = (0, import_debug4.default)("integrations:sentry");
@@ -2116,36 +2971,36 @@ async function downloadArtifacts(options) {
2116
2971
  }
2117
2972
  const tmpDir = await createTempDirectory();
2118
2973
  const tmpFile = `${deploymentId}.zip`;
2119
- const tmpFilePath = path4.join(tmpDir.path, tmpFile);
2120
- const fileStream = fs7.createWriteStream(tmpFilePath);
2974
+ const tmpFilePath = path11.join(tmpDir.path, tmpFile);
2975
+ const fileStream = fs12.createWriteStream(tmpFilePath);
2121
2976
  await streamPipeline(response.body, fileStream);
2122
2977
  debug4("Artifacts downloaded", { tmpFilePath });
2123
2978
  return tmpFilePath;
2124
2979
  }
2125
2980
  function createTempDirectory() {
2126
- const tempDir = path4.join(os2.tmpdir(), "apps-in-toss", "sentry-integration");
2127
- fs7.mkdirSync(tempDir, { recursive: true });
2981
+ const tempDir = path11.join(os2.tmpdir(), "apps-in-toss", "sentry-integration");
2982
+ fs12.mkdirSync(tempDir, { recursive: true });
2128
2983
  debug4("Temp directory created", { tempDir });
2129
2984
  return {
2130
2985
  path: tempDir,
2131
2986
  cleanup: () => {
2132
- fs7.rmSync(tempDir, { recursive: true, force: true });
2987
+ fs12.rmSync(tempDir, { recursive: true, force: true });
2133
2988
  }
2134
2989
  };
2135
2990
  }
2136
2991
 
2137
2992
  // src/integrations/UploadSentrySourcemap/extractSentryDebugId.ts
2138
2993
  init_esm_shims();
2139
- import fs8 from "fs/promises";
2994
+ import fs13 from "fs/promises";
2140
2995
  async function extractSentryDebugId(bundlePath) {
2141
- const bundleContent = await fs8.readFile(bundlePath, "utf-8");
2996
+ const bundleContent = await fs13.readFile(bundlePath, "utf-8");
2142
2997
  return bundleContent.match(/SENTRY_DEBUG_ID=([\w-]+)/)?.[1];
2143
2998
  }
2144
2999
 
2145
3000
  // src/integrations/UploadSentrySourcemap/extractSources.ts
2146
3001
  init_esm_shims();
2147
- import * as fs9 from "fs";
2148
- import * as path5 from "path";
3002
+ import * as fs14 from "fs";
3003
+ import * as path12 from "path";
2149
3004
  import { pipeline as pipeline2 } from "stream";
2150
3005
  import { promisify as promisify2 } from "util";
2151
3006
  import * as zlib from "zlib";
@@ -2166,12 +3021,12 @@ async function extractSources(zipPath) {
2166
3021
  hermesSourceMap: ""
2167
3022
  }
2168
3023
  };
2169
- await fs9.createReadStream(zipPath).pipe(unzipper.Parse()).on("entry", async (entry) => {
3024
+ await fs14.createReadStream(zipPath).pipe(unzipper.Parse()).on("entry", async (entry) => {
2170
3025
  const isRoot = !entry.path.includes("/");
2171
- const fileName = path5.basename(entry.path);
2172
- const outputPath = path5.join(path5.dirname(zipPath), fileName);
3026
+ const fileName = path12.basename(entry.path);
3027
+ const outputPath = path12.join(path12.dirname(zipPath), fileName);
2173
3028
  if (isRoot) {
2174
- entry.pipe(fs9.createWriteStream(outputPath));
3029
+ entry.pipe(fs14.createWriteStream(outputPath));
2175
3030
  const platform = fileName.includes("android") ? "android" : "ios";
2176
3031
  if (fileName.endsWith(".js")) {
2177
3032
  sources[platform].packagerBundle = outputPath;
@@ -2199,7 +3054,7 @@ async function extractSources(zipPath) {
2199
3054
  }
2200
3055
  async function decompressGzip(gzFile) {
2201
3056
  const outfile = gzFile.replace(/\.gz$/g, "");
2202
- await pipe(fs9.createReadStream(gzFile), zlib.createGunzip(), fs9.createWriteStream(outfile));
3057
+ await pipe(fs14.createReadStream(gzFile), zlib.createGunzip(), fs14.createWriteStream(outfile));
2203
3058
  return outfile;
2204
3059
  }
2205
3060
 
@@ -2230,7 +3085,7 @@ function uploadSourcemap(bundlePath, sourcemapPath, options) {
2230
3085
  }
2231
3086
 
2232
3087
  // src/integrations/UploadSentrySourcemap/UploadSentrySourcemap.ts
2233
- var UploadSentrySourcemap = class extends Command5 {
3088
+ var UploadSentrySourcemap = class extends Command6 {
2234
3089
  static paths = [["sentry", "upload-sourcemap"]];
2235
3090
  apiKey = Option5.String("--api-key", {
2236
3091
  required: false,
@@ -2270,7 +3125,7 @@ var UploadSentrySourcemap = class extends Command5 {
2270
3125
  try {
2271
3126
  const zipPath = await downloadArtifacts({ apiKey, appName, deploymentId, baseUrl });
2272
3127
  const sources = await extractSources(zipPath);
2273
- await p4.tasks([
3128
+ await p7.tasks([
2274
3129
  {
2275
3130
  title: "Android \uC18C\uC2A4\uB9F5 \uC5C5\uB85C\uB4DC \uC911...",
2276
3131
  task: async () => {
@@ -2296,10 +3151,10 @@ var UploadSentrySourcemap = class extends Command5 {
2296
3151
  }
2297
3152
  }
2298
3153
  ]);
2299
- p4.outro("Sentry \uC18C\uC2A4\uB9F5 \uC5C5\uB85C\uB4DC \uC644\uB8CC");
3154
+ p7.outro("Sentry \uC18C\uC2A4\uB9F5 \uC5C5\uB85C\uB4DC \uC644\uB8CC");
2300
3155
  } catch (error) {
2301
3156
  if (error instanceof Error) {
2302
- p4.log.error(error.message);
3157
+ p7.log.error(error.message);
2303
3158
  } else {
2304
3159
  console.error(error);
2305
3160
  }
@@ -2312,14 +3167,14 @@ var UploadSentrySourcemap = class extends Command5 {
2312
3167
  throw new Error("Sentry Debug ID\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
2313
3168
  }
2314
3169
  const mergedSourceMap = await mergeSourceMaps(
2315
- await fs10.readFile(sources.packagerSourceMap, "utf-8"),
2316
- await fs10.readFile(sources.hermesSourceMap, "utf-8")
3170
+ await fs15.readFile(sources.packagerSourceMap, "utf-8"),
3171
+ await fs15.readFile(sources.hermesSourceMap, "utf-8")
2317
3172
  );
2318
3173
  const injectedSourceMap = injectSentryDebugId(mergedSourceMap, debugId);
2319
- await fs10.writeFile(sources.hermesSourceMap, JSON.stringify(injectedSourceMap, null, 2), "utf-8");
3174
+ await fs15.writeFile(sources.hermesSourceMap, JSON.stringify(injectedSourceMap, null, 2), "utf-8");
2320
3175
  }
2321
3176
  async promptRequiredValue(type, message, validateMessage) {
2322
- const result = await p4[type]({
3177
+ const result = await p7[type]({
2323
3178
  message,
2324
3179
  validate: (value) => {
2325
3180
  if (value.length === 0) {
@@ -2328,7 +3183,7 @@ var UploadSentrySourcemap = class extends Command5 {
2328
3183
  return;
2329
3184
  }
2330
3185
  });
2331
- if (p4.isCancel(result)) {
3186
+ if (p7.isCancel(result)) {
2332
3187
  throw new Error("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694.");
2333
3188
  }
2334
3189
  return result;
@@ -2336,11 +3191,13 @@ var UploadSentrySourcemap = class extends Command5 {
2336
3191
  };
2337
3192
 
2338
3193
  // src/index.ts
3194
+ import { babelBuild as babelBuild2, babelJsonReplacementPlugin, getPackageManager as getPackageManager3, loadConfig as loadConfig2 } from "@apps-in-toss/web-config";
2339
3195
  function initialize() {
2340
3196
  const cli = new Cli({
2341
3197
  binaryLabel: "ait",
2342
3198
  binaryName: "ait"
2343
3199
  });
3200
+ cli.register(BuildCommand);
2344
3201
  cli.register(DeployCommand);
2345
3202
  cli.register(InitCommand);
2346
3203
  cli.register(MigrateCommand);
@@ -2352,5 +3209,9 @@ function initialize() {
2352
3209
  cli.runExit(process.argv.slice(2));
2353
3210
  }
2354
3211
  export {
2355
- initialize
3212
+ babelBuild2 as babelBuild,
3213
+ babelJsonReplacementPlugin,
3214
+ getPackageManager3 as getPackageManager,
3215
+ initialize,
3216
+ loadConfig2 as loadConfig
2356
3217
  };