arcadible 0.1.1 → 0.1.2
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 +0 -1
- package/bin/arc-deploy.js +62 -22
- package/bin/arc-init.js +7 -7
- package/bin/arc-pack.js +1 -2
- package/bin/arc-validate.js +9 -8
- package/package.json +3 -1
- package/src/action/deploy-git/git.js +175 -6
- package/src/action/deploy-git/tool.js +77 -2
- package/src/action/init/tool.js +2 -2
- package/src/cli/deploy.js +3 -3
- package/src/config/workflow.js +6 -1
- package/src/parser/manifest.js +5 -6
- package/src/parser/pkg.js +56 -0
- package/src/parser/project.js +6 -2
- package/src/parser/readme.js +21 -11
- package/src/prompt/{template.js → starter.js} +11 -7
- package/src/schema/game.js +18 -0
- package/src/util/log.js +42 -1
- package/src/util/objs.js +11 -1
- package/src/util/output.js +10 -2
- package/src/util/request.js +2 -2
- package/src/action/deploy-git/release.js +0 -74
package/bin/arc-default.js
CHANGED
|
@@ -35,7 +35,6 @@ const main = function (argv) {
|
|
|
35
35
|
.command("inspect", "Inspect project metadata")
|
|
36
36
|
.command("login", "Log in to Arcadible")
|
|
37
37
|
.command("logout", "Log out of Arcadible")
|
|
38
|
-
.command("pack", "Package for distribution")
|
|
39
38
|
.command("validate", "Validate workspace")
|
|
40
39
|
.command("whoami", "Show current account")
|
|
41
40
|
.help("help")
|
package/bin/arc-deploy.js
CHANGED
|
@@ -17,6 +17,7 @@ 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 validate = require("../src/cli/validate");
|
|
20
21
|
|
|
21
22
|
// [use]
|
|
22
23
|
|
|
@@ -32,7 +33,6 @@ const SUBCMD = "deploy";
|
|
|
32
33
|
// [define]
|
|
33
34
|
|
|
34
35
|
const conf = {
|
|
35
|
-
git: false,
|
|
36
36
|
json: false,
|
|
37
37
|
production: false,
|
|
38
38
|
quiet: false,
|
|
@@ -41,24 +41,69 @@ const conf = {
|
|
|
41
41
|
|
|
42
42
|
// [function]
|
|
43
43
|
|
|
44
|
+
const handler = function ({ json, quiet }) {
|
|
45
|
+
return {
|
|
46
|
+
onBegin() {
|
|
47
|
+
if (!json && !quiet) {
|
|
48
|
+
log.p("Deploying project...");
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
onInfo({ level, message }) {
|
|
52
|
+
if (json || quiet) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
switch (level) {
|
|
56
|
+
case "warn":
|
|
57
|
+
log.pw(`⚠ ${message}`);
|
|
58
|
+
return;
|
|
59
|
+
default:
|
|
60
|
+
log.p(`• ${message}`);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// [function]
|
|
67
|
+
|
|
44
68
|
const start = function (argv) {
|
|
45
69
|
const json = argv.json;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
const pre = !argv.production;
|
|
71
|
+
const quiet = argv.quiet;
|
|
72
|
+
const root = resolve(process.cwd(), argv.cwd);
|
|
73
|
+
return validate({ root })
|
|
74
|
+
.then((issues) => {
|
|
75
|
+
const valid = !issues.length;
|
|
76
|
+
if (!valid) {
|
|
77
|
+
throw new Error("Validate failed. Run `arc validate` for details.");
|
|
78
|
+
}
|
|
79
|
+
return deploy({
|
|
80
|
+
direct: false,
|
|
81
|
+
handler: handler({ json, quiet }),
|
|
82
|
+
pre,
|
|
83
|
+
preId: "rc",
|
|
84
|
+
root,
|
|
85
|
+
});
|
|
86
|
+
})
|
|
87
|
+
.then((data) => {
|
|
88
|
+
if (json) {
|
|
89
|
+
print({ version: data });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (!quiet) {
|
|
93
|
+
log.p(`✓ ${pre ? "Prerelease" : "Release"} v${data.to} submitted.`);
|
|
94
|
+
log.hs("Deployed.");
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
.catch((ex) => {
|
|
98
|
+
const message = ex.message;
|
|
99
|
+
if (json) {
|
|
100
|
+
print({ error: { message } });
|
|
101
|
+
} else {
|
|
102
|
+
log.hd("Deploy aborted.");
|
|
103
|
+
log.p(message);
|
|
104
|
+
}
|
|
105
|
+
process.exit(1);
|
|
106
|
+
});
|
|
62
107
|
};
|
|
63
108
|
|
|
64
109
|
// [function]
|
|
@@ -74,11 +119,6 @@ const main = function (argv) {
|
|
|
74
119
|
describe: "Deploy to production.",
|
|
75
120
|
type: "boolean",
|
|
76
121
|
})
|
|
77
|
-
.option("git", {
|
|
78
|
-
default: conf.git,
|
|
79
|
-
describe: "Deploy using Git.",
|
|
80
|
-
type: "boolean",
|
|
81
|
-
})
|
|
82
122
|
.option("json", {
|
|
83
123
|
alias: "j",
|
|
84
124
|
default: conf.json,
|
package/bin/arc-init.js
CHANGED
|
@@ -20,7 +20,7 @@ const output = require("../src/util/output");
|
|
|
20
20
|
const pkg = require("../package.json");
|
|
21
21
|
const project = require("../src/prompt/project");
|
|
22
22
|
const rc = require("../src/util/rc");
|
|
23
|
-
const
|
|
23
|
+
const starter = require("../src/prompt/starter");
|
|
24
24
|
|
|
25
25
|
// [use]
|
|
26
26
|
|
|
@@ -70,7 +70,7 @@ const start = function (argv) {
|
|
|
70
70
|
handler: handler({ json, quiet }),
|
|
71
71
|
project: argv.project,
|
|
72
72
|
root,
|
|
73
|
-
|
|
73
|
+
starter: argv.starter,
|
|
74
74
|
})
|
|
75
75
|
.then((data) => {
|
|
76
76
|
const dir = relative(root, data.path);
|
|
@@ -110,14 +110,14 @@ const prompt = async function ({ yes, ...argv }) {
|
|
|
110
110
|
const opts = { ...argv };
|
|
111
111
|
if (yes) {
|
|
112
112
|
opts.project ??= project.input.default;
|
|
113
|
-
opts.
|
|
113
|
+
opts.starter ??= starter.select.default;
|
|
114
114
|
return opts;
|
|
115
115
|
}
|
|
116
116
|
if (!argv.project) {
|
|
117
117
|
opts.project = await input(project.input);
|
|
118
118
|
}
|
|
119
|
-
if (!argv.
|
|
120
|
-
opts.
|
|
119
|
+
if (!argv.starter) {
|
|
120
|
+
opts.starter = await select(starter.select);
|
|
121
121
|
}
|
|
122
122
|
return opts;
|
|
123
123
|
};
|
|
@@ -135,9 +135,9 @@ const main = function (argv) {
|
|
|
135
135
|
type: "string",
|
|
136
136
|
}),
|
|
137
137
|
)
|
|
138
|
-
.option("
|
|
138
|
+
.option("starter", {
|
|
139
139
|
alias: "t",
|
|
140
|
-
describe: "Select a project
|
|
140
|
+
describe: "Select a project starter.",
|
|
141
141
|
type: "string",
|
|
142
142
|
})
|
|
143
143
|
.option("yes", {
|
package/bin/arc-pack.js
CHANGED
|
@@ -49,7 +49,7 @@ const start = function (argv) {
|
|
|
49
49
|
.then((issues) => {
|
|
50
50
|
const valid = !issues.length;
|
|
51
51
|
if (!valid) {
|
|
52
|
-
throw new Error("
|
|
52
|
+
throw new Error("Validate failed. Run `arc validate` for details.");
|
|
53
53
|
}
|
|
54
54
|
return pack({ output: argv.output, root });
|
|
55
55
|
})
|
|
@@ -60,7 +60,6 @@ const start = function (argv) {
|
|
|
60
60
|
}
|
|
61
61
|
if (!quiet) {
|
|
62
62
|
log.hs("Packed.");
|
|
63
|
-
print(data, { toml: true });
|
|
64
63
|
}
|
|
65
64
|
})
|
|
66
65
|
.catch((ex) => {
|
package/bin/arc-validate.js
CHANGED
|
@@ -44,18 +44,19 @@ const start = function (argv) {
|
|
|
44
44
|
const quiet = argv.quiet;
|
|
45
45
|
return validate({ root: resolve(process.cwd(), argv.cwd) })
|
|
46
46
|
.then((issues) => {
|
|
47
|
-
const
|
|
47
|
+
const count = issues.length;
|
|
48
|
+
const term = count === 1 ? "issue" : "issues";
|
|
48
49
|
if (json) {
|
|
49
50
|
print({ issues });
|
|
50
|
-
} else if (
|
|
51
|
-
if (
|
|
52
|
-
log.
|
|
51
|
+
} else if (!quiet) {
|
|
52
|
+
if (count) {
|
|
53
|
+
log.hd(`${count} ${term} found.`);
|
|
54
|
+
log.p(issues.map((error) => `✗ ${error}`));
|
|
55
|
+
} else {
|
|
56
|
+
log.hs("Validated.");
|
|
53
57
|
}
|
|
54
|
-
} else {
|
|
55
|
-
log.hd("Failed.");
|
|
56
|
-
log.p(issues.map((error) => `✖ ${error}`));
|
|
57
58
|
}
|
|
58
|
-
process.exit(
|
|
59
|
+
process.exit(count ? 1 : 0);
|
|
59
60
|
})
|
|
60
61
|
.catch((ex) => {
|
|
61
62
|
const message = ex.message;
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"degit": "^2.8.6",
|
|
19
19
|
"dompurify": "^3.3.1",
|
|
20
20
|
"dot-prop": "^6.0.1",
|
|
21
|
+
"fast-json-stable-stringify": "^2.1.0",
|
|
21
22
|
"fs-extra": "^11.3.2",
|
|
22
23
|
"image-size": "^2.0.2",
|
|
23
24
|
"jsdom": "^27.3.0",
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"mp4box": "^2.3.0",
|
|
26
27
|
"open": "^8.4.2",
|
|
27
28
|
"rc": "^1.2.8",
|
|
29
|
+
"semver": "^7.7.3",
|
|
28
30
|
"yargs": "^17.7.2",
|
|
29
31
|
"zod": "^4.1.13"
|
|
30
32
|
},
|
|
@@ -49,5 +51,5 @@
|
|
|
49
51
|
"license": "Apache-2.0",
|
|
50
52
|
"main": "./src/cli/index.js",
|
|
51
53
|
"name": "arcadible",
|
|
52
|
-
"version": "0.1.
|
|
54
|
+
"version": "0.1.2"
|
|
53
55
|
}
|
|
@@ -4,20 +4,189 @@
|
|
|
4
4
|
|
|
5
5
|
const execFile = require("node:child_process").execFile;
|
|
6
6
|
|
|
7
|
+
// [import]
|
|
8
|
+
|
|
9
|
+
const semver = require("semver");
|
|
10
|
+
|
|
11
|
+
// [import]
|
|
12
|
+
|
|
13
|
+
const strs = require("../../util/strs");
|
|
14
|
+
|
|
15
|
+
// [use]
|
|
16
|
+
|
|
17
|
+
const compareSemver = semver.compare;
|
|
18
|
+
const trimWhitespace = strs.trimWhitespace;
|
|
19
|
+
const validSemver = semver.valid;
|
|
20
|
+
|
|
21
|
+
// [declare]
|
|
22
|
+
|
|
23
|
+
const PREFIX = "arcadible/release/v";
|
|
24
|
+
|
|
25
|
+
// [function]
|
|
26
|
+
|
|
27
|
+
const git = function (root, args, cb) {
|
|
28
|
+
execFile("git", ["-C", root, ...args], cb);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// [function]
|
|
32
|
+
|
|
33
|
+
const ensureRepo = function (root, cb) {
|
|
34
|
+
const message = [
|
|
35
|
+
"Unable to find Git repository.",
|
|
36
|
+
"Run this command from a Git repository.",
|
|
37
|
+
];
|
|
38
|
+
git(root, ["rev-parse", "--is-inside-work-tree"], (err) => {
|
|
39
|
+
if (err) {
|
|
40
|
+
cb(new Error(message.join("\n"), { cause: err }));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
cb();
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// [function]
|
|
48
|
+
|
|
49
|
+
const ensureRemote = function (root, cb) {
|
|
50
|
+
const message = [
|
|
51
|
+
"Unable to access Git remote 'origin'.",
|
|
52
|
+
"Verify the remote exists and you have permission to access it.",
|
|
53
|
+
];
|
|
54
|
+
git(root, ["ls-remote", "origin"], (err) => {
|
|
55
|
+
if (err) {
|
|
56
|
+
cb(new Error(message.join("\n"), { cause: err }));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
cb();
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
7
63
|
// [function]
|
|
8
64
|
|
|
9
|
-
const
|
|
10
|
-
|
|
65
|
+
const ensureClean = function (root, cb) {
|
|
66
|
+
const message = [
|
|
67
|
+
"Unable to continue with unstaged changes.",
|
|
68
|
+
"Stage, commit, or discard local changes before deploying.",
|
|
69
|
+
];
|
|
70
|
+
git(root, ["diff", "--quiet"], (err) => {
|
|
11
71
|
if (err) {
|
|
12
|
-
|
|
72
|
+
if (err.code === 1) {
|
|
73
|
+
cb(new Error(message.join("\n"), { cause: err }));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
cb(err);
|
|
13
77
|
return;
|
|
14
78
|
}
|
|
15
|
-
|
|
16
|
-
|
|
79
|
+
git(root, ["diff", "--cached", "--quiet"], (err) => {
|
|
80
|
+
if (!err) {
|
|
81
|
+
cb(null, { cached: false });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (err.code === 1) {
|
|
85
|
+
cb(null, { cached: true });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
cb(err);
|
|
17
89
|
});
|
|
18
90
|
});
|
|
19
91
|
};
|
|
20
92
|
|
|
93
|
+
// [function]
|
|
94
|
+
|
|
95
|
+
const fetchTags = function (root, cb) {
|
|
96
|
+
const message = [
|
|
97
|
+
"Unable to synchronize Git release tags.",
|
|
98
|
+
"Run `arc deploy` again to retry with the latest release tags.",
|
|
99
|
+
];
|
|
100
|
+
git(
|
|
101
|
+
root,
|
|
102
|
+
["fetch", "origin", `refs/tags/${PREFIX}*:refs/tags/${PREFIX}*`],
|
|
103
|
+
(err) => {
|
|
104
|
+
if (err) {
|
|
105
|
+
cb(new Error(message.join("\n"), { cause: err }));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
cb();
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// [function]
|
|
114
|
+
|
|
115
|
+
const listTags = function (root, cb) {
|
|
116
|
+
fetchTags(root, (err) => {
|
|
117
|
+
if (err) {
|
|
118
|
+
cb(err);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
git(root, ["tag", "--list", `${PREFIX}*`], (err, stdOut) => {
|
|
122
|
+
if (err) {
|
|
123
|
+
cb(err);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const versions = trimWhitespace(stdOut)
|
|
127
|
+
.split("\n")
|
|
128
|
+
.map((tag) => tag.slice(PREFIX.length))
|
|
129
|
+
.filter(validSemver)
|
|
130
|
+
.sort(compareSemver);
|
|
131
|
+
cb(null, versions.at(-1) || "0.0.0");
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// [function]
|
|
137
|
+
|
|
138
|
+
const createTag = function (root, version, pre, cb) {
|
|
139
|
+
const message = [
|
|
140
|
+
"Unable to create Git tag.",
|
|
141
|
+
"Verify the release tag does not already exist locally.",
|
|
142
|
+
];
|
|
143
|
+
git(
|
|
144
|
+
root,
|
|
145
|
+
[
|
|
146
|
+
"tag",
|
|
147
|
+
"-a",
|
|
148
|
+
`${PREFIX}${version}`,
|
|
149
|
+
"-m",
|
|
150
|
+
pre ? `Prerelease v${version}` : `Release v${version}`,
|
|
151
|
+
],
|
|
152
|
+
(err) => {
|
|
153
|
+
if (err) {
|
|
154
|
+
cb(new Error(message.join("\n"), { cause: err }));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
cb();
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// [function]
|
|
163
|
+
|
|
164
|
+
const pushTag = function (root, version, cb) {
|
|
165
|
+
const message = [
|
|
166
|
+
"Unable to push Git tag.",
|
|
167
|
+
"Run `arc deploy` again to retry with the latest release version.",
|
|
168
|
+
];
|
|
169
|
+
git(root, ["push", "origin", `${PREFIX}${version}`], (err) => {
|
|
170
|
+
if (err) {
|
|
171
|
+
cb(new Error(message.join("\n"), { cause: err }));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
cb();
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// [function]
|
|
179
|
+
|
|
180
|
+
const release = function (root, version, pre, cb) {
|
|
181
|
+
createTag(root, version, pre, (err) => {
|
|
182
|
+
if (err) {
|
|
183
|
+
cb(err);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
pushTag(root, version, cb);
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
|
|
21
190
|
// [export]
|
|
22
191
|
|
|
23
|
-
module.exports = {
|
|
192
|
+
module.exports = { ensureClean, ensureRemote, ensureRepo, listTags, release };
|
|
@@ -1,9 +1,84 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const semver = require("semver");
|
|
6
|
+
|
|
7
|
+
// [import]
|
|
8
|
+
|
|
9
|
+
const git = require("./git");
|
|
10
|
+
|
|
11
|
+
// [use]
|
|
12
|
+
|
|
13
|
+
const ensureClean = git.ensureClean;
|
|
14
|
+
const ensureRemote = git.ensureRemote;
|
|
15
|
+
const ensureRepo = git.ensureRepo;
|
|
16
|
+
const incSemver = semver.inc;
|
|
17
|
+
const listTags = git.listTags;
|
|
18
|
+
const release = git.release;
|
|
19
|
+
|
|
20
|
+
// [function]
|
|
21
|
+
|
|
22
|
+
const deployGit = function ({ pre, preId, root }, handler, cb) {
|
|
23
|
+
listTags(root, (err, from) => {
|
|
24
|
+
if (err) {
|
|
25
|
+
cb(err);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const to = incSemver(from, pre ? "prerelease" : "patch", preId);
|
|
29
|
+
release(root, to, pre, (err) => {
|
|
30
|
+
if (err) {
|
|
31
|
+
cb(err);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
cb(null, { from, to });
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// [function]
|
|
40
|
+
|
|
41
|
+
const deploy = function ({ pre, preId, root }, { onInfo }, cb) {
|
|
42
|
+
ensureRepo(root, (err) => {
|
|
43
|
+
if (err) {
|
|
44
|
+
cb(err);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
ensureClean(root, (err, diff) => {
|
|
48
|
+
if (err) {
|
|
49
|
+
cb(err);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (diff.cached) {
|
|
53
|
+
onInfo({
|
|
54
|
+
level: "warn",
|
|
55
|
+
message: "Staged but uncommitted changes will not be deployed.",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
ensureRemote(root, (err) => {
|
|
59
|
+
if (err) {
|
|
60
|
+
cb(err);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
deployGit({ pre, preId, root }, { onInfo }, cb);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
3
69
|
// [function]
|
|
4
70
|
|
|
5
|
-
const main = function () {
|
|
6
|
-
|
|
71
|
+
const main = function ({ pre, preId, root }, { onBegin, ...handler }) {
|
|
72
|
+
onBegin({ root });
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
deploy({ pre, preId, root }, handler, (err, data) => {
|
|
75
|
+
if (err) {
|
|
76
|
+
reject(err);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
resolve(data);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
7
82
|
};
|
|
8
83
|
|
|
9
84
|
// [export]
|
package/src/action/init/tool.js
CHANGED
|
@@ -27,14 +27,14 @@ const init = function (src, dest, { onBegin, onInfo }) {
|
|
|
27
27
|
|
|
28
28
|
// [function]
|
|
29
29
|
|
|
30
|
-
const main = function ({ force, project, root,
|
|
30
|
+
const main = function ({ force, project, root, starter }, handler) {
|
|
31
31
|
const dest = resolve(root, project);
|
|
32
32
|
return pathExists(dest)
|
|
33
33
|
.then((exists) => {
|
|
34
34
|
if (exists && !force) {
|
|
35
35
|
throw new Error("Directory exists. Run with `--force` to overwrite.");
|
|
36
36
|
}
|
|
37
|
-
return init(
|
|
37
|
+
return init(starter, dest, handler);
|
|
38
38
|
})
|
|
39
39
|
.then(() => ({ path: dest }));
|
|
40
40
|
};
|
package/src/cli/deploy.js
CHANGED
|
@@ -7,9 +7,9 @@ const deployTool = require("../action/deploy/tool");
|
|
|
7
7
|
|
|
8
8
|
// [function]
|
|
9
9
|
|
|
10
|
-
const main = function ({
|
|
11
|
-
const tool =
|
|
12
|
-
return tool(conf);
|
|
10
|
+
const main = function ({ direct, handler, ...conf }) {
|
|
11
|
+
const tool = direct ? deployTool : deployGitTool;
|
|
12
|
+
return tool(conf, handler);
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
// [export]
|
package/src/config/workflow.js
CHANGED
package/src/parser/manifest.js
CHANGED
|
@@ -12,6 +12,7 @@ const TOML = require("@iarna/toml");
|
|
|
12
12
|
// [use]
|
|
13
13
|
|
|
14
14
|
const join = path.join;
|
|
15
|
+
const pathExists = fs.pathExists;
|
|
15
16
|
const readFile = fs.readFile;
|
|
16
17
|
|
|
17
18
|
// [declare]
|
|
@@ -33,12 +34,10 @@ const parseToml = function (buf) {
|
|
|
33
34
|
// [function]
|
|
34
35
|
|
|
35
36
|
const parse = function (root) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
.catch(reject);
|
|
41
|
-
});
|
|
37
|
+
const file = join(root, MANIFEST);
|
|
38
|
+
return pathExists(file)
|
|
39
|
+
.then((exists) => (exists ? readFile(file, "utf8") : null))
|
|
40
|
+
.then((buf) => (buf === null ? {} : parseToml(buf)));
|
|
42
41
|
};
|
|
43
42
|
|
|
44
43
|
// [export]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
|
|
7
|
+
// [import]
|
|
8
|
+
|
|
9
|
+
const fs = require("fs-extra");
|
|
10
|
+
|
|
11
|
+
// [use]
|
|
12
|
+
|
|
13
|
+
const join = path.join;
|
|
14
|
+
const pathExists = fs.pathExists;
|
|
15
|
+
const readFile = fs.readFile;
|
|
16
|
+
|
|
17
|
+
// [declare]
|
|
18
|
+
|
|
19
|
+
const PACKAGE = "package.json";
|
|
20
|
+
|
|
21
|
+
// [function]
|
|
22
|
+
|
|
23
|
+
const parseJson = function (buf) {
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(buf);
|
|
26
|
+
} catch (ex) {
|
|
27
|
+
throw new Error(`Unable to parse ${PACKAGE}: ${ex.message}`, {
|
|
28
|
+
cause: ex,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// [function]
|
|
34
|
+
|
|
35
|
+
const extract = function (pkg) {
|
|
36
|
+
const game = { version: pkg.version || null };
|
|
37
|
+
return Object.fromEntries(
|
|
38
|
+
Object.entries({ game }).filter(([, value]) =>
|
|
39
|
+
Object.values(value).some(Boolean),
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// [function]
|
|
45
|
+
|
|
46
|
+
const parse = function (root) {
|
|
47
|
+
const file = join(root, PACKAGE);
|
|
48
|
+
return pathExists(file)
|
|
49
|
+
.then((exists) => (exists ? readFile(file, "utf8") : null))
|
|
50
|
+
.then((buf) => (buf === null ? {} : parseJson(buf)))
|
|
51
|
+
.then((pkg) => (Object.keys(pkg).length ? extract(pkg) : {}));
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// [export]
|
|
55
|
+
|
|
56
|
+
module.exports = { parse };
|
package/src/parser/project.js
CHANGED
|
@@ -6,16 +6,18 @@ const cfggame = require("../config/game");
|
|
|
6
6
|
const cfgworkflow = require("../config/workflow");
|
|
7
7
|
const manifest = require("./manifest");
|
|
8
8
|
const media = require("./media");
|
|
9
|
+
const pkg = require("./pkg");
|
|
9
10
|
const promise = require("../util/promise");
|
|
10
11
|
const readme = require("./readme");
|
|
11
12
|
|
|
12
13
|
// [function]
|
|
13
14
|
|
|
14
|
-
const configGame = function (readmeGame, mediaGame, manifestGame) {
|
|
15
|
+
const configGame = function (readmeGame, mediaGame, pkgGame, manifestGame) {
|
|
15
16
|
return {
|
|
16
17
|
...cfggame,
|
|
17
18
|
...(readmeGame || {}),
|
|
18
19
|
...(mediaGame || {}),
|
|
20
|
+
...(pkgGame || {}),
|
|
19
21
|
...(manifestGame || {}),
|
|
20
22
|
};
|
|
21
23
|
};
|
|
@@ -35,14 +37,16 @@ const parse = function (root) {
|
|
|
35
37
|
const parsers = [
|
|
36
38
|
() => manifest.parse(root),
|
|
37
39
|
() => media.parse(root),
|
|
40
|
+
() => pkg.parse(root),
|
|
38
41
|
() => readme.parse(root),
|
|
39
42
|
];
|
|
40
43
|
return promise
|
|
41
44
|
.serial(parsers)
|
|
42
|
-
.then(([manifestData, mediaData, readmeData]) => {
|
|
45
|
+
.then(([manifestData, mediaData, pkgData, readmeData]) => {
|
|
43
46
|
const game = configGame(
|
|
44
47
|
readmeData.game,
|
|
45
48
|
mediaData.game,
|
|
49
|
+
pkgData.game,
|
|
46
50
|
manifestData.game,
|
|
47
51
|
);
|
|
48
52
|
const workflow = configWorkflow(manifestData.workflow);
|
package/src/parser/readme.js
CHANGED
|
@@ -18,13 +18,14 @@ const strs = require("../util/strs");
|
|
|
18
18
|
// [use]
|
|
19
19
|
|
|
20
20
|
const join = path.join;
|
|
21
|
+
const pathExists = fs.pathExists;
|
|
21
22
|
const pruneEmpty = objs.pruneEmpty;
|
|
22
23
|
const readFile = fs.readFile;
|
|
23
24
|
const trimWhitespace = strs.trimWhitespace;
|
|
24
25
|
|
|
25
26
|
// [declare]
|
|
26
27
|
|
|
27
|
-
const README = "README.md";
|
|
28
|
+
const README = ["arcadible.md", "README.md"];
|
|
28
29
|
|
|
29
30
|
// [function]
|
|
30
31
|
|
|
@@ -118,25 +119,34 @@ const extract = function (html) {
|
|
|
118
119
|
|
|
119
120
|
// [function]
|
|
120
121
|
|
|
121
|
-
const parseReadme = function (buf) {
|
|
122
|
+
const parseReadme = function (buf, file) {
|
|
122
123
|
try {
|
|
123
124
|
return extract(MD.parse(buf));
|
|
124
125
|
} catch (ex) {
|
|
125
|
-
throw new Error(`Unable to parse ${
|
|
126
|
+
throw new Error(`Unable to parse ${file}: ${ex.message}`, {
|
|
127
|
+
cause: ex,
|
|
128
|
+
});
|
|
126
129
|
}
|
|
127
130
|
};
|
|
128
131
|
|
|
129
132
|
// [function]
|
|
130
133
|
|
|
134
|
+
const findReadme = function (root) {
|
|
135
|
+
return Promise.all(
|
|
136
|
+
README.map((file) =>
|
|
137
|
+
pathExists(join(root, file)).then((exists) => (exists ? file : null)),
|
|
138
|
+
),
|
|
139
|
+
).then((files) => files.find(Boolean) || null);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// [function]
|
|
143
|
+
|
|
131
144
|
const parse = function (root) {
|
|
132
|
-
return
|
|
133
|
-
readFile(join(root,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.then(resolve)
|
|
138
|
-
.catch(reject);
|
|
139
|
-
});
|
|
145
|
+
return findReadme(root)
|
|
146
|
+
.then((file) => (file ? readFile(join(root, file), "utf8") : null))
|
|
147
|
+
.then((buf) => (buf === null ? null : parseReadme(buf)))
|
|
148
|
+
.then(pruneEmpty)
|
|
149
|
+
.then((game) => ({ game: game || null }));
|
|
140
150
|
};
|
|
141
151
|
|
|
142
152
|
// [export]
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
// [declare]
|
|
4
|
+
|
|
5
|
+
const REPO = "arcadible";
|
|
6
|
+
|
|
3
7
|
// [export]
|
|
4
8
|
|
|
5
9
|
module.exports = {
|
|
@@ -8,30 +12,30 @@ module.exports = {
|
|
|
8
12
|
{
|
|
9
13
|
description: "Blank starter template.",
|
|
10
14
|
name: "Blank",
|
|
11
|
-
value:
|
|
15
|
+
value: `${REPO}/starter`,
|
|
12
16
|
},
|
|
13
17
|
{
|
|
14
18
|
description: "Three.js starter template.",
|
|
15
19
|
name: "Three.js",
|
|
16
|
-
value:
|
|
20
|
+
value: `${REPO}/starter-threejs`,
|
|
17
21
|
},
|
|
18
22
|
{
|
|
19
23
|
description: "Phaser starter template.",
|
|
20
24
|
name: "Phaser",
|
|
21
|
-
value:
|
|
25
|
+
value: `${REPO}/starter-phaser`,
|
|
22
26
|
},
|
|
23
27
|
{
|
|
24
28
|
description: "PixiJS starter template.",
|
|
25
29
|
name: "PixiJS",
|
|
26
|
-
value:
|
|
30
|
+
value: `${REPO}/starter-pixijs`,
|
|
27
31
|
},
|
|
28
32
|
{
|
|
29
33
|
description: "Babylon.js starter template.",
|
|
30
34
|
name: "Babylon.js",
|
|
31
|
-
value:
|
|
35
|
+
value: `${REPO}/starter-babylonjs`,
|
|
32
36
|
},
|
|
33
37
|
],
|
|
34
|
-
default:
|
|
35
|
-
message: "
|
|
38
|
+
default: `${REPO}/starter`,
|
|
39
|
+
message: "Starter",
|
|
36
40
|
},
|
|
37
41
|
};
|
package/src/schema/game.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
5
|
const chalk = require("chalk");
|
|
6
|
+
const semver = require("semver");
|
|
6
7
|
const z = require("zod");
|
|
7
8
|
|
|
8
9
|
// [import]
|
|
@@ -16,6 +17,10 @@ const cfgurl = require("../config/url");
|
|
|
16
17
|
const cfgvisibility = require("../config/visibility");
|
|
17
18
|
const dom = require("../util/dom");
|
|
18
19
|
|
|
20
|
+
// [use]
|
|
21
|
+
|
|
22
|
+
const validSemver = semver.valid;
|
|
23
|
+
|
|
19
24
|
// [function]
|
|
20
25
|
|
|
21
26
|
const reference = function (field) {
|
|
@@ -267,6 +272,18 @@ const zTrailer = function () {
|
|
|
267
272
|
|
|
268
273
|
// [function]
|
|
269
274
|
|
|
275
|
+
const zVersion = function () {
|
|
276
|
+
const field = "game.version";
|
|
277
|
+
return z
|
|
278
|
+
.string()
|
|
279
|
+
.refine(
|
|
280
|
+
(value) => validSemver(value) !== null,
|
|
281
|
+
message(field, "Must be a valid semver."),
|
|
282
|
+
);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
// [function]
|
|
286
|
+
|
|
270
287
|
const zVisibility = function () {
|
|
271
288
|
// const field = "game.visibility";
|
|
272
289
|
return z.optional(z.enum(cfgvisibility));
|
|
@@ -312,6 +329,7 @@ const main = function (value, { root }) {
|
|
|
312
329
|
tagline: zTagline(),
|
|
313
330
|
title: zTitle(),
|
|
314
331
|
trailer: zTrailer(),
|
|
332
|
+
version: zVersion(),
|
|
315
333
|
visibility: zVisibility(),
|
|
316
334
|
wordmark: zWordmark(root),
|
|
317
335
|
wordmark_animated: zWordmarkAnimated(root),
|
package/src/util/log.js
CHANGED
|
@@ -72,6 +72,30 @@ const pdnl = function (message) {
|
|
|
72
72
|
|
|
73
73
|
// [function]
|
|
74
74
|
|
|
75
|
+
const hw = function (message) {
|
|
76
|
+
log(console.log, message, { bold: true, color: "yellow" });
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// [function]
|
|
80
|
+
|
|
81
|
+
const hwnl = function (message) {
|
|
82
|
+
log(console.log, message, { bold: true, color: "yellow", nl: true });
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// [function]
|
|
86
|
+
|
|
87
|
+
const pw = function (message) {
|
|
88
|
+
log(console.log, message, { color: "yellow" });
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// [function]
|
|
92
|
+
|
|
93
|
+
const pwnl = function (message) {
|
|
94
|
+
log(console.log, message, { color: "yellow", nl: true });
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// [function]
|
|
98
|
+
|
|
75
99
|
const hs = function (message) {
|
|
76
100
|
log(console.log, message, { bold: true, color: "green" });
|
|
77
101
|
};
|
|
@@ -96,4 +120,21 @@ const psnl = function (message) {
|
|
|
96
120
|
|
|
97
121
|
// [export]
|
|
98
122
|
|
|
99
|
-
module.exports = {
|
|
123
|
+
module.exports = {
|
|
124
|
+
h,
|
|
125
|
+
hd,
|
|
126
|
+
hdnl,
|
|
127
|
+
hnl,
|
|
128
|
+
hs,
|
|
129
|
+
hsnl,
|
|
130
|
+
hw,
|
|
131
|
+
hwnl,
|
|
132
|
+
p,
|
|
133
|
+
pd,
|
|
134
|
+
pdnl,
|
|
135
|
+
pnl,
|
|
136
|
+
ps,
|
|
137
|
+
psnl,
|
|
138
|
+
pw,
|
|
139
|
+
pwnl,
|
|
140
|
+
};
|
package/src/util/objs.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const stringify = require("fast-json-stable-stringify");
|
|
6
|
+
|
|
3
7
|
// [function]
|
|
4
8
|
|
|
5
9
|
const pruneEmpty = function (value) {
|
|
@@ -23,6 +27,12 @@ const pruneEmpty = function (value) {
|
|
|
23
27
|
/* eslint-enable no-undefined */
|
|
24
28
|
};
|
|
25
29
|
|
|
30
|
+
// [function]
|
|
31
|
+
|
|
32
|
+
const sort = function (value) {
|
|
33
|
+
return JSON.parse(stringify(value));
|
|
34
|
+
};
|
|
35
|
+
|
|
26
36
|
// [export]
|
|
27
37
|
|
|
28
|
-
module.exports = { pruneEmpty };
|
|
38
|
+
module.exports = { pruneEmpty, sort };
|
package/src/util/output.js
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
const TOML = require("@iarna/toml");
|
|
6
6
|
|
|
7
|
+
// [import]
|
|
8
|
+
|
|
9
|
+
const objs = require("./objs");
|
|
10
|
+
|
|
11
|
+
// [use]
|
|
12
|
+
|
|
13
|
+
const sort = objs.sort;
|
|
14
|
+
|
|
7
15
|
// [function]
|
|
8
16
|
|
|
9
17
|
const write = function (data) {
|
|
@@ -13,7 +21,7 @@ const write = function (data) {
|
|
|
13
21
|
// [function]
|
|
14
22
|
|
|
15
23
|
const printJson = function (data) {
|
|
16
|
-
write(JSON.stringify(data, null, 2));
|
|
24
|
+
write(JSON.stringify(sort(data), null, 2));
|
|
17
25
|
};
|
|
18
26
|
|
|
19
27
|
// [function]
|
|
@@ -25,7 +33,7 @@ const printToml = function (data, key = "value") {
|
|
|
25
33
|
return;
|
|
26
34
|
}
|
|
27
35
|
try {
|
|
28
|
-
write(TOML.stringify(data));
|
|
36
|
+
write(TOML.stringify(sort(data)));
|
|
29
37
|
} catch (ex) {
|
|
30
38
|
write(TOML.stringify({ [field]: data }));
|
|
31
39
|
}
|
package/src/util/request.js
CHANGED
|
@@ -24,8 +24,8 @@ const parse = function (resp) {
|
|
|
24
24
|
|
|
25
25
|
const send = function (method, url, body, { token } = {}) {
|
|
26
26
|
const headers = {
|
|
27
|
-
"X-Arc-Id": CLIENT_ID,
|
|
28
|
-
"X-Arc-Version": CLIENT_VERSION,
|
|
27
|
+
"X-Arc-Client-Id": CLIENT_ID,
|
|
28
|
+
"X-Arc-Client-Version": CLIENT_VERSION,
|
|
29
29
|
};
|
|
30
30
|
if (token) {
|
|
31
31
|
headers.authorization = `Bearer ${token}`;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
// [import]
|
|
4
|
-
|
|
5
|
-
const execFile = require("node:child_process").execFile;
|
|
6
|
-
|
|
7
|
-
// [import]
|
|
8
|
-
|
|
9
|
-
const strs = require("../../util/strs");
|
|
10
|
-
|
|
11
|
-
// [use]
|
|
12
|
-
|
|
13
|
-
const trimWhitespace = strs.trimWhitespace;
|
|
14
|
-
|
|
15
|
-
// [declare]
|
|
16
|
-
|
|
17
|
-
const RE_TAG_EXISTS = /tag\s+'([^']+)'\s+already\s+exists/iu;
|
|
18
|
-
|
|
19
|
-
// [function]
|
|
20
|
-
|
|
21
|
-
const knownErr = function (stdErr) {
|
|
22
|
-
const tagExists = stdErr.match(RE_TAG_EXISTS);
|
|
23
|
-
if (tagExists) {
|
|
24
|
-
return [
|
|
25
|
-
`Git tag exists: ${tagExists[1]}`,
|
|
26
|
-
"The package version has been synchronized.",
|
|
27
|
-
"Try again.",
|
|
28
|
-
].join("\n");
|
|
29
|
-
}
|
|
30
|
-
return stdErr;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
// [function]
|
|
34
|
-
|
|
35
|
-
const npm = function (root, pre, preId) {
|
|
36
|
-
return [
|
|
37
|
-
"--prefix",
|
|
38
|
-
root,
|
|
39
|
-
"version",
|
|
40
|
-
pre ? "prerelease" : "patch",
|
|
41
|
-
"--preid",
|
|
42
|
-
preId,
|
|
43
|
-
"-m",
|
|
44
|
-
pre ? "Prerelease v%s" : "Release v%s",
|
|
45
|
-
];
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// [function]
|
|
49
|
-
|
|
50
|
-
const git = function (root) {
|
|
51
|
-
return ["-C", root, "push", "--follow-tags"];
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// [function]
|
|
55
|
-
|
|
56
|
-
const main = function (root, { pre, preId }, cb) {
|
|
57
|
-
execFile("npm", npm(root, pre, preId), (err, stdOut, stdErr) => {
|
|
58
|
-
if (err) {
|
|
59
|
-
cb(new Error(knownErr(stdErr), { cause: err }));
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
execFile("git", git(root), (err) => {
|
|
63
|
-
if (err) {
|
|
64
|
-
cb(new Error(knownErr(stdErr), { cause: err }));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
cb(null, trimWhitespace(stdOut));
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// [export]
|
|
73
|
-
|
|
74
|
-
module.exports = main;
|