@piyushdoorwar/yamlet 1.1.14 → 1.12.0

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 (2) hide show
  1. package/dist/yamlet.js +88 -19
  2. package/package.json +1 -1
package/dist/yamlet.js CHANGED
@@ -293,6 +293,71 @@ function yamletUserAgent() {
293
293
 
294
294
  // core/src/oauth2.ts
295
295
  import { request } from "undici";
296
+ var OAuth2Error = class extends Error {
297
+ constructor(kind, message, status) {
298
+ super(message);
299
+ this.kind = kind;
300
+ this.status = status;
301
+ this.name = "OAuth2Error";
302
+ }
303
+ kind;
304
+ status;
305
+ };
306
+ var UNRESOLVED = /\{\{\s*([^{}\s]+)\s*\}\}/;
307
+ function resolveUrl(label, raw, resolve2) {
308
+ const url = resolve2(raw).trim();
309
+ if (!url) throw new OAuth2Error("config", `${label} is not set`);
310
+ const missing = UNRESOLVED.exec(url);
311
+ if (missing) throw new OAuth2Error("config", `${label} uses {{${missing[1]}}}, which is not defined in any active scope`);
312
+ let parsed;
313
+ try {
314
+ parsed = new URL(url);
315
+ } catch {
316
+ throw new OAuth2Error("config", `${label} is not a valid URL: ${url}`);
317
+ }
318
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new OAuth2Error("config", `${label} must start with http:// or https://`);
319
+ return url;
320
+ }
321
+ var NETWORK_HINTS = {
322
+ ENOTFOUND: "the host name could not be found",
323
+ EAI_AGAIN: "the host name could not be resolved",
324
+ ECONNREFUSED: "the connection was refused",
325
+ ECONNRESET: "the connection was reset",
326
+ ETIMEDOUT: "the connection timed out",
327
+ UND_ERR_CONNECT_TIMEOUT: "the connection timed out",
328
+ UND_ERR_HEADERS_TIMEOUT: "the server took too long to answer",
329
+ UND_ERR_BODY_TIMEOUT: "the server took too long to answer",
330
+ CERT_HAS_EXPIRED: "the server's TLS certificate has expired",
331
+ DEPTH_ZERO_SELF_SIGNED_CERT: "the server uses a self-signed TLS certificate",
332
+ SELF_SIGNED_CERT_IN_CHAIN: "the server's TLS certificate chain is self-signed",
333
+ UNABLE_TO_VERIFY_LEAF_SIGNATURE: "the server's TLS certificate could not be verified"
334
+ };
335
+ function networkError(url, err) {
336
+ const e = err;
337
+ const code = e?.cause?.code ?? e?.code;
338
+ const reason = (code && NETWORK_HINTS[code]) ?? e?.cause?.message ?? e?.message ?? String(err);
339
+ let host = url;
340
+ try {
341
+ host = new URL(url).host;
342
+ } catch {
343
+ }
344
+ return new OAuth2Error("network", `Could not reach the token URL (${host}): ${reason}`);
345
+ }
346
+ function providerError(status, text) {
347
+ let detail = "";
348
+ try {
349
+ const o = JSON.parse(text);
350
+ const err = typeof o.error === "string" ? o.error : typeof o.message === "string" ? o.message : "";
351
+ const desc = typeof o.error_description === "string" ? o.error_description : "";
352
+ detail = [err, desc].filter(Boolean).join(": ");
353
+ } catch {
354
+ const form = new URLSearchParams(text);
355
+ if (form.get("error")) detail = [form.get("error"), form.get("error_description")].filter(Boolean).join(": ");
356
+ }
357
+ if (!detail) detail = text.trim().replace(/\s+/g, " ").slice(0, 300) || "empty response";
358
+ const hint = /invalid_client/i.test(detail) ? " Check the client ID and secret, and whether the provider expects them in the Basic auth header or the request body." : /invalid_grant/i.test(detail) ? " The username, password, code or refresh token was rejected." : /invalid_scope/i.test(detail) ? " Check the scope value." : "";
359
+ return new OAuth2Error("provider", `The token endpoint answered ${status}: ${detail}.${hint}`, status);
360
+ }
296
361
  function parseTokenBody(text, contentType) {
297
362
  let raw;
298
363
  if (contentType.includes("x-www-form-urlencoded") || !text.trim().startsWith("{") && text.includes("access_token=")) {
@@ -301,14 +366,14 @@ function parseTokenBody(text, contentType) {
301
366
  try {
302
367
  raw = JSON.parse(text);
303
368
  } catch {
304
- throw new Error(`Token endpoint returned a non-JSON response: ${text.slice(0, 200)}`);
369
+ throw new OAuth2Error("provider", `The token endpoint did not return JSON: ${text.trim().slice(0, 200) || "empty response"}`);
305
370
  }
306
371
  }
307
372
  const o = raw ?? {};
308
373
  const accessToken = typeof o.access_token === "string" ? o.access_token : "";
309
374
  if (!accessToken) {
310
- const err = o.error ? `${o.error}${o.error_description ? `: ${o.error_description}` : ""}` : "no access_token in response";
311
- throw new Error(`Token request failed: ${err}`);
375
+ const err = o.error ? `${o.error}${o.error_description ? `: ${o.error_description}` : ""}` : "the response has no access_token";
376
+ throw new OAuth2Error("provider", `Token request failed: ${err}`);
312
377
  }
313
378
  const expires = Number(o.expires_in);
314
379
  const result = { accessToken, raw };
@@ -318,8 +383,7 @@ function parseTokenBody(text, contentType) {
318
383
  return result;
319
384
  }
320
385
  async function requestToken(cfg, resolve2, form, opts = {}) {
321
- const url = resolve2(cfg.accessTokenUrl).trim();
322
- if (!url) throw new Error("OAuth 2.0 access token URL is not set");
386
+ const url = resolveUrl("Token URL", cfg.accessTokenUrl, resolve2);
323
387
  const clientId = resolve2(cfg.clientId);
324
388
  const clientSecret = resolve2(cfg.clientSecret);
325
389
  const headers = {
@@ -333,17 +397,22 @@ async function requestToken(cfg, resolve2, form, opts = {}) {
333
397
  } else if (clientId || clientSecret) {
334
398
  headers.authorization = `Basic ${Buffer.from(`${clientId}:${clientSecret}`, "utf8").toString("base64")}`;
335
399
  }
336
- const res = await request(url, {
337
- method: "POST",
338
- headers,
339
- body: body.toString(),
340
- dispatcher: opts.dispatcher ?? defaultAgent(),
341
- signal: opts.signal
342
- });
343
- const text = await res.body.text();
344
- if (res.statusCode < 200 || res.statusCode >= 300) {
345
- throw new Error(`Token request failed (${res.statusCode}): ${text.slice(0, 500)}`);
400
+ let res;
401
+ let text;
402
+ try {
403
+ res = await request(url, {
404
+ method: "POST",
405
+ headers,
406
+ body: body.toString(),
407
+ dispatcher: opts.dispatcher ?? defaultAgent(),
408
+ signal: opts.signal
409
+ });
410
+ text = await res.body.text();
411
+ } catch (err) {
412
+ if (opts.signal?.aborted) throw err;
413
+ throw networkError(url, err);
346
414
  }
415
+ if (res.statusCode < 200 || res.statusCode >= 300) throw providerError(res.statusCode, text);
347
416
  const ct = res.headers["content-type"];
348
417
  return parseTokenBody(text, String(Array.isArray(ct) ? ct[0] : ct ?? ""));
349
418
  }
@@ -1473,7 +1542,7 @@ ${opts.script}
1473
1542
 
1474
1543
  // core/src/requestExecutor.ts
1475
1544
  var MAX_REDIRECTS = 10;
1476
- var NETWORK_HINTS = {
1545
+ var NETWORK_HINTS2 = {
1477
1546
  ENOTFOUND: "host name could not be resolved",
1478
1547
  EAI_AGAIN: "DNS lookup timed out",
1479
1548
  ECONNREFUSED: "connection refused",
@@ -1507,8 +1576,8 @@ var errMessage2 = (e) => {
1507
1576
  if (msg && msg !== "fetch failed") add(msg);
1508
1577
  const hasInner = Array.isArray(err.errors) && err.errors.length > 0;
1509
1578
  if (code && !msg && hasInner) {
1510
- } else if (code && !msg.includes(code)) add(NETWORK_HINTS[code] ? `${code}: ${NETWORK_HINTS[code]}` : code);
1511
- else if (code && NETWORK_HINTS[code]) add(`(${NETWORK_HINTS[code]})`);
1579
+ } else if (code && !msg.includes(code)) add(NETWORK_HINTS2[code] ? `${code}: ${NETWORK_HINTS2[code]}` : code);
1580
+ else if (code && NETWORK_HINTS2[code]) add(`(${NETWORK_HINTS2[code]})`);
1512
1581
  if (Array.isArray(err.errors)) for (const inner of err.errors.slice(0, 3)) walk2(inner, depth + 1);
1513
1582
  walk2(err.cause, depth + 1);
1514
1583
  };
@@ -3364,7 +3433,7 @@ function ensureUniqueIds(ws, rel) {
3364
3433
  }
3365
3434
 
3366
3435
  // cli/src/index.ts
3367
- var VERSION = true ? "1.1.14" : "0.0.0-dev";
3436
+ var VERSION = true ? "1.12.0" : "0.0.0-dev";
3368
3437
  setYamletVersion(VERSION);
3369
3438
  var CliError = class extends Error {
3370
3439
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piyushdoorwar/yamlet",
3
- "version": "1.1.14",
3
+ "version": "1.12.0",
4
4
  "description": "Run Yamlet API collections (Git-friendly YAML) from the command line or CI.",
5
5
  "type": "module",
6
6
  "bin": {