@ones-open/cli 1.0.1-16596.1816 → 1.0.1-8523.1883

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.
Files changed (42) hide show
  1. package/dist/index.cjs +569 -194
  2. package/dist/index.js +567 -192
  3. package/dist/types/actions/build/index.d.ts.map +1 -1
  4. package/dist/types/actions/install/index.d.ts.map +1 -1
  5. package/dist/types/actions/login/index.d.ts.map +1 -1
  6. package/dist/types/actions/tunnel/hosted-token.d.ts +5 -0
  7. package/dist/types/actions/tunnel/hosted-token.d.ts.map +1 -0
  8. package/dist/types/actions/tunnel/index.d.ts +1 -0
  9. package/dist/types/actions/tunnel/index.d.ts.map +1 -1
  10. package/dist/types/actions/tunnel/tunnel-client.d.ts +20 -0
  11. package/dist/types/actions/tunnel/tunnel-client.d.ts.map +1 -0
  12. package/dist/types/actions/tunnel/tunnel.d.ts +3 -1
  13. package/dist/types/actions/tunnel/tunnel.d.ts.map +1 -1
  14. package/dist/types/actions/whoami/index.d.ts.map +1 -1
  15. package/dist/types/common/config/types.d.ts +1 -0
  16. package/dist/types/common/config/types.d.ts.map +1 -1
  17. package/dist/types/common/config/utils.d.ts.map +1 -1
  18. package/dist/types/common/error/enums.d.ts +3 -1
  19. package/dist/types/common/error/enums.d.ts.map +1 -1
  20. package/dist/types/common/locales/en/index.d.ts +2 -0
  21. package/dist/types/common/locales/en/index.d.ts.map +1 -1
  22. package/dist/types/common/package/schema.d.ts +2 -234
  23. package/dist/types/common/package/schema.d.ts.map +1 -1
  24. package/dist/types/common/package/utils.d.ts +4 -1
  25. package/dist/types/common/package/utils.d.ts.map +1 -1
  26. package/dist/types/common/public/consts.d.ts +2 -0
  27. package/dist/types/common/public/consts.d.ts.map +1 -0
  28. package/dist/types/common/public/index.d.ts +1 -0
  29. package/dist/types/common/public/index.d.ts.map +1 -1
  30. package/dist/types/common/request/consts.d.ts +2 -0
  31. package/dist/types/common/request/consts.d.ts.map +1 -1
  32. package/dist/types/common/request/fetch.d.ts +2 -1
  33. package/dist/types/common/request/fetch.d.ts.map +1 -1
  34. package/dist/types/common/request/types.d.ts +22 -2
  35. package/dist/types/common/request/types.d.ts.map +1 -1
  36. package/dist/types/common/store/schema.d.ts +5 -2
  37. package/dist/types/common/store/schema.d.ts.map +1 -1
  38. package/dist/types/common/store/utils.d.ts +2 -0
  39. package/dist/types/common/store/utils.d.ts.map +1 -1
  40. package/package.json +7 -4
  41. package/public/logo.svg +4 -0
  42. /package/{dist → public}/callback.html +0 -0
package/dist/index.js CHANGED
@@ -1,21 +1,26 @@
1
1
  import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
2
2
  import { Command } from "commander";
3
- import { ErrorCode as ErrorCode$1, throwError, getCommandOptions, addCommandUsage, addCommandOutput, $create, setContext } from "create-ones-app";
4
- import { get, noop, merge } from "lodash-es";
5
- import process, { cwd, exit } from "node:process";
6
- import { dirname, join, resolve } from "node:path";
3
+ import { ErrorCode as ErrorCode$1, AppPackageJSONSchema, throwError, AppManifestJSONSchema, getPublicPath as getPublicPath$1, PUBLIC_FILENAME, AppRcJSONSchema, getCommandOptions, HostedTokenScope, addCommandUsage, addCommandOutput, $create, setContext } from "create-ones-app";
4
+ import { dirname, join, resolve, basename } from "node:path";
5
+ import { spawnSync } from "node:child_process";
6
+ import { readFileSync, createWriteStream } from "node:fs";
7
+ import archiver from "archiver";
8
+ import { get, merge, noop } from "lodash-es";
9
+ import process$1, { cwd, exit } from "node:process";
7
10
  import { fileURLToPath } from "node:url";
8
- import { readFileSync } from "node:fs";
9
- import { z } from "zod";
11
+ import { cosmiconfig } from "cosmiconfig";
10
12
  import fse from "fs-extra";
11
13
  import envPaths from "env-paths";
14
+ import { z } from "zod";
15
+ import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
16
+ import WebSocket from "ws";
17
+ import axios from "axios";
18
+ import _reduceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reduce";
12
19
  import http from "node:http";
13
20
  import ora from "ora";
14
21
  import open from "open";
15
22
  import getPort from "get-port";
16
23
  import { v7 } from "uuid";
17
- import axios from "axios";
18
- import _reduceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reduce";
19
24
  const en = {
20
25
  "desc.ones": "cli for ones",
21
26
  "desc.build": "build the application",
@@ -42,7 +47,9 @@ const en = {
42
47
  "error.schema.app.manifest.parseError": "app manifest json parse error",
43
48
  "error.build.scriptNotFound": "build script not found",
44
49
  "error.dev.scriptNotFound": "dev script not found",
45
- "error.store.permission": 'permission denied, please check the file permission with "{filePath}"'
50
+ "error.store.permission": 'permission denied, please check the file permission with "{filePath}"',
51
+ "error.hostedToken.requestFailed": "failed to request hosted token",
52
+ "error.hostedToken.empty": "hosted token is empty"
46
53
  };
47
54
  const map = {
48
55
  en
@@ -84,49 +91,14 @@ var ErrorCode = ((ErrorCode2) => {
84
91
  ErrorCode2["BUILD_SCRIPT_NOT_FOUND"] = "E09";
85
92
  ErrorCode2["DEV_SCRIPT_NOT_FOUND"] = "E10";
86
93
  ErrorCode2["STORE_PERMISSION"] = "E11";
94
+ ErrorCode2["HOSTED_TOKEN_REQUEST_FAILED"] = "E12";
95
+ ErrorCode2["HOSTED_TOKEN_EMPTY"] = "E13";
87
96
  return ErrorCode2;
88
97
  })(ErrorCode || {});
89
- const AppPackageJSONSchema = z.object({
90
- scripts: z.object({
91
- dev: z.string().optional(),
92
- build: z.string().optional()
93
- }).optional()
94
- });
95
- const AppManifestJSONSchema = z.object({
96
- app: z.object({
97
- id: z.string(),
98
- name: z.string(),
99
- version: z.string(),
100
- logo: z.string().optional(),
101
- desc: z.string().optional(),
102
- base_url: z.string().optional(),
103
- auth: z.object({
104
- type: z.literal("jwt")
105
- }),
106
- ones_version: z.object({
107
- min: z.string(),
108
- max: z.string()
109
- }).optional(),
110
- lifecycle_callback: z.object({
111
- install: z.string(),
112
- enabled: z.string().optional(),
113
- disabled: z.string().optional(),
114
- uninstalled: z.string().optional()
115
- }),
116
- oauth: z.object({
117
- type: z.array(z.enum(["app", "user"])).optional(),
118
- scope: z.array(z.string()),
119
- redirect_url: z.string().optional()
120
- }).optional(),
121
- events: z.object({
122
- url: z.string(),
123
- types: z.array(z.object({
124
- eventType: z.string()
125
- }))
126
- }).optional(),
127
- extensions: z.record(z.unknown()).optional()
128
- })
129
- });
98
+ const getPublicPath = () => {
99
+ const __dirname = dirname(fileURLToPath(import.meta.url));
100
+ return join(__dirname, "../public");
101
+ };
130
102
  const getPackageJSONPath = () => {
131
103
  const __dirname = dirname(fileURLToPath(import.meta.url));
132
104
  return join(__dirname, "../package.json");
@@ -142,6 +114,9 @@ const getPackageJSON = () => {
142
114
  return {};
143
115
  }
144
116
  };
117
+ const getAppWorkspacePath = () => {
118
+ return join(cwd());
119
+ };
145
120
  const getAppPackageJSONPath = () => {
146
121
  return join(cwd(), "./package.json");
147
122
  };
@@ -159,7 +134,7 @@ const getAppPackageJSON = () => {
159
134
  }
160
135
  };
161
136
  const getAppManifestJSONPath = () => {
162
- return join(cwd(), "./opkx.json");
137
+ return join(cwd(), PUBLIC_FILENAME.MANIFEST);
163
138
  };
164
139
  const getAppManifestJSON = () => {
165
140
  const path = getAppManifestJSONPath();
@@ -174,6 +149,43 @@ const getAppManifestJSON = () => {
174
149
  return throwError(ErrorCode.APP_MANIFEST_JSON_PARSE_ERROR, i18n.t("error.schema.app.manifest.parseError"));
175
150
  }
176
151
  };
152
+ const defaultAppRcJSON = {
153
+ dev: {
154
+ command: ["npm run dev"]
155
+ }
156
+ };
157
+ let storeAppRcJSON = null;
158
+ const getAppRcJSON = async () => {
159
+ if (storeAppRcJSON)
160
+ ;
161
+ else {
162
+ try {
163
+ const path = join(getPublicPath$1(), PUBLIC_FILENAME.RC);
164
+ const string = readFileSync(path, {
165
+ encoding: "utf8"
166
+ });
167
+ const json = JSON.parse(string);
168
+ storeAppRcJSON = AppRcJSONSchema.parse(json);
169
+ } catch (error) {
170
+ storeAppRcJSON = {};
171
+ }
172
+ }
173
+ const templateAppRcJSON = storeAppRcJSON || {};
174
+ let currentAppRcJSON;
175
+ const explorer = cosmiconfig("ones");
176
+ try {
177
+ const result = await explorer.search();
178
+ const json = result === null || result === void 0 ? void 0 : result.config;
179
+ currentAppRcJSON = AppRcJSONSchema.parse(json);
180
+ } catch (error) {
181
+ currentAppRcJSON = {};
182
+ }
183
+ return {
184
+ ...defaultAppRcJSON,
185
+ ...templateAppRcJSON,
186
+ ...currentAppRcJSON
187
+ };
188
+ };
177
189
  const isOPKXFilename = /\.opkx$/;
178
190
  const defaultOutputPath = "";
179
191
  const normalize$a = async (options) => {
@@ -191,7 +203,7 @@ const normalize$a = async (options) => {
191
203
  };
192
204
  };
193
205
  const build = async function() {
194
- var _appPackageJSON$scrip;
206
+ var _appPackageJSON$scrip, _appRcJSON$build$comp, _appRcJSON$build;
195
207
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
196
208
  args[_key] = arguments[_key];
197
209
  }
@@ -199,16 +211,55 @@ const build = async function() {
199
211
  options
200
212
  } = getCommandOptions(args, buildCommandArguments);
201
213
  const normalizedOptions = await normalize$a(options);
202
- console.log("build", normalizedOptions);
203
214
  const appPackageJSON = getAppPackageJSON();
204
- console.log("appPackageJSON", appPackageJSON);
205
215
  const appManifestJSON = getAppManifestJSON();
206
- console.log("appManifestJSON", appManifestJSON);
207
- if ((_appPackageJSON$scrip = appPackageJSON.scripts) !== null && _appPackageJSON$scrip !== void 0 && _appPackageJSON$scrip.build)
208
- ;
209
- else {
216
+ const appRcJSON = await getAppRcJSON();
217
+ appManifestJSON.app.name;
218
+ if ((_appPackageJSON$scrip = appPackageJSON.scripts) !== null && _appPackageJSON$scrip !== void 0 && _appPackageJSON$scrip.build) {
219
+ spawnSync("npm", ["run", "build"], {
220
+ cwd: getAppWorkspacePath(),
221
+ stdio: "inherit"
222
+ });
223
+ } else {
210
224
  return throwError(ErrorCode.BUILD_SCRIPT_NOT_FOUND, i18n.t("error.build.scriptNotFound"));
211
225
  }
226
+ const archive = archiver("zip", {
227
+ zlib: {
228
+ level: 9
229
+ }
230
+ });
231
+ archive.on("error", (err) => {
232
+ throw err;
233
+ });
234
+ archive.on("warning", (err) => {
235
+ throw err;
236
+ });
237
+ archive.on("progress", (progress) => {
238
+ const {
239
+ entries,
240
+ fs
241
+ } = progress;
242
+ const entriesStr = entries.total > 0 ? ` ${entries.processed}/${entries.total} files` : "";
243
+ const bytesStr = fs.totalBytes > 0 ? ` ${(fs.processedBytes / 1024).toFixed(1)}/${(fs.totalBytes / 1024).toFixed(1)} KB` : "";
244
+ process.stdout.write(`\rCompressing:${entriesStr}${bytesStr} `);
245
+ });
246
+ archive.on("finish", () => {
247
+ process.stdout.write("\n");
248
+ console.log(`Output file: ${normalizedOptions.output}`);
249
+ console.log(`OPKX "${basename(normalizedOptions.output)}" created successfully!`);
250
+ });
251
+ const outputStream = createWriteStream(normalizedOptions.output);
252
+ archive.pipe(outputStream);
253
+ const files = (_appRcJSON$build$comp = (_appRcJSON$build = appRcJSON.build) === null || _appRcJSON$build === void 0 || (_appRcJSON$build = _appRcJSON$build.compress) === null || _appRcJSON$build === void 0 ? void 0 : _appRcJSON$build.files) !== null && _appRcJSON$build$comp !== void 0 ? _appRcJSON$build$comp : [];
254
+ files.forEach((file) => {
255
+ archive.glob(file, {
256
+ cwd: getAppWorkspacePath()
257
+ });
258
+ });
259
+ archive.file(PUBLIC_FILENAME.MANIFEST, {
260
+ name: PUBLIC_FILENAME.MANIFEST
261
+ });
262
+ archive.finalize();
212
263
  };
213
264
  var InstallOptions = /* @__PURE__ */ ((InstallOptions2) => {
214
265
  InstallOptions2["AUTO"] = "auto";
@@ -285,7 +336,8 @@ const StoreJSONSchema = z.object({
285
336
  timestamp: z.number().optional(),
286
337
  base_url: z.string().optional(),
287
338
  region_url: z.string().optional(),
288
- ones_token: z.string().optional()
339
+ ones_token: z.string().optional(),
340
+ host_token: z.string().optional()
289
341
  });
290
342
  const {
291
343
  ensureFile,
@@ -350,6 +402,11 @@ const mergeStore = async (store) => {
350
402
  ...store
351
403
  });
352
404
  };
405
+ const getBaseURL = async () => {
406
+ var _store$base_url;
407
+ const store = await getStore();
408
+ return (_store$base_url = store.base_url) !== null && _store$base_url !== void 0 ? _store$base_url : "";
409
+ };
353
410
  const setBaseURL = async (baseURL) => {
354
411
  return mergeStore({
355
412
  base_url: baseURL
@@ -375,14 +432,415 @@ const setONESToken = async (token) => {
375
432
  ones_token: token
376
433
  });
377
434
  };
378
- const invokeTunnel = async (port) => {
379
- console.log("invokeTunnel", port);
435
+ class TunnelClient {
436
+ constructor(localPort, baseUrl, appID, hostedToken) {
437
+ _defineProperty(this, "ws", null);
438
+ this.localPort = localPort;
439
+ this.baseUrl = baseUrl;
440
+ this.appID = appID;
441
+ this.hostedToken = hostedToken;
442
+ }
443
+ async connect() {
444
+ const proxyUrl = this.buildProxyUrl();
445
+ this.ws = new WebSocket(proxyUrl, {
446
+ headers: {
447
+ Authorization: `Bearer ${this.hostedToken}`
448
+ }
449
+ });
450
+ this.ws.on("message", async (data) => {
451
+ const message = this.parseMessage(data);
452
+ if (!message) {
453
+ return;
454
+ }
455
+ await this.handleMessage(message);
456
+ });
457
+ this.ws.on("ping", (data) => {
458
+ var _this$ws;
459
+ (_this$ws = this.ws) === null || _this$ws === void 0 || _this$ws.pong(data);
460
+ });
461
+ this.ws.on("error", (error) => {
462
+ console.error("WebSocket error:", error);
463
+ });
464
+ return new Promise((resolve2, reject) => {
465
+ var _this$ws2, _this$ws3;
466
+ (_this$ws2 = this.ws) === null || _this$ws2 === void 0 || _this$ws2.on("open", () => resolve2());
467
+ (_this$ws3 = this.ws) === null || _this$ws3 === void 0 || _this$ws3.on("error", reject);
468
+ });
469
+ }
470
+ close() {
471
+ var _this$ws4;
472
+ (_this$ws4 = this.ws) === null || _this$ws4 === void 0 || _this$ws4.close();
473
+ }
474
+ buildProxyUrl() {
475
+ const url = new URL("/platform/app/relay/", this.baseUrl);
476
+ url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
477
+ url.searchParams.set("app_id", this.appID);
478
+ return url.toString();
479
+ }
480
+ parseMessage(data) {
481
+ const payload = data.toString();
482
+ try {
483
+ const message = JSON.parse(payload);
484
+ if (!message) {
485
+ return null;
486
+ }
487
+ return message;
488
+ } catch (error) {
489
+ console.error("Invalid tunnel message:", error);
490
+ return null;
491
+ }
492
+ }
493
+ async handleMessage(message) {
494
+ const request = this.getRequestPayload(message);
495
+ if (!request) {
496
+ return;
497
+ }
498
+ if (request.path === ONES_CLI_MANIFEST_PATH) {
499
+ var _this$ws5;
500
+ const appManifest = getAppManifestJSON().app;
501
+ const baseURL = await buildTunnelUrl();
502
+ const reply = {
503
+ id: message.id,
504
+ payload: {
505
+ status: 200,
506
+ headers: {
507
+ "content-type": ["application/json"]
508
+ },
509
+ body: {
510
+ ...appManifest,
511
+ base_url: baseURL
512
+ }
513
+ }
514
+ };
515
+ (_this$ws5 = this.ws) === null || _this$ws5 === void 0 || _this$ws5.send(JSON.stringify(reply));
516
+ return;
517
+ }
518
+ try {
519
+ var _this$ws6;
520
+ const response = await this.forwardRequest(request);
521
+ const reply = {
522
+ id: message.id,
523
+ payload: response
524
+ };
525
+ (_this$ws6 = this.ws) === null || _this$ws6 === void 0 || _this$ws6.send(JSON.stringify(reply));
526
+ } catch (error) {
527
+ var _this$ws7;
528
+ const reply = {
529
+ id: message.id,
530
+ payload: {
531
+ status: 500,
532
+ headers: {
533
+ "x-agent-error": [error instanceof Error ? error.message : "Unknown error"]
534
+ },
535
+ body: "agent request error"
536
+ }
537
+ };
538
+ (_this$ws7 = this.ws) === null || _this$ws7 === void 0 || _this$ws7.send(JSON.stringify(reply));
539
+ }
540
+ }
541
+ getRequestPayload(message) {
542
+ const payload = message.payload;
543
+ if (!(payload !== null && payload !== void 0 && payload.method) || !(payload !== null && payload !== void 0 && payload.path)) {
544
+ return null;
545
+ }
546
+ return payload;
547
+ }
548
+ async forwardRequest(payload) {
549
+ const url = new URL(payload.path, `http://127.0.0.1:${this.localPort}`);
550
+ if (payload.query) {
551
+ Object.entries(payload.query).forEach((_ref) => {
552
+ let [key, value] = _ref;
553
+ url.searchParams.set(key, value);
554
+ });
555
+ }
556
+ const headers = this.normalizeHeaders(payload.headers);
557
+ const body = this.normalizeBody(payload.body);
558
+ const response = await axios.request({
559
+ url: url.toString(),
560
+ method: payload.method,
561
+ headers,
562
+ data: body,
563
+ responseType: "text",
564
+ validateStatus: () => true
565
+ });
566
+ return {
567
+ status: response.status,
568
+ headers: this.collectHeaders(response.headers),
569
+ body: this.normalizeResponseBody(response.data)
570
+ };
571
+ }
572
+ normalizeHeaders(headers) {
573
+ if (!headers) {
574
+ return void 0;
575
+ }
576
+ const normalized = {};
577
+ Object.entries(headers).forEach((_ref2) => {
578
+ let [key, values] = _ref2;
579
+ if (!values || values.length === 0) {
580
+ return;
581
+ }
582
+ normalized[key] = values.join(",");
583
+ });
584
+ return normalized;
585
+ }
586
+ collectHeaders(headers) {
587
+ const collected = {};
588
+ Object.entries(headers).forEach((_ref3) => {
589
+ let [key, value] = _ref3;
590
+ if (Array.isArray(value)) {
591
+ collected[key] = value.map((item) => String(item));
592
+ return;
593
+ }
594
+ if (value !== void 0 && value !== null) {
595
+ collected[key] = [String(value)];
596
+ }
597
+ });
598
+ return collected;
599
+ }
600
+ normalizeBody(body) {
601
+ if (body === void 0 || body === null) {
602
+ return void 0;
603
+ }
604
+ if (typeof body === "string") {
605
+ return body;
606
+ }
607
+ return JSON.stringify(body);
608
+ }
609
+ normalizeResponseBody(body) {
610
+ if (!body) {
611
+ return void 0;
612
+ }
613
+ try {
614
+ return JSON.parse(body);
615
+ } catch {
616
+ return body;
617
+ }
618
+ }
619
+ }
620
+ const getPath = (path, map2) => {
621
+ var _context;
622
+ return _reduceInstanceProperty(_context = path.split("/")).call(_context, (base, part) => {
623
+ if (/^:/.test(part)) {
624
+ return `${base}/${map2[part.slice(1)]}`;
625
+ }
626
+ return `${base}/${part}`;
627
+ }, "").slice(1);
628
+ };
629
+ const consoleUnauthorizedMessage = () => {
630
+ console.log("Not logged in");
631
+ console.log('Login with "ones login" command');
632
+ };
633
+ const getURL = async (path, pathMap, queryMap) => {
634
+ const base = await getRegionURL();
635
+ if (base) {
636
+ const query = new URLSearchParams(queryMap !== null && queryMap !== void 0 ? queryMap : {}).toString();
637
+ return `${base}${getPath(path, pathMap !== null && pathMap !== void 0 ? pathMap : {})}${query ? `?${query}` : ""}`;
638
+ }
639
+ consoleUnauthorizedMessage();
640
+ exit(1);
641
+ };
642
+ const getHeaders = async (value) => {
643
+ const token = await getONESToken();
644
+ if (token) {
645
+ return merge({
646
+ Authorization: `Bearer ${token}`
647
+ }, value);
648
+ }
649
+ consoleUnauthorizedMessage();
650
+ exit(1);
651
+ };
652
+ const handleError = (error) => {
653
+ var _error$response;
654
+ if (((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) === 401) {
655
+ console.log(error.response.statusText);
656
+ consoleUnauthorizedMessage();
657
+ } else {
658
+ console.error(error);
659
+ }
660
+ return {};
661
+ };
662
+ const API = {
663
+ TOKEN_INFO: "/project/api/project/auth/token_info",
664
+ HOSTED_TOKEN: "/platform/runtime_manager/hosted_token",
665
+ APP_LIST: "/platform/api/app/list",
666
+ APP_INSTALL: "/platform/api/app/install",
667
+ APP_UPGRADE: "/platform/api/app/upgrade",
668
+ APP_UNINSTALL: "/platform/api/app/:installation_id/uninstall",
669
+ APP_ENABLE: "/platform/api/app/:installation_id/enable",
670
+ APP_DISABLE: "/platform/api/app/:installation_id/disable"
671
+ };
672
+ const isRecord = (value) => {
673
+ return typeof value === "object" && value !== null;
674
+ };
675
+ const getHostedTokenScopes = (ones2) => {
676
+ const storage = ones2 === null || ones2 === void 0 ? void 0 : ones2.storage;
677
+ if (!storage) {
678
+ return [];
679
+ }
680
+ const scopes = /* @__PURE__ */ new Set();
681
+ if (Array.isArray(storage.entities) && storage.entities.length > 0) {
682
+ scopes.add(HostedTokenScope.STORAGE_ENTITY);
683
+ }
684
+ if (storage.object !== void 0 && storage.object !== null && storage.object !== false) {
685
+ scopes.add(HostedTokenScope.STORAGE_OBJECT);
686
+ }
687
+ return Array.from(scopes);
688
+ };
689
+ const getRelayScope = () => {
690
+ return HostedTokenScope.RELAY;
691
+ };
692
+ const getHostToken = async (baseUrl, userToken, appID, scopes) => {
693
+ const url = `${baseUrl.replace(/\/$/, "")}${API.HOSTED_TOKEN}`;
694
+ return axios.post(url, {
695
+ app_id: appID,
696
+ scopes
697
+ }, {
698
+ headers: {
699
+ Authorization: `Bearer ${userToken}`
700
+ }
701
+ }).then((resp) => {
702
+ const data = resp === null || resp === void 0 ? void 0 : resp.data;
703
+ const tokenFromData = (value) => {
704
+ if (isRecord(value) && isRecord(value.data)) {
705
+ const hosted_token = value.data.hosted_token;
706
+ if (typeof hosted_token === "string" && hosted_token.length > 0) {
707
+ return hosted_token;
708
+ }
709
+ }
710
+ return null;
711
+ };
712
+ const token = tokenFromData(data);
713
+ if (token) {
714
+ return token;
715
+ }
716
+ return throwError(ErrorCode.HOSTED_TOKEN_EMPTY, i18n.t("error.hostedToken.empty"));
717
+ }).catch((error) => {
718
+ handleError(error);
719
+ return throwError(ErrorCode.HOSTED_TOKEN_REQUEST_FAILED, i18n.t("error.hostedToken.requestFailed"));
720
+ });
721
+ };
722
+ const fetchAppBase = async (params) => {
723
+ var _params$url;
724
+ const url = await getURL((_params$url = params.url) !== null && _params$url !== void 0 ? _params$url : "", params.pathMap, params.queryMap);
725
+ const headers = await getHeaders(params.headers);
726
+ const response = await axios({
727
+ ...params,
728
+ url,
729
+ headers
730
+ });
731
+ return response.data;
732
+ };
733
+ const fetchAppList = async (appID) => {
734
+ return await fetchAppBase({
735
+ url: API.APP_LIST,
736
+ method: "GET",
737
+ queryMap: {
738
+ app_id: appID
739
+ }
740
+ }).catch(handleError);
741
+ };
742
+ const fetchTokenInfo = async () => {
743
+ return await fetchAppBase({
744
+ url: API.TOKEN_INFO,
745
+ method: "GET"
746
+ }).catch(handleError);
747
+ };
748
+ const fetchAppInstall = async (data) => {
749
+ var _appList$data$0$insta, _appList$data;
750
+ const appID = getAppManifestJSON().app.id;
751
+ const appList = await fetchAppList(appID);
752
+ const installationID = (_appList$data$0$insta = (_appList$data = appList.data) === null || _appList$data === void 0 || (_appList$data = _appList$data[0]) === null || _appList$data === void 0 ? void 0 : _appList$data.installation_id) !== null && _appList$data$0$insta !== void 0 ? _appList$data$0$insta : "";
753
+ const url = installationID ? API.APP_UPGRADE : API.APP_INSTALL;
754
+ return await fetchAppBase({
755
+ url,
756
+ method: "POST",
757
+ data
758
+ }).catch(handleError);
759
+ };
760
+ const fetchAppUninstall = async () => {
761
+ var _appList$data$0$insta2, _appList$data2;
762
+ const appID = getAppManifestJSON().app.id;
763
+ const appList = await fetchAppList(appID);
764
+ const installationID = (_appList$data$0$insta2 = (_appList$data2 = appList.data) === null || _appList$data2 === void 0 || (_appList$data2 = _appList$data2[0]) === null || _appList$data2 === void 0 ? void 0 : _appList$data2.installation_id) !== null && _appList$data$0$insta2 !== void 0 ? _appList$data$0$insta2 : "";
765
+ return await fetchAppBase({
766
+ url: API.APP_UNINSTALL,
767
+ method: "POST",
768
+ pathMap: {
769
+ installation_id: installationID
770
+ }
771
+ }).catch(handleError);
772
+ };
773
+ const fetchAppEnable = async () => {
774
+ var _appList$data$0$insta3, _appList$data3;
775
+ const appID = getAppManifestJSON().app.id;
776
+ const appList = await fetchAppList(appID);
777
+ const installationID = (_appList$data$0$insta3 = (_appList$data3 = appList.data) === null || _appList$data3 === void 0 || (_appList$data3 = _appList$data3[0]) === null || _appList$data3 === void 0 ? void 0 : _appList$data3.installation_id) !== null && _appList$data$0$insta3 !== void 0 ? _appList$data$0$insta3 : "";
778
+ return await fetchAppBase({
779
+ url: API.APP_ENABLE,
780
+ method: "POST",
781
+ pathMap: {
782
+ installation_id: installationID
783
+ }
784
+ }).catch(handleError);
785
+ };
786
+ const fetchAppDisable = async () => {
787
+ var _appList$data$0$insta4, _appList$data4;
788
+ const appID = getAppManifestJSON().app.id;
789
+ const appList = await fetchAppList(appID);
790
+ const installationID = (_appList$data$0$insta4 = (_appList$data4 = appList.data) === null || _appList$data4 === void 0 || (_appList$data4 = _appList$data4[0]) === null || _appList$data4 === void 0 ? void 0 : _appList$data4.installation_id) !== null && _appList$data$0$insta4 !== void 0 ? _appList$data$0$insta4 : "";
791
+ return await fetchAppBase({
792
+ url: API.APP_DISABLE,
793
+ method: "POST",
794
+ pathMap: {
795
+ installation_id: installationID
796
+ }
797
+ }).catch(handleError);
798
+ };
799
+ const ONES_CLI_MANIFEST_PATH = "/__ones_cli_manifest__";
800
+ const buildTunnelContext = async () => {
801
+ var _appManifestJSON$app$, _appManifestJSON$app;
380
802
  const appManifestJSON = getAppManifestJSON();
381
- console.log("appManifestJSON", appManifestJSON);
803
+ const appID = (_appManifestJSON$app$ = (_appManifestJSON$app = appManifestJSON.app) === null || _appManifestJSON$app === void 0 ? void 0 : _appManifestJSON$app.id) !== null && _appManifestJSON$app$ !== void 0 ? _appManifestJSON$app$ : "";
804
+ if (!appID) {
805
+ throw new Error("app id is empty");
806
+ }
382
807
  const regionURL = await getRegionURL();
808
+ if (!regionURL) {
809
+ throw new Error("region url is empty");
810
+ }
811
+ return {
812
+ appManifestJSON,
813
+ appID,
814
+ regionURL
815
+ };
816
+ };
817
+ const buildTunnelUrl = async () => {
818
+ const {
819
+ appID,
820
+ regionURL
821
+ } = await buildTunnelContext();
822
+ const url = new URL(regionURL);
823
+ return `${url.protocol}//${url.host}/platform/app/relay/dispatch/${appID}`;
824
+ };
825
+ const invokeTunnel = async (port) => {
826
+ const {
827
+ appManifestJSON,
828
+ appID,
829
+ regionURL
830
+ } = await buildTunnelContext();
383
831
  const onesToken = await getONESToken();
384
- console.log("regionURL", regionURL);
385
- console.log("onesToken", onesToken);
832
+ if (!onesToken) {
833
+ consoleUnauthorizedMessage();
834
+ exit(1);
835
+ }
836
+ const storageScopes = getHostedTokenScopes(appManifestJSON.ones);
837
+ const scopes = Array.from(/* @__PURE__ */ new Set([...storageScopes, getRelayScope()]));
838
+ const hostedToken = await getHostToken(regionURL, onesToken, appID, scopes);
839
+ process.env.ONES_HOSTED_TOKEN = hostedToken;
840
+ const client = new TunnelClient(port, regionURL, appID, hostedToken);
841
+ await client.connect();
842
+ const runnelUrl = await buildTunnelUrl();
843
+ console.log(`Relay endpoint: ${runnelUrl}`);
386
844
  };
387
845
  const tunnel = async function() {
388
846
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
@@ -392,18 +850,15 @@ const tunnel = async function() {
392
850
  options
393
851
  } = getCommandOptions(args, tunnelCommandArguments);
394
852
  const normalizedOptions = await normalize$8(options);
395
- await invokeTunnel(normalizedOptions.port);
853
+ await invokeTunnel(Number(normalizedOptions.port));
396
854
  };
397
855
  const config = {
398
856
  defaultPort: {
399
- login: 8200
857
+ login: 8200,
858
+ tunnel: 8201
400
859
  }
401
860
  };
402
861
  const getConfig = () => config;
403
- const getPublicPath = () => {
404
- const __dirname = dirname(fileURLToPath(import.meta.url));
405
- return join(__dirname, "../public");
406
- };
407
862
  function createPromise() {
408
863
  let resolve2;
409
864
  let reject;
@@ -479,6 +934,10 @@ const login = async function() {
479
934
  const html = readFileSync(htmlPath, {
480
935
  encoding: "utf-8"
481
936
  });
937
+ const logoPath = join(publicPath, "logo.svg");
938
+ const logo = readFileSync(logoPath, {
939
+ encoding: "utf-8"
940
+ });
482
941
  const {
483
942
  promise,
484
943
  resolve: resolve2
@@ -487,6 +946,21 @@ const login = async function() {
487
946
  var _req$url$split$, _req$url, _search2$get, _search2$get2;
488
947
  const search2 = new URLSearchParams((_req$url$split$ = (_req$url = req.url) === null || _req$url === void 0 ? void 0 : _req$url.split("?")[1]) !== null && _req$url$split$ !== void 0 ? _req$url$split$ : "");
489
948
  const state = search2.get("state");
949
+ if (state === "logo") {
950
+ res.writeHead(200, {
951
+ "Content-Type": "image/svg+xml"
952
+ });
953
+ res.end(logo);
954
+ return;
955
+ }
956
+ if (state === "cancel") {
957
+ res.writeHead(200, {
958
+ "Content-Type": "image/svg+xml"
959
+ });
960
+ res.end(logo);
961
+ resolve2(null);
962
+ return;
963
+ }
490
964
  const token = (_search2$get = search2.get("access_token")) !== null && _search2$get !== void 0 ? _search2$get : "";
491
965
  const region = (_search2$get2 = search2.get("region_url")) !== null && _search2$get2 !== void 0 ? _search2$get2 : "";
492
966
  if (state === uuid && token && region) {
@@ -495,22 +969,31 @@ const login = async function() {
495
969
  ones_token: token,
496
970
  region_url: region
497
971
  });
972
+ res.writeHead(200, {
973
+ "Content-Type": "text/html"
974
+ });
975
+ res.end(html);
976
+ return;
498
977
  }
499
978
  res.writeHead(200, {
500
979
  "Content-Type": "text/html"
501
980
  });
502
- res.end(html);
981
+ res.end("Invalid state error, please try again!");
503
982
  });
504
983
  server.listen(port);
505
984
  promise.then(async (store) => {
506
- var _store$base_url, _store$ones_token, _store$region_url;
507
985
  await sleep(100);
508
986
  server.closeAllConnections();
509
- await setBaseURL((_store$base_url = store.base_url) !== null && _store$base_url !== void 0 ? _store$base_url : "");
510
- await setONESToken((_store$ones_token = store.ones_token) !== null && _store$ones_token !== void 0 ? _store$ones_token : "");
511
- await setRegionURL((_store$region_url = store.region_url) !== null && _store$region_url !== void 0 ? _store$region_url : "");
512
- console.log("Logged in successfully!");
513
- process.exit(0);
987
+ if (store) {
988
+ var _store$base_url, _store$ones_token, _store$region_url;
989
+ await setBaseURL((_store$base_url = store.base_url) !== null && _store$base_url !== void 0 ? _store$base_url : "");
990
+ await setONESToken((_store$ones_token = store.ones_token) !== null && _store$ones_token !== void 0 ? _store$ones_token : "");
991
+ await setRegionURL((_store$region_url = store.region_url) !== null && _store$region_url !== void 0 ? _store$region_url : "");
992
+ console.log("Logged in successfully!");
993
+ } else {
994
+ console.log("Login canceled!");
995
+ }
996
+ process$1.exit(0);
514
997
  });
515
998
  console.log("Logging into your ONES account...");
516
999
  console.log(`Opening ${url}`);
@@ -533,120 +1016,6 @@ const logout = async function() {
533
1016
  await setStore({});
534
1017
  console.log("Logged out successfully!");
535
1018
  };
536
- const API = {
537
- TOKEN_INFO: "/project/api/project/auth/token_info",
538
- APP_LIST: "/platform/api/app/list",
539
- APP_INSTALL: "/app/install",
540
- APP_UNINSTALL: "/app/uninstall",
541
- APP_ENABLE: "/platform/api/app/:installation_id/enable",
542
- APP_DISABLE: "/platform/api/app/:installation_id/disable"
543
- };
544
- const getPath = (path, map2) => {
545
- var _context;
546
- return _reduceInstanceProperty(_context = path.split("/")).call(_context, (base, part) => {
547
- if (/^:/.test(part)) {
548
- return `${base}/${map2[part.slice(1)]}`;
549
- }
550
- return `${base}/${part}`;
551
- }, "").slice(1);
552
- };
553
- const consoleUnauthorizedMessage = () => {
554
- console.log("Not logged in");
555
- console.log('Login with "ones login" command');
556
- };
557
- const getURL = async (path, pathMap, queryMap) => {
558
- const base = await getRegionURL();
559
- if (base) {
560
- const query = new URLSearchParams(queryMap !== null && queryMap !== void 0 ? queryMap : {}).toString();
561
- return `${base}${getPath(path, pathMap !== null && pathMap !== void 0 ? pathMap : {})}${query ? `?${query}` : ""}`;
562
- }
563
- consoleUnauthorizedMessage();
564
- exit(1);
565
- };
566
- const getHeaders = async (value) => {
567
- const token = await getONESToken();
568
- if (token) {
569
- return merge({
570
- Authorization: `Bearer ${token}`
571
- }, value);
572
- }
573
- consoleUnauthorizedMessage();
574
- exit(1);
575
- };
576
- const handleError = (error) => {
577
- var _error$response;
578
- if (((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) === 401) {
579
- console.log(error.response.statusText);
580
- consoleUnauthorizedMessage();
581
- } else {
582
- console.error(error);
583
- }
584
- return {};
585
- };
586
- const fetchAppBase = async (params) => {
587
- var _params$url;
588
- const url = await getURL((_params$url = params.url) !== null && _params$url !== void 0 ? _params$url : "", params.pathMap, params.queryMap);
589
- const headers = await getHeaders(params.headers);
590
- const response = await axios({
591
- ...params,
592
- url,
593
- headers
594
- });
595
- return response.data;
596
- };
597
- const fetchAppList = async (appID) => {
598
- return await fetchAppBase({
599
- url: API.APP_LIST,
600
- method: "GET",
601
- queryMap: {
602
- app_id: appID
603
- }
604
- }).catch(handleError);
605
- };
606
- const fetchTokenInfo = async () => {
607
- return await fetchAppBase({
608
- url: API.TOKEN_INFO,
609
- method: "GET"
610
- }).catch(handleError);
611
- };
612
- const fetchAppInstall = async () => {
613
- return await fetchAppBase({
614
- url: API.APP_INSTALL,
615
- method: "POST"
616
- }).catch(handleError);
617
- };
618
- const fetchAppUninstall = async () => {
619
- return await fetchAppBase({
620
- url: API.APP_UNINSTALL,
621
- method: "POST"
622
- }).catch(handleError);
623
- };
624
- const fetchAppEnable = async () => {
625
- var _appList$data$0$insta, _appList$data;
626
- const appID = getAppManifestJSON().app.id;
627
- const appList = await fetchAppList(appID);
628
- const installationID = (_appList$data$0$insta = (_appList$data = appList.data) === null || _appList$data === void 0 || (_appList$data = _appList$data[0]) === null || _appList$data === void 0 ? void 0 : _appList$data.installation_id) !== null && _appList$data$0$insta !== void 0 ? _appList$data$0$insta : "";
629
- return await fetchAppBase({
630
- url: API.APP_ENABLE,
631
- method: "POST",
632
- pathMap: {
633
- installation_id: installationID
634
- }
635
- }).catch(handleError);
636
- };
637
- const fetchAppDisable = async () => {
638
- var _appList$data$0$insta2, _appList$data2;
639
- const appID = getAppManifestJSON().app.id;
640
- const appList = await fetchAppList(appID);
641
- const installationID = (_appList$data$0$insta2 = (_appList$data2 = appList.data) === null || _appList$data2 === void 0 || (_appList$data2 = _appList$data2[0]) === null || _appList$data2 === void 0 ? void 0 : _appList$data2.installation_id) !== null && _appList$data$0$insta2 !== void 0 ? _appList$data$0$insta2 : "";
642
- return await fetchAppBase({
643
- url: API.APP_DISABLE,
644
- method: "POST",
645
- pathMap: {
646
- installation_id: installationID
647
- }
648
- }).catch(handleError);
649
- };
650
1019
  const normalize$5 = async (options) => {
651
1020
  noop(options);
652
1021
  return {};
@@ -661,11 +1030,13 @@ const whoami = async function() {
661
1030
  } = getCommandOptions(args, whoamiCommandArguments);
662
1031
  const normalizedOptions = await normalize$5(options);
663
1032
  noop(normalizedOptions);
1033
+ const baseURL = await getBaseURL();
664
1034
  const tokenInfo = await fetchTokenInfo();
665
1035
  const name2 = (_tokenInfo$user = tokenInfo.user) === null || _tokenInfo$user === void 0 ? void 0 : _tokenInfo$user.name;
666
1036
  const email = (_tokenInfo$user2 = tokenInfo.user) === null || _tokenInfo$user2 === void 0 ? void 0 : _tokenInfo$user2.email;
667
1037
  if (name2 && email) {
668
1038
  console.log(`${name2} <${email}>`);
1039
+ console.log(`ONES: ${baseURL}`);
669
1040
  } else {
670
1041
  consoleUnauthorizedMessage();
671
1042
  }
@@ -683,7 +1054,11 @@ const install = async function() {
683
1054
  } = getCommandOptions(args, installCommandArguments);
684
1055
  const normalizedOptions = await normalize$4(options);
685
1056
  noop(normalizedOptions);
686
- const result = await fetchAppInstall();
1057
+ await invokeTunnel(getConfig().defaultPort.tunnel);
1058
+ const runnelUrl = await buildTunnelUrl();
1059
+ const result = await fetchAppInstall({
1060
+ manifest_url: `${runnelUrl}${ONES_CLI_MANIFEST_PATH}`
1061
+ });
687
1062
  if (result.code === "OK") {
688
1063
  console.log("App installed successfully!");
689
1064
  } else {