chofex-cli 0.1.47 → 0.1.49

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 +4 -0
  2. package/dist/index.js +102 -51
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -34,6 +34,10 @@ use `requirements` only when requirements-only human output is preferred.
34
34
  Run `chofex login` to authenticate. For automation, provide an OAuth access
35
35
  token with `CHOFEX_TOKEN`.
36
36
 
37
+ When applying again after a rejection, interactive registration pre-fills the
38
+ previous application's answers. Keep a value by pressing Enter, or press Ctrl+U
39
+ and type a replacement for an answer that needs to change.
40
+
37
41
  Accepted participants must confirm which profile picture reviewers should use:
38
42
  their Clerk picture, their GitHub avatar, or a custom upload. Interactive
39
43
  confirmation prompts for the choice and local file path. For JSON input, set
package/dist/index.js CHANGED
@@ -59239,7 +59239,7 @@ var processProfileUsername = (input, state, validate3) => {
59239
59239
  onSome: (value3) => insertInput(state, value3)
59240
59240
  }));
59241
59241
  };
59242
- var profileUsernamePrompt = (message, profilePrefix, validate3 = exports_Effect.succeed) => exports_Prompt.custom({ cursor: 0, value: "" }, {
59242
+ var profileUsernamePrompt = (message, profilePrefix, validate3 = exports_Effect.succeed, defaultValue = "") => exports_Prompt.custom({ cursor: defaultValue.length, value: defaultValue }, {
59243
59243
  render: (state, action2) => {
59244
59244
  if (action2._tag === "Beep")
59245
59245
  return exports_Effect.succeed(ansi.beep);
@@ -59251,13 +59251,14 @@ var profileUsernamePrompt = (message, profilePrefix, validate3 = exports_Effect.
59251
59251
 
59252
59252
  // src/input.ts
59253
59253
  var validatePromptValue = (schema, value3) => exports_Schema.decodeUnknownEffect(schema)(value3).pipe(exports_Effect.asVoid, exports_Effect.mapError((error2) => error2.message));
59254
- var requiredText = (message, schema) => exports_Prompt.text({
59254
+ var requiredText = (message, schema, defaultValue = "") => exports_Prompt.text({
59255
59255
  message,
59256
+ default: defaultValue,
59256
59257
  validate: (value3) => validatePromptValue(schema, value3).pipe(exports_Effect.as(value3))
59257
59258
  });
59258
- var optionalText2 = (message, schema) => exports_Prompt.text({
59259
+ var optionalText2 = (message, schema, defaultValue = "") => exports_Prompt.text({
59259
59260
  message,
59260
- default: "",
59261
+ default: defaultValue,
59261
59262
  validate: (value3) => {
59262
59263
  if (value3 === "")
59263
59264
  return exports_Effect.succeed(value3);
@@ -59276,7 +59277,54 @@ var dateOfBirthPrompt = () => exports_Prompt.text({
59276
59277
  });
59277
59278
  var githubProfilePrefix = "github.com/";
59278
59279
  var linkedInProfilePrefix = "linkedin.com/in/";
59280
+ var profileUsernameFromUrl = (profileUrl, profilePrefix) => {
59281
+ if (!profileUrl)
59282
+ return "";
59283
+ const normalized = profileUrl.replace(/^https?:\/\/(?:www\.)?/i, "").replace(/\/$/, "");
59284
+ if (!normalized.toLowerCase().startsWith(profilePrefix))
59285
+ return "";
59286
+ const username = normalized.slice(profilePrefix.length);
59287
+ if (!/^[A-Za-z0-9._-]+$/.test(username))
59288
+ return "";
59289
+ return username;
59290
+ };
59291
+ var profileUrlPrompt = (usernameMessage, urlMessage, profilePrefix, schema, defaultUrl) => {
59292
+ const defaultUsername = profileUsernameFromUrl(defaultUrl, profilePrefix);
59293
+ if (defaultUrl && !defaultUsername) {
59294
+ return optionalText2(urlMessage, schema, defaultUrl);
59295
+ }
59296
+ return profileUsernamePrompt(usernameMessage, profilePrefix, (value3) => {
59297
+ if (value3 === "")
59298
+ return exports_Effect.succeed(value3);
59299
+ return validatePromptValue(schema, `${profilePrefix}${value3}`).pipe(exports_Effect.as(value3));
59300
+ }, defaultUsername).pipe(exports_Prompt.map((value3) => {
59301
+ if (value3 === "")
59302
+ return value3;
59303
+ return `${profilePrefix}${value3}`;
59304
+ }));
59305
+ };
59279
59306
  var withoutEmptyStrings = (input) => Object.fromEntries(Object.entries(input).filter(([, value3]) => value3 !== "" && value3 !== undefined));
59307
+ var applicationDefaultsFromRegistration = (registration) => ({
59308
+ firstName: registration.firstName,
59309
+ lastName: registration.lastName,
59310
+ pronouns: registration.pronouns,
59311
+ city: registration.city,
59312
+ organization: registration.organization,
59313
+ role: registration.role,
59314
+ fieldOfStudy: registration.fieldOfStudy,
59315
+ graduationYear: registration.graduationYear,
59316
+ shippedProject: registration.shippedProject,
59317
+ hackathonProject: registration.hackathonProject,
59318
+ bio: registration.bio,
59319
+ githubUrl: registration.githubUrl,
59320
+ linkedInUrl: registration.linkedInUrl,
59321
+ portfolioUrl: registration.portfolioUrl,
59322
+ teamPreference: registration.teamPreference,
59323
+ teamName: registration.teamName,
59324
+ codeOfConductAccepted: true,
59325
+ privacyPolicyAccepted: true,
59326
+ mediaConsent: registration.mediaConsent
59327
+ });
59280
59328
  var readStdin = async () => {
59281
59329
  const chunks = [];
59282
59330
  for await (const chunk of process.stdin) {
@@ -59307,50 +59355,55 @@ var validateSemantics = (input, requirements) => {
59307
59355
  issues: requirements
59308
59356
  }));
59309
59357
  };
59310
- var applicationDetailsPrompts = exports_Prompt.all({
59311
- firstName: requiredText("First name", applicationInputFields.firstName),
59312
- lastName: requiredText("Last name", applicationInputFields.lastName),
59313
- pronouns: optionalText2("Pronouns (optional)", applicationInputFields.pronouns),
59314
- city: requiredText("City of residence in Peru", applicationInputFields.city),
59315
- organization: optionalText2("Organization (optional)", applicationInputFields.organization),
59316
- role: optionalText2("Role (optional)", applicationInputFields.role),
59317
- fieldOfStudy: optionalText2("Field of study (optional)", applicationInputFields.fieldOfStudy),
59358
+ var applicationDetailsPrompts = (defaults2) => exports_Prompt.all({
59359
+ firstName: requiredText("First name", applicationInputFields.firstName, defaults2.firstName),
59360
+ lastName: requiredText("Last name", applicationInputFields.lastName, defaults2.lastName),
59361
+ pronouns: optionalText2("Pronouns (optional)", applicationInputFields.pronouns, defaults2.pronouns),
59362
+ city: requiredText("City of residence in Peru", applicationInputFields.city, defaults2.city),
59363
+ organization: optionalText2("Organization (optional)", applicationInputFields.organization, defaults2.organization),
59364
+ role: optionalText2("Role (optional)", applicationInputFields.role, defaults2.role),
59365
+ fieldOfStudy: optionalText2("Field of study (optional)", applicationInputFields.fieldOfStudy, defaults2.fieldOfStudy),
59318
59366
  graduationYear: exports_Prompt.text({
59319
59367
  message: "Graduation year (optional)",
59320
- default: "",
59368
+ default: defaults2.graduationYear?.toString() ?? "",
59321
59369
  validate: (value3) => {
59322
59370
  if (value3 === "")
59323
59371
  return exports_Effect.succeed(value3);
59324
59372
  return validatePromptValue(applicationInputFields.graduationYear, Number(value3)).pipe(exports_Effect.as(value3));
59325
59373
  }
59326
59374
  }),
59327
- shippedProject: requiredText("What have you shipped?", applicationInputFields.shippedProject),
59328
- hackathonProject: requiredText("What do you want to ship at the hackathon?", applicationInputFields.hackathonProject),
59329
- bio: requiredText("Short bio", applicationInputFields.bio),
59330
- githubUsername: profileUsernamePrompt("GitHub username (optional)", githubProfilePrefix, (value3) => {
59331
- if (value3 === "")
59332
- return exports_Effect.succeed(value3);
59333
- return validatePromptValue(applicationInputFields.githubUrl, `${githubProfilePrefix}${value3}`).pipe(exports_Effect.as(value3));
59334
- }),
59335
- linkedInUsername: profileUsernamePrompt("LinkedIn username (optional)", linkedInProfilePrefix, (value3) => {
59336
- if (value3 === "")
59337
- return exports_Effect.succeed(value3);
59338
- return validatePromptValue(applicationInputFields.linkedInUrl, `${linkedInProfilePrefix}${value3}`).pipe(exports_Effect.as(value3));
59339
- }),
59340
- portfolioUrl: optionalText2("Portfolio URL (optional)", applicationInputFields.portfolioUrl)
59341
- });
59342
- var teamPreferencePrompt = exports_Prompt.select({
59375
+ shippedProject: requiredText("What have you shipped?", applicationInputFields.shippedProject, defaults2.shippedProject),
59376
+ hackathonProject: requiredText("What do you want to ship at the hackathon?", applicationInputFields.hackathonProject, defaults2.hackathonProject),
59377
+ bio: requiredText("Short bio", applicationInputFields.bio, defaults2.bio),
59378
+ githubUrl: profileUrlPrompt("GitHub username (optional)", "GitHub URL (optional)", githubProfilePrefix, applicationInputFields.githubUrl, defaults2.githubUrl),
59379
+ linkedInUrl: profileUrlPrompt("LinkedIn username (optional)", "LinkedIn URL (optional)", linkedInProfilePrefix, applicationInputFields.linkedInUrl, defaults2.linkedInUrl),
59380
+ portfolioUrl: optionalText2("Portfolio URL (optional)", applicationInputFields.portfolioUrl, defaults2.portfolioUrl)
59381
+ });
59382
+ var teamPreferencePrompt = (defaultValue) => exports_Prompt.select({
59343
59383
  message: "Team preference",
59344
59384
  choices: [
59345
- { title: "I have a team", value: "have_team" },
59346
- { title: "I am looking for a team", value: "looking_for_team" },
59347
- { title: "I will participate solo", value: "solo" }
59385
+ {
59386
+ title: "I have a team",
59387
+ value: "have_team",
59388
+ selected: defaultValue === "have_team"
59389
+ },
59390
+ {
59391
+ title: "I am looking for a team",
59392
+ value: "looking_for_team",
59393
+ selected: defaultValue === "looking_for_team"
59394
+ },
59395
+ {
59396
+ title: "I will participate solo",
59397
+ value: "solo",
59398
+ selected: defaultValue === "solo"
59399
+ }
59348
59400
  ]
59349
59401
  });
59350
59402
  var publicDocumentUrl = (baseUrl, path4) => `${baseUrl.replace(/\/$/, "")}${path4}`;
59351
- var requiredAgreement = exports_Effect.fn("requiredAgreement")(function* (name, url2) {
59403
+ var requiredAgreement = exports_Effect.fn("requiredAgreement")(function* (name, url2, initial = false) {
59352
59404
  const accepted = yield* exports_Prompt.run(exports_Prompt.confirm({
59353
- message: `Do you accept the ${name}? Read it at ${url2}`
59405
+ message: `Do you accept the ${name}? Read it at ${url2}`,
59406
+ initial
59354
59407
  }));
59355
59408
  if (accepted)
59356
59409
  return true;
@@ -59368,17 +59421,18 @@ var requiredAgreement = exports_Effect.fn("requiredAgreement")(function* (name,
59368
59421
  return true;
59369
59422
  return yield* cliError("REGISTRATION_CANCELLED", "Registration cancelled. Your answers were not submitted.");
59370
59423
  });
59371
- var interactiveApplication = (publicBaseUrl) => exports_Effect.gen(function* () {
59372
- const details = yield* exports_Prompt.run(applicationDetailsPrompts);
59373
- const teamPreference = yield* exports_Prompt.run(teamPreferencePrompt);
59424
+ var interactiveApplication = (publicBaseUrl, defaults2) => exports_Effect.gen(function* () {
59425
+ const details = yield* exports_Prompt.run(applicationDetailsPrompts(defaults2));
59426
+ const teamPreference = yield* exports_Prompt.run(teamPreferencePrompt(defaults2.teamPreference));
59374
59427
  let teamName;
59375
59428
  if (teamPreference === "have_team") {
59376
- teamName = yield* exports_Prompt.run(requiredText("Team name", applicationInputFields.teamName));
59429
+ teamName = yield* exports_Prompt.run(requiredText("Team name", applicationInputFields.teamName, defaults2.teamName));
59377
59430
  }
59378
- const codeOfConductAccepted = yield* requiredAgreement("Terms and Code of Conduct", publicDocumentUrl(publicBaseUrl, "/terms"));
59379
- const privacyPolicyAccepted = yield* requiredAgreement("Privacy Policy", publicDocumentUrl(publicBaseUrl, "/privacy"));
59431
+ const codeOfConductAccepted = yield* requiredAgreement("Terms and Code of Conduct", publicDocumentUrl(publicBaseUrl, "/terms"), defaults2.codeOfConductAccepted);
59432
+ const privacyPolicyAccepted = yield* requiredAgreement("Privacy Policy", publicDocumentUrl(publicBaseUrl, "/privacy"), defaults2.privacyPolicyAccepted);
59380
59433
  const mediaConsent = yield* exports_Prompt.run(exports_Prompt.confirm({
59381
- message: "Do you consent to appearing in event media? (optional)"
59434
+ message: "Do you consent to appearing in event media? (optional)",
59435
+ initial: defaults2.mediaConsent ?? false
59382
59436
  }));
59383
59437
  return {
59384
59438
  ...details,
@@ -59389,17 +59443,10 @@ var interactiveApplication = (publicBaseUrl) => exports_Effect.gen(function* ()
59389
59443
  mediaConsent
59390
59444
  };
59391
59445
  }).pipe(exports_Effect.map((input) => {
59392
- const { githubUsername, linkedInUsername, ...application } = input;
59393
- const normalized = withoutEmptyStrings(application);
59446
+ const normalized = withoutEmptyStrings(input);
59394
59447
  if (input.graduationYear !== "") {
59395
59448
  normalized.graduationYear = Number(input.graduationYear);
59396
59449
  }
59397
- if (githubUsername !== "") {
59398
- normalized.githubUrl = `${githubProfilePrefix}${githubUsername}`;
59399
- }
59400
- if (linkedInUsername !== "") {
59401
- normalized.linkedInUrl = `${linkedInProfilePrefix}${linkedInUsername}`;
59402
- }
59403
59450
  return normalized;
59404
59451
  }));
59405
59452
  var shirtSizePrompt = (participationMode) => {
@@ -59474,7 +59521,7 @@ var inputOrInteractive = (path4, interactive) => {
59474
59521
  return cliError("PROMPT_CANCELLED", "Interactive input was cancelled");
59475
59522
  }));
59476
59523
  };
59477
- var applicationInput = (path4, publicBaseUrl) => inputOrInteractive(path4, interactiveApplication(publicBaseUrl)).pipe(exports_Effect.flatMap((input) => decode2(ApplicationInput, input, applicationInputFieldNames)), exports_Effect.flatMap((input) => validateSemantics(input, applicationSemanticRequirements(input))));
59524
+ var applicationInput = (path4, publicBaseUrl, defaults2 = {}) => inputOrInteractive(path4, interactiveApplication(publicBaseUrl, defaults2)).pipe(exports_Effect.flatMap((input) => decode2(ApplicationInput, input, applicationInputFieldNames)), exports_Effect.flatMap((input) => validateSemantics(input, applicationSemanticRequirements(input))));
59478
59525
  var acceptedDetailsInput = (path4, participationMode, pictures = {}) => inputOrInteractive(path4, interactiveAcceptedDetails(participationMode, pictures)).pipe(exports_Effect.flatMap((input) => decode2(AcceptedDetailsInput, input, acceptedDetailsInputFieldNames)), exports_Effect.flatMap((input) => validateSemantics(input, acceptedDetailsSemanticRequirements(input, participationMode))));
59479
59526
  var picturePathInput = (suppliedPath) => {
59480
59527
  if (suppliedPath)
@@ -61297,7 +61344,11 @@ var registerCommand = exports_Command.make("register", { input: inputFlag }, exp
61297
61344
  });
61298
61345
  }
61299
61346
  }
61300
- const body = yield* applicationInput(exports_Option.getOrUndefined(input), config.publicSiteUrl);
61347
+ let applicationDefaults;
61348
+ if (exports_Option.isSome(current) && current.value.data.registration.status === "rejected") {
61349
+ applicationDefaults = applicationDefaultsFromRegistration(current.value.data.registration);
61350
+ }
61351
+ const body = yield* applicationInput(exports_Option.getOrUndefined(input), config.publicSiteUrl, applicationDefaults);
61301
61352
  return yield* register(client, body);
61302
61353
  });
61303
61354
  yield* execute(options.output, operation, createdText);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chofex-cli",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "description": "Command-line client for the Chofex Hackathon",
5
5
  "type": "module",
6
6
  "bin": {