@miosa/cli 1.1.18 → 1.1.20
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/README.md +0 -21
- package/dist/client.d.ts +1 -15
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +44 -118
- package/dist/client.js.map +1 -1
- package/dist/commands/databases.d.ts.map +1 -1
- package/dist/commands/databases.js +33 -10
- package/dist/commands/databases.js.map +1 -1
- package/dist/commands/devices.js +2 -5
- package/dist/commands/devices.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +127 -58
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +91 -23
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/templates.d.ts.map +1 -1
- package/dist/commands/templates.js +252 -521
- package/dist/commands/templates.js.map +1 -1
- package/dist/commands/util.d.ts +0 -1
- package/dist/commands/util.d.ts.map +1 -1
- package/dist/commands/util.js +2 -15
- package/dist/commands/util.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +1 -5
- package/dist/commands/watch.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +2 -18
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -37
- package/dist/errors.js.map +1 -1
- package/dist/net-diagnosis.d.ts +87 -0
- package/dist/net-diagnosis.d.ts.map +1 -0
- package/dist/net-diagnosis.js +408 -0
- package/dist/net-diagnosis.js.map +1 -0
- package/dist/types.d.ts +6 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/api-validation.d.ts +0 -53
- package/dist/api-validation.d.ts.map +0 -1
- package/dist/api-validation.js +0 -200
- package/dist/api-validation.js.map +0 -1
- package/dist/endpoint.d.ts +0 -37
- package/dist/endpoint.d.ts.map +0 -1
- package/dist/endpoint.js +0 -123
- package/dist/endpoint.js.map +0 -1
package/dist/api-validation.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Field-level validation errors from the platform API.
|
|
3
|
-
*
|
|
4
|
-
* The API reports rejected fields in a top-level `errors` key, in one of two
|
|
5
|
-
* shapes depending on which validator refused:
|
|
6
|
-
*
|
|
7
|
-
* Ecto changeset (`Ecto.Changeset.traverse_errors/2`) — a map of field to a
|
|
8
|
-
* list of messages, possibly nested for embedded schemas:
|
|
9
|
-
*
|
|
10
|
-
* {"error":{"code":"VALIDATION_FAILED","message":"sandbox template is invalid"},
|
|
11
|
-
* "errors":{"slug":["a template with this name already exists"]}}
|
|
12
|
-
*
|
|
13
|
-
* Hand-rolled spec validators (BuildSpec) — a list of objects:
|
|
14
|
-
*
|
|
15
|
-
* {"error":{"code":"INVALID_BUILDSPEC","message":"BuildSpec is invalid"},
|
|
16
|
-
* "errors":[{"code":"REQUIRED","field":"from","message":"is required"}]}
|
|
17
|
-
*
|
|
18
|
-
* Neither shape was read before: the CLI only looked at `error.details`, so it
|
|
19
|
-
* fell back to dumping the whole raw response body and the customer saw a JSON
|
|
20
|
-
* blob naming an internal column (2026-08-26 live customer call).
|
|
21
|
-
*/
|
|
22
|
-
export interface FieldIssue {
|
|
23
|
-
/** Server-reported field path, e.g. "slug" or "steps.0.run". */
|
|
24
|
-
readonly field: string;
|
|
25
|
-
readonly message: string;
|
|
26
|
-
readonly code?: string;
|
|
27
|
-
}
|
|
28
|
-
export declare function isUniquenessMessage(message: string): boolean;
|
|
29
|
-
export declare function isServerAssignedField(field: string): boolean;
|
|
30
|
-
export declare function fieldLabel(field: string): string;
|
|
31
|
-
/**
|
|
32
|
-
* Collect field-level issues from an error response body. Returns an empty
|
|
33
|
-
* array when the body carries no per-field detail, so callers can fall back to
|
|
34
|
-
* the top-level message.
|
|
35
|
-
*/
|
|
36
|
-
export declare function parseFieldIssues(body: unknown): FieldIssue[];
|
|
37
|
-
export interface RenderedIssues {
|
|
38
|
-
/** One "field: message" line per issue, already labelled for the caller. */
|
|
39
|
-
readonly lines: string[];
|
|
40
|
-
/** Actionable next step, when the issues imply one. */
|
|
41
|
-
readonly hint?: string;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Turn field issues into the lines the CLI prints.
|
|
45
|
-
*
|
|
46
|
-
* `sentFields` are the top-level keys the CLI actually put in the request body.
|
|
47
|
-
* They are what makes the misattribution guard possible: when the server blames
|
|
48
|
-
* a field the request never set (the `[:tenant_id, :slug]` unique_constraint
|
|
49
|
-
* case, where Ecto attaches a composite-index error to the FIRST field), the
|
|
50
|
-
* CLI must not repeat that blame back to the user as if it were their input.
|
|
51
|
-
*/
|
|
52
|
-
export declare function renderFieldIssues(issues: readonly FieldIssue[], sentFields?: readonly string[]): RenderedIssues;
|
|
53
|
-
//# sourceMappingURL=api-validation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-validation.d.ts","sourceRoot":"","sources":["../src/api-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAuCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,EAAE,CAY5D;AA0DD,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,UAAU,GAAE,SAAS,MAAM,EAAO,GACjC,cAAc,CAgDhB"}
|
package/dist/api-validation.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Field-level validation errors from the platform API.
|
|
3
|
-
*
|
|
4
|
-
* The API reports rejected fields in a top-level `errors` key, in one of two
|
|
5
|
-
* shapes depending on which validator refused:
|
|
6
|
-
*
|
|
7
|
-
* Ecto changeset (`Ecto.Changeset.traverse_errors/2`) — a map of field to a
|
|
8
|
-
* list of messages, possibly nested for embedded schemas:
|
|
9
|
-
*
|
|
10
|
-
* {"error":{"code":"VALIDATION_FAILED","message":"sandbox template is invalid"},
|
|
11
|
-
* "errors":{"slug":["a template with this name already exists"]}}
|
|
12
|
-
*
|
|
13
|
-
* Hand-rolled spec validators (BuildSpec) — a list of objects:
|
|
14
|
-
*
|
|
15
|
-
* {"error":{"code":"INVALID_BUILDSPEC","message":"BuildSpec is invalid"},
|
|
16
|
-
* "errors":[{"code":"REQUIRED","field":"from","message":"is required"}]}
|
|
17
|
-
*
|
|
18
|
-
* Neither shape was read before: the CLI only looked at `error.details`, so it
|
|
19
|
-
* fell back to dumping the whole raw response body and the customer saw a JSON
|
|
20
|
-
* blob naming an internal column (2026-08-26 live customer call).
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Fields the client never sets: the server assigns them from the credential or
|
|
24
|
-
* from its own request context. A validation error attributed to one of these
|
|
25
|
-
* is a server-side attribution artifact, not something the caller can correct
|
|
26
|
-
* by changing its request.
|
|
27
|
-
*/
|
|
28
|
-
const SERVER_ASSIGNED_FIELDS = new Set([
|
|
29
|
-
"tenant_id",
|
|
30
|
-
"organization_id",
|
|
31
|
-
"owner_id",
|
|
32
|
-
"user_id",
|
|
33
|
-
"workspace_id",
|
|
34
|
-
"account_id",
|
|
35
|
-
"api_key_id",
|
|
36
|
-
]);
|
|
37
|
-
/**
|
|
38
|
-
* Internal column names mapped to the flag or field a caller actually controls.
|
|
39
|
-
* Keeps the CLI from telling someone to fix a field their command has no way
|
|
40
|
-
* to set.
|
|
41
|
-
*/
|
|
42
|
-
const FIELD_LABELS = {
|
|
43
|
-
slug: "name",
|
|
44
|
-
build_spec: "dockerfile",
|
|
45
|
-
normalized_build_spec: "dockerfile",
|
|
46
|
-
dockerfile: "dockerfile",
|
|
47
|
-
from: "dockerfile (FROM)",
|
|
48
|
-
steps: "dockerfile (RUN/WORKDIR/ENV steps)",
|
|
49
|
-
startCmd: "dockerfile (CMD/ENTRYPOINT)",
|
|
50
|
-
previewPort: "dockerfile (EXPOSE)",
|
|
51
|
-
artifactPaths: "dockerfile (artifact paths)",
|
|
52
|
-
};
|
|
53
|
-
/** Messages Ecto/Postgres produce for a unique-index violation. */
|
|
54
|
-
const UNIQUENESS_MESSAGE = /has already been taken|already exists|must be unique/i;
|
|
55
|
-
export function isUniquenessMessage(message) {
|
|
56
|
-
return UNIQUENESS_MESSAGE.test(message);
|
|
57
|
-
}
|
|
58
|
-
export function isServerAssignedField(field) {
|
|
59
|
-
return SERVER_ASSIGNED_FIELDS.has(rootField(field));
|
|
60
|
-
}
|
|
61
|
-
export function fieldLabel(field) {
|
|
62
|
-
const root = rootField(field);
|
|
63
|
-
const mapped = FIELD_LABELS[root];
|
|
64
|
-
if (!mapped)
|
|
65
|
-
return field;
|
|
66
|
-
const rest = field.slice(root.length);
|
|
67
|
-
return `${mapped}${rest}`;
|
|
68
|
-
}
|
|
69
|
-
function rootField(field) {
|
|
70
|
-
const dot = field.indexOf(".");
|
|
71
|
-
return dot === -1 ? field : field.slice(0, dot);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Collect field-level issues from an error response body. Returns an empty
|
|
75
|
-
* array when the body carries no per-field detail, so callers can fall back to
|
|
76
|
-
* the top-level message.
|
|
77
|
-
*/
|
|
78
|
-
export function parseFieldIssues(body) {
|
|
79
|
-
if (!isRecord(body))
|
|
80
|
-
return [];
|
|
81
|
-
const candidates = [body["errors"]];
|
|
82
|
-
if (isRecord(body["error"]))
|
|
83
|
-
candidates.push(body["error"]["details"]);
|
|
84
|
-
candidates.push(body["details"]);
|
|
85
|
-
for (const candidate of candidates) {
|
|
86
|
-
const issues = collect(candidate, "");
|
|
87
|
-
if (issues.length > 0)
|
|
88
|
-
return issues;
|
|
89
|
-
}
|
|
90
|
-
return [];
|
|
91
|
-
}
|
|
92
|
-
function collect(value, path) {
|
|
93
|
-
if (value === null || value === undefined)
|
|
94
|
-
return [];
|
|
95
|
-
if (typeof value === "string") {
|
|
96
|
-
return path === "" ? [] : [{ field: path, message: value }];
|
|
97
|
-
}
|
|
98
|
-
if (Array.isArray(value)) {
|
|
99
|
-
// A list of message strings under a field path, or a list of
|
|
100
|
-
// {field, message} objects at the top level.
|
|
101
|
-
return value.flatMap((entry, index) => {
|
|
102
|
-
if (typeof entry === "string") {
|
|
103
|
-
return path === "" ? [] : [{ field: path, message: entry }];
|
|
104
|
-
}
|
|
105
|
-
if (isRecord(entry) && typeof entry["message"] === "string") {
|
|
106
|
-
const field = asString(entry["field"]) ?? asString(entry["path"]) ?? path;
|
|
107
|
-
if (!field)
|
|
108
|
-
return [];
|
|
109
|
-
return [
|
|
110
|
-
{
|
|
111
|
-
field,
|
|
112
|
-
message: entry["message"],
|
|
113
|
-
...(asString(entry["code"])
|
|
114
|
-
? { code: asString(entry["code"]) }
|
|
115
|
-
: {}),
|
|
116
|
-
},
|
|
117
|
-
];
|
|
118
|
-
}
|
|
119
|
-
return collect(entry, path === "" ? String(index) : `${path}.${index}`);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
if (isRecord(value)) {
|
|
123
|
-
// A single {field, message} object.
|
|
124
|
-
if (typeof value["message"] === "string" && !("errors" in value)) {
|
|
125
|
-
const field = asString(value["field"]) ?? asString(value["path"]) ?? path;
|
|
126
|
-
if (field) {
|
|
127
|
-
return [
|
|
128
|
-
{
|
|
129
|
-
field,
|
|
130
|
-
message: value["message"],
|
|
131
|
-
...(asString(value["code"])
|
|
132
|
-
? { code: asString(value["code"]) }
|
|
133
|
-
: {}),
|
|
134
|
-
},
|
|
135
|
-
];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return Object.entries(value).flatMap(([key, nested]) => collect(nested, path === "" ? key : `${path}.${key}`));
|
|
139
|
-
}
|
|
140
|
-
return [];
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Turn field issues into the lines the CLI prints.
|
|
144
|
-
*
|
|
145
|
-
* `sentFields` are the top-level keys the CLI actually put in the request body.
|
|
146
|
-
* They are what makes the misattribution guard possible: when the server blames
|
|
147
|
-
* a field the request never set (the `[:tenant_id, :slug]` unique_constraint
|
|
148
|
-
* case, where Ecto attaches a composite-index error to the FIRST field), the
|
|
149
|
-
* CLI must not repeat that blame back to the user as if it were their input.
|
|
150
|
-
*/
|
|
151
|
-
export function renderFieldIssues(issues, sentFields = []) {
|
|
152
|
-
if (issues.length === 0)
|
|
153
|
-
return { lines: [] };
|
|
154
|
-
const sent = new Set(sentFields);
|
|
155
|
-
const lines = [];
|
|
156
|
-
const hints = [];
|
|
157
|
-
for (const issue of issues) {
|
|
158
|
-
const root = rootField(issue.field);
|
|
159
|
-
const misattributed = isServerAssignedField(issue.field) &&
|
|
160
|
-
!sent.has(root) &&
|
|
161
|
-
isUniquenessMessage(issue.message);
|
|
162
|
-
if (misattributed) {
|
|
163
|
-
// The request never carried this field, so the caller cannot act on it.
|
|
164
|
-
// Report the collision as a collision and name the misattribution
|
|
165
|
-
// instead of parroting an internal column back at the user.
|
|
166
|
-
const collided = nameLikeField(sentFields);
|
|
167
|
-
lines.push(collided
|
|
168
|
-
? `${collided}: already used by one of your existing resources`
|
|
169
|
-
: "already exists: this resource is already registered");
|
|
170
|
-
lines.push(`(the server reported this against "${issue.field}", ` +
|
|
171
|
-
`which this command did not send - treat it as a duplicate, not a tenancy problem)`);
|
|
172
|
-
hints.push(collided
|
|
173
|
-
? `Pick a different --${collided}, or remove the existing one first.`
|
|
174
|
-
: "Pick a different name, or remove the existing resource first.");
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
lines.push(`${fieldLabel(issue.field)}: ${issue.message}`);
|
|
178
|
-
if (isUniquenessMessage(issue.message)) {
|
|
179
|
-
const label = fieldLabel(issue.field);
|
|
180
|
-
hints.push(`Pick a different --${label}, or remove the existing one first.`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
const hint = hints[0];
|
|
184
|
-
return hint === undefined ? { lines } : { lines, hint };
|
|
185
|
-
}
|
|
186
|
-
/** The most name-like field the request actually sent, for a duplicate hint. */
|
|
187
|
-
function nameLikeField(sentFields) {
|
|
188
|
-
for (const candidate of ["name", "slug", "title", "id"]) {
|
|
189
|
-
if (sentFields.includes(candidate))
|
|
190
|
-
return candidate === "slug" ? "name" : candidate;
|
|
191
|
-
}
|
|
192
|
-
return undefined;
|
|
193
|
-
}
|
|
194
|
-
function asString(value) {
|
|
195
|
-
return typeof value === "string" && value !== "" ? value : undefined;
|
|
196
|
-
}
|
|
197
|
-
function isRecord(value) {
|
|
198
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
199
|
-
}
|
|
200
|
-
//# sourceMappingURL=api-validation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-validation.js","sourceRoot":"","sources":["../src/api-validation.ts"],"names":[],"mappings":"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"}
|
package/dist/endpoint.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Endpoint resolution and transport-failure diagnosis.
|
|
3
|
-
*
|
|
4
|
-
* A CLI that cannot resolve its API host must say which host it tried, where
|
|
5
|
-
* that host came from, and how to change it. The bare
|
|
6
|
-
* `Network error: getaddrinfo ENOTFOUND <host>` it printed before named the
|
|
7
|
-
* host but nothing else, leaving no way to tell a typo in `MIOSA_ENDPOINT`
|
|
8
|
-
* apart from a typo in `~/.miosa/config.json` apart from real DNS trouble
|
|
9
|
-
* (2026-08-26 live customer call).
|
|
10
|
-
*/
|
|
11
|
-
import { NetworkError } from "./errors.js";
|
|
12
|
-
export declare const DEFAULT_ENDPOINT = "https://api.miosa.ai";
|
|
13
|
-
export type EndpointSource = "MIOSA_ENDPOINT" | "config-file" | "built-in-default";
|
|
14
|
-
export interface EndpointOrigin {
|
|
15
|
-
readonly source: EndpointSource;
|
|
16
|
-
/** Human description of where the value lives, and how to change it. */
|
|
17
|
-
readonly where: string;
|
|
18
|
-
readonly fix: string;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Work out where the endpoint currently in use came from. Mirrors the
|
|
22
|
-
* precedence in `loadConfig`: MIOSA_ENDPOINT, then the config file, then the
|
|
23
|
-
* built-in default.
|
|
24
|
-
*/
|
|
25
|
-
export declare function endpointOrigin(endpoint: string): EndpointOrigin;
|
|
26
|
-
/**
|
|
27
|
-
* Reject an endpoint that is not a usable absolute http(s) URL before any
|
|
28
|
-
* request is attempted. Undici's own failure for this is the opaque
|
|
29
|
-
* `TypeError: Invalid URL`, which does not even echo the offending value.
|
|
30
|
-
*/
|
|
31
|
-
export declare function assertUsableEndpoint(endpoint: string): void;
|
|
32
|
-
/**
|
|
33
|
-
* Build a NetworkError that names the host, the config value behind it, and
|
|
34
|
-
* the command that changes it.
|
|
35
|
-
*/
|
|
36
|
-
export declare function transportError(err: unknown, endpoint: string): NetworkError;
|
|
37
|
-
//# sourceMappingURL=endpoint.d.ts.map
|
package/dist/endpoint.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,YAAY,EAAa,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD,MAAM,MAAM,cAAc,GACxB,gBAAgB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAyB/D;AAaD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAkB3D;AAyBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAuC3E"}
|
package/dist/endpoint.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Endpoint resolution and transport-failure diagnosis.
|
|
3
|
-
*
|
|
4
|
-
* A CLI that cannot resolve its API host must say which host it tried, where
|
|
5
|
-
* that host came from, and how to change it. The bare
|
|
6
|
-
* `Network error: getaddrinfo ENOTFOUND <host>` it printed before named the
|
|
7
|
-
* host but nothing else, leaving no way to tell a typo in `MIOSA_ENDPOINT`
|
|
8
|
-
* apart from a typo in `~/.miosa/config.json` apart from real DNS trouble
|
|
9
|
-
* (2026-08-26 live customer call).
|
|
10
|
-
*/
|
|
11
|
-
import { getConfigPath } from "./config.js";
|
|
12
|
-
import { NetworkError, UserError } from "./errors.js";
|
|
13
|
-
export const DEFAULT_ENDPOINT = "https://api.miosa.ai";
|
|
14
|
-
/**
|
|
15
|
-
* Work out where the endpoint currently in use came from. Mirrors the
|
|
16
|
-
* precedence in `loadConfig`: MIOSA_ENDPOINT, then the config file, then the
|
|
17
|
-
* built-in default.
|
|
18
|
-
*/
|
|
19
|
-
export function endpointOrigin(endpoint) {
|
|
20
|
-
const fromEnv = process.env["MIOSA_ENDPOINT"];
|
|
21
|
-
const normalized = endpoint.replace(/\/$/, "");
|
|
22
|
-
if (fromEnv && fromEnv.replace(/\/$/, "") === normalized) {
|
|
23
|
-
return {
|
|
24
|
-
source: "MIOSA_ENDPOINT",
|
|
25
|
-
where: "the MIOSA_ENDPOINT environment variable",
|
|
26
|
-
fix: `unset MIOSA_ENDPOINT (or: export MIOSA_ENDPOINT=${DEFAULT_ENDPOINT})`,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
if (normalized === DEFAULT_ENDPOINT) {
|
|
30
|
-
return {
|
|
31
|
-
source: "built-in-default",
|
|
32
|
-
where: `the built-in default (${DEFAULT_ENDPOINT})`,
|
|
33
|
-
fix: `miosa config set api_url ${DEFAULT_ENDPOINT}`,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
source: "config-file",
|
|
38
|
-
where: `"endpoint" in ${configFileForDisplay()}`,
|
|
39
|
-
fix: `miosa config set api_url ${DEFAULT_ENDPOINT}`,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Config file path for the message. Tolerates a stubbed config module (unit
|
|
44
|
-
* tests replace it wholesale) by degrading to the documented location rather
|
|
45
|
-
* than crashing the error path that is meant to explain a failure.
|
|
46
|
-
*/
|
|
47
|
-
function configFileForDisplay() {
|
|
48
|
-
return typeof getConfigPath === "function"
|
|
49
|
-
? getConfigPath()
|
|
50
|
-
: "~/.miosa/config.json";
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Reject an endpoint that is not a usable absolute http(s) URL before any
|
|
54
|
-
* request is attempted. Undici's own failure for this is the opaque
|
|
55
|
-
* `TypeError: Invalid URL`, which does not even echo the offending value.
|
|
56
|
-
*/
|
|
57
|
-
export function assertUsableEndpoint(endpoint) {
|
|
58
|
-
const origin = endpointOrigin(endpoint);
|
|
59
|
-
let parsed;
|
|
60
|
-
try {
|
|
61
|
-
parsed = new URL(endpoint);
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
throw new UserError(`The MIOSA API endpoint is not a valid URL: ${JSON.stringify(endpoint)}`, `It is set in ${origin.where}. An endpoint must include the scheme, ` +
|
|
65
|
-
`for example ${DEFAULT_ENDPOINT}. Fix it with: ${origin.fix}`);
|
|
66
|
-
}
|
|
67
|
-
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
68
|
-
throw new UserError(`The MIOSA API endpoint must be http or https, got ${JSON.stringify(endpoint)}`, `It is set in ${origin.where}. Fix it with: ${origin.fix}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/** Walk `err.cause` for the first entry carrying an errno-style `code`. */
|
|
72
|
-
function transportCause(err) {
|
|
73
|
-
let current = err;
|
|
74
|
-
for (let depth = 0; depth < 6 && current !== null && typeof current === "object"; depth += 1) {
|
|
75
|
-
const candidate = current;
|
|
76
|
-
if (typeof candidate.code === "string")
|
|
77
|
-
return candidate;
|
|
78
|
-
current = candidate.cause;
|
|
79
|
-
}
|
|
80
|
-
return undefined;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Build a NetworkError that names the host, the config value behind it, and
|
|
84
|
-
* the command that changes it.
|
|
85
|
-
*/
|
|
86
|
-
export function transportError(err, endpoint) {
|
|
87
|
-
const origin = endpointOrigin(endpoint);
|
|
88
|
-
const raw = err instanceof Error ? err.message : String(err);
|
|
89
|
-
const cause = transportCause(err);
|
|
90
|
-
const code = typeof cause?.code === "string" ? cause.code : undefined;
|
|
91
|
-
let host;
|
|
92
|
-
try {
|
|
93
|
-
host = new URL(endpoint).host;
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
host = endpoint;
|
|
97
|
-
}
|
|
98
|
-
const detail = (() => {
|
|
99
|
-
switch (code) {
|
|
100
|
-
case "ENOTFOUND":
|
|
101
|
-
case "EAI_AGAIN":
|
|
102
|
-
return `DNS lookup failed for host "${host}" (${code}). That hostname does not resolve from this machine.`;
|
|
103
|
-
case "ECONNREFUSED":
|
|
104
|
-
return `The host "${host}" refused the connection (ECONNREFUSED). It resolved, but nothing is listening on that port.`;
|
|
105
|
-
case "ETIMEDOUT":
|
|
106
|
-
case "UND_ERR_CONNECT_TIMEOUT":
|
|
107
|
-
return `Connecting to "${host}" timed out (${code}).`;
|
|
108
|
-
case "CERT_HAS_EXPIRED":
|
|
109
|
-
case "DEPTH_ZERO_SELF_SIGNED_CERT":
|
|
110
|
-
case "UNABLE_TO_VERIFY_LEAF_SIGNATURE":
|
|
111
|
-
return `TLS verification failed for "${host}" (${code}).`;
|
|
112
|
-
default:
|
|
113
|
-
return `Could not reach "${host}": ${raw}`;
|
|
114
|
-
}
|
|
115
|
-
})();
|
|
116
|
-
const hint = code === "ENOTFOUND" || code === "EAI_AGAIN"
|
|
117
|
-
? `The endpoint ${endpoint} comes from ${origin.where}. ` +
|
|
118
|
-
`Check it for a typo, then: ${origin.fix}`
|
|
119
|
-
: `The endpoint ${endpoint} comes from ${origin.where}. ` +
|
|
120
|
-
`Verify it with "miosa config get api_url", or change it: ${origin.fix}`;
|
|
121
|
-
return new NetworkError(`Cannot reach the MIOSA API. ${detail}`, hint);
|
|
122
|
-
}
|
|
123
|
-
//# sourceMappingURL=endpoint.js.map
|
package/dist/endpoint.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"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"}
|