arcadible 0.1.19 → 0.1.20

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.
@@ -30,15 +30,17 @@ const main = function (argv) {
30
30
  yargs(hideBin(argv))
31
31
  .scriptName(CMD)
32
32
  .usage("$0 <command> [options]")
33
- .command("init", "Initialize a project")
34
- .command("validate", "Validate project workspace")
35
- .command("deploy", "Deploy to Arcadible")
33
+ .command("init", "Initialize project")
36
34
  .command("inspect", "Inspect project")
37
- .command("count", "Show game counts")
35
+ .command("validate", "Validate project")
36
+ .command("build", "Build project")
37
+ .command("pack", "Package project")
38
+ .command("deploy", "Deploy project")
39
+ .command("open", "Open a game's store page")
38
40
  .command("play", "Play a game")
39
41
  .command("login", "Log in to Arcadible")
40
- .command("logout", "Log out of Arcadible")
41
42
  .command("whoami", "Show Arcadible account")
43
+ .command("logout", "Log out of Arcadible")
42
44
  .help("help")
43
45
  .alias("help", "h")
44
46
  .version(pkg.version)
package/bin/arc-deploy.js CHANGED
@@ -42,8 +42,8 @@ const SUBCMD = "deploy";
42
42
  // [define]
43
43
 
44
44
  const conf = {
45
- git: false,
46
45
  json: false,
46
+ method: "direct",
47
47
  quiet: false,
48
48
  ...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
49
49
  };
@@ -97,7 +97,7 @@ const handler = function ({ json, pb, quiet, sw }) {
97
97
  // [function]
98
98
 
99
99
  const start = function (argv) {
100
- const git = argv.git;
100
+ const git = argv.method === "git";
101
101
  const json = argv.json;
102
102
  const quiet = argv.quiet;
103
103
  const root = resolve(process.cwd(), argv.cwd);
@@ -110,7 +110,7 @@ const start = function (argv) {
110
110
  throw new Error(phrase.issuesFound(count));
111
111
  }
112
112
  sw.stop();
113
- sw = new SpinnerWheel("Checking login... %s");
113
+ sw = new SpinnerWheel("Checking... %s");
114
114
  return whoami({ handler: handler({ json, pb, quiet, sw }) });
115
115
  })
116
116
  .then((current) => {
@@ -211,12 +211,15 @@ const main = function (argv) {
211
211
  return start(
212
212
  yargs(hideBin(argv))
213
213
  .scriptName(`${CMD} ${SUBCMD}`)
214
- .usage("$0 [options]")
215
- .option("git", {
216
- default: conf.git,
217
- describe: "Deploy using Git workflow",
218
- type: "boolean",
219
- })
214
+ .usage("$0 [method] [options]")
215
+ .command("$0 [method]", false, (cli) =>
216
+ cli.positional("method", {
217
+ choices: ["direct", "git"],
218
+ default: conf.method,
219
+ describe: "Deploy method",
220
+ type: "string",
221
+ }),
222
+ )
220
223
  .option("json", {
221
224
  alias: "j",
222
225
  default: conf.json,
package/bin/arc-init.js CHANGED
@@ -73,14 +73,13 @@ const handler = function ({ json, quiet, sw }) {
73
73
  const start = function (argv) {
74
74
  const json = argv.json;
75
75
  const quiet = argv.quiet;
76
- const root = resolve(process.cwd(), argv.cwd);
77
76
  const sw = new SpinnerWheel("Initializing... %s");
78
77
  return init({
79
78
  force: true,
80
79
  handler: handler({ json, quiet, sw }),
81
80
  patch: argv.patch,
82
81
  project: argv.project,
83
- root,
82
+ root: resolve(process.cwd(), argv.cwd),
84
83
  template: argv.template,
85
84
  })
86
85
  .then((project) => {
@@ -17,12 +17,14 @@ const log = require("../src/util/log");
17
17
  const output = require("../src/util/output");
18
18
  const pkg = require("../package.json");
19
19
  const rc = require("../src/util/rc");
20
+ const spinner = require("../src/util/spinner");
20
21
 
21
22
  // [use]
22
23
 
23
24
  const findRc = rc.findRc;
24
25
  const print = output.print;
25
26
  const resolve = path.resolve;
27
+ const SpinnerWheel = spinner.SpinnerWheel;
26
28
 
27
29
  // [declare]
28
30
 
@@ -32,30 +34,47 @@ const SUBCMD = "inspect";
32
34
  // [define]
33
35
 
34
36
  const conf = {
35
- game: "self",
36
37
  json: false,
37
- selector: "",
38
+ selector: null,
38
39
  ...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
39
40
  };
40
41
 
41
42
  // [function]
42
43
 
44
+ const handler = function ({ json, sw }) {
45
+ return {
46
+ onInspectFetch() {
47
+ sw.start(json);
48
+ },
49
+ };
50
+ };
51
+
52
+ // [function]
53
+
43
54
  const start = function (argv) {
44
55
  const json = argv.json;
45
56
  const selector = argv.selector;
57
+ const sw = new SpinnerWheel("Loading... %s");
46
58
  return inspect({
47
- game: argv.game,
59
+ game: null,
60
+ handler: handler({ json, sw }),
48
61
  root: resolve(process.cwd(), argv.cwd),
49
62
  selector,
50
63
  })
51
64
  .then((data) => {
52
- print(data, { key: selector, toml: !json });
65
+ if (json) {
66
+ print(data);
67
+ return;
68
+ }
69
+ sw.stop(true);
70
+ print(data, { key: selector, toml: true });
53
71
  })
54
72
  .catch((ex) => {
55
73
  const message = ex.message;
56
74
  if (json) {
57
75
  print({ error: { message } });
58
76
  } else {
77
+ sw.stop(true);
59
78
  log.hd("Inspect aborted.");
60
79
  log.p(message);
61
80
  }
@@ -77,12 +96,6 @@ const main = function (argv) {
77
96
  type: "string",
78
97
  }),
79
98
  )
80
- .option("game", {
81
- alias: "g",
82
- default: conf.game,
83
- describe: "Game handle or ID",
84
- type: "string",
85
- })
86
99
  .option("json", {
87
100
  alias: "j",
88
101
  default: conf.json,
package/bin/arc-login.js CHANGED
@@ -4,7 +4,6 @@
4
4
  // [import]
5
5
 
6
6
  const hideBin = require("yargs/helpers").hideBin;
7
- const open = require("open");
8
7
  const qrcode = require("qrcode-terminal");
9
8
  const yargs = require("yargs/yargs");
10
9
 
@@ -14,11 +13,13 @@ const log = require("../src/util/log");
14
13
  const login = require("../src/cli/login");
15
14
  const pkg = require("../package.json");
16
15
  const rc = require("../src/util/rc");
16
+ const shell = require("../src/util/shell");
17
17
  const spinner = require("../src/util/spinner");
18
18
 
19
19
  // [use]
20
20
 
21
21
  const findRc = rc.findRc;
22
+ const launch = shell.launch;
22
23
  const SpinnerWheel = spinner.SpinnerWheel;
23
24
 
24
25
  // [declare]
@@ -77,7 +78,7 @@ const handler = function ({ browser, qrcode: qr, sw }) {
77
78
  if (browser) {
78
79
  log.nlp("Press Enter to open the URL.");
79
80
  onLoginEnter(() => {
80
- open(link).catch(() => {});
81
+ launch(link);
81
82
  });
82
83
  }
83
84
  });
package/bin/arc-logout.js CHANGED
@@ -11,18 +11,32 @@ const yargs = require("yargs/yargs");
11
11
  const log = require("../src/util/log");
12
12
  const logout = require("../src/cli/logout");
13
13
  const pkg = require("../package.json");
14
+ const rc = require("../src/util/rc");
15
+
16
+ // [use]
17
+
18
+ const findRc = rc.findRc;
14
19
 
15
20
  // [declare]
16
21
 
17
22
  const CMD = "arc";
18
23
  const SUBCMD = "logout";
19
24
 
25
+ // [define]
26
+
27
+ const conf = {
28
+ quiet: false,
29
+ ...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
30
+ };
31
+
20
32
  // [function]
21
33
 
22
- const start = function () {
34
+ const start = function (argv) {
23
35
  return logout()
24
36
  .then(() => {
25
- log.hs("Logged out.");
37
+ if (!argv.quiet) {
38
+ log.hs("Logged out.");
39
+ }
26
40
  })
27
41
  .catch((ex) => {
28
42
  log.hd("Logout aborted.");
@@ -38,6 +52,12 @@ const main = function (argv) {
38
52
  yargs(hideBin(argv))
39
53
  .scriptName(`${CMD} ${SUBCMD}`)
40
54
  .usage("$0 [options]")
55
+ .option("quiet", {
56
+ alias: "q",
57
+ default: conf.quiet,
58
+ describe: "Output only errors",
59
+ type: "boolean",
60
+ })
41
61
  .help("help")
42
62
  .alias("help", "h")
43
63
  .version(pkg.version)
@@ -12,53 +12,54 @@ const yargs = require("yargs/yargs");
12
12
 
13
13
  // [import]
14
14
 
15
- const count = require("../src/cli/count");
15
+ const cfguri = require("../src/config/uri");
16
16
  const log = require("../src/util/log");
17
- const output = require("../src/util/output");
17
+ const open = require("../src/cli/open");
18
+ const phrase = require("../src/phrase");
18
19
  const pkg = require("../package.json");
19
20
  const rc = require("../src/util/rc");
21
+ const shell = require("../src/util/shell");
20
22
 
21
23
  // [use]
22
24
 
23
25
  const findRc = rc.findRc;
24
- const print = output.print;
26
+ const launch = shell.launch;
25
27
  const resolve = path.resolve;
26
28
 
27
29
  // [declare]
28
30
 
29
31
  const CMD = "arc";
30
- const SUBCMD = "count";
32
+ const SUBCMD = "open";
31
33
 
32
34
  // [define]
33
35
 
34
36
  const conf = {
37
+ browser: false,
35
38
  game: "self",
36
- json: false,
37
- selector: "",
38
39
  ...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
39
40
  };
40
41
 
41
42
  // [function]
42
43
 
43
44
  const start = function (argv) {
44
- const json = argv.json;
45
- const selector = argv.selector;
46
- return count({
45
+ return open({
47
46
  game: argv.game,
48
47
  root: resolve(process.cwd(), argv.cwd),
49
- selector,
50
48
  })
51
49
  .then((data) => {
52
- print(data, { key: selector, toml: !json });
50
+ const page = data?.page;
51
+ if (!page) {
52
+ throw new Error(phrase.noGameId());
53
+ }
54
+ launch(
55
+ argv.browser
56
+ ? `${cfguri.HOST_HTTP_WWW}${page}`
57
+ : `${cfguri.HOST_APP_STORE}${page}`,
58
+ );
53
59
  })
54
60
  .catch((ex) => {
55
- const message = ex.message;
56
- if (json) {
57
- print({ error: { message } });
58
- } else {
59
- log.hd("Count aborted.");
60
- log.p(message);
61
- }
61
+ log.hd("Open aborted.");
62
+ log.p(ex.message);
62
63
  process.exit(1);
63
64
  });
64
65
  };
@@ -69,24 +70,17 @@ const main = function (argv) {
69
70
  return start(
70
71
  yargs(hideBin(argv))
71
72
  .scriptName(`${CMD} ${SUBCMD}`)
72
- .usage("$0 [selector] [options]")
73
- .command("$0 [selector]", false, (cli) =>
74
- cli.positional("selector", {
75
- default: conf.selector,
76
- describe: "Property selector",
73
+ .usage("$0 [game] [options]")
74
+ .command("$0 [game]", false, (cli) =>
75
+ cli.positional("game", {
76
+ default: conf.game,
77
+ describe: "Game handle or ID",
77
78
  type: "string",
78
79
  }),
79
80
  )
80
- .option("game", {
81
- alias: "g",
82
- default: conf.game,
83
- describe: "Game handle or ID",
84
- type: "string",
85
- })
86
- .option("json", {
87
- alias: "j",
88
- default: conf.json,
89
- describe: "Format output as JSON",
81
+ .option("browser", {
82
+ default: conf.browser,
83
+ describe: "Open in a web browser",
90
84
  type: "boolean",
91
85
  })
92
86
  .option("cwd", {
package/bin/arc-pack.js CHANGED
@@ -12,6 +12,7 @@ const yargs = require("yargs/yargs");
12
12
 
13
13
  // [import]
14
14
 
15
+ const cfgworkflow = require("../src/config/workflow");
15
16
  const log = require("../src/util/log");
16
17
  const output = require("../src/util/output");
17
18
  const pack = require("../src/cli/pack");
@@ -36,9 +37,9 @@ const SUBCMD = "pack";
36
37
  // [define]
37
38
 
38
39
  const conf = {
39
- input: null,
40
+ input: cfgworkflow.deploy_dir,
40
41
  json: false,
41
- output: null,
42
+ output: ".arc/package/game.zip",
42
43
  quiet: false,
43
44
  ...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
44
45
  };
package/bin/arc-play.js CHANGED
@@ -12,15 +12,21 @@ const yargs = require("yargs/yargs");
12
12
 
13
13
  // [import]
14
14
 
15
+ const cfguri = require("../src/config/uri");
15
16
  const log = require("../src/util/log");
17
+ const phrase = require("../src/phrase");
16
18
  const pkg = require("../package.json");
17
19
  const play = require("../src/cli/play");
18
20
  const rc = require("../src/util/rc");
21
+ const shell = require("../src/util/shell");
22
+ const spinner = require("../src/util/spinner");
19
23
 
20
24
  // [use]
21
25
 
22
26
  const findRc = rc.findRc;
27
+ const launch = shell.launch;
23
28
  const resolve = path.resolve;
29
+ const SpinnerWheel = spinner.SpinnerWheel;
24
30
 
25
31
  // [declare]
26
32
 
@@ -30,23 +36,50 @@ const SUBCMD = "play";
30
36
  // [define]
31
37
 
32
38
  const conf = {
33
- browser: true,
39
+ browser: false,
34
40
  game: "self",
41
+ quiet: false,
42
+ release: "production",
35
43
  ...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
36
44
  };
37
45
 
38
46
  // [function]
39
47
 
48
+ const handler = function ({ quiet, sw }) {
49
+ return {
50
+ onPlayFetch() {
51
+ sw.start(quiet);
52
+ },
53
+ };
54
+ };
55
+
56
+ // [function]
57
+
40
58
  const start = function (argv) {
59
+ const sw = new SpinnerWheel("Opening... %s");
41
60
  return play({
42
- browser: argv.browser,
43
61
  game: argv.game,
62
+ handler: handler({ quiet: argv.quiet, sw }),
63
+ release: argv.release,
44
64
  root: resolve(process.cwd(), argv.cwd),
45
- }).catch((ex) => {
46
- log.hd("Play aborted.");
47
- log.p(ex.message);
48
- process.exit(1);
49
- });
65
+ })
66
+ .then((data) => {
67
+ const orientation = data?.orientation;
68
+ const url = data?.url;
69
+ if (!orientation || !url) {
70
+ throw new Error(phrase.noGameId());
71
+ }
72
+ sw.stop(true);
73
+ launch(
74
+ argv.browser ? url : `${cfguri.HOST_APP_PLAY}/${orientation}/${url}`,
75
+ );
76
+ })
77
+ .catch((ex) => {
78
+ sw.stop(true);
79
+ log.hd("Play aborted.");
80
+ log.p(ex.message);
81
+ process.exit(1);
82
+ });
50
83
  };
51
84
 
52
85
  // [function]
@@ -55,11 +88,18 @@ const main = function (argv) {
55
88
  return start(
56
89
  yargs(hideBin(argv))
57
90
  .scriptName(`${CMD} ${SUBCMD}`)
58
- .usage("$0 [options]")
59
- .option("game", {
60
- alias: "g",
61
- default: conf.game,
62
- describe: "Game handle or ID",
91
+ .usage("$0 [game] [options]")
92
+ .command("$0 [game]", false, (cli) =>
93
+ cli.positional("game", {
94
+ default: conf.game,
95
+ describe: "Game handle or ID",
96
+ type: "string",
97
+ }),
98
+ )
99
+ .option("release", {
100
+ alias: "r",
101
+ default: conf.release,
102
+ describe: "Release channel or version",
63
103
  type: "string",
64
104
  })
65
105
  .option("browser", {
@@ -67,6 +107,12 @@ const main = function (argv) {
67
107
  describe: "Open in a web browser",
68
108
  type: "boolean",
69
109
  })
110
+ .option("quiet", {
111
+ alias: "q",
112
+ default: conf.quiet,
113
+ describe: "Output only errors",
114
+ type: "boolean",
115
+ })
70
116
  .option("cwd", {
71
117
  alias: "C",
72
118
  default: ".",
@@ -41,7 +41,6 @@ const conf = {
41
41
 
42
42
  const start = function (argv) {
43
43
  const json = argv.json;
44
- const quiet = argv.quiet;
45
44
  return validate({ root: resolve(process.cwd(), argv.cwd) })
46
45
  .then((issues) => {
47
46
  const count = issues.length;
@@ -50,7 +49,7 @@ const start = function (argv) {
50
49
  } else if (count) {
51
50
  log.hd(`${count} ${count === 1 ? "issue" : "issues"} found.`);
52
51
  log.p(issues.map((error) => `✗ ${error}`));
53
- } else if (!quiet) {
52
+ } else if (!argv.quiet) {
54
53
  log.hs("No issues found.");
55
54
  }
56
55
  process.exit(count ? 1 : 0);
package/bin/arc-whoami.js CHANGED
@@ -48,7 +48,7 @@ const handler = function ({ json, sw }) {
48
48
 
49
49
  const start = function (argv) {
50
50
  const json = argv.json;
51
- const sw = new SpinnerWheel("Checking login... %s");
51
+ const sw = new SpinnerWheel("Checking... %s");
52
52
  return whoami({ handler: handler({ json, sw }) })
53
53
  .then((current) => {
54
54
  const profile = current?.profile;
package/package.json CHANGED
@@ -2,15 +2,14 @@
2
2
  "bin": {
3
3
  "arc": "bin/arc.js",
4
4
  "arc-build": "bin/arc-build.js",
5
- "arc-count": "bin/arc-count.js",
6
5
  "arc-deploy": "bin/arc-deploy.js",
7
6
  "arc-init": "bin/arc-init.js",
8
7
  "arc-inspect": "bin/arc-inspect.js",
9
8
  "arc-login": "bin/arc-login.js",
10
9
  "arc-logout": "bin/arc-logout.js",
10
+ "arc-open": "bin/arc-open.js",
11
11
  "arc-pack": "bin/arc-pack.js",
12
12
  "arc-play": "bin/arc-play.js",
13
- "arc-predeploy": "bin/arc-predeploy.js",
14
13
  "arc-validate": "bin/arc-validate.js",
15
14
  "arc-whoami": "bin/arc-whoami.js"
16
15
  },
@@ -43,12 +42,12 @@
43
42
  },
44
43
  "exports": {
45
44
  "./build": "./src/cli/build.js",
46
- "./count": "./src/cli/count.js",
47
45
  "./deploy": "./src/cli/deploy.js",
48
46
  "./init": "./src/cli/init.js",
49
47
  "./inspect": "./src/cli/inspect.js",
50
48
  "./login": "./src/cli/login.js",
51
49
  "./logout": "./src/cli/logout.js",
50
+ "./open": "./src/cli/open.js",
52
51
  "./pack": "./src/cli/pack.js",
53
52
  "./play": "./src/cli/play.js",
54
53
  "./predeploy": "./src/cli/predeploy.js",
@@ -62,5 +61,5 @@
62
61
  "license": "Apache-2.0",
63
62
  "main": "./src/cli/index.js",
64
63
  "name": "arcadible",
65
- "version": "0.1.19"
64
+ "version": "0.1.20"
66
65
  }
package/src/account.js CHANGED
@@ -71,15 +71,16 @@ const get = function (onRefresh) {
71
71
  }
72
72
  throw ex;
73
73
  })
74
- .then((account) => {
75
- if (!account || !account.session) {
74
+ .then((current) => {
75
+ const session = current?.session;
76
+ if (!session) {
76
77
  return null;
77
78
  }
78
- return expired(account.session)
79
+ return expired(session)
79
80
  ? (onRefresh &&
80
- onRefresh((renew) => (renew ? refresh(account) : null))) ||
81
+ onRefresh((renew) => (renew ? refresh(current) : null))) ||
81
82
  null
82
- : account;
83
+ : current;
83
84
  });
84
85
  };
85
86
 
@@ -13,33 +13,49 @@ const project = require("../../parser/project");
13
13
 
14
14
  // [function]
15
15
 
16
- const inspect = function (proj, key) {
16
+ const select = function (proj, key) {
17
17
  return key ? dotProp.get(proj, key, null) : proj;
18
18
  };
19
19
 
20
20
  // [function]
21
21
 
22
- const main = function ({ game, root, selector }) {
23
- if (!game || game === "self") {
24
- return project(root).then((proj) => inspect(proj, selector));
25
- }
22
+ const inspect = function (id) {
26
23
  return api
27
- .discoverGameBuilds(game, {
24
+ .discoverGameBuilds(id, {
28
25
  channel: "production",
29
26
  select: "manifest",
30
27
  })
31
28
  .then((builds) => {
32
29
  if (!builds.length) {
33
- throw new Error(phrase.noProductionBuild(game));
30
+ throw new Error(phrase.noProductionBuild(id));
34
31
  }
35
- const manifest = builds[0].manifest || {};
32
+ const manifest = builds[0]?.manifest ?? {};
36
33
  if (manifest.game) {
37
34
  media.dehydrate(manifest.game);
38
35
  }
39
- return inspect(manifest, selector);
36
+ return manifest;
40
37
  });
41
38
  };
42
39
 
40
+ // [function]
41
+
42
+ const main = function ({ game: id, root, selector }, { onInspectFetch }) {
43
+ const local = !id;
44
+ if (onInspectFetch && !local) {
45
+ onInspectFetch({ game: id });
46
+ }
47
+ if (local) {
48
+ return project(root).then((data) => select(data, selector));
49
+ }
50
+ if (id === "self") {
51
+ return project(root)
52
+ .then(({ game }) => game?.handle ?? game?.id)
53
+ .then(inspect)
54
+ .then((data) => select(data, selector));
55
+ }
56
+ return inspect(id).then((data) => select(data, selector));
57
+ };
58
+
43
59
  // [export]
44
60
 
45
61
  module.exports = main;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ // [import]
4
+
5
+ const project = require("../../parser/project");
6
+
7
+ // [function]
8
+
9
+ const open = function (id) {
10
+ return id ? { page: `/play/${id}` } : null;
11
+ };
12
+
13
+ // [function]
14
+
15
+ const main = function ({ game: id, root }) {
16
+ if (id === "self") {
17
+ return project(root).then(({ game }) => open(game?.handle ?? game?.id));
18
+ }
19
+ return Promise.resolve(open(id));
20
+ };
21
+
22
+ // [export]
23
+
24
+ module.exports = main;
@@ -2,42 +2,39 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const dotProp = require("dot-prop");
6
-
7
- // [import]
8
-
9
5
  const api = require("../../api");
10
- const media = require("./media");
11
- const phrase = require("../../phrase");
6
+ const cfguri = require("../../config/uri");
12
7
  const project = require("../../parser/project");
13
8
 
14
9
  // [function]
15
10
 
16
- const inspect = function (proj, key) {
17
- return key ? dotProp.get(proj, key, null) : proj;
11
+ const play = function (id, release) {
12
+ if (!id) {
13
+ return Promise.resolve(null);
14
+ }
15
+ const target = release === "production" ? "" : `:${release}`;
16
+ const url = `${cfguri.HOST_HTTP_PLAY}/${id}${target}/`;
17
+ return api
18
+ .discoverGame(id, { select: "orientation" })
19
+ .catch(() => null)
20
+ .then((game) => ({
21
+ orientation: game?.orientation ?? "natural",
22
+ url,
23
+ }));
18
24
  };
19
25
 
20
26
  // [function]
21
27
 
22
- const main = function ({ game, root, selector }) {
23
- if (!game || game === "self") {
24
- return project(root).then((proj) => inspect(proj, selector));
28
+ const main = function ({ game: id, release, root }, { onPlayFetch }) {
29
+ if (onPlayFetch) {
30
+ onPlayFetch({ game: id });
25
31
  }
26
- return api
27
- .discoverGameBuilds(game, {
28
- channel: "production",
29
- select: "manifest",
30
- })
31
- .then((builds) => {
32
- if (!builds.length) {
33
- throw new Error(phrase.noProductionBuild(game));
34
- }
35
- const manifest = builds[0].manifest || {};
36
- if (manifest.game) {
37
- media.dehydrate(manifest.game);
38
- }
39
- return inspect(manifest, selector);
40
- });
32
+ if (id === "self") {
33
+ return project(root).then(({ game }) =>
34
+ play(game?.handle ?? game?.id, release),
35
+ );
36
+ }
37
+ return play(id, release);
41
38
  };
42
39
 
43
40
  // [export]
package/src/api.js CHANGED
@@ -42,6 +42,12 @@ const postUpload = function (form, opts) {
42
42
 
43
43
  // [function]
44
44
 
45
+ const discoverGame = function (id, opts) {
46
+ return request.get(endpoint(`/discover/games/${id}`), opts);
47
+ };
48
+
49
+ // [function]
50
+
45
51
  const discoverGameBuilds = function (id, opts) {
46
52
  return request.get(endpoint(`/discover/games/${id}/builds`), opts);
47
53
  };
@@ -55,6 +61,7 @@ const gameBuild = function (id, version, opts) {
55
61
  // [export]
56
62
 
57
63
  module.exports = {
64
+ discoverGame,
58
65
  discoverGameBuilds,
59
66
  flow,
60
67
  gameBuild,
package/src/cli/index.js CHANGED
@@ -3,12 +3,12 @@
3
3
  // [import]
4
4
 
5
5
  const build = require("./build");
6
- const count = require("./count");
7
6
  const deploy = require("./deploy");
8
7
  const init = require("./init");
9
8
  const inspect = require("./inspect");
10
9
  const login = require("./login");
11
10
  const logout = require("./logout");
11
+ const open = require("./open");
12
12
  const pack = require("./pack");
13
13
  const play = require("./play");
14
14
  const predeploy = require("./predeploy");
@@ -19,12 +19,12 @@ const whoami = require("./whoami");
19
19
 
20
20
  module.exports = {
21
21
  build,
22
- count,
23
22
  deploy,
24
23
  init,
25
24
  inspect,
26
25
  login,
27
26
  logout,
27
+ open,
28
28
  pack,
29
29
  play,
30
30
  predeploy,
@@ -6,8 +6,8 @@ const inspectTool = require("../action/inspect/tool");
6
6
 
7
7
  // [function]
8
8
 
9
- const main = function (conf) {
10
- return inspectTool(conf);
9
+ const main = function ({ handler, ...conf }) {
10
+ return inspectTool(conf, handler);
11
11
  };
12
12
 
13
13
  // [export]
@@ -2,12 +2,12 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const countTool = require("../action/count/tool");
5
+ const openTool = require("../action/open/tool");
6
6
 
7
7
  // [function]
8
8
 
9
9
  const main = function (conf) {
10
- return countTool(conf);
10
+ return openTool(conf);
11
11
  };
12
12
 
13
13
  // [export]
package/src/cli/play.js CHANGED
@@ -6,8 +6,8 @@ const playTool = require("../action/play/tool");
6
6
 
7
7
  // [function]
8
8
 
9
- const main = function (conf) {
10
- return playTool(conf);
9
+ const main = function ({ handler, ...conf }) {
10
+ return playTool(conf, handler);
11
11
  };
12
12
 
13
13
  // [export]
package/src/config/uri.js CHANGED
@@ -2,13 +2,17 @@
2
2
 
3
3
  // [declare]
4
4
 
5
- const SLD = "arcadible";
5
+ const DOMAIN = "arcadible";
6
+ const PROTOCOL = DOMAIN;
6
7
 
7
8
  // [export]
8
9
 
9
10
  module.exports = {
10
- HOST_HTTP_ACCOUNT: `https://account.${SLD}.com`,
11
- HOST_HTTP_API: `https://api.${SLD}.com`,
12
- HOST_HTTP_DEVELOPER: `https://developer.${SLD}.com`,
13
- HOST_HTTP_WWW: `https://${SLD}.com`,
11
+ HOST_APP_PLAY: `${PROTOCOL}://play`,
12
+ HOST_APP_STORE: `${PROTOCOL}://store`,
13
+ HOST_HTTP_ACCOUNT: `https://account.${DOMAIN}.com`,
14
+ HOST_HTTP_API: `https://api.${DOMAIN}.com`,
15
+ HOST_HTTP_DEVELOPER: `https://developer.${DOMAIN}.com`,
16
+ HOST_HTTP_PLAY: `https://play.${DOMAIN}.com`,
17
+ HOST_HTTP_WWW: `https://${DOMAIN}.com`,
14
18
  };
package/src/config/url.js CHANGED
@@ -4,14 +4,10 @@
4
4
 
5
5
  const cfguri = require("./uri");
6
6
 
7
- // [declare]
8
-
9
- const SLD = "arcadible";
10
-
11
7
  // [export]
12
8
 
13
9
  module.exports = {
14
10
  GETTING_STARTED: `${cfguri.HOST_HTTP_DEVELOPER}/guides/games/getting-started`,
15
11
  LINK: `${cfguri.HOST_HTTP_ACCOUNT}/link`,
16
- MANIFEST: `${cfguri.HOST_HTTP_DEVELOPER}/references/${SLD}-manifest`,
12
+ MANIFEST: `${cfguri.HOST_HTTP_DEVELOPER}/references/arcadible-manifest`,
17
13
  };
@@ -95,7 +95,7 @@ const extractDescription = function (doc) {
95
95
  const parts = [];
96
96
  let node = first.nextSibling;
97
97
  while (node && node !== last) {
98
- parts.push(node.outerHTML || node.textContent);
98
+ parts.push(node.outerHTML ?? node.textContent);
99
99
  node = node.nextSibling;
100
100
  }
101
101
  return trimWhitespace(parts.join(""));
@@ -135,7 +135,7 @@ const findReadme = function (root) {
135
135
  README.map((file) =>
136
136
  pathExists(join(root, file)).then((exists) => (exists ? file : null)),
137
137
  ),
138
- ).then((files) => files.find(Boolean) || null);
138
+ ).then((files) => files.find(Boolean) ?? null);
139
139
  };
140
140
 
141
141
  // [function]
@@ -145,7 +145,7 @@ const main = function (root) {
145
145
  .then((file) => (file ? readFile(join(root, file), "utf8") : null))
146
146
  .then((buf) => (buf === null ? null : parseReadme(buf)))
147
147
  .then(deepCompact)
148
- .then((game) => ({ game: game || null }));
148
+ .then((game) => ({ game: game ?? null }));
149
149
  };
150
150
 
151
151
  // [export]
package/src/phrase.js CHANGED
@@ -74,6 +74,12 @@ const loginFailed = function () {
74
74
 
75
75
  // [function]
76
76
 
77
+ const noGameId = function () {
78
+ return "No game handle or ID.";
79
+ };
80
+
81
+ // [function]
82
+
77
83
  const noProductionBuild = function () {
78
84
  return "No production build found.";
79
85
  };
@@ -150,6 +156,7 @@ module.exports = {
150
156
  issuesFound,
151
157
  loginExpired,
152
158
  loginFailed,
159
+ noGameId,
153
160
  noProductionBuild,
154
161
  noVideoMetadata,
155
162
  noVideoTrack,
@@ -2,7 +2,8 @@
2
2
 
3
3
  // [declare]
4
4
 
5
- const REPO = "arcadible";
5
+ const OWNER = "arcadible";
6
+ const REPO = "starter";
6
7
 
7
8
  // [export]
8
9
 
@@ -10,32 +11,37 @@ module.exports = {
10
11
  select: {
11
12
  choices: [
12
13
  {
13
- description: "Plain JavaScript starter.",
14
- name: "Default",
15
- value: `${REPO}/starter`,
14
+ alias: "blank",
15
+ description: "Blank JavaScript starter.",
16
+ name: "Blank",
17
+ value: `${OWNER}/${REPO}`,
16
18
  },
17
19
  {
20
+ alias: "threejs",
18
21
  description: "Three.js starter.",
19
22
  name: "Three.js",
20
- value: `${REPO}/starter-threejs`,
23
+ value: `${OWNER}/${REPO}-threejs`,
21
24
  },
22
25
  {
26
+ alias: "phaser",
23
27
  description: "Phaser starter.",
24
28
  name: "Phaser",
25
- value: `${REPO}/starter-phaser`,
29
+ value: `${OWNER}/${REPO}-phaser`,
26
30
  },
27
31
  {
32
+ alias: "pixijs",
28
33
  description: "PixiJS starter.",
29
34
  name: "PixiJS",
30
- value: `${REPO}/starter-pixijs`,
35
+ value: `${OWNER}/${REPO}-pixijs`,
31
36
  },
32
37
  {
38
+ alias: "babylonjs",
33
39
  description: "Babylon.js starter.",
34
40
  name: "Babylon.js",
35
- value: `${REPO}/starter-babylonjs`,
41
+ value: `${OWNER}/${REPO}-babylonjs`,
36
42
  },
37
43
  ],
38
- default: `${REPO}/starter`,
44
+ default: `${OWNER}/${REPO}`,
39
45
  message: "Template",
40
46
  },
41
47
  };
@@ -305,7 +305,7 @@ const zId = function () {
305
305
  .string(
306
306
  message(field, [
307
307
  "Must be defined.",
308
- "Run `arc init` to generate a new ID.",
308
+ "Run `arc init` to generate a new game ID.",
309
309
  ]),
310
310
  )
311
311
  .uuid(message(field, ["Must be a valid UUID."]))
package/src/util/http.js CHANGED
@@ -6,10 +6,11 @@ const HttpError = class extends Error {
6
6
 
7
7
  // [constructor]
8
8
 
9
- constructor(status, message) {
9
+ constructor(status, { message, title }) {
10
10
  super(message);
11
- this.name = "HttpError";
12
11
  this.status = status;
12
+ this.name = title;
13
+ this.message = `HttpError: ${this.name} (${this.status})`;
13
14
  }
14
15
  };
15
16
 
@@ -23,8 +23,8 @@ const printJson = function (data) {
23
23
 
24
24
  // [function]
25
25
 
26
- const printToml = function (data, key = "value") {
27
- const field = key.split(".").at(-1);
26
+ const printToml = function (data, key) {
27
+ const field = (key ?? "value").split(".").at(-1);
28
28
  if (data === null) {
29
29
  write(`# ${field} = null`);
30
30
  return;
package/src/util/rc.js CHANGED
@@ -33,7 +33,7 @@ const config = function (cmd, argv, option) {
33
33
  // [function]
34
34
 
35
35
  const findRc = function (cmd, subcmd, argv, option) {
36
- return rc(cmd, {}, { config: config(cmd, argv, option) })[subcmd] || {};
36
+ return rc(cmd, {}, { config: config(cmd, argv, option) })[subcmd] ?? {};
37
37
  };
38
38
 
39
39
  // [export]
@@ -19,7 +19,7 @@ const CLIENT_VERSION = pkg.version;
19
19
  const parse = function (resp) {
20
20
  return resp.json().then((json) => {
21
21
  if (!resp.ok) {
22
- throw new HttpError(resp.status, json.data.message);
22
+ throw new HttpError(resp.status, json.data);
23
23
  }
24
24
  return json.data;
25
25
  });
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ // [import]
4
+
5
+ const open = require("open");
6
+
7
+ // [function]
8
+
9
+ const launch = function (uri) {
10
+ open(uri).catch(() => {});
11
+ };
12
+
13
+ // [export]
14
+
15
+ module.exports = { launch };
package/src/util/video.js CHANGED
@@ -50,7 +50,7 @@ const readMp4 = function (file) {
50
50
  let video = null;
51
51
  mp4.onReady = (info) => {
52
52
  const track = info.tracks.find((t) => t.video);
53
- if (!track || !track.video) {
53
+ if (!track?.video) {
54
54
  error = new Error(phrase.noVideoTrack());
55
55
  return;
56
56
  }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
@@ -1,45 +0,0 @@
1
- "use strict";
2
-
3
- // [import]
4
-
5
- const dotProp = require("dot-prop");
6
-
7
- // [import]
8
-
9
- const api = require("../../api");
10
- const media = require("./media");
11
- const phrase = require("../../phrase");
12
- const project = require("../../parser/project");
13
-
14
- // [function]
15
-
16
- const inspect = function (proj, key) {
17
- return key ? dotProp.get(proj, key, null) : proj;
18
- };
19
-
20
- // [function]
21
-
22
- const main = function ({ game, root, selector }) {
23
- if (!game || game === "self") {
24
- return project(root).then((proj) => inspect(proj, selector));
25
- }
26
- return api
27
- .discoverGameBuilds(game, {
28
- channel: "production",
29
- select: "manifest",
30
- })
31
- .then((builds) => {
32
- if (!builds.length) {
33
- throw new Error(phrase.noProductionBuild(game));
34
- }
35
- const manifest = builds[0].manifest || {};
36
- if (manifest.game) {
37
- media.dehydrate(manifest.game);
38
- }
39
- return inspect(manifest, selector);
40
- });
41
- };
42
-
43
- // [export]
44
-
45
- module.exports = main;