@apps-in-toss/plugins 1.10.0 → 1.11.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.cjs CHANGED
@@ -64,11 +64,11 @@ var require_validateReport = __commonJS({
64
64
  Object.defineProperty(exports2, "__esModule", { value: true });
65
65
  exports2._validateReport = void 0;
66
66
  var _validateReport2 = (array) => {
67
- const reportable = (path10) => {
67
+ const reportable = (path8) => {
68
68
  if (array.length === 0)
69
69
  return true;
70
70
  const last = array[array.length - 1].path;
71
- return path10.length > last.length || last.substring(0, path10.length) !== path10;
71
+ return path8.length > last.length || last.substring(0, path8.length) !== path8;
72
72
  };
73
73
  return (exceptable, error2) => {
74
74
  var _a;
@@ -124,24 +124,24 @@ var require_createStandardSchema = __commonJS({
124
124
  PathParserState2[PathParserState2["StringKey"] = 2] = "StringKey";
125
125
  PathParserState2[PathParserState2["NumberKey"] = 3] = "NumberKey";
126
126
  })(PathParserState || (PathParserState = {}));
127
- var typiaPathToStandardSchemaPath = (path10) => {
128
- if (!path10.startsWith("$input")) {
129
- throw new Error(`Invalid path: ${JSON.stringify(path10)}`);
127
+ var typiaPathToStandardSchemaPath = (path8) => {
128
+ if (!path8.startsWith("$input")) {
129
+ throw new Error(`Invalid path: ${JSON.stringify(path8)}`);
130
130
  }
131
131
  const segments = [];
132
132
  let currentSegment = "";
133
133
  let state = PathParserState.Start;
134
134
  let index = "$input".length - 1;
135
- while (index < path10.length - 1) {
135
+ while (index < path8.length - 1) {
136
136
  index++;
137
- const char = path10[index];
137
+ const char = path8[index];
138
138
  if (state === PathParserState.Property) {
139
139
  if (char === "." || char === "[") {
140
140
  segments.push({
141
141
  key: currentSegment
142
142
  });
143
143
  state = PathParserState.Start;
144
- } else if (index === path10.length - 1) {
144
+ } else if (index === path8.length - 1) {
145
145
  currentSegment += char;
146
146
  segments.push({
147
147
  key: currentSegment
@@ -159,9 +159,9 @@ var require_createStandardSchema = __commonJS({
159
159
  index += 2;
160
160
  state = PathParserState.Start;
161
161
  } else if (char === "\\") {
162
- currentSegment += path10[index];
162
+ currentSegment += path8[index];
163
163
  index++;
164
- currentSegment += path10[index];
164
+ currentSegment += path8[index];
165
165
  } else {
166
166
  currentSegment += char;
167
167
  }
@@ -176,11 +176,11 @@ var require_createStandardSchema = __commonJS({
176
176
  currentSegment += char;
177
177
  }
178
178
  }
179
- if (state === PathParserState.Start && index < path10.length - 1) {
180
- const newChar = path10[index];
179
+ if (state === PathParserState.Start && index < path8.length - 1) {
180
+ const newChar = path8[index];
181
181
  currentSegment = "";
182
182
  if (newChar === "[") {
183
- if (path10[index + 1] === '"') {
183
+ if (path8[index + 1] === '"') {
184
184
  state = PathParserState.StringKey;
185
185
  index++;
186
186
  currentSegment = '"';
@@ -195,13 +195,72 @@ var require_createStandardSchema = __commonJS({
195
195
  }
196
196
  }
197
197
  if (state !== PathParserState.Start) {
198
- throw new Error(`Failed to parse path: ${JSON.stringify(path10)}`);
198
+ throw new Error(`Failed to parse path: ${JSON.stringify(path8)}`);
199
199
  }
200
200
  return segments;
201
201
  };
202
202
  }
203
203
  });
204
204
 
205
+ // package.json
206
+ var require_package = __commonJS({
207
+ "package.json"(exports2, module2) {
208
+ module2.exports = {
209
+ name: "@apps-in-toss/plugins",
210
+ type: "module",
211
+ version: "1.11.0",
212
+ description: "The plugins for Apps In Toss",
213
+ scripts: {
214
+ test: "vitest --run",
215
+ typecheck: "tsc --noEmit",
216
+ lint: "eslint .",
217
+ build: "tsup"
218
+ },
219
+ main: "./dist/index.cjs",
220
+ module: "./dist/index.js",
221
+ types: "./dist/index.d.ts",
222
+ exports: {
223
+ ".": {
224
+ types: "./dist/index.d.ts",
225
+ import: "./dist/index.js",
226
+ require: "./dist/index.cjs"
227
+ },
228
+ "./internal": {
229
+ types: "./dist/internal.d.ts",
230
+ import: "./dist/internal.js",
231
+ require: "./dist/internal.cjs"
232
+ },
233
+ "./package.json": "./package.json"
234
+ },
235
+ files: [
236
+ "dist/**/*"
237
+ ],
238
+ devDependencies: {
239
+ "@ryoppippi/unplugin-typia": "^2.6.5",
240
+ "@types/archiver": "^6.0.3",
241
+ "@types/connect": "^3",
242
+ tsup: "^8.4.0",
243
+ typescript: "5.8.3",
244
+ typia: "^9.3.0",
245
+ vitest: "^3.2.4"
246
+ },
247
+ dependencies: {
248
+ "@apps-in-toss/ait-format": "^1.0.0",
249
+ "@granite-js/plugin-core": "0.1.31",
250
+ "@granite-js/plugin-micro-frontend": "0.1.31",
251
+ "@granite-js/plugin-sentry": "0.1.31",
252
+ "@granite-js/utils": "0.1.31",
253
+ archiver: "^7.0.1",
254
+ connect: "^3.7.0",
255
+ esbuild: "0.25.5",
256
+ execa: "9.3.0",
257
+ picocolors: "^1.1.1",
258
+ uuidv7: "^1.0.2"
259
+ }
260
+ };
261
+ }
262
+ });
263
+
205
264
  // src/index.ts
206
265
  var index_exports = {};
207
266
  __export(index_exports, {
@@ -224,7 +283,6 @@ __export(index_exports, {
224
283
  setupRuntimeSetupScript: () => setupRuntimeSetupScript,
225
284
  validateAppInTossPluginOptions: () => validateAppInTossPluginOptions,
226
285
  validateAppManifest: () => validateAppManifest,
227
- validateZip: () => validateZip,
228
286
  withAppsInTossCommon: () => withAppsInTossCommon
229
287
  });
230
288
  module.exports = __toCommonJS(index_exports);
@@ -234,7 +292,7 @@ init_cjs_shims();
234
292
  init_cjs_shims();
235
293
  var import_path5 = __toESM(require("path"), 1);
236
294
  var import_plugin_micro_frontend = require("@granite-js/plugin-micro-frontend");
237
- var import_utils7 = require("@granite-js/utils");
295
+ var import_utils5 = require("@granite-js/utils");
238
296
 
239
297
  // src/constants.ts
240
298
  init_cjs_shims();
@@ -322,7 +380,7 @@ async function appsInTossAppJson(options) {
322
380
  init_cjs_shims();
323
381
  var import_path3 = __toESM(require("path"), 1);
324
382
  var import_plugin_core = require("@granite-js/plugin-core");
325
- var import_utils4 = require("@granite-js/utils");
383
+ var import_utils2 = require("@granite-js/utils");
326
384
  var import_picocolors2 = __toESM(require("picocolors"), 1);
327
385
 
328
386
  // src/utils/collectDependencyVersions.ts
@@ -385,8 +443,8 @@ async function resolvePackageVersions(rootDir, packageNames) {
385
443
  function createVirtualEntry(packageNames) {
386
444
  return packageNames.map((packageName) => `import '${packageName}';`).join("\n");
387
445
  }
388
- function extractPackagePath(path10, packageName) {
389
- const normalizedPath = normalizePath(path10);
446
+ function extractPackagePath(path8, packageName) {
447
+ const normalizedPath = normalizePath(path8);
390
448
  if (normalizedPath.endsWith("/package.json")) {
391
449
  return normalizedPath.replace(/\/package\.json$/, "");
392
450
  }
@@ -396,8 +454,8 @@ function extractPackagePath(path10, packageName) {
396
454
  }
397
455
  throw new Error(`Failed to extract path: ${packageName}`);
398
456
  }
399
- function normalizePath(path10) {
400
- return path10.replace(/\\/g, "/");
457
+ function normalizePath(path8) {
458
+ return path8.replace(/\\/g, "/");
401
459
  }
402
460
  async function getPackageVersion(packagePath) {
403
461
  const packageJson = JSON.parse(await fs2.readFile(path2.join(packagePath, "package.json"), "utf-8"));
@@ -406,91 +464,416 @@ async function getPackageVersion(packagePath) {
406
464
 
407
465
  // src/utils/createArtifact.ts
408
466
  init_cjs_shims();
467
+ var fs3 = __toESM(require("fs/promises"), 1);
409
468
  var import_path2 = __toESM(require("path"), 1);
410
- var import_utils3 = require("@granite-js/utils");
469
+ var import_ait_format = require("@apps-in-toss/ait-format");
411
470
 
412
- // src/utils/compressToZip.ts
471
+ // src/utils/getUnityMetaDataEnv.ts
413
472
  init_cjs_shims();
414
- var fs3 = __toESM(require("fs"), 1);
415
- var path3 = __toESM(require("path"), 1);
416
- var import_archiver = __toESM(require("archiver"), 1);
417
- async function compressToZip(config) {
418
- const { files, outfile } = config;
419
- return new Promise((resolve, reject) => {
420
- const outputStream = fs3.createWriteStream(outfile);
421
- const archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } });
422
- outputStream.on("close", () => resolve(outfile));
423
- outputStream.on("error", (error2) => reject(error2));
424
- archive.on("error", (error2) => reject(error2)).pipe(outputStream);
425
- files.forEach(({ path: filePath, name }) => {
426
- const fileName = name ?? path3.basename(filePath);
427
- archive.append(fs3.createReadStream(filePath), { name: fileName });
428
- });
429
- archive.finalize();
473
+ function getUnityMetaDataEnv() {
474
+ const metaData = process.env.UNITY_METADATA;
475
+ if (!metaData) return {};
476
+ try {
477
+ return JSON.parse(metaData);
478
+ } catch (e) {
479
+ console.warn("UNITY_METADATA is not a valid JSON:", e);
480
+ return {};
481
+ }
482
+ }
483
+
484
+ // src/utils/createArtifact.ts
485
+ async function createArtifact(options) {
486
+ const { bundleFiles, outfile, appJsonPath, reactNativeVersion, sdkVersion, isGame } = options;
487
+ const unityMetaData = getUnityMetaDataEnv();
488
+ const appJsonContent = await fs3.readFile(appJsonPath, "utf-8");
489
+ const appJson = JSON.parse(appJsonContent);
490
+ const runtime = reactNativeVersion.replace(/\./g, "_");
491
+ const namedBundleFiles = bundleFiles.map((bundle) => {
492
+ const extension = import_path2.default.extname(bundle.path);
493
+ return {
494
+ path: bundle.path,
495
+ name: `bundle.${bundle.platform}.${runtime}${extension === ".map" ? ".js.map" : extension}`
496
+ };
497
+ });
498
+ const writer = import_ait_format.AppsInTossBundle.writer({
499
+ deploymentId: options.deploymentId,
500
+ appName: appJson.appName,
501
+ createdBy: "@apps-in-toss/plugins"
502
+ });
503
+ writer.setMetadata({
504
+ platform: import_ait_format.PlatformType.REACT_NATIVE,
505
+ runtimeVersion: reactNativeVersion,
506
+ isGame,
507
+ sdkVersion,
508
+ bundleFiles: namedBundleFiles.map(({ name }) => name),
509
+ packageJson: options.packageJson,
510
+ extra: { unityMetaData }
430
511
  });
512
+ for (const permission of appJson.permissions ?? []) {
513
+ writer.addPermission(permission.name, permission.access);
514
+ }
515
+ for (const bundle of namedBundleFiles) {
516
+ const content = await fs3.readFile(bundle.path);
517
+ writer.addFile(bundle.name, new Uint8Array(content));
518
+ }
519
+ for (const file of options.additionalFilesToZip ?? []) {
520
+ const content = await fs3.readFile(file.path);
521
+ writer.addFile(file.name, new Uint8Array(content));
522
+ }
523
+ const buffer = await writer.toBuffer();
524
+ await fs3.writeFile(outfile, buffer);
525
+ return outfile;
431
526
  }
432
527
 
433
- // src/utils/updateAppJsonMetadata.ts
434
- init_cjs_shims();
435
- var fs4 = __toESM(require("fs/promises"), 1);
436
- var path4 = __toESM(require("path"), 1);
437
- var import_utils2 = require("@granite-js/utils");
438
- async function resolveAppManifestPath() {
439
- const cwd = (0, import_utils2.getPackageRoot)();
440
- const appManifestPath = path4.join(cwd, ".granite", APP_MANIFEST_NAME);
441
- await fs4.access(appManifestPath, fs4.constants.F_OK);
442
- return appManifestPath;
528
+ // src/plugins/artifact.ts
529
+ function appsInTossCreateArtifact(deploymentId, buildOption) {
530
+ const packageRoot = (0, import_utils2.getPackageRoot)();
531
+ return {
532
+ name: "apps-in-toss:create-artifact",
533
+ build: {
534
+ order: "post",
535
+ handler: async ({ buildResults, appName, cwd }) => {
536
+ const buildFailed = buildResults.some(import_plugin_core.isBuildFailure);
537
+ if (buildFailed) {
538
+ throw new Error("\uBC88\uB4E4 \uBE4C\uB4DC \uC2E4\uD328");
539
+ }
540
+ log("\uC571 \uBE4C\uB4DC \uC911...");
541
+ const { dependencies, devDependencies } = await collectDependencyVersions(cwd);
542
+ const artifactOutfile = await createArtifact({
543
+ reactNativeVersion: REACT_NATIVE_VERSION,
544
+ deploymentId,
545
+ sdkVersion: buildOption.sdkVersion,
546
+ isGame: buildOption.isGame,
547
+ packageJson: { dependencies, devDependencies },
548
+ bundleFiles: buildResults.filter(import_plugin_core.isBuildSuccess).map(({ outfile, sourcemapOutfile, platform }) => [
549
+ {
550
+ path: outfile,
551
+ platform
552
+ },
553
+ {
554
+ path: sourcemapOutfile,
555
+ platform
556
+ }
557
+ ]).flat(),
558
+ outfile: import_path3.default.join(cwd, `${appName}.ait`),
559
+ appJsonPath: import_path3.default.join(packageRoot, ".granite", APP_MANIFEST_NAME)
560
+ });
561
+ if (!artifactOutfile) {
562
+ throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
563
+ }
564
+ const filename = import_path3.default.basename(artifactOutfile);
565
+ log(`\u2705 ${import_picocolors2.default.green(`${filename}`)} \uBE4C\uB4DC \uC644\uB8CC`);
566
+ }
567
+ }
568
+ };
443
569
  }
444
- async function readAppJson(appJsonPath) {
445
- const appJson = await fs4.readFile(appJsonPath, "utf8");
446
- return JSON.parse(appJson);
570
+
571
+ // src/plugins/build.ts
572
+ init_cjs_shims();
573
+ function appsInTossEsbuildConfig(envScript) {
574
+ return {
575
+ name: "apps-in-toss:esbuild-config",
576
+ config: {
577
+ esbuild: {
578
+ banner: {
579
+ js: envScript
580
+ }
581
+ }
582
+ }
583
+ };
447
584
  }
448
- async function writeAppJson(appJsonPath, content) {
449
- await fs4.writeFile(appJsonPath, JSON.stringify(content));
585
+ function appsInTossMetroConfig(envScriptPath) {
586
+ return {
587
+ name: "apps-in-toss:metro-config",
588
+ config: {
589
+ metro: {
590
+ serializer: {
591
+ getPolyfills: () => [envScriptPath]
592
+ }
593
+ }
594
+ }
595
+ };
450
596
  }
451
- async function updateAppJsonMetadata(metadata) {
452
- const appJsonPath = await resolveAppManifestPath();
453
- const appJson = await readAppJson(appJsonPath);
454
- await writeAppJson(appJsonPath, {
455
- ...appJson,
456
- _metadata: metadata
597
+
598
+ // src/plugins/compat.ts
599
+ init_cjs_shims();
600
+ var import_fs = __toESM(require("fs"), 1);
601
+ var import_path4 = __toESM(require("path"), 1);
602
+ var import_utils3 = require("@granite-js/utils");
603
+ var nativeModuleProxyContent = `
604
+ (function () {
605
+ global.nativeModuleProxy = new Proxy(global.nativeModuleProxy, {
606
+ get: function (target, name) {
607
+ if (name === 'GraniteModule') {
608
+ return target['BedrockModule'] || target[name];
609
+ }
610
+
611
+ if (name === 'GraniteCoreModule') {
612
+ return target['BedrockCoreModule'] || target[name];
613
+ }
614
+
615
+ return target[name];
616
+ }
457
617
  });
618
+
619
+ global.__nativeModuleProxyConfigured = true;
620
+ })(
621
+ typeof globalThis !== 'undefined'
622
+ ? globalThis
623
+ : typeof global !== 'undefined'
624
+ ? global
625
+ : typeof window !== 'undefined'
626
+ ? window
627
+ : this
628
+ );
629
+ `;
630
+ var reactNativeModuleProxyContent = `
631
+ (function (global) {
632
+ if (global.__nativeModuleProxyConfigured) {
633
+ return;
634
+ }
635
+
636
+ function getCustomTurboModuleRegistry(registry) {
637
+ var remappedModules = {
638
+ 'GraniteModule': 'BedrockModule',
639
+ 'GraniteCoreModule': 'BedrockCoreModule',
640
+ };
641
+
642
+ return {
643
+ get: function (name) {
644
+ var mod;
645
+ var remappedName = remappedModules[name];
646
+
647
+ if (remappedName) {
648
+ mod = registry.get(remappedName);
649
+ }
650
+
651
+ return mod || registry.get(name);
652
+ },
653
+ getEnforcing: function (name) {
654
+ var mod;
655
+ var remappedName = remappedModules[name];
656
+
657
+ if (remappedName) {
658
+ mod = registry.get(remappedName);
659
+ }
660
+
661
+ return mod || registry.getEnforcing(name);
662
+ }
663
+ };
664
+ }
665
+
666
+ function createReactNativeProxy(reactNative) {
667
+ return new Proxy(reactNative, {
668
+ get: function (target, name) {
669
+ var origin = target[name];
670
+ return name === 'TurboModuleRegistry' ? getCustomTurboModuleRegistry(origin) : origin;
671
+ }
672
+ });
673
+ }
674
+
675
+ var reactNative;
676
+
677
+ if (typeof global.__MICRO_FRONTEND__ !== 'undefined') {
678
+ var mod = global.__MICRO_FRONTEND__.__SHARED__['react-native'];
679
+ reactNative = mod && mod.get();
680
+ }
681
+
682
+ if (reactNative == null && typeof __bedrock_require__ === 'function') {
683
+ reactNative = global.__bedrock_require__('react-native');
684
+ }
685
+
686
+ if (reactNative == null) {
687
+ throw new Error('cannot get react-native in the global registry');
688
+ }
689
+
690
+ global.__reactNativeProxy = createReactNativeProxy(reactNative);
691
+ global.__MICRO_FRONTEND__.__SHARED__['react-native'] = {
692
+ get: function () {
693
+ return global.__reactNativeProxy;
694
+ },
695
+ loaded: true,
696
+ };
697
+ })(
698
+ typeof globalThis !== 'undefined'
699
+ ? globalThis
700
+ : typeof global !== 'undefined'
701
+ ? global
702
+ : typeof window !== 'undefined'
703
+ ? window
704
+ : this
705
+ );
706
+ `;
707
+ function bedrockCompat({ isHost }) {
708
+ const metroPolyfillContent = import_path4.default.join((0, import_utils3.getLocalTempDirectoryPath)((0, import_utils3.getPackageRoot)()), "metro-native-module-proxy.js");
709
+ import_fs.default.writeFileSync(metroPolyfillContent, nativeModuleProxyContent);
710
+ return {
711
+ name: "bedrock-compat-plugin",
712
+ config: {
713
+ esbuild: {
714
+ banner: {
715
+ js: isHost ? nativeModuleProxyContent : reactNativeModuleProxyContent
716
+ }
717
+ },
718
+ metro: {
719
+ serializer: {
720
+ getPolyfills: () => [metroPolyfillContent]
721
+ }
722
+ }
723
+ }
724
+ };
458
725
  }
459
726
 
460
- // src/types.ts
727
+ // src/plugins/devServer.ts
461
728
  init_cjs_shims();
462
- var __typia_transform__isFormatUuid = __toESM(require_isFormatUuid(), 1);
463
- var __typia_transform__validateReport = __toESM(require_validateReport(), 1);
464
- var __typia_transform__createStandardSchema = __toESM(require_createStandardSchema(), 1);
465
- var validateAppManifest = (() => {
466
- 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));
467
- const _io1 = (input) => "clipboard" === input.name && ("read" === input.access || "write" === input.access);
468
- const _io2 = (input) => "geolocation" === input.name && "access" === input.access;
469
- const _io3 = (input) => "contacts" === input.name && ("read" === input.access || "write" === input.access);
470
- const _io4 = (input) => "photos" === input.name && ("read" === input.access || "write" === input.access);
471
- const _io5 = (input) => "camera" === input.name && "access" === input.access;
472
- const _io6 = (input) => Array.isArray(input.bundleFiles) && input.bundleFiles.every((elem) => "string" === typeof elem) && ("string" === typeof input.deploymentId && __typia_transform__isFormatUuid._isFormatUuid(input.deploymentId));
473
- const _iu0 = (input) => (() => {
474
- if ("camera" === input.name)
475
- return _io5(input);
476
- else if ("photos" === input.name)
477
- return _io4(input);
478
- else if ("contacts" === input.name)
479
- return _io3(input);
480
- else if ("geolocation" === input.name)
481
- return _io2(input);
482
- else if ("clipboard" === input.name)
483
- return _io1(input);
484
- else
485
- return false;
486
- })();
487
- const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.appName || _report(_exceptionable, {
488
- path: _path + ".appName",
489
- expected: "string",
490
- value: input.appName
491
- }), (Array.isArray(input.permissions) || _report(_exceptionable, {
492
- path: _path + ".permissions",
493
- expected: "Array<Permission>",
729
+
730
+ // src/utils/createServerPermissionsMiddleware.ts
731
+ init_cjs_shims();
732
+ function createServerPermissionsMiddleware(permissions) {
733
+ const parsedPermissions = parsePermissions(permissions);
734
+ return (req, res, next) => {
735
+ if (req.method === "GET" && req.url === "/permissions") {
736
+ res.writeHead(200, {
737
+ "Content-Length": Buffer.byteLength(parsedPermissions),
738
+ "Content-Type": "text/plain"
739
+ }).end(parsedPermissions);
740
+ return;
741
+ }
742
+ next();
743
+ };
744
+ }
745
+ function parsePermissions(permissions) {
746
+ const permissionMap = /* @__PURE__ */ new Map();
747
+ for (const permission of permissions) {
748
+ const { name, access } = permission;
749
+ if (!permissionMap.has(name)) {
750
+ permissionMap.set(name, /* @__PURE__ */ new Set());
751
+ }
752
+ let accessValue = null;
753
+ switch (access) {
754
+ case "read":
755
+ accessValue = "r";
756
+ break;
757
+ case "write":
758
+ accessValue = "w";
759
+ break;
760
+ case "access":
761
+ accessValue = "a";
762
+ break;
763
+ default:
764
+ accessValue = null;
765
+ }
766
+ if (!accessValue) {
767
+ continue;
768
+ }
769
+ permissionMap.get(name).add(accessValue);
770
+ }
771
+ return Array.from(permissionMap.entries()).map(([name, accesses]) => `${name}:${Array.from(accesses).sort().join("")}`).sort().join(",");
772
+ }
773
+
774
+ // src/plugins/devServer.ts
775
+ function appsInTossDevServer(options) {
776
+ return {
777
+ name: "apps-in-toss:dev-server",
778
+ config: {
779
+ metro: {
780
+ middlewares: [createServerPermissionsMiddleware(options.permissions)]
781
+ }
782
+ }
783
+ };
784
+ }
785
+
786
+ // src/plugins/notice.ts
787
+ init_cjs_shims();
788
+ function appsInTossPostNotice() {
789
+ const phase = "post";
790
+ return {
791
+ name: "apps-in-toss:post-notice",
792
+ dev: {
793
+ order: phase,
794
+ handler() {
795
+ }
796
+ },
797
+ build: {
798
+ order: phase,
799
+ async handler({ appName }) {
800
+ if (this.meta.sentry) {
801
+ const command = [
802
+ "ait sentry upload-sourcemap",
803
+ `--app-name ${appName}`,
804
+ "--api-key <API_KEY>",
805
+ "--deployment-id <DEPLOYMENT_ID>"
806
+ ].join(" \\\n");
807
+ log(
808
+ `Sentry \uAD6C\uC131\uC774 \uAC10\uC9C0\uB410\uC5B4\uC694. \uC815\uD655\uD55C \uC624\uB958 \uCD94\uC801\uC744 \uC704\uD574\uC11C\uB294 \uBC30\uD3EC\uAC00 \uB05D\uB09C \uB4A4 \uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uC18C\uC2A4\uB9F5\uC744 \uC5C5\uB85C\uB4DC\uD574 \uC8FC\uC138\uC694.
809
+
810
+ ${command}
811
+ `
812
+ );
813
+ }
814
+ }
815
+ }
816
+ };
817
+ }
818
+
819
+ // src/plugins/resolve.ts
820
+ init_cjs_shims();
821
+ var import_module = __toESM(require("module"), 1);
822
+ function getRequire() {
823
+ return typeof require === "function" ? require : import_module.default.createRequire(importMetaUrl);
824
+ }
825
+ function requireMicroFrontendRuntime() {
826
+ const require2 = getRequire();
827
+ const runtimePath = require2.resolve("@granite-js/plugin-micro-frontend/runtime");
828
+ return {
829
+ name: "apps-in-toss-micro-frontend",
830
+ config: {
831
+ resolver: {
832
+ alias: [
833
+ {
834
+ from: "@granite-js/plugin-micro-frontend/runtime",
835
+ to: runtimePath
836
+ }
837
+ ]
838
+ }
839
+ }
840
+ };
841
+ }
842
+
843
+ // src/types.ts
844
+ init_cjs_shims();
845
+ var __typia_transform__isFormatUuid = __toESM(require_isFormatUuid(), 1);
846
+ var __typia_transform__validateReport = __toESM(require_validateReport(), 1);
847
+ var __typia_transform__createStandardSchema = __toESM(require_createStandardSchema(), 1);
848
+ var validateAppManifest = (() => {
849
+ 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));
850
+ const _io1 = (input) => "clipboard" === input.name && ("read" === input.access || "write" === input.access);
851
+ const _io2 = (input) => "geolocation" === input.name && "access" === input.access;
852
+ const _io3 = (input) => "contacts" === input.name && ("read" === input.access || "write" === input.access);
853
+ const _io4 = (input) => "photos" === input.name && ("read" === input.access || "write" === input.access);
854
+ const _io5 = (input) => "camera" === input.name && "access" === input.access;
855
+ const _io6 = (input) => Array.isArray(input.bundleFiles) && input.bundleFiles.every((elem) => "string" === typeof elem) && ("string" === typeof input.deploymentId && __typia_transform__isFormatUuid._isFormatUuid(input.deploymentId));
856
+ const _iu0 = (input) => (() => {
857
+ if ("camera" === input.name)
858
+ return _io5(input);
859
+ else if ("photos" === input.name)
860
+ return _io4(input);
861
+ else if ("contacts" === input.name)
862
+ return _io3(input);
863
+ else if ("geolocation" === input.name)
864
+ return _io2(input);
865
+ else if ("clipboard" === input.name)
866
+ return _io1(input);
867
+ else
868
+ return false;
869
+ })();
870
+ const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.appName || _report(_exceptionable, {
871
+ path: _path + ".appName",
872
+ expected: "string",
873
+ value: input.appName
874
+ }), (Array.isArray(input.permissions) || _report(_exceptionable, {
875
+ path: _path + ".permissions",
876
+ expected: "Array<Permission>",
494
877
  value: input.permissions
495
878
  })) && input.permissions.map((elem, _index3) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
496
879
  path: _path + ".permissions[" + _index3 + "]",
@@ -891,354 +1274,6 @@ var validateAppInTossPluginOptions = (() => {
891
1274
  });
892
1275
  })();
893
1276
 
894
- // src/utils/createArtifact.ts
895
- async function validateZip(zipPath) {
896
- const appJsonString = await (0, import_utils3.readZipContent)(zipPath, "app.json");
897
- const appJson = JSON.parse(appJsonString);
898
- const validated = validateAppManifest(appJson);
899
- if (!validated.success) {
900
- throw new Error("granite.config.ts \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
901
- }
902
- }
903
- async function createArtifact(options) {
904
- const { bundleFiles, outfile, appJsonPath, reactNativeVersion } = options;
905
- const namedBundleFiles = bundleFiles.map((bundle) => {
906
- const originalName = import_path2.default.basename(bundle.path);
907
- const extension = import_path2.default.extname(originalName);
908
- const runtime = reactNativeVersion.replace(new RegExp(/\./g), "_");
909
- return {
910
- path: bundle.path,
911
- // TODO: Use shared utils for sync file name specification with Lambda
912
- name: `bundle.${bundle.platform}.${runtime}${extension === ".map" ? `.js.map` : extension}`
913
- };
914
- });
915
- await updateAppJsonMetadata({
916
- runtimeVersion: reactNativeVersion,
917
- bundleFiles: namedBundleFiles.map(({ name }) => name),
918
- deploymentId: options.deploymentId,
919
- packageJson: options.packageJson
920
- });
921
- await compressToZip({
922
- files: [{ path: appJsonPath, name: "app.json" }, ...namedBundleFiles, ...options.additionalFilesToZip ?? []],
923
- outfile
924
- });
925
- await validateZip(outfile);
926
- return outfile;
927
- }
928
-
929
- // src/plugins/artifact.ts
930
- function appsInTossCreateArtifact(deploymentId) {
931
- const packageRoot = (0, import_utils4.getPackageRoot)();
932
- return {
933
- name: "apps-in-toss:create-artifact",
934
- build: {
935
- order: "post",
936
- handler: async ({ buildResults, appName, cwd }) => {
937
- const buildFailed = buildResults.some(import_plugin_core.isBuildFailure);
938
- if (buildFailed) {
939
- throw new Error("\uBC88\uB4E4 \uBE4C\uB4DC \uC2E4\uD328");
940
- }
941
- log("\uC571 \uBE4C\uB4DC \uC911...");
942
- const { dependencies, devDependencies } = await collectDependencyVersions(cwd);
943
- const artifactOutfile = await createArtifact({
944
- reactNativeVersion: REACT_NATIVE_VERSION,
945
- deploymentId,
946
- packageJson: { dependencies, devDependencies },
947
- bundleFiles: buildResults.filter(import_plugin_core.isBuildSuccess).map(({ outfile, sourcemapOutfile, platform }) => [
948
- {
949
- path: outfile,
950
- platform
951
- },
952
- {
953
- path: sourcemapOutfile,
954
- platform
955
- }
956
- ]).flat(),
957
- outfile: import_path3.default.join(cwd, `${appName}.ait`),
958
- appJsonPath: import_path3.default.join(packageRoot, ".granite", APP_MANIFEST_NAME)
959
- });
960
- if (!artifactOutfile) {
961
- throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
962
- }
963
- const filename = import_path3.default.basename(artifactOutfile);
964
- log(`\u2705 ${import_picocolors2.default.green(`${filename}`)} \uBE4C\uB4DC \uC644\uB8CC`);
965
- }
966
- }
967
- };
968
- }
969
-
970
- // src/plugins/build.ts
971
- init_cjs_shims();
972
- function appsInTossEsbuildConfig(envScript) {
973
- return {
974
- name: "apps-in-toss:esbuild-config",
975
- config: {
976
- esbuild: {
977
- banner: {
978
- js: envScript
979
- }
980
- }
981
- }
982
- };
983
- }
984
- function appsInTossMetroConfig(envScriptPath) {
985
- return {
986
- name: "apps-in-toss:metro-config",
987
- config: {
988
- metro: {
989
- serializer: {
990
- getPolyfills: () => [envScriptPath]
991
- }
992
- }
993
- }
994
- };
995
- }
996
-
997
- // src/plugins/compat.ts
998
- init_cjs_shims();
999
- var import_fs = __toESM(require("fs"), 1);
1000
- var import_path4 = __toESM(require("path"), 1);
1001
- var import_utils5 = require("@granite-js/utils");
1002
- var nativeModuleProxyContent = `
1003
- (function () {
1004
- global.nativeModuleProxy = new Proxy(global.nativeModuleProxy, {
1005
- get: function (target, name) {
1006
- if (name === 'GraniteModule') {
1007
- return target['BedrockModule'] || target[name];
1008
- }
1009
-
1010
- if (name === 'GraniteCoreModule') {
1011
- return target['BedrockCoreModule'] || target[name];
1012
- }
1013
-
1014
- return target[name];
1015
- }
1016
- });
1017
-
1018
- global.__nativeModuleProxyConfigured = true;
1019
- })(
1020
- typeof globalThis !== 'undefined'
1021
- ? globalThis
1022
- : typeof global !== 'undefined'
1023
- ? global
1024
- : typeof window !== 'undefined'
1025
- ? window
1026
- : this
1027
- );
1028
- `;
1029
- var reactNativeModuleProxyContent = `
1030
- (function (global) {
1031
- if (global.__nativeModuleProxyConfigured) {
1032
- return;
1033
- }
1034
-
1035
- function getCustomTurboModuleRegistry(registry) {
1036
- var remappedModules = {
1037
- 'GraniteModule': 'BedrockModule',
1038
- 'GraniteCoreModule': 'BedrockCoreModule',
1039
- };
1040
-
1041
- return {
1042
- get: function (name) {
1043
- var mod;
1044
- var remappedName = remappedModules[name];
1045
-
1046
- if (remappedName) {
1047
- mod = registry.get(remappedName);
1048
- }
1049
-
1050
- return mod || registry.get(name);
1051
- },
1052
- getEnforcing: function (name) {
1053
- var mod;
1054
- var remappedName = remappedModules[name];
1055
-
1056
- if (remappedName) {
1057
- mod = registry.get(remappedName);
1058
- }
1059
-
1060
- return mod || registry.getEnforcing(name);
1061
- }
1062
- };
1063
- }
1064
-
1065
- function createReactNativeProxy(reactNative) {
1066
- return new Proxy(reactNative, {
1067
- get: function (target, name) {
1068
- var origin = target[name];
1069
- return name === 'TurboModuleRegistry' ? getCustomTurboModuleRegistry(origin) : origin;
1070
- }
1071
- });
1072
- }
1073
-
1074
- var reactNative;
1075
-
1076
- if (typeof global.__MICRO_FRONTEND__ !== 'undefined') {
1077
- var mod = global.__MICRO_FRONTEND__.__SHARED__['react-native'];
1078
- reactNative = mod && mod.get();
1079
- }
1080
-
1081
- if (reactNative == null && typeof __bedrock_require__ === 'function') {
1082
- reactNative = global.__bedrock_require__('react-native');
1083
- }
1084
-
1085
- if (reactNative == null) {
1086
- throw new Error('cannot get react-native in the global registry');
1087
- }
1088
-
1089
- global.__reactNativeProxy = createReactNativeProxy(reactNative);
1090
- global.__MICRO_FRONTEND__.__SHARED__['react-native'] = {
1091
- get: function () {
1092
- return global.__reactNativeProxy;
1093
- },
1094
- loaded: true,
1095
- };
1096
- })(
1097
- typeof globalThis !== 'undefined'
1098
- ? globalThis
1099
- : typeof global !== 'undefined'
1100
- ? global
1101
- : typeof window !== 'undefined'
1102
- ? window
1103
- : this
1104
- );
1105
- `;
1106
- function bedrockCompat({ isHost }) {
1107
- const metroPolyfillContent = import_path4.default.join((0, import_utils5.getLocalTempDirectoryPath)((0, import_utils5.getPackageRoot)()), "metro-native-module-proxy.js");
1108
- import_fs.default.writeFileSync(metroPolyfillContent, nativeModuleProxyContent);
1109
- return {
1110
- name: "bedrock-compat-plugin",
1111
- config: {
1112
- esbuild: {
1113
- banner: {
1114
- js: isHost ? nativeModuleProxyContent : reactNativeModuleProxyContent
1115
- }
1116
- },
1117
- metro: {
1118
- serializer: {
1119
- getPolyfills: () => [metroPolyfillContent]
1120
- }
1121
- }
1122
- }
1123
- };
1124
- }
1125
-
1126
- // src/plugins/devServer.ts
1127
- init_cjs_shims();
1128
-
1129
- // src/utils/createServerPermissionsMiddleware.ts
1130
- init_cjs_shims();
1131
- function createServerPermissionsMiddleware(permissions) {
1132
- const parsedPermissions = parsePermissions(permissions);
1133
- return (req, res, next) => {
1134
- if (req.method === "GET" && req.url === "/permissions") {
1135
- res.writeHead(200, {
1136
- "Content-Length": Buffer.byteLength(parsedPermissions),
1137
- "Content-Type": "text/plain"
1138
- }).end(parsedPermissions);
1139
- return;
1140
- }
1141
- next();
1142
- };
1143
- }
1144
- function parsePermissions(permissions) {
1145
- const permissionMap = /* @__PURE__ */ new Map();
1146
- for (const permission of permissions) {
1147
- const { name, access: access2 } = permission;
1148
- if (!permissionMap.has(name)) {
1149
- permissionMap.set(name, /* @__PURE__ */ new Set());
1150
- }
1151
- let accessValue = null;
1152
- switch (access2) {
1153
- case "read":
1154
- accessValue = "r";
1155
- break;
1156
- case "write":
1157
- accessValue = "w";
1158
- break;
1159
- case "access":
1160
- accessValue = "a";
1161
- break;
1162
- default:
1163
- accessValue = null;
1164
- }
1165
- if (!accessValue) {
1166
- continue;
1167
- }
1168
- permissionMap.get(name).add(accessValue);
1169
- }
1170
- return Array.from(permissionMap.entries()).map(([name, accesses]) => `${name}:${Array.from(accesses).sort().join("")}`).sort().join(",");
1171
- }
1172
-
1173
- // src/plugins/devServer.ts
1174
- function appsInTossDevServer(options) {
1175
- return {
1176
- name: "apps-in-toss:dev-server",
1177
- config: {
1178
- metro: {
1179
- middlewares: [createServerPermissionsMiddleware(options.permissions)]
1180
- }
1181
- }
1182
- };
1183
- }
1184
-
1185
- // src/plugins/notice.ts
1186
- init_cjs_shims();
1187
- function appsInTossPostNotice() {
1188
- const phase = "post";
1189
- return {
1190
- name: "apps-in-toss:post-notice",
1191
- dev: {
1192
- order: phase,
1193
- handler() {
1194
- }
1195
- },
1196
- build: {
1197
- order: phase,
1198
- async handler({ appName }) {
1199
- if (this.meta.sentry) {
1200
- const command = [
1201
- "ait sentry upload-sourcemap",
1202
- `--app-name ${appName}`,
1203
- "--api-key <API_KEY>",
1204
- "--deployment-id <DEPLOYMENT_ID>"
1205
- ].join(" \\\n");
1206
- log(
1207
- `Sentry \uAD6C\uC131\uC774 \uAC10\uC9C0\uB410\uC5B4\uC694. \uC815\uD655\uD55C \uC624\uB958 \uCD94\uC801\uC744 \uC704\uD574\uC11C\uB294 \uBC30\uD3EC\uAC00 \uB05D\uB09C \uB4A4 \uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uC18C\uC2A4\uB9F5\uC744 \uC5C5\uB85C\uB4DC\uD574 \uC8FC\uC138\uC694.
1208
-
1209
- ${command}
1210
- `
1211
- );
1212
- }
1213
- }
1214
- }
1215
- };
1216
- }
1217
-
1218
- // src/plugins/resolve.ts
1219
- init_cjs_shims();
1220
- var import_module = __toESM(require("module"), 1);
1221
- function getRequire() {
1222
- return typeof require === "function" ? require : import_module.default.createRequire(importMetaUrl);
1223
- }
1224
- function requireMicroFrontendRuntime() {
1225
- const require2 = getRequire();
1226
- const runtimePath = require2.resolve("@granite-js/plugin-micro-frontend/runtime");
1227
- return {
1228
- name: "apps-in-toss-micro-frontend",
1229
- config: {
1230
- resolver: {
1231
- alias: [
1232
- {
1233
- from: "@granite-js/plugin-micro-frontend/runtime",
1234
- to: runtimePath
1235
- }
1236
- ]
1237
- }
1238
- }
1239
- };
1240
- }
1241
-
1242
1277
  // src/utils/generateDeploymentId.ts
1243
1278
  init_cjs_shims();
1244
1279
  var import_uuidv7 = require("uuidv7");
@@ -1246,11 +1281,18 @@ function generateDeploymentId() {
1246
1281
  return (0, import_uuidv7.uuidv7)();
1247
1282
  }
1248
1283
 
1284
+ // src/utils/getSdkVersion.ts
1285
+ init_cjs_shims();
1286
+ function getSdkVersion() {
1287
+ const packageJson = require_package();
1288
+ return packageJson.version;
1289
+ }
1290
+
1249
1291
  // src/utils/setupRuntimeSetupScript.ts
1250
1292
  init_cjs_shims();
1251
1293
  var import_node_fs2 = __toESM(require("fs"), 1);
1252
1294
  var import_node_path = __toESM(require("path"), 1);
1253
- var import_utils6 = require("@granite-js/utils");
1295
+ var import_utils4 = require("@granite-js/utils");
1254
1296
  var import_esbuild = require("esbuild");
1255
1297
  function setupRuntimeSetupScript(config) {
1256
1298
  const script = getRuntimeSetupScript(
@@ -1295,7 +1337,7 @@ function getRuntimeSetupScript(metadata, identifier) {
1295
1337
  }).code;
1296
1338
  }
1297
1339
  function writeRuntimeSetupScript(script) {
1298
- const packageRoot = (0, import_utils6.getPackageRoot)();
1340
+ const packageRoot = (0, import_utils4.getPackageRoot)();
1299
1341
  const granitePath = import_node_path.default.join(packageRoot, ".granite");
1300
1342
  try {
1301
1343
  import_node_fs2.default.accessSync(granitePath);
@@ -1398,9 +1440,14 @@ function appsInToss(options) {
1398
1440
  process.exit(1);
1399
1441
  }
1400
1442
  const deploymentId = generateDeploymentId();
1401
- const root = (0, import_utils7.getPackageRoot)();
1443
+ const root = (0, import_utils5.getPackageRoot)();
1444
+ const sdkVersion = getSdkVersion();
1445
+ const buildOptions = {
1446
+ sdkVersion,
1447
+ isGame: result.data.appType === "game"
1448
+ };
1402
1449
  return withAppsInTossCommon(
1403
- [appsInTossDevServer(options), appsInTossCreateArtifact(deploymentId), appsInTossPostNotice()],
1450
+ [appsInTossDevServer(options), appsInTossCreateArtifact(deploymentId, buildOptions), appsInTossPostNotice()],
1404
1451
  {
1405
1452
  ...options,
1406
1453
  root,
@@ -1492,6 +1539,5 @@ function analytics() {
1492
1539
  setupRuntimeSetupScript,
1493
1540
  validateAppInTossPluginOptions,
1494
1541
  validateAppManifest,
1495
- validateZip,
1496
1542
  withAppsInTossCommon
1497
1543
  });