@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/internal.js CHANGED
@@ -1,98 +1,40 @@
1
1
  import { createRequire } from 'module'; const require = createRequire(import.meta.url);
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
2
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
3
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
4
  }) : x)(function(x) {
6
5
  if (typeof require !== "undefined") return require.apply(this, arguments);
7
6
  throw Error('Dynamic require of "' + x + '" is not supported');
8
7
  });
9
- var __commonJS = (cb, mod) => function __require2() {
10
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
- };
12
-
13
- // package.json
14
- var require_package = __commonJS({
15
- "package.json"(exports, module) {
16
- module.exports = {
17
- name: "@apps-in-toss/plugins",
18
- type: "module",
19
- version: "1.14.0",
20
- description: "The plugins for Apps In Toss",
21
- scripts: {
22
- test: "vitest --run",
23
- typecheck: "tsc --noEmit",
24
- lint: "eslint .",
25
- build: "tsup"
26
- },
27
- main: "./dist/index.cjs",
28
- module: "./dist/index.js",
29
- types: "./dist/index.d.ts",
30
- exports: {
31
- ".": {
32
- types: "./dist/index.d.ts",
33
- import: "./dist/index.js",
34
- require: "./dist/index.cjs"
35
- },
36
- "./internal": {
37
- types: "./dist/internal.d.ts",
38
- import: "./dist/internal.js",
39
- require: "./dist/internal.cjs"
40
- },
41
- "./package.json": "./package.json"
42
- },
43
- files: [
44
- "dist/**/*"
45
- ],
46
- devDependencies: {
47
- "@ryoppippi/unplugin-typia": "^2.6.5",
48
- "@types/archiver": "^6.0.3",
49
- "@types/connect": "^3",
50
- tsup: "^8.4.0",
51
- typescript: "5.8.3",
52
- typia: "^9.3.0",
53
- vitest: "^3.2.4"
54
- },
55
- dependencies: {
56
- "@apps-in-toss/ait-format": "^1.0.0",
57
- "@granite-js/plugin-core": "0.1.31",
58
- "@granite-js/plugin-micro-frontend": "0.1.31",
59
- "@granite-js/plugin-sentry": "0.1.31",
60
- "@granite-js/utils": "0.1.31",
61
- archiver: "^7.0.1",
62
- connect: "^3.7.0",
63
- esbuild: "0.25.5",
64
- execa: "9.3.0",
65
- picocolors: "^1.1.1",
66
- uuidv7: "^1.0.2"
67
- }
68
- };
69
- }
70
- });
71
8
 
72
9
  // src/appsInTossHost.ts
10
+ import { reactNativeCompatibilityPlugin, reactNativeReverseCompatibilityPlugin } from "@apps-in-toss/plugin-compat";
73
11
  import { microFrontend } from "@granite-js/plugin-micro-frontend";
74
12
  import { sentry } from "@granite-js/plugin-sentry";
13
+ import { getPackageRoot as getPackageRoot6 } from "@granite-js/utils";
75
14
 
76
15
  // src/constants.ts
77
- var REACT_NATIVE_VERSION = "0.72.6";
16
+ var REACT_NATIVE_VERSION = "0.84.0";
78
17
  var APP_MANIFEST_NAME = "app.json";
79
18
  var MICRO_FRONTEND_HOST_NAME = "apps-in-toss-host";
80
19
  var HOST_CONTEXT_IDENTIFIER = "__appsInTossHost";
81
- var SHRED_PACKAGES = [
20
+ var getSharedPackages = ({ reactNativeVersion }) => [
82
21
  "@react-native-community/blur",
83
22
  "@react-navigation/native",
84
23
  "@react-navigation/native-stack",
24
+ "@sentry/react-native",
85
25
  "@shopify/flash-list",
86
- "lottie-react-native",
87
26
  "react-native-safe-area-context",
88
27
  "react-native-screens",
89
- "react-native-fast-image",
90
28
  "react-native-svg",
91
29
  "react-native-gesture-handler",
92
30
  "react-native",
93
31
  "react",
94
- "react-native-video",
95
- "react-native-webview"
32
+ "react-native-webview",
33
+ "@granite-js/image",
34
+ "@granite-js/lottie",
35
+ "@granite-js/video",
36
+ ...reactNativeVersion === "0.84" ? ["brick-module", "@react-navigation/elements"] : [],
37
+ ...reactNativeVersion === "0.72" ? ["react-native-fast-image", "lottie-react-native", "react-native-video"] : []
96
38
  ];
97
39
 
98
40
  // src/plugins/appJson.ts
@@ -105,7 +47,8 @@ async function appsInTossAppJson(options) {
105
47
  const appJsonPath = path.join(packageRoot, ".granite", APP_MANIFEST_NAME);
106
48
  const appJsonObject = {
107
49
  appName,
108
- permissions: options.permissions
50
+ permissions: options.permissions,
51
+ ...options.appType != null ? { appType: options.appType } : {}
109
52
  };
110
53
  await fs.promises.mkdir(path.dirname(appJsonPath), { recursive: true });
111
54
  try {
@@ -113,7 +56,8 @@ async function appsInTossAppJson(options) {
113
56
  const existingAppJsonObject = JSON.parse(existingAppJson);
114
57
  Object.assign(appJsonObject, existingAppJsonObject, {
115
58
  appName,
116
- permissions: appJsonObject.permissions
59
+ permissions: appJsonObject.permissions,
60
+ ...options.appType != null ? { appType: options.appType } : {}
117
61
  });
118
62
  } catch {
119
63
  }
@@ -137,7 +81,6 @@ async function appsInTossAppJson(options) {
137
81
  }
138
82
 
139
83
  // src/plugins/artifact.ts
140
- import path4 from "path";
141
84
  import { isBuildFailure, isBuildSuccess } from "@granite-js/plugin-core";
142
85
  import { getPackageRoot as getPackageRoot2 } from "@granite-js/utils";
143
86
  import pc2 from "picocolors";
@@ -145,192 +88,13 @@ import pc2 from "picocolors";
145
88
  // src/log.ts
146
89
  import pc from "picocolors";
147
90
  var TAG = pc.bold(pc.cyan("[AppsInToss]"));
148
- function log(...args) {
149
- console.log(TAG, ...args);
150
- }
151
91
 
152
92
  // src/utils/collectDependencyVersions.ts
153
- import * as fs2 from "fs/promises";
154
- import * as path2 from "path";
155
93
  import * as esbuild from "esbuild";
156
- async function collectDependencyVersions(rootDir) {
157
- const packageJsonPath = path2.join(rootDir, "package.json");
158
- const packageJson = JSON.parse(await fs2.readFile(packageJsonPath, "utf8"));
159
- const [dependencies, devDependencies] = await Promise.all([
160
- resolvePackageVersions(rootDir, Object.keys(packageJson.dependencies)),
161
- resolvePackageVersions(rootDir, Object.keys(packageJson.devDependencies))
162
- ]);
163
- return { dependencies, devDependencies };
164
- }
165
- async function resolvePackageVersions(rootDir, packageNames) {
166
- const results = {};
167
- await esbuild.build({
168
- stdin: { contents: createVirtualEntry(packageNames) },
169
- bundle: true,
170
- write: false,
171
- logLevel: "silent",
172
- plugins: [
173
- {
174
- name: "collect-package-version",
175
- setup(build2) {
176
- const RESOLVING = Symbol();
177
- build2.onResolve({ filter: /.*/ }, async (args) => {
178
- if (args.pluginData === RESOLVING) {
179
- return null;
180
- }
181
- const resolveOptions = {
182
- importer: args.importer,
183
- kind: args.kind,
184
- resolveDir: rootDir,
185
- pluginData: RESOLVING
186
- };
187
- let result = await build2.resolve(path2.join(args.path, "package.json"), resolveOptions);
188
- if (result.errors.length) {
189
- result = await build2.resolve(args.path, resolveOptions);
190
- }
191
- if (result.errors.length) {
192
- return result;
193
- }
194
- const packageName = args.path;
195
- const packagePath = extractPackagePath(result.path, packageName);
196
- if (packagePath) {
197
- results[packageName] = await getPackageVersion(packagePath);
198
- }
199
- return result;
200
- });
201
- build2.onLoad({ filter: /.*/ }, () => ({ contents: "// empty source" }));
202
- }
203
- }
204
- ]
205
- });
206
- return results;
207
- }
208
- function createVirtualEntry(packageNames) {
209
- return packageNames.map((packageName) => `import '${packageName}';`).join("\n");
210
- }
211
- function extractPackagePath(path7, packageName) {
212
- const normalizedPath = normalizePath(path7);
213
- if (normalizedPath.endsWith("/package.json")) {
214
- return normalizedPath.replace(/\/package\.json$/, "");
215
- }
216
- const match = normalizedPath.match(new RegExp(`(.*?node_modules/${packageName})/.*$`));
217
- if (match) {
218
- return match[1];
219
- }
220
- throw new Error(`Failed to extract path: ${packageName}`);
221
- }
222
- function normalizePath(path7) {
223
- return path7.replace(/\\/g, "/");
224
- }
225
- async function getPackageVersion(packagePath) {
226
- const packageJson = JSON.parse(await fs2.readFile(path2.join(packagePath, "package.json"), "utf-8"));
227
- return packageJson.version;
228
- }
229
94
 
230
95
  // src/utils/createArtifact.ts
231
- import * as fs3 from "fs/promises";
232
- import path3 from "path";
233
96
  import { AppsInTossBundle, PlatformType } from "@apps-in-toss/ait-format";
234
97
 
235
- // src/utils/getUnityMetaDataEnv.ts
236
- function getUnityMetaDataEnv() {
237
- const metaData = process.env.UNITY_METADATA;
238
- if (!metaData) return {};
239
- try {
240
- return JSON.parse(metaData);
241
- } catch (e) {
242
- console.warn("UNITY_METADATA is not a valid JSON:", e);
243
- return {};
244
- }
245
- }
246
-
247
- // src/utils/createArtifact.ts
248
- async function createArtifact(options) {
249
- const { bundleFiles, outfile, appJsonPath, reactNativeVersion, sdkVersion, isGame } = options;
250
- const unityMetaData = getUnityMetaDataEnv();
251
- const appJsonContent = await fs3.readFile(appJsonPath, "utf-8");
252
- const appJson = JSON.parse(appJsonContent);
253
- const runtime = reactNativeVersion.replace(/\./g, "_");
254
- const namedBundleFiles = bundleFiles.map((bundle) => {
255
- const extension = path3.extname(bundle.path);
256
- return {
257
- path: bundle.path,
258
- name: `bundle.${bundle.platform}.${runtime}${extension === ".map" ? ".js.map" : extension}`
259
- };
260
- });
261
- const writer = AppsInTossBundle.writer({
262
- deploymentId: options.deploymentId,
263
- appName: appJson.appName,
264
- createdBy: "@apps-in-toss/plugins"
265
- });
266
- writer.setMetadata({
267
- platform: PlatformType.REACT_NATIVE,
268
- runtimeVersion: reactNativeVersion,
269
- isGame,
270
- sdkVersion,
271
- bundleFiles: namedBundleFiles.map(({ name }) => name),
272
- packageJson: options.packageJson,
273
- extra: { unityMetaData }
274
- });
275
- for (const permission of appJson.permissions ?? []) {
276
- writer.addPermission(permission.name, permission.access);
277
- }
278
- for (const bundle of namedBundleFiles) {
279
- const content = await fs3.readFile(bundle.path);
280
- writer.addFile(bundle.name, new Uint8Array(content));
281
- }
282
- for (const file of options.additionalFilesToZip ?? []) {
283
- const content = await fs3.readFile(file.path);
284
- writer.addFile(file.name, new Uint8Array(content));
285
- }
286
- const buffer = await writer.toBuffer();
287
- await fs3.writeFile(outfile, buffer);
288
- return outfile;
289
- }
290
-
291
- // src/plugins/artifact.ts
292
- function appsInTossCreateArtifact(deploymentId, buildOption) {
293
- const packageRoot = getPackageRoot2();
294
- return {
295
- name: "apps-in-toss:create-artifact",
296
- build: {
297
- order: "post",
298
- handler: async ({ buildResults, appName, cwd }) => {
299
- const buildFailed = buildResults.some(isBuildFailure);
300
- if (buildFailed) {
301
- throw new Error("\uBC88\uB4E4 \uBE4C\uB4DC \uC2E4\uD328");
302
- }
303
- log("\uC571 \uBE4C\uB4DC \uC911...");
304
- const { dependencies, devDependencies } = await collectDependencyVersions(cwd);
305
- const artifactOutfile = await createArtifact({
306
- reactNativeVersion: REACT_NATIVE_VERSION,
307
- deploymentId,
308
- sdkVersion: buildOption.sdkVersion,
309
- isGame: buildOption.isGame,
310
- packageJson: { dependencies, devDependencies },
311
- bundleFiles: buildResults.filter(isBuildSuccess).map(({ outfile, sourcemapOutfile, platform }) => [
312
- {
313
- path: outfile,
314
- platform
315
- },
316
- {
317
- path: sourcemapOutfile,
318
- platform
319
- }
320
- ]).flat(),
321
- outfile: path4.join(cwd, `${appName}.ait`),
322
- appJsonPath: path4.join(packageRoot, ".granite", APP_MANIFEST_NAME)
323
- });
324
- if (!artifactOutfile) {
325
- throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
326
- }
327
- const filename = path4.basename(artifactOutfile);
328
- log(`\u2705 ${pc2.green(`${filename}`)} \uBE4C\uB4DC \uC644\uB8CC`);
329
- }
330
- }
331
- };
332
- }
333
-
334
98
  // src/plugins/build.ts
335
99
  function appsInTossEsbuildConfig(envScript) {
336
100
  return {
@@ -358,8 +122,8 @@ function appsInTossMetroConfig(envScriptPath) {
358
122
  }
359
123
 
360
124
  // src/plugins/compat.ts
361
- import fs4 from "fs";
362
- import path5 from "path";
125
+ import fs2 from "fs";
126
+ import path2 from "path";
363
127
  import { getLocalTempDirectoryPath, getPackageRoot as getPackageRoot3 } from "@granite-js/utils";
364
128
  var nativeModuleProxyContent = `
365
129
  (function () {
@@ -466,8 +230,8 @@ var reactNativeModuleProxyContent = `
466
230
  );
467
231
  `;
468
232
  function bedrockCompat({ isHost }) {
469
- const metroPolyfillContent = path5.join(getLocalTempDirectoryPath(getPackageRoot3()), "metro-native-module-proxy.js");
470
- fs4.writeFileSync(metroPolyfillContent, nativeModuleProxyContent);
233
+ const metroPolyfillContent = path2.join(getLocalTempDirectoryPath(getPackageRoot3()), "metro-native-module-proxy.js");
234
+ fs2.writeFileSync(metroPolyfillContent, nativeModuleProxyContent);
471
235
  return {
472
236
  name: "bedrock-compat-plugin",
473
237
  config: {
@@ -485,6 +249,51 @@ function bedrockCompat({ isHost }) {
485
249
  };
486
250
  }
487
251
 
252
+ // src/plugins/crypto.ts
253
+ import fs3 from "fs";
254
+ import path3 from "path";
255
+ import { getLocalTempDirectoryPath as getLocalTempDirectoryPath2, getPackageRoot as getPackageRoot4 } from "@granite-js/utils";
256
+ var cryptoPolyfillContent = `
257
+ (function (global) {
258
+ if (!global.__decrypt &&
259
+ global.nativeModuleProxy &&
260
+ global.nativeModuleProxy.TossCoreCryptoModule &&
261
+ global.nativeModuleProxy.TossCoreCryptoModule.decrypt) {
262
+ global.__decrypt = global.nativeModuleProxy.TossCoreCryptoModule.decrypt;
263
+ }
264
+ })(
265
+ typeof globalThis !== 'undefined'
266
+ ? globalThis
267
+ : typeof global !== 'undefined'
268
+ ? global
269
+ : typeof window !== 'undefined'
270
+ ? window
271
+ : this
272
+ );
273
+ `;
274
+ function appsInTossCrypto({ isHost }) {
275
+ const metroPolyfillPath = path3.join(getLocalTempDirectoryPath2(getPackageRoot4()), "metro-crypto-polyfill.js");
276
+ fs3.writeFileSync(metroPolyfillPath, cryptoPolyfillContent);
277
+ return {
278
+ name: "apps-in-toss-crypto-plugin",
279
+ config: {
280
+ ...isHost ? {
281
+ esbuild: {
282
+ banner: {
283
+ js: cryptoPolyfillContent
284
+ }
285
+ }
286
+ } : {},
287
+ metro: {
288
+ serializer: {
289
+ // Metro 단일 번들 환경에서는 Host/Remote 구분 없이 항상 polyfill 필요
290
+ getPolyfills: () => [metroPolyfillPath]
291
+ }
292
+ }
293
+ }
294
+ };
295
+ }
296
+
488
297
  // src/utils/createServerPermissionsMiddleware.ts
489
298
  function createServerPermissionsMiddleware(permissions) {
490
299
  const parsedPermissions = parsePermissions(permissions);
@@ -566,19 +375,21 @@ function requireMicroFrontendRuntime() {
566
375
  // src/utils/generateDeploymentId.ts
567
376
  import { uuidv7 } from "uuidv7";
568
377
  function generateDeploymentId() {
378
+ if (process.env.AIT_DEPLOYMENT_ID != null && process.env.AIT_DEPLOYMENT_ID.length > 0) {
379
+ return process.env.AIT_DEPLOYMENT_ID;
380
+ }
569
381
  return uuidv7();
570
382
  }
571
383
 
572
- // src/utils/getSdkVersion.ts
573
- function getSdkVersion() {
574
- const packageJson = require_package();
575
- return packageJson.version;
384
+ // src/utils/getReactNativeTarget.ts
385
+ function getReactNativeTarget(target) {
386
+ return target ?? REACT_NATIVE_VERSION;
576
387
  }
577
388
 
578
389
  // src/utils/setupRuntimeSetupScript.ts
579
- import fs5 from "node:fs";
580
- import path6 from "node:path";
581
- import { getPackageRoot as getPackageRoot4 } from "@granite-js/utils";
390
+ import fs4 from "node:fs";
391
+ import path4 from "node:path";
392
+ import { getPackageRoot as getPackageRoot5 } from "@granite-js/utils";
582
393
  import { transformSync } from "esbuild";
583
394
  function setupHostRuntimeSetupScript(metadata) {
584
395
  const script = getRuntimeSetupScript(metadata, HOST_CONTEXT_IDENTIFIER);
@@ -608,15 +419,15 @@ function getRuntimeSetupScript(metadata, identifier) {
608
419
  }).code;
609
420
  }
610
421
  function writeRuntimeSetupScript(script) {
611
- const packageRoot = getPackageRoot4();
612
- const granitePath = path6.join(packageRoot, ".granite");
422
+ const packageRoot = getPackageRoot5();
423
+ const granitePath = path4.join(packageRoot, ".granite");
613
424
  try {
614
- fs5.accessSync(granitePath);
425
+ fs4.accessSync(granitePath);
615
426
  } catch {
616
- fs5.mkdirSync(granitePath, { recursive: true });
427
+ fs4.mkdirSync(granitePath, { recursive: true });
617
428
  }
618
- const envFilePath = path6.join(granitePath, ".apps-in-toss.env.js");
619
- fs5.writeFileSync(envFilePath, script, "utf-8");
429
+ const envFilePath = path4.join(granitePath, ".apps-in-toss.env.js");
430
+ fs4.writeFileSync(envFilePath, script, "utf-8");
620
431
  return envFilePath;
621
432
  }
622
433
  function getBedrockCompatScript() {
@@ -681,17 +492,18 @@ function getMicroFrontendCompatScript() {
681
492
 
682
493
  // src/appsInTossHost.ts
683
494
  var PERMISSIONS = [];
495
+ function getAppsInTossHostBuildPlugins() {
496
+ const plugins = [appsInTossDevServer({ permissions: PERMISSIONS })];
497
+ return plugins;
498
+ }
684
499
  function appsInTossHost(options) {
685
500
  const deploymentId = generateDeploymentId();
501
+ const reactNativeTarget = getReactNativeTarget(options.target);
502
+ const reactNativeVersion = reactNativeTarget.startsWith("0.72") ? "0.72" : "0.84";
686
503
  const { contents, path: envFilePath } = setupHostRuntimeSetupScript({
687
504
  deploymentId,
688
505
  environment: getHostEnvironment()
689
506
  });
690
- const sdkVersion = getSdkVersion();
691
- const buildOptions = {
692
- sdkVersion,
693
- isGame: false
694
- };
695
507
  return [
696
508
  requireMicroFrontendRuntime(),
697
509
  microFrontend({
@@ -700,19 +512,20 @@ function appsInTossHost(options) {
700
512
  host: options?.remote?.host ?? "localhost",
701
513
  port: options?.remote?.port ?? 8082
702
514
  },
703
- shared: SHRED_PACKAGES.reduce(
704
- (prev, curr) => ({ ...prev, [curr]: { eager: true } }),
705
- {}
706
- )
515
+ shared: getSharedPackages({
516
+ reactNativeVersion
517
+ }).reduce((prev, curr) => ({ ...prev, [curr]: { eager: true } }), {})
707
518
  }),
519
+ reactNativeCompatibilityPlugin({ target: reactNativeTarget, rootDir: getPackageRoot6() }),
520
+ reactNativeReverseCompatibilityPlugin({ target: reactNativeTarget, rootDir: getPackageRoot6(), isHost: true }),
708
521
  appsInTossAppJson({ permissions: PERMISSIONS }),
709
- appsInTossDevServer({ permissions: PERMISSIONS }),
710
- appsInTossCreateArtifact(deploymentId, buildOptions),
522
+ ...getAppsInTossHostBuildPlugins(),
711
523
  appsInTossEsbuildConfig(contents),
712
524
  appsInTossMetroConfig(envFilePath),
713
525
  bedrockCompat({ isHost: true }),
526
+ reactNativeVersion === "0.84" ? appsInTossCrypto({ isHost: true }) : null,
714
527
  sentry({ useClient: false })
715
- ];
528
+ ].filter((plugin) => plugin !== null);
716
529
  }
717
530
  function getHostEnvironment() {
718
531
  const environment = process.env.HOST_ENV;
@@ -725,5 +538,6 @@ function getHostEnvironment() {
725
538
  }
726
539
  }
727
540
  export {
728
- appsInTossHost
541
+ appsInTossHost,
542
+ getAppsInTossHostBuildPlugins
729
543
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@apps-in-toss/plugins",
3
3
  "type": "module",
4
- "version": "1.14.0",
4
+ "version": "2.0.0",
5
5
  "description": "The plugins for Apps In Toss",
6
6
  "scripts": {
7
7
  "test": "vitest --run",
@@ -38,11 +38,12 @@
38
38
  "vitest": "^3.2.4"
39
39
  },
40
40
  "dependencies": {
41
- "@apps-in-toss/ait-format": "^1.0.0",
42
- "@granite-js/plugin-core": "0.1.31",
43
- "@granite-js/plugin-micro-frontend": "0.1.31",
44
- "@granite-js/plugin-sentry": "0.1.31",
45
- "@granite-js/utils": "0.1.31",
41
+ "@apps-in-toss/ait-format": "1.0.0",
42
+ "@apps-in-toss/plugin-compat": "2.0.0",
43
+ "@granite-js/plugin-core": "1.0.4",
44
+ "@granite-js/plugin-micro-frontend": "1.0.4",
45
+ "@granite-js/plugin-sentry": "1.0.4",
46
+ "@granite-js/utils": "1.0.4",
46
47
  "archiver": "^7.0.1",
47
48
  "connect": "^3.7.0",
48
49
  "esbuild": "0.25.5",