arcadible 0.1.4 → 0.1.6
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 +4 -5
- package/bin/arc-init.js +13 -13
- package/bin/arc-inspect.js +3 -3
- package/bin/arc-login.js +2 -1
- package/bin/arc-pack.js +5 -5
- package/bin/arc-validate.js +7 -10
- package/bin/arc-whoami.js +1 -1
- package/package.json +1 -1
- package/src/action/deploy-git/git.js +6 -6
- package/src/action/deploy-git/tool.js +2 -2
- package/src/action/init/tool.js +5 -3
- package/src/action/inspect/tool.js +1 -1
- package/src/action/pack/tool.js +3 -3
- package/src/action/validate/tool.js +1 -1
- package/src/config/workflow.js +1 -1
- package/src/parser/manifest.js +2 -2
- package/src/parser/media.js +6 -6
- package/src/parser/pkg.js +12 -8
- package/src/parser/project.js +9 -8
- package/src/parser/readme.js +4 -4
- package/src/prompt/{starter.js → template.js} +6 -6
- package/src/schema/check/game.js +67 -0
- package/src/schema/check/workflow.js +47 -0
- package/src/schema/game.js +193 -65
- package/src/schema/workflow.js +29 -59
- package/src/user.js +2 -2
- package/src/util/dom.js +3 -3
- package/src/util/image.js +84 -0
- package/src/util/log.js +4 -4
- package/src/util/objs.js +11 -11
- package/src/util/output.js +3 -3
- package/src/util/schema.js +6 -6
- package/src/util/strs.js +11 -1
- package/src/util/video.js +122 -0
- package/src/util/zip.js +2 -2
package/src/util/dom.js
CHANGED
|
@@ -7,12 +7,12 @@ const jsdom = require("jsdom");
|
|
|
7
7
|
|
|
8
8
|
// [use]
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const JSDOM = jsdom.JSDOM;
|
|
11
11
|
|
|
12
12
|
// [function]
|
|
13
13
|
|
|
14
14
|
const sanitize = function (str, cfg) {
|
|
15
|
-
const dom = dompurify(new
|
|
15
|
+
const dom = dompurify(new JSDOM().window);
|
|
16
16
|
if (cfg) {
|
|
17
17
|
return dom.sanitize(str, {
|
|
18
18
|
ALLOWED_ATTR: cfg.ALLOWED_ATTR,
|
|
@@ -24,4 +24,4 @@ const sanitize = function (str, cfg) {
|
|
|
24
24
|
|
|
25
25
|
// [export]
|
|
26
26
|
|
|
27
|
-
module.exports = { DOM, sanitize };
|
|
27
|
+
module.exports = { DOM: JSDOM, sanitize };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const fs = require("fs-extra");
|
|
6
|
+
const imageSize = require("image-size").imageSize;
|
|
7
|
+
|
|
8
|
+
// [use]
|
|
9
|
+
|
|
10
|
+
const readFileSync = fs.readFileSync; // eslint-disable-line no-sync
|
|
11
|
+
const statSync = fs.statSync; // eslint-disable-line no-sync
|
|
12
|
+
|
|
13
|
+
// [function]
|
|
14
|
+
|
|
15
|
+
const checkAspect = function (width, height, aspect) {
|
|
16
|
+
if (!aspect) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
const parts = aspect.split(":");
|
|
20
|
+
if (parts.length !== 2) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const aspectWidth = Number(parts[0]);
|
|
24
|
+
const aspectHeight = Number(parts[1]);
|
|
25
|
+
if (!aspectWidth || !aspectHeight) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return width * aspectHeight === height * aspectWidth;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// [function]
|
|
32
|
+
|
|
33
|
+
const checkSize = function (file, maxSize) {
|
|
34
|
+
if (!maxSize) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return statSync(file).size <= maxSize;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// [function]
|
|
41
|
+
|
|
42
|
+
const checkPng = function (file, { aspect, maxSize, minHeight, minWidth }) {
|
|
43
|
+
if (!checkSize(file, maxSize)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const buffer = readFileSync(file);
|
|
47
|
+
const { height, width } = imageSize(buffer);
|
|
48
|
+
if (minWidth && width < minWidth) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if (minHeight && height < minHeight) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (!checkAspect(width, height, aspect)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// [function]
|
|
61
|
+
|
|
62
|
+
const checkSvg = function (file, { maxSize }) {
|
|
63
|
+
if (!checkSize(file, maxSize)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// [function]
|
|
70
|
+
|
|
71
|
+
const check = function (file, { type, ...opts }) {
|
|
72
|
+
switch (type) {
|
|
73
|
+
case "image/png":
|
|
74
|
+
return checkPng(file, opts);
|
|
75
|
+
case "image/svg+xml":
|
|
76
|
+
return checkSvg(file, opts);
|
|
77
|
+
default:
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// [export]
|
|
83
|
+
|
|
84
|
+
module.exports = { check };
|
package/src/util/log.js
CHANGED
|
@@ -73,25 +73,25 @@ const pdnl = function (message) {
|
|
|
73
73
|
// [function]
|
|
74
74
|
|
|
75
75
|
const hw = function (message) {
|
|
76
|
-
log(console.
|
|
76
|
+
log(console.warn, message, { bold: true, color: "yellow" });
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
// [function]
|
|
80
80
|
|
|
81
81
|
const hwnl = function (message) {
|
|
82
|
-
log(console.
|
|
82
|
+
log(console.warn, message, { bold: true, color: "yellow", nl: true });
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
// [function]
|
|
86
86
|
|
|
87
87
|
const pw = function (message) {
|
|
88
|
-
log(console.
|
|
88
|
+
log(console.warn, message, { color: "yellow" });
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
// [function]
|
|
92
92
|
|
|
93
93
|
const pwnl = function (message) {
|
|
94
|
-
log(console.
|
|
94
|
+
log(console.warn, message, { color: "yellow", nl: true });
|
|
95
95
|
};
|
|
96
96
|
|
|
97
97
|
// [function]
|
package/src/util/objs.js
CHANGED
|
@@ -6,33 +6,33 @@ const stringify = require("fast-json-stable-stringify");
|
|
|
6
6
|
|
|
7
7
|
// [function]
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const deepCompact = function (obj) {
|
|
10
10
|
/* eslint-disable no-undefined */
|
|
11
|
-
if (
|
|
11
|
+
if (obj === null || obj === undefined) {
|
|
12
12
|
return undefined;
|
|
13
13
|
}
|
|
14
|
-
if (Array.isArray(
|
|
15
|
-
const cleaned =
|
|
14
|
+
if (Array.isArray(obj)) {
|
|
15
|
+
const cleaned = obj.map(deepCompact).filter((v) => v !== undefined);
|
|
16
16
|
return cleaned.length ? cleaned : undefined;
|
|
17
17
|
}
|
|
18
|
-
if (typeof
|
|
18
|
+
if (typeof obj === "object") {
|
|
19
19
|
const cleaned = Object.fromEntries(
|
|
20
|
-
Object.entries(
|
|
21
|
-
.map(([k, v]) => [k,
|
|
20
|
+
Object.entries(obj)
|
|
21
|
+
.map(([k, v]) => [k, deepCompact(v)])
|
|
22
22
|
.filter(([, v]) => v !== undefined),
|
|
23
23
|
);
|
|
24
24
|
return Object.keys(cleaned).length ? cleaned : undefined;
|
|
25
25
|
}
|
|
26
|
-
return
|
|
26
|
+
return obj;
|
|
27
27
|
/* eslint-enable no-undefined */
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
// [function]
|
|
31
31
|
|
|
32
|
-
const
|
|
33
|
-
return JSON.parse(stringify(
|
|
32
|
+
const deepSort = function (obj) {
|
|
33
|
+
return JSON.parse(stringify(obj));
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
// [export]
|
|
37
37
|
|
|
38
|
-
module.exports = {
|
|
38
|
+
module.exports = { deepCompact, deepSort };
|
package/src/util/output.js
CHANGED
|
@@ -10,7 +10,7 @@ const objs = require("./objs");
|
|
|
10
10
|
|
|
11
11
|
// [use]
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const deepSort = objs.deepSort;
|
|
14
14
|
|
|
15
15
|
// [function]
|
|
16
16
|
|
|
@@ -21,7 +21,7 @@ const write = function (data) {
|
|
|
21
21
|
// [function]
|
|
22
22
|
|
|
23
23
|
const printJson = function (data) {
|
|
24
|
-
write(JSON.stringify(
|
|
24
|
+
write(JSON.stringify(deepSort(data), null, 2));
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
// [function]
|
|
@@ -33,7 +33,7 @@ const printToml = function (data, key = "value") {
|
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
try {
|
|
36
|
-
write(TOML.stringify(
|
|
36
|
+
write(TOML.stringify(deepSort(data)));
|
|
37
37
|
} catch (ex) {
|
|
38
38
|
write(TOML.stringify({ [field]: data }));
|
|
39
39
|
}
|
package/src/util/schema.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
// [function]
|
|
4
4
|
|
|
5
|
-
const format = function (name,
|
|
6
|
-
return
|
|
7
|
-
(
|
|
5
|
+
const format = function (name, { issues }) {
|
|
6
|
+
return issues.map(
|
|
7
|
+
({ message, path }) => `${name}.${path.join(".") || "value"}: ${message}`,
|
|
8
8
|
);
|
|
9
9
|
};
|
|
10
10
|
|
|
@@ -12,9 +12,9 @@ const format = function (name, error) {
|
|
|
12
12
|
|
|
13
13
|
const validator = function (name, schema) {
|
|
14
14
|
return (value, conf) => {
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
return { issues: format(name,
|
|
15
|
+
const { error, success } = schema(value, conf).safeParse(value);
|
|
16
|
+
if (!success) {
|
|
17
|
+
return { issues: format(name, error) };
|
|
18
18
|
}
|
|
19
19
|
return { issues: [] };
|
|
20
20
|
};
|
package/src/util/strs.js
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
// [function]
|
|
4
4
|
|
|
5
|
+
const indentLines = function (strs, spaces = 2) {
|
|
6
|
+
const pad = " ".repeat(spaces);
|
|
7
|
+
return strs
|
|
8
|
+
.split("\n")
|
|
9
|
+
.map((str) => pad + str)
|
|
10
|
+
.join("\n");
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// [function]
|
|
14
|
+
|
|
5
15
|
const stripLeadingInvisible = function (str) {
|
|
6
16
|
return String(str).replace(
|
|
7
17
|
// eslint-disable-next-line no-misleading-character-class
|
|
@@ -18,4 +28,4 @@ const trimWhitespace = function (str) {
|
|
|
18
28
|
|
|
19
29
|
// [export]
|
|
20
30
|
|
|
21
|
-
module.exports = { stripLeadingInvisible, trimWhitespace };
|
|
31
|
+
module.exports = { indentLines, stripLeadingInvisible, trimWhitespace };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// [import]
|
|
4
|
+
|
|
5
|
+
const createFile = require("mp4box").createFile;
|
|
6
|
+
const fs = require("fs-extra");
|
|
7
|
+
|
|
8
|
+
// [use]
|
|
9
|
+
|
|
10
|
+
const readFileSync = fs.readFileSync; // eslint-disable-line no-sync
|
|
11
|
+
const statSync = fs.statSync; // eslint-disable-line no-sync
|
|
12
|
+
|
|
13
|
+
// [function]
|
|
14
|
+
|
|
15
|
+
const checkAspect = function (width, height, aspect) {
|
|
16
|
+
if (!aspect) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
const parts = aspect.split(":");
|
|
20
|
+
if (parts.length !== 2) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const aspectWidth = Number(parts[0]);
|
|
24
|
+
const aspectHeight = Number(parts[1]);
|
|
25
|
+
if (!aspectWidth || !aspectHeight) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return width * aspectHeight === height * aspectWidth;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// [function]
|
|
32
|
+
|
|
33
|
+
const checkSize = function (file, maxSize) {
|
|
34
|
+
if (!maxSize) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return statSync(file).size <= maxSize;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// [function]
|
|
41
|
+
|
|
42
|
+
const readMp4 = function (file) {
|
|
43
|
+
const data = readFileSync(file);
|
|
44
|
+
const mp4 = createFile();
|
|
45
|
+
let error = null;
|
|
46
|
+
let video = null;
|
|
47
|
+
mp4.onReady = function (info) {
|
|
48
|
+
const track = info.tracks.find((t) => t.video);
|
|
49
|
+
if (!track || !track.video) {
|
|
50
|
+
error = new Error("No video track found.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
video = {
|
|
54
|
+
duration: info.duration / info.timescale,
|
|
55
|
+
height: track.video.height,
|
|
56
|
+
width: track.video.width,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
mp4.onError = function (mod, msg) {
|
|
60
|
+
error = new Error(`MP4Box(${mod}): ${msg}`);
|
|
61
|
+
};
|
|
62
|
+
const buffer = data.buffer.slice(
|
|
63
|
+
data.byteOffset,
|
|
64
|
+
data.byteOffset + data.byteLength,
|
|
65
|
+
);
|
|
66
|
+
buffer.fileStart = 0;
|
|
67
|
+
mp4.appendBuffer(buffer);
|
|
68
|
+
mp4.flush();
|
|
69
|
+
if (error) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
if (!video) {
|
|
73
|
+
throw new Error("MP4 metadata not available.");
|
|
74
|
+
}
|
|
75
|
+
return video;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// [function]
|
|
79
|
+
|
|
80
|
+
const checkMp4 = function (
|
|
81
|
+
file,
|
|
82
|
+
{ aspect, maxDuration, maxSize, minHeight, minWidth },
|
|
83
|
+
) {
|
|
84
|
+
if (!checkSize(file, maxSize)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
let video = null;
|
|
88
|
+
try {
|
|
89
|
+
video = readMp4(file);
|
|
90
|
+
} catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
const { duration, height, width } = video;
|
|
94
|
+
if (minWidth && width < minWidth) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (minHeight && height < minHeight) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
if (maxDuration && duration > maxDuration) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (!checkAspect(width, height, aspect)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// [function]
|
|
110
|
+
|
|
111
|
+
const check = function (file, { type, ...opts }) {
|
|
112
|
+
switch (type) {
|
|
113
|
+
case "video/mp4":
|
|
114
|
+
return checkMp4(file, opts);
|
|
115
|
+
default:
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// [export]
|
|
121
|
+
|
|
122
|
+
module.exports = { check };
|
package/src/util/zip.js
CHANGED
|
@@ -16,8 +16,8 @@ const objs = require("./objs");
|
|
|
16
16
|
// [use]
|
|
17
17
|
|
|
18
18
|
const createHash = crypto.createHash;
|
|
19
|
+
const deepSort = objs.deepSort;
|
|
19
20
|
const join = path.join;
|
|
20
|
-
const sortObjs = objs.sort;
|
|
21
21
|
|
|
22
22
|
// [class]
|
|
23
23
|
|
|
@@ -41,7 +41,7 @@ const Main = class {
|
|
|
41
41
|
addJson(name, value) {
|
|
42
42
|
const entry = join(this.prefix, name);
|
|
43
43
|
const content = Buffer.from(
|
|
44
|
-
JSON.stringify(
|
|
44
|
+
JSON.stringify(deepSort(value), null, 2),
|
|
45
45
|
"utf8",
|
|
46
46
|
);
|
|
47
47
|
this.zip.addFile(entry, content);
|