chofex-cli 0.1.149 → 0.1.172

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 (3) hide show
  1. package/README.md +8 -5
  2. package/dist/index.js +40 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -101,11 +101,14 @@ chofex --output json whoami
101
101
  ```
102
102
 
103
103
  Versions before `0.1.140` used a retired API origin whose cross-origin redirect
104
- removed the bearer token. Current releases call `https://hacktheandes.com`
105
- directly. If the API still responds with `Authentication failed`, share the CLI
106
- version, error code, and request ID when asking for support. For a different
107
- local authentication error, share its code and message instead. Never share the
108
- access or refresh token.
104
+ removed the bearer token. Versions `0.1.140` through `0.1.145` call
105
+ `https://hacktheandes.com` but still mint OAuth tokens from the retired Clerk
106
+ application, so login can print success while `whoami` and `status` return
107
+ `AUTHENTICATION_REQUIRED`. Current releases (`0.1.146` and later) use
108
+ `https://clerk.hacktheandes.com`. If the API still responds with
109
+ `Authentication failed` after updating, share the CLI version, error code, and
110
+ request ID when asking for support. For a different local authentication error,
111
+ share its code and message instead. Never share the access or refresh token.
109
112
 
110
113
  When applying again after a rejection, interactive registration pre-fills the
111
114
  previous application's answers. Keep a value by pressing Enter, or press Ctrl+U
package/dist/index.js CHANGED
@@ -58729,6 +58729,13 @@ var ParticipantChallengeProgressSchema = exports_Schema.Struct({
58729
58729
  shareCode: exports_Schema.optional(exports_Schema.String),
58730
58730
  rank: exports_Schema.optional(exports_Schema.Number)
58731
58731
  });
58732
+ var ParticipantChallengeMilestoneSchema = exports_Schema.Struct({
58733
+ attemptId: exports_Schema.String,
58734
+ slug: exports_Schema.String,
58735
+ title: exports_Schema.String,
58736
+ startedAt: exports_Schema.String,
58737
+ completedAt: exports_Schema.optional(exports_Schema.String)
58738
+ });
58732
58739
  var ChallengeCatalogItemSchema = exports_Schema.Struct({
58733
58740
  slug: ChallengeSlugSchema,
58734
58741
  number: exports_Schema.Number,
@@ -59583,13 +59590,20 @@ var exitCodeFor = (error2) => {
59583
59590
  };
59584
59591
 
59585
59592
  // src/api-client.ts
59593
+ var authenticationRecoveryMessage = (code, message) => {
59594
+ if (code !== "AUTHENTICATION_REQUIRED")
59595
+ return message;
59596
+ if (message !== "Authentication failed")
59597
+ return message;
59598
+ return `${message}. If login just succeeded, update the CLI with \`chofex update\` or \`npm install --global chofex-cli@latest\`, then run \`chofex logout\` and \`chofex login\`.`;
59599
+ };
59586
59600
  var endpoint = (apiUrl, path4) => `${apiUrl.replace(/\/$/, "")}${path4}`;
59587
- var resolveAuthentication = (suppliedToken, campaignAttribution, forceRefresh = false) => {
59601
+ var resolveAuthentication = (suppliedToken, campaignAttribution, authenticate, forceRefresh = false) => {
59588
59602
  if (suppliedToken) {
59589
59603
  return exports_Effect.succeed({ accessToken: suppliedToken, campaignAttribution });
59590
59604
  }
59591
59605
  return exports_Effect.tryPromise({
59592
- try: () => authentication(forceRefresh),
59606
+ try: () => authenticate(forceRefresh),
59593
59607
  catch: (error2) => cliError("AUTHENTICATION_REQUIRED", String(error2), false)
59594
59608
  });
59595
59609
  };
@@ -59625,7 +59639,7 @@ var decodeHttpBody = exports_Effect.fn("decodeHttpBody")(function* (response, de
59625
59639
  if (!response.ok) {
59626
59640
  const failure = exports_Schema.decodeUnknownResult(ApiFailureSchema)(body);
59627
59641
  if (exports_Result.isSuccess(failure)) {
59628
- return yield* cliError(failure.success.error.code, failure.success.error.message, failure.success.error.retryable, failure.success.error.details, failure.success.requestId);
59642
+ return yield* cliError(failure.success.error.code, authenticationRecoveryMessage(failure.success.error.code, failure.success.error.message), failure.success.error.retryable, failure.success.error.details, failure.success.requestId);
59629
59643
  }
59630
59644
  return yield* cliError("HTTP_ERROR", `The API request failed with status ${response.status}`, response.status >= 500);
59631
59645
  }
@@ -59633,11 +59647,14 @@ var decodeHttpBody = exports_Effect.fn("decodeHttpBody")(function* (response, de
59633
59647
  });
59634
59648
  var request3 = exports_Effect.fn("apiRequest")(function* (options, path4, init, decodeResponse) {
59635
59649
  const suppliedToken = options.token ?? process.env.CHOFEX_TOKEN;
59636
- let credentials = yield* resolveAuthentication(suppliedToken, options.campaignAttribution);
59650
+ const authenticate = options.authenticate ?? authentication;
59651
+ const credentials = yield* resolveAuthentication(suppliedToken, options.campaignAttribution, authenticate);
59637
59652
  let response = yield* sendRequest(options, path4, init, credentials);
59638
59653
  if (response.status === 401 && !suppliedToken) {
59639
- credentials = yield* resolveAuthentication(undefined, undefined, true);
59640
- response = yield* sendRequest(options, path4, init, credentials);
59654
+ const refreshed = yield* resolveAuthentication(undefined, undefined, authenticate, true).pipe(exports_Effect.map((value3) => ({ ok: true, value: value3 })), exports_Effect.catch(() => exports_Effect.succeed({ ok: false })));
59655
+ if (refreshed.ok) {
59656
+ response = yield* sendRequest(options, path4, init, refreshed.value);
59657
+ }
59641
59658
  }
59642
59659
  return yield* decodeHttpBody(response, decodeResponse);
59643
59660
  });
@@ -59977,7 +59994,7 @@ var challengeRankingText = (ranking, now3 = new Date) => {
59977
59994
  return lines2.join(`
59978
59995
  `);
59979
59996
  }
59980
- lines2.push(`${ranking.competitorCount} official evaluations`, "");
59997
+ lines2.push("");
59981
59998
  if (ranking.entries.length === 0) {
59982
59999
  lines2.push("No official evaluations yet.");
59983
60000
  return lines2.join(`
@@ -62744,15 +62761,27 @@ var loginCommand = exports_Command.make("login", {}, exports_Effect.fn("loginCom
62744
62761
  try: () => login(),
62745
62762
  catch: (error2) => cliError("LOGIN_FAILED", String(error2))
62746
62763
  });
62747
- yield* getCurrentUser({ apiUrl: options.apiUrl, token }).pipe(exports_Effect.catch(() => exports_Effect.succeed(undefined)));
62764
+ const currentUser = yield* getCurrentUser({
62765
+ apiUrl: options.apiUrl,
62766
+ token
62767
+ });
62768
+ const environmentTokenActive = Boolean(process.env.CHOFEX_TOKEN);
62748
62769
  return {
62749
62770
  version: 1,
62750
62771
  ok: true,
62751
- requestId: crypto.randomUUID(),
62752
- data: { authenticated: true }
62772
+ requestId: currentUser.requestId,
62773
+ data: {
62774
+ authenticated: true,
62775
+ environmentTokenActive
62776
+ }
62753
62777
  };
62754
62778
  });
62755
- yield* execute(options.output, operation, () => "Signed in successfully.");
62779
+ yield* execute(options.output, operation, (result3) => {
62780
+ if (result3.environmentTokenActive) {
62781
+ return "Signed in successfully. CHOFEX_TOKEN is set and will override the stored session; unset it before running other commands.";
62782
+ }
62783
+ return "Signed in successfully.";
62784
+ });
62756
62785
  })).pipe(exports_Command.withDescription("Sign in through Clerk OAuth in your browser"));
62757
62786
  var logoutCommand = exports_Command.make("logout", {}, exports_Effect.fn("logoutCommand")(function* () {
62758
62787
  const options = yield* root;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chofex-cli",
3
- "version": "0.1.149",
3
+ "version": "0.1.172",
4
4
  "description": "Command-line client for Hack the Andes",
5
5
  "type": "module",
6
6
  "bin": {