@apps-in-toss/web-framework 3.0.0-beta.9d42c0b → 3.0.0-beta.b36d7b5
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/cli.js +655 -29
- package/dist/config.cjs +2 -0
- package/dist/config.d.cts +2 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import { Cli } from "clipanion";
|
|
4
|
+
import { Cli, Builtins } from "clipanion";
|
|
5
5
|
|
|
6
6
|
// src/cli/commands/build/index.ts
|
|
7
|
-
import * as
|
|
7
|
+
import * as p2 from "@clack/prompts";
|
|
8
8
|
import { Command } from "clipanion";
|
|
9
9
|
import path3 from "path";
|
|
10
10
|
|
|
11
11
|
// src/cli/commands/build/buildArtifact.ts
|
|
12
12
|
import { AppsInTossBundle, PlatformType } from "@apps-in-toss/ait-format";
|
|
13
|
+
import * as p from "@clack/prompts";
|
|
13
14
|
import { cosmiconfig } from "cosmiconfig";
|
|
14
15
|
import { TypeScriptLoader } from "cosmiconfig-typescript-loader";
|
|
15
16
|
import path2 from "path";
|
|
@@ -61,6 +62,10 @@ async function buildArtifact() {
|
|
|
61
62
|
appsInTossConfig.webBundleDir
|
|
62
63
|
);
|
|
63
64
|
const webBundleFiles = await getWebBundleFiles(webBundleDir);
|
|
65
|
+
if (webBundleFiles.find((file) => file.name === "index.html") == null) {
|
|
66
|
+
p.log.error("\uC6F9 \uBE4C\uB4DC \uB514\uB809\uD1A0\uB9AC\uC5D0 index.html\uC774 \uC874\uC7AC\uD574\uC57C \uD569\uB2C8\uB2E4.");
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
64
69
|
for (const file of webBundleFiles) {
|
|
65
70
|
writer.addFile("sources/" + file.name, file.data);
|
|
66
71
|
}
|
|
@@ -131,7 +136,7 @@ async function getWebBundleFiles(webBundleDir) {
|
|
|
131
136
|
const filePaths = await getFilePathsInDir(webBundleDir);
|
|
132
137
|
const files = [];
|
|
133
138
|
for (const filePath of filePaths) {
|
|
134
|
-
const name =
|
|
139
|
+
const name = path2.relative(webBundleDir, filePath);
|
|
135
140
|
const data = new Uint8Array(await readFile(filePath));
|
|
136
141
|
files.push({ name, data });
|
|
137
142
|
}
|
|
@@ -158,30 +163,572 @@ var BuildCommand = class extends Command {
|
|
|
158
163
|
});
|
|
159
164
|
async execute() {
|
|
160
165
|
const buildResult = await buildArtifact();
|
|
161
|
-
|
|
166
|
+
p2.log.success(
|
|
162
167
|
`\uC571\uC778\uD1A0\uC2A4 \uBE4C\uB4DC\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. (${path3.basename(buildResult.outPath)})`
|
|
163
168
|
);
|
|
164
|
-
|
|
169
|
+
p2.log.info(`deploymentId: ${buildResult.deploymentId}`);
|
|
165
170
|
}
|
|
166
171
|
};
|
|
167
172
|
|
|
168
|
-
// src/cli/commands/
|
|
173
|
+
// src/cli/commands/deploy/index.ts
|
|
174
|
+
import assert from "assert";
|
|
175
|
+
import fs4 from "fs";
|
|
176
|
+
import path5 from "path";
|
|
177
|
+
import { AppsInTossBundle as AppsInTossBundle2 } from "@apps-in-toss/ait-format";
|
|
169
178
|
import * as p3 from "@clack/prompts";
|
|
170
179
|
import { Command as Command2, Option } from "clipanion";
|
|
171
180
|
|
|
181
|
+
// src/cli/utils/colors.ts
|
|
182
|
+
function wrap(open, close) {
|
|
183
|
+
return (input) => `\x1B[${open}m${input}\x1B[${close}m`;
|
|
184
|
+
}
|
|
185
|
+
var colors = {
|
|
186
|
+
cyan: wrap(36, 39),
|
|
187
|
+
green: wrap(32, 39),
|
|
188
|
+
underline: wrap(4, 24)
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// src/cli/utils/TokenStorage.ts
|
|
192
|
+
import fs2 from "fs";
|
|
193
|
+
import os from "os";
|
|
194
|
+
import path4 from "path";
|
|
195
|
+
var TokenStorage = class {
|
|
196
|
+
static get path() {
|
|
197
|
+
const home = os.homedir();
|
|
198
|
+
const dir = path4.join(home, ".ait");
|
|
199
|
+
if (!fs2.existsSync(dir)) {
|
|
200
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
201
|
+
}
|
|
202
|
+
return path4.join(dir, "credentials");
|
|
203
|
+
}
|
|
204
|
+
static read() {
|
|
205
|
+
const file = this.path;
|
|
206
|
+
if (!fs2.existsSync(file)) {
|
|
207
|
+
return {};
|
|
208
|
+
}
|
|
209
|
+
const raw = fs2.readFileSync(file, "utf8");
|
|
210
|
+
try {
|
|
211
|
+
const parsed = JSON.parse(raw);
|
|
212
|
+
if (parsed && typeof parsed === "object") {
|
|
213
|
+
return parsed;
|
|
214
|
+
}
|
|
215
|
+
} catch {
|
|
216
|
+
}
|
|
217
|
+
return {};
|
|
218
|
+
}
|
|
219
|
+
static write(map) {
|
|
220
|
+
const file = this.path;
|
|
221
|
+
const content = JSON.stringify(map, null, 2);
|
|
222
|
+
fs2.writeFileSync(file, content, { encoding: "utf8" });
|
|
223
|
+
}
|
|
224
|
+
static set(workspace, token) {
|
|
225
|
+
const creds = this.read();
|
|
226
|
+
creds[workspace] = token;
|
|
227
|
+
this.write(creds);
|
|
228
|
+
}
|
|
229
|
+
static delete(workspace) {
|
|
230
|
+
const creds = this.read();
|
|
231
|
+
if (workspace in creds) {
|
|
232
|
+
delete creds[workspace];
|
|
233
|
+
this.write(creds);
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
static get(workspace) {
|
|
239
|
+
const creds = this.read();
|
|
240
|
+
return creds[workspace];
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// src/cli/utils/upload.ts
|
|
245
|
+
import fs3 from "fs";
|
|
246
|
+
|
|
247
|
+
// src/cli/utils/constants.ts
|
|
248
|
+
var DEFAULT_API_BASE_URL = "https://apps-in-toss.toss.im/console";
|
|
249
|
+
|
|
250
|
+
// src/cli/utils/flowAsync.ts
|
|
251
|
+
function flowAsync(...funcs) {
|
|
252
|
+
return async function(...args) {
|
|
253
|
+
let result = funcs.length ? await funcs[0].apply(this, args) : args[0];
|
|
254
|
+
for (let i = 1; i < funcs.length; i++) {
|
|
255
|
+
result = await funcs[i]?.call(this, result);
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/cli/utils/handleFetchResponse.ts
|
|
262
|
+
async function handleFetchResponse(response) {
|
|
263
|
+
if (!response.ok) {
|
|
264
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
265
|
+
}
|
|
266
|
+
const data = await response.clone().json();
|
|
267
|
+
if (data.resultType !== "SUCCESS") {
|
|
268
|
+
const errorCode = data?.error?.errorCode ?? "-1";
|
|
269
|
+
const errorReason = data?.error?.reason ?? "unknown";
|
|
270
|
+
throw new Error(`${errorReason} (Code: ${errorCode})`);
|
|
271
|
+
}
|
|
272
|
+
return data.success;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/cli/utils/withRetry.ts
|
|
276
|
+
import { setTimeout as sleep } from "timers/promises";
|
|
277
|
+
async function withRetry(fn, options = {}) {
|
|
278
|
+
const {
|
|
279
|
+
maxRetries = 60,
|
|
280
|
+
delayMs = 1e4,
|
|
281
|
+
shouldRetryOnResult,
|
|
282
|
+
shouldRetryOnError,
|
|
283
|
+
onRetry
|
|
284
|
+
} = options;
|
|
285
|
+
let attempt = 0;
|
|
286
|
+
while (attempt < maxRetries) {
|
|
287
|
+
try {
|
|
288
|
+
const result = await fn();
|
|
289
|
+
if (shouldRetryOnResult && shouldRetryOnResult(result)) {
|
|
290
|
+
onRetry?.(attempt + 1, { result });
|
|
291
|
+
await sleep(delayMs);
|
|
292
|
+
attempt++;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
} catch (error) {
|
|
297
|
+
const retryable = shouldRetryOnError ? shouldRetryOnError(error) : false;
|
|
298
|
+
if (!retryable) {
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
onRetry?.(attempt + 1, { error });
|
|
302
|
+
await sleep(delayMs);
|
|
303
|
+
attempt++;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
throw new Error("\uCD5C\uB300 \uB300\uAE30\uC2DC\uAC04\uC744 \uCD08\uACFC\uD588\uC5B4\uC694.");
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/cli/utils/upload.ts
|
|
310
|
+
async function uploadArtifact(config) {
|
|
311
|
+
return flowAsync(
|
|
312
|
+
uploadStart(),
|
|
313
|
+
uploadArtifactToRemote(),
|
|
314
|
+
uploadComplete(),
|
|
315
|
+
checkBundleStatus()
|
|
316
|
+
)(config);
|
|
317
|
+
}
|
|
318
|
+
function uploadStart() {
|
|
319
|
+
return async (config) => {
|
|
320
|
+
const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
|
|
321
|
+
const response = await fetch(
|
|
322
|
+
`${baseUrl}/api-public/v3/openapi/bundles/${config.appName}/upload-start`,
|
|
323
|
+
{
|
|
324
|
+
method: "POST",
|
|
325
|
+
headers: {
|
|
326
|
+
"Content-Type": "application/json",
|
|
327
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
328
|
+
},
|
|
329
|
+
body: JSON.stringify({
|
|
330
|
+
deploymentId: config.deploymentId,
|
|
331
|
+
memo: config.memo
|
|
332
|
+
})
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
return {
|
|
336
|
+
config,
|
|
337
|
+
output: await handleFetchResponse(response)
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function uploadArtifactToRemote() {
|
|
342
|
+
return async (params) => {
|
|
343
|
+
const { config, output } = params;
|
|
344
|
+
const stat = await fs3.promises.stat(config.artifactPath);
|
|
345
|
+
const stream = fs3.createReadStream(config.artifactPath);
|
|
346
|
+
const response = await fetch(output.uploadUrl, {
|
|
347
|
+
method: "PUT",
|
|
348
|
+
headers: {
|
|
349
|
+
"Content-Type": "application/zip",
|
|
350
|
+
"Content-Length": String(stat.size)
|
|
351
|
+
},
|
|
352
|
+
// Node.js의 fetch는 ReadStream을 body로 받을 수 있으나 DOM 타입에는 없어 캐스팅합니다.
|
|
353
|
+
body: stream,
|
|
354
|
+
duplex: "half"
|
|
355
|
+
});
|
|
356
|
+
if (!response.ok) {
|
|
357
|
+
throw new Error("\uC5C5\uB85C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.");
|
|
358
|
+
}
|
|
359
|
+
return config;
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function uploadComplete() {
|
|
363
|
+
return async (config) => {
|
|
364
|
+
const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
|
|
365
|
+
const response = await fetch(
|
|
366
|
+
`${baseUrl}/api-public/v3/openapi/bundles/${config.appName}/upload-complete`,
|
|
367
|
+
{
|
|
368
|
+
method: "POST",
|
|
369
|
+
headers: {
|
|
370
|
+
"Content-Type": "application/json",
|
|
371
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
372
|
+
},
|
|
373
|
+
body: JSON.stringify({
|
|
374
|
+
deploymentId: config.deploymentId
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
await handleFetchResponse(response);
|
|
379
|
+
return config;
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function checkBundleStatus(delayMs = 1e4, maxRetries = 10) {
|
|
383
|
+
return async (config) => {
|
|
384
|
+
const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
|
|
385
|
+
function assertBuildNotFailed(config2, reviewStatus2) {
|
|
386
|
+
if (reviewStatus2 === "BUILD_FAILED") {
|
|
387
|
+
throw new Error(
|
|
388
|
+
`\uBE4C\uB4DC\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uCF58\uC194\uC5D0\uC11C \uBE4C\uB4DC \uC2E4\uD328 \uC0AC\uC720\uB97C \uD655\uC778\uD574\uC8FC\uC138\uC694.(deploymentId: ${config2.deploymentId})`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async function pollBundleStatus() {
|
|
393
|
+
const response = await fetch(
|
|
394
|
+
`${baseUrl}/api-public/v3/openapi/bundles/${config.appName}/deployments/${config.deploymentId}`,
|
|
395
|
+
{
|
|
396
|
+
method: "GET",
|
|
397
|
+
headers: {
|
|
398
|
+
"Content-Type": "application/json",
|
|
399
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
const { reviewStatus: reviewStatus2 } = await handleFetchResponse(response);
|
|
404
|
+
return reviewStatus2;
|
|
405
|
+
}
|
|
406
|
+
const reviewStatus = await withRetry(pollBundleStatus, {
|
|
407
|
+
maxRetries,
|
|
408
|
+
delayMs,
|
|
409
|
+
shouldRetryOnResult: (reviewStatus2) => reviewStatus2 === "BUILDING" || reviewStatus2 === "PREPARE",
|
|
410
|
+
shouldRetryOnError: () => false
|
|
411
|
+
});
|
|
412
|
+
assertBuildNotFailed(config, reviewStatus);
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/cli/commands/deploy/index.ts
|
|
417
|
+
var DeployCommand = class extends Command2 {
|
|
418
|
+
static paths = [["deploy"]];
|
|
419
|
+
static usage = Command2.Usage({
|
|
420
|
+
category: "Deploy",
|
|
421
|
+
description: "\uBE4C\uB4DC\uB41C .ait \uC544\uD2F0\uD329\uD2B8\uB97C \uC571\uC778\uD1A0\uC2A4\uC5D0 \uC5C5\uB85C\uB4DC(\uBC30\uD3EC)\uD569\uB2C8\uB2E4.",
|
|
422
|
+
examples: [
|
|
423
|
+
["\uAE30\uBCF8 \uC544\uD2F0\uD329\uD2B8(.ait) \uBC30\uD3EC", "apps-in-toss deploy"],
|
|
424
|
+
[
|
|
425
|
+
"\uD2B9\uC815 .ait \uD30C\uC77C \uBC30\uD3EC",
|
|
426
|
+
"apps-in-toss deploy --location ./dist/my-app.ait"
|
|
427
|
+
],
|
|
428
|
+
["\uD504\uB85C\uD544\uC5D0 \uC800\uC7A5\uB41C \uD1A0\uD070\uC73C\uB85C \uBC30\uD3EC", "apps-in-toss deploy --profile dev"],
|
|
429
|
+
[
|
|
430
|
+
"\uCD9C\uC2DC \uBA54\uBAA8\uC640 \uD568\uAED8 \uBC30\uD3EC",
|
|
431
|
+
'apps-in-toss deploy -m "\uCD9C\uC2DC \uBA54\uBAA8(\uCD5C\uB300 1000\uC790)"'
|
|
432
|
+
],
|
|
433
|
+
["\uBC30\uD3EC \uACB0\uACFC scheme\uB9CC \uCD9C\uB825", "apps-in-toss deploy --scheme-only"]
|
|
434
|
+
]
|
|
435
|
+
});
|
|
436
|
+
apiKey = Option.String("--api-key", {
|
|
437
|
+
required: false,
|
|
438
|
+
description: "\uBC30\uD3EC\uB97C \uC704\uD55C API \uD0A4\uC785\uB2C8\uB2E4. \uBA85\uC2DC\uC801\uC73C\uB85C \uC774 \uC635\uC158\uC73C\uB85C api key\uB97C \uC9C1\uC811 \uC785\uB825\uD558\uAC70\uB098, --profile \uC635\uC158\uC744 \uC0AC\uC6A9\uD574\uC11C \uD504\uB85C\uD544\uC744 \uC9C0\uC815\uD558\uBA74 \uD504\uB85C\uD544\uC5D0 \uB4F1\uB85D\uB41C api key\uB97C \uC0AC\uC6A9\uD574\uC694."
|
|
439
|
+
});
|
|
440
|
+
workspace = Option.String("--workspace", {
|
|
441
|
+
required: false,
|
|
442
|
+
description: "(deprecated) \uD1A0\uD070 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uC774\uB984\uC785\uB2C8\uB2E4. \uC774 \uC635\uC158 \uB300\uC2E0 --profile \uC635\uC158\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."
|
|
443
|
+
});
|
|
444
|
+
profile = Option.String("--profile", {
|
|
445
|
+
required: false,
|
|
446
|
+
description: "apps-in-toss token add \uBA85\uB839\uC5B4\uB97C \uD1B5\uD574 \uB4F1\uB85D\uD55C \uD504\uB85C\uD544\uC774\uC5D0\uC694. \uD504\uB85C\uD544\uC774 \uC5C6\uC73C\uBA74 default \uD504\uB85C\uD544\uC744 \uC0AC\uC6A9\uD574\uC694."
|
|
447
|
+
});
|
|
448
|
+
baseUrl = Option.String("--base-url", {
|
|
449
|
+
description: "API Base URL",
|
|
450
|
+
required: false
|
|
451
|
+
});
|
|
452
|
+
location = Option.String("--location", {
|
|
453
|
+
description: "\uC5C5\uB85C\uB4DC\uD560 .ait \uD30C\uC77C\uC758 \uACBD\uB85C\uB97C \uBA85\uC2DC\uC801\uC73C\uB85C \uC9C0\uC815\uD574\uC694. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uD328\uD0A4\uC9C0 \uB8E8\uD2B8 \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC788\uB294 ait \uD30C\uC77C\uC774\uC5D0\uC694.",
|
|
454
|
+
required: false
|
|
455
|
+
});
|
|
456
|
+
schemeOnly = Option.Boolean("--scheme-only", {
|
|
457
|
+
required: false,
|
|
458
|
+
description: "\uBC30\uD3EC \uACB0\uACFC\uB97C intoss-private scheme\uB9CC \uCD9C\uB825\uD558\uB3C4\uB85D \uC124\uC815\uD574\uC694. \uAE30\uBCF8\uAC12\uC740 false\uC608\uC694."
|
|
459
|
+
});
|
|
460
|
+
memo = Option.String("-m,--memo", {
|
|
461
|
+
required: false,
|
|
462
|
+
description: "\uCD9C\uC2DC \uBA54\uBAA8\uB97C \uC785\uB825\uD574\uC694. \uCD5C\uB300 1000\uC790\uAE4C\uC9C0 \uC785\uB825\uD560 \uC218 \uC788\uC5B4\uC694."
|
|
463
|
+
});
|
|
464
|
+
async execute() {
|
|
465
|
+
const baseUrl = this.baseUrl;
|
|
466
|
+
const profile = this.profile || this.workspace || "default";
|
|
467
|
+
if (this.workspace) {
|
|
468
|
+
p3.log.warn(
|
|
469
|
+
"(deprecated) --workspace \uC635\uC158\uC740 \uC774\uC81C \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC544\uC694. \uC774 \uC635\uC158 \uB300\uC2E0 --profile \uC635\uC158\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
const apiKey = await this.getApiKey(profile);
|
|
473
|
+
if (p3.isCancel(apiKey)) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
if (this.memo != null && this.memo.length > 1e3) {
|
|
478
|
+
throw new Error("memo\uB294 \uCD5C\uB300 1000\uC790\uAE4C\uC9C0 \uC785\uB825\uD560 \uC218 \uC788\uC5B4\uC694.");
|
|
479
|
+
}
|
|
480
|
+
const resolvedArtifactPath = this.getArtifactPath(this.location);
|
|
481
|
+
const buffer = fs4.readFileSync(resolvedArtifactPath);
|
|
482
|
+
const format = AppsInTossBundle2.detect(buffer);
|
|
483
|
+
if (format !== AppsInTossBundle2.Format.AIT) {
|
|
484
|
+
throw new Error("\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD\uC785\uB2C8\uB2E4");
|
|
485
|
+
}
|
|
486
|
+
const reader = AppsInTossBundle2.reader(buffer);
|
|
487
|
+
const appName = reader.appName;
|
|
488
|
+
const deploymentId = reader.deploymentId;
|
|
489
|
+
assert(typeof appName === "string", "ait \uD30C\uC77C\uC5D0 appName\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
490
|
+
assert(
|
|
491
|
+
typeof deploymentId === "string",
|
|
492
|
+
"ait \uD30C\uC77C\uC5D0 deploymentId\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
493
|
+
);
|
|
494
|
+
const colorAppName = this.decorate(appName, colors.cyan);
|
|
495
|
+
if (this.schemeOnly) {
|
|
496
|
+
await uploadArtifact({
|
|
497
|
+
artifactPath: resolvedArtifactPath,
|
|
498
|
+
appName,
|
|
499
|
+
deploymentId,
|
|
500
|
+
apiKey,
|
|
501
|
+
memo: this.memo,
|
|
502
|
+
baseUrl
|
|
503
|
+
});
|
|
504
|
+
} else {
|
|
505
|
+
await p3.tasks([
|
|
506
|
+
{
|
|
507
|
+
title: `${colorAppName} \uC571 \uBC30\uD3EC \uC911...`,
|
|
508
|
+
task: async () => {
|
|
509
|
+
await uploadArtifact({
|
|
510
|
+
artifactPath: resolvedArtifactPath,
|
|
511
|
+
appName,
|
|
512
|
+
deploymentId,
|
|
513
|
+
apiKey,
|
|
514
|
+
memo: this.memo,
|
|
515
|
+
baseUrl
|
|
516
|
+
});
|
|
517
|
+
return `${colorAppName} \uBC30\uD3EC\uAC00 \uC644\uB8CC\uB418\uC5C8\uC5B4\uC694`;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
]);
|
|
521
|
+
}
|
|
522
|
+
this.printResult(appName, deploymentId);
|
|
523
|
+
} catch (error) {
|
|
524
|
+
if (error instanceof Error) {
|
|
525
|
+
this.printError(error);
|
|
526
|
+
} else {
|
|
527
|
+
console.error(error);
|
|
528
|
+
}
|
|
529
|
+
process.exit(1);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
decorate(message, color) {
|
|
533
|
+
if (this.schemeOnly) {
|
|
534
|
+
return message;
|
|
535
|
+
}
|
|
536
|
+
return colors.underline(color(message));
|
|
537
|
+
}
|
|
538
|
+
printResult(appName, deploymentId) {
|
|
539
|
+
const result = `intoss-private://${appName}?_deploymentId=${deploymentId}`;
|
|
540
|
+
if (this.schemeOnly) {
|
|
541
|
+
this.context.stdout.write(`${result}
|
|
542
|
+
`);
|
|
543
|
+
} else {
|
|
544
|
+
p3.note(this.decorate(result, colors.green));
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
printError(error) {
|
|
548
|
+
if (this.schemeOnly) {
|
|
549
|
+
this.context.stdout.write(`${error.message}
|
|
550
|
+
`);
|
|
551
|
+
} else {
|
|
552
|
+
p3.log.error(error.message);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
async getApiKey(profile) {
|
|
556
|
+
const token = TokenStorage.get(profile) || this.apiKey;
|
|
557
|
+
if (token) {
|
|
558
|
+
return token;
|
|
559
|
+
}
|
|
560
|
+
return await p3.password({
|
|
561
|
+
message: "\uC571\uC778\uD1A0\uC2A4 \uBC30\uD3EC API \uD0A4\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",
|
|
562
|
+
validate: (value) => {
|
|
563
|
+
if (value == null || value.length === 0) {
|
|
564
|
+
return "API \uD0A4\uB294 \uD544\uC218 \uC785\uB825 \uD56D\uBAA9\uC785\uB2C8\uB2E4.";
|
|
565
|
+
}
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
getArtifactPath(location) {
|
|
571
|
+
if (location) {
|
|
572
|
+
if (!location.endsWith(".ait")) {
|
|
573
|
+
throw new Error("\uBC30\uD3EC\uD560 \uD30C\uC77C\uC740 .ait \uD655\uC7A5\uC790\uC5EC\uC57C \uD569\uB2C8\uB2E4.");
|
|
574
|
+
}
|
|
575
|
+
return path5.resolve(location);
|
|
576
|
+
}
|
|
577
|
+
const packageRoot = getPackageRoot(process.cwd());
|
|
578
|
+
const artifactFile = fs4.readdirSync(packageRoot).find((file) => file.endsWith(".ait"));
|
|
579
|
+
if (!artifactFile) {
|
|
580
|
+
throw new Error("\uBC30\uD3EC\uD560 .ait \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
581
|
+
}
|
|
582
|
+
return path5.resolve(packageRoot, artifactFile);
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
// src/cli/commands/init/index.ts
|
|
587
|
+
import { appendFile, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
588
|
+
import { join } from "path";
|
|
589
|
+
import * as p4 from "@clack/prompts";
|
|
590
|
+
import { Command as Command3, Option as Option2 } from "clipanion";
|
|
591
|
+
|
|
592
|
+
// src/cli/utils/ensureSelect.ts
|
|
593
|
+
async function ensureSelect({
|
|
594
|
+
value,
|
|
595
|
+
prompt
|
|
596
|
+
}) {
|
|
597
|
+
if (value) {
|
|
598
|
+
return value;
|
|
599
|
+
}
|
|
600
|
+
return await prompt();
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// src/cli/utils/kebabCase.ts
|
|
604
|
+
function kebabCase(str) {
|
|
605
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// src/cli/utils/transformTemplate.ts
|
|
609
|
+
function transformTemplate(templateString, values) {
|
|
610
|
+
let result = templateString;
|
|
611
|
+
for (const key in values) {
|
|
612
|
+
const placeholder = `%%${key}%%`;
|
|
613
|
+
result = result.replace(new RegExp(placeholder, "g"), values[key]);
|
|
614
|
+
}
|
|
615
|
+
return result;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/cli/commands/init/templates.ts
|
|
619
|
+
var WEB_FRAMEWORK_CONFIG_TEMPLATE = `import { defineConfig } from '@apps-in-toss/web-framework/config';
|
|
620
|
+
|
|
621
|
+
export default defineConfig({
|
|
622
|
+
appName: '%%appName%%',
|
|
623
|
+
brand: {
|
|
624
|
+
primaryColor: '#3182F6', // \uD654\uBA74\uC5D0 \uB178\uCD9C\uB420 \uC571\uC758 \uAE30\uBCF8 \uC0C9\uC0C1\uC73C\uB85C \uBC14\uAFD4\uC8FC\uC138\uC694.
|
|
625
|
+
},
|
|
626
|
+
permissions: [],
|
|
627
|
+
webBundleDir: '%%webBundleDir%%',
|
|
628
|
+
});
|
|
629
|
+
`;
|
|
630
|
+
|
|
631
|
+
// src/cli/commands/init/index.ts
|
|
632
|
+
async function templateWebFramework({
|
|
633
|
+
appName,
|
|
634
|
+
cwd,
|
|
635
|
+
skipInput
|
|
636
|
+
}) {
|
|
637
|
+
const packageJsonPath = join(cwd, "package.json");
|
|
638
|
+
const packageJsonRaw = await readFile2(packageJsonPath, {
|
|
639
|
+
encoding: "utf-8"
|
|
640
|
+
});
|
|
641
|
+
const packageJson = JSON.parse(packageJsonRaw);
|
|
642
|
+
packageJson.scripts ??= {};
|
|
643
|
+
if (packageJson.scripts.build) {
|
|
644
|
+
packageJson.scripts.build = packageJson.scripts.build + " && ait build";
|
|
645
|
+
}
|
|
646
|
+
packageJson.scripts.deploy = "ait deploy";
|
|
647
|
+
await writeFile2(packageJsonPath, JSON.stringify(packageJson, null, 2), {
|
|
648
|
+
encoding: "utf-8"
|
|
649
|
+
});
|
|
650
|
+
p4.log.step(".gitignore \uD30C\uC77C\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911...");
|
|
651
|
+
await appendFile(join(cwd, ".gitignore"), "\n*.ait\n");
|
|
652
|
+
const webBundleDir = skipInput ? "dist" : await p4.text({
|
|
653
|
+
message: "\uC6F9 \uBC88\uB4E4 \uACB0\uACFC\uBB3C\uC774 \uC704\uCE58\uD55C \uB514\uB809\uD1A0\uB9AC\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.",
|
|
654
|
+
placeholder: "dist",
|
|
655
|
+
defaultValue: "dist"
|
|
656
|
+
});
|
|
657
|
+
if (p4.isCancel(webBundleDir)) {
|
|
658
|
+
p4.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
p4.log.step("apps-in-toss.config.ts \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
|
|
662
|
+
const config = transformTemplate(WEB_FRAMEWORK_CONFIG_TEMPLATE, {
|
|
663
|
+
appName,
|
|
664
|
+
webBundleDir
|
|
665
|
+
});
|
|
666
|
+
await writeFile2(join(cwd, "apps-in-toss.config.ts"), config, {
|
|
667
|
+
encoding: "utf-8"
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
var InitCommand = class extends Command3 {
|
|
671
|
+
static paths = [["init"]];
|
|
672
|
+
static usage = Command3.Usage({
|
|
673
|
+
category: "Setup",
|
|
674
|
+
description: "\uC571\uC778\uD1A0\uC2A4 \uC6F9 \uD504\uB808\uC784\uC6CC\uD06C \uAC1C\uBC1C/\uBC30\uD3EC \uC124\uC815\uC744 \uCD08\uAE30\uD654\uD569\uB2C8\uB2E4.",
|
|
675
|
+
examples: [
|
|
676
|
+
["\uB300\uD654\uD615\uC73C\uB85C \uCD08\uAE30\uD654", "apps-in-toss init"],
|
|
677
|
+
["\uC571 \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC5EC \uCD08\uAE30\uD654", "apps-in-toss init --app-name my-miniapp"]
|
|
678
|
+
]
|
|
679
|
+
});
|
|
680
|
+
appName = Option2.String("--app-name", {
|
|
681
|
+
required: false,
|
|
682
|
+
description: "\uC571 \uC774\uB984(\uCF00\uBC25-\uCF00\uC774\uC2A4)\uC744 \uC9C0\uC815\uD574\uC694. \uC608) my-miniapp"
|
|
683
|
+
});
|
|
684
|
+
skipInput = Option2.Boolean("--skip-input", { required: false, hidden: true });
|
|
685
|
+
async execute() {
|
|
686
|
+
const cwd = getPackageRoot(process.cwd());
|
|
687
|
+
p4.intro("\u{1F680} \uC571 \uCD08\uAE30\uD654\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4");
|
|
688
|
+
const appName = await ensureSelect({
|
|
689
|
+
value: this.appName,
|
|
690
|
+
prompt: async () => p4.text({
|
|
691
|
+
message: "Enter app name",
|
|
692
|
+
validate: (value) => {
|
|
693
|
+
if (!value) {
|
|
694
|
+
return "\uC571 \uC774\uB984\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694";
|
|
695
|
+
}
|
|
696
|
+
const kebabCaseValue = kebabCase(value);
|
|
697
|
+
if (value !== kebabCaseValue) {
|
|
698
|
+
return `\uC571 \uC774\uB984\uC740 \uCF00\uBC25-\uCF00\uC774\uC2A4 \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4 (\uC608\uC2DC: ${kebabCaseValue})`;
|
|
699
|
+
}
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
})
|
|
703
|
+
});
|
|
704
|
+
if (p4.isCancel(appName)) {
|
|
705
|
+
p4.cancel("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
p4.log.step(`\uC571 \uC774\uB984\uC774 '${appName}'\uC73C\uB85C \uC124\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4`);
|
|
709
|
+
await templateWebFramework({
|
|
710
|
+
appName,
|
|
711
|
+
cwd,
|
|
712
|
+
skipInput: this.skipInput ?? false
|
|
713
|
+
});
|
|
714
|
+
p4.outro("\u2728 \uCD08\uAE30\uD654\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!");
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
// src/cli/commands/migration/index.ts
|
|
719
|
+
import * as p6 from "@clack/prompts";
|
|
720
|
+
import { Command as Command4, Option as Option3 } from "clipanion";
|
|
721
|
+
|
|
172
722
|
// src/cli/commands/migration/web-framework-v3.ts
|
|
173
|
-
import * as
|
|
723
|
+
import * as p5 from "@clack/prompts";
|
|
174
724
|
import { cosmiconfig as cosmiconfig2 } from "cosmiconfig";
|
|
175
725
|
import { TypeScriptLoader as TypeScriptLoader2 } from "cosmiconfig-typescript-loader";
|
|
176
|
-
import { readFile as
|
|
726
|
+
import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
177
727
|
import { resolve } from "path";
|
|
178
728
|
import jscodeshift from "jscodeshift";
|
|
179
729
|
async function migrateWebFrameworkV3() {
|
|
180
730
|
const projectRoot = getPackageRoot(process.cwd());
|
|
181
|
-
|
|
182
|
-
p2.log.info(
|
|
183
|
-
"\uC790\uB3D9 \uB9C8\uC774\uADF8\uB808\uC774\uC158\uC5D0 \uC2E4\uD328\uD560 \uACBD\uC6B0, \uCEE4\uBBA4\uB2C8\uD2F0\uC5D0\uC11C \uC218\uB3D9 \uB9C8\uC774\uADF8\uB808\uC774\uC158 \uAC00\uC774\uB4DC\uB97C \uCC38\uACE0\uD574\uC8FC\uC138\uC694.\nhttps://techchat-apps-in-toss.toss.im"
|
|
184
|
-
);
|
|
731
|
+
p5.log.info("@apps-in-toss/web-framework V3 \uC790\uB3D9 \uB9C8\uC774\uADF8\uB808\uC774\uC158\uC744 \uC2DC\uC791\uD569\uB2C8\uB2E4.");
|
|
185
732
|
const { config: graniteConfig, filepath: graniteConfigPath } = await getGraniteConfig(projectRoot);
|
|
186
733
|
await migrateAppsInTossConfig(
|
|
187
734
|
graniteConfigPath,
|
|
@@ -195,10 +742,10 @@ async function migrateWebFrameworkV3() {
|
|
|
195
742
|
graniteConfig.web.commands.dev,
|
|
196
743
|
graniteConfig.web.commands.build
|
|
197
744
|
);
|
|
198
|
-
|
|
745
|
+
p5.log.success("\uB9C8\uC774\uADF8\uB808\uC774\uC158\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
199
746
|
}
|
|
200
747
|
async function getGraniteConfig(projectRoot) {
|
|
201
|
-
|
|
748
|
+
p5.log.info("granite.config \uD30C\uC77C \uCC3E\uB294 \uC911..");
|
|
202
749
|
const result = await cosmiconfig2("granite", {
|
|
203
750
|
loaders: {
|
|
204
751
|
".ts": TypeScriptLoader2(),
|
|
@@ -215,16 +762,16 @@ async function getGraniteConfig(projectRoot) {
|
|
|
215
762
|
]
|
|
216
763
|
}).search(projectRoot);
|
|
217
764
|
if (result == null) {
|
|
218
|
-
|
|
765
|
+
p5.log.error("granite.config \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
219
766
|
process.exit(1);
|
|
220
767
|
}
|
|
221
768
|
return result;
|
|
222
769
|
}
|
|
223
770
|
async function migrateAppsInTossConfig(configPath, outputPath) {
|
|
224
|
-
|
|
225
|
-
const root = jscodeshift((await
|
|
226
|
-
root.find(jscodeshift.ObjectExpression).forEach((
|
|
227
|
-
const obj =
|
|
771
|
+
p5.log.info("granite.config\uB97C apps-in-toss.config\uB85C \uB9C8\uC774\uADF8\uB808\uC774\uC158\uD569\uB2C8\uB2E4.");
|
|
772
|
+
const root = jscodeshift((await readFile3(configPath)).toString());
|
|
773
|
+
root.find(jscodeshift.ObjectExpression).forEach((path7) => {
|
|
774
|
+
const obj = path7.value;
|
|
228
775
|
for (const prop of obj.properties) {
|
|
229
776
|
if (jscodeshift.Property.check(prop) && jscodeshift.Identifier.check(prop.key) && prop.key.name === "brand" && jscodeshift.ObjectExpression.check(prop.value)) {
|
|
230
777
|
prop.value.properties = prop.value.properties.filter(
|
|
@@ -252,39 +799,39 @@ async function migrateAppsInTossConfig(configPath, outputPath) {
|
|
|
252
799
|
return true;
|
|
253
800
|
});
|
|
254
801
|
});
|
|
255
|
-
await
|
|
256
|
-
|
|
802
|
+
await writeFile3(outputPath, root.toSource());
|
|
803
|
+
p5.log.info("apps-in-toss.config\uAC00 \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
257
804
|
}
|
|
258
805
|
async function migratePackageJsonScripts(packageJsonPath, dev, build) {
|
|
259
|
-
|
|
260
|
-
const packageJson = JSON.parse((await
|
|
806
|
+
p5.log.info("package.json\uC758 dev, build \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC218\uC815\uD569\uB2C8\uB2E4.");
|
|
807
|
+
const packageJson = JSON.parse((await readFile3(packageJsonPath)).toString());
|
|
261
808
|
if (packageJson.scripts == null) {
|
|
262
809
|
packageJson.scripts = {};
|
|
263
810
|
}
|
|
264
811
|
packageJson.scripts["dev"] = dev;
|
|
265
812
|
packageJson.scripts["build"] = `${build} && ait build`;
|
|
266
|
-
await
|
|
267
|
-
|
|
813
|
+
await writeFile3(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
814
|
+
p5.log.info("package.json \uC218\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
268
815
|
}
|
|
269
816
|
|
|
270
817
|
// src/cli/commands/migration/index.ts
|
|
271
818
|
var MIGRATION_TARGETS = {
|
|
272
819
|
v3: migrateWebFrameworkV3
|
|
273
820
|
};
|
|
274
|
-
var MigrationCommand = class extends
|
|
821
|
+
var MigrationCommand = class extends Command4 {
|
|
275
822
|
static paths = [["migrate"]];
|
|
276
|
-
static usage =
|
|
823
|
+
static usage = Command4.Usage({
|
|
277
824
|
category: "Migration",
|
|
278
825
|
description: "\uB9C8\uC774\uADF8\uB808\uC774\uC158\uC744 \uC2E4\uD589\uD569\uB2C8\uB2E4.",
|
|
279
826
|
examples: [["Run migration", "apps-in-toss migrate <target>"]]
|
|
280
827
|
});
|
|
281
|
-
target =
|
|
828
|
+
target = Option3.String({ required: true });
|
|
282
829
|
async execute() {
|
|
283
830
|
const target = MIGRATION_TARGETS[this.target];
|
|
284
831
|
if (target != null) {
|
|
285
832
|
await target();
|
|
286
833
|
} else {
|
|
287
|
-
|
|
834
|
+
p6.log.error(
|
|
288
835
|
[
|
|
289
836
|
"\uC798\uBABB\uB41C \uB9C8\uC774\uADF8\uB808\uC774\uC158 target \uC785\uB2C8\uB2E4. \uC544\uB798 \uC911 \uD558\uB098\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.\n",
|
|
290
837
|
...Object.keys(MIGRATION_TARGETS)
|
|
@@ -295,6 +842,79 @@ var MigrationCommand = class extends Command2 {
|
|
|
295
842
|
}
|
|
296
843
|
};
|
|
297
844
|
|
|
845
|
+
// src/cli/commands/token/index.ts
|
|
846
|
+
import * as p7 from "@clack/prompts";
|
|
847
|
+
import { Command as Command5, Option as Option4 } from "clipanion";
|
|
848
|
+
var TokenCommand = class extends Command5 {
|
|
849
|
+
static paths = [["token"]];
|
|
850
|
+
static usage = Command5.Usage({
|
|
851
|
+
category: "Auth",
|
|
852
|
+
description: "\uD1A0\uD070 \uAD00\uB828 \uD558\uC704 \uBA85\uB839\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4.",
|
|
853
|
+
examples: [
|
|
854
|
+
["\uD1A0\uD070 \uCD94\uAC00", "apps-in-toss token add <profile?>"],
|
|
855
|
+
["\uD1A0\uD070 \uC0AD\uC81C", "apps-in-toss token remove <profile?>"]
|
|
856
|
+
]
|
|
857
|
+
});
|
|
858
|
+
async execute() {
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
var TokenAddCommand = class extends Command5 {
|
|
862
|
+
static paths = [["token", "add"]];
|
|
863
|
+
static usage = Command5.Usage({
|
|
864
|
+
category: "Auth",
|
|
865
|
+
description: "\uC2DC\uD06C\uB9BF \uD1A0\uD070\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.",
|
|
866
|
+
examples: [
|
|
867
|
+
["\uAE30\uBCF8 \uBCC4\uCE6D\uC73C\uB85C \uD1A0\uD070 \uCD94\uAC00", "apps-in-toss token add"],
|
|
868
|
+
["\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC5EC \uD1A0\uD070 \uCD94\uAC00", "apps-in-toss token add dev"]
|
|
869
|
+
]
|
|
870
|
+
});
|
|
871
|
+
profile = Option4.String({ required: false });
|
|
872
|
+
apiKey = Option4.String("--api-key", { required: false });
|
|
873
|
+
async execute() {
|
|
874
|
+
const profile = this.profile || "default";
|
|
875
|
+
const secret = this.apiKey ? this.apiKey : await p7.password({
|
|
876
|
+
message: "Enter secret token:",
|
|
877
|
+
validate: (value) => {
|
|
878
|
+
if (value == null || value.length === 0) {
|
|
879
|
+
return "\uD1A0\uD070\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
880
|
+
}
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
if (p7.isCancel(secret)) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
TokenStorage.set(profile, secret);
|
|
888
|
+
this.context.stdout.write(
|
|
889
|
+
`${profile} \uD504\uB85C\uD544\uB85C\uC758 \uC694\uCCAD\uC740 \uC774\uC81C \uBE44\uBC00 \uD1A0\uD070\uC744 \uC0AC\uC6A9\uD558\uC5EC \uC778\uC99D\uB429\uB2C8\uB2E4.
|
|
890
|
+
`
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
var TokenRemoveCommand = class extends Command5 {
|
|
895
|
+
static paths = [["token", "remove"]];
|
|
896
|
+
static usage = Command5.Usage({
|
|
897
|
+
category: "Auth",
|
|
898
|
+
description: "\uC2DC\uD06C\uB9BF \uD1A0\uD070\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4.",
|
|
899
|
+
examples: [
|
|
900
|
+
["\uAE30\uBCF8 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uC758 \uD1A0\uD070 \uC0AD\uC81C", "apps-in-toss token remove"],
|
|
901
|
+
["\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC5EC \uD1A0\uD070 \uC0AD\uC81C", "apps-in-toss token remove dev"]
|
|
902
|
+
]
|
|
903
|
+
});
|
|
904
|
+
profile = Option4.String({ required: false });
|
|
905
|
+
async execute() {
|
|
906
|
+
const profile = this.profile || "default";
|
|
907
|
+
const removed = TokenStorage.delete(profile);
|
|
908
|
+
if (removed) {
|
|
909
|
+
this.context.stdout.write(`\uD1A0\uD070\uC744 \uC81C\uAC70\uD588\uC2B5\uB2C8\uB2E4: ${profile}.
|
|
910
|
+
`);
|
|
911
|
+
} else {
|
|
912
|
+
this.context.stdout.write(`\uD1A0\uD070\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${profile}.
|
|
913
|
+
`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
|
|
298
918
|
// src/cli/index.ts
|
|
299
919
|
var cli = new Cli({
|
|
300
920
|
binaryLabel: "appsintoss",
|
|
@@ -302,5 +922,11 @@ var cli = new Cli({
|
|
|
302
922
|
enableCapture: true
|
|
303
923
|
});
|
|
304
924
|
cli.register(BuildCommand);
|
|
925
|
+
cli.register(DeployCommand);
|
|
926
|
+
cli.register(InitCommand);
|
|
305
927
|
cli.register(MigrationCommand);
|
|
928
|
+
cli.register(TokenCommand);
|
|
929
|
+
cli.register(TokenAddCommand);
|
|
930
|
+
cli.register(TokenRemoveCommand);
|
|
931
|
+
cli.register(Builtins.HelpCommand);
|
|
306
932
|
cli.runExit(process.argv.slice(2));
|
package/dist/config.cjs
CHANGED
package/dist/config.d.cts
CHANGED
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apps-in-toss/web-framework",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.b36d7b5",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"import": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@apps-in-toss/ait-format": "^1.0.0",
|
|
39
|
-
"@apps-in-toss/webview-bridge": "^3.0.0-beta.
|
|
39
|
+
"@apps-in-toss/webview-bridge": "^3.0.0-beta.b36d7b5",
|
|
40
40
|
"@clack/prompts": "^1.3.0",
|
|
41
41
|
"clipanion": "^4.0.0-rc.4",
|
|
42
42
|
"cosmiconfig": "^9.0.1",
|