@apps-in-toss/plugins 1.9.4 → 1.10.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
@@ -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 = (path10) => {
65
+ const reportable = (path8) => {
66
66
  if (array.length === 0)
67
67
  return true;
68
68
  const last = array[array.length - 1].path;
69
- return path10.length > last.length || last.substring(0, path10.length) !== path10;
69
+ return path8.length > last.length || last.substring(0, path8.length) !== path8;
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 = (path10) => {
126
- if (!path10.startsWith("$input")) {
127
- throw new Error(`Invalid path: ${JSON.stringify(path10)}`);
125
+ var typiaPathToStandardSchemaPath = (path8) => {
126
+ if (!path8.startsWith("$input")) {
127
+ throw new Error(`Invalid path: ${JSON.stringify(path8)}`);
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 < path10.length - 1) {
133
+ while (index < path8.length - 1) {
134
134
  index++;
135
- const char = path10[index];
135
+ const char = path8[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 === path10.length - 1) {
142
+ } else if (index === path8.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 += path10[index];
160
+ currentSegment += path8[index];
161
161
  index++;
162
- currentSegment += path10[index];
162
+ currentSegment += path8[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 < path10.length - 1) {
178
- const newChar = path10[index];
177
+ if (state === PathParserState.Start && index < path8.length - 1) {
178
+ const newChar = path8[index];
179
179
  currentSegment = "";
180
180
  if (newChar === "[") {
181
- if (path10[index + 1] === '"') {
181
+ if (path8[index + 1] === '"') {
182
182
  state = PathParserState.StringKey;
183
183
  index++;
184
184
  currentSegment = '"';
@@ -193,21 +193,80 @@ var require_createStandardSchema = __commonJS({
193
193
  }
194
194
  }
195
195
  if (state !== PathParserState.Start) {
196
- throw new Error(`Failed to parse path: ${JSON.stringify(path10)}`);
196
+ throw new Error(`Failed to parse path: ${JSON.stringify(path8)}`);
197
197
  }
198
198
  return segments;
199
199
  };
200
200
  }
201
201
  });
202
202
 
203
+ // package.json
204
+ var require_package = __commonJS({
205
+ "package.json"(exports, module) {
206
+ module.exports = {
207
+ name: "@apps-in-toss/plugins",
208
+ type: "module",
209
+ version: "1.10.1",
210
+ description: "The plugins for Apps In Toss",
211
+ scripts: {
212
+ test: "vitest --run",
213
+ typecheck: "tsc --noEmit",
214
+ lint: "eslint .",
215
+ build: "tsup"
216
+ },
217
+ main: "./dist/index.cjs",
218
+ module: "./dist/index.js",
219
+ types: "./dist/index.d.ts",
220
+ exports: {
221
+ ".": {
222
+ types: "./dist/index.d.ts",
223
+ import: "./dist/index.js",
224
+ require: "./dist/index.cjs"
225
+ },
226
+ "./internal": {
227
+ types: "./dist/internal.d.ts",
228
+ import: "./dist/internal.js",
229
+ require: "./dist/internal.cjs"
230
+ },
231
+ "./package.json": "./package.json"
232
+ },
233
+ files: [
234
+ "dist/**/*"
235
+ ],
236
+ devDependencies: {
237
+ "@ryoppippi/unplugin-typia": "^2.6.5",
238
+ "@types/archiver": "^6.0.3",
239
+ "@types/connect": "^3",
240
+ tsup: "^8.4.0",
241
+ typescript: "5.8.3",
242
+ typia: "^9.3.0",
243
+ vitest: "^3.2.4"
244
+ },
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",
251
+ archiver: "^7.0.1",
252
+ connect: "^3.7.0",
253
+ esbuild: "0.25.5",
254
+ execa: "9.3.0",
255
+ picocolors: "^1.1.1",
256
+ uuidv7: "^1.0.2"
257
+ }
258
+ };
259
+ }
260
+ });
261
+
203
262
  // src/index.ts
204
263
  init_esm_shims();
205
264
 
206
265
  // src/appsInToss.ts
207
266
  init_esm_shims();
208
- import path9 from "path";
267
+ import path7 from "path";
209
268
  import { microFrontend } from "@granite-js/plugin-micro-frontend";
210
- import { getPackageRoot as getPackageRoot6 } from "@granite-js/utils";
269
+ import { getPackageRoot as getPackageRoot5 } from "@granite-js/utils";
211
270
 
212
271
  // src/constants.ts
213
272
  init_esm_shims();
@@ -293,9 +352,9 @@ async function appsInTossAppJson(options) {
293
352
 
294
353
  // src/plugins/artifact.ts
295
354
  init_esm_shims();
296
- import path6 from "path";
355
+ import path4 from "path";
297
356
  import { isBuildFailure, isBuildSuccess } from "@granite-js/plugin-core";
298
- import { getPackageRoot as getPackageRoot3 } from "@granite-js/utils";
357
+ import { getPackageRoot as getPackageRoot2 } from "@granite-js/utils";
299
358
  import pc2 from "picocolors";
300
359
 
301
360
  // src/utils/collectDependencyVersions.ts
@@ -358,8 +417,8 @@ async function resolvePackageVersions(rootDir, packageNames) {
358
417
  function createVirtualEntry(packageNames) {
359
418
  return packageNames.map((packageName) => `import '${packageName}';`).join("\n");
360
419
  }
361
- function extractPackagePath(path10, packageName) {
362
- const normalizedPath = normalizePath(path10);
420
+ function extractPackagePath(path8, packageName) {
421
+ const normalizedPath = normalizePath(path8);
363
422
  if (normalizedPath.endsWith("/package.json")) {
364
423
  return normalizedPath.replace(/\/package\.json$/, "");
365
424
  }
@@ -369,8 +428,8 @@ function extractPackagePath(path10, packageName) {
369
428
  }
370
429
  throw new Error(`Failed to extract path: ${packageName}`);
371
430
  }
372
- function normalizePath(path10) {
373
- return path10.replace(/\\/g, "/");
431
+ function normalizePath(path8) {
432
+ return path8.replace(/\\/g, "/");
374
433
  }
375
434
  async function getPackageVersion(packagePath) {
376
435
  const packageJson = JSON.parse(await fs2.readFile(path2.join(packagePath, "package.json"), "utf-8"));
@@ -379,97 +438,422 @@ async function getPackageVersion(packagePath) {
379
438
 
380
439
  // src/utils/createArtifact.ts
381
440
  init_esm_shims();
382
- import path5 from "path";
383
- import { readZipContent } from "@granite-js/utils";
441
+ import * as fs3 from "fs/promises";
442
+ import path3 from "path";
443
+ import { AppsInTossBundle, PlatformType } from "@apps-in-toss/ait-format";
384
444
 
385
- // src/utils/compressToZip.ts
445
+ // src/utils/getUnityMetaDataEnv.ts
386
446
  init_esm_shims();
387
- import * as fs3 from "fs";
388
- import * as path3 from "path";
389
- import archiver from "archiver";
390
- async function compressToZip(config) {
391
- const { files, outfile } = config;
392
- return new Promise((resolve, reject) => {
393
- const outputStream = fs3.createWriteStream(outfile);
394
- const archive = archiver("zip", { zlib: { level: 9 } });
395
- outputStream.on("close", () => resolve(outfile));
396
- outputStream.on("error", (error2) => reject(error2));
397
- archive.on("error", (error2) => reject(error2)).pipe(outputStream);
398
- files.forEach(({ path: filePath, name }) => {
399
- const fileName = name ?? path3.basename(filePath);
400
- archive.append(fs3.createReadStream(filePath), { name: fileName });
401
- });
402
- archive.finalize();
447
+ function getUnityMetaDataEnv() {
448
+ const metaData = process.env.UNITY_METADATA;
449
+ if (!metaData) return {};
450
+ try {
451
+ return JSON.parse(metaData);
452
+ } catch (e) {
453
+ console.warn("UNITY_METADATA is not a valid JSON:", e);
454
+ return {};
455
+ }
456
+ }
457
+
458
+ // src/utils/createArtifact.ts
459
+ async function createArtifact(options) {
460
+ const { bundleFiles, outfile, appJsonPath, reactNativeVersion, sdkVersion, isGame } = options;
461
+ const unityMetaData = getUnityMetaDataEnv();
462
+ const appJsonContent = await fs3.readFile(appJsonPath, "utf-8");
463
+ const appJson = JSON.parse(appJsonContent);
464
+ const runtime = reactNativeVersion.replace(/\./g, "_");
465
+ const namedBundleFiles = bundleFiles.map((bundle) => {
466
+ const extension = path3.extname(bundle.path);
467
+ return {
468
+ path: bundle.path,
469
+ name: `bundle.${bundle.platform}.${runtime}${extension === ".map" ? ".js.map" : extension}`
470
+ };
471
+ });
472
+ const writer = AppsInTossBundle.writer({
473
+ deploymentId: options.deploymentId,
474
+ appName: appJson.appName,
475
+ createdBy: "@apps-in-toss/plugins"
476
+ });
477
+ writer.setMetadata({
478
+ platform: PlatformType.REACT_NATIVE,
479
+ runtimeVersion: reactNativeVersion,
480
+ isGame,
481
+ sdkVersion,
482
+ bundleFiles: namedBundleFiles.map(({ name }) => name),
483
+ packageJson: options.packageJson,
484
+ extra: { unityMetaData }
403
485
  });
486
+ for (const permission of appJson.permissions ?? []) {
487
+ writer.addPermission(permission.name, permission.access);
488
+ }
489
+ for (const bundle of namedBundleFiles) {
490
+ const content = await fs3.readFile(bundle.path);
491
+ writer.addFile(bundle.name, new Uint8Array(content));
492
+ }
493
+ for (const file of options.additionalFilesToZip ?? []) {
494
+ const content = await fs3.readFile(file.path);
495
+ writer.addFile(file.name, new Uint8Array(content));
496
+ }
497
+ const buffer = await writer.toBuffer();
498
+ await fs3.writeFile(outfile, buffer);
499
+ return outfile;
404
500
  }
405
501
 
406
- // src/utils/updateAppJsonMetadata.ts
407
- init_esm_shims();
408
- import * as fs4 from "fs/promises";
409
- import * as path4 from "path";
410
- import { getPackageRoot as getPackageRoot2 } from "@granite-js/utils";
411
- async function resolveAppManifestPath() {
412
- const cwd = getPackageRoot2();
413
- const appManifestPath = path4.join(cwd, ".granite", APP_MANIFEST_NAME);
414
- await fs4.access(appManifestPath, fs4.constants.F_OK);
415
- return appManifestPath;
502
+ // src/plugins/artifact.ts
503
+ function appsInTossCreateArtifact(deploymentId, buildOption) {
504
+ const packageRoot = getPackageRoot2();
505
+ return {
506
+ name: "apps-in-toss:create-artifact",
507
+ build: {
508
+ order: "post",
509
+ handler: async ({ buildResults, appName, cwd }) => {
510
+ const buildFailed = buildResults.some(isBuildFailure);
511
+ if (buildFailed) {
512
+ throw new Error("\uBC88\uB4E4 \uBE4C\uB4DC \uC2E4\uD328");
513
+ }
514
+ log("\uC571 \uBE4C\uB4DC \uC911...");
515
+ const { dependencies, devDependencies } = await collectDependencyVersions(cwd);
516
+ const artifactOutfile = await createArtifact({
517
+ reactNativeVersion: REACT_NATIVE_VERSION,
518
+ deploymentId,
519
+ sdkVersion: buildOption.sdkVersion,
520
+ isGame: buildOption.isGame,
521
+ packageJson: { dependencies, devDependencies },
522
+ bundleFiles: buildResults.filter(isBuildSuccess).map(({ outfile, sourcemapOutfile, platform }) => [
523
+ {
524
+ path: outfile,
525
+ platform
526
+ },
527
+ {
528
+ path: sourcemapOutfile,
529
+ platform
530
+ }
531
+ ]).flat(),
532
+ outfile: path4.join(cwd, `${appName}.ait`),
533
+ appJsonPath: path4.join(packageRoot, ".granite", APP_MANIFEST_NAME)
534
+ });
535
+ if (!artifactOutfile) {
536
+ throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
537
+ }
538
+ const filename = path4.basename(artifactOutfile);
539
+ log(`\u2705 ${pc2.green(`${filename}`)} \uBE4C\uB4DC \uC644\uB8CC`);
540
+ }
541
+ }
542
+ };
416
543
  }
417
- async function readAppJson(appJsonPath) {
418
- const appJson = await fs4.readFile(appJsonPath, "utf8");
419
- return JSON.parse(appJson);
544
+
545
+ // src/plugins/build.ts
546
+ init_esm_shims();
547
+ function appsInTossEsbuildConfig(envScript) {
548
+ return {
549
+ name: "apps-in-toss:esbuild-config",
550
+ config: {
551
+ esbuild: {
552
+ banner: {
553
+ js: envScript
554
+ }
555
+ }
556
+ }
557
+ };
420
558
  }
421
- async function writeAppJson(appJsonPath, content) {
422
- await fs4.writeFile(appJsonPath, JSON.stringify(content));
559
+ function appsInTossMetroConfig(envScriptPath) {
560
+ return {
561
+ name: "apps-in-toss:metro-config",
562
+ config: {
563
+ metro: {
564
+ serializer: {
565
+ getPolyfills: () => [envScriptPath]
566
+ }
567
+ }
568
+ }
569
+ };
423
570
  }
424
- async function updateAppJsonMetadata(metadata) {
425
- const appJsonPath = await resolveAppManifestPath();
426
- const appJson = await readAppJson(appJsonPath);
427
- await writeAppJson(appJsonPath, {
428
- ...appJson,
429
- _metadata: metadata
571
+
572
+ // src/plugins/compat.ts
573
+ init_esm_shims();
574
+ import fs4 from "fs";
575
+ import path5 from "path";
576
+ import { getLocalTempDirectoryPath, getPackageRoot as getPackageRoot3 } from "@granite-js/utils";
577
+ var nativeModuleProxyContent = `
578
+ (function () {
579
+ global.nativeModuleProxy = new Proxy(global.nativeModuleProxy, {
580
+ get: function (target, name) {
581
+ if (name === 'GraniteModule') {
582
+ return target['BedrockModule'] || target[name];
583
+ }
584
+
585
+ if (name === 'GraniteCoreModule') {
586
+ return target['BedrockCoreModule'] || target[name];
587
+ }
588
+
589
+ return target[name];
590
+ }
430
591
  });
592
+
593
+ global.__nativeModuleProxyConfigured = true;
594
+ })(
595
+ typeof globalThis !== 'undefined'
596
+ ? globalThis
597
+ : typeof global !== 'undefined'
598
+ ? global
599
+ : typeof window !== 'undefined'
600
+ ? window
601
+ : this
602
+ );
603
+ `;
604
+ var reactNativeModuleProxyContent = `
605
+ (function (global) {
606
+ if (global.__nativeModuleProxyConfigured) {
607
+ return;
608
+ }
609
+
610
+ function getCustomTurboModuleRegistry(registry) {
611
+ var remappedModules = {
612
+ 'GraniteModule': 'BedrockModule',
613
+ 'GraniteCoreModule': 'BedrockCoreModule',
614
+ };
615
+
616
+ return {
617
+ get: function (name) {
618
+ var mod;
619
+ var remappedName = remappedModules[name];
620
+
621
+ if (remappedName) {
622
+ mod = registry.get(remappedName);
623
+ }
624
+
625
+ return mod || registry.get(name);
626
+ },
627
+ getEnforcing: function (name) {
628
+ var mod;
629
+ var remappedName = remappedModules[name];
630
+
631
+ if (remappedName) {
632
+ mod = registry.get(remappedName);
633
+ }
634
+
635
+ return mod || registry.getEnforcing(name);
636
+ }
637
+ };
638
+ }
639
+
640
+ function createReactNativeProxy(reactNative) {
641
+ return new Proxy(reactNative, {
642
+ get: function (target, name) {
643
+ var origin = target[name];
644
+ return name === 'TurboModuleRegistry' ? getCustomTurboModuleRegistry(origin) : origin;
645
+ }
646
+ });
647
+ }
648
+
649
+ var reactNative;
650
+
651
+ if (typeof global.__MICRO_FRONTEND__ !== 'undefined') {
652
+ var mod = global.__MICRO_FRONTEND__.__SHARED__['react-native'];
653
+ reactNative = mod && mod.get();
654
+ }
655
+
656
+ if (reactNative == null && typeof __bedrock_require__ === 'function') {
657
+ reactNative = global.__bedrock_require__('react-native');
658
+ }
659
+
660
+ if (reactNative == null) {
661
+ throw new Error('cannot get react-native in the global registry');
662
+ }
663
+
664
+ global.__reactNativeProxy = createReactNativeProxy(reactNative);
665
+ global.__MICRO_FRONTEND__.__SHARED__['react-native'] = {
666
+ get: function () {
667
+ return global.__reactNativeProxy;
668
+ },
669
+ loaded: true,
670
+ };
671
+ })(
672
+ typeof globalThis !== 'undefined'
673
+ ? globalThis
674
+ : typeof global !== 'undefined'
675
+ ? global
676
+ : typeof window !== 'undefined'
677
+ ? window
678
+ : this
679
+ );
680
+ `;
681
+ function bedrockCompat({ isHost }) {
682
+ const metroPolyfillContent = path5.join(getLocalTempDirectoryPath(getPackageRoot3()), "metro-native-module-proxy.js");
683
+ fs4.writeFileSync(metroPolyfillContent, nativeModuleProxyContent);
684
+ return {
685
+ name: "bedrock-compat-plugin",
686
+ config: {
687
+ esbuild: {
688
+ banner: {
689
+ js: isHost ? nativeModuleProxyContent : reactNativeModuleProxyContent
690
+ }
691
+ },
692
+ metro: {
693
+ serializer: {
694
+ getPolyfills: () => [metroPolyfillContent]
695
+ }
696
+ }
697
+ }
698
+ };
431
699
  }
432
700
 
433
- // src/types.ts
701
+ // src/plugins/devServer.ts
434
702
  init_esm_shims();
435
- var __typia_transform__isFormatUuid = __toESM(require_isFormatUuid(), 1);
436
- var __typia_transform__validateReport = __toESM(require_validateReport(), 1);
437
- var __typia_transform__createStandardSchema = __toESM(require_createStandardSchema(), 1);
438
- var validateAppManifest = (() => {
439
- 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));
440
- const _io1 = (input) => "clipboard" === input.name && ("read" === input.access || "write" === input.access);
441
- const _io2 = (input) => "geolocation" === input.name && "access" === input.access;
442
- const _io3 = (input) => "contacts" === input.name && ("read" === input.access || "write" === input.access);
443
- const _io4 = (input) => "photos" === input.name && ("read" === input.access || "write" === input.access);
444
- const _io5 = (input) => "camera" === input.name && "access" === input.access;
445
- const _io6 = (input) => Array.isArray(input.bundleFiles) && input.bundleFiles.every((elem) => "string" === typeof elem) && ("string" === typeof input.deploymentId && __typia_transform__isFormatUuid._isFormatUuid(input.deploymentId));
446
- const _iu0 = (input) => (() => {
447
- if ("camera" === input.name)
448
- return _io5(input);
449
- else if ("photos" === input.name)
450
- return _io4(input);
451
- else if ("contacts" === input.name)
452
- return _io3(input);
453
- else if ("geolocation" === input.name)
454
- return _io2(input);
455
- else if ("clipboard" === input.name)
456
- return _io1(input);
457
- else
458
- return false;
459
- })();
460
- const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.appName || _report(_exceptionable, {
461
- path: _path + ".appName",
462
- expected: "string",
463
- value: input.appName
464
- }), (Array.isArray(input.permissions) || _report(_exceptionable, {
465
- path: _path + ".permissions",
466
- expected: "Array<Permission>",
467
- value: input.permissions
468
- })) && input.permissions.map((elem, _index3) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
469
- path: _path + ".permissions[" + _index3 + "]",
470
- expected: "(CameraPermission | ClipboardPermission | ContactsPermission | GeolocationPermission | PhotosPermission)",
471
- value: elem
472
- })) && _vu0(elem, _path + ".permissions[" + _index3 + "]", _exceptionable) || _report(_exceptionable, {
703
+
704
+ // src/utils/createServerPermissionsMiddleware.ts
705
+ init_esm_shims();
706
+ function createServerPermissionsMiddleware(permissions) {
707
+ const parsedPermissions = parsePermissions(permissions);
708
+ return (req, res, next) => {
709
+ if (req.method === "GET" && req.url === "/permissions") {
710
+ res.writeHead(200, {
711
+ "Content-Length": Buffer.byteLength(parsedPermissions),
712
+ "Content-Type": "text/plain"
713
+ }).end(parsedPermissions);
714
+ return;
715
+ }
716
+ next();
717
+ };
718
+ }
719
+ function parsePermissions(permissions) {
720
+ const permissionMap = /* @__PURE__ */ new Map();
721
+ for (const permission of permissions) {
722
+ const { name, access } = permission;
723
+ if (!permissionMap.has(name)) {
724
+ permissionMap.set(name, /* @__PURE__ */ new Set());
725
+ }
726
+ let accessValue = null;
727
+ switch (access) {
728
+ case "read":
729
+ accessValue = "r";
730
+ break;
731
+ case "write":
732
+ accessValue = "w";
733
+ break;
734
+ case "access":
735
+ accessValue = "a";
736
+ break;
737
+ default:
738
+ accessValue = null;
739
+ }
740
+ if (!accessValue) {
741
+ continue;
742
+ }
743
+ permissionMap.get(name).add(accessValue);
744
+ }
745
+ return Array.from(permissionMap.entries()).map(([name, accesses]) => `${name}:${Array.from(accesses).sort().join("")}`).sort().join(",");
746
+ }
747
+
748
+ // src/plugins/devServer.ts
749
+ function appsInTossDevServer(options) {
750
+ return {
751
+ name: "apps-in-toss:dev-server",
752
+ config: {
753
+ metro: {
754
+ middlewares: [createServerPermissionsMiddleware(options.permissions)]
755
+ }
756
+ }
757
+ };
758
+ }
759
+
760
+ // src/plugins/notice.ts
761
+ init_esm_shims();
762
+ function appsInTossPostNotice() {
763
+ const phase = "post";
764
+ return {
765
+ name: "apps-in-toss:post-notice",
766
+ dev: {
767
+ order: phase,
768
+ handler() {
769
+ }
770
+ },
771
+ build: {
772
+ order: phase,
773
+ async handler({ appName }) {
774
+ if (this.meta.sentry) {
775
+ const command = [
776
+ "ait sentry upload-sourcemap",
777
+ `--app-name ${appName}`,
778
+ "--api-key <API_KEY>",
779
+ "--deployment-id <DEPLOYMENT_ID>"
780
+ ].join(" \\\n");
781
+ log(
782
+ `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.
783
+
784
+ ${command}
785
+ `
786
+ );
787
+ }
788
+ }
789
+ }
790
+ };
791
+ }
792
+
793
+ // src/plugins/resolve.ts
794
+ init_esm_shims();
795
+ import Module from "module";
796
+ function getRequire() {
797
+ return typeof __require === "function" ? __require : Module.createRequire(import.meta.url);
798
+ }
799
+ function requireMicroFrontendRuntime() {
800
+ const require2 = getRequire();
801
+ const runtimePath = require2.resolve("@granite-js/plugin-micro-frontend/runtime");
802
+ return {
803
+ name: "apps-in-toss-micro-frontend",
804
+ config: {
805
+ resolver: {
806
+ alias: [
807
+ {
808
+ from: "@granite-js/plugin-micro-frontend/runtime",
809
+ to: runtimePath
810
+ }
811
+ ]
812
+ }
813
+ }
814
+ };
815
+ }
816
+
817
+ // src/types.ts
818
+ init_esm_shims();
819
+ var __typia_transform__isFormatUuid = __toESM(require_isFormatUuid(), 1);
820
+ var __typia_transform__validateReport = __toESM(require_validateReport(), 1);
821
+ var __typia_transform__createStandardSchema = __toESM(require_createStandardSchema(), 1);
822
+ 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));
824
+ const _io1 = (input) => "clipboard" === input.name && ("read" === input.access || "write" === input.access);
825
+ const _io2 = (input) => "geolocation" === input.name && "access" === input.access;
826
+ const _io3 = (input) => "contacts" === input.name && ("read" === input.access || "write" === input.access);
827
+ const _io4 = (input) => "photos" === input.name && ("read" === input.access || "write" === input.access);
828
+ const _io5 = (input) => "camera" === input.name && "access" === input.access;
829
+ const _io6 = (input) => Array.isArray(input.bundleFiles) && input.bundleFiles.every((elem) => "string" === typeof elem) && ("string" === typeof input.deploymentId && __typia_transform__isFormatUuid._isFormatUuid(input.deploymentId));
830
+ const _iu0 = (input) => (() => {
831
+ if ("camera" === input.name)
832
+ return _io5(input);
833
+ else if ("photos" === input.name)
834
+ return _io4(input);
835
+ else if ("contacts" === input.name)
836
+ return _io3(input);
837
+ else if ("geolocation" === input.name)
838
+ return _io2(input);
839
+ else if ("clipboard" === input.name)
840
+ return _io1(input);
841
+ else
842
+ return false;
843
+ })();
844
+ const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.appName || _report(_exceptionable, {
845
+ path: _path + ".appName",
846
+ expected: "string",
847
+ value: input.appName
848
+ }), (Array.isArray(input.permissions) || _report(_exceptionable, {
849
+ path: _path + ".permissions",
850
+ expected: "Array<Permission>",
851
+ value: input.permissions
852
+ })) && input.permissions.map((elem, _index3) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
853
+ path: _path + ".permissions[" + _index3 + "]",
854
+ expected: "(CameraPermission | ClipboardPermission | ContactsPermission | GeolocationPermission | PhotosPermission)",
855
+ value: elem
856
+ })) && _vu0(elem, _path + ".permissions[" + _index3 + "]", _exceptionable) || _report(_exceptionable, {
473
857
  path: _path + ".permissions[" + _index3 + "]",
474
858
  expected: "(CameraPermission | ClipboardPermission | ContactsPermission | GeolocationPermission | PhotosPermission)",
475
859
  value: elem
@@ -864,354 +1248,6 @@ var validateAppInTossPluginOptions = (() => {
864
1248
  });
865
1249
  })();
866
1250
 
867
- // src/utils/createArtifact.ts
868
- async function validateZip(zipPath) {
869
- const appJsonString = await readZipContent(zipPath, "app.json");
870
- const appJson = JSON.parse(appJsonString);
871
- const validated = validateAppManifest(appJson);
872
- if (!validated.success) {
873
- throw new Error("granite.config.ts \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
874
- }
875
- }
876
- async function createArtifact(options) {
877
- const { bundleFiles, outfile, appJsonPath, reactNativeVersion } = options;
878
- const namedBundleFiles = bundleFiles.map((bundle) => {
879
- const originalName = path5.basename(bundle.path);
880
- const extension = path5.extname(originalName);
881
- const runtime = reactNativeVersion.replace(new RegExp(/\./g), "_");
882
- return {
883
- path: bundle.path,
884
- // TODO: Use shared utils for sync file name specification with Lambda
885
- name: `bundle.${bundle.platform}.${runtime}${extension === ".map" ? `.js.map` : extension}`
886
- };
887
- });
888
- await updateAppJsonMetadata({
889
- runtimeVersion: reactNativeVersion,
890
- bundleFiles: namedBundleFiles.map(({ name }) => name),
891
- deploymentId: options.deploymentId,
892
- packageJson: options.packageJson
893
- });
894
- await compressToZip({
895
- files: [{ path: appJsonPath, name: "app.json" }, ...namedBundleFiles, ...options.additionalFilesToZip ?? []],
896
- outfile
897
- });
898
- await validateZip(outfile);
899
- return outfile;
900
- }
901
-
902
- // src/plugins/artifact.ts
903
- function appsInTossCreateArtifact(deploymentId) {
904
- const packageRoot = getPackageRoot3();
905
- return {
906
- name: "apps-in-toss:create-artifact",
907
- build: {
908
- order: "post",
909
- handler: async ({ buildResults, appName, cwd }) => {
910
- const buildFailed = buildResults.some(isBuildFailure);
911
- if (buildFailed) {
912
- throw new Error("\uBC88\uB4E4 \uBE4C\uB4DC \uC2E4\uD328");
913
- }
914
- log("\uC571 \uBE4C\uB4DC \uC911...");
915
- const { dependencies, devDependencies } = await collectDependencyVersions(cwd);
916
- const artifactOutfile = await createArtifact({
917
- reactNativeVersion: REACT_NATIVE_VERSION,
918
- deploymentId,
919
- packageJson: { dependencies, devDependencies },
920
- bundleFiles: buildResults.filter(isBuildSuccess).map(({ outfile, sourcemapOutfile, platform }) => [
921
- {
922
- path: outfile,
923
- platform
924
- },
925
- {
926
- path: sourcemapOutfile,
927
- platform
928
- }
929
- ]).flat(),
930
- outfile: path6.join(cwd, `${appName}.ait`),
931
- appJsonPath: path6.join(packageRoot, ".granite", APP_MANIFEST_NAME)
932
- });
933
- if (!artifactOutfile) {
934
- throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
935
- }
936
- const filename = path6.basename(artifactOutfile);
937
- log(`\u2705 ${pc2.green(`${filename}`)} \uBE4C\uB4DC \uC644\uB8CC`);
938
- }
939
- }
940
- };
941
- }
942
-
943
- // src/plugins/build.ts
944
- init_esm_shims();
945
- function appsInTossEsbuildConfig(envScript) {
946
- return {
947
- name: "apps-in-toss:esbuild-config",
948
- config: {
949
- esbuild: {
950
- banner: {
951
- js: envScript
952
- }
953
- }
954
- }
955
- };
956
- }
957
- function appsInTossMetroConfig(envScriptPath) {
958
- return {
959
- name: "apps-in-toss:metro-config",
960
- config: {
961
- metro: {
962
- serializer: {
963
- getPolyfills: () => [envScriptPath]
964
- }
965
- }
966
- }
967
- };
968
- }
969
-
970
- // src/plugins/compat.ts
971
- init_esm_shims();
972
- import fs5 from "fs";
973
- import path7 from "path";
974
- import { getLocalTempDirectoryPath, getPackageRoot as getPackageRoot4 } from "@granite-js/utils";
975
- var nativeModuleProxyContent = `
976
- (function () {
977
- global.nativeModuleProxy = new Proxy(global.nativeModuleProxy, {
978
- get: function (target, name) {
979
- if (name === 'GraniteModule') {
980
- return target['BedrockModule'] || target[name];
981
- }
982
-
983
- if (name === 'GraniteCoreModule') {
984
- return target['BedrockCoreModule'] || target[name];
985
- }
986
-
987
- return target[name];
988
- }
989
- });
990
-
991
- global.__nativeModuleProxyConfigured = true;
992
- })(
993
- typeof globalThis !== 'undefined'
994
- ? globalThis
995
- : typeof global !== 'undefined'
996
- ? global
997
- : typeof window !== 'undefined'
998
- ? window
999
- : this
1000
- );
1001
- `;
1002
- var reactNativeModuleProxyContent = `
1003
- (function (global) {
1004
- if (global.__nativeModuleProxyConfigured) {
1005
- return;
1006
- }
1007
-
1008
- function getCustomTurboModuleRegistry(registry) {
1009
- var remappedModules = {
1010
- 'GraniteModule': 'BedrockModule',
1011
- 'GraniteCoreModule': 'BedrockCoreModule',
1012
- };
1013
-
1014
- return {
1015
- get: function (name) {
1016
- var mod;
1017
- var remappedName = remappedModules[name];
1018
-
1019
- if (remappedName) {
1020
- mod = registry.get(remappedName);
1021
- }
1022
-
1023
- return mod || registry.get(name);
1024
- },
1025
- getEnforcing: function (name) {
1026
- var mod;
1027
- var remappedName = remappedModules[name];
1028
-
1029
- if (remappedName) {
1030
- mod = registry.get(remappedName);
1031
- }
1032
-
1033
- return mod || registry.getEnforcing(name);
1034
- }
1035
- };
1036
- }
1037
-
1038
- function createReactNativeProxy(reactNative) {
1039
- return new Proxy(reactNative, {
1040
- get: function (target, name) {
1041
- var origin = target[name];
1042
- return name === 'TurboModuleRegistry' ? getCustomTurboModuleRegistry(origin) : origin;
1043
- }
1044
- });
1045
- }
1046
-
1047
- var reactNative;
1048
-
1049
- if (typeof global.__MICRO_FRONTEND__ !== 'undefined') {
1050
- var mod = global.__MICRO_FRONTEND__.__SHARED__['react-native'];
1051
- reactNative = mod && mod.get();
1052
- }
1053
-
1054
- if (reactNative == null && typeof __bedrock_require__ === 'function') {
1055
- reactNative = global.__bedrock_require__('react-native');
1056
- }
1057
-
1058
- if (reactNative == null) {
1059
- throw new Error('cannot get react-native in the global registry');
1060
- }
1061
-
1062
- global.__reactNativeProxy = createReactNativeProxy(reactNative);
1063
- global.__MICRO_FRONTEND__.__SHARED__['react-native'] = {
1064
- get: function () {
1065
- return global.__reactNativeProxy;
1066
- },
1067
- loaded: true,
1068
- };
1069
- })(
1070
- typeof globalThis !== 'undefined'
1071
- ? globalThis
1072
- : typeof global !== 'undefined'
1073
- ? global
1074
- : typeof window !== 'undefined'
1075
- ? window
1076
- : this
1077
- );
1078
- `;
1079
- function bedrockCompat({ isHost }) {
1080
- const metroPolyfillContent = path7.join(getLocalTempDirectoryPath(getPackageRoot4()), "metro-native-module-proxy.js");
1081
- fs5.writeFileSync(metroPolyfillContent, nativeModuleProxyContent);
1082
- return {
1083
- name: "bedrock-compat-plugin",
1084
- config: {
1085
- esbuild: {
1086
- banner: {
1087
- js: isHost ? nativeModuleProxyContent : reactNativeModuleProxyContent
1088
- }
1089
- },
1090
- metro: {
1091
- serializer: {
1092
- getPolyfills: () => [metroPolyfillContent]
1093
- }
1094
- }
1095
- }
1096
- };
1097
- }
1098
-
1099
- // src/plugins/devServer.ts
1100
- init_esm_shims();
1101
-
1102
- // src/utils/createServerPermissionsMiddleware.ts
1103
- init_esm_shims();
1104
- function createServerPermissionsMiddleware(permissions) {
1105
- const parsedPermissions = parsePermissions(permissions);
1106
- return (req, res, next) => {
1107
- if (req.method === "GET" && req.url === "/permissions") {
1108
- res.writeHead(200, {
1109
- "Content-Length": Buffer.byteLength(parsedPermissions),
1110
- "Content-Type": "text/plain"
1111
- }).end(parsedPermissions);
1112
- return;
1113
- }
1114
- next();
1115
- };
1116
- }
1117
- function parsePermissions(permissions) {
1118
- const permissionMap = /* @__PURE__ */ new Map();
1119
- for (const permission of permissions) {
1120
- const { name, access: access2 } = permission;
1121
- if (!permissionMap.has(name)) {
1122
- permissionMap.set(name, /* @__PURE__ */ new Set());
1123
- }
1124
- let accessValue = null;
1125
- switch (access2) {
1126
- case "read":
1127
- accessValue = "r";
1128
- break;
1129
- case "write":
1130
- accessValue = "w";
1131
- break;
1132
- case "access":
1133
- accessValue = "a";
1134
- break;
1135
- default:
1136
- accessValue = null;
1137
- }
1138
- if (!accessValue) {
1139
- continue;
1140
- }
1141
- permissionMap.get(name).add(accessValue);
1142
- }
1143
- return Array.from(permissionMap.entries()).map(([name, accesses]) => `${name}:${Array.from(accesses).sort().join("")}`).sort().join(",");
1144
- }
1145
-
1146
- // src/plugins/devServer.ts
1147
- function appsInTossDevServer(options) {
1148
- return {
1149
- name: "apps-in-toss:dev-server",
1150
- config: {
1151
- metro: {
1152
- middlewares: [createServerPermissionsMiddleware(options.permissions)]
1153
- }
1154
- }
1155
- };
1156
- }
1157
-
1158
- // src/plugins/notice.ts
1159
- init_esm_shims();
1160
- function appsInTossPostNotice() {
1161
- const phase = "post";
1162
- return {
1163
- name: "apps-in-toss:post-notice",
1164
- dev: {
1165
- order: phase,
1166
- handler() {
1167
- }
1168
- },
1169
- build: {
1170
- order: phase,
1171
- async handler({ appName }) {
1172
- if (this.meta.sentry) {
1173
- const command = [
1174
- "ait sentry upload-sourcemap",
1175
- `--app-name ${appName}`,
1176
- "--api-key <API_KEY>",
1177
- "--deployment-id <DEPLOYMENT_ID>"
1178
- ].join(" \\\n");
1179
- log(
1180
- `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.
1181
-
1182
- ${command}
1183
- `
1184
- );
1185
- }
1186
- }
1187
- }
1188
- };
1189
- }
1190
-
1191
- // src/plugins/resolve.ts
1192
- init_esm_shims();
1193
- import Module from "module";
1194
- function getRequire() {
1195
- return typeof __require === "function" ? __require : Module.createRequire(import.meta.url);
1196
- }
1197
- function requireMicroFrontendRuntime() {
1198
- const require2 = getRequire();
1199
- const runtimePath = require2.resolve("@granite-js/plugin-micro-frontend/runtime");
1200
- return {
1201
- name: "apps-in-toss-micro-frontend",
1202
- config: {
1203
- resolver: {
1204
- alias: [
1205
- {
1206
- from: "@granite-js/plugin-micro-frontend/runtime",
1207
- to: runtimePath
1208
- }
1209
- ]
1210
- }
1211
- }
1212
- };
1213
- }
1214
-
1215
1251
  // src/utils/generateDeploymentId.ts
1216
1252
  init_esm_shims();
1217
1253
  import { uuidv7 } from "uuidv7";
@@ -1219,11 +1255,18 @@ function generateDeploymentId() {
1219
1255
  return uuidv7();
1220
1256
  }
1221
1257
 
1258
+ // src/utils/getSdkVersion.ts
1259
+ init_esm_shims();
1260
+ function getSdkVersion() {
1261
+ const packageJson = require_package();
1262
+ return packageJson.version;
1263
+ }
1264
+
1222
1265
  // src/utils/setupRuntimeSetupScript.ts
1223
1266
  init_esm_shims();
1224
- import fs6 from "node:fs";
1225
- import path8 from "node:path";
1226
- import { getPackageRoot as getPackageRoot5 } from "@granite-js/utils";
1267
+ import fs5 from "node:fs";
1268
+ import path6 from "node:path";
1269
+ import { getPackageRoot as getPackageRoot4 } from "@granite-js/utils";
1227
1270
  import { transformSync } from "esbuild";
1228
1271
  function setupRuntimeSetupScript(config) {
1229
1272
  const script = getRuntimeSetupScript(
@@ -1268,15 +1311,15 @@ function getRuntimeSetupScript(metadata, identifier) {
1268
1311
  }).code;
1269
1312
  }
1270
1313
  function writeRuntimeSetupScript(script) {
1271
- const packageRoot = getPackageRoot5();
1272
- const granitePath = path8.join(packageRoot, ".granite");
1314
+ const packageRoot = getPackageRoot4();
1315
+ const granitePath = path6.join(packageRoot, ".granite");
1273
1316
  try {
1274
- fs6.accessSync(granitePath);
1317
+ fs5.accessSync(granitePath);
1275
1318
  } catch {
1276
- fs6.mkdirSync(granitePath, { recursive: true });
1319
+ fs5.mkdirSync(granitePath, { recursive: true });
1277
1320
  }
1278
- const envFilePath = path8.join(granitePath, ".apps-in-toss.env.js");
1279
- fs6.writeFileSync(envFilePath, script, "utf-8");
1321
+ const envFilePath = path6.join(granitePath, ".apps-in-toss.env.js");
1322
+ fs5.writeFileSync(envFilePath, script, "utf-8");
1280
1323
  return envFilePath;
1281
1324
  }
1282
1325
  function getBedrockCompatScript() {
@@ -1371,14 +1414,19 @@ function appsInToss(options) {
1371
1414
  process.exit(1);
1372
1415
  }
1373
1416
  const deploymentId = generateDeploymentId();
1374
- const root = getPackageRoot6();
1417
+ const root = getPackageRoot5();
1418
+ const sdkVersion = getSdkVersion();
1419
+ const buildOptions = {
1420
+ sdkVersion,
1421
+ isGame: result.data.appType === "game"
1422
+ };
1375
1423
  return withAppsInTossCommon(
1376
- [appsInTossDevServer(options), appsInTossCreateArtifact(deploymentId), appsInTossPostNotice()],
1424
+ [appsInTossDevServer(options), appsInTossCreateArtifact(deploymentId, buildOptions), appsInTossPostNotice()],
1377
1425
  {
1378
1426
  ...options,
1379
1427
  root,
1380
1428
  deploymentId,
1381
- exposePath: path9.join(root, "./src/_app.tsx"),
1429
+ exposePath: path7.join(root, "./src/_app.tsx"),
1382
1430
  navigationBar: result.data.navigationBar
1383
1431
  }
1384
1432
  );
@@ -1464,6 +1512,5 @@ export {
1464
1512
  setupRuntimeSetupScript,
1465
1513
  validateAppInTossPluginOptions,
1466
1514
  validateAppManifest,
1467
- validateZip,
1468
1515
  withAppsInTossCommon
1469
1516
  };