arcadible 0.1.45 → 0.1.46

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.
Files changed (53) hide show
  1. package/bin/arc-build.js +9 -17
  2. package/bin/arc-deploy.js +20 -36
  3. package/bin/arc-init.js +6 -16
  4. package/bin/arc-inspect.js +3 -7
  5. package/bin/arc-login.js +5 -5
  6. package/bin/arc-logout.js +4 -8
  7. package/bin/arc-open.js +7 -20
  8. package/bin/arc-pack.js +4 -14
  9. package/bin/arc-play.js +6 -20
  10. package/bin/arc-validate.js +8 -17
  11. package/bin/arc-whoami.js +5 -9
  12. package/bin/arc.js +7 -2
  13. package/package.json +1 -1
  14. package/src/account.js +5 -5
  15. package/src/action/build/tool.js +8 -15
  16. package/src/action/deploy/tool-git.js +1 -6
  17. package/src/action/deploy/wait.js +5 -11
  18. package/src/action/init/manifest.js +9 -37
  19. package/src/action/login/flow.js +3 -10
  20. package/src/action/open/tool.js +2 -1
  21. package/src/action/pack/limits.js +4 -6
  22. package/src/action/pack/tool.js +6 -5
  23. package/src/action/play/tool.js +3 -3
  24. package/src/action/predeploy/ac.js +28 -43
  25. package/src/action/predeploy/git.js +4 -4
  26. package/src/action/predeploy/pm.js +1 -1
  27. package/src/action/predeploy/published.js +4 -4
  28. package/src/action/predeploy/tool-git.js +10 -10
  29. package/src/action/validate/unknown.js +11 -10
  30. package/src/config/file.js +23 -0
  31. package/src/config/limit.js +21 -0
  32. package/src/parser/env.js +0 -2
  33. package/src/parser/manifest.js +15 -13
  34. package/src/parser/media.js +9 -11
  35. package/src/parser/project.js +31 -9
  36. package/src/phrase.js +168 -39
  37. package/src/schema/game.js +65 -42
  38. package/src/schema/workflow.js +7 -8
  39. package/src/util/argv.js +27 -1
  40. package/src/util/command.js +18 -0
  41. package/src/util/delay.js +5 -21
  42. package/src/util/doc.js +4 -13
  43. package/src/util/links.js +17 -2
  44. package/src/util/media.js +2 -2
  45. package/src/util/objs.js +8 -1
  46. package/src/util/output.js +24 -2
  47. package/src/util/rc.js +2 -2
  48. package/src/util/request.js +1 -1
  49. package/src/util/s3.js +1 -1
  50. package/src/util/schema.js +9 -3
  51. package/src/util/uris.js +1 -1
  52. package/src/util/zip.js +2 -2
  53. package/src/config/doc.js +0 -7
@@ -14,13 +14,12 @@ const z = require("zod");
14
14
  const cfgai = require("../config/ai");
15
15
  const cfgaudience = require("../config/audience");
16
16
  const cfgcode = require("../config/code");
17
- const cfgdoc = require("../config/doc");
17
+ const cfgfile = require("../config/file");
18
18
  const cfggenre = require("../config/genre");
19
19
  const cfghtml = require("../config/html");
20
20
  const cfgimage = require("../config/image");
21
21
  const cfginput = require("../config/input");
22
22
  const cfgorientation = require("../config/orientation");
23
- const cfgproduct = require("../config/product");
24
23
  const cfgvideo = require("../config/video");
25
24
  const cfgvisibility = require("../config/visibility");
26
25
  const chars = require("../util/chars");
@@ -38,6 +37,7 @@ const cleanSemver = semver.clean;
38
37
  const docCheck = check.doc;
39
38
  const existsCheck = check.exists;
40
39
  const extname = path.extname;
40
+ const posixDirname = path.posix.dirname;
41
41
  const ISSUE = cfgcode.ISSUE;
42
42
  const imageCheck = check.image;
43
43
  const invalidChars = chars.invalid;
@@ -51,13 +51,12 @@ const videoCheck = check.video;
51
51
 
52
52
  // [declare]
53
53
 
54
- const HANDLE = cfgproduct.handle;
55
54
  const message = schemaMessage.messages("game");
56
55
 
57
56
  // [declare]
58
57
 
59
- const GALLERY = `.${HANDLE}/gallery`;
60
- const MEDIA = `.${HANDLE}`;
58
+ const GALLERY = cfgfile.GALLERY;
59
+ const MEDIA = cfgfile.MEDIA;
61
60
 
62
61
  // [declare]
63
62
 
@@ -144,15 +143,16 @@ const required = function (field, lines) {
144
143
  // [function]
145
144
 
146
145
  // a list of distinct values. Without a max, its length is up to the values.
147
- const zSet = function (field, schema, { max = Infinity, min }) {
148
- return z
149
- .array(schema)
150
- .min(min, atLeast(field, min, "element"))
151
- .max(max, message(field, [`Must not exceed: ${max} elements`]))
152
- .refine(
153
- (items) => new Set(items).size === items.length,
154
- message(field, ["Must not contain duplicate elements."], ISSUE.DUPLICATE),
155
- );
146
+ const zSet = function (field, schema, { max, min }) {
147
+ const list = z.array(schema).min(min, atLeast(field, min, "element"));
148
+ return (
149
+ max
150
+ ? list.max(max, message(field, [`Must not exceed: ${max} elements`]))
151
+ : list
152
+ ).refine(
153
+ (items) => new Set(items).size === items.length,
154
+ message(field, ["Must not contain duplicate elements."], ISSUE.DUPLICATE),
155
+ );
156
156
  };
157
157
 
158
158
  // [function]
@@ -174,11 +174,17 @@ const zSetBasefile = function (field, schema, { max, min }) {
174
174
 
175
175
  // [function]
176
176
 
177
+ // a string of `min` to `max` characters, counted as Arcadible counts them: a
178
+ // character outside the Basic Multilingual Plane, such as an emoji, is one,
179
+ // though JavaScript's length counts it as two.
177
180
  const zString = function (field, char, { max, min }) {
178
181
  return z
179
182
  .string()
180
183
  .min(min, { ...atLeast(field, min, "character"), abort: min === 1 })
181
- .max(max, message(field, [`Must not exceed: ${max} characters`]))
184
+ .refine(
185
+ (str) => [...str].length <= max,
186
+ message(field, [`Must not exceed: ${max} characters`], ISSUE.TOO_LONG),
187
+ )
182
188
  .superRefine((str, ctx) => {
183
189
  const invalid = invalidChars(str, char);
184
190
  if (invalid.length) {
@@ -197,8 +203,12 @@ const zString = function (field, char, { max, min }) {
197
203
 
198
204
  // [function]
199
205
 
206
+ // plain text, which can't be only spaces.
200
207
  const zText = function (field, opts) {
201
- return zString(field, /[\p{L}0-9 .,!?'"():;-]/u, opts);
208
+ return zString(field, /[\p{L}0-9 .,!?'"():;-]/u, opts).refine(
209
+ (str) => str.trim() !== "",
210
+ message(field, ["Must not be blank."], ISSUE.EMPTY),
211
+ );
202
212
  };
203
213
 
204
214
  // [function]
@@ -206,7 +216,7 @@ const zText = function (field, opts) {
206
216
  const zHtml = function (field, root, { max, min, ...opts }) {
207
217
  const char = /[\p{L}\p{M}\p{N}\p{P}\p{S}\p{Zs}\r\n]/u;
208
218
  return zString(field, char, { max, min }).superRefine((str, ctx) => {
209
- const issues = docCheck(root, str, { ...opts, type: cfgdoc[".html"] });
219
+ const issues = docCheck(root, str, opts);
210
220
  if (issues.length) {
211
221
  ctx.addIssue({
212
222
  code: "custom",
@@ -284,27 +294,34 @@ const zMp4 = function (field, root, opts) {
284
294
  const zPngMp4 = function (field, root, optsPng, optsMp4) {
285
295
  const pngSchema = zPng(field, root, optsPng);
286
296
  const mp4Schema = zMp4(field, root, optsMp4);
287
- return z.string().superRefine((file, ctx) => {
288
- const ext = extname(file);
289
- let schema = null;
290
- if (Object.hasOwn(cfgimage, ext)) {
291
- schema = pngSchema;
292
- }
293
- if (Object.hasOwn(cfgvideo, ext)) {
294
- schema = mp4Schema;
295
- }
296
- if (!schema) {
297
- ctx.addIssue({
298
- code: "custom",
299
- ...message(field, ["Must be a PNG or MP4 file."], ISSUE.MEDIA_INVALID),
300
- });
301
- return;
302
- }
303
- const result = schema.safeParse(file);
304
- if (!result.success) {
305
- result.error.issues.forEach((issue) => ctx.addIssue(issue));
306
- }
307
- });
297
+ return z
298
+ .string()
299
+ .min(1, { ...atLeast(field, 1), abort: true })
300
+ .superRefine((file, ctx) => {
301
+ const ext = extname(file);
302
+ let schema = null;
303
+ if (Object.hasOwn(cfgimage, ext)) {
304
+ schema = pngSchema;
305
+ }
306
+ if (Object.hasOwn(cfgvideo, ext)) {
307
+ schema = mp4Schema;
308
+ }
309
+ if (!schema) {
310
+ ctx.addIssue({
311
+ code: "custom",
312
+ ...message(
313
+ field,
314
+ ["Must be a PNG or MP4 file."],
315
+ ISSUE.MEDIA_INVALID,
316
+ ),
317
+ });
318
+ return;
319
+ }
320
+ const result = schema.safeParse(file);
321
+ if (!result.success) {
322
+ result.error.issues.forEach((issue) => ctx.addIssue(issue));
323
+ }
324
+ });
308
325
  };
309
326
 
310
327
  // [function]
@@ -383,6 +400,10 @@ const checkSrc = function (root, src, tag) {
383
400
  ) {
384
401
  return false;
385
402
  }
403
+ // the store page finds it by the gallery's path, exactly.
404
+ if (posixDirname(src) !== GALLERY) {
405
+ return phrase.docMediaPath(src, GALLERY);
406
+ }
386
407
  return existsCheck(root, src) || phrase.docMediaMissing(src);
387
408
  };
388
409
 
@@ -465,6 +486,7 @@ const zId = function () {
465
486
  .string(
466
487
  required(field, [`Run ${phrase.cmdInit()} to generate a new game ID.`]),
467
488
  )
489
+ .min(1, { ...atLeast(field, 1), abort: true })
468
490
  .uuid(message(field, ["Must be a valid UUID."]))
469
491
  .refine(
470
492
  (value) => value === value.toLowerCase(),
@@ -542,10 +564,11 @@ const zVersion = function () {
542
564
  .string(
543
565
  required(field, ["A version is required unless one can be derived."]),
544
566
  )
545
- .refine(
546
- (value) => validSemver(value) !== null,
547
- message(field, ["Must be valid semver."], ISSUE.VERSION_INVALID),
548
- )
567
+ .min(1, { ...atLeast(field, 1), abort: true })
568
+ .refine((value) => validSemver(value) !== null, {
569
+ ...message(field, ["Must be valid semver."], ISSUE.VERSION_INVALID),
570
+ abort: true,
571
+ })
549
572
  .refine(
550
573
  // lowercase too, since the database refuses an uppercase prerelease.
551
574
  (value) => cleanSemver(value) === value && value === value.toLowerCase(),
@@ -7,14 +7,17 @@ const z = require("zod");
7
7
  // [import]
8
8
 
9
9
  const cfgcode = require("../config/code");
10
+ const cfgfile = require("../config/file");
10
11
  const cfgproduct = require("../config/product");
11
12
  const check = require("./check/workflow");
13
+ const commands = require("../util/command");
12
14
  const phrase = require("../phrase");
13
15
  const schemaMessage = require("./message");
14
16
 
15
17
  // [use]
16
18
 
17
19
  const avoidsCheck = check.avoids;
20
+ const buildCommand = commands.buildCommand;
18
21
  const ISSUE = cfgcode.ISSUE;
19
22
  const existsCheck = check.exists;
20
23
  const hasFileCheck = check.hasFile;
@@ -25,20 +28,16 @@ const lacksFilesCheck = check.lacksFiles;
25
28
 
26
29
  // [declare]
27
30
 
28
- const HANDLE = cfgproduct.handle;
29
31
  const message = schemaMessage.messages("workflow");
30
- const MEDIA = `.${HANDLE}`;
32
+ const MEDIA = cfgfile.MEDIA;
31
33
  const INDEX = "index.html";
32
- const RESERVED = [`${HANDLE}.json`, MEDIA];
34
+ const RESERVED = [cfgfile.PACKAGED, MEDIA];
33
35
 
34
36
  // [function]
35
37
 
36
- // whether `build` runs anything: a command that isn't blank, as `arc build`
37
- // trims and drops blank ones (action/build/tool.js).
38
+ // whether `build` runs anything, as `arc build` runs it.
38
39
  const hasBuild = function (build) {
39
- return [build]
40
- .flat()
41
- .some((cmd) => typeof cmd === "string" && cmd.trim() !== "");
40
+ return buildCommand(build) !== "";
42
41
  };
43
42
 
44
43
  // [function]
package/src/util/argv.js CHANGED
@@ -19,6 +19,11 @@ const parse = helpers.Parser;
19
19
 
20
20
  // [declare]
21
21
 
22
+ // the --browser option of arc open and arc play.
23
+ const BROWSER = {
24
+ describe: "Open in a web browser",
25
+ type: "boolean",
26
+ };
22
27
  // the -C, --cwd option of every project command.
23
28
  const CWD = {
24
29
  alias: "C",
@@ -26,6 +31,18 @@ const CWD = {
26
31
  describe: "Set the working directory",
27
32
  type: "string",
28
33
  };
34
+ // the -j, --json option, which prints one JSON document (OUTPUT.md).
35
+ const JSON_OUTPUT = {
36
+ alias: "j",
37
+ describe: "Format output as JSON",
38
+ type: "boolean",
39
+ };
40
+ // the -q, --quiet option, which prints only errors.
41
+ const QUIET = {
42
+ alias: "q",
43
+ describe: "Output only errors",
44
+ type: "boolean",
45
+ };
29
46
 
30
47
  // [function]
31
48
 
@@ -87,4 +104,13 @@ const fail = function (argv) {
87
104
 
88
105
  // [export]
89
106
 
90
- module.exports = { CWD, cwd, fail, json, normalize };
107
+ module.exports = {
108
+ BROWSER,
109
+ CWD,
110
+ JSON_OUTPUT,
111
+ QUIET,
112
+ cwd,
113
+ fail,
114
+ json,
115
+ normalize,
116
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ // [function]
4
+
5
+ // workflow.build as the shell runs it: each command trimmed, blank ones
6
+ // dropped, and a list joined with `&&`. Blank when there's nothing to run.
7
+ const buildCommand = function (build) {
8
+ return [build]
9
+ .flat()
10
+ .filter((cmd) => typeof cmd === "string")
11
+ .map((cmd) => cmd.trim())
12
+ .filter(Boolean)
13
+ .join(" && ");
14
+ };
15
+
16
+ // [export]
17
+
18
+ module.exports = { buildCommand };
package/src/util/delay.js CHANGED
@@ -1,21 +1,5 @@
1
1
  "use strict";
2
2
 
3
- // [import]
4
-
5
- const phrase = require("../phrase");
6
- const time = require("./time");
7
-
8
- // [declare]
9
-
10
- const POLL = {
11
- delay: time.s(1),
12
- factor: 1,
13
- interval: time.m(1),
14
- maxDelay: time.s(1),
15
- timeout: Infinity,
16
- timeoutError: phrase.timedOut(),
17
- };
18
-
19
3
  // [function]
20
4
 
21
5
  const backoff = function (elapsed, delay, factor, interval, maxDelay) {
@@ -39,10 +23,13 @@ const wait = function (delay, next) {
39
23
 
40
24
  // [function]
41
25
 
26
+ // calls fn(value) until it resolves to something other than null, backing
27
+ // off by `factor` every `interval`, up to `maxDelay`. After `timeout`, it
28
+ // throws timeoutError(), the caller's own error, with its code.
42
29
  const poll = function (
43
30
  fn,
44
31
  value,
45
- { delay, factor, interval, maxDelay, timeout, timeoutError } = POLL,
32
+ { delay, factor, interval, maxDelay, timeout, timeoutError },
46
33
  ) {
47
34
  const started = Date.now();
48
35
  const next = function () {
@@ -52,10 +39,7 @@ const poll = function (
52
39
  }
53
40
  const elapsed = Date.now() - started;
54
41
  if (elapsed >= timeout) {
55
- // a function makes the caller's own error, with its code.
56
- throw typeof timeoutError === "function"
57
- ? timeoutError()
58
- : new Error(timeoutError);
42
+ throw timeoutError();
59
43
  }
60
44
  return wait(backoff(elapsed, delay, factor, interval, maxDelay), next);
61
45
  });
package/src/util/doc.js CHANGED
@@ -6,7 +6,6 @@ const jsdom = require("jsdom");
6
6
 
7
7
  // [import]
8
8
 
9
- const cfgdoc = require("../config/doc");
10
9
  const phrase = require("../phrase");
11
10
 
12
11
  // [use]
@@ -59,23 +58,15 @@ const checkNode = function (node, opts, issues) {
59
58
 
60
59
  // [function]
61
60
 
62
- // checks HTML as written, before anything sanitizes it: every element must be
63
- // allowed, with only its allowed attributes, each passing its hook. Each
64
- // problem is reported once.
65
- const checkHtml = function (str, { allowed, hooks = {} }) {
61
+ // checks the description's HTML as written, before anything sanitizes it:
62
+ // every element must be allowed, with only its allowed attributes, each
63
+ // passing its hook. Each problem is reported once.
64
+ const check = function (str, { allowed, hooks = {} }) {
66
65
  const issues = new Set();
67
66
  checkNode(JSDOM.fragment(str), { allowed, hooks }, issues);
68
67
  return [...issues];
69
68
  };
70
69
 
71
- // [function]
72
-
73
- const check = function (str, { type, ...opts }) {
74
- const checks = { [cfgdoc[".html"]]: checkHtml };
75
- const checkDoc = checks[type];
76
- return checkDoc ? checkDoc(str, opts) : [phrase.docUnsupported()];
77
- };
78
-
79
70
  // [export]
80
71
 
81
72
  module.exports = { check };
package/src/util/links.js CHANGED
@@ -41,13 +41,26 @@ const storePage = function (game) {
41
41
 
42
42
  // [function]
43
43
 
44
+ // a game's store page on the web.
45
+ const storeUrl = function (game) {
46
+ return `${cfguri.HOST_HTTP_WWW}${storePage(game)}`;
47
+ };
48
+
49
+ // [function]
50
+
51
+ // a game's page in Studio, on one of its tabs, such as `builds`.
52
+ const studioUrl = function (game, tab) {
53
+ return `${cfguri.HOST_HTTP_STUDIO}/games/${game}/${tab}`;
54
+ };
55
+
56
+ // [function]
57
+
44
58
  // where a deployed version will be, once it's published: its channel, that
45
59
  // channel's play link, and for production, its store page.
46
60
  const published = function ({ handle, id, version }) {
47
61
  const game = handle ?? id;
48
62
  const release = channel(version);
49
- const store =
50
- release === PRODUCTION ? `${cfguri.HOST_HTTP_WWW}${storePage(game)}` : null;
63
+ const store = release === PRODUCTION ? storeUrl(game) : null;
51
64
  return { channel: release, store, url: playUrl(game, release) };
52
65
  };
53
66
 
@@ -60,4 +73,6 @@ module.exports = {
60
73
  playUrl,
61
74
  published,
62
75
  storePage,
76
+ storeUrl,
77
+ studioUrl,
63
78
  };
package/src/util/media.js CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  // [import]
4
4
 
5
- const limits = require("../action/pack/limits");
5
+ const cfglimit = require("../config/limit");
6
6
 
7
7
  // [declare]
8
8
 
9
9
  // a file too large to pack isn't read.
10
- const MAX_READ = limits.MAX_FILE_SIZE;
10
+ const MAX_READ = cfglimit.FILE_SIZE;
11
11
 
12
12
  // [function]
13
13
 
package/src/util/objs.js CHANGED
@@ -29,10 +29,17 @@ const deepCompact = function (obj) {
29
29
 
30
30
  // [function]
31
31
 
32
+ // a TOML table: an object, not an array.
33
+ const isTable = function (value) {
34
+ return value !== null && typeof value === "object" && !Array.isArray(value);
35
+ };
36
+
37
+ // [function]
38
+
32
39
  const deepSort = function (obj) {
33
40
  return JSON.parse(stringify(obj));
34
41
  };
35
42
 
36
43
  // [export]
37
44
 
38
- module.exports = { deepCompact, deepSort };
45
+ module.exports = { deepCompact, deepSort, isTable };
@@ -41,7 +41,7 @@ const printToml = function (data, key, nl = false) {
41
41
  }
42
42
  try {
43
43
  write(TOML.stringify(deepSort(data)), nl);
44
- } catch (ex) {
44
+ } catch {
45
45
  write(TOML.stringify(deepSort({ [field]: data })), nl);
46
46
  }
47
47
  };
@@ -107,6 +107,20 @@ const abort = function (
107
107
 
108
108
  // [function]
109
109
 
110
+ // where arc open or arc play opened the page, with its URL, or that it
111
+ // couldn't, with the URL to open by hand.
112
+ const launched = function (where, url) {
113
+ if (where) {
114
+ log.result(phrase.opened(where), [url]);
115
+ return;
116
+ }
117
+ log.result(phrase.unableToOpen(), [url, phrase.openToContinue()], {
118
+ color: "yellow",
119
+ });
120
+ };
121
+
122
+ // [function]
123
+
110
124
  // arc validate's warnings, such as an unknown field, on stderr in yellow,
111
125
  // before a command that validates goes on. Left out with `--json` and
112
126
  // `--quiet`; arc validate --json lists them.
@@ -134,4 +148,12 @@ const warning = function (code, message, path = null) {
134
148
 
135
149
  // [export]
136
150
 
137
- module.exports = { abort, print, printJson, printToml, warn, warning };
151
+ module.exports = {
152
+ abort,
153
+ launched,
154
+ print,
155
+ printJson,
156
+ printToml,
157
+ warn,
158
+ warning,
159
+ };
package/src/util/rc.js CHANGED
@@ -81,7 +81,7 @@ const read = function (file) {
81
81
  let str = null;
82
82
  try {
83
83
  str = readFileSync(file, "utf8");
84
- } catch (ex) {
84
+ } catch {
85
85
  return {};
86
86
  }
87
87
  if (!/^\s*\{/u.test(str)) {
@@ -111,7 +111,7 @@ const findRc = function (cmd, subcmd, argv) {
111
111
  {},
112
112
  );
113
113
  } catch (ex) {
114
- return abort(`${subcmd[0].toUpperCase()}${subcmd.slice(1)} aborted.`, ex, {
114
+ return abort(phrase.aborted(subcmd), ex, {
115
115
  json: args.json(argv),
116
116
  });
117
117
  }
@@ -27,7 +27,7 @@ const json = function (resp) {
27
27
  return resp.text().then((text) => {
28
28
  try {
29
29
  return JSON.parse(text);
30
- } catch (ex) {
30
+ } catch {
31
31
  return null;
32
32
  }
33
33
  });
package/src/util/s3.js CHANGED
@@ -8,7 +8,7 @@ const https = require("node:https");
8
8
  // [import]
9
9
 
10
10
  const cfgcode = require("../config/code");
11
- const error = require("../util/error");
11
+ const error = require("./error");
12
12
  const phrase = require("../phrase");
13
13
 
14
14
  // [use]
@@ -24,7 +24,7 @@ const NUMBERS = new Set(["bigint", "int", "number"]);
24
24
  // a zod issue's code (config/code.js, ISSUE). Our own checks name theirs in
25
25
  // params; zod's built-in ones, which drop params, are named from what zod
26
26
  // reports. Anything else is `invalid`, so every issue has a code.
27
- const codeOf = function (issue) {
27
+ const issueCodeOf = function (issue) {
28
28
  switch (issue.code) {
29
29
  case "custom":
30
30
  return issue.params?.code ?? ISSUE.INVALID;
@@ -71,7 +71,7 @@ const codeOf = function (issue) {
71
71
  const toIssue = function (name, issue) {
72
72
  const { details, message } = schemaMessage.parse(issue.message);
73
73
  return {
74
- code: codeOf(issue),
74
+ code: issueCodeOf(issue),
75
75
  details,
76
76
  link: issue.path.length
77
77
  ? schemaMessage.link(name, String(issue.path[0]))
@@ -128,4 +128,10 @@ const validator = function (name, schema) {
128
128
 
129
129
  // [export]
130
130
 
131
- module.exports = { codeOf, compare, dereference, print, validator };
131
+ module.exports = {
132
+ compare,
133
+ dereference,
134
+ issueCodeOf,
135
+ print,
136
+ validator,
137
+ };
package/src/util/uris.js CHANGED
@@ -8,7 +8,7 @@
8
8
  const isSafeUri = function (uri) {
9
9
  try {
10
10
  return new URL(uri).protocol === "https:";
11
- } catch (ex) {
11
+ } catch {
12
12
  return false;
13
13
  }
14
14
  };
package/src/util/zip.js CHANGED
@@ -21,7 +21,7 @@ const join = path.posix.join;
21
21
 
22
22
  // [class]
23
23
 
24
- const Main = class {
24
+ const Zip = class {
25
25
 
26
26
  // [constructor]
27
27
 
@@ -85,4 +85,4 @@ const Main = class {
85
85
 
86
86
  // [export]
87
87
 
88
- module.exports = Main;
88
+ module.exports = Zip;
package/src/config/doc.js DELETED
@@ -1,7 +0,0 @@
1
- "use strict";
2
-
3
- // [export]
4
-
5
- module.exports = {
6
- ".html": "text/html",
7
- };