arcadible 0.1.32 → 0.1.33
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/README.md +4 -4
- package/bin/arc-build.js +23 -5
- package/bin/arc-deploy.js +78 -13
- package/bin/arc-init.js +6 -1
- package/bin/arc-inspect.js +1 -0
- package/bin/arc-login.js +4 -1
- package/bin/arc-open.js +4 -1
- package/bin/arc-pack.js +23 -3
- package/bin/arc-play.js +4 -1
- package/bin/arc-validate.js +1 -0
- package/bin/arc-whoami.js +1 -0
- package/package.json +3 -3
- package/src/account.js +7 -4
- package/src/action/build/tool.js +8 -4
- package/src/action/deploy/tool-git.js +49 -61
- package/src/action/deploy/tool.js +50 -44
- package/src/action/deploy/wait.js +10 -9
- package/src/action/init/manifest.js +23 -6
- package/src/action/init/tool-patch.js +1 -7
- package/src/action/init/tool.js +12 -9
- package/src/action/login/flow.js +7 -3
- package/src/action/pack/limits.js +13 -3
- package/src/action/pack/tool.js +19 -6
- package/src/action/play/tool.js +7 -1
- package/src/action/predeploy/ac.js +39 -22
- package/src/action/predeploy/git.js +55 -58
- package/src/action/predeploy/pm.js +24 -17
- package/src/action/predeploy/published.js +15 -2
- package/src/action/predeploy/tool-git.js +45 -90
- package/src/action/predeploy/tool.js +7 -33
- package/src/action/validate/tool.js +5 -4
- package/src/api.js +0 -1
- package/src/config/code.js +111 -0
- package/src/config/url.js +2 -1
- package/src/parser/env.js +12 -2
- package/src/parser/given.js +17 -0
- package/src/parser/manifest.js +8 -1
- package/src/parser/media.js +5 -9
- package/src/parser/project.js +4 -1
- package/src/parser/readme-file.js +8 -1
- package/src/phrase.js +42 -0
- package/src/schema/check/game.js +5 -26
- package/src/schema/game.js +117 -210
- package/src/schema/message.js +46 -7
- package/src/schema/readme.js +8 -3
- package/src/schema/workflow.js +35 -15
- package/src/util/argv.js +33 -1
- package/src/util/delay.js +4 -1
- package/src/util/error.js +49 -0
- package/src/util/image.js +4 -30
- package/src/util/log.js +8 -0
- package/src/util/media.js +40 -0
- package/src/util/output.js +34 -4
- package/src/util/request.js +11 -2
- package/src/util/s3.js +37 -20
- package/src/util/schema.js +93 -30
- package/src/util/video.js +4 -27
|
@@ -6,95 +6,83 @@ const semver = require("semver");
|
|
|
6
6
|
|
|
7
7
|
// [import]
|
|
8
8
|
|
|
9
|
+
const cfgcode = require("../../config/code");
|
|
10
|
+
const error = require("../../util/error");
|
|
11
|
+
const given = require("../../parser/given");
|
|
9
12
|
const links = require("../../util/links");
|
|
10
13
|
const phrase = require("../../phrase");
|
|
11
|
-
const project = require("../../parser/project");
|
|
12
14
|
const repo = require("../predeploy/git");
|
|
13
15
|
|
|
14
16
|
// [use]
|
|
15
17
|
|
|
18
|
+
const ArcError = error.ArcError;
|
|
19
|
+
const failWith = repo.failWith;
|
|
16
20
|
const git = repo.git;
|
|
17
21
|
const prereleaseSemver = semver.prerelease;
|
|
18
22
|
const tagOf = repo.tagOf;
|
|
19
23
|
|
|
20
24
|
// [function]
|
|
21
25
|
|
|
22
|
-
const createTag = function (root, version
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
prereleaseSemver(version) === null
|
|
31
|
-
? phrase.versionRelease(version)
|
|
32
|
-
: phrase.versionPrerelease(version),
|
|
33
|
-
],
|
|
34
|
-
(err) => {
|
|
35
|
-
if (err) {
|
|
36
|
-
cb(new Error(phrase.gitTagCreateFailed(version), { cause: err }));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
cb(null);
|
|
40
|
-
},
|
|
26
|
+
const createTag = function (root, version) {
|
|
27
|
+
const message =
|
|
28
|
+
prereleaseSemver(version) === null
|
|
29
|
+
? phrase.versionRelease(version)
|
|
30
|
+
: phrase.versionPrerelease(version);
|
|
31
|
+
return git(root, ["tag", "-a", tagOf(version), "-m", message]).then(
|
|
32
|
+
() => null,
|
|
33
|
+
failWith(cfgcode.GIT_TAG_CREATE_FAILED, phrase.gitTagCreateFailed(version)),
|
|
41
34
|
);
|
|
42
35
|
};
|
|
43
36
|
|
|
44
37
|
// [function]
|
|
45
38
|
|
|
46
|
-
// the local tag
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
cause: err,
|
|
53
|
-
});
|
|
54
|
-
git(root, ["tag", "-d", tagOf(version)], () => cb(failed));
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
cb(null);
|
|
58
|
-
});
|
|
39
|
+
// deletes the local tag, then fails with `failed` whether or not it could.
|
|
40
|
+
const untag = function (root, version, failed) {
|
|
41
|
+
const fail = () => {
|
|
42
|
+
throw failed;
|
|
43
|
+
};
|
|
44
|
+
return git(root, ["tag", "-d", tagOf(version)]).then(fail, fail);
|
|
59
45
|
};
|
|
60
46
|
|
|
61
47
|
// [function]
|
|
62
48
|
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
49
|
+
// the local tag is deleted when the push fails, so trying again isn't
|
|
50
|
+
// blocked by a tag that was never released.
|
|
51
|
+
const pushTag = function (root, version) {
|
|
52
|
+
return git(root, ["push", "origin", tagOf(version)]).then(
|
|
53
|
+
() => null,
|
|
54
|
+
(err) =>
|
|
55
|
+
untag(
|
|
56
|
+
root,
|
|
57
|
+
version,
|
|
58
|
+
new ArcError(
|
|
59
|
+
cfgcode.GIT_TAG_PUSH_FAILED,
|
|
60
|
+
phrase.gitTagPushFailed(version),
|
|
61
|
+
{
|
|
62
|
+
cause: err,
|
|
63
|
+
},
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
);
|
|
73
67
|
};
|
|
74
68
|
|
|
75
69
|
// [function]
|
|
76
70
|
|
|
77
|
-
|
|
71
|
+
// tags the version and pushes the tag: the Arcadible GitHub App publishes
|
|
72
|
+
// the release that the workflow builds from it.
|
|
73
|
+
const main = function (conf, { onDeployBegin }) {
|
|
78
74
|
if (onDeployBegin) {
|
|
79
75
|
onDeployBegin();
|
|
80
76
|
}
|
|
81
|
-
return
|
|
82
|
-
({ game }) =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
...links.published(game),
|
|
91
|
-
game: game.id,
|
|
92
|
-
tag: tagOf(game.version),
|
|
93
|
-
version: { to: game.version },
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
}),
|
|
97
|
-
);
|
|
77
|
+
return given(conf)
|
|
78
|
+
.then(({ game }) => Promise.all([game, createTag(conf.root, game.version)]))
|
|
79
|
+
.then(([game]) => Promise.all([game, pushTag(conf.root, game.version)]))
|
|
80
|
+
.then(([game]) => ({
|
|
81
|
+
...links.published(game),
|
|
82
|
+
game: game.id,
|
|
83
|
+
tag: tagOf(game.version),
|
|
84
|
+
version: { to: game.version },
|
|
85
|
+
}));
|
|
98
86
|
};
|
|
99
87
|
|
|
100
88
|
// [export]
|
|
@@ -3,39 +3,55 @@
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
5
|
const api = require("../../api");
|
|
6
|
+
const cfgcode = require("../../config/code");
|
|
7
|
+
const error = require("../../util/error");
|
|
8
|
+
const given = require("../../parser/given");
|
|
6
9
|
const links = require("../../util/links");
|
|
7
10
|
const phrase = require("../../phrase");
|
|
8
|
-
const project = require("../../parser/project");
|
|
9
11
|
const s3 = require("../../util/s3");
|
|
10
12
|
|
|
13
|
+
// [use]
|
|
14
|
+
|
|
15
|
+
const ArcError = error.ArcError;
|
|
16
|
+
|
|
11
17
|
// [function]
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{ id, version },
|
|
17
|
-
onUploadProgress,
|
|
18
|
-
cb,
|
|
19
|
-
) {
|
|
19
|
+
// asks the API for an upload link, then sends the zip to it, and resolves
|
|
20
|
+
// with the upload.
|
|
21
|
+
const uploadBuild = function (current, artifact, { id, version }, onProgress) {
|
|
20
22
|
const form = new FormData();
|
|
21
23
|
form.append("artifact", id);
|
|
22
24
|
form.append("version", version);
|
|
23
25
|
form.append("sha256", artifact.sha256);
|
|
24
26
|
form.append("size", artifact.size);
|
|
25
|
-
// api
|
|
26
27
|
return api
|
|
27
28
|
.postUpload(form, null, api.auth(current?.session?.access_token))
|
|
28
29
|
.then(
|
|
29
|
-
(upload) =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
(upload) =>
|
|
31
|
+
Promise.all([
|
|
32
|
+
upload,
|
|
33
|
+
s3.upload(upload.upload_url, artifact, onProgress),
|
|
34
|
+
]),
|
|
34
35
|
(err) => {
|
|
35
|
-
// the API refuses a game that was deleted or is another account's
|
|
36
|
-
|
|
36
|
+
// the API refuses a game that was deleted or is another account's,
|
|
37
|
+
// and the same version uploaded again within 5 minutes.
|
|
38
|
+
if (err.status === 403) {
|
|
39
|
+
throw new ArcError(
|
|
40
|
+
cfgcode.GAME_UNAVAILABLE,
|
|
41
|
+
phrase.gameUnavailable(id),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (err.status === 429) {
|
|
45
|
+
throw new ArcError(
|
|
46
|
+
cfgcode.UPLOAD_RATE_LIMITED,
|
|
47
|
+
phrase.uploadRateLimited(version),
|
|
48
|
+
{ cause: err },
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
throw err;
|
|
37
52
|
},
|
|
38
|
-
)
|
|
53
|
+
)
|
|
54
|
+
.then(([upload]) => upload);
|
|
39
55
|
};
|
|
40
56
|
|
|
41
57
|
// [function]
|
|
@@ -43,37 +59,27 @@ const uploadBuild = function (
|
|
|
43
59
|
const main = function (
|
|
44
60
|
current,
|
|
45
61
|
artifact,
|
|
46
|
-
|
|
62
|
+
conf,
|
|
47
63
|
{ onDeployBegin, onUploadProgress },
|
|
48
64
|
) {
|
|
49
65
|
if (onDeployBegin) {
|
|
50
|
-
onDeployBegin({ root });
|
|
66
|
+
onDeployBegin({ root: conf.root });
|
|
51
67
|
}
|
|
52
|
-
return
|
|
53
|
-
({ game }) =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
resolve({
|
|
68
|
-
...links.published(game),
|
|
69
|
-
game: game.id,
|
|
70
|
-
release: upload.id,
|
|
71
|
-
version: { to: game.version },
|
|
72
|
-
});
|
|
73
|
-
},
|
|
74
|
-
);
|
|
75
|
-
}),
|
|
76
|
-
);
|
|
68
|
+
return given(conf)
|
|
69
|
+
.then(({ game }) =>
|
|
70
|
+
Promise.all([
|
|
71
|
+
game,
|
|
72
|
+
uploadBuild(current, artifact, game, onUploadProgress),
|
|
73
|
+
]),
|
|
74
|
+
)
|
|
75
|
+
.then(([game, upload]) => ({
|
|
76
|
+
...links.published(game),
|
|
77
|
+
game: game.id,
|
|
78
|
+
// a direct deploy's release shares its upload's id, which `--wait`
|
|
79
|
+
// follows.
|
|
80
|
+
release: upload.id,
|
|
81
|
+
version: { to: game.version },
|
|
82
|
+
}));
|
|
77
83
|
};
|
|
78
84
|
|
|
79
85
|
// [export]
|
|
@@ -44,16 +44,17 @@ const studioUrl = function (game) {
|
|
|
44
44
|
// the repository's GitHub Actions page, from origin's URL, or null when
|
|
45
45
|
// origin isn't on GitHub.
|
|
46
46
|
const actionsUrl = function (root) {
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
const match =
|
|
50
|
-
|
|
51
|
-
: /github\.com[:/]([^/\s]+)\/([^/\s]+?)(?:\.git)?\s*$/u.exec(stdout);
|
|
52
|
-
resolve(
|
|
53
|
-
match ? `https://github.com/${match[1]}/${match[2]}/actions` : null,
|
|
47
|
+
return git(root, ["remote", "get-url", "origin"]).then(
|
|
48
|
+
(stdout) => {
|
|
49
|
+
const match = /github\.com[:/]([^/\s]+)\/([^/\s]+?)(?:\.git)?\s*$/u.exec(
|
|
50
|
+
stdout,
|
|
54
51
|
);
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
return match
|
|
53
|
+
? `https://github.com/${match[1]}/${match[2]}/actions`
|
|
54
|
+
: null;
|
|
55
|
+
},
|
|
56
|
+
() => null,
|
|
57
|
+
);
|
|
57
58
|
};
|
|
58
59
|
|
|
59
60
|
// [function]
|
|
@@ -11,12 +11,16 @@ const fs = require("fs-extra");
|
|
|
11
11
|
|
|
12
12
|
// [import]
|
|
13
13
|
|
|
14
|
+
const cfgcode = require("../../config/code");
|
|
14
15
|
const cfgproduct = require("../../config/product");
|
|
16
|
+
const env = require("../../parser/env");
|
|
17
|
+
const error = require("../../util/error");
|
|
15
18
|
const phrase = require("../../phrase");
|
|
16
19
|
const TOML = require("../../util/toml");
|
|
17
20
|
|
|
18
21
|
// [use]
|
|
19
22
|
|
|
23
|
+
const ArcError = error.ArcError;
|
|
20
24
|
const join = path.join;
|
|
21
25
|
const pathExists = fs.pathExists;
|
|
22
26
|
const randomUUID = crypto.randomUUID;
|
|
@@ -34,12 +38,23 @@ const parseToml = function (buf) {
|
|
|
34
38
|
try {
|
|
35
39
|
return TOML.parse(buf);
|
|
36
40
|
} catch (ex) {
|
|
37
|
-
throw new
|
|
41
|
+
throw new ArcError(
|
|
42
|
+
cfgcode.PARSE_FAILED,
|
|
43
|
+
phrase.unableToParse(MANIFEST, ex.message),
|
|
44
|
+
{ cause: ex },
|
|
45
|
+
);
|
|
38
46
|
}
|
|
39
47
|
};
|
|
40
48
|
|
|
41
49
|
// [function]
|
|
42
50
|
|
|
51
|
+
// the version the project's package.json gives, if any.
|
|
52
|
+
const detectVersion = function (dest) {
|
|
53
|
+
return env(dest).then(({ game }) => game?.version ?? null);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// [function]
|
|
57
|
+
|
|
43
58
|
const pickVersion = function (version, envVersion) {
|
|
44
59
|
if (version) {
|
|
45
60
|
return { version };
|
|
@@ -57,10 +72,12 @@ const readManifest = function (file) {
|
|
|
57
72
|
|
|
58
73
|
// [function]
|
|
59
74
|
|
|
60
|
-
|
|
75
|
+
// a new project always gets its own id: a template's, such as an existing
|
|
76
|
+
// game's, belongs to that game.
|
|
77
|
+
const patchGame = function (envVersion, game = {}, { fresh = false } = {}) {
|
|
61
78
|
const { id, version, ...rest } = game;
|
|
62
79
|
return {
|
|
63
|
-
id: id ?? randomUUID(),
|
|
80
|
+
id: fresh ? randomUUID() : (id ?? randomUUID()),
|
|
64
81
|
...pickVersion(version, envVersion),
|
|
65
82
|
...rest,
|
|
66
83
|
};
|
|
@@ -77,11 +94,11 @@ const shouldWrite = function (manifest, next) {
|
|
|
77
94
|
|
|
78
95
|
// [function]
|
|
79
96
|
|
|
80
|
-
const prepare = function (dest, envVersion) {
|
|
97
|
+
const prepare = function (dest, envVersion, opts) {
|
|
81
98
|
const file = join(dest, MANIFEST);
|
|
82
99
|
return readManifest(file).then((manifest) => {
|
|
83
100
|
const { game, ...rest } = manifest;
|
|
84
|
-
const next = { game: patchGame(envVersion, game), ...rest };
|
|
101
|
+
const next = { game: patchGame(envVersion, game, opts), ...rest };
|
|
85
102
|
if (shouldWrite(manifest, next)) {
|
|
86
103
|
return writeFile(file, TOML.stringify(next), "utf8");
|
|
87
104
|
}
|
|
@@ -91,4 +108,4 @@ const prepare = function (dest, envVersion) {
|
|
|
91
108
|
|
|
92
109
|
// [export]
|
|
93
110
|
|
|
94
|
-
module.exports = { prepare };
|
|
111
|
+
module.exports = { detectVersion, prepare };
|
|
@@ -6,22 +6,16 @@ const path = require("node:path");
|
|
|
6
6
|
|
|
7
7
|
// [import]
|
|
8
8
|
|
|
9
|
-
const env = require("../../parser/env");
|
|
10
9
|
const manifest = require("./manifest");
|
|
11
10
|
|
|
12
11
|
// [use]
|
|
13
12
|
|
|
13
|
+
const detectVersion = manifest.detectVersion;
|
|
14
14
|
const prepare = manifest.prepare;
|
|
15
15
|
const resolve = path.resolve;
|
|
16
16
|
|
|
17
17
|
// [function]
|
|
18
18
|
|
|
19
|
-
const detectVersion = function (dest) {
|
|
20
|
-
return env(dest).then(({ game }) => game?.version ?? null);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// [function]
|
|
24
|
-
|
|
25
19
|
// an existing project: add a manifest, and copy nothing from the template.
|
|
26
20
|
const main = function ({ project, root }, { onInitBegin }) {
|
|
27
21
|
const dest = resolve(root, project);
|
package/src/action/init/tool.js
CHANGED
|
@@ -11,12 +11,15 @@ const fs = require("fs-extra");
|
|
|
11
11
|
|
|
12
12
|
// [import]
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const cfgcode = require("../../config/code");
|
|
15
|
+
const error = require("../../util/error");
|
|
15
16
|
const manifest = require("./manifest");
|
|
16
17
|
const phrase = require("../../phrase");
|
|
17
18
|
|
|
18
19
|
// [use]
|
|
19
20
|
|
|
21
|
+
const ArcError = error.ArcError;
|
|
22
|
+
const detectVersion = manifest.detectVersion;
|
|
20
23
|
const join = path.join;
|
|
21
24
|
const prepare = manifest.prepare;
|
|
22
25
|
const remove = fs.remove;
|
|
@@ -34,12 +37,6 @@ const removeLicense = function (dest) {
|
|
|
34
37
|
|
|
35
38
|
// [function]
|
|
36
39
|
|
|
37
|
-
const detectVersion = function (dest) {
|
|
38
|
-
return env(dest).then(({ game }) => game?.version ?? null);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// [function]
|
|
42
|
-
|
|
43
40
|
const scaffold = function (src, dest, { onInitBegin }) {
|
|
44
41
|
if (onInitBegin) {
|
|
45
42
|
onInitBegin({ dest, src });
|
|
@@ -47,7 +44,13 @@ const scaffold = function (src, dest, { onInitBegin }) {
|
|
|
47
44
|
return degit(src, { cache: false, force: true, verbose: false })
|
|
48
45
|
.clone(dest)
|
|
49
46
|
.catch((ex) => {
|
|
50
|
-
throw new
|
|
47
|
+
throw new ArcError(
|
|
48
|
+
cfgcode.TEMPLATE_UNAVAILABLE,
|
|
49
|
+
phrase.templateUnavailable(src),
|
|
50
|
+
{
|
|
51
|
+
cause: ex,
|
|
52
|
+
},
|
|
53
|
+
);
|
|
51
54
|
});
|
|
52
55
|
};
|
|
53
56
|
|
|
@@ -59,7 +62,7 @@ const main = function ({ project, root, template }, handler) {
|
|
|
59
62
|
return scaffold(template, dest, handler)
|
|
60
63
|
.then(() => removeLicense(dest))
|
|
61
64
|
.then(() => detectVersion(dest))
|
|
62
|
-
.then((version) => prepare(dest, version))
|
|
65
|
+
.then((version) => prepare(dest, version, { fresh: true }))
|
|
63
66
|
.then(() => ({ path: dest, template }));
|
|
64
67
|
};
|
|
65
68
|
|
package/src/action/login/flow.js
CHANGED
|
@@ -7,13 +7,16 @@ const crypto = require("node:crypto");
|
|
|
7
7
|
// [import]
|
|
8
8
|
|
|
9
9
|
const api = require("../../api");
|
|
10
|
+
const cfgcode = require("../../config/code");
|
|
10
11
|
const cfgurl = require("../../config/url");
|
|
11
12
|
const delay = require("../../util/delay");
|
|
13
|
+
const error = require("../../util/error");
|
|
12
14
|
const phrase = require("../../phrase");
|
|
13
15
|
const time = require("../../util/time");
|
|
14
16
|
|
|
15
17
|
// [use]
|
|
16
18
|
|
|
19
|
+
const ArcError = error.ArcError;
|
|
17
20
|
const poll = delay.poll;
|
|
18
21
|
const randomUUID = crypto.randomUUID;
|
|
19
22
|
|
|
@@ -24,7 +27,8 @@ const POLL = {
|
|
|
24
27
|
factor: 1.5,
|
|
25
28
|
interval: time.s(15),
|
|
26
29
|
maxDelay: time.s(5),
|
|
27
|
-
timeoutError:
|
|
30
|
+
timeoutError: () =>
|
|
31
|
+
new ArcError(cfgcode.LOGIN_EXPIRED, phrase.loginExpired()),
|
|
28
32
|
};
|
|
29
33
|
|
|
30
34
|
// [function]
|
|
@@ -67,9 +71,9 @@ const pollFlow = function (value, onLoginPoll) {
|
|
|
67
71
|
case "completed":
|
|
68
72
|
return data;
|
|
69
73
|
case "failed":
|
|
70
|
-
throw new
|
|
74
|
+
throw new ArcError(cfgcode.LOGIN_FAILED, phrase.loginFailed());
|
|
71
75
|
default:
|
|
72
|
-
throw new
|
|
76
|
+
throw new ArcError(cfgcode.LOGIN_EXPIRED, phrase.loginExpired());
|
|
73
77
|
}
|
|
74
78
|
});
|
|
75
79
|
};
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
|
+
const cfgcode = require("../../config/code");
|
|
6
|
+
const error = require("../../util/error");
|
|
5
7
|
const phrase = require("../../phrase");
|
|
6
8
|
const size = require("../../util/size");
|
|
7
9
|
|
|
8
10
|
// [use]
|
|
9
11
|
|
|
12
|
+
const ArcError = error.ArcError;
|
|
10
13
|
const toMb = size.toMb;
|
|
11
14
|
|
|
12
15
|
// [declare]
|
|
@@ -25,16 +28,23 @@ const MAX_TOTAL_SIZE = size.mb(256);
|
|
|
25
28
|
const check = function (entries) {
|
|
26
29
|
const large = entries.find((entry) => entry.size > MAX_FILE_SIZE);
|
|
27
30
|
if (large) {
|
|
28
|
-
throw new
|
|
31
|
+
throw new ArcError(
|
|
32
|
+
cfgcode.PACKAGE_FILE_TOO_LARGE,
|
|
29
33
|
phrase.packageFileTooLarge(large.name, toMb(MAX_FILE_SIZE)),
|
|
30
34
|
);
|
|
31
35
|
}
|
|
32
36
|
if (entries.length > MAX_FILES) {
|
|
33
|
-
throw new
|
|
37
|
+
throw new ArcError(
|
|
38
|
+
cfgcode.PACKAGE_TOO_MANY_FILES,
|
|
39
|
+
phrase.packageTooManyFiles(MAX_FILES),
|
|
40
|
+
);
|
|
34
41
|
}
|
|
35
42
|
const total = entries.reduce((sum, entry) => sum + entry.size, 0);
|
|
36
43
|
if (total > MAX_TOTAL_SIZE) {
|
|
37
|
-
throw new
|
|
44
|
+
throw new ArcError(
|
|
45
|
+
cfgcode.PACKAGE_UNCOMPRESSED_TOO_LARGE,
|
|
46
|
+
phrase.packageUncompressedTooLarge(toMb(MAX_TOTAL_SIZE)),
|
|
47
|
+
);
|
|
38
48
|
}
|
|
39
49
|
};
|
|
40
50
|
|
package/src/action/pack/tool.js
CHANGED
|
@@ -10,15 +10,18 @@ const fs = require("fs-extra");
|
|
|
10
10
|
|
|
11
11
|
// [import]
|
|
12
12
|
|
|
13
|
+
const cfgcode = require("../../config/code");
|
|
13
14
|
const cfgproduct = require("../../config/product");
|
|
15
|
+
const error = require("../../util/error");
|
|
16
|
+
const given = require("../../parser/given");
|
|
14
17
|
const limits = require("./limits");
|
|
15
18
|
const phrase = require("../../phrase");
|
|
16
|
-
const project = require("../../parser/project");
|
|
17
19
|
const size = require("../../util/size");
|
|
18
20
|
const Zip = require("../../util/zip");
|
|
19
21
|
|
|
20
22
|
// [use]
|
|
21
23
|
|
|
24
|
+
const ArcError = error.ArcError;
|
|
22
25
|
const parse = path.parse;
|
|
23
26
|
const pathExists = fs.pathExists;
|
|
24
27
|
const resolve = path.resolve;
|
|
@@ -43,10 +46,16 @@ const SIZE_PARTIAL = size.mb(64);
|
|
|
43
46
|
|
|
44
47
|
const verifyPartial = function (zip) {
|
|
45
48
|
if (!zip.has(MAIN)) {
|
|
46
|
-
throw new
|
|
49
|
+
throw new ArcError(
|
|
50
|
+
cfgcode.PACKAGE_INDEX_MISSING,
|
|
51
|
+
phrase.packageFileMissing(MAIN),
|
|
52
|
+
);
|
|
47
53
|
}
|
|
48
54
|
if (zip.stat().size > SIZE_PARTIAL) {
|
|
49
|
-
throw new
|
|
55
|
+
throw new ArcError(
|
|
56
|
+
cfgcode.PACKAGE_TOO_LARGE,
|
|
57
|
+
phrase.packageTooLarge(size.toMb(SIZE_PARTIAL)),
|
|
58
|
+
);
|
|
50
59
|
}
|
|
51
60
|
return zip;
|
|
52
61
|
};
|
|
@@ -65,7 +74,10 @@ const pack = function (name, game, { inputPath, mediaPath, outputPath }) {
|
|
|
65
74
|
return pathExists(inputPath)
|
|
66
75
|
.then((existsInput) => {
|
|
67
76
|
if (!existsInput) {
|
|
68
|
-
throw new
|
|
77
|
+
throw new ArcError(
|
|
78
|
+
cfgcode.PATH_NOT_FOUND,
|
|
79
|
+
phrase.unableToFind(inputPath),
|
|
80
|
+
);
|
|
69
81
|
}
|
|
70
82
|
zip.addDir(inputPath);
|
|
71
83
|
return zip;
|
|
@@ -88,8 +100,9 @@ const pack = function (name, game, { inputPath, mediaPath, outputPath }) {
|
|
|
88
100
|
|
|
89
101
|
// [function]
|
|
90
102
|
|
|
91
|
-
const main = function ({ input, output,
|
|
92
|
-
|
|
103
|
+
const main = function ({ input, output, ...conf }) {
|
|
104
|
+
const root = conf.root;
|
|
105
|
+
return given(conf).then(({ game, workflow }) => {
|
|
93
106
|
const name = game.handle ?? game.id;
|
|
94
107
|
const file = output ?? `${OUTPUT}/${name}-v${game.version}.zip`;
|
|
95
108
|
return pack(parse(file).name, game, {
|
package/src/action/play/tool.js
CHANGED
|
@@ -3,10 +3,16 @@
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
5
|
const api = require("../../api");
|
|
6
|
+
const cfgcode = require("../../config/code");
|
|
7
|
+
const error = require("../../util/error");
|
|
6
8
|
const links = require("../../util/links");
|
|
7
9
|
const phrase = require("../../phrase");
|
|
8
10
|
const project = require("../../parser/project");
|
|
9
11
|
|
|
12
|
+
// [use]
|
|
13
|
+
|
|
14
|
+
const ArcError = error.ArcError;
|
|
15
|
+
|
|
10
16
|
// [function]
|
|
11
17
|
|
|
12
18
|
// the game, `select`ed, or null when the API can't be reached. It rejects
|
|
@@ -15,7 +21,7 @@ const project = require("../../parser/project");
|
|
|
15
21
|
const lookup = function (id, select) {
|
|
16
22
|
return api.discoverGame(id, { select }).catch((err) => {
|
|
17
23
|
if (err?.status === 404) {
|
|
18
|
-
throw new
|
|
24
|
+
throw new ArcError(cfgcode.GAME_NOT_FOUND, phrase.gameNotFound(id));
|
|
19
25
|
}
|
|
20
26
|
return null;
|
|
21
27
|
});
|