arcadible 1.0.2 → 1.0.4

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/src/util/md.js CHANGED
@@ -32,7 +32,7 @@ const escape = function (str) {
32
32
  .replace(/>/gu, ">");
33
33
  };
34
34
 
35
- // [declare]
35
+ // [define]
36
36
 
37
37
  // there is no video syntax in Markdown, so an image of a video renders as the
38
38
  // video the developer would have written: its src and title, and no alt.
@@ -59,6 +59,20 @@ const print = function (data, { key, nl, toml } = {}) {
59
59
 
60
60
  // [function]
61
61
 
62
+ // exits with `code` once stdout has written what it holds. A pipe on macOS
63
+ // writes later, so exiting at once would cut a large --json document short;
64
+ // with nothing held, it exits at once, as a caller that goes on expects.
65
+ const exit = function (code) {
66
+ if (!process.stdout.writableLength) {
67
+ process.exit(code);
68
+ }
69
+ process.exitCode = code;
70
+ process.stdout.write("", () => process.exit(code));
71
+ return new Promise(() => {});
72
+ };
73
+
74
+ // [function]
75
+
62
76
  // a command's error path: the error as JSON, or its heading ("Deploy
63
77
  // aborted.") and the reason on stderr, then its code and the link to it on
64
78
  // the Errors page, once the spinner and progress bar are cleared. Then exits
@@ -102,7 +116,7 @@ const abort = function (
102
116
  log.pd(message);
103
117
  log.nlpd([phrase.errorCode(shown), chalk.cyan.underline(link)]);
104
118
  }
105
- process.exit(1);
119
+ return exit(1);
106
120
  };
107
121
 
108
122
  // [function]
@@ -128,7 +142,7 @@ const warn = function (warnings, { json, quiet } = {}) {
128
142
  if (json || quiet) {
129
143
  return;
130
144
  }
131
- warnings.forEach((each) => log.pw(`⚠ ${schema.print(each)}`));
145
+ warnings.forEach((each) => log.pw(schema.print(each)));
132
146
  };
133
147
 
134
148
  // [function]
@@ -150,6 +164,7 @@ const warning = function (code, message, path = null) {
150
164
 
151
165
  module.exports = {
152
166
  abort,
167
+ exit,
153
168
  launched,
154
169
  print,
155
170
  printJson,
@@ -17,6 +17,14 @@ const ISSUE = cfgcode.ISSUE;
17
17
 
18
18
  // [declare]
19
19
 
20
+ // how a value's kind is named, as TOML writes it.
21
+ const KINDS = {
22
+ array: "a list",
23
+ boolean: "true or false",
24
+ number: "a number",
25
+ object: "a table",
26
+ string: "a string",
27
+ };
20
28
  const NUMBERS = new Set(["bigint", "int", "number"]);
21
29
 
22
30
  // [function]
@@ -65,11 +73,54 @@ const issueCodeOf = function (issue) {
65
73
 
66
74
  // [function]
67
75
 
76
+ // a value's kind, as TOML writes it: "a string", "a list", "a table".
77
+ const kindOf = function (type) {
78
+ return KINDS[type] ?? `a ${type}`;
79
+ };
80
+
81
+ // [function]
82
+
83
+ // what zod reports itself (a value of the wrong type, or not one of the
84
+ // options), in arc's words, as `{ message, details }`: "Must be a string, not
85
+ // a number." Null for a message of our own.
86
+ const zodMessage = function (issue) {
87
+ if (issue.code === "invalid_value" && issue.values) {
88
+ return { details: [issue.values.join(", ")], message: "Must be one of:" };
89
+ }
90
+ const given = Array.isArray(issue.input) ? "array" : typeof issue.input;
91
+ if (issue.code === "invalid_type" && typeof issue.input !== "undefined") {
92
+ return {
93
+ details: [],
94
+ message: `Must be ${kindOf(issue.expected)}, not ${kindOf(given)}.`,
95
+ };
96
+ }
97
+ if (
98
+ issue.code === "invalid_union" &&
99
+ issue.errors.every((branch) =>
100
+ branch.every((each) => each.code === "invalid_type"),
101
+ )
102
+ ) {
103
+ const expected = [
104
+ ...new Set(issue.errors.map((branch) => kindOf(branch[0].expected))),
105
+ ];
106
+ return {
107
+ details: [],
108
+ message: `Must be ${expected.join(" or ")}, not ${kindOf(given)}.`,
109
+ };
110
+ }
111
+ return null;
112
+ };
113
+
114
+ // [function]
115
+
68
116
  // a zod issue as arc validate reports it: the field's path, the rule's code,
69
117
  // the message's first line and its details, and the link to the field's
70
118
  // rules, or null for a field the docs leave out.
71
119
  const toIssue = function (name, issue) {
72
- const { details, message } = schemaMessage.parse(issue.message);
120
+ const parsed = schemaMessage.parse(issue.message);
121
+ const { details, message } =
122
+ (/^Invalid (input|option)\b/u.test(parsed.message) && zodMessage(issue)) ||
123
+ parsed;
73
124
  return {
74
125
  code: issueCodeOf(issue),
75
126
  details,
@@ -133,5 +184,6 @@ module.exports = {
133
184
  dereference,
134
185
  issueCodeOf,
135
186
  print,
187
+ toIssue,
136
188
  validator,
137
189
  };