@apps-in-toss/web-framework 0.0.0-dev.1740740040772 → 0.0.0-dev.1740746154601
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/chunk-DI2VGQ6M.js +53 -0
- package/dist/chunk-HL7M3JLX.js +53 -0
- package/dist/chunk-I3ZDGLIW.js +19 -0
- package/dist/chunk-TZCMTMV7.js +38 -0
- package/dist/cli/index.cjs +644 -0
- package/dist/cli/index.d.cts +2 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +592 -0
- package/dist/cli.cjs +560 -0
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +509 -0
- package/dist/closeView.d.ts +23 -0
- package/dist/generateHapticFeedback.d.ts +51 -0
- package/dist/getDeviceId.d.ts +31 -0
- package/dist/getLocale.d.ts +30 -0
- package/dist/getNetworkStatus.d.ts +54 -0
- package/dist/getSchemeUri.d.ts +25 -0
- package/dist/index.cjs +18 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.js +1 -1
- package/dist/setScreenAwakeMode.d.ts +68 -0
- package/dist/setSecureScreen.d.ts +33 -0
- package/dist/share.d.ts +36 -0
- package/package.json +9 -9
- package/dist/chunk-SHV3PFAA.js +0 -169
package/dist/cli.js
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
__dirname,
|
|
4
|
+
__require,
|
|
5
|
+
loadConfig
|
|
6
|
+
} from "./chunk-HL7M3JLX.js";
|
|
7
|
+
|
|
8
|
+
// src/cli.ts
|
|
9
|
+
import { Cli } from "clipanion";
|
|
10
|
+
|
|
11
|
+
// src/BuildCommand/BuildCommand.ts
|
|
12
|
+
import { Command, Option } from "clipanion";
|
|
13
|
+
import picocolors from "picocolors";
|
|
14
|
+
|
|
15
|
+
// src/BuildCommand/build.ts
|
|
16
|
+
import fs from "fs";
|
|
17
|
+
import path from "path";
|
|
18
|
+
import { createArtifact } from "@apps-in-toss/framework/cli-presets";
|
|
19
|
+
import * as mpack from "@react-native-bedrock/mpack-next";
|
|
20
|
+
import { statusPlugin } from "@react-native-bedrock/mpack-next/plugins";
|
|
21
|
+
import { execa } from "execa";
|
|
22
|
+
import presets from "react-native-bedrock/presets";
|
|
23
|
+
|
|
24
|
+
// src/utils/getPackageManager.ts
|
|
25
|
+
function getPackageManager({ isExecutor = false } = {}) {
|
|
26
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
27
|
+
const packageManagerCommands = {
|
|
28
|
+
npm: isExecutor ? "npx" : "npm",
|
|
29
|
+
pnpm: "pnpm",
|
|
30
|
+
yarn: "yarn"
|
|
31
|
+
};
|
|
32
|
+
if (!userAgent) {
|
|
33
|
+
return {
|
|
34
|
+
packageManager: packageManagerCommands["npm"],
|
|
35
|
+
version: "0.0.0"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const [packageManagerInfo] = userAgent.match(/(\w+)\/(\d+\.\d+\.\d+)/) || [];
|
|
39
|
+
const [packageManager, version2] = packageManagerInfo?.split("/") ?? ["npm", null];
|
|
40
|
+
if (!packageManager) {
|
|
41
|
+
return {
|
|
42
|
+
packageManager: packageManagerCommands["npm"],
|
|
43
|
+
version: "0.0.0"
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
packageManager: packageManagerCommands[packageManager],
|
|
48
|
+
version: version2 ?? "0.0.0"
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/BuildCommand/build.ts
|
|
53
|
+
async function build({ distDirname, cache }) {
|
|
54
|
+
const config = await loadConfig();
|
|
55
|
+
const rootDir = process.cwd();
|
|
56
|
+
const reactNativeProjectDir = path.resolve(__dirname, "..", "react-native");
|
|
57
|
+
const projectRootTmp = path.resolve(process.cwd(), ".apps-in-toss");
|
|
58
|
+
await fs.promises.mkdir(projectRootTmp, { recursive: true });
|
|
59
|
+
await fs.promises.writeFile(
|
|
60
|
+
path.join(projectRootTmp, "metadata.json"),
|
|
61
|
+
JSON.stringify({ appName: config.appName, webPort: config.web.port })
|
|
62
|
+
);
|
|
63
|
+
const appName = config.appName;
|
|
64
|
+
const { packageManager } = getPackageManager({ isExecutor: true });
|
|
65
|
+
const distDir = path.join(rootDir, distDirname);
|
|
66
|
+
const webDistDir = path.join(distDir, "web");
|
|
67
|
+
await fs.promises.rm(distDir, { recursive: true, force: true });
|
|
68
|
+
await execa(packageManager, config.web.commands.build.split(" "), {
|
|
69
|
+
cwd: process.cwd(),
|
|
70
|
+
stdio: "inherit"
|
|
71
|
+
});
|
|
72
|
+
await fs.promises.mkdir(webDistDir, { recursive: true });
|
|
73
|
+
const items = await fs.promises.readdir(distDir);
|
|
74
|
+
for (const item of items) {
|
|
75
|
+
const src = path.join(distDir, item);
|
|
76
|
+
const dest = path.join(webDistDir, item);
|
|
77
|
+
if (src === webDistDir) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
await fs.promises.rename(src, dest);
|
|
81
|
+
}
|
|
82
|
+
const buildResults = await mpack.runBundle({
|
|
83
|
+
clean: false,
|
|
84
|
+
metafile: false,
|
|
85
|
+
dev: false,
|
|
86
|
+
rootDir: reactNativeProjectDir,
|
|
87
|
+
cache,
|
|
88
|
+
plugins: [statusPlugin],
|
|
89
|
+
config: {
|
|
90
|
+
appName,
|
|
91
|
+
services: {
|
|
92
|
+
sentry: {
|
|
93
|
+
enabled: false
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
concurrency: 2,
|
|
97
|
+
tasks: [
|
|
98
|
+
{
|
|
99
|
+
tag: `${appName}-ios`,
|
|
100
|
+
presets: [presets.service()],
|
|
101
|
+
build: {
|
|
102
|
+
babel: {
|
|
103
|
+
conditions: [(_code) => _code.includes("Ait")],
|
|
104
|
+
plugins: [
|
|
105
|
+
[
|
|
106
|
+
__require.resolve("@apps-in-toss/babel-plugin-json"),
|
|
107
|
+
{ jsonPath: "./.apps-in-toss/metadata.json", identifierName: "Ait" }
|
|
108
|
+
]
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
platform: "ios",
|
|
112
|
+
entry: path.join(reactNativeProjectDir, "src", "_app.tsx"),
|
|
113
|
+
outfile: path.join(distDir, `${appName}.ios.js`)
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
tag: `${appName}-android`,
|
|
118
|
+
presets: [presets.service()],
|
|
119
|
+
build: {
|
|
120
|
+
babel: {
|
|
121
|
+
conditions: [(_code) => _code.includes("Ait")],
|
|
122
|
+
plugins: [
|
|
123
|
+
[
|
|
124
|
+
__require.resolve("@apps-in-toss/babel-plugin-json"),
|
|
125
|
+
{ jsonPath: "./.apps-in-toss/metadata.json", identifierName: "Ait" }
|
|
126
|
+
]
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
platform: "android",
|
|
130
|
+
entry: path.join(reactNativeProjectDir, "src", "_app.tsx"),
|
|
131
|
+
outfile: path.join(distDir, `${appName}.android.js`)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const artifactOutfile = await createArtifact({
|
|
138
|
+
buildResults,
|
|
139
|
+
rootDir,
|
|
140
|
+
reactNativeProjectDir,
|
|
141
|
+
webOutDir: webDistDir
|
|
142
|
+
});
|
|
143
|
+
if (!artifactOutfile) {
|
|
144
|
+
throw new Error("\uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.");
|
|
145
|
+
}
|
|
146
|
+
return artifactOutfile;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/constants.ts
|
|
150
|
+
var APP_MANIFEST_NAME = "app.json";
|
|
151
|
+
var DEFAULT_DIST_DIR = "dist";
|
|
152
|
+
var API_BASE_URL = "https://apps-in-toss.toss.im/console";
|
|
153
|
+
var DEFAULT_LOCALHOST_PORT = 8081;
|
|
154
|
+
var DEFAULT_HOST = "localhost";
|
|
155
|
+
|
|
156
|
+
// src/BuildCommand/BuildCommand.ts
|
|
157
|
+
var BuildCommand = class extends Command {
|
|
158
|
+
static paths = [[`build`]];
|
|
159
|
+
static usage = Command.Usage({
|
|
160
|
+
category: "Build",
|
|
161
|
+
description: "Apps In Toss \uBE4C\uB4DC \uC544\uD2F0\uD329\uD2B8\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4",
|
|
162
|
+
examples: [["\uBE4C\uB4DC \uC544\uD2F0\uD329\uD2B8 \uC0DD\uC131\uD558\uAE30", "ait build"]]
|
|
163
|
+
});
|
|
164
|
+
cache = Option.Boolean("--cache", true);
|
|
165
|
+
async execute() {
|
|
166
|
+
const artifactOutfile = await build({
|
|
167
|
+
distDirname: DEFAULT_DIST_DIR,
|
|
168
|
+
cache: this.cache
|
|
169
|
+
});
|
|
170
|
+
console.log(`
|
|
171
|
+
${picocolors.blue(artifactOutfile)}
|
|
172
|
+
`);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/DeployCommand/DeployCommand.ts
|
|
177
|
+
import assert from "assert";
|
|
178
|
+
import path2 from "path";
|
|
179
|
+
import * as p from "@clack/prompts";
|
|
180
|
+
import { Command as Command2, Option as Option2 } from "clipanion";
|
|
181
|
+
import Debug2 from "debug";
|
|
182
|
+
import picocolors2 from "picocolors";
|
|
183
|
+
|
|
184
|
+
// src/DeployCommand/upload.ts
|
|
185
|
+
import * as fs2 from "fs";
|
|
186
|
+
import Debug from "debug";
|
|
187
|
+
var debug = Debug("cli:deploy");
|
|
188
|
+
async function uploadArtifact(config) {
|
|
189
|
+
debug("uploadArtifact", config);
|
|
190
|
+
const response = await fetch(
|
|
191
|
+
`${API_BASE_URL}/api-public/v3/appsintossconsole/bundles/${config.appName}/sandbox/upload`,
|
|
192
|
+
{
|
|
193
|
+
method: "POST",
|
|
194
|
+
headers: {
|
|
195
|
+
"Content-Type": "application/octet-stream",
|
|
196
|
+
"X-Ait-Console-Api-Key": config.apiKey
|
|
197
|
+
},
|
|
198
|
+
body: fs2.createReadStream(config.artifactPath),
|
|
199
|
+
duplex: "half"
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
return handleResponse(response);
|
|
203
|
+
}
|
|
204
|
+
async function handleResponse(response) {
|
|
205
|
+
debug(`Response ${response.status} ${response.statusText}`);
|
|
206
|
+
if (!response.ok) {
|
|
207
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
208
|
+
}
|
|
209
|
+
const data = await response.clone().json();
|
|
210
|
+
debug("uploadArtifact response", data);
|
|
211
|
+
if (data.resultType !== "SUCCESS") {
|
|
212
|
+
const errorCode = data?.error?.errorCode ?? "-1";
|
|
213
|
+
const errorReason = data?.error.reason ?? "unknown";
|
|
214
|
+
throw new Error(`${errorReason} (Code: ${errorCode})`);
|
|
215
|
+
}
|
|
216
|
+
const result = data.success;
|
|
217
|
+
return result.deploymentId;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/utils/readZipContent.ts
|
|
221
|
+
import yauzl from "yauzl";
|
|
222
|
+
function readZipContent(zipPath, fileName) {
|
|
223
|
+
return new Promise((resolve, reject) => {
|
|
224
|
+
yauzl.open(zipPath, { lazyEntries: true }, (error, zipFile) => {
|
|
225
|
+
if (error) {
|
|
226
|
+
reject(error);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
zipFile.on("entry", (entry) => {
|
|
230
|
+
if (entry.fileName === fileName) {
|
|
231
|
+
zipFile.openReadStream(entry, (error2, readStream) => {
|
|
232
|
+
if (error2) {
|
|
233
|
+
throw error2;
|
|
234
|
+
}
|
|
235
|
+
let fileData = "";
|
|
236
|
+
readStream.on("data", (chunk) => fileData += chunk.toString("utf8")).on("end", () => {
|
|
237
|
+
zipFile.close();
|
|
238
|
+
resolve(fileData);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
} else {
|
|
242
|
+
zipFile.readEntry();
|
|
243
|
+
}
|
|
244
|
+
}).on("end", () => {
|
|
245
|
+
zipFile.close();
|
|
246
|
+
reject(new Error(`'${fileName}' not found in zip file`));
|
|
247
|
+
}).on("error", (error2) => {
|
|
248
|
+
zipFile.close();
|
|
249
|
+
reject(error2);
|
|
250
|
+
});
|
|
251
|
+
zipFile.readEntry();
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/DeployCommand/DeployCommand.ts
|
|
257
|
+
var debug2 = Debug2("cli:deploy");
|
|
258
|
+
var DeployCommand = class extends Command2 {
|
|
259
|
+
static paths = [["deploy"]];
|
|
260
|
+
apiKey = Option2.String("--api-key", {
|
|
261
|
+
required: false,
|
|
262
|
+
description: "\uC54C\uD30C \uBC30\uD3EC\uB97C \uC704\uD55C API \uD0A4"
|
|
263
|
+
});
|
|
264
|
+
async execute() {
|
|
265
|
+
const apiKey = this.apiKey || await p.password({
|
|
266
|
+
message: "\uC571\uC778\uD1A0\uC2A4 \uBC30\uD3EC API \uD0A4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",
|
|
267
|
+
validate: (value) => {
|
|
268
|
+
if (value.length === 0) {
|
|
269
|
+
return "API \uD0A4\uB294 \uD544\uC218 \uC785\uB825 \uD56D\uBAA9\uC785\uB2C8\uB2E4.";
|
|
270
|
+
}
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
if (p.isCancel(apiKey)) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
const artifactOutfile = await build({
|
|
279
|
+
distDirname: DEFAULT_DIST_DIR,
|
|
280
|
+
cache: false
|
|
281
|
+
});
|
|
282
|
+
const rootDir = process.cwd();
|
|
283
|
+
const resolvedArtifactPath = path2.resolve(rootDir, artifactOutfile);
|
|
284
|
+
const appIdentifier = await readZipContent(resolvedArtifactPath, APP_MANIFEST_NAME).then((rawAppManifest) => {
|
|
285
|
+
const appManifest = JSON.parse(rawAppManifest);
|
|
286
|
+
const appIdentifier2 = appManifest.appName;
|
|
287
|
+
assert(typeof appIdentifier2 === "string", "invalid appName");
|
|
288
|
+
return appIdentifier2;
|
|
289
|
+
}).catch((error) => {
|
|
290
|
+
debug2("invalid ait file", error);
|
|
291
|
+
throw new Error("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 ait \uD30C\uC77C\uC785\uB2C8\uB2E4");
|
|
292
|
+
});
|
|
293
|
+
let deploymentId = null;
|
|
294
|
+
const colorAppName = picocolors2.underline(picocolors2.cyan(appIdentifier));
|
|
295
|
+
await p.tasks([
|
|
296
|
+
{
|
|
297
|
+
title: `${colorAppName} \uC571 \uBC30\uD3EC \uC911...`,
|
|
298
|
+
task: async () => {
|
|
299
|
+
deploymentId = await uploadArtifact({
|
|
300
|
+
artifactPath: resolvedArtifactPath,
|
|
301
|
+
appName: appIdentifier,
|
|
302
|
+
apiKey
|
|
303
|
+
});
|
|
304
|
+
return `${colorAppName} \uBC30\uD3EC\uAC00 \uC644\uB8CC\uB418\uC5C8\uC5B4\uC694`;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
]);
|
|
308
|
+
if (deploymentId) {
|
|
309
|
+
p.note(`Deployment ID: ${picocolors2.underline(picocolors2.green(deploymentId))}`);
|
|
310
|
+
}
|
|
311
|
+
} catch (error) {
|
|
312
|
+
if (error instanceof Error) {
|
|
313
|
+
p.log.error(error.message);
|
|
314
|
+
} else {
|
|
315
|
+
console.error(error);
|
|
316
|
+
}
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/DevCommand/DevCommand.ts
|
|
323
|
+
import fs3 from "fs";
|
|
324
|
+
import path3 from "path";
|
|
325
|
+
import * as mpack2 from "@react-native-bedrock/mpack-next";
|
|
326
|
+
import { Command as Command3, Option as Option3 } from "clipanion";
|
|
327
|
+
import { execa as execa2 } from "execa";
|
|
328
|
+
import presets2 from "react-native-bedrock/presets";
|
|
329
|
+
var DevCommand = class extends Command3 {
|
|
330
|
+
static paths = [[`dev`]];
|
|
331
|
+
static usage = Command3.Usage({
|
|
332
|
+
category: "Development",
|
|
333
|
+
description: "AppsInToss \uAC1C\uBC1C \uC11C\uBC84\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4",
|
|
334
|
+
examples: [["\uAC1C\uBC1C \uC11C\uBC84 \uC2E4\uD589\uD558\uAE30", "ait dev"]]
|
|
335
|
+
});
|
|
336
|
+
host = Option3.String("--host");
|
|
337
|
+
port = Option3.String("--port");
|
|
338
|
+
async execute() {
|
|
339
|
+
const config = await loadConfig();
|
|
340
|
+
const serverOptions = {
|
|
341
|
+
host: this.host,
|
|
342
|
+
port: this.port ? parseInt(this.port, 10) : void 0
|
|
343
|
+
};
|
|
344
|
+
const cwd = path3.resolve(__dirname, "..", "react-native");
|
|
345
|
+
const projectRootTmp = path3.resolve(process.cwd(), ".apps-in-toss");
|
|
346
|
+
await fs3.promises.mkdir(projectRootTmp, { recursive: true });
|
|
347
|
+
await fs3.promises.writeFile(
|
|
348
|
+
path3.join(projectRootTmp, "metadata.json"),
|
|
349
|
+
JSON.stringify({ appName: config.appName, webPort: config.web.port })
|
|
350
|
+
);
|
|
351
|
+
const appName = config.appName;
|
|
352
|
+
await mpack2.runServer({
|
|
353
|
+
host: serverOptions.host,
|
|
354
|
+
port: serverOptions.port,
|
|
355
|
+
enableEmbeddedReactDevTools: true,
|
|
356
|
+
enableRouterGen: false,
|
|
357
|
+
onServerReady: async () => {
|
|
358
|
+
this.context.stdout.write(
|
|
359
|
+
`Server is running on http://${serverOptions.host || DEFAULT_HOST}:${serverOptions.port || DEFAULT_LOCALHOST_PORT}
|
|
360
|
+
`
|
|
361
|
+
);
|
|
362
|
+
const { packageManager } = getPackageManager({ isExecutor: true });
|
|
363
|
+
await execa2(packageManager, config.web.commands.dev.split(" "), {
|
|
364
|
+
cwd: process.cwd(),
|
|
365
|
+
stdio: "inherit"
|
|
366
|
+
});
|
|
367
|
+
},
|
|
368
|
+
cwd,
|
|
369
|
+
config: {
|
|
370
|
+
appName,
|
|
371
|
+
services: {
|
|
372
|
+
sentry: {
|
|
373
|
+
enabled: false
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
devServer: {
|
|
377
|
+
presets: [presets2.service()],
|
|
378
|
+
build: {
|
|
379
|
+
entry: "./src/_app.tsx"
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
tasks: []
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/InitCommand/InitCommand.ts
|
|
389
|
+
import fs4 from "fs";
|
|
390
|
+
import path4 from "path";
|
|
391
|
+
import * as p2 from "@clack/prompts";
|
|
392
|
+
import { Command as Command4 } from "clipanion";
|
|
393
|
+
import { kebabCase } from "es-toolkit";
|
|
394
|
+
|
|
395
|
+
// src/InitCommand/templates/index.tsx
|
|
396
|
+
var CONFIG_TEMPLATE = `import { defineConfig } from '@apps-in-toss/web-framework';
|
|
397
|
+
|
|
398
|
+
export default defineConfig({
|
|
399
|
+
appName: '%%appName%%',
|
|
400
|
+
web: {
|
|
401
|
+
port: %%webPort%%,
|
|
402
|
+
commands: {
|
|
403
|
+
dev: '%%webDevCommand%%',
|
|
404
|
+
build: '%%webBuildCommand%%',
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
`;
|
|
409
|
+
|
|
410
|
+
// src/utils/transformTemplate.ts
|
|
411
|
+
function transformTemplate(templateString, values) {
|
|
412
|
+
let result = templateString;
|
|
413
|
+
for (const key in values) {
|
|
414
|
+
const placeholder = `%%${key}%%`;
|
|
415
|
+
result = result.replace(new RegExp(placeholder, "g"), values[key]);
|
|
416
|
+
}
|
|
417
|
+
return result;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// src/InitCommand/InitCommand.ts
|
|
421
|
+
var InitCommand = class extends Command4 {
|
|
422
|
+
static paths = [[`init`]];
|
|
423
|
+
async execute() {
|
|
424
|
+
p2.intro("\u{1F680} \uC571 \uCD08\uAE30\uD654\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4");
|
|
425
|
+
const appName = await p2.text({
|
|
426
|
+
message: "Enter app name",
|
|
427
|
+
validate: (value) => {
|
|
428
|
+
if (!value) {
|
|
429
|
+
return "\uC571 \uC774\uB984\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694";
|
|
430
|
+
}
|
|
431
|
+
const kebabCaseValue = kebabCase(value);
|
|
432
|
+
if (value !== kebabCaseValue) {
|
|
433
|
+
return `\uC571 \uC774\uB984\uC740 \uCF00\uBC25-\uCF00\uC774\uC2A4 \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4 (\uC608\uC2DC: ${kebabCaseValue})`;
|
|
434
|
+
}
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
if (p2.isCancel(appName)) {
|
|
439
|
+
p2.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
p2.log.step(`\uC571 \uC774\uB984\uC774 '${appName}'\uC73C\uB85C \uC124\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4`);
|
|
443
|
+
const webPort = await p2.text({
|
|
444
|
+
message: "Enter web port",
|
|
445
|
+
placeholder: "5173",
|
|
446
|
+
defaultValue: "5173"
|
|
447
|
+
});
|
|
448
|
+
if (p2.isCancel(webPort)) {
|
|
449
|
+
p2.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
p2.log.step("package.json \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC124\uC815\uD558\uB294 \uC911...");
|
|
453
|
+
const packageJson = await fs4.promises.readFile(path4.join(process.cwd(), "package.json"), {
|
|
454
|
+
encoding: "utf-8"
|
|
455
|
+
});
|
|
456
|
+
const scripts = JSON.parse(packageJson);
|
|
457
|
+
const original = {
|
|
458
|
+
dev: scripts?.scripts?.dev || scripts?.scripts?.start,
|
|
459
|
+
build: scripts?.scripts?.build
|
|
460
|
+
};
|
|
461
|
+
scripts.scripts.dev = "ait dev";
|
|
462
|
+
scripts.scripts.build = "ait build";
|
|
463
|
+
scripts.scripts.deploy = "ait deploy";
|
|
464
|
+
await fs4.promises.writeFile(path4.join(process.cwd(), "package.json"), JSON.stringify(scripts, null, 2), {
|
|
465
|
+
encoding: "utf-8"
|
|
466
|
+
});
|
|
467
|
+
p2.log.step("apps-in-toss.config.web.ts \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
|
|
468
|
+
const config = transformTemplate(CONFIG_TEMPLATE, {
|
|
469
|
+
appName,
|
|
470
|
+
webPort,
|
|
471
|
+
webDevCommand: original.dev === "ait dev" ? "" : original.dev,
|
|
472
|
+
webBuildCommand: original.build === "ait build" ? "" : original.build
|
|
473
|
+
});
|
|
474
|
+
await fs4.promises.writeFile(path4.join(process.cwd(), "apps-in-toss.config.web.ts"), config, {
|
|
475
|
+
encoding: "utf-8"
|
|
476
|
+
});
|
|
477
|
+
p2.log.step(".gitignore \uD30C\uC77C\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911...");
|
|
478
|
+
await fs4.promises.appendFile(path4.join(process.cwd(), ".gitignore"), "\n.apps-in-toss\n");
|
|
479
|
+
p2.log.step("app.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
|
|
480
|
+
await fs4.promises.writeFile(
|
|
481
|
+
path4.join(process.cwd(), "app.json"),
|
|
482
|
+
JSON.stringify({
|
|
483
|
+
clientId: "",
|
|
484
|
+
appName,
|
|
485
|
+
permissions: []
|
|
486
|
+
}),
|
|
487
|
+
{
|
|
488
|
+
encoding: "utf-8"
|
|
489
|
+
}
|
|
490
|
+
);
|
|
491
|
+
p2.outro("\u2728 \uCD08\uAE30\uD654\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!");
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
// package.json
|
|
496
|
+
var version = "0.1.6-next.6";
|
|
497
|
+
|
|
498
|
+
// src/cli.ts
|
|
499
|
+
var cli = new Cli({
|
|
500
|
+
binaryLabel: "apps-in-toss",
|
|
501
|
+
binaryName: "apps-in-toss",
|
|
502
|
+
binaryVersion: version,
|
|
503
|
+
enableCapture: true
|
|
504
|
+
});
|
|
505
|
+
cli.register(InitCommand);
|
|
506
|
+
cli.register(DevCommand);
|
|
507
|
+
cli.register(BuildCommand);
|
|
508
|
+
cli.register(DeployCommand);
|
|
509
|
+
cli.runExit(process.argv.slice(2));
|
package/dist/closeView.d.ts
CHANGED
|
@@ -1 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
* @tag BedrockModule
|
|
4
|
+
* @category BedrockModules
|
|
5
|
+
* @kind function
|
|
6
|
+
* @name closeView
|
|
7
|
+
* @description 현재 화면을 닫는 함수에요. 예를 들어, "닫기" 버튼을 눌러서 서비스를 종료할 때 사용할 수 있어요.
|
|
8
|
+
* @returns {Promise<void>}
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ### 닫기 버튼을 눌러 화면 닫기
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
*
|
|
15
|
+
* import { closeView } from '@apps-in-toss/web-framework';
|
|
16
|
+
*
|
|
17
|
+
* function CloseButton() {
|
|
18
|
+
* return <input type="button" value="닫기" onClick={closeView} />;
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function closeView(): Promise<void>;
|
|
23
|
+
|
|
1
24
|
export {};
|
|
@@ -1 +1,52 @@
|
|
|
1
|
+
export type HapticFeedbackType = "tickWeak" | "tap" | "tickMedium" | "softMedium" | "basicWeak" | "basicMedium" | "success" | "error" | "wiggle" | "confetti";
|
|
2
|
+
/**
|
|
3
|
+
* @public
|
|
4
|
+
* @tag HapticFeedbackType
|
|
5
|
+
* @category Types
|
|
6
|
+
* @name HapticFeedbackOptions
|
|
7
|
+
* @description
|
|
8
|
+
* generateHapticFeedback 함수에 전달할 햅틱진동의 타입을 나타내요. 진동타입의 종류는 다음과 같아요.
|
|
9
|
+
* ```typescript
|
|
10
|
+
* type HapticFeedbackType =
|
|
11
|
+
* | "tickWeak"
|
|
12
|
+
* | "tap"
|
|
13
|
+
* | "tickMedium"
|
|
14
|
+
* | "softMedium"
|
|
15
|
+
* | "basicWeak"
|
|
16
|
+
* | "basicMedium"
|
|
17
|
+
* | "success"
|
|
18
|
+
* | "error"
|
|
19
|
+
* | "wiggle"
|
|
20
|
+
* | "confetti";
|
|
21
|
+
* ```
|
|
22
|
+
* @typedef { type: HapticFeedbackType } HapticFeedbackOptions
|
|
23
|
+
* @typedef { "tickWeak" | "tap" | "tickMedium" | "softMedium" | "basicWeak" | "basicMedium" | "success" | "error" | "wiggle" | "confetti" } HapticFeedbackType
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
export interface HapticFeedbackOptions {
|
|
27
|
+
type: HapticFeedbackType;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
* @tag BedrockModule
|
|
32
|
+
* @category BedrockModules
|
|
33
|
+
* @kind function
|
|
34
|
+
* @name generateHapticFeedback
|
|
35
|
+
* @description 디바이스에 햅틱 진동을 일으키는 함수예요. 예를 들어, 버튼 터치나 화면전환에 드라마틱한 효과를 주고 싶을 때 사용할 수 있어요. [HapticFeedbackOptions](../Types/HapticFeedbackOptions.html)에서 진동타입을 확인해 보세요.
|
|
36
|
+
* @returns {void}
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ### 버튼을 눌러 햅틱 일으키기
|
|
40
|
+
*
|
|
41
|
+
* ```tsx
|
|
42
|
+
*
|
|
43
|
+
* import { generateHapticFeedback } from '@apps-in-toss/web-framework';
|
|
44
|
+
*
|
|
45
|
+
* function GenerateHapticFeedback() {
|
|
46
|
+
* return <input type="button" value="햅틱" onClick={() => { generateHapticFeedback( { type: "tickWeak"}) }} />;
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function generateHapticFeedback(options: HapticFeedbackOptions): Promise<void>;
|
|
51
|
+
|
|
1
52
|
export {};
|
package/dist/getDeviceId.d.ts
CHANGED
|
@@ -1 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
* @tag BedrockModule
|
|
4
|
+
* @category BedrockModules
|
|
5
|
+
* @kind function
|
|
6
|
+
* @name getDeviceId
|
|
7
|
+
* @description
|
|
8
|
+
* 사용 중인 기기의 고유 식별자를 문자열로 반환해요.
|
|
9
|
+
*
|
|
10
|
+
* 이 함수는 현재 사용 중인 기기의 고유 식별자를 문자열로 반환해요. 기기별로 설정이나 데이터를 저장하거나 사용자의 기기를 식별해서 로그를 기록하고 분석하는 데 사용할 수 있어요. 같은 사용자의 여러 기기를 구분하는 데도 유용해요.
|
|
11
|
+
*
|
|
12
|
+
* @returns {string} 기기의 고유 식별자를 나타내는 문자열이에요.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ### 기기 고유 식별자 가져오기
|
|
16
|
+
*
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { getDeviceId } from '@apps-in-toss/web-framework';
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* function MyPage() {
|
|
22
|
+
* const id = getDeviceId();
|
|
23
|
+
*
|
|
24
|
+
* return (
|
|
25
|
+
* <span>사용자의 기기 고유 식별자: {id}</span>
|
|
26
|
+
* );
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function getDeviceId(): string;
|
|
31
|
+
|
|
1
32
|
export {};
|
package/dist/getLocale.d.ts
CHANGED
|
@@ -1 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
* @tag BedrockModule
|
|
4
|
+
* @category BedrockModules
|
|
5
|
+
* @kind function
|
|
6
|
+
* @name getLocale
|
|
7
|
+
* @description
|
|
8
|
+
* 사용자의 로케일(locale) 정보를 반환해요. 네이티브 모듈에서 로케일 정보를 가져올 수 없을 때는 기본값으로 'ko-KR'을 반환합니다. 앱의 현지화 및 언어 설정과 관련된 기능을 구현할 때 사용하세요.
|
|
9
|
+
*
|
|
10
|
+
* @returns {string} 사용자의 로케일 정보를 반환해요.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ### 현재 사용자의 로케일 정보 가져오기
|
|
14
|
+
*
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { getLocale } from '@apps-in-toss/web-framework';
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
* function MyPage() {
|
|
20
|
+
* const locale = getLocale();
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <span>사용자의 로케일 정보: {locale}</span>
|
|
24
|
+
* )
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function getLocale(): string;
|
|
30
|
+
|
|
1
31
|
export {};
|
|
@@ -1 +1,55 @@
|
|
|
1
|
+
export type NetworkStatus = "OFFLINE" | "WIFI" | "2G" | "3G" | "4G" | "5G" | "WWAN" | "UNKNOWN";
|
|
2
|
+
/**
|
|
3
|
+
* @public
|
|
4
|
+
* @tag BedrockModule
|
|
5
|
+
* @category BedrockModules
|
|
6
|
+
* @kind function
|
|
7
|
+
* @name getNetworkStatus
|
|
8
|
+
* @description
|
|
9
|
+
* 디바이스의 현재 네트워크 연결 상태를 가져오는 함수예요.
|
|
10
|
+
* 반환 값은 `NetworkStatus` 타입으로, 인터넷 연결 여부와 연결 유형(Wi-Fi, 모바일 데이터 등)을 나타내요. 값은 다음 중 하나예요.
|
|
11
|
+
*
|
|
12
|
+
* - `OFFLINE`: 인터넷에 연결되지 않은 상태예요.
|
|
13
|
+
* - `WIFI`: Wi-Fi에 연결된 상태예요.
|
|
14
|
+
* - `2G`: 2G 네트워크에 연결된 상태예요.
|
|
15
|
+
* - `3G`: 3G 네트워크에 연결된 상태예요.
|
|
16
|
+
* - `4G`: 4G 네트워크에 연결된 상태예요.
|
|
17
|
+
* - `5G`: 5G 네트워크에 연결된 상태예요.
|
|
18
|
+
* - `WWAN`: 인터넷은 연결되었지만, 연결 유형(Wi-Fi, 2G~5G)을 알 수 없는 상태예요. 이 상태는 iOS에서만 확인할 수 있어요.
|
|
19
|
+
* - `UNKNOWN`: 인터넷 연결 상태를 알 수 없는 상태예요. 이 상태는 안드로이드에서만 확인할 수 있어요.
|
|
20
|
+
*
|
|
21
|
+
* @returns {Promise<NetworkStatus>} 네트워크 상태를 반환해요.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ### 현재 네트워크 상태 가져오기
|
|
25
|
+
*
|
|
26
|
+
* 네트워크 연결 상태를 가져와 화면에 표시하는 예제예요.
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* import { useState, useEffect } from 'react';
|
|
30
|
+
*
|
|
31
|
+
* import { getNetworkStatus, NetworkStatus } from '@apps-in-toss/web-framework';
|
|
32
|
+
*
|
|
33
|
+
* function GetNetworkStatus() {
|
|
34
|
+
* const [status, setStatus] = useState<NetworkStatus | ''>('');
|
|
35
|
+
*
|
|
36
|
+
* useEffect(() => {
|
|
37
|
+
* async function fetchStatus() {
|
|
38
|
+
* const networkStatus = await getNetworkStatus();
|
|
39
|
+
* setStatus(networkStatus);
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* fetchStatus();
|
|
43
|
+
* }, []);
|
|
44
|
+
*
|
|
45
|
+
* return (
|
|
46
|
+
* <div>
|
|
47
|
+
* <span>현재 네트워크 상태: {status}</span>
|
|
48
|
+
* </div>
|
|
49
|
+
* );
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function getNetworkStatus(): Promise<NetworkStatus>;
|
|
54
|
+
|
|
1
55
|
export {};
|