arcadible 0.1.9 → 0.1.10

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,13 +30,13 @@ 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")
33
35
  .command("deploy", "Deploy to Arcadible")
34
- .command("validate", "Validate workspace")
35
36
  .command("inspect", "Inspect project metadata")
36
- .command("init", "Initialize a project")
37
- .command("whoami", "Show current Arcadible account")
38
37
  .command("login", "Log in to Arcadible")
39
38
  .command("logout", "Log out of Arcadible")
39
+ .command("whoami", "Show Arcadible account")
40
40
  .help("help")
41
41
  .alias("help", "h")
42
42
  .version(pkg.version)
package/bin/arc-deploy.js CHANGED
@@ -112,7 +112,7 @@ const main = function (argv) {
112
112
  .usage("$0 [options]")
113
113
  .option("git", {
114
114
  default: conf.git,
115
- describe: "Deploy through Git",
115
+ describe: "Deploy using Git workflow",
116
116
  type: "boolean",
117
117
  })
118
118
  .option("json", {
package/bin/arc-init.js CHANGED
@@ -82,14 +82,18 @@ const start = function (argv) {
82
82
  }
83
83
  if (!quiet) {
84
84
  log.hsnl("Initialized.");
85
+ log.h("Getting started:");
86
+ log.pnl(cfgurl.GETTING_STARTED);
85
87
  log.h("Next steps:");
86
- log.pnl(
87
- [data.path === root ? null : `cd ${dir}`, "npm install", "arc deploy"]
88
+ log.p(
89
+ [
90
+ data.path === root ? null : `cd ${dir}`,
91
+ "arc login",
92
+ "arc deploy (or: arc deploy --git)",
93
+ ]
88
94
  .filter(Boolean)
89
- .join(" && "),
95
+ .map((step, i) => `${i + 1}. ${step}`),
90
96
  );
91
- log.h("Getting started:");
92
- log.p(cfgurl.GETTING_STARTED);
93
97
  }
94
98
  // degit sometimes hangs
95
99
  process.exit(0);
@@ -149,7 +153,7 @@ const main = function (argv) {
149
153
  .option("yes", {
150
154
  alias: "y",
151
155
  default: conf.yes,
152
- describe: "Answer prompts using default values",
156
+ describe: "Accept all prompt defaults",
153
157
  type: "boolean",
154
158
  })
155
159
  .option("json", {
package/package.json CHANGED
@@ -51,5 +51,5 @@
51
51
  "license": "Apache-2.0",
52
52
  "main": "./src/cli/index.js",
53
53
  "name": "arcadible",
54
- "version": "0.1.9"
54
+ "version": "0.1.10"
55
55
  }
@@ -17,7 +17,7 @@ const os = require("./util/os");
17
17
  // [use]
18
18
 
19
19
  const configDir = os.configDir;
20
- const deepCompact = objs.deepCompact;
20
+ const deepSort = objs.deepSort;
21
21
  const join = path.join;
22
22
  const mkdir = fs.promises.mkdir;
23
23
  const readFile = fs.promises.readFile;
@@ -27,7 +27,7 @@ const writeFile = fs.promises.writeFile;
27
27
  // [declare]
28
28
 
29
29
  const CMD = "arc";
30
- const FILE = "user.json";
30
+ const FILE = "account.json";
31
31
 
32
32
  // [define]
33
33
 
@@ -42,20 +42,22 @@ const expired = function (session) {
42
42
 
43
43
  // [function]
44
44
 
45
- const save = function (user) {
45
+ const save = function (account) {
46
46
  return mkdir(dir, { recursive: true })
47
47
  .then(() =>
48
- writeFile(file, JSON.stringify(deepCompact(user), null, 2), "utf8"),
48
+ writeFile(file, JSON.stringify(deepSort(account), null, 2), "utf8"),
49
49
  )
50
- .then(() => user);
50
+ .then(() => account);
51
51
  };
52
52
 
53
53
  // [function]
54
54
 
55
- const refresh = function ({ session, ...user }) {
55
+ const refresh = function ({ session, ...account }) {
56
56
  const form = new FormData();
57
57
  form.append("refresh_token", session.refresh_token);
58
- return api.authRefresh(form).then((data) => save({ ...user, session: data }));
58
+ return api
59
+ .authRefresh(form)
60
+ .then((data) => save({ ...account, session: data }));
59
61
  };
60
62
 
61
63
  // [function]
@@ -69,13 +71,13 @@ const get = function ({ onRefresh }) {
69
71
  }
70
72
  throw ex;
71
73
  })
72
- .then((user) => {
73
- if (!user || !user.session) {
74
+ .then((account) => {
75
+ if (!account || !account.session) {
74
76
  return null;
75
77
  }
76
- return expired(user.session)
77
- ? onRefresh((renew) => (renew ? refresh(user) : null))
78
- : user;
78
+ return expired(account.session)
79
+ ? onRefresh((renew) => (renew ? refresh(account) : null))
80
+ : account;
79
81
  });
80
82
  };
81
83
 
@@ -44,7 +44,7 @@ const ensureRepo = function (root, cb) {
44
44
  const ensureRemote = function (root, cb) {
45
45
  const message = [
46
46
  "Unable to access Git remote 'origin'.",
47
- "Ensure the remote exists and you have permission to access it.",
47
+ "Ensure the remote 'origin' exists and you have permission to access it.",
48
48
  ];
49
49
  git(root, ["ls-remote", "origin"], (err) => {
50
50
  if (err) {
@@ -8,7 +8,10 @@ const path = require("node:path");
8
8
  // [import]
9
9
 
10
10
  const fs = require("fs-extra");
11
- const TOML = require("@iarna/toml");
11
+
12
+ // [import]
13
+
14
+ const TOML = require("../../util/toml");
12
15
 
13
16
  // [use]
14
17
 
@@ -37,14 +40,10 @@ const parseToml = function (buf) {
37
40
  // [function]
38
41
 
39
42
  const pickVersion = function (version, envVersion) {
40
- switch (true) {
41
- case Boolean(version):
42
- return { version };
43
- case Boolean(envVersion):
44
- return {};
45
- default:
46
- return { version: "0.1.0" };
43
+ if (version) {
44
+ return { version };
47
45
  }
46
+ return envVersion ? {} : { version: "0.1.0" };
48
47
  };
49
48
 
50
49
  // [function]
@@ -57,7 +56,7 @@ const readManifest = function (file) {
57
56
 
58
57
  // [function]
59
58
 
60
- const prepareGame = function (envVersion, game = {}) {
59
+ const patchGame = function (envVersion, game = {}) {
61
60
  const { id, version, ...rest } = game;
62
61
  return {
63
62
  id: id ?? randomUUID(),
@@ -81,7 +80,7 @@ const prepare = function (dest, envVersion) {
81
80
  const file = join(dest, MANIFEST);
82
81
  return readManifest(file).then((manifest) => {
83
82
  const { game, ...rest } = manifest;
84
- const next = { game: prepareGame(envVersion, game), ...rest };
83
+ const next = { game: patchGame(envVersion, game), ...rest };
85
84
  if (shouldWrite(manifest, next)) {
86
85
  return writeFile(file, TOML.stringify(next), "utf8");
87
86
  }
@@ -16,7 +16,7 @@ const resolve = path.resolve;
16
16
 
17
17
  // [function]
18
18
 
19
- const inferVersion = function (root) {
19
+ const detectVersion = function (root) {
20
20
  return env(root).then(({ game }) => game?.version ?? null);
21
21
  };
22
22
 
@@ -28,10 +28,10 @@ const init = function () {
28
28
 
29
29
  // [function]
30
30
 
31
- const main = function ({ project, root }) {
31
+ const main = function ({ force, project, root, template }, handler) {
32
32
  const dest = resolve(root, project);
33
- return init()
34
- .then(() => inferVersion(dest))
33
+ return init(dest, { force, template }, handler)
34
+ .then(() => detectVersion(dest))
35
35
  .then((version) => prepare(dest, version))
36
36
  .then(() => ({ path: dest }));
37
37
  };
@@ -34,13 +34,13 @@ const removeLicense = function (dest) {
34
34
 
35
35
  // [function]
36
36
 
37
- const inferVersion = function (root) {
37
+ const detectVersion = function (root) {
38
38
  return env(root).then(({ game }) => game?.version ?? null);
39
39
  };
40
40
 
41
41
  // [function]
42
42
 
43
- const init = function (src, dest, { onBegin, onInfo }) {
43
+ const scaffold = function (src, dest, { onBegin, onInfo }) {
44
44
  onBegin({ dest, src });
45
45
  return degit(src, { cache: false, force: true, verbose: false })
46
46
  .on("info", onInfo)
@@ -49,19 +49,22 @@ const init = function (src, dest, { onBegin, onInfo }) {
49
49
 
50
50
  // [function]
51
51
 
52
+ const init = function (dest, { force, template }, handler) {
53
+ return pathExists(dest).then((exists) => {
54
+ if (exists && !force) {
55
+ throw new Error("Directory already exists. Use `--force` to overwrite.");
56
+ }
57
+ return scaffold(template, dest, handler);
58
+ });
59
+ };
60
+
61
+ // [function]
62
+
52
63
  const main = function ({ force, project, root, template }, handler) {
53
64
  const dest = resolve(root, project);
54
- return pathExists(dest)
55
- .then((exists) => {
56
- if (exists && !force) {
57
- throw new Error(
58
- "Directory already exists. Use `--force` to overwrite.",
59
- );
60
- }
61
- return init(template, dest, handler);
62
- })
65
+ return init(dest, { force, template }, handler)
63
66
  .then(() => removeLicense(dest))
64
- .then(() => inferVersion(dest))
67
+ .then(() => detectVersion(dest))
65
68
  .then((version) => prepare(dest, version))
66
69
  .then(() => ({ path: dest }));
67
70
  };
@@ -2,13 +2,13 @@
2
2
 
3
3
  // [import]
4
4
 
5
+ const account = require("../../account");
5
6
  const flow = require("./flow");
6
- const user = require("../../user");
7
7
 
8
8
  // [function]
9
9
 
10
10
  const main = function (conf, handler) {
11
- return flow(handler).then(user.save);
11
+ return flow(handler).then(account.save);
12
12
  };
13
13
 
14
14
  // [export]
@@ -2,12 +2,12 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const user = require("../../user");
5
+ const account = require("../../account");
6
6
 
7
7
  // [function]
8
8
 
9
9
  const main = function () {
10
- return user.remove();
10
+ return account.remove();
11
11
  };
12
12
 
13
13
  // [export]
@@ -2,12 +2,12 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const user = require("../../user");
5
+ const account = require("../../account");
6
6
 
7
7
  // [function]
8
8
 
9
9
  const main = function (conf, handler) {
10
- return user.get(handler);
10
+ return account.get(handler);
11
11
  };
12
12
 
13
13
  // [export]
package/src/parser/env.js CHANGED
@@ -37,10 +37,10 @@ const parseJson = function (buf) {
37
37
 
38
38
  // [function]
39
39
 
40
- const extract = function (pkg) {
40
+ const extract = function (conf) {
41
41
  /* eslint-disable camelcase */
42
- const game = { version: pkg.version };
43
- const workflow = { build: pkg.scripts?.build ?? "" };
42
+ const game = { version: conf.version };
43
+ const workflow = { build: conf.scripts?.build ?? "" };
44
44
  /* eslint-enable camelcase */
45
45
  return deepCompact({ game, workflow });
46
46
  };
@@ -52,7 +52,7 @@ const main = function (root) {
52
52
  return pathExists(file)
53
53
  .then((exists) => (exists ? readFile(file, "utf8") : null))
54
54
  .then((buf) => (buf === null ? {} : parseJson(buf)))
55
- .then((pkg) => (Object.keys(pkg).length ? extract(pkg) : {}));
55
+ .then((conf) => (Object.keys(conf).length ? extract(conf) : {}));
56
56
  };
57
57
 
58
58
  // [export]
@@ -7,10 +7,15 @@ const path = require("node:path");
7
7
  // [import]
8
8
 
9
9
  const fs = require("fs-extra");
10
- const TOML = require("@iarna/toml");
10
+
11
+ // [import]
12
+
13
+ const objs = require("../util/objs");
14
+ const TOML = require("../util/toml");
11
15
 
12
16
  // [use]
13
17
 
18
+ const deepCompact = objs.deepCompact;
14
19
  const join = path.join;
15
20
  const pathExists = fs.pathExists;
16
21
  const readFile = fs.readFile;
@@ -33,11 +38,18 @@ const parseToml = function (buf) {
33
38
 
34
39
  // [function]
35
40
 
41
+ const extract = function (conf) {
42
+ return deepCompact(conf);
43
+ };
44
+
45
+ // [function]
46
+
36
47
  const main = function (root) {
37
48
  const file = join(root, MANIFEST);
38
49
  return pathExists(file)
39
50
  .then((exists) => (exists ? readFile(file, "utf8") : null))
40
- .then((buf) => (buf === null ? {} : parseToml(buf)));
51
+ .then((buf) => (buf === null ? {} : parseToml(buf)))
52
+ .then((conf) => (Object.keys(conf).length ? extract(conf) : {}));
41
53
  };
42
54
 
43
55
  // [export]
@@ -10,8 +10,8 @@ module.exports = {
10
10
  select: {
11
11
  choices: [
12
12
  {
13
- description: "Blank starter.",
14
- name: "Blank",
13
+ description: "Zero-build static starter.",
14
+ name: "Default",
15
15
  value: `${REPO}/starter`,
16
16
  },
17
17
  {
@@ -301,8 +301,12 @@ const zIconVideo = function (root) {
301
301
  const zId = function () {
302
302
  const field = "id";
303
303
  return z
304
- .string()
305
- .uuid(message(field, ["Must be a valid UUID."]))
304
+ .uuid(
305
+ message(field, [
306
+ "Must be a valid UUID.",
307
+ "Run `arc init` to generate a new game ID.",
308
+ ]),
309
+ )
306
310
  .refine(
307
311
  (value) => value === value.toLowerCase(),
308
312
  message(field, ["Must use lowercase characters."]),
@@ -389,7 +393,7 @@ const zTrailer = function () {
389
393
  .refine(
390
394
  (url) =>
391
395
  zVimeo().safeParse(url).success || zYouTube().safeParse(url).success,
392
- message(field, ["Must be a YouTube (or Vimeo) URL."]),
396
+ message(field, ["Must be a YouTube or Vimeo URL."]),
393
397
  )
394
398
  .optional();
395
399
  };
@@ -402,7 +406,7 @@ const zVersion = function () {
402
406
  .string()
403
407
  .refine(
404
408
  (value) => validSemver(value) !== null,
405
- message(field, ["Must be a valid semver."]),
409
+ message(field, ["Must be valid semver."]),
406
410
  );
407
411
  };
408
412
 
@@ -61,7 +61,7 @@ const zDeployDir = function (root, { build }) {
61
61
  )
62
62
  .refine(
63
63
  (file) => isOutCheck(root, file),
64
- message(field, ["Must be within the project."]),
64
+ message(field, ["Must be within the project directory."]),
65
65
  )
66
66
  .refine(
67
67
  (file) => isReservedCheck(root, file, MEDIA),
@@ -70,8 +70,8 @@ const zDeployDir = function (root, { build }) {
70
70
  .refine(
71
71
  (file) => build || existsCheck(root, file),
72
72
  message(field, [
73
- "Must exist if there is no build step.",
74
- "Run `arc inspect workflow.deploy_dir` for its value.",
73
+ "Must exist when there is no build step.",
74
+ "Run `arc inspect workflow.deploy_dir` to check the configured value.",
75
75
  ]),
76
76
  );
77
77
  };
package/src/util/delay.js CHANGED
@@ -46,7 +46,7 @@ const poll = function (
46
46
  }
47
47
  const elapsed = Date.now() - started;
48
48
  if (elapsed >= timeout) {
49
- throw new Error("Timed out.");
49
+ throw new Error("Operation timed out.");
50
50
  }
51
51
  return wait(backoff(elapsed, delay, factor, interval, maxDelay), next);
52
52
  });
@@ -2,11 +2,8 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const TOML = require("@iarna/toml");
6
-
7
- // [import]
8
-
9
5
  const objs = require("./objs");
6
+ const TOML = require("./toml");
10
7
 
11
8
  // [use]
12
9
 
@@ -35,7 +32,7 @@ const printToml = function (data, key = "value") {
35
32
  try {
36
33
  write(TOML.stringify(deepSort(data)));
37
34
  } catch (ex) {
38
- write(TOML.stringify({ [field]: data }));
35
+ write(TOML.stringify(deepSort({ [field]: data })));
39
36
  }
40
37
  };
41
38
 
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ // [import]
4
+
5
+ const TOML = require("@iarna/toml");
6
+
7
+ // [use]
8
+
9
+ const parse = TOML.parse;
10
+ const stringify = TOML.stringify;
11
+
12
+ // [export]
13
+
14
+ module.exports = { parse, stringify };
package/src/util/video.js CHANGED
@@ -57,7 +57,7 @@ const readMp4 = function (file) {
57
57
  };
58
58
  };
59
59
  mp4.onError = function (mod, msg) {
60
- error = new Error(`MP4Box(${mod}): ${msg}`);
60
+ error = new Error(msg);
61
61
  };
62
62
  const buffer = data.buffer.slice(
63
63
  data.byteOffset,
@@ -70,7 +70,7 @@ const readMp4 = function (file) {
70
70
  throw error;
71
71
  }
72
72
  if (!video) {
73
- throw new Error("MP4 metadata not available.");
73
+ throw new Error("No video metadata found.");
74
74
  }
75
75
  return video;
76
76
  };