arcadible 0.1.44 → 0.1.46

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 (55) hide show
  1. package/bin/arc-build.js +9 -17
  2. package/bin/arc-deploy.js +20 -36
  3. package/bin/arc-init.js +6 -16
  4. package/bin/arc-inspect.js +3 -7
  5. package/bin/arc-login.js +5 -5
  6. package/bin/arc-logout.js +4 -8
  7. package/bin/arc-open.js +7 -20
  8. package/bin/arc-pack.js +4 -14
  9. package/bin/arc-play.js +6 -20
  10. package/bin/arc-validate.js +8 -17
  11. package/bin/arc-whoami.js +5 -9
  12. package/bin/arc.js +7 -2
  13. package/package.json +1 -1
  14. package/src/account.js +5 -5
  15. package/src/action/build/tool.js +8 -15
  16. package/src/action/deploy/tool-git.js +1 -6
  17. package/src/action/deploy/wait.js +5 -11
  18. package/src/action/init/manifest.js +9 -37
  19. package/src/action/login/flow.js +3 -10
  20. package/src/action/open/tool.js +4 -3
  21. package/src/action/pack/limits.js +4 -6
  22. package/src/action/pack/tool.js +9 -5
  23. package/src/action/play/tool.js +6 -6
  24. package/src/action/predeploy/ac.js +34 -31
  25. package/src/action/predeploy/git.js +4 -4
  26. package/src/action/predeploy/pm.js +1 -1
  27. package/src/action/predeploy/published.js +4 -4
  28. package/src/action/predeploy/tool-git.js +10 -10
  29. package/src/action/validate/unknown.js +11 -10
  30. package/src/config/code.js +1 -1
  31. package/src/config/file.js +23 -0
  32. package/src/config/limit.js +21 -0
  33. package/src/parser/env.js +0 -2
  34. package/src/parser/manifest.js +15 -13
  35. package/src/parser/media.js +9 -11
  36. package/src/parser/project.js +31 -9
  37. package/src/parser/self.js +27 -0
  38. package/src/phrase.js +175 -43
  39. package/src/schema/game.js +65 -42
  40. package/src/schema/workflow.js +7 -8
  41. package/src/util/argv.js +27 -1
  42. package/src/util/command.js +18 -0
  43. package/src/util/delay.js +5 -21
  44. package/src/util/doc.js +4 -13
  45. package/src/util/links.js +17 -2
  46. package/src/util/media.js +2 -2
  47. package/src/util/objs.js +8 -1
  48. package/src/util/output.js +24 -2
  49. package/src/util/rc.js +2 -2
  50. package/src/util/request.js +1 -1
  51. package/src/util/s3.js +1 -1
  52. package/src/util/schema.js +9 -3
  53. package/src/util/uris.js +1 -1
  54. package/src/util/zip.js +2 -2
  55. package/src/config/doc.js +0 -7
package/src/util/argv.js CHANGED
@@ -19,6 +19,11 @@ const parse = helpers.Parser;
19
19
 
20
20
  // [declare]
21
21
 
22
+ // the --browser option of arc open and arc play.
23
+ const BROWSER = {
24
+ describe: "Open in a web browser",
25
+ type: "boolean",
26
+ };
22
27
  // the -C, --cwd option of every project command.
23
28
  const CWD = {
24
29
  alias: "C",
@@ -26,6 +31,18 @@ const CWD = {
26
31
  describe: "Set the working directory",
27
32
  type: "string",
28
33
  };
34
+ // the -j, --json option, which prints one JSON document (OUTPUT.md).
35
+ const JSON_OUTPUT = {
36
+ alias: "j",
37
+ describe: "Format output as JSON",
38
+ type: "boolean",
39
+ };
40
+ // the -q, --quiet option, which prints only errors.
41
+ const QUIET = {
42
+ alias: "q",
43
+ describe: "Output only errors",
44
+ type: "boolean",
45
+ };
29
46
 
30
47
  // [function]
31
48
 
@@ -87,4 +104,13 @@ const fail = function (argv) {
87
104
 
88
105
  // [export]
89
106
 
90
- module.exports = { CWD, cwd, fail, json, normalize };
107
+ module.exports = {
108
+ BROWSER,
109
+ CWD,
110
+ JSON_OUTPUT,
111
+ QUIET,
112
+ cwd,
113
+ fail,
114
+ json,
115
+ normalize,
116
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ // [function]
4
+
5
+ // workflow.build as the shell runs it: each command trimmed, blank ones
6
+ // dropped, and a list joined with `&&`. Blank when there's nothing to run.
7
+ const buildCommand = function (build) {
8
+ return [build]
9
+ .flat()
10
+ .filter((cmd) => typeof cmd === "string")
11
+ .map((cmd) => cmd.trim())
12
+ .filter(Boolean)
13
+ .join(" && ");
14
+ };
15
+
16
+ // [export]
17
+
18
+ module.exports = { buildCommand };
package/src/util/delay.js CHANGED
@@ -1,21 +1,5 @@
1
1
  "use strict";
2
2
 
3
- // [import]
4
-
5
- const phrase = require("../phrase");
6
- const time = require("./time");
7
-
8
- // [declare]
9
-
10
- const POLL = {
11
- delay: time.s(1),
12
- factor: 1,
13
- interval: time.m(1),
14
- maxDelay: time.s(1),
15
- timeout: Infinity,
16
- timeoutError: phrase.timedOut(),
17
- };
18
-
19
3
  // [function]
20
4
 
21
5
  const backoff = function (elapsed, delay, factor, interval, maxDelay) {
@@ -39,10 +23,13 @@ const wait = function (delay, next) {
39
23
 
40
24
  // [function]
41
25
 
26
+ // calls fn(value) until it resolves to something other than null, backing
27
+ // off by `factor` every `interval`, up to `maxDelay`. After `timeout`, it
28
+ // throws timeoutError(), the caller's own error, with its code.
42
29
  const poll = function (
43
30
  fn,
44
31
  value,
45
- { delay, factor, interval, maxDelay, timeout, timeoutError } = POLL,
32
+ { delay, factor, interval, maxDelay, timeout, timeoutError },
46
33
  ) {
47
34
  const started = Date.now();
48
35
  const next = function () {
@@ -52,10 +39,7 @@ const poll = function (
52
39
  }
53
40
  const elapsed = Date.now() - started;
54
41
  if (elapsed >= timeout) {
55
- // a function makes the caller's own error, with its code.
56
- throw typeof timeoutError === "function"
57
- ? timeoutError()
58
- : new Error(timeoutError);
42
+ throw timeoutError();
59
43
  }
60
44
  return wait(backoff(elapsed, delay, factor, interval, maxDelay), next);
61
45
  });
package/src/util/doc.js CHANGED
@@ -6,7 +6,6 @@ const jsdom = require("jsdom");
6
6
 
7
7
  // [import]
8
8
 
9
- const cfgdoc = require("../config/doc");
10
9
  const phrase = require("../phrase");
11
10
 
12
11
  // [use]
@@ -59,23 +58,15 @@ const checkNode = function (node, opts, issues) {
59
58
 
60
59
  // [function]
61
60
 
62
- // checks HTML as written, before anything sanitizes it: every element must be
63
- // allowed, with only its allowed attributes, each passing its hook. Each
64
- // problem is reported once.
65
- const checkHtml = function (str, { allowed, hooks = {} }) {
61
+ // checks the description's HTML as written, before anything sanitizes it:
62
+ // every element must be allowed, with only its allowed attributes, each
63
+ // passing its hook. Each problem is reported once.
64
+ const check = function (str, { allowed, hooks = {} }) {
66
65
  const issues = new Set();
67
66
  checkNode(JSDOM.fragment(str), { allowed, hooks }, issues);
68
67
  return [...issues];
69
68
  };
70
69
 
71
- // [function]
72
-
73
- const check = function (str, { type, ...opts }) {
74
- const checks = { [cfgdoc[".html"]]: checkHtml };
75
- const checkDoc = checks[type];
76
- return checkDoc ? checkDoc(str, opts) : [phrase.docUnsupported()];
77
- };
78
-
79
70
  // [export]
80
71
 
81
72
  module.exports = { check };
package/src/util/links.js CHANGED
@@ -41,13 +41,26 @@ const storePage = function (game) {
41
41
 
42
42
  // [function]
43
43
 
44
+ // a game's store page on the web.
45
+ const storeUrl = function (game) {
46
+ return `${cfguri.HOST_HTTP_WWW}${storePage(game)}`;
47
+ };
48
+
49
+ // [function]
50
+
51
+ // a game's page in Studio, on one of its tabs, such as `builds`.
52
+ const studioUrl = function (game, tab) {
53
+ return `${cfguri.HOST_HTTP_STUDIO}/games/${game}/${tab}`;
54
+ };
55
+
56
+ // [function]
57
+
44
58
  // where a deployed version will be, once it's published: its channel, that
45
59
  // channel's play link, and for production, its store page.
46
60
  const published = function ({ handle, id, version }) {
47
61
  const game = handle ?? id;
48
62
  const release = channel(version);
49
- const store =
50
- release === PRODUCTION ? `${cfguri.HOST_HTTP_WWW}${storePage(game)}` : null;
63
+ const store = release === PRODUCTION ? storeUrl(game) : null;
51
64
  return { channel: release, store, url: playUrl(game, release) };
52
65
  };
53
66
 
@@ -60,4 +73,6 @@ module.exports = {
60
73
  playUrl,
61
74
  published,
62
75
  storePage,
76
+ storeUrl,
77
+ studioUrl,
63
78
  };
package/src/util/media.js CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const limits = require("../action/pack/limits");
5
+ const cfglimit = require("../config/limit");
6
6
 
7
7
  // [declare]
8
8
 
9
9
  // a file too large to pack isn't read.
10
- const MAX_READ = limits.MAX_FILE_SIZE;
10
+ const MAX_READ = cfglimit.FILE_SIZE;
11
11
 
12
12
  // [function]
13
13
 
package/src/util/objs.js CHANGED
@@ -29,10 +29,17 @@ const deepCompact = function (obj) {
29
29
 
30
30
  // [function]
31
31
 
32
+ // a TOML table: an object, not an array.
33
+ const isTable = function (value) {
34
+ return value !== null && typeof value === "object" && !Array.isArray(value);
35
+ };
36
+
37
+ // [function]
38
+
32
39
  const deepSort = function (obj) {
33
40
  return JSON.parse(stringify(obj));
34
41
  };
35
42
 
36
43
  // [export]
37
44
 
38
- module.exports = { deepCompact, deepSort };
45
+ module.exports = { deepCompact, deepSort, isTable };
@@ -41,7 +41,7 @@ const printToml = function (data, key, nl = false) {
41
41
  }
42
42
  try {
43
43
  write(TOML.stringify(deepSort(data)), nl);
44
- } catch (ex) {
44
+ } catch {
45
45
  write(TOML.stringify(deepSort({ [field]: data })), nl);
46
46
  }
47
47
  };
@@ -107,6 +107,20 @@ const abort = function (
107
107
 
108
108
  // [function]
109
109
 
110
+ // where arc open or arc play opened the page, with its URL, or that it
111
+ // couldn't, with the URL to open by hand.
112
+ const launched = function (where, url) {
113
+ if (where) {
114
+ log.result(phrase.opened(where), [url]);
115
+ return;
116
+ }
117
+ log.result(phrase.unableToOpen(), [url, phrase.openToContinue()], {
118
+ color: "yellow",
119
+ });
120
+ };
121
+
122
+ // [function]
123
+
110
124
  // arc validate's warnings, such as an unknown field, on stderr in yellow,
111
125
  // before a command that validates goes on. Left out with `--json` and
112
126
  // `--quiet`; arc validate --json lists them.
@@ -134,4 +148,12 @@ const warning = function (code, message, path = null) {
134
148
 
135
149
  // [export]
136
150
 
137
- module.exports = { abort, print, printJson, printToml, warn, warning };
151
+ module.exports = {
152
+ abort,
153
+ launched,
154
+ print,
155
+ printJson,
156
+ printToml,
157
+ warn,
158
+ warning,
159
+ };
package/src/util/rc.js CHANGED
@@ -81,7 +81,7 @@ const read = function (file) {
81
81
  let str = null;
82
82
  try {
83
83
  str = readFileSync(file, "utf8");
84
- } catch (ex) {
84
+ } catch {
85
85
  return {};
86
86
  }
87
87
  if (!/^\s*\{/u.test(str)) {
@@ -111,7 +111,7 @@ const findRc = function (cmd, subcmd, argv) {
111
111
  {},
112
112
  );
113
113
  } catch (ex) {
114
- return abort(`${subcmd[0].toUpperCase()}${subcmd.slice(1)} aborted.`, ex, {
114
+ return abort(phrase.aborted(subcmd), ex, {
115
115
  json: args.json(argv),
116
116
  });
117
117
  }
@@ -27,7 +27,7 @@ const json = function (resp) {
27
27
  return resp.text().then((text) => {
28
28
  try {
29
29
  return JSON.parse(text);
30
- } catch (ex) {
30
+ } catch {
31
31
  return null;
32
32
  }
33
33
  });
package/src/util/s3.js CHANGED
@@ -8,7 +8,7 @@ const https = require("node:https");
8
8
  // [import]
9
9
 
10
10
  const cfgcode = require("../config/code");
11
- const error = require("../util/error");
11
+ const error = require("./error");
12
12
  const phrase = require("../phrase");
13
13
 
14
14
  // [use]
@@ -24,7 +24,7 @@ const NUMBERS = new Set(["bigint", "int", "number"]);
24
24
  // a zod issue's code (config/code.js, ISSUE). Our own checks name theirs in
25
25
  // params; zod's built-in ones, which drop params, are named from what zod
26
26
  // reports. Anything else is `invalid`, so every issue has a code.
27
- const codeOf = function (issue) {
27
+ const issueCodeOf = function (issue) {
28
28
  switch (issue.code) {
29
29
  case "custom":
30
30
  return issue.params?.code ?? ISSUE.INVALID;
@@ -71,7 +71,7 @@ const codeOf = function (issue) {
71
71
  const toIssue = function (name, issue) {
72
72
  const { details, message } = schemaMessage.parse(issue.message);
73
73
  return {
74
- code: codeOf(issue),
74
+ code: issueCodeOf(issue),
75
75
  details,
76
76
  link: issue.path.length
77
77
  ? schemaMessage.link(name, String(issue.path[0]))
@@ -128,4 +128,10 @@ const validator = function (name, schema) {
128
128
 
129
129
  // [export]
130
130
 
131
- module.exports = { codeOf, compare, dereference, print, validator };
131
+ module.exports = {
132
+ compare,
133
+ dereference,
134
+ issueCodeOf,
135
+ print,
136
+ validator,
137
+ };
package/src/util/uris.js CHANGED
@@ -8,7 +8,7 @@
8
8
  const isSafeUri = function (uri) {
9
9
  try {
10
10
  return new URL(uri).protocol === "https:";
11
- } catch (ex) {
11
+ } catch {
12
12
  return false;
13
13
  }
14
14
  };
package/src/util/zip.js CHANGED
@@ -21,7 +21,7 @@ const join = path.posix.join;
21
21
 
22
22
  // [class]
23
23
 
24
- const Main = class {
24
+ const Zip = class {
25
25
 
26
26
  // [constructor]
27
27
 
@@ -85,4 +85,4 @@ const Main = class {
85
85
 
86
86
  // [export]
87
87
 
88
- module.exports = Main;
88
+ module.exports = Zip;
package/src/config/doc.js DELETED
@@ -1,7 +0,0 @@
1
- "use strict";
2
-
3
- // [export]
4
-
5
- module.exports = {
6
- ".html": "text/html",
7
- };