arcadible 0.1.23 → 0.1.25
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-init.js +3 -3
- package/bin/arc-validate.js +13 -2
- package/package.json +1 -1
- package/src/action/predeploy/git.js +2 -2
- package/src/action/predeploy/pm.js +4 -4
- package/src/action/predeploy/tool-git.js +2 -1
- package/src/config/template.js +45 -0
- package/src/phrase.js +187 -0
- package/src/schema/game.js +100 -40
- package/src/schema/workflow.js +3 -3
- package/src/util/bytes.js +24 -0
- package/src/util/http.js +5 -1
- package/src/util/image.js +9 -8
- package/src/util/progress.js +5 -15
- package/src/util/schema.js +26 -2
- package/src/util/video.js +12 -9
- package/src/prompt/template.js +0 -46
package/bin/arc-init.js
CHANGED
|
@@ -16,12 +16,12 @@ const yargs = require("yargs/yargs");
|
|
|
16
16
|
|
|
17
17
|
const cfgpackage = require("../src/config/package");
|
|
18
18
|
const cfgproduct = require("../src/config/product");
|
|
19
|
+
const cfgtemplate = require("../src/config/template");
|
|
19
20
|
const init = require("../src/cli/init");
|
|
20
21
|
const log = require("../src/util/log");
|
|
21
22
|
const output = require("../src/util/output");
|
|
22
23
|
const rc = require("../src/util/rc");
|
|
23
24
|
const spinner = require("../src/util/spinner");
|
|
24
|
-
const template = require("../src/prompt/template");
|
|
25
25
|
|
|
26
26
|
// [use]
|
|
27
27
|
|
|
@@ -126,11 +126,11 @@ const prompt = async function ({ yes, ...argv }) {
|
|
|
126
126
|
const opts = { ...argv };
|
|
127
127
|
opts.patch = await patch(opts.cwd, opts.project);
|
|
128
128
|
if (opts.patch || yes) {
|
|
129
|
-
opts.template ??=
|
|
129
|
+
opts.template ??= cfgtemplate.default;
|
|
130
130
|
return opts;
|
|
131
131
|
}
|
|
132
132
|
if (!opts.template) {
|
|
133
|
-
opts.template = await select(
|
|
133
|
+
opts.template = await select(cfgtemplate);
|
|
134
134
|
}
|
|
135
135
|
return opts;
|
|
136
136
|
};
|
package/bin/arc-validate.js
CHANGED
|
@@ -17,10 +17,12 @@ const cfgproduct = require("../src/config/product");
|
|
|
17
17
|
const log = require("../src/util/log");
|
|
18
18
|
const output = require("../src/util/output");
|
|
19
19
|
const rc = require("../src/util/rc");
|
|
20
|
+
const schema = require("../src/util/schema");
|
|
20
21
|
const validate = require("../src/cli/validate");
|
|
21
22
|
|
|
22
23
|
// [use]
|
|
23
24
|
|
|
25
|
+
const dereference = schema.dereference;
|
|
24
26
|
const findRc = rc.findRc;
|
|
25
27
|
const print = output.print;
|
|
26
28
|
const resolve = path.resolve;
|
|
@@ -49,8 +51,17 @@ const start = function (argv) {
|
|
|
49
51
|
if (json) {
|
|
50
52
|
print({ issues });
|
|
51
53
|
} else if (count) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
const [probs, refs] = dereference(issues);
|
|
55
|
+
const probcount = probs.length;
|
|
56
|
+
if (probcount) {
|
|
57
|
+
log.hd(`${probcount} ${probcount === 1 ? "issue" : "issues"}:`);
|
|
58
|
+
log.p(probs.map((prob) => `✗ ${prob}`));
|
|
59
|
+
}
|
|
60
|
+
const refcount = refs.length;
|
|
61
|
+
if (refcount) {
|
|
62
|
+
log.h(`${refcount} ${refcount === 1 ? "reference" : "references"}:`);
|
|
63
|
+
log.p(refs);
|
|
64
|
+
}
|
|
54
65
|
} else if (!argv.quiet) {
|
|
55
66
|
log.hs("No issues found.");
|
|
56
67
|
}
|
package/package.json
CHANGED
|
@@ -107,8 +107,8 @@ const createTag = function (root, version, cb) {
|
|
|
107
107
|
`${PREFIX}${version}`,
|
|
108
108
|
"-m",
|
|
109
109
|
prereleaseSemver(version) === null
|
|
110
|
-
?
|
|
111
|
-
:
|
|
110
|
+
? phrase.versionRelease(version)
|
|
111
|
+
: phrase.versionPrerelease(version),
|
|
112
112
|
],
|
|
113
113
|
(err) => {
|
|
114
114
|
if (err) {
|
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
const fs = require("node:fs");
|
|
6
6
|
const path = require("node:path");
|
|
7
7
|
|
|
8
|
+
// [import]
|
|
9
|
+
|
|
10
|
+
const phrase = require("../../phrase");
|
|
11
|
+
|
|
8
12
|
// [use]
|
|
9
13
|
|
|
10
14
|
const existsSync = fs.existsSync; // eslint-disable-line no-sync
|
|
11
15
|
const join = path.join;
|
|
12
16
|
|
|
13
|
-
// [import]
|
|
14
|
-
|
|
15
|
-
const phrase = require("../../phrase");
|
|
16
|
-
|
|
17
17
|
// [function]
|
|
18
18
|
|
|
19
19
|
const ensureLockFile = function (root, cb) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
5
|
const git = require("./git");
|
|
6
|
+
const phrase = require("../../phrase");
|
|
6
7
|
const pm = require("./pm");
|
|
7
8
|
const project = require("../../parser/project");
|
|
8
9
|
|
|
@@ -42,7 +43,7 @@ const deployEnsureGit = function ({ root }, { onLogInfo }, cb) {
|
|
|
42
43
|
if (diff.cached && onLogInfo) {
|
|
43
44
|
onLogInfo({
|
|
44
45
|
level: "warn",
|
|
45
|
-
message:
|
|
46
|
+
message: phrase.gitStagedUnincluded(),
|
|
46
47
|
});
|
|
47
48
|
}
|
|
48
49
|
ensureRemote(root, cb);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const cfgproduct = require("./product");
|
|
6
|
+
const phrase = require("../phrase");
|
|
7
|
+
|
|
8
|
+
// [declare]
|
|
9
|
+
|
|
10
|
+
const HANDLE = cfgproduct.handle;
|
|
11
|
+
const STARTER = `${HANDLE}/starter`;
|
|
12
|
+
|
|
13
|
+
// [export]
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
choices: [
|
|
17
|
+
{
|
|
18
|
+
description: phrase.starterBlank(),
|
|
19
|
+
name: "Blank",
|
|
20
|
+
value: STARTER,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
description: phrase.starterThreeJs(),
|
|
24
|
+
name: "Three.js",
|
|
25
|
+
value: `${STARTER}-threejs`,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
description: phrase.starterPhaser(),
|
|
29
|
+
name: "Phaser",
|
|
30
|
+
value: `${STARTER}-phaser`,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
description: phrase.starterPixiJs(),
|
|
34
|
+
name: "PixiJS",
|
|
35
|
+
value: `${STARTER}-pixijs`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
description: phrase.starterBabylonJs(),
|
|
39
|
+
name: "Babylon.js",
|
|
40
|
+
value: `${STARTER}-babylonjs`,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
default: STARTER,
|
|
44
|
+
message: "Template",
|
|
45
|
+
};
|
package/src/phrase.js
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
|
+
const bytes = require("./util/bytes");
|
|
5
6
|
const cfgproduct = require("./config/product");
|
|
6
7
|
|
|
8
|
+
// [use]
|
|
9
|
+
|
|
10
|
+
const formatBytes = bytes.formatBytes;
|
|
11
|
+
|
|
7
12
|
// [declare]
|
|
8
13
|
|
|
9
14
|
const TOOL = cfgproduct.tool;
|
|
@@ -73,6 +78,12 @@ const gitRepoMissing = function () {
|
|
|
73
78
|
|
|
74
79
|
// [function]
|
|
75
80
|
|
|
81
|
+
const gitStagedUnincluded = function () {
|
|
82
|
+
return ["Staged but uncommitted changes will not be included."].join("\n");
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// [function]
|
|
86
|
+
|
|
76
87
|
const gitTagCreateFailed = function () {
|
|
77
88
|
return [
|
|
78
89
|
"Unable to create Git tag.",
|
|
@@ -100,6 +111,42 @@ const gitVersionExists = function () {
|
|
|
100
111
|
|
|
101
112
|
// [function]
|
|
102
113
|
|
|
114
|
+
const httpError = function (name, status) {
|
|
115
|
+
return `HttpError: ${name} (${status})`;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// [function]
|
|
119
|
+
|
|
120
|
+
const imageAspect = function (aspect) {
|
|
121
|
+
return `Image aspect ratio must be: ${aspect}`;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// [function]
|
|
125
|
+
|
|
126
|
+
const imageHeightMin = function (height) {
|
|
127
|
+
return `Image height must be at least: ${height}px`;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// [function]
|
|
131
|
+
|
|
132
|
+
const imageSizeMax = function (size) {
|
|
133
|
+
return `Image size must not exceed: ${formatBytes(size)}`;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// [function]
|
|
137
|
+
|
|
138
|
+
const imageUnsupported = function () {
|
|
139
|
+
return "Image has an unsupported file type.";
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// [function]
|
|
143
|
+
|
|
144
|
+
const imageWidthMin = function (width) {
|
|
145
|
+
return `Image width must be at least: ${width}px`;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// [function]
|
|
149
|
+
|
|
103
150
|
const issuesFound = function (count) {
|
|
104
151
|
return `${count} ${count === 1 ? "issue" : "issues"} found. Run ${cmdValidate()} for details.`;
|
|
105
152
|
};
|
|
@@ -172,6 +219,60 @@ const packageTooLarge = function (size, assets) {
|
|
|
172
219
|
|
|
173
220
|
// [function]
|
|
174
221
|
|
|
222
|
+
const sizeB = function (size) {
|
|
223
|
+
return `${size} B`;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// [function]
|
|
227
|
+
|
|
228
|
+
const sizeGb = function (size) {
|
|
229
|
+
return `${size} GB`;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// [function]
|
|
233
|
+
|
|
234
|
+
const sizeKb = function (size) {
|
|
235
|
+
return `${size} KB`;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// [function]
|
|
239
|
+
|
|
240
|
+
const sizeMb = function (size) {
|
|
241
|
+
return `${size} MB`;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// [function]
|
|
245
|
+
|
|
246
|
+
const starterBabylonJs = function () {
|
|
247
|
+
return "Babylon.js starter.";
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// [function]
|
|
251
|
+
|
|
252
|
+
const starterBlank = function () {
|
|
253
|
+
return "Blank JavaScript starter.";
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// [function]
|
|
257
|
+
|
|
258
|
+
const starterPhaser = function () {
|
|
259
|
+
return "Phaser starter.";
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// [function]
|
|
263
|
+
|
|
264
|
+
const starterPixiJs = function () {
|
|
265
|
+
return "PixiJS starter.";
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// [function]
|
|
269
|
+
|
|
270
|
+
const starterThreeJs = function () {
|
|
271
|
+
return "Three.js starter.";
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// [function]
|
|
275
|
+
|
|
175
276
|
const timedOut = function () {
|
|
176
277
|
return "Timed out.";
|
|
177
278
|
};
|
|
@@ -194,6 +295,66 @@ const uploadFailed = function (status) {
|
|
|
194
295
|
return `Upload failed with status ${status}.`;
|
|
195
296
|
};
|
|
196
297
|
|
|
298
|
+
// [function]
|
|
299
|
+
|
|
300
|
+
const versionPrerelease = function (version) {
|
|
301
|
+
return `Prerelease v${version}`;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
// [function]
|
|
305
|
+
|
|
306
|
+
const versionRelease = function (version) {
|
|
307
|
+
return `Release v${version}`;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// [function]
|
|
311
|
+
|
|
312
|
+
const videoAspect = function (aspect) {
|
|
313
|
+
return `Video aspect ratio must be: ${aspect}`;
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// [function]
|
|
317
|
+
|
|
318
|
+
const videoDurationMax = function (maxDuration) {
|
|
319
|
+
return `Video duration must not exceed: ${maxDuration}s`;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// [function]
|
|
323
|
+
|
|
324
|
+
const videoDurationMin = function (duration) {
|
|
325
|
+
return `Video duration must be at least: ${duration}s`;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// [function]
|
|
329
|
+
|
|
330
|
+
const videoHeightMin = function (height) {
|
|
331
|
+
return `Video height must be at least: ${height}px`;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// [function]
|
|
335
|
+
|
|
336
|
+
const videoInvalid = function () {
|
|
337
|
+
return "Video is an invalid file.";
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// [function]
|
|
341
|
+
|
|
342
|
+
const videoSizeMax = function (size) {
|
|
343
|
+
return `Video size must not exceed: ${formatBytes(size)}`;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
// [function]
|
|
347
|
+
|
|
348
|
+
const videoUnsupported = function () {
|
|
349
|
+
return "Video has an unsupported file type.";
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// [function]
|
|
353
|
+
|
|
354
|
+
const videoWidthMin = function (width) {
|
|
355
|
+
return `Video width must be at least: ${width}px`;
|
|
356
|
+
};
|
|
357
|
+
|
|
197
358
|
// [export]
|
|
198
359
|
|
|
199
360
|
module.exports = {
|
|
@@ -206,9 +367,16 @@ module.exports = {
|
|
|
206
367
|
gitChangesPresent,
|
|
207
368
|
gitRemoteMissing,
|
|
208
369
|
gitRepoMissing,
|
|
370
|
+
gitStagedUnincluded,
|
|
209
371
|
gitTagCreateFailed,
|
|
210
372
|
gitTagPushFailed,
|
|
211
373
|
gitVersionExists,
|
|
374
|
+
httpError,
|
|
375
|
+
imageAspect,
|
|
376
|
+
imageHeightMin,
|
|
377
|
+
imageSizeMax,
|
|
378
|
+
imageUnsupported,
|
|
379
|
+
imageWidthMin,
|
|
212
380
|
issuesFound,
|
|
213
381
|
loginExpired,
|
|
214
382
|
loginFailed,
|
|
@@ -221,8 +389,27 @@ module.exports = {
|
|
|
221
389
|
overwriteWithForce,
|
|
222
390
|
packageFileMissing,
|
|
223
391
|
packageTooLarge,
|
|
392
|
+
sizeB,
|
|
393
|
+
sizeGb,
|
|
394
|
+
sizeKb,
|
|
395
|
+
sizeMb,
|
|
396
|
+
starterBabylonJs,
|
|
397
|
+
starterBlank,
|
|
398
|
+
starterPhaser,
|
|
399
|
+
starterPixiJs,
|
|
400
|
+
starterThreeJs,
|
|
224
401
|
timedOut,
|
|
225
402
|
unableToFind,
|
|
226
403
|
unableToParse,
|
|
227
404
|
uploadFailed,
|
|
405
|
+
versionPrerelease,
|
|
406
|
+
versionRelease,
|
|
407
|
+
videoAspect,
|
|
408
|
+
videoDurationMax,
|
|
409
|
+
videoDurationMin,
|
|
410
|
+
videoHeightMin,
|
|
411
|
+
videoInvalid,
|
|
412
|
+
videoSizeMax,
|
|
413
|
+
videoUnsupported,
|
|
414
|
+
videoWidthMin,
|
|
228
415
|
};
|
package/src/schema/game.js
CHANGED
|
@@ -64,8 +64,8 @@ const message = function (field, lines) {
|
|
|
64
64
|
const zText = function (field, { max, min }) {
|
|
65
65
|
return z
|
|
66
66
|
.string()
|
|
67
|
-
.min(min)
|
|
68
|
-
.max(max)
|
|
67
|
+
.min(min, message(field, [`Must be at least: ${min} character`]))
|
|
68
|
+
.max(max, message(field, [`Must not exceed: ${max} characters`]))
|
|
69
69
|
.regex(
|
|
70
70
|
/^[\p{L}0-9 .,!?'"():;-]+$/u,
|
|
71
71
|
message(field, ["Contains invalid characters."]),
|
|
@@ -77,7 +77,7 @@ const zText = function (field, { max, min }) {
|
|
|
77
77
|
const zMedia = function (field, root) {
|
|
78
78
|
return z
|
|
79
79
|
.string()
|
|
80
|
-
.min(1)
|
|
80
|
+
.min(1, message(field, ["Must be defined."]))
|
|
81
81
|
.refine(
|
|
82
82
|
(file) => isRelativeCheck(root, file),
|
|
83
83
|
message(field, ["Must be a relative path."]),
|
|
@@ -96,33 +96,48 @@ const zMedia = function (field, root) {
|
|
|
96
96
|
// [function]
|
|
97
97
|
|
|
98
98
|
const zPng = function (field, root, opts) {
|
|
99
|
-
return zMedia(field, root).
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
return zMedia(field, root).superRefine((file, ctx) => {
|
|
100
|
+
const issues = imageCheck(root, file, { ...opts, type: cfgimage[".png"] });
|
|
101
|
+
if (issues.length) {
|
|
102
|
+
ctx.addIssue({
|
|
103
|
+
code: "custom",
|
|
104
|
+
...message(field, ["Invalid PNG.", ...issues]),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
103
108
|
};
|
|
104
109
|
|
|
105
110
|
// [function]
|
|
106
111
|
|
|
107
112
|
const zSvg = function (field, root, opts) {
|
|
108
|
-
return zMedia(field, root).
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
113
|
+
return zMedia(field, root).superRefine((file, ctx) => {
|
|
114
|
+
const issues = imageCheck(root, file, { ...opts, type: cfgimage[".svg"] });
|
|
115
|
+
if (issues.length) {
|
|
116
|
+
ctx.addIssue({
|
|
117
|
+
code: "custom",
|
|
118
|
+
...message(field, ["Invalid SVG.", ...issues]),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
});
|
|
112
122
|
};
|
|
113
123
|
|
|
114
124
|
// [function]
|
|
115
125
|
|
|
116
126
|
const zMp4 = function (field, root, opts) {
|
|
117
|
-
return zMedia(field, root).
|
|
118
|
-
(file
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
127
|
+
return zMedia(field, root).superRefine((file, ctx) => {
|
|
128
|
+
const issues = videoCheck(root, file, {
|
|
129
|
+
maxDuration: 30,
|
|
130
|
+
minDuration: 3,
|
|
131
|
+
...opts,
|
|
132
|
+
type: cfgvideo[".mp4"],
|
|
133
|
+
});
|
|
134
|
+
if (issues.length) {
|
|
135
|
+
ctx.addIssue({
|
|
136
|
+
code: "custom",
|
|
137
|
+
...message(field, ["Invalid MP4.", ...issues]),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
126
141
|
};
|
|
127
142
|
|
|
128
143
|
// [function]
|
|
@@ -184,7 +199,7 @@ const zBannerVideo = function (root) {
|
|
|
184
199
|
|
|
185
200
|
const zBio = function () {
|
|
186
201
|
const field = "bio";
|
|
187
|
-
return z.optional(zText(field, { max:
|
|
202
|
+
return z.optional(zText(field, { max: 30 * 5, min: 1 }));
|
|
188
203
|
};
|
|
189
204
|
|
|
190
205
|
// [function]
|
|
@@ -222,8 +237,8 @@ const zDescription = function () {
|
|
|
222
237
|
return z.optional(
|
|
223
238
|
z
|
|
224
239
|
.string()
|
|
225
|
-
.min(1)
|
|
226
|
-
.max(
|
|
240
|
+
.min(1, message(field, ["Must be at least: 1 character"]))
|
|
241
|
+
.max(3000, message(field, ["Must not exceed: 3000 characters"]))
|
|
227
242
|
.refine(
|
|
228
243
|
(str) =>
|
|
229
244
|
str ===
|
|
@@ -243,22 +258,58 @@ const zGallery = function (root) {
|
|
|
243
258
|
return z.optional(
|
|
244
259
|
z
|
|
245
260
|
.array(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
261
|
+
zMedia(field, root).superRefine((file, ctx) => {
|
|
262
|
+
if (file.endsWith(".png")) {
|
|
263
|
+
const issues = imageCheck(root, file, {
|
|
264
|
+
maxSize: size.mb(2),
|
|
265
|
+
type: cfgimage[".png"],
|
|
266
|
+
});
|
|
267
|
+
if (issues.length) {
|
|
268
|
+
ctx.addIssue({
|
|
269
|
+
code: "custom",
|
|
270
|
+
...message(field, [`Invalid PNG: ${file}`, ...issues]),
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
} else if (file.endsWith(".svg")) {
|
|
274
|
+
const issues = imageCheck(root, file, {
|
|
275
|
+
maxSize: size.mb(1),
|
|
276
|
+
type: cfgimage[".svg"],
|
|
277
|
+
});
|
|
278
|
+
if (issues.length) {
|
|
279
|
+
ctx.addIssue({
|
|
280
|
+
code: "custom",
|
|
281
|
+
...message(field, [`Invalid SVG: ${file}`, ...issues]),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
} else if (file.endsWith(".mp4")) {
|
|
285
|
+
const issues = videoCheck(root, file, {
|
|
286
|
+
maxDuration: 30,
|
|
287
|
+
maxSize: size.mb(15),
|
|
288
|
+
minDuration: 3,
|
|
289
|
+
type: cfgvideo[".mp4"],
|
|
290
|
+
});
|
|
291
|
+
if (issues.length) {
|
|
292
|
+
ctx.addIssue({
|
|
293
|
+
code: "custom",
|
|
294
|
+
...message(field, [`Invalid MP4: ${file}`, ...issues]),
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}),
|
|
251
299
|
)
|
|
252
|
-
.
|
|
253
|
-
.max(12),
|
|
300
|
+
.max(12, message(field, ["Must not exceed: 12 elements"])),
|
|
254
301
|
);
|
|
255
302
|
};
|
|
256
303
|
|
|
257
304
|
// [function]
|
|
258
305
|
|
|
259
306
|
const zGenres = function () {
|
|
260
|
-
|
|
261
|
-
return z.optional(
|
|
307
|
+
const field = "genres";
|
|
308
|
+
return z.optional(
|
|
309
|
+
z
|
|
310
|
+
.array(z.enum(cfggenre))
|
|
311
|
+
.max(3, message(field, ["Must not exceed: 3 elements"])),
|
|
312
|
+
);
|
|
262
313
|
};
|
|
263
314
|
|
|
264
315
|
// [function]
|
|
@@ -324,8 +375,12 @@ const zId = function () {
|
|
|
324
375
|
// [function]
|
|
325
376
|
|
|
326
377
|
const zInputs = function () {
|
|
327
|
-
|
|
328
|
-
return z.optional(
|
|
378
|
+
const field = "inputs";
|
|
379
|
+
return z.optional(
|
|
380
|
+
z
|
|
381
|
+
.array(z.enum(cfginput))
|
|
382
|
+
.max(3, message(field, ["Must not exceed: 3 elements"])),
|
|
383
|
+
);
|
|
329
384
|
};
|
|
330
385
|
|
|
331
386
|
// [function]
|
|
@@ -366,29 +421,34 @@ const zPosterVideo = function (root) {
|
|
|
366
421
|
// [function]
|
|
367
422
|
|
|
368
423
|
const zPrice = function () {
|
|
369
|
-
|
|
370
|
-
return z.optional(
|
|
424
|
+
const field = "price";
|
|
425
|
+
return z.optional(
|
|
426
|
+
z
|
|
427
|
+
.int()
|
|
428
|
+
.min(0, message(field, ["Must not be below: 0"]))
|
|
429
|
+
.max(25, message(field, ["Must not be above: 25"])),
|
|
430
|
+
);
|
|
371
431
|
};
|
|
372
432
|
|
|
373
433
|
// [function]
|
|
374
434
|
|
|
375
435
|
const zShortTitle = function () {
|
|
376
436
|
const field = "short_title";
|
|
377
|
-
return z.optional(zText(field, { max:
|
|
437
|
+
return z.optional(zText(field, { max: 30 / 2, min: 1 }));
|
|
378
438
|
};
|
|
379
439
|
|
|
380
440
|
// [function]
|
|
381
441
|
|
|
382
442
|
const zTagline = function () {
|
|
383
443
|
const field = "tagline";
|
|
384
|
-
return z.optional(zText(field, { max:
|
|
444
|
+
return z.optional(zText(field, { max: 30 * 1, min: 1 }));
|
|
385
445
|
};
|
|
386
446
|
|
|
387
447
|
// [function]
|
|
388
448
|
|
|
389
449
|
const zTitle = function () {
|
|
390
450
|
const field = "title";
|
|
391
|
-
return z.optional(zText(field, { max:
|
|
451
|
+
return z.optional(zText(field, { max: 30 * 1, min: 1 }));
|
|
392
452
|
};
|
|
393
453
|
|
|
394
454
|
// [function]
|
|
@@ -397,7 +457,7 @@ const zTrailer = function () {
|
|
|
397
457
|
const field = "trailer";
|
|
398
458
|
return z
|
|
399
459
|
.string()
|
|
400
|
-
.max(255)
|
|
460
|
+
.max(255, message(field, ["Must not exceed: 255 characters"]))
|
|
401
461
|
.refine(
|
|
402
462
|
(url) =>
|
|
403
463
|
zVimeo().safeParse(url).success || zYouTube().safeParse(url).success,
|
package/src/schema/workflow.js
CHANGED
|
@@ -29,7 +29,7 @@ const MEDIA = `.${HANDLE}`;
|
|
|
29
29
|
// [function]
|
|
30
30
|
|
|
31
31
|
const reference = function (field) {
|
|
32
|
-
return chalk.cyan.underline(`${cfgurl.MANIFEST}#
|
|
32
|
+
return chalk.cyan.underline(`${cfgurl.MANIFEST}#game.${field}`);
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
// [function]
|
|
@@ -64,11 +64,11 @@ const zDeployDir = function (root, { build }) {
|
|
|
64
64
|
)
|
|
65
65
|
.refine(
|
|
66
66
|
(file) => isOutCheck(root, file),
|
|
67
|
-
message(field, ["Must be within the project
|
|
67
|
+
message(field, ["Must be within the project."]),
|
|
68
68
|
)
|
|
69
69
|
.refine(
|
|
70
70
|
(file) => isReservedCheck(root, file, MEDIA),
|
|
71
|
-
message(field, [`Must not contain ${MEDIA}.`]),
|
|
71
|
+
message(field, [`Must not contain ${MEDIA} in path.`]),
|
|
72
72
|
)
|
|
73
73
|
.refine(
|
|
74
74
|
(file) => build || existsCheck(root, file),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const phrase = require("../phrase");
|
|
6
|
+
|
|
7
|
+
// [function]
|
|
8
|
+
|
|
9
|
+
const formatBytes = function (bytes) {
|
|
10
|
+
switch (true) {
|
|
11
|
+
case bytes < 1024:
|
|
12
|
+
return phrase.sizeB(bytes);
|
|
13
|
+
case bytes < 1024 ** 2:
|
|
14
|
+
return phrase.sizeKb((bytes / 1024).toFixed(1));
|
|
15
|
+
case bytes < 1024 ** 3:
|
|
16
|
+
return phrase.sizeMb((bytes / 1024 / 1024).toFixed(1));
|
|
17
|
+
default:
|
|
18
|
+
return phrase.sizeGb((bytes / 1024 / 1024 / 1024).toFixed(1));
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// [export]
|
|
23
|
+
|
|
24
|
+
module.exports = { formatBytes };
|
package/src/util/http.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const phrase = require("../phrase");
|
|
6
|
+
|
|
3
7
|
// [class]
|
|
4
8
|
|
|
5
9
|
const HttpError = class extends Error {
|
|
@@ -10,7 +14,7 @@ const HttpError = class extends Error {
|
|
|
10
14
|
super(message);
|
|
11
15
|
this.status = status;
|
|
12
16
|
this.name = title;
|
|
13
|
-
this.message =
|
|
17
|
+
this.message = phrase.httpError(this.name, this.status);
|
|
14
18
|
}
|
|
15
19
|
};
|
|
16
20
|
|
package/src/util/image.js
CHANGED
|
@@ -12,6 +12,7 @@ const imageSize = require("image-size").imageSize;
|
|
|
12
12
|
// [import]
|
|
13
13
|
|
|
14
14
|
const cfgimage = require("../config/image");
|
|
15
|
+
const phrase = require("../phrase");
|
|
15
16
|
|
|
16
17
|
// [use]
|
|
17
18
|
|
|
@@ -50,29 +51,29 @@ const checkSize = function (file, maxSize) {
|
|
|
50
51
|
|
|
51
52
|
const checkPng = function (file, { aspect, maxSize, minHeight, minWidth }) {
|
|
52
53
|
if (!checkSize(file, maxSize)) {
|
|
53
|
-
return
|
|
54
|
+
return [phrase.imageSizeMax(maxSize)];
|
|
54
55
|
}
|
|
55
56
|
const buffer = readFileSync(file);
|
|
56
57
|
const { height, width } = imageSize(buffer);
|
|
57
58
|
if (minWidth && width < minWidth) {
|
|
58
|
-
return
|
|
59
|
+
return [phrase.imageWidthMin(minWidth)];
|
|
59
60
|
}
|
|
60
61
|
if (minHeight && height < minHeight) {
|
|
61
|
-
return
|
|
62
|
+
return [phrase.imageHeightMin(minHeight)];
|
|
62
63
|
}
|
|
63
64
|
if (!checkAspect(width, height, aspect)) {
|
|
64
|
-
return
|
|
65
|
+
return [phrase.imageAspect(aspect)];
|
|
65
66
|
}
|
|
66
|
-
return
|
|
67
|
+
return [];
|
|
67
68
|
};
|
|
68
69
|
|
|
69
70
|
// [function]
|
|
70
71
|
|
|
71
72
|
const checkSvg = function (file, { maxSize }) {
|
|
72
73
|
if (!checkSize(file, maxSize)) {
|
|
73
|
-
return
|
|
74
|
+
return [phrase.imageSizeMax(maxSize)];
|
|
74
75
|
}
|
|
75
|
-
return
|
|
76
|
+
return [];
|
|
76
77
|
};
|
|
77
78
|
|
|
78
79
|
// [function]
|
|
@@ -85,7 +86,7 @@ const check = function (file, { type, ...opts }) {
|
|
|
85
86
|
const checkImage = checks[type];
|
|
86
87
|
return checkImage && cfgimage[extname(file)] === type
|
|
87
88
|
? checkImage(file, opts)
|
|
88
|
-
:
|
|
89
|
+
: [phrase.imageUnsupported()];
|
|
89
90
|
};
|
|
90
91
|
|
|
91
92
|
// [export]
|
package/src/util/progress.js
CHANGED
|
@@ -4,8 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
const cliProgress = require("cli-progress");
|
|
6
6
|
|
|
7
|
+
// [import]
|
|
8
|
+
|
|
9
|
+
const bytes = require("./bytes");
|
|
10
|
+
|
|
7
11
|
// [use]
|
|
8
12
|
|
|
13
|
+
const formatBytes = bytes.formatBytes;
|
|
9
14
|
const Presets = cliProgress.Presets;
|
|
10
15
|
const SingleBar = cliProgress.SingleBar;
|
|
11
16
|
|
|
@@ -15,21 +20,6 @@ const FORMAT = "[{bar}] {percentage}% | {value}/{total}";
|
|
|
15
20
|
|
|
16
21
|
// [function]
|
|
17
22
|
|
|
18
|
-
const formatBytes = function (bytes) {
|
|
19
|
-
switch (true) {
|
|
20
|
-
case bytes < 1000:
|
|
21
|
-
return `${bytes} B`;
|
|
22
|
-
case bytes < 1000 * 1000:
|
|
23
|
-
return `${(bytes / 1000).toFixed(1)} KB`;
|
|
24
|
-
case bytes < 1000 * 1000 * 1000:
|
|
25
|
-
return `${(bytes / 1000 / 1000).toFixed(1)} MB`;
|
|
26
|
-
default:
|
|
27
|
-
return `${(bytes / 1000 / 1000 / 1000).toFixed(1)} GB`;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// [function]
|
|
32
|
-
|
|
33
23
|
const formatValue = function (value, opts, type) {
|
|
34
24
|
if (type === "percentage") {
|
|
35
25
|
return value;
|
package/src/util/schema.js
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
|
|
7
|
+
// [function]
|
|
8
|
+
|
|
9
|
+
const dereference = function (issues) {
|
|
10
|
+
const references = new Set();
|
|
11
|
+
const output = issues.map((issue) =>
|
|
12
|
+
issue
|
|
13
|
+
.split("\n")
|
|
14
|
+
.filter((line) => {
|
|
15
|
+
if (/https?:\/\//u.test(line)) {
|
|
16
|
+
references.add(line.trim());
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
})
|
|
21
|
+
.join("\n"),
|
|
22
|
+
);
|
|
23
|
+
return [output, [...references]];
|
|
24
|
+
};
|
|
25
|
+
|
|
3
26
|
// [function]
|
|
4
27
|
|
|
5
28
|
const format = function (name, { issues }) {
|
|
6
29
|
return issues.map(
|
|
7
|
-
({ message, path }) =>
|
|
30
|
+
({ message, path }) =>
|
|
31
|
+
`${chalk.cyan(`${name}.${path.join(".") || "value"}`)}: ${message}`,
|
|
8
32
|
);
|
|
9
33
|
};
|
|
10
34
|
|
|
@@ -22,4 +46,4 @@ const validator = function (name, schema) {
|
|
|
22
46
|
|
|
23
47
|
// [export]
|
|
24
48
|
|
|
25
|
-
module.exports = { validator };
|
|
49
|
+
module.exports = { dereference, validator };
|
package/src/util/video.js
CHANGED
|
@@ -89,31 +89,34 @@ const readMp4 = function (file) {
|
|
|
89
89
|
|
|
90
90
|
const checkMp4 = function (
|
|
91
91
|
file,
|
|
92
|
-
{ aspect, maxDuration, maxSize, minHeight, minWidth },
|
|
92
|
+
{ aspect, maxDuration, maxSize, minDuration, minHeight, minWidth },
|
|
93
93
|
) {
|
|
94
94
|
if (!checkSize(file, maxSize)) {
|
|
95
|
-
return
|
|
95
|
+
return [phrase.videoSizeMax(maxSize)];
|
|
96
96
|
}
|
|
97
97
|
let video = null;
|
|
98
98
|
try {
|
|
99
99
|
video = readMp4(file);
|
|
100
100
|
} catch {
|
|
101
|
-
return
|
|
101
|
+
return [phrase.videoInvalid()];
|
|
102
102
|
}
|
|
103
103
|
const { duration, height, width } = video;
|
|
104
104
|
if (minWidth && width < minWidth) {
|
|
105
|
-
return
|
|
105
|
+
return [phrase.videoWidthMin(minWidth)];
|
|
106
106
|
}
|
|
107
107
|
if (minHeight && height < minHeight) {
|
|
108
|
-
return
|
|
108
|
+
return [phrase.videoHeightMin(minHeight)];
|
|
109
|
+
}
|
|
110
|
+
if (minDuration && duration < minDuration) {
|
|
111
|
+
return [phrase.videoDurationMin(minDuration)];
|
|
109
112
|
}
|
|
110
113
|
if (maxDuration && duration > maxDuration) {
|
|
111
|
-
return
|
|
114
|
+
return [phrase.videoDurationMax(maxDuration)];
|
|
112
115
|
}
|
|
113
116
|
if (!checkAspect(width, height, aspect)) {
|
|
114
|
-
return
|
|
117
|
+
return [phrase.videoAspect(aspect)];
|
|
115
118
|
}
|
|
116
|
-
return
|
|
119
|
+
return [];
|
|
117
120
|
};
|
|
118
121
|
|
|
119
122
|
// [function]
|
|
@@ -125,7 +128,7 @@ const check = function (file, { type, ...opts }) {
|
|
|
125
128
|
const checkVideo = checks[type];
|
|
126
129
|
return checkVideo && cfgvideo[extname(file)] === type
|
|
127
130
|
? checkVideo(file, opts)
|
|
128
|
-
:
|
|
131
|
+
: [phrase.videoUnsupported()];
|
|
129
132
|
};
|
|
130
133
|
|
|
131
134
|
// [export]
|
package/src/prompt/template.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
// [import]
|
|
4
|
-
|
|
5
|
-
const cfgproduct = require("../config/product");
|
|
6
|
-
|
|
7
|
-
// [declare]
|
|
8
|
-
|
|
9
|
-
const HANDLE = cfgproduct.handle;
|
|
10
|
-
const STARTER = `${HANDLE}/starter`;
|
|
11
|
-
|
|
12
|
-
// [export]
|
|
13
|
-
|
|
14
|
-
module.exports = {
|
|
15
|
-
select: {
|
|
16
|
-
choices: [
|
|
17
|
-
{
|
|
18
|
-
description: "Blank JavaScript starter.",
|
|
19
|
-
name: "Blank",
|
|
20
|
-
value: STARTER,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
description: "Three.js starter.",
|
|
24
|
-
name: "Three.js",
|
|
25
|
-
value: `${STARTER}-threejs`,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
description: "Phaser starter.",
|
|
29
|
-
name: "Phaser",
|
|
30
|
-
value: `${STARTER}-phaser`,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
description: "PixiJS starter.",
|
|
34
|
-
name: "PixiJS",
|
|
35
|
-
value: `${STARTER}-pixijs`,
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
description: "Babylon.js starter.",
|
|
39
|
-
name: "Babylon.js",
|
|
40
|
-
value: `${STARTER}-babylonjs`,
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
default: STARTER,
|
|
44
|
-
message: "Template",
|
|
45
|
-
},
|
|
46
|
-
};
|