arcadible 0.1.8 → 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.
- package/bin/arc-default.js +3 -3
- package/bin/arc-deploy.js +1 -1
- package/bin/arc-init.js +28 -24
- package/bin/arc-pack.js +1 -1
- package/package.json +1 -1
- package/src/{user.js → account.js} +14 -12
- package/src/action/{deploy-git → deploy}/git.js +1 -1
- package/src/action/init/manifest.js +93 -0
- package/src/action/init/tool-patch.js +41 -0
- package/src/action/init/tool.js +40 -12
- package/src/action/login/flow.js +3 -1
- package/src/action/login/tool.js +2 -2
- package/src/action/logout/tool.js +2 -2
- package/src/action/pack/tool.js +51 -10
- package/src/action/whoami/tool.js +2 -2
- package/src/cli/deploy.js +2 -2
- package/src/cli/init.js +4 -2
- package/src/parser/{pkg.js → env.js} +4 -4
- package/src/parser/manifest.js +14 -2
- package/src/parser/project.js +18 -19
- package/src/prompt/template.js +2 -2
- package/src/schema/game.js +21 -16
- package/src/schema/workflow.js +4 -4
- package/src/util/delay.js +59 -0
- package/src/util/output.js +2 -5
- package/src/util/size.js +29 -0
- package/src/util/time.js +1 -51
- package/src/util/toml.js +14 -0
- package/src/util/video.js +2 -2
- package/src/util/zip.js +6 -0
- package/src/prompt/project.js +0 -10
- /package/src/action/{deploy-git/tool.js → deploy/tool-git.js} +0 -0
package/bin/arc-default.js
CHANGED
|
@@ -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
package/bin/arc-init.js
CHANGED
|
@@ -7,6 +7,7 @@ const path = require("node:path");
|
|
|
7
7
|
|
|
8
8
|
// [import]
|
|
9
9
|
|
|
10
|
+
const fs = require("fs-extra");
|
|
10
11
|
const hideBin = require("yargs/helpers").hideBin;
|
|
11
12
|
const prompts = require("@inquirer/prompts");
|
|
12
13
|
const yargs = require("yargs/yargs");
|
|
@@ -18,14 +19,14 @@ const init = require("../src/cli/init");
|
|
|
18
19
|
const log = require("../src/util/log");
|
|
19
20
|
const output = require("../src/util/output");
|
|
20
21
|
const pkg = require("../package.json");
|
|
21
|
-
const project = require("../src/prompt/project");
|
|
22
22
|
const rc = require("../src/util/rc");
|
|
23
23
|
const template = require("../src/prompt/template");
|
|
24
24
|
|
|
25
25
|
// [use]
|
|
26
26
|
|
|
27
27
|
const findRc = rc.findRc;
|
|
28
|
-
const
|
|
28
|
+
const join = path.join;
|
|
29
|
+
const pathExists = fs.pathExists;
|
|
29
30
|
const print = output.print;
|
|
30
31
|
const relative = path.relative;
|
|
31
32
|
const resolve = path.resolve;
|
|
@@ -39,8 +40,8 @@ const SUBCMD = "init";
|
|
|
39
40
|
// [define]
|
|
40
41
|
|
|
41
42
|
const conf = {
|
|
42
|
-
force: false,
|
|
43
43
|
json: false,
|
|
44
|
+
project: ".",
|
|
44
45
|
quiet: false,
|
|
45
46
|
yes: false,
|
|
46
47
|
...findRc(CMD, SUBCMD, process.argv, ["--cwd", "-C"]),
|
|
@@ -66,8 +67,9 @@ const start = function (argv) {
|
|
|
66
67
|
const quiet = argv.quiet;
|
|
67
68
|
const root = resolve(process.cwd(), argv.cwd);
|
|
68
69
|
return init({
|
|
69
|
-
force:
|
|
70
|
+
force: false,
|
|
70
71
|
handler: handler({ json, quiet }),
|
|
72
|
+
patch: argv.patch,
|
|
71
73
|
project: argv.project,
|
|
72
74
|
root,
|
|
73
75
|
template: argv.template,
|
|
@@ -80,14 +82,18 @@ const start = function (argv) {
|
|
|
80
82
|
}
|
|
81
83
|
if (!quiet) {
|
|
82
84
|
log.hsnl("Initialized.");
|
|
85
|
+
log.h("Getting started:");
|
|
86
|
+
log.pnl(cfgurl.GETTING_STARTED);
|
|
83
87
|
log.h("Next steps:");
|
|
84
|
-
log.
|
|
85
|
-
[
|
|
88
|
+
log.p(
|
|
89
|
+
[
|
|
90
|
+
data.path === root ? null : `cd ${dir}`,
|
|
91
|
+
"arc login",
|
|
92
|
+
"arc deploy (or: arc deploy --git)",
|
|
93
|
+
]
|
|
86
94
|
.filter(Boolean)
|
|
87
|
-
.
|
|
95
|
+
.map((step, i) => `${i + 1}. ${step}`),
|
|
88
96
|
);
|
|
89
|
-
log.h("Getting started:");
|
|
90
|
-
log.p(cfgurl.GETTING_STARTED);
|
|
91
97
|
}
|
|
92
98
|
// degit sometimes hangs
|
|
93
99
|
process.exit(0);
|
|
@@ -106,17 +112,20 @@ const start = function (argv) {
|
|
|
106
112
|
|
|
107
113
|
// [function]
|
|
108
114
|
|
|
115
|
+
const patch = function (cwd, project) {
|
|
116
|
+
return pathExists(join(resolve(process.cwd(), cwd), project));
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// [function]
|
|
120
|
+
|
|
109
121
|
const prompt = async function ({ yes, ...argv }) {
|
|
110
122
|
const opts = { ...argv };
|
|
111
|
-
|
|
112
|
-
|
|
123
|
+
opts.patch = await patch(opts.cwd, opts.project);
|
|
124
|
+
if (opts.patch || yes) {
|
|
113
125
|
opts.template ??= template.select.default;
|
|
114
126
|
return opts;
|
|
115
127
|
}
|
|
116
|
-
if (!
|
|
117
|
-
opts.project = await input(project.input);
|
|
118
|
-
}
|
|
119
|
-
if (!argv.template) {
|
|
128
|
+
if (!opts.template) {
|
|
120
129
|
opts.template = await select(template.select);
|
|
121
130
|
}
|
|
122
131
|
return opts;
|
|
@@ -128,9 +137,10 @@ const main = function (argv) {
|
|
|
128
137
|
return prompt(
|
|
129
138
|
yargs(hideBin(argv))
|
|
130
139
|
.scriptName(`${CMD} ${SUBCMD}`)
|
|
131
|
-
.usage("$0
|
|
132
|
-
.command("$0
|
|
140
|
+
.usage("$0 [project] [options]")
|
|
141
|
+
.command("$0 [project]", false, (cli) =>
|
|
133
142
|
cli.positional("project", {
|
|
143
|
+
default: conf.project,
|
|
134
144
|
describe: "Project directory",
|
|
135
145
|
type: "string",
|
|
136
146
|
}),
|
|
@@ -143,13 +153,7 @@ const main = function (argv) {
|
|
|
143
153
|
.option("yes", {
|
|
144
154
|
alias: "y",
|
|
145
155
|
default: conf.yes,
|
|
146
|
-
describe: "
|
|
147
|
-
type: "boolean",
|
|
148
|
-
})
|
|
149
|
-
.option("force", {
|
|
150
|
-
alias: "f",
|
|
151
|
-
default: conf.force,
|
|
152
|
-
describe: "Overwrite an existing directory",
|
|
156
|
+
describe: "Accept all prompt defaults",
|
|
153
157
|
type: "boolean",
|
|
154
158
|
})
|
|
155
159
|
.option("json", {
|
package/bin/arc-pack.js
CHANGED
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ const os = require("./util/os");
|
|
|
17
17
|
// [use]
|
|
18
18
|
|
|
19
19
|
const configDir = os.configDir;
|
|
20
|
-
const
|
|
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 = "
|
|
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 (
|
|
45
|
+
const save = function (account) {
|
|
46
46
|
return mkdir(dir, { recursive: true })
|
|
47
47
|
.then(() =>
|
|
48
|
-
writeFile(file, JSON.stringify(
|
|
48
|
+
writeFile(file, JSON.stringify(deepSort(account), null, 2), "utf8"),
|
|
49
49
|
)
|
|
50
|
-
.then(() =>
|
|
50
|
+
.then(() => account);
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
// [function]
|
|
54
54
|
|
|
55
|
-
const refresh = function ({ session, ...
|
|
55
|
+
const refresh = function ({ session, ...account }) {
|
|
56
56
|
const form = new FormData();
|
|
57
57
|
form.append("refresh_token", session.refresh_token);
|
|
58
|
-
return api
|
|
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((
|
|
73
|
-
if (!
|
|
74
|
+
.then((account) => {
|
|
75
|
+
if (!account || !account.session) {
|
|
74
76
|
return null;
|
|
75
77
|
}
|
|
76
|
-
return expired(
|
|
77
|
-
? onRefresh((renew) => (renew ? refresh(
|
|
78
|
-
:
|
|
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) {
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const crypto = require("node:crypto");
|
|
6
|
+
const path = require("node:path");
|
|
7
|
+
|
|
8
|
+
// [import]
|
|
9
|
+
|
|
10
|
+
const fs = require("fs-extra");
|
|
11
|
+
|
|
12
|
+
// [import]
|
|
13
|
+
|
|
14
|
+
const TOML = require("../../util/toml");
|
|
15
|
+
|
|
16
|
+
// [use]
|
|
17
|
+
|
|
18
|
+
const join = path.join;
|
|
19
|
+
const pathExists = fs.pathExists;
|
|
20
|
+
const randomUUID = crypto.randomUUID;
|
|
21
|
+
const readFile = fs.promises.readFile;
|
|
22
|
+
const writeFile = fs.promises.writeFile;
|
|
23
|
+
|
|
24
|
+
// [declare]
|
|
25
|
+
|
|
26
|
+
const MANIFEST = "arcadible.toml";
|
|
27
|
+
|
|
28
|
+
// [function]
|
|
29
|
+
|
|
30
|
+
const parseToml = function (buf) {
|
|
31
|
+
try {
|
|
32
|
+
return TOML.parse(buf);
|
|
33
|
+
} catch (ex) {
|
|
34
|
+
throw new Error(`Unable to parse ${MANIFEST}: ${ex.message}`, {
|
|
35
|
+
cause: ex,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// [function]
|
|
41
|
+
|
|
42
|
+
const pickVersion = function (version, envVersion) {
|
|
43
|
+
if (version) {
|
|
44
|
+
return { version };
|
|
45
|
+
}
|
|
46
|
+
return envVersion ? {} : { version: "0.1.0" };
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// [function]
|
|
50
|
+
|
|
51
|
+
const readManifest = function (file) {
|
|
52
|
+
return pathExists(file)
|
|
53
|
+
.then((exists) => (exists ? readFile(file, "utf8") : null))
|
|
54
|
+
.then((buf) => (buf === null ? {} : parseToml(buf)));
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// [function]
|
|
58
|
+
|
|
59
|
+
const patchGame = function (envVersion, game = {}) {
|
|
60
|
+
const { id, version, ...rest } = game;
|
|
61
|
+
return {
|
|
62
|
+
id: id ?? randomUUID(),
|
|
63
|
+
...pickVersion(version, envVersion),
|
|
64
|
+
...rest,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// [function]
|
|
69
|
+
|
|
70
|
+
const shouldWrite = function (manifest, next) {
|
|
71
|
+
return (
|
|
72
|
+
manifest.game?.id !== next.game?.id ||
|
|
73
|
+
manifest.game?.version !== next.game?.version
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// [function]
|
|
78
|
+
|
|
79
|
+
const prepare = function (dest, envVersion) {
|
|
80
|
+
const file = join(dest, MANIFEST);
|
|
81
|
+
return readManifest(file).then((manifest) => {
|
|
82
|
+
const { game, ...rest } = manifest;
|
|
83
|
+
const next = { game: patchGame(envVersion, game), ...rest };
|
|
84
|
+
if (shouldWrite(manifest, next)) {
|
|
85
|
+
return writeFile(file, TOML.stringify(next), "utf8");
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// [export]
|
|
92
|
+
|
|
93
|
+
module.exports = { prepare };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
|
|
7
|
+
// [import]
|
|
8
|
+
|
|
9
|
+
const env = require("../../parser/env");
|
|
10
|
+
const manifest = require("./manifest");
|
|
11
|
+
|
|
12
|
+
// [use]
|
|
13
|
+
|
|
14
|
+
const prepare = manifest.prepare;
|
|
15
|
+
const resolve = path.resolve;
|
|
16
|
+
|
|
17
|
+
// [function]
|
|
18
|
+
|
|
19
|
+
const detectVersion = function (root) {
|
|
20
|
+
return env(root).then(({ game }) => game?.version ?? null);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// [function]
|
|
24
|
+
|
|
25
|
+
const init = function () {
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// [function]
|
|
30
|
+
|
|
31
|
+
const main = function ({ force, project, root, template }, handler) {
|
|
32
|
+
const dest = resolve(root, project);
|
|
33
|
+
return init(dest, { force, template }, handler)
|
|
34
|
+
.then(() => detectVersion(dest))
|
|
35
|
+
.then((version) => prepare(dest, version))
|
|
36
|
+
.then(() => ({ path: dest }));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// [export]
|
|
40
|
+
|
|
41
|
+
module.exports = main;
|
package/src/action/init/tool.js
CHANGED
|
@@ -9,35 +9,63 @@ const path = require("node:path");
|
|
|
9
9
|
const degit = require("degit");
|
|
10
10
|
const fs = require("fs-extra");
|
|
11
11
|
|
|
12
|
+
// [import]
|
|
13
|
+
|
|
14
|
+
const env = require("../../parser/env");
|
|
15
|
+
const manifest = require("./manifest");
|
|
16
|
+
|
|
12
17
|
// [use]
|
|
13
18
|
|
|
19
|
+
const join = path.join;
|
|
14
20
|
const pathExists = fs.pathExists;
|
|
21
|
+
const prepare = manifest.prepare;
|
|
15
22
|
const remove = fs.remove;
|
|
16
23
|
const resolve = path.resolve;
|
|
17
24
|
|
|
25
|
+
// [declare]
|
|
26
|
+
|
|
27
|
+
const LICENSE = "LICENSE";
|
|
28
|
+
|
|
29
|
+
// [function]
|
|
30
|
+
|
|
31
|
+
const removeLicense = function (dest) {
|
|
32
|
+
return remove(join(dest, LICENSE));
|
|
33
|
+
};
|
|
34
|
+
|
|
18
35
|
// [function]
|
|
19
36
|
|
|
20
|
-
const
|
|
37
|
+
const detectVersion = function (root) {
|
|
38
|
+
return env(root).then(({ game }) => game?.version ?? null);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// [function]
|
|
42
|
+
|
|
43
|
+
const scaffold = function (src, dest, { onBegin, onInfo }) {
|
|
21
44
|
onBegin({ dest, src });
|
|
22
45
|
return degit(src, { cache: false, force: true, verbose: false })
|
|
23
46
|
.on("info", onInfo)
|
|
24
|
-
.clone(dest)
|
|
25
|
-
|
|
47
|
+
.clone(dest);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// [function]
|
|
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
|
+
});
|
|
26
59
|
};
|
|
27
60
|
|
|
28
61
|
// [function]
|
|
29
62
|
|
|
30
63
|
const main = function ({ force, project, root, template }, handler) {
|
|
31
64
|
const dest = resolve(root, project);
|
|
32
|
-
return
|
|
33
|
-
.then((
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"Directory already exists. Use `--force` to overwrite.",
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
return init(template, dest, handler);
|
|
40
|
-
})
|
|
65
|
+
return init(dest, { force, template }, handler)
|
|
66
|
+
.then(() => removeLicense(dest))
|
|
67
|
+
.then(() => detectVersion(dest))
|
|
68
|
+
.then((version) => prepare(dest, version))
|
|
41
69
|
.then(() => ({ path: dest }));
|
|
42
70
|
};
|
|
43
71
|
|
package/src/action/login/flow.js
CHANGED
|
@@ -8,10 +8,12 @@ const crypto = require("node:crypto");
|
|
|
8
8
|
|
|
9
9
|
const api = require("../../api");
|
|
10
10
|
const cfgurl = require("../../config/url");
|
|
11
|
+
const delay = require("../../util/delay");
|
|
11
12
|
const time = require("../../util/time");
|
|
12
13
|
|
|
13
14
|
// [use]
|
|
14
15
|
|
|
16
|
+
const poll = delay.poll;
|
|
15
17
|
const randomUUID = crypto.randomUUID;
|
|
16
18
|
|
|
17
19
|
// [function]
|
|
@@ -75,7 +77,7 @@ const main = function ({ onCreated, onPoll }) {
|
|
|
75
77
|
onCreated,
|
|
76
78
|
).then(({ id }) => {
|
|
77
79
|
const timeout = Math.max(0, expiresAt.getTime() - Date.now() - time.s(15));
|
|
78
|
-
return
|
|
80
|
+
return poll(
|
|
79
81
|
(flow) => pollFlow(flow, onPoll),
|
|
80
82
|
{ id, token },
|
|
81
83
|
{
|
package/src/action/login/tool.js
CHANGED
|
@@ -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(
|
|
11
|
+
return flow(handler).then(account.save);
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
// [export]
|
package/src/action/pack/tool.js
CHANGED
|
@@ -11,6 +11,7 @@ const fs = require("fs-extra");
|
|
|
11
11
|
// [import]
|
|
12
12
|
|
|
13
13
|
const project = require("../../parser/project");
|
|
14
|
+
const size = require("../../util/size");
|
|
14
15
|
const Zip = require("../../util/zip");
|
|
15
16
|
|
|
16
17
|
// [use]
|
|
@@ -21,38 +22,78 @@ const resolve = path.resolve;
|
|
|
21
22
|
|
|
22
23
|
// [declare]
|
|
23
24
|
|
|
25
|
+
const MAIN = "index.html";
|
|
24
26
|
const MANIFEST = "arcadible.json";
|
|
25
27
|
const MEDIA = ".arcadible";
|
|
28
|
+
const OUTPUT = ".arc/package";
|
|
29
|
+
|
|
30
|
+
// [declare]
|
|
31
|
+
|
|
32
|
+
const SIZE_PARTIAL = size.mb(64);
|
|
33
|
+
const SIZE_TOTAL = size.mb(256);
|
|
34
|
+
|
|
35
|
+
// [function]
|
|
36
|
+
|
|
37
|
+
const verifyPartial = function (zip) {
|
|
38
|
+
if (!zip.has(MAIN)) {
|
|
39
|
+
throw new Error(`Package is missing "${MAIN}".`);
|
|
40
|
+
}
|
|
41
|
+
if (zip.stat().size > SIZE_PARTIAL) {
|
|
42
|
+
const max = SIZE_PARTIAL / 1024 / 1024;
|
|
43
|
+
throw new Error(`Package size (excluding store assets) exceeds ${max} MB.`);
|
|
44
|
+
}
|
|
45
|
+
return zip;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// [function]
|
|
49
|
+
|
|
50
|
+
const verifyTotal = function (zip) {
|
|
51
|
+
if (zip.stat().size > SIZE_TOTAL) {
|
|
52
|
+
const max = SIZE_TOTAL / 1024 / 1024;
|
|
53
|
+
throw new Error(`Package size (including store assets) exceeds ${max} MB.`);
|
|
54
|
+
}
|
|
55
|
+
return zip;
|
|
56
|
+
};
|
|
26
57
|
|
|
27
58
|
// [function]
|
|
28
59
|
|
|
29
60
|
const pack = function (name, game, { deployPath, mediaPath, zipPath }) {
|
|
30
61
|
const zip = new Zip(name);
|
|
31
|
-
return
|
|
32
|
-
.then((
|
|
62
|
+
return pathExists(deployPath)
|
|
63
|
+
.then((existsDeploy) => {
|
|
33
64
|
if (existsDeploy) {
|
|
34
65
|
zip.addDir(deployPath);
|
|
35
66
|
}
|
|
67
|
+
return zip;
|
|
68
|
+
})
|
|
69
|
+
.then(verifyPartial)
|
|
70
|
+
.then(() => pathExists(mediaPath))
|
|
71
|
+
.then((existsMedia) => {
|
|
36
72
|
if (existsMedia) {
|
|
37
73
|
zip.addDir(mediaPath, MEDIA);
|
|
38
74
|
}
|
|
39
75
|
zip.addJson(MANIFEST, { game });
|
|
40
|
-
zip
|
|
41
|
-
return zip.stat();
|
|
76
|
+
return zip;
|
|
42
77
|
})
|
|
43
|
-
.then(
|
|
78
|
+
.then(verifyTotal)
|
|
79
|
+
.then((file) => {
|
|
80
|
+
file.write(zipPath);
|
|
81
|
+
return { path: zipPath, ...file.stat() };
|
|
82
|
+
});
|
|
44
83
|
};
|
|
45
84
|
|
|
46
85
|
// [function]
|
|
47
86
|
|
|
48
87
|
const main = function ({ output, root }) {
|
|
49
|
-
return project(root).then(({ game, workflow }) =>
|
|
50
|
-
|
|
88
|
+
return project(root).then(({ game, workflow }) => {
|
|
89
|
+
const name = game.handle || game.id;
|
|
90
|
+
const file = output || `${OUTPUT}/${name}-v${game.version}.zip`;
|
|
91
|
+
return pack(parse(file).name, game, {
|
|
51
92
|
deployPath: resolve(root, workflow.deploy_dir),
|
|
52
93
|
mediaPath: resolve(root, MEDIA),
|
|
53
|
-
zipPath: resolve(root,
|
|
54
|
-
})
|
|
55
|
-
);
|
|
94
|
+
zipPath: resolve(root, file),
|
|
95
|
+
});
|
|
96
|
+
});
|
|
56
97
|
};
|
|
57
98
|
|
|
58
99
|
// [export]
|
package/src/cli/deploy.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
|
-
const deployGitTool = require("../action/deploy-git/tool");
|
|
6
5
|
const deployTool = require("../action/deploy/tool");
|
|
6
|
+
const deployToolGit = require("../action/deploy/tool-git");
|
|
7
7
|
|
|
8
8
|
// [function]
|
|
9
9
|
|
|
10
10
|
const main = function ({ git, handler, ...conf }) {
|
|
11
|
-
const tool = git ?
|
|
11
|
+
const tool = git ? deployToolGit : deployTool;
|
|
12
12
|
return tool(conf, handler);
|
|
13
13
|
};
|
|
14
14
|
|
package/src/cli/init.js
CHANGED
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
5
|
const initTool = require("../action/init/tool");
|
|
6
|
+
const initToolPatch = require("../action/init/tool-patch");
|
|
6
7
|
|
|
7
8
|
// [function]
|
|
8
9
|
|
|
9
|
-
const main = function ({ handler, ...conf }) {
|
|
10
|
-
|
|
10
|
+
const main = function ({ handler, patch, ...conf }) {
|
|
11
|
+
const tool = patch ? initToolPatch : initTool;
|
|
12
|
+
return tool(conf, handler);
|
|
11
13
|
};
|
|
12
14
|
|
|
13
15
|
// [export]
|
|
@@ -37,10 +37,10 @@ const parseJson = function (buf) {
|
|
|
37
37
|
|
|
38
38
|
// [function]
|
|
39
39
|
|
|
40
|
-
const extract = function (
|
|
40
|
+
const extract = function (conf) {
|
|
41
41
|
/* eslint-disable camelcase */
|
|
42
|
-
const game = { version:
|
|
43
|
-
const workflow = { 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((
|
|
55
|
+
.then((conf) => (Object.keys(conf).length ? extract(conf) : {}));
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
// [export]
|
package/src/parser/manifest.js
CHANGED
|
@@ -7,10 +7,15 @@ const path = require("node:path");
|
|
|
7
7
|
// [import]
|
|
8
8
|
|
|
9
9
|
const fs = require("fs-extra");
|
|
10
|
-
|
|
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]
|
package/src/parser/project.js
CHANGED
|
@@ -4,31 +4,31 @@
|
|
|
4
4
|
|
|
5
5
|
const cfggame = require("../config/game");
|
|
6
6
|
const cfgworkflow = require("../config/workflow");
|
|
7
|
+
const env = require("./env");
|
|
7
8
|
const manifest = require("./manifest");
|
|
8
9
|
const media = require("./media");
|
|
9
|
-
const pkg = require("./pkg");
|
|
10
10
|
const promise = require("../util/promise");
|
|
11
11
|
const readme = require("./readme");
|
|
12
12
|
|
|
13
13
|
// [function]
|
|
14
14
|
|
|
15
|
-
const configGame = function (readmeGame, mediaGame,
|
|
15
|
+
const configGame = function (readmeGame, mediaGame, envGame, manifestGame) {
|
|
16
16
|
return {
|
|
17
17
|
...cfggame,
|
|
18
|
-
...(readmeGame
|
|
19
|
-
...(mediaGame
|
|
20
|
-
...(
|
|
21
|
-
...(manifestGame
|
|
18
|
+
...(readmeGame ?? {}),
|
|
19
|
+
...(mediaGame ?? {}),
|
|
20
|
+
...(envGame ?? {}),
|
|
21
|
+
...(manifestGame ?? {}),
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
// [function]
|
|
26
26
|
|
|
27
|
-
const configWorkflow = function (
|
|
27
|
+
const configWorkflow = function (envWorkflow, manifestWorkflow) {
|
|
28
28
|
return {
|
|
29
29
|
...cfgworkflow,
|
|
30
|
-
...(
|
|
31
|
-
...(manifestWorkflow
|
|
30
|
+
...(envWorkflow ?? {}),
|
|
31
|
+
...(manifestWorkflow ?? {}),
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
34
|
|
|
@@ -36,23 +36,22 @@ const configWorkflow = function (pkgWorkflow, manifestWorkflow) {
|
|
|
36
36
|
|
|
37
37
|
const main = function (root) {
|
|
38
38
|
const parsers = [
|
|
39
|
-
() => manifest(root),
|
|
40
|
-
() => media(root),
|
|
41
|
-
() => pkg(root),
|
|
42
39
|
() => readme(root),
|
|
40
|
+
() => media(root),
|
|
41
|
+
() => env(root),
|
|
42
|
+
() => manifest(root),
|
|
43
43
|
];
|
|
44
44
|
return promise
|
|
45
45
|
.serial(parsers)
|
|
46
|
-
.then(([
|
|
47
|
-
|
|
46
|
+
.then(([readmeData, mediaData, envData, manifestData]) => ({
|
|
47
|
+
game: configGame(
|
|
48
48
|
readmeData.game,
|
|
49
49
|
mediaData.game,
|
|
50
|
-
|
|
50
|
+
envData.game,
|
|
51
51
|
manifestData.game,
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
52
|
+
),
|
|
53
|
+
workflow: configWorkflow(envData.workflow, manifestData.workflow),
|
|
54
|
+
}));
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
// [export]
|
package/src/prompt/template.js
CHANGED
package/src/schema/game.js
CHANGED
|
@@ -17,6 +17,7 @@ const cfgurl = require("../config/url");
|
|
|
17
17
|
const cfgvisibility = require("../config/visibility");
|
|
18
18
|
const check = require("./check/game");
|
|
19
19
|
const dom = require("../util/dom");
|
|
20
|
+
const size = require("../util/size");
|
|
20
21
|
const strs = require("../util/strs");
|
|
21
22
|
|
|
22
23
|
// [use]
|
|
@@ -152,7 +153,7 @@ const zBanner = function (root) {
|
|
|
152
153
|
return z.optional(
|
|
153
154
|
zPng(field, root, {
|
|
154
155
|
aspect: "2:1",
|
|
155
|
-
maxSize: 2
|
|
156
|
+
maxSize: size.mb(2),
|
|
156
157
|
minHeight: 512,
|
|
157
158
|
minWidth: 1024,
|
|
158
159
|
}),
|
|
@@ -166,7 +167,7 @@ const zBannerVideo = function (root) {
|
|
|
166
167
|
return z.optional(
|
|
167
168
|
zMp4(field, root, {
|
|
168
169
|
aspect: "2:1",
|
|
169
|
-
maxSize: 5
|
|
170
|
+
maxSize: size.mb(5),
|
|
170
171
|
minHeight: 512,
|
|
171
172
|
minWidth: 1024,
|
|
172
173
|
}),
|
|
@@ -187,7 +188,7 @@ const zCover = function (root) {
|
|
|
187
188
|
return z.optional(
|
|
188
189
|
zPng(field, root, {
|
|
189
190
|
aspect: "3:2",
|
|
190
|
-
maxSize: 2
|
|
191
|
+
maxSize: size.mb(2),
|
|
191
192
|
minHeight: 512,
|
|
192
193
|
minWidth: 768,
|
|
193
194
|
}),
|
|
@@ -201,7 +202,7 @@ const zCoverVideo = function (root) {
|
|
|
201
202
|
return z.optional(
|
|
202
203
|
zMp4(field, root, {
|
|
203
204
|
aspect: "3:2",
|
|
204
|
-
maxSize: 5
|
|
205
|
+
maxSize: size.mb(5),
|
|
205
206
|
minHeight: 512,
|
|
206
207
|
minWidth: 768,
|
|
207
208
|
}),
|
|
@@ -237,8 +238,8 @@ const zGallery = function (root) {
|
|
|
237
238
|
z
|
|
238
239
|
.array(
|
|
239
240
|
z.union([
|
|
240
|
-
zPng(field, root, { maxSize: 2
|
|
241
|
-
zMp4(field, root, { maxSize: 5
|
|
241
|
+
zPng(field, root, { maxSize: size.mb(2) }),
|
|
242
|
+
zMp4(field, root, { maxSize: size.mb(5) }),
|
|
242
243
|
]),
|
|
243
244
|
)
|
|
244
245
|
.min(1)
|
|
@@ -274,7 +275,7 @@ const zIcon = function (root) {
|
|
|
274
275
|
return z.optional(
|
|
275
276
|
zPng(field, root, {
|
|
276
277
|
aspect: "1:1",
|
|
277
|
-
maxSize: 2
|
|
278
|
+
maxSize: size.mb(2),
|
|
278
279
|
minHeight: 512,
|
|
279
280
|
minWidth: 512,
|
|
280
281
|
}),
|
|
@@ -288,7 +289,7 @@ const zIconVideo = function (root) {
|
|
|
288
289
|
return z.optional(
|
|
289
290
|
zMp4(field, root, {
|
|
290
291
|
aspect: "1:1",
|
|
291
|
-
maxSize: 5
|
|
292
|
+
maxSize: size.mb(5),
|
|
292
293
|
minHeight: 512,
|
|
293
294
|
minWidth: 512,
|
|
294
295
|
}),
|
|
@@ -300,8 +301,12 @@ const zIconVideo = function (root) {
|
|
|
300
301
|
const zId = function () {
|
|
301
302
|
const field = "id";
|
|
302
303
|
return z
|
|
303
|
-
.
|
|
304
|
-
|
|
304
|
+
.uuid(
|
|
305
|
+
message(field, [
|
|
306
|
+
"Must be a valid UUID.",
|
|
307
|
+
"Run `arc init` to generate a new game ID.",
|
|
308
|
+
]),
|
|
309
|
+
)
|
|
305
310
|
.refine(
|
|
306
311
|
(value) => value === value.toLowerCase(),
|
|
307
312
|
message(field, ["Must use lowercase characters."]),
|
|
@@ -329,7 +334,7 @@ const zPoster = function (root) {
|
|
|
329
334
|
return z.optional(
|
|
330
335
|
zPng(field, root, {
|
|
331
336
|
aspect: "2:3",
|
|
332
|
-
maxSize: 2
|
|
337
|
+
maxSize: size.mb(2),
|
|
333
338
|
minHeight: 768,
|
|
334
339
|
minWidth: 512,
|
|
335
340
|
}),
|
|
@@ -343,7 +348,7 @@ const zPosterVideo = function (root) {
|
|
|
343
348
|
return z.optional(
|
|
344
349
|
zMp4(field, root, {
|
|
345
350
|
aspect: "2:3",
|
|
346
|
-
maxSize: 5
|
|
351
|
+
maxSize: size.mb(5),
|
|
347
352
|
minHeight: 768,
|
|
348
353
|
minWidth: 512,
|
|
349
354
|
}),
|
|
@@ -388,7 +393,7 @@ const zTrailer = function () {
|
|
|
388
393
|
.refine(
|
|
389
394
|
(url) =>
|
|
390
395
|
zVimeo().safeParse(url).success || zYouTube().safeParse(url).success,
|
|
391
|
-
message(field, ["Must be a YouTube
|
|
396
|
+
message(field, ["Must be a YouTube or Vimeo URL."]),
|
|
392
397
|
)
|
|
393
398
|
.optional();
|
|
394
399
|
};
|
|
@@ -401,7 +406,7 @@ const zVersion = function () {
|
|
|
401
406
|
.string()
|
|
402
407
|
.refine(
|
|
403
408
|
(value) => validSemver(value) !== null,
|
|
404
|
-
message(field, ["Must be
|
|
409
|
+
message(field, ["Must be valid semver."]),
|
|
405
410
|
);
|
|
406
411
|
};
|
|
407
412
|
|
|
@@ -419,7 +424,7 @@ const zWordmark = function (root) {
|
|
|
419
424
|
return z.optional(
|
|
420
425
|
zSvg(field, root, {
|
|
421
426
|
aspect: "1:1",
|
|
422
|
-
maxSize: 512
|
|
427
|
+
maxSize: size.kb(512),
|
|
423
428
|
}),
|
|
424
429
|
);
|
|
425
430
|
};
|
|
@@ -431,7 +436,7 @@ const zWordmarkAnimated = function (root) {
|
|
|
431
436
|
return z.optional(
|
|
432
437
|
zSvg(field, root, {
|
|
433
438
|
aspect: "1:1",
|
|
434
|
-
maxSize:
|
|
439
|
+
maxSize: size.mb(1),
|
|
435
440
|
}),
|
|
436
441
|
);
|
|
437
442
|
};
|
package/src/schema/workflow.js
CHANGED
|
@@ -45,7 +45,7 @@ const message = function (field, lines) {
|
|
|
45
45
|
|
|
46
46
|
const zBuild = function () {
|
|
47
47
|
// const field = "build";
|
|
48
|
-
return z.string();
|
|
48
|
+
return z.union([z.string(), z.array(z.string())]);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
// [function]
|
|
@@ -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
|
|
74
|
-
"Run `arc inspect workflow.deploy_dir`
|
|
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
|
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const time = require("./time");
|
|
6
|
+
|
|
7
|
+
// [function]
|
|
8
|
+
|
|
9
|
+
const backoff = function (elapsed, delay, factor, interval, maxDelay) {
|
|
10
|
+
const step = Math.floor(elapsed / interval);
|
|
11
|
+
return Math.min(delay * factor ** step, maxDelay);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// [function]
|
|
15
|
+
|
|
16
|
+
const sleep = function (delay) {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
setTimeout(resolve, delay);
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// [function]
|
|
23
|
+
|
|
24
|
+
const wait = function (delay, next) {
|
|
25
|
+
return sleep(delay).then(next);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// [function]
|
|
29
|
+
|
|
30
|
+
const poll = function (
|
|
31
|
+
fn,
|
|
32
|
+
value,
|
|
33
|
+
{
|
|
34
|
+
delay = time.s(1),
|
|
35
|
+
factor = 1,
|
|
36
|
+
interval = time.m(1),
|
|
37
|
+
maxDelay = delay,
|
|
38
|
+
timeout = Infinity,
|
|
39
|
+
} = {},
|
|
40
|
+
) {
|
|
41
|
+
const started = Date.now();
|
|
42
|
+
const next = function () {
|
|
43
|
+
return fn(value).then((result) => {
|
|
44
|
+
if (result !== null) {
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
const elapsed = Date.now() - started;
|
|
48
|
+
if (elapsed >= timeout) {
|
|
49
|
+
throw new Error("Operation timed out.");
|
|
50
|
+
}
|
|
51
|
+
return wait(backoff(elapsed, delay, factor, interval, maxDelay), next);
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
return next();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// [export]
|
|
58
|
+
|
|
59
|
+
module.exports = { poll };
|
package/src/util/output.js
CHANGED
|
@@ -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
|
|
package/src/util/size.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [function]
|
|
4
|
+
|
|
5
|
+
const b = function (value) {
|
|
6
|
+
return value;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// [function]
|
|
10
|
+
|
|
11
|
+
const kb = function (value) {
|
|
12
|
+
return b(value * 1024);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// [function]
|
|
16
|
+
|
|
17
|
+
const mb = function (value) {
|
|
18
|
+
return kb(value * 1024);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// [function]
|
|
22
|
+
|
|
23
|
+
const gb = function (value) {
|
|
24
|
+
return mb(value * 1024);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// [export]
|
|
28
|
+
|
|
29
|
+
module.exports = { b, gb, kb, mb };
|
package/src/util/time.js
CHANGED
|
@@ -24,56 +24,6 @@ const h = function (value) {
|
|
|
24
24
|
return m(value * 60);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
// [function]
|
|
28
|
-
|
|
29
|
-
const backoff = function (elapsed, delay, factor, interval, maxDelay) {
|
|
30
|
-
const step = Math.floor(elapsed / interval);
|
|
31
|
-
return Math.min(delay * factor ** step, maxDelay);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// [function]
|
|
35
|
-
|
|
36
|
-
const sleep = function (delay) {
|
|
37
|
-
return new Promise((resolve) => {
|
|
38
|
-
setTimeout(resolve, delay);
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// [function]
|
|
43
|
-
|
|
44
|
-
const wait = function (delay, next) {
|
|
45
|
-
return sleep(delay).then(next);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// [function]
|
|
49
|
-
|
|
50
|
-
const poll = function (
|
|
51
|
-
fn,
|
|
52
|
-
value,
|
|
53
|
-
{
|
|
54
|
-
delay = s(1),
|
|
55
|
-
factor = 1,
|
|
56
|
-
interval = m(1),
|
|
57
|
-
maxDelay = delay,
|
|
58
|
-
timeout = Infinity,
|
|
59
|
-
} = {},
|
|
60
|
-
) {
|
|
61
|
-
const started = Date.now();
|
|
62
|
-
const next = function () {
|
|
63
|
-
return fn(value).then((result) => {
|
|
64
|
-
if (result !== null) {
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
67
|
-
const elapsed = Date.now() - started;
|
|
68
|
-
if (elapsed >= timeout) {
|
|
69
|
-
throw new Error("Timed out.");
|
|
70
|
-
}
|
|
71
|
-
return wait(backoff(elapsed, delay, factor, interval, maxDelay), next);
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
return next();
|
|
75
|
-
};
|
|
76
|
-
|
|
77
27
|
// [export]
|
|
78
28
|
|
|
79
|
-
module.exports = { h, m, ms,
|
|
29
|
+
module.exports = { h, m, ms, s };
|
package/src/util/toml.js
ADDED
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(
|
|
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("
|
|
73
|
+
throw new Error("No video metadata found.");
|
|
74
74
|
}
|
|
75
75
|
return video;
|
|
76
76
|
};
|
package/src/util/zip.js
CHANGED
|
@@ -49,6 +49,12 @@ const Main = class {
|
|
|
49
49
|
|
|
50
50
|
// [method]
|
|
51
51
|
|
|
52
|
+
has(name) {
|
|
53
|
+
return this.zip.getEntry(join(this.prefix, name)) !== null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// [method]
|
|
57
|
+
|
|
52
58
|
stat() {
|
|
53
59
|
const buffer = this.zip.toBuffer();
|
|
54
60
|
const hash = createHash("sha256").update(buffer).digest("hex");
|
package/src/prompt/project.js
DELETED
|
File without changes
|