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
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
// [import]
|
|
12
|
+
|
|
13
|
+
const imageCheck = require("../../util/image").check;
|
|
14
|
+
const videoCheck = require("../../util/video").check;
|
|
15
|
+
|
|
16
|
+
// [use]
|
|
17
|
+
|
|
18
|
+
const isAbsolute = path.isAbsolute;
|
|
19
|
+
const join = path.join;
|
|
20
|
+
const pathExistsSync = fs.pathExistsSync; // eslint-disable-line no-sync
|
|
21
|
+
const relative = path.relative;
|
|
22
|
+
const resolve = path.resolve;
|
|
23
|
+
|
|
24
|
+
// [function]
|
|
25
|
+
|
|
26
|
+
const exists = function (root, target) {
|
|
27
|
+
return pathExistsSync(join(root, target));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// [function]
|
|
31
|
+
|
|
32
|
+
const image = function (root, target, opts) {
|
|
33
|
+
return imageCheck(join(root, target), opts);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// [function]
|
|
37
|
+
|
|
38
|
+
const isIn = function (root, target, parent) {
|
|
39
|
+
const parentRoot = resolve(root, parent);
|
|
40
|
+
const targetPath = resolve(root, target);
|
|
41
|
+
const rel = relative(parentRoot, targetPath);
|
|
42
|
+
return rel && !rel.startsWith("..") && !isAbsolute(rel);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// [function]
|
|
46
|
+
|
|
47
|
+
const isOut = function (root, target) {
|
|
48
|
+
const rootPath = resolve(root);
|
|
49
|
+
const targetPath = resolve(root, target);
|
|
50
|
+
return targetPath === rootPath || targetPath.startsWith(rootPath + path.sep);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// [function]
|
|
54
|
+
|
|
55
|
+
const isRelative = function (root, target) {
|
|
56
|
+
return !isAbsolute(target);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// [function]
|
|
60
|
+
|
|
61
|
+
const video = function (root, target, opts) {
|
|
62
|
+
return videoCheck(join(root, target), opts);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// [export]
|
|
66
|
+
|
|
67
|
+
module.exports = { exists, image, isIn, isOut, isRelative, video };
|
|
@@ -0,0 +1,47 @@
|
|
|
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 isAbsolute = path.isAbsolute;
|
|
14
|
+
const join = path.join;
|
|
15
|
+
const pathExistsSync = fs.pathExistsSync; // eslint-disable-line no-sync
|
|
16
|
+
const resolve = path.resolve;
|
|
17
|
+
|
|
18
|
+
// [function]
|
|
19
|
+
|
|
20
|
+
const exists = function (root, target) {
|
|
21
|
+
return pathExistsSync(join(root, target));
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// [function]
|
|
25
|
+
|
|
26
|
+
const isOut = function (root, target) {
|
|
27
|
+
const rootPath = resolve(root);
|
|
28
|
+
const targetPath = resolve(root, target);
|
|
29
|
+
return targetPath === rootPath || targetPath.startsWith(rootPath + path.sep);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// [function]
|
|
33
|
+
|
|
34
|
+
const isRelative = function (root, target) {
|
|
35
|
+
return !isAbsolute(target);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// [function]
|
|
39
|
+
|
|
40
|
+
const isReserved = function (root, target, parent) {
|
|
41
|
+
const targetPath = resolve(root, target);
|
|
42
|
+
return !targetPath.split(path.sep).includes(parent);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// [export]
|
|
46
|
+
|
|
47
|
+
module.exports = { exists, isOut, isRelative, isReserved };
|
package/src/schema/game.js
CHANGED
|
@@ -15,32 +15,35 @@ const cfginput = require("../config/input");
|
|
|
15
15
|
const cfgorientation = require("../config/orientation");
|
|
16
16
|
const cfgurl = require("../config/url");
|
|
17
17
|
const cfgvisibility = require("../config/visibility");
|
|
18
|
+
const check = require("./check/game");
|
|
18
19
|
const dom = require("../util/dom");
|
|
20
|
+
const strs = require("../util/strs");
|
|
19
21
|
|
|
20
22
|
// [use]
|
|
21
23
|
|
|
24
|
+
const existsCheck = check.exists;
|
|
25
|
+
const imageCheck = check.image;
|
|
26
|
+
const indentLines = strs.indentLines;
|
|
27
|
+
const isInCheck = check.isIn;
|
|
28
|
+
const isOutCheck = check.isOut;
|
|
29
|
+
const isRelativeCheck = check.isRelative;
|
|
22
30
|
const validSemver = semver.valid;
|
|
31
|
+
const videoCheck = check.video;
|
|
23
32
|
|
|
24
|
-
// [
|
|
33
|
+
// [declare]
|
|
25
34
|
|
|
26
|
-
const
|
|
27
|
-
return chalk.cyan.underline(`${cfgurl.MANIFEST}#${field}`);
|
|
28
|
-
};
|
|
35
|
+
const MEDIA = ".arcadible";
|
|
29
36
|
|
|
30
37
|
// [function]
|
|
31
38
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
return text
|
|
35
|
-
.split("\n")
|
|
36
|
-
.map((line) => pad + line)
|
|
37
|
-
.join("\n");
|
|
39
|
+
const reference = function (field) {
|
|
40
|
+
return chalk.cyan.underline(`${cfgurl.MANIFEST}#game.${field}`);
|
|
38
41
|
};
|
|
39
42
|
|
|
40
43
|
// [function]
|
|
41
44
|
|
|
42
45
|
const message = function (field, msg) {
|
|
43
|
-
return { message: [msg,
|
|
46
|
+
return { message: [msg, indentLines(reference(field))].join("\n") };
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
// [function]
|
|
@@ -58,20 +61,55 @@ const zText = function (field, { max, min }) {
|
|
|
58
61
|
|
|
59
62
|
// [function]
|
|
60
63
|
|
|
61
|
-
const
|
|
62
|
-
return z
|
|
64
|
+
const zMedia = function (field, root) {
|
|
65
|
+
return z
|
|
66
|
+
.string()
|
|
67
|
+
.min(1)
|
|
68
|
+
.refine(
|
|
69
|
+
(file) => isRelativeCheck(root, file),
|
|
70
|
+
message(field, "Must be a relative path."),
|
|
71
|
+
)
|
|
72
|
+
.refine(
|
|
73
|
+
(file) => isOutCheck(root, file),
|
|
74
|
+
message(field, "Must be within the project."),
|
|
75
|
+
)
|
|
76
|
+
.refine(
|
|
77
|
+
(file) => isInCheck(root, file, MEDIA),
|
|
78
|
+
message(field, `Must be within ${MEDIA}.`),
|
|
79
|
+
)
|
|
80
|
+
.refine((file) => existsCheck(root, file), message(field, "Must exist."));
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// [function]
|
|
84
|
+
|
|
85
|
+
const zPng = function (field, root, opts) {
|
|
86
|
+
return zMedia(field, root).refine(
|
|
87
|
+
(file) => imageCheck(root, file, { ...opts, type: "image/png" }),
|
|
88
|
+
message(field, "Invalid PNG."),
|
|
89
|
+
);
|
|
63
90
|
};
|
|
64
91
|
|
|
65
92
|
// [function]
|
|
66
93
|
|
|
67
|
-
const zSvg = function () {
|
|
68
|
-
return
|
|
94
|
+
const zSvg = function (field, root, opts) {
|
|
95
|
+
return zMedia(field, root).refine(
|
|
96
|
+
(file) => imageCheck(root, file, { ...opts, type: "image/svg+xml" }),
|
|
97
|
+
message(field, "Invalid SVG."),
|
|
98
|
+
);
|
|
69
99
|
};
|
|
70
100
|
|
|
71
101
|
// [function]
|
|
72
102
|
|
|
73
|
-
const zMp4 = function () {
|
|
74
|
-
return
|
|
103
|
+
const zMp4 = function (field, root, opts) {
|
|
104
|
+
return zMedia(field, root).refine(
|
|
105
|
+
(file) =>
|
|
106
|
+
videoCheck(root, file, {
|
|
107
|
+
maxDuration: 10,
|
|
108
|
+
...opts,
|
|
109
|
+
type: "video/mp4",
|
|
110
|
+
}),
|
|
111
|
+
message(field, "Invalid MP4."),
|
|
112
|
+
);
|
|
75
113
|
};
|
|
76
114
|
|
|
77
115
|
// [function]
|
|
@@ -97,49 +135,77 @@ const zYouTube = function () {
|
|
|
97
135
|
// [function]
|
|
98
136
|
|
|
99
137
|
const zAudience = function () {
|
|
100
|
-
// const field = "
|
|
138
|
+
// const field = "audience";
|
|
101
139
|
return z.optional(z.enum(cfgaudience));
|
|
102
140
|
};
|
|
103
141
|
|
|
104
142
|
// [function]
|
|
105
143
|
|
|
106
|
-
const zBanner = function () {
|
|
107
|
-
|
|
108
|
-
return z.optional(
|
|
144
|
+
const zBanner = function (root) {
|
|
145
|
+
const field = "banner";
|
|
146
|
+
return z.optional(
|
|
147
|
+
zPng(field, root, {
|
|
148
|
+
aspect: "2:1",
|
|
149
|
+
maxSize: 2 * 1024 * 1024,
|
|
150
|
+
minHeight: 512,
|
|
151
|
+
minWidth: 1024,
|
|
152
|
+
}),
|
|
153
|
+
);
|
|
109
154
|
};
|
|
110
155
|
|
|
111
156
|
// [function]
|
|
112
157
|
|
|
113
|
-
const zBannerVideo = function () {
|
|
114
|
-
|
|
115
|
-
return z.optional(
|
|
158
|
+
const zBannerVideo = function (root) {
|
|
159
|
+
const field = "banner_video";
|
|
160
|
+
return z.optional(
|
|
161
|
+
zMp4(field, root, {
|
|
162
|
+
aspect: "2:1",
|
|
163
|
+
maxSize: 5 * 1024 * 1024,
|
|
164
|
+
minHeight: 512,
|
|
165
|
+
minWidth: 1024,
|
|
166
|
+
}),
|
|
167
|
+
);
|
|
116
168
|
};
|
|
117
169
|
|
|
118
170
|
// [function]
|
|
119
171
|
|
|
120
172
|
const zBio = function () {
|
|
121
|
-
const field = "
|
|
173
|
+
const field = "bio";
|
|
122
174
|
return z.optional(zText(field, { max: 192, min: 1 }));
|
|
123
175
|
};
|
|
124
176
|
|
|
125
177
|
// [function]
|
|
126
178
|
|
|
127
|
-
const zCover = function () {
|
|
128
|
-
|
|
129
|
-
return z.optional(
|
|
179
|
+
const zCover = function (root) {
|
|
180
|
+
const field = "cover";
|
|
181
|
+
return z.optional(
|
|
182
|
+
zPng(field, root, {
|
|
183
|
+
aspect: "3:2",
|
|
184
|
+
maxSize: 2 * 1024 * 1024,
|
|
185
|
+
minHeight: 512,
|
|
186
|
+
minWidth: 768,
|
|
187
|
+
}),
|
|
188
|
+
);
|
|
130
189
|
};
|
|
131
190
|
|
|
132
191
|
// [function]
|
|
133
192
|
|
|
134
|
-
const zCoverVideo = function () {
|
|
135
|
-
|
|
136
|
-
return z.optional(
|
|
193
|
+
const zCoverVideo = function (root) {
|
|
194
|
+
const field = "cover_video";
|
|
195
|
+
return z.optional(
|
|
196
|
+
zMp4(field, root, {
|
|
197
|
+
aspect: "3:2",
|
|
198
|
+
maxSize: 5 * 1024 * 1024,
|
|
199
|
+
minHeight: 512,
|
|
200
|
+
minWidth: 768,
|
|
201
|
+
}),
|
|
202
|
+
);
|
|
137
203
|
};
|
|
138
204
|
|
|
139
205
|
// [function]
|
|
140
206
|
|
|
141
207
|
const zDescription = function () {
|
|
142
|
-
const field = "
|
|
208
|
+
const field = "description";
|
|
143
209
|
return z.optional(
|
|
144
210
|
z
|
|
145
211
|
.string()
|
|
@@ -159,22 +225,32 @@ const zDescription = function () {
|
|
|
159
225
|
|
|
160
226
|
// [function]
|
|
161
227
|
|
|
162
|
-
const zGallery = function () {
|
|
163
|
-
|
|
164
|
-
return z.optional(
|
|
228
|
+
const zGallery = function (root) {
|
|
229
|
+
const field = "gallery";
|
|
230
|
+
return z.optional(
|
|
231
|
+
z
|
|
232
|
+
.array(
|
|
233
|
+
z.union([
|
|
234
|
+
zPng(field, root, { maxSize: 2 * 1024 * 1024 }),
|
|
235
|
+
zMp4(field, root, { maxSize: 5 * 1024 * 1024 }),
|
|
236
|
+
]),
|
|
237
|
+
)
|
|
238
|
+
.min(1)
|
|
239
|
+
.max(12),
|
|
240
|
+
);
|
|
165
241
|
};
|
|
166
242
|
|
|
167
243
|
// [function]
|
|
168
244
|
|
|
169
245
|
const zGenres = function () {
|
|
170
|
-
// const field = "
|
|
246
|
+
// const field = "genres";
|
|
171
247
|
return z.optional(z.array(z.enum(cfggenre)).max(3));
|
|
172
248
|
};
|
|
173
249
|
|
|
174
250
|
// [function]
|
|
175
251
|
|
|
176
252
|
const zHandle = function () {
|
|
177
|
-
const field = "
|
|
253
|
+
const field = "handle";
|
|
178
254
|
return z.optional(
|
|
179
255
|
z
|
|
180
256
|
.string()
|
|
@@ -187,85 +263,126 @@ const zHandle = function () {
|
|
|
187
263
|
|
|
188
264
|
// [function]
|
|
189
265
|
|
|
190
|
-
const zIcon = function () {
|
|
191
|
-
|
|
192
|
-
return z.optional(
|
|
266
|
+
const zIcon = function (root) {
|
|
267
|
+
const field = "icon";
|
|
268
|
+
return z.optional(
|
|
269
|
+
zPng(field, root, {
|
|
270
|
+
aspect: "1:1",
|
|
271
|
+
maxSize: 2 * 1024 * 1024,
|
|
272
|
+
minHeight: 512,
|
|
273
|
+
minWidth: 512,
|
|
274
|
+
}),
|
|
275
|
+
);
|
|
193
276
|
};
|
|
194
277
|
|
|
195
278
|
// [function]
|
|
196
279
|
|
|
197
|
-
const zIconVideo = function () {
|
|
198
|
-
|
|
199
|
-
return z.optional(
|
|
280
|
+
const zIconVideo = function (root) {
|
|
281
|
+
const field = "icon_video";
|
|
282
|
+
return z.optional(
|
|
283
|
+
zMp4(field, root, {
|
|
284
|
+
aspect: "1:1",
|
|
285
|
+
maxSize: 5 * 1024 * 1024,
|
|
286
|
+
minHeight: 512,
|
|
287
|
+
minWidth: 512,
|
|
288
|
+
}),
|
|
289
|
+
);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// [function]
|
|
293
|
+
|
|
294
|
+
const zId = function () {
|
|
295
|
+
const field = "id";
|
|
296
|
+
return z
|
|
297
|
+
.string()
|
|
298
|
+
.uuid(message(field, "Must be a valid UUID."))
|
|
299
|
+
.refine(
|
|
300
|
+
(value) => value === value.toLowerCase(),
|
|
301
|
+
message(field, "Must use lowercase characters."),
|
|
302
|
+
);
|
|
200
303
|
};
|
|
201
304
|
|
|
202
305
|
// [function]
|
|
203
306
|
|
|
204
307
|
const zInputs = function () {
|
|
205
|
-
// const field = "
|
|
308
|
+
// const field = "inputs";
|
|
206
309
|
return z.optional(z.array(z.enum(cfginput)).max(3));
|
|
207
310
|
};
|
|
208
311
|
|
|
209
312
|
// [function]
|
|
210
313
|
|
|
211
314
|
const zOrientation = function () {
|
|
212
|
-
// const field = "
|
|
315
|
+
// const field = "orientation";
|
|
213
316
|
return z.optional(z.enum(cfgorientation));
|
|
214
317
|
};
|
|
215
318
|
|
|
216
319
|
// [function]
|
|
217
320
|
|
|
218
|
-
const zPoster = function () {
|
|
219
|
-
|
|
220
|
-
return z.optional(
|
|
321
|
+
const zPoster = function (root) {
|
|
322
|
+
const field = "poster";
|
|
323
|
+
return z.optional(
|
|
324
|
+
zPng(field, root, {
|
|
325
|
+
aspect: "2:3",
|
|
326
|
+
maxSize: 2 * 1024 * 1024,
|
|
327
|
+
minHeight: 768,
|
|
328
|
+
minWidth: 512,
|
|
329
|
+
}),
|
|
330
|
+
);
|
|
221
331
|
};
|
|
222
332
|
|
|
223
333
|
// [function]
|
|
224
334
|
|
|
225
|
-
const zPosterVideo = function () {
|
|
226
|
-
|
|
227
|
-
return z.optional(
|
|
335
|
+
const zPosterVideo = function (root) {
|
|
336
|
+
const field = "poster_video";
|
|
337
|
+
return z.optional(
|
|
338
|
+
zMp4(field, root, {
|
|
339
|
+
aspect: "2:3",
|
|
340
|
+
maxSize: 5 * 1024 * 1024,
|
|
341
|
+
minHeight: 768,
|
|
342
|
+
minWidth: 512,
|
|
343
|
+
}),
|
|
344
|
+
);
|
|
228
345
|
};
|
|
229
346
|
|
|
230
347
|
// [function]
|
|
231
348
|
|
|
232
349
|
const zPrice = function () {
|
|
233
|
-
// const field = "
|
|
350
|
+
// const field = "price";
|
|
234
351
|
return z.optional(z.int().min(0).max(25));
|
|
235
352
|
};
|
|
236
353
|
|
|
237
354
|
// [function]
|
|
238
355
|
|
|
239
356
|
const zShortTitle = function () {
|
|
240
|
-
const field = "
|
|
357
|
+
const field = "short_title";
|
|
241
358
|
return z.optional(zText(field, { max: 16, min: 1 }));
|
|
242
359
|
};
|
|
243
360
|
|
|
244
361
|
// [function]
|
|
245
362
|
|
|
246
363
|
const zTagline = function () {
|
|
247
|
-
const field = "
|
|
364
|
+
const field = "tagline";
|
|
248
365
|
return z.optional(zText(field, { max: 96, min: 1 }));
|
|
249
366
|
};
|
|
250
367
|
|
|
251
368
|
// [function]
|
|
252
369
|
|
|
253
370
|
const zTitle = function () {
|
|
254
|
-
const field = "
|
|
371
|
+
const field = "title";
|
|
255
372
|
return z.optional(zText(field, { max: 64, min: 1 }));
|
|
256
373
|
};
|
|
257
374
|
|
|
258
375
|
// [function]
|
|
259
376
|
|
|
260
377
|
const zTrailer = function () {
|
|
261
|
-
const field = "
|
|
378
|
+
const field = "trailer";
|
|
262
379
|
return z
|
|
263
380
|
.string()
|
|
264
381
|
.max(255)
|
|
265
382
|
.refine(
|
|
266
383
|
(url) =>
|
|
267
384
|
zVimeo().safeParse(url).success || zYouTube().safeParse(url).success,
|
|
268
|
-
message(field, "Must be a YouTube (or
|
|
385
|
+
message(field, "Must be a YouTube (or Vimeo) URL."),
|
|
269
386
|
)
|
|
270
387
|
.optional();
|
|
271
388
|
};
|
|
@@ -273,7 +390,7 @@ const zTrailer = function () {
|
|
|
273
390
|
// [function]
|
|
274
391
|
|
|
275
392
|
const zVersion = function () {
|
|
276
|
-
const field = "
|
|
393
|
+
const field = "version";
|
|
277
394
|
return z
|
|
278
395
|
.string()
|
|
279
396
|
.refine(
|
|
@@ -285,22 +402,32 @@ const zVersion = function () {
|
|
|
285
402
|
// [function]
|
|
286
403
|
|
|
287
404
|
const zVisibility = function () {
|
|
288
|
-
// const field = "
|
|
405
|
+
// const field = "visibility";
|
|
289
406
|
return z.optional(z.enum(cfgvisibility));
|
|
290
407
|
};
|
|
291
408
|
|
|
292
409
|
// [function]
|
|
293
410
|
|
|
294
|
-
const zWordmark = function () {
|
|
295
|
-
|
|
296
|
-
return z.optional(
|
|
411
|
+
const zWordmark = function (root) {
|
|
412
|
+
const field = "wordmark";
|
|
413
|
+
return z.optional(
|
|
414
|
+
zSvg(field, root, {
|
|
415
|
+
aspect: "1:1",
|
|
416
|
+
maxSize: 512 * 1024,
|
|
417
|
+
}),
|
|
418
|
+
);
|
|
297
419
|
};
|
|
298
420
|
|
|
299
421
|
// [function]
|
|
300
422
|
|
|
301
|
-
const zWordmarkAnimated = function () {
|
|
302
|
-
|
|
303
|
-
return z.optional(
|
|
423
|
+
const zWordmarkAnimated = function (root) {
|
|
424
|
+
const field = "wordmark_animated";
|
|
425
|
+
return z.optional(
|
|
426
|
+
zSvg(field, root, {
|
|
427
|
+
aspect: "1:1",
|
|
428
|
+
maxSize: 1024 * 1024,
|
|
429
|
+
}),
|
|
430
|
+
);
|
|
304
431
|
};
|
|
305
432
|
|
|
306
433
|
// [function]
|
|
@@ -320,6 +447,7 @@ const main = function (value, { root }) {
|
|
|
320
447
|
handle: zHandle(),
|
|
321
448
|
icon: zIcon(root),
|
|
322
449
|
icon_video: zIconVideo(root),
|
|
450
|
+
id: zId(),
|
|
323
451
|
inputs: zInputs(),
|
|
324
452
|
orientation: zOrientation(),
|
|
325
453
|
poster: zPoster(root),
|
package/src/schema/workflow.js
CHANGED
|
@@ -2,24 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
// [import]
|
|
4
4
|
|
|
5
|
-
const path = require("node:path");
|
|
6
|
-
|
|
7
|
-
// [import]
|
|
8
|
-
|
|
9
5
|
const chalk = require("chalk");
|
|
10
|
-
const fs = require("fs-extra");
|
|
11
6
|
const z = require("zod");
|
|
12
7
|
|
|
13
8
|
// [import]
|
|
14
9
|
|
|
15
10
|
const cfgurl = require("../config/url");
|
|
11
|
+
const check = require("./check/workflow");
|
|
12
|
+
const strs = require("../util/strs");
|
|
16
13
|
|
|
17
14
|
// [use]
|
|
18
15
|
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
16
|
+
const existsCheck = check.exists;
|
|
17
|
+
const indentLines = strs.indentLines;
|
|
18
|
+
const isOutCheck = check.isOut;
|
|
19
|
+
const isRelativeCheck = check.isRelative;
|
|
20
|
+
const isReservedCheck = check.isReserved;
|
|
23
21
|
|
|
24
22
|
// [declare]
|
|
25
23
|
|
|
@@ -28,78 +26,50 @@ const MEDIA = ".arcadible";
|
|
|
28
26
|
// [function]
|
|
29
27
|
|
|
30
28
|
const reference = function (field) {
|
|
31
|
-
return chalk.cyan.underline(`${cfgurl.MANIFEST}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// [function]
|
|
35
|
-
|
|
36
|
-
const indent = function (text, spaces = 2) {
|
|
37
|
-
const pad = " ".repeat(spaces);
|
|
38
|
-
return text
|
|
39
|
-
.split("\n")
|
|
40
|
-
.map((line) => pad + line)
|
|
41
|
-
.join("\n");
|
|
29
|
+
return chalk.cyan.underline(`${cfgurl.MANIFEST}#workflow.${field}`);
|
|
42
30
|
};
|
|
43
31
|
|
|
44
32
|
// [function]
|
|
45
33
|
|
|
46
34
|
const message = function (field, msg) {
|
|
47
|
-
return { message: [msg,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// [function]
|
|
51
|
-
|
|
52
|
-
const isOutPath = function (root, dir) {
|
|
53
|
-
const resolvedRoot = resolve(root);
|
|
54
|
-
const resolvedTarget = resolve(root, dir);
|
|
55
|
-
const outside =
|
|
56
|
-
resolvedTarget !== resolvedRoot &&
|
|
57
|
-
!resolvedTarget.startsWith(resolvedRoot + path.sep);
|
|
58
|
-
return outside;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// [function]
|
|
62
|
-
|
|
63
|
-
const isMediaPath = function (root, dir) {
|
|
64
|
-
const resolvedTarget = resolve(root, dir);
|
|
65
|
-
const containsMedia = resolvedTarget.split(path.sep).includes(MEDIA);
|
|
66
|
-
return containsMedia;
|
|
35
|
+
return { message: [msg, indentLines(reference(field))].join("\n") };
|
|
67
36
|
};
|
|
68
37
|
|
|
69
38
|
// [function]
|
|
70
39
|
|
|
71
|
-
const
|
|
72
|
-
return
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// [function]
|
|
76
|
-
|
|
77
|
-
const zDeployDir = function (root, { skip_build: skipBuild }) {
|
|
78
|
-
const field = "workflow.deploy_dir";
|
|
79
|
-
let zz = z
|
|
40
|
+
const zMedia = function (field, root, { skipBuild }) {
|
|
41
|
+
return z
|
|
80
42
|
.string()
|
|
81
43
|
.min(1)
|
|
82
|
-
.refine((dir) => !isAbsolute(dir), message(field, "Must be relative."))
|
|
83
44
|
.refine(
|
|
84
|
-
(
|
|
45
|
+
(file) => isRelativeCheck(root, file),
|
|
46
|
+
message(field, "Must be a relative path."),
|
|
47
|
+
)
|
|
48
|
+
.refine(
|
|
49
|
+
(file) => isOutCheck(root, file),
|
|
85
50
|
message(field, "Must be within the project."),
|
|
86
51
|
)
|
|
87
52
|
.refine(
|
|
88
|
-
(
|
|
89
|
-
message(field,
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
(dir) => isRealPath(root, dir),
|
|
53
|
+
(file) => isReservedCheck(root, file, MEDIA),
|
|
54
|
+
message(field, `Must not contain ${MEDIA}.`),
|
|
55
|
+
)
|
|
56
|
+
.refine(
|
|
57
|
+
(file) => !skipBuild || existsCheck(root, file),
|
|
94
58
|
message(field, "Must exist."),
|
|
95
59
|
);
|
|
96
|
-
|
|
97
|
-
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// [function]
|
|
63
|
+
|
|
64
|
+
const zDeployDir = function (root, { skip_build: skipBuild }) {
|
|
65
|
+
const field = "deploy_dir";
|
|
66
|
+
return zMedia(field, root, { skipBuild });
|
|
98
67
|
};
|
|
99
68
|
|
|
100
69
|
// [function]
|
|
101
70
|
|
|
102
71
|
const zSkipBuild = function () {
|
|
72
|
+
// const field = "skip_build";
|
|
103
73
|
return z.boolean();
|
|
104
74
|
};
|
|
105
75
|
|
package/src/user.js
CHANGED
|
@@ -17,10 +17,10 @@ const os = require("./util/os");
|
|
|
17
17
|
// [use]
|
|
18
18
|
|
|
19
19
|
const configDir = os.configDir;
|
|
20
|
+
const deepCompact = objs.deepCompact;
|
|
20
21
|
const join = path.join;
|
|
21
22
|
const mkdir = fs.promises.mkdir;
|
|
22
23
|
const readFile = fs.promises.readFile;
|
|
23
|
-
const sortObjs = objs.sort;
|
|
24
24
|
const unlink = fs.promises.unlink;
|
|
25
25
|
const writeFile = fs.promises.writeFile;
|
|
26
26
|
|
|
@@ -45,7 +45,7 @@ const expired = function (session) {
|
|
|
45
45
|
const save = function (user) {
|
|
46
46
|
return mkdir(dir, { recursive: true })
|
|
47
47
|
.then(() =>
|
|
48
|
-
writeFile(file, JSON.stringify(
|
|
48
|
+
writeFile(file, JSON.stringify(deepCompact(user), null, 2), "utf8"),
|
|
49
49
|
)
|
|
50
50
|
.then(() => user);
|
|
51
51
|
};
|