@apps-in-toss/plugins 1.14.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -27,6 +27,7 @@ type CameraPermission = {
27
27
  type Permission = ClipboardPermission | GeolocationPermission | ContactsPermission | PhotosPermission | CameraPermission;
28
28
  type AppManifest = {
29
29
  appName: string;
30
+ appType?: 'general' | 'game';
30
31
  permissions: Permission[];
31
32
  _metadata: {
32
33
  bundleFiles: string[];
@@ -49,6 +50,7 @@ interface InitialAccessoryButton {
49
50
  }
50
51
  declare const validateAppManifest: ((input: unknown) => typia.IValidation<AppManifest>) & _standard_schema_spec.StandardSchemaV1<unknown, AppManifest>;
51
52
  interface AppsInTossPluginOptions {
53
+ target?: '0.72.6' | '0.84.0';
52
54
  appType?: 'general' | 'game';
53
55
  brand: {
54
56
  displayName: string;
@@ -64,6 +66,7 @@ interface AppsInTossPluginOptions {
64
66
  }
65
67
  declare const validateAppInTossPluginOptions: ((input: unknown) => typia.IValidation<AppsInTossPluginOptions>) & _standard_schema_spec.StandardSchemaV1<unknown, AppsInTossPluginOptions>;
66
68
 
69
+ declare function getAppsInTossBuildPlugins(options: Pick<AppsInTossPluginOptions, 'permissions'>): GranitePluginCore[];
67
70
  declare function withAppsInTossCommon(plugins: (GranitePluginCore | Promise<GranitePluginCore>)[], options: AppsInTossPluginOptions & {
68
71
  root: string;
69
72
  deploymentId: string;
@@ -92,6 +95,7 @@ interface CreateArtifactOptions {
92
95
  bundleFiles: {
93
96
  path: string;
94
97
  platform: 'ios' | 'android';
98
+ runtimeVersion?: string;
95
99
  }[];
96
100
  reactNativeVersion: string;
97
101
  sdkVersion: string;
@@ -100,10 +104,12 @@ interface CreateArtifactOptions {
100
104
  outfile: string;
101
105
  deploymentId: AppsInTossBuildMetadata['deploymentId'];
102
106
  packageJson: AppsInTossBuildMetadata['packageJson'];
107
+ isWeb: boolean;
103
108
  additionalFilesToZip?: {
104
109
  path: string;
105
110
  name: string;
106
111
  }[];
112
+ extra?: Record<string, unknown>;
107
113
  }
108
114
  declare function createArtifact(options: CreateArtifactOptions): Promise<string>;
109
115
 
@@ -127,12 +133,15 @@ declare function collectDependencyVersions(rootDir: string): Promise<{
127
133
  devDependencies: Record<string, string>;
128
134
  }>;
129
135
 
130
- declare function appsInTossAppJson(options: Pick<AppsInTossPluginOptions, 'permissions'>): Promise<GranitePluginCore>;
136
+ declare function getSdkVersion(): string;
137
+
138
+ declare function appsInTossAppJson(options: Pick<AppsInTossPluginOptions, 'permissions' | 'appType'>): Promise<GranitePluginCore>;
131
139
 
132
140
  declare function appsInTossCreateArtifact(deploymentId: string, buildOption: {
133
141
  isGame: boolean;
134
142
  sdkVersion: string;
135
- }): GranitePluginCore;
143
+ isWeb: boolean;
144
+ }, reactNativeVersion?: string): GranitePluginCore;
136
145
 
137
146
  declare function appsInTossEsbuildConfig(envScript: string): GranitePluginCore;
138
147
  declare function appsInTossMetroConfig(envScriptPath: string): GranitePluginCore;
@@ -153,10 +162,28 @@ declare function bedrockCompat({ isHost }: {
153
162
  isHost: boolean;
154
163
  }): GranitePluginCore;
155
164
 
165
+ /**
166
+ * TossCoreCryptoModule의 decrypt 메서드를 global.__decrypt로 노출하는 polyfill 코드
167
+ *
168
+ * - global.__decrypt가 이미 존재하는 경우 덮어쓰지 않음
169
+ * - TossCoreCryptoModule.decrypt가 존재할 때만 할당하여 런타임 에러 방지
170
+ */
171
+ declare const cryptoPolyfillContent = "\n(function (global) {\n if (!global.__decrypt &&\n global.nativeModuleProxy &&\n global.nativeModuleProxy.TossCoreCryptoModule &&\n global.nativeModuleProxy.TossCoreCryptoModule.decrypt) {\n global.__decrypt = global.nativeModuleProxy.TossCoreCryptoModule.decrypt;\n }\n})(\n typeof globalThis !== 'undefined'\n ? globalThis\n : typeof global !== 'undefined'\n ? global\n : typeof window !== 'undefined'\n ? window\n : this\n);\n";
172
+ /**
173
+ * TossCoreCryptoModule을 전역에서 접근 가능하도록 설정하는 Granite 플러그인
174
+ *
175
+ * @param isHost - Host 번들 여부
176
+ * - true: Host 번들 (esbuild banner에 polyfill 포함)
177
+ * - false: Remote 번들 (esbuild banner에서 제외, Host에서 이미 로드됨)
178
+ */
179
+ declare function appsInTossCrypto({ isHost }: {
180
+ isHost: boolean;
181
+ }): GranitePluginCore;
182
+
156
183
  declare function appsInTossDevServer(options: Pick<AppsInTossPluginOptions, 'permissions'>): GranitePluginCore;
157
184
 
158
185
  declare function appsInTossPostNotice(): GranitePluginCore;
159
186
 
160
187
  declare function requireMicroFrontendRuntime(): GranitePluginCore;
161
188
 
162
- export { type AppManifest, type AppsInTossPluginOptions, type BuildResult, type CreateArtifactOptions, type InitialAccessoryButton, type Permission, analytics, appsInToss, appsInTossAppJson, appsInTossCreateArtifact, appsInTossDevServer, appsInTossEsbuildConfig, appsInTossMetroConfig, appsInTossPostNotice, bedrockCompat, collectDependencyVersions, createArtifact, getRuntimeSetupScript, nativeModuleProxyContent, reactNativeModuleProxyContent, requireMicroFrontendRuntime, setupHostRuntimeSetupScript, setupRuntimeSetupScript, validateAppInTossPluginOptions, validateAppManifest, withAppsInTossCommon };
189
+ export { type AppManifest, type AppsInTossPluginOptions, type BuildResult, type CreateArtifactOptions, type InitialAccessoryButton, type Permission, analytics, appsInToss, appsInTossAppJson, appsInTossCreateArtifact, appsInTossCrypto, appsInTossDevServer, appsInTossEsbuildConfig, appsInTossMetroConfig, appsInTossPostNotice, bedrockCompat, collectDependencyVersions, createArtifact, cryptoPolyfillContent, getAppsInTossBuildPlugins, getRuntimeSetupScript, getSdkVersion, nativeModuleProxyContent, reactNativeModuleProxyContent, requireMicroFrontendRuntime, setupHostRuntimeSetupScript, setupRuntimeSetupScript, validateAppInTossPluginOptions, validateAppManifest, withAppsInTossCommon };
package/dist/index.js CHANGED
@@ -34,9 +34,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  mod
35
35
  ));
36
36
 
37
- // ../../../.yarn/__virtual__/tsup-virtual-dc9661456a/0/cache/tsup-npm-8.4.0-f78d2622c9-c6636ffd6a.zip/node_modules/tsup/assets/esm_shims.js
37
+ // ../../../.yarn/__virtual__/tsup-virtual-5946fc3428/0/cache/tsup-npm-8.4.0-f78d2622c9-c6636ffd6a.zip/node_modules/tsup/assets/esm_shims.js
38
38
  var init_esm_shims = __esm({
39
- "../../../.yarn/__virtual__/tsup-virtual-dc9661456a/0/cache/tsup-npm-8.4.0-f78d2622c9-c6636ffd6a.zip/node_modules/tsup/assets/esm_shims.js"() {
39
+ "../../../.yarn/__virtual__/tsup-virtual-5946fc3428/0/cache/tsup-npm-8.4.0-f78d2622c9-c6636ffd6a.zip/node_modules/tsup/assets/esm_shims.js"() {
40
40
  "use strict";
41
41
  }
42
42
  });
@@ -62,11 +62,11 @@ var require_validateReport = __commonJS({
62
62
  Object.defineProperty(exports, "__esModule", { value: true });
63
63
  exports._validateReport = void 0;
64
64
  var _validateReport2 = (array) => {
65
- const reportable = (path8) => {
65
+ const reportable = (path9) => {
66
66
  if (array.length === 0)
67
67
  return true;
68
68
  const last = array[array.length - 1].path;
69
- return path8.length > last.length || last.substring(0, path8.length) !== path8;
69
+ return path9.length > last.length || last.substring(0, path9.length) !== path9;
70
70
  };
71
71
  return (exceptable, error2) => {
72
72
  var _a;
@@ -122,24 +122,24 @@ var require_createStandardSchema = __commonJS({
122
122
  PathParserState2[PathParserState2["StringKey"] = 2] = "StringKey";
123
123
  PathParserState2[PathParserState2["NumberKey"] = 3] = "NumberKey";
124
124
  })(PathParserState || (PathParserState = {}));
125
- var typiaPathToStandardSchemaPath = (path8) => {
126
- if (!path8.startsWith("$input")) {
127
- throw new Error(`Invalid path: ${JSON.stringify(path8)}`);
125
+ var typiaPathToStandardSchemaPath = (path9) => {
126
+ if (!path9.startsWith("$input")) {
127
+ throw new Error(`Invalid path: ${JSON.stringify(path9)}`);
128
128
  }
129
129
  const segments = [];
130
130
  let currentSegment = "";
131
131
  let state = PathParserState.Start;
132
132
  let index = "$input".length - 1;
133
- while (index < path8.length - 1) {
133
+ while (index < path9.length - 1) {
134
134
  index++;
135
- const char = path8[index];
135
+ const char = path9[index];
136
136
  if (state === PathParserState.Property) {
137
137
  if (char === "." || char === "[") {
138
138
  segments.push({
139
139
  key: currentSegment
140
140
  });
141
141
  state = PathParserState.Start;
142
- } else if (index === path8.length - 1) {
142
+ } else if (index === path9.length - 1) {
143
143
  currentSegment += char;
144
144
  segments.push({
145
145
  key: currentSegment
@@ -157,9 +157,9 @@ var require_createStandardSchema = __commonJS({
157
157
  index += 2;
158
158
  state = PathParserState.Start;
159
159
  } else if (char === "\\") {
160
- currentSegment += path8[index];
160
+ currentSegment += path9[index];
161
161
  index++;
162
- currentSegment += path8[index];
162
+ currentSegment += path9[index];
163
163
  } else {
164
164
  currentSegment += char;
165
165
  }
@@ -174,11 +174,11 @@ var require_createStandardSchema = __commonJS({
174
174
  currentSegment += char;
175
175
  }
176
176
  }
177
- if (state === PathParserState.Start && index < path8.length - 1) {
178
- const newChar = path8[index];
177
+ if (state === PathParserState.Start && index < path9.length - 1) {
178
+ const newChar = path9[index];
179
179
  currentSegment = "";
180
180
  if (newChar === "[") {
181
- if (path8[index + 1] === '"') {
181
+ if (path9[index + 1] === '"') {
182
182
  state = PathParserState.StringKey;
183
183
  index++;
184
184
  currentSegment = '"';
@@ -193,7 +193,7 @@ var require_createStandardSchema = __commonJS({
193
193
  }
194
194
  }
195
195
  if (state !== PathParserState.Start) {
196
- throw new Error(`Failed to parse path: ${JSON.stringify(path8)}`);
196
+ throw new Error(`Failed to parse path: ${JSON.stringify(path9)}`);
197
197
  }
198
198
  return segments;
199
199
  };
@@ -206,7 +206,7 @@ var require_package = __commonJS({
206
206
  module.exports = {
207
207
  name: "@apps-in-toss/plugins",
208
208
  type: "module",
209
- version: "1.14.0",
209
+ version: "2.0.0",
210
210
  description: "The plugins for Apps In Toss",
211
211
  scripts: {
212
212
  test: "vitest --run",
@@ -243,15 +243,16 @@ var require_package = __commonJS({
243
243
  vitest: "^3.2.4"
244
244
  },
245
245
  dependencies: {
246
- "@apps-in-toss/ait-format": "^1.0.0",
247
- "@granite-js/plugin-core": "0.1.31",
248
- "@granite-js/plugin-micro-frontend": "0.1.31",
249
- "@granite-js/plugin-sentry": "0.1.31",
250
- "@granite-js/utils": "0.1.31",
246
+ "@apps-in-toss/ait-format": "1.0.0",
247
+ "@apps-in-toss/plugin-compat": "workspace:*",
248
+ "@granite-js/plugin-core": "catalog:granite-js",
249
+ "@granite-js/plugin-micro-frontend": "catalog:granite-js",
250
+ "@granite-js/plugin-sentry": "catalog:granite-js",
251
+ "@granite-js/utils": "catalog:granite-js",
251
252
  archiver: "^7.0.1",
252
253
  connect: "^3.7.0",
253
- esbuild: "0.25.5",
254
- execa: "9.3.0",
254
+ esbuild: "catalog:tooling",
255
+ execa: "catalog:tooling",
255
256
  picocolors: "^1.1.1",
256
257
  uuidv7: "^1.0.2"
257
258
  }
@@ -264,34 +265,38 @@ init_esm_shims();
264
265
 
265
266
  // src/appsInToss.ts
266
267
  init_esm_shims();
267
- import path7 from "path";
268
+ import path8 from "path";
269
+ import { reactNativeCompatibilityPlugin, reactNativeReverseCompatibilityPlugin } from "@apps-in-toss/plugin-compat";
268
270
  import { microFrontend } from "@granite-js/plugin-micro-frontend";
269
- import { getPackageRoot as getPackageRoot5 } from "@granite-js/utils";
271
+ import { getPackageRoot as getPackageRoot6 } from "@granite-js/utils";
270
272
 
271
273
  // src/constants.ts
272
274
  init_esm_shims();
273
- var REACT_NATIVE_VERSION = "0.72.6";
275
+ var REACT_NATIVE_VERSION = "0.84.0";
274
276
  var APP_MANIFEST_NAME = "app.json";
275
277
  var MICRO_FRONTEND_HOST_NAME = "apps-in-toss-host";
276
278
  var MICRO_FRONTEND_REMOTE_NAME = "apps-in-toss-service";
277
279
  var MICRO_FRONTEND_REMOTE_EXPOSE_PATH = "./ServiceEntry";
278
280
  var HOST_CONTEXT_IDENTIFIER = "__appsInTossHost";
279
281
  var SERVICE_CONTEXT_IDENTIFIER = "__appsInToss";
280
- var SHRED_PACKAGES = [
282
+ var getSharedPackages = ({ reactNativeVersion }) => [
281
283
  "@react-native-community/blur",
282
284
  "@react-navigation/native",
283
285
  "@react-navigation/native-stack",
286
+ "@sentry/react-native",
284
287
  "@shopify/flash-list",
285
- "lottie-react-native",
286
288
  "react-native-safe-area-context",
287
289
  "react-native-screens",
288
- "react-native-fast-image",
289
290
  "react-native-svg",
290
291
  "react-native-gesture-handler",
291
292
  "react-native",
292
293
  "react",
293
- "react-native-video",
294
- "react-native-webview"
294
+ "react-native-webview",
295
+ "@granite-js/image",
296
+ "@granite-js/lottie",
297
+ "@granite-js/video",
298
+ ...reactNativeVersion === "0.84" ? ["brick-module", "@react-navigation/elements"] : [],
299
+ ...reactNativeVersion === "0.72" ? ["react-native-fast-image", "lottie-react-native", "react-native-video"] : []
295
300
  ];
296
301
 
297
302
  // src/log.ts
@@ -319,7 +324,8 @@ async function appsInTossAppJson(options) {
319
324
  const appJsonPath = path.join(packageRoot, ".granite", APP_MANIFEST_NAME);
320
325
  const appJsonObject = {
321
326
  appName,
322
- permissions: options.permissions
327
+ permissions: options.permissions,
328
+ ...options.appType != null ? { appType: options.appType } : {}
323
329
  };
324
330
  await fs.promises.mkdir(path.dirname(appJsonPath), { recursive: true });
325
331
  try {
@@ -327,7 +333,8 @@ async function appsInTossAppJson(options) {
327
333
  const existingAppJsonObject = JSON.parse(existingAppJson);
328
334
  Object.assign(appJsonObject, existingAppJsonObject, {
329
335
  appName,
330
- permissions: appJsonObject.permissions
336
+ permissions: appJsonObject.permissions,
337
+ ...options.appType != null ? { appType: options.appType } : {}
331
338
  });
332
339
  } catch {
333
340
  }
@@ -417,8 +424,8 @@ async function resolvePackageVersions(rootDir, packageNames) {
417
424
  function createVirtualEntry(packageNames) {
418
425
  return packageNames.map((packageName) => `import '${packageName}';`).join("\n");
419
426
  }
420
- function extractPackagePath(path8, packageName) {
421
- const normalizedPath = normalizePath(path8);
427
+ function extractPackagePath(path9, packageName) {
428
+ const normalizedPath = normalizePath(path9);
422
429
  if (normalizedPath.endsWith("/package.json")) {
423
430
  return normalizedPath.replace(/\/package\.json$/, "");
424
431
  }
@@ -428,8 +435,8 @@ function extractPackagePath(path8, packageName) {
428
435
  }
429
436
  throw new Error(`Failed to extract path: ${packageName}`);
430
437
  }
431
- function normalizePath(path8) {
432
- return path8.replace(/\\/g, "/");
438
+ function normalizePath(path9) {
439
+ return path9.replace(/\\/g, "/");
433
440
  }
434
441
  async function getPackageVersion(packagePath) {
435
442
  const packageJson = JSON.parse(await fs2.readFile(path2.join(packagePath, "package.json"), "utf-8"));
@@ -457,13 +464,14 @@ function getUnityMetaDataEnv() {
457
464
 
458
465
  // src/utils/createArtifact.ts
459
466
  async function createArtifact(options) {
460
- const { bundleFiles, outfile, appJsonPath, reactNativeVersion, sdkVersion, isGame } = options;
467
+ const { bundleFiles, outfile, appJsonPath, reactNativeVersion, sdkVersion, isGame, isWeb } = options;
461
468
  const unityMetaData = getUnityMetaDataEnv();
462
469
  const appJsonContent = await fs3.readFile(appJsonPath, "utf-8");
463
470
  const appJson = JSON.parse(appJsonContent);
464
- const runtime = reactNativeVersion.replace(/\./g, "_");
465
471
  const namedBundleFiles = bundleFiles.map((bundle) => {
466
- const extension = path3.extname(bundle.path);
472
+ const originalName = path3.basename(bundle.path);
473
+ const extension = path3.extname(originalName);
474
+ const runtime = (bundle.runtimeVersion ?? reactNativeVersion).replace(new RegExp(/\./g), "_");
467
475
  return {
468
476
  path: bundle.path,
469
477
  name: `bundle.${bundle.platform}.${runtime}${extension === ".map" ? ".js.map" : extension}`
@@ -475,13 +483,13 @@ async function createArtifact(options) {
475
483
  createdBy: "@apps-in-toss/plugins"
476
484
  });
477
485
  writer.setMetadata({
478
- platform: PlatformType.REACT_NATIVE,
486
+ platform: isWeb ? PlatformType.WEB : PlatformType.REACT_NATIVE,
479
487
  runtimeVersion: reactNativeVersion,
480
488
  isGame,
481
489
  sdkVersion,
482
490
  bundleFiles: namedBundleFiles.map(({ name }) => name),
483
491
  packageJson: options.packageJson,
484
- extra: { unityMetaData }
492
+ extra: { unityMetaData, ...options.extra }
485
493
  });
486
494
  for (const permission of appJson.permissions ?? []) {
487
495
  writer.addPermission(permission.name, permission.access);
@@ -500,7 +508,7 @@ async function createArtifact(options) {
500
508
  }
501
509
 
502
510
  // src/plugins/artifact.ts
503
- function appsInTossCreateArtifact(deploymentId, buildOption) {
511
+ function appsInTossCreateArtifact(deploymentId, buildOption, reactNativeVersion = REACT_NATIVE_VERSION) {
504
512
  const packageRoot = getPackageRoot2();
505
513
  return {
506
514
  name: "apps-in-toss:create-artifact",
@@ -514,7 +522,7 @@ function appsInTossCreateArtifact(deploymentId, buildOption) {
514
522
  log("\uC571 \uBE4C\uB4DC \uC911...");
515
523
  const { dependencies, devDependencies } = await collectDependencyVersions(cwd);
516
524
  const artifactOutfile = await createArtifact({
517
- reactNativeVersion: REACT_NATIVE_VERSION,
525
+ reactNativeVersion,
518
526
  deploymentId,
519
527
  sdkVersion: buildOption.sdkVersion,
520
528
  isGame: buildOption.isGame,
@@ -530,7 +538,8 @@ function appsInTossCreateArtifact(deploymentId, buildOption) {
530
538
  }
531
539
  ]).flat(),
532
540
  outfile: path4.join(cwd, `${appName}.ait`),
533
- appJsonPath: path4.join(packageRoot, ".granite", APP_MANIFEST_NAME)
541
+ appJsonPath: path4.join(packageRoot, ".granite", APP_MANIFEST_NAME),
542
+ isWeb: buildOption.isWeb
534
543
  });
535
544
  if (!artifactOutfile) {
536
545
  throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
@@ -698,6 +707,52 @@ function bedrockCompat({ isHost }) {
698
707
  };
699
708
  }
700
709
 
710
+ // src/plugins/crypto.ts
711
+ init_esm_shims();
712
+ import fs5 from "fs";
713
+ import path6 from "path";
714
+ import { getLocalTempDirectoryPath as getLocalTempDirectoryPath2, getPackageRoot as getPackageRoot4 } from "@granite-js/utils";
715
+ var cryptoPolyfillContent = `
716
+ (function (global) {
717
+ if (!global.__decrypt &&
718
+ global.nativeModuleProxy &&
719
+ global.nativeModuleProxy.TossCoreCryptoModule &&
720
+ global.nativeModuleProxy.TossCoreCryptoModule.decrypt) {
721
+ global.__decrypt = global.nativeModuleProxy.TossCoreCryptoModule.decrypt;
722
+ }
723
+ })(
724
+ typeof globalThis !== 'undefined'
725
+ ? globalThis
726
+ : typeof global !== 'undefined'
727
+ ? global
728
+ : typeof window !== 'undefined'
729
+ ? window
730
+ : this
731
+ );
732
+ `;
733
+ function appsInTossCrypto({ isHost }) {
734
+ const metroPolyfillPath = path6.join(getLocalTempDirectoryPath2(getPackageRoot4()), "metro-crypto-polyfill.js");
735
+ fs5.writeFileSync(metroPolyfillPath, cryptoPolyfillContent);
736
+ return {
737
+ name: "apps-in-toss-crypto-plugin",
738
+ config: {
739
+ ...isHost ? {
740
+ esbuild: {
741
+ banner: {
742
+ js: cryptoPolyfillContent
743
+ }
744
+ }
745
+ } : {},
746
+ metro: {
747
+ serializer: {
748
+ // Metro 단일 번들 환경에서는 Host/Remote 구분 없이 항상 polyfill 필요
749
+ getPolyfills: () => [metroPolyfillPath]
750
+ }
751
+ }
752
+ }
753
+ };
754
+ }
755
+
701
756
  // src/plugins/devServer.ts
702
757
  init_esm_shims();
703
758
 
@@ -820,7 +875,7 @@ var __typia_transform__isFormatUuid = __toESM(require_isFormatUuid(), 1);
820
875
  var __typia_transform__validateReport = __toESM(require_validateReport(), 1);
821
876
  var __typia_transform__createStandardSchema = __toESM(require_createStandardSchema(), 1);
822
877
  var validateAppManifest = (() => {
823
- const _io0 = (input) => "string" === typeof input.appName && (Array.isArray(input.permissions) && input.permissions.every((elem) => "object" === typeof elem && null !== elem && _iu0(elem))) && ("object" === typeof input._metadata && null !== input._metadata && _io6(input._metadata));
878
+ const _io0 = (input) => "string" === typeof input.appName && (void 0 === input.appType || "general" === input.appType || "game" === input.appType) && (Array.isArray(input.permissions) && input.permissions.every((elem) => "object" === typeof elem && null !== elem && _iu0(elem))) && ("object" === typeof input._metadata && null !== input._metadata && _io6(input._metadata));
824
879
  const _io1 = (input) => "clipboard" === input.name && ("read" === input.access || "write" === input.access);
825
880
  const _io2 = (input) => "geolocation" === input.name && "access" === input.access;
826
881
  const _io3 = (input) => "contacts" === input.name && ("read" === input.access || "write" === input.access);
@@ -845,6 +900,10 @@ var validateAppManifest = (() => {
845
900
  path: _path + ".appName",
846
901
  expected: "string",
847
902
  value: input.appName
903
+ }), void 0 === input.appType || "general" === input.appType || "game" === input.appType || _report(_exceptionable, {
904
+ path: _path + ".appType",
905
+ expected: '("game" | "general" | undefined)',
906
+ value: input.appType
848
907
  }), (Array.isArray(input.permissions) || _report(_exceptionable, {
849
908
  path: _path + ".permissions",
850
909
  expected: "Array<Permission>",
@@ -987,7 +1046,7 @@ var validateAppManifest = (() => {
987
1046
  });
988
1047
  })();
989
1048
  var validateAppInTossPluginOptions = (() => {
990
- const _io0 = (input) => (void 0 === input.appType || "general" === input.appType || "game" === input.appType) && ("object" === typeof input.brand && null !== input.brand && _io1(input.brand)) && (Array.isArray(input.permissions) && input.permissions.every((elem) => "object" === typeof elem && null !== elem && _iu0(elem))) && (void 0 === input.navigationBar || "object" === typeof input.navigationBar && null !== input.navigationBar && false === Array.isArray(input.navigationBar) && _io7(input.navigationBar));
1049
+ const _io0 = (input) => (void 0 === input.target || "0.72.6" === input.target || "0.84.0" === input.target) && (void 0 === input.appType || "general" === input.appType || "game" === input.appType) && ("object" === typeof input.brand && null !== input.brand && _io1(input.brand)) && (Array.isArray(input.permissions) && input.permissions.every((elem) => "object" === typeof elem && null !== elem && _iu0(elem))) && (void 0 === input.navigationBar || "object" === typeof input.navigationBar && null !== input.navigationBar && false === Array.isArray(input.navigationBar) && _io7(input.navigationBar));
991
1050
  const _io1 = (input) => "string" === typeof input.displayName && "string" === typeof input.primaryColor && "string" === typeof input.icon;
992
1051
  const _io2 = (input) => "clipboard" === input.name && ("read" === input.access || "write" === input.access);
993
1052
  const _io3 = (input) => "geolocation" === input.name && "access" === input.access;
@@ -1021,7 +1080,11 @@ var validateAppInTossPluginOptions = (() => {
1021
1080
  else
1022
1081
  return false;
1023
1082
  })();
1024
- const _vo0 = (input, _path, _exceptionable = true) => [void 0 === input.appType || "general" === input.appType || "game" === input.appType || _report(_exceptionable, {
1083
+ const _vo0 = (input, _path, _exceptionable = true) => [void 0 === input.target || "0.72.6" === input.target || "0.84.0" === input.target || _report(_exceptionable, {
1084
+ path: _path + ".target",
1085
+ expected: '("0.72.6" | "0.84.0" | undefined)',
1086
+ value: input.target
1087
+ }), void 0 === input.appType || "general" === input.appType || "game" === input.appType || _report(_exceptionable, {
1025
1088
  path: _path + ".appType",
1026
1089
  expected: '("game" | "general" | undefined)',
1027
1090
  value: input.appType
@@ -1252,21 +1315,23 @@ var validateAppInTossPluginOptions = (() => {
1252
1315
  init_esm_shims();
1253
1316
  import { uuidv7 } from "uuidv7";
1254
1317
  function generateDeploymentId() {
1318
+ if (process.env.AIT_DEPLOYMENT_ID != null && process.env.AIT_DEPLOYMENT_ID.length > 0) {
1319
+ return process.env.AIT_DEPLOYMENT_ID;
1320
+ }
1255
1321
  return uuidv7();
1256
1322
  }
1257
1323
 
1258
- // src/utils/getSdkVersion.ts
1324
+ // src/utils/getReactNativeTarget.ts
1259
1325
  init_esm_shims();
1260
- function getSdkVersion() {
1261
- const packageJson = require_package();
1262
- return packageJson.version;
1326
+ function getReactNativeTarget(target) {
1327
+ return target ?? REACT_NATIVE_VERSION;
1263
1328
  }
1264
1329
 
1265
1330
  // src/utils/setupRuntimeSetupScript.ts
1266
1331
  init_esm_shims();
1267
- import fs5 from "node:fs";
1268
- import path6 from "node:path";
1269
- import { getPackageRoot as getPackageRoot4 } from "@granite-js/utils";
1332
+ import fs6 from "node:fs";
1333
+ import path7 from "node:path";
1334
+ import { getPackageRoot as getPackageRoot5 } from "@granite-js/utils";
1270
1335
  import { transformSync } from "esbuild";
1271
1336
  function setupRuntimeSetupScript(config) {
1272
1337
  const script = getRuntimeSetupScript(
@@ -1311,15 +1376,15 @@ function getRuntimeSetupScript(metadata, identifier) {
1311
1376
  }).code;
1312
1377
  }
1313
1378
  function writeRuntimeSetupScript(script) {
1314
- const packageRoot = getPackageRoot4();
1315
- const granitePath = path6.join(packageRoot, ".granite");
1379
+ const packageRoot = getPackageRoot5();
1380
+ const granitePath = path7.join(packageRoot, ".granite");
1316
1381
  try {
1317
- fs5.accessSync(granitePath);
1382
+ fs6.accessSync(granitePath);
1318
1383
  } catch {
1319
- fs5.mkdirSync(granitePath, { recursive: true });
1384
+ fs6.mkdirSync(granitePath, { recursive: true });
1320
1385
  }
1321
- const envFilePath = path6.join(granitePath, ".apps-in-toss.env.js");
1322
- fs5.writeFileSync(envFilePath, script, "utf-8");
1386
+ const envFilePath = path7.join(granitePath, ".apps-in-toss.env.js");
1387
+ fs6.writeFileSync(envFilePath, script, "utf-8");
1323
1388
  return envFilePath;
1324
1389
  }
1325
1390
  function getBedrockCompatScript() {
@@ -1383,6 +1448,10 @@ function getMicroFrontendCompatScript() {
1383
1448
  }
1384
1449
 
1385
1450
  // src/appsInToss.ts
1451
+ function getAppsInTossBuildPlugins(options) {
1452
+ const plugins = [appsInTossDevServer(options), appsInTossPostNotice()];
1453
+ return plugins;
1454
+ }
1386
1455
  function withAppsInTossCommon(plugins, options) {
1387
1456
  const { contents, path: envScriptPath } = setupRuntimeSetupScript({
1388
1457
  appType: options.appType,
@@ -1390,6 +1459,8 @@ function withAppsInTossCommon(plugins, options) {
1390
1459
  deploymentId: options.deploymentId,
1391
1460
  navigationBar: options.navigationBar
1392
1461
  });
1462
+ const target = getReactNativeTarget(options.target);
1463
+ const reactNativeVersion = target.startsWith("0.72") ? "0.72" : "0.84";
1393
1464
  return [
1394
1465
  requireMicroFrontendRuntime(),
1395
1466
  microFrontend({
@@ -1397,15 +1468,20 @@ function withAppsInTossCommon(plugins, options) {
1397
1468
  exposes: {
1398
1469
  [MICRO_FRONTEND_REMOTE_EXPOSE_PATH]: options.exposePath
1399
1470
  },
1400
- shared: SHRED_PACKAGES,
1471
+ shared: getSharedPackages({
1472
+ reactNativeVersion
1473
+ }),
1401
1474
  reactNativeBasePath: options.reactNativeBasePath
1402
1475
  }),
1403
1476
  appsInTossAppJson(options),
1477
+ reactNativeCompatibilityPlugin({ target, rootDir: options.root }),
1478
+ reactNativeReverseCompatibilityPlugin({ target, rootDir: options.root, isHost: false }),
1404
1479
  appsInTossEsbuildConfig(contents),
1405
1480
  appsInTossMetroConfig(envScriptPath),
1406
1481
  bedrockCompat({ isHost: false }),
1482
+ reactNativeVersion === "0.84" ? appsInTossCrypto({ isHost: false }) : null,
1407
1483
  ...plugins
1408
- ];
1484
+ ].filter((plugin) => plugin !== null);
1409
1485
  }
1410
1486
  function appsInToss(options) {
1411
1487
  const result = validateAppInTossPluginOptions(options);
@@ -1414,22 +1490,14 @@ function appsInToss(options) {
1414
1490
  process.exit(1);
1415
1491
  }
1416
1492
  const deploymentId = generateDeploymentId();
1417
- const root = getPackageRoot5();
1418
- const sdkVersion = getSdkVersion();
1419
- const buildOptions = {
1420
- sdkVersion,
1421
- isGame: result.data.appType === "game"
1422
- };
1423
- return withAppsInTossCommon(
1424
- [appsInTossDevServer(options), appsInTossCreateArtifact(deploymentId, buildOptions), appsInTossPostNotice()],
1425
- {
1426
- ...options,
1427
- root,
1428
- deploymentId,
1429
- exposePath: path7.join(root, "./src/_app.tsx"),
1430
- navigationBar: result.data.navigationBar
1431
- }
1432
- );
1493
+ const root = getPackageRoot6();
1494
+ return withAppsInTossCommon(getAppsInTossBuildPlugins(options), {
1495
+ ...options,
1496
+ root,
1497
+ deploymentId,
1498
+ exposePath: path8.join(root, "./src/_app.tsx"),
1499
+ navigationBar: result.data.navigationBar
1500
+ });
1433
1501
  }
1434
1502
 
1435
1503
  // src/analytics.ts
@@ -1492,11 +1560,19 @@ function analytics() {
1492
1560
  }
1493
1561
  };
1494
1562
  }
1563
+
1564
+ // src/utils/getSdkVersion.ts
1565
+ init_esm_shims();
1566
+ function getSdkVersion() {
1567
+ const packageJson = require_package();
1568
+ return packageJson.version;
1569
+ }
1495
1570
  export {
1496
1571
  analytics,
1497
1572
  appsInToss,
1498
1573
  appsInTossAppJson,
1499
1574
  appsInTossCreateArtifact,
1575
+ appsInTossCrypto,
1500
1576
  appsInTossDevServer,
1501
1577
  appsInTossEsbuildConfig,
1502
1578
  appsInTossMetroConfig,
@@ -1504,7 +1580,10 @@ export {
1504
1580
  bedrockCompat,
1505
1581
  collectDependencyVersions,
1506
1582
  createArtifact,
1583
+ cryptoPolyfillContent,
1584
+ getAppsInTossBuildPlugins,
1507
1585
  getRuntimeSetupScript,
1586
+ getSdkVersion,
1508
1587
  nativeModuleProxyContent,
1509
1588
  reactNativeModuleProxyContent,
1510
1589
  requireMicroFrontendRuntime,