@agi-ventures-canada/hackathon-cli 0.1.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 (121) hide show
  1. package/bin/cli.mjs +11 -0
  2. package/dist/_chunks/assign.mjs +35 -0
  3. package/dist/_chunks/assign.mjs.map +1 -0
  4. package/dist/_chunks/assignments-create.mjs +37 -0
  5. package/dist/_chunks/assignments-create.mjs.map +1 -0
  6. package/dist/_chunks/assignments-delete.mjs +22 -0
  7. package/dist/_chunks/assignments-delete.mjs.map +1 -0
  8. package/dist/_chunks/assignments-list.mjs +35 -0
  9. package/dist/_chunks/assignments-list.mjs.map +1 -0
  10. package/dist/_chunks/auto-assign.mjs +31 -0
  11. package/dist/_chunks/auto-assign.mjs.map +1 -0
  12. package/dist/_chunks/calculate.mjs +18 -0
  13. package/dist/_chunks/calculate.mjs.map +1 -0
  14. package/dist/_chunks/cancel.mjs +22 -0
  15. package/dist/_chunks/cancel.mjs.map +1 -0
  16. package/dist/_chunks/config.mjs +70 -0
  17. package/dist/_chunks/config.mjs.map +1 -0
  18. package/dist/_chunks/constants.mjs +14 -0
  19. package/dist/_chunks/constants.mjs.map +1 -0
  20. package/dist/_chunks/create.mjs +66 -0
  21. package/dist/_chunks/create.mjs.map +1 -0
  22. package/dist/_chunks/create2.mjs +47 -0
  23. package/dist/_chunks/create2.mjs.map +1 -0
  24. package/dist/_chunks/create3.mjs +51 -0
  25. package/dist/_chunks/create3.mjs.map +1 -0
  26. package/dist/_chunks/create4.mjs +55 -0
  27. package/dist/_chunks/create4.mjs.map +1 -0
  28. package/dist/_chunks/create5.mjs +60 -0
  29. package/dist/_chunks/create5.mjs.map +1 -0
  30. package/dist/_chunks/create6.mjs +57 -0
  31. package/dist/_chunks/create6.mjs.map +1 -0
  32. package/dist/_chunks/criteria-create.mjs +77 -0
  33. package/dist/_chunks/criteria-create.mjs.map +1 -0
  34. package/dist/_chunks/criteria-delete.mjs +22 -0
  35. package/dist/_chunks/criteria-delete.mjs.map +1 -0
  36. package/dist/_chunks/criteria-list.mjs +35 -0
  37. package/dist/_chunks/criteria-list.mjs.map +1 -0
  38. package/dist/_chunks/criteria-update.mjs +49 -0
  39. package/dist/_chunks/criteria-update.mjs.map +1 -0
  40. package/dist/_chunks/delete.mjs +24 -0
  41. package/dist/_chunks/delete.mjs.map +1 -0
  42. package/dist/_chunks/delete2.mjs +22 -0
  43. package/dist/_chunks/delete2.mjs.map +1 -0
  44. package/dist/_chunks/delete3.mjs +22 -0
  45. package/dist/_chunks/delete3.mjs.map +1 -0
  46. package/dist/_chunks/delete4.mjs +22 -0
  47. package/dist/_chunks/delete4.mjs.map +1 -0
  48. package/dist/_chunks/delete5.mjs +22 -0
  49. package/dist/_chunks/delete5.mjs.map +1 -0
  50. package/dist/_chunks/get.mjs +61 -0
  51. package/dist/_chunks/get.mjs.map +1 -0
  52. package/dist/_chunks/get2.mjs +43 -0
  53. package/dist/_chunks/get2.mjs.map +1 -0
  54. package/dist/_chunks/get3.mjs +39 -0
  55. package/dist/_chunks/get3.mjs.map +1 -0
  56. package/dist/_chunks/get4.mjs +47 -0
  57. package/dist/_chunks/get4.mjs.map +1 -0
  58. package/dist/_chunks/hackathons.mjs +64 -0
  59. package/dist/_chunks/hackathons.mjs.map +1 -0
  60. package/dist/_chunks/invitations-cancel.mjs +22 -0
  61. package/dist/_chunks/invitations-cancel.mjs.map +1 -0
  62. package/dist/_chunks/invitations-list.mjs +31 -0
  63. package/dist/_chunks/invitations-list.mjs.map +1 -0
  64. package/dist/_chunks/judges-add.mjs +37 -0
  65. package/dist/_chunks/judges-add.mjs.map +1 -0
  66. package/dist/_chunks/judges-list.mjs +35 -0
  67. package/dist/_chunks/judges-list.mjs.map +1 -0
  68. package/dist/_chunks/judges-remove.mjs +22 -0
  69. package/dist/_chunks/judges-remove.mjs.map +1 -0
  70. package/dist/_chunks/list.mjs +39 -0
  71. package/dist/_chunks/list.mjs.map +1 -0
  72. package/dist/_chunks/list2.mjs +37 -0
  73. package/dist/_chunks/list2.mjs.map +1 -0
  74. package/dist/_chunks/list3.mjs +31 -0
  75. package/dist/_chunks/list3.mjs.map +1 -0
  76. package/dist/_chunks/list4.mjs +35 -0
  77. package/dist/_chunks/list4.mjs.map +1 -0
  78. package/dist/_chunks/list5.mjs +39 -0
  79. package/dist/_chunks/list5.mjs.map +1 -0
  80. package/dist/_chunks/list6.mjs +40 -0
  81. package/dist/_chunks/list6.mjs.map +1 -0
  82. package/dist/_chunks/login.mjs +114 -0
  83. package/dist/_chunks/login.mjs.map +1 -0
  84. package/dist/_chunks/logout.mjs +16 -0
  85. package/dist/_chunks/logout.mjs.map +1 -0
  86. package/dist/_chunks/org.mjs +35 -0
  87. package/dist/_chunks/org.mjs.map +1 -0
  88. package/dist/_chunks/pick-results.mjs +35 -0
  89. package/dist/_chunks/pick-results.mjs.map +1 -0
  90. package/dist/_chunks/publish.mjs +22 -0
  91. package/dist/_chunks/publish.mjs.map +1 -0
  92. package/dist/_chunks/reorder.mjs +16 -0
  93. package/dist/_chunks/reorder.mjs.map +1 -0
  94. package/dist/_chunks/reorder2.mjs +16 -0
  95. package/dist/_chunks/reorder2.mjs.map +1 -0
  96. package/dist/_chunks/resolve.mjs +15 -0
  97. package/dist/_chunks/resolve.mjs.map +1 -0
  98. package/dist/_chunks/result.mjs +46 -0
  99. package/dist/_chunks/result.mjs.map +1 -0
  100. package/dist/_chunks/results.mjs +43 -0
  101. package/dist/_chunks/results.mjs.map +1 -0
  102. package/dist/_chunks/submissions.mjs +35 -0
  103. package/dist/_chunks/submissions.mjs.map +1 -0
  104. package/dist/_chunks/unassign.mjs +22 -0
  105. package/dist/_chunks/unassign.mjs.map +1 -0
  106. package/dist/_chunks/unpublish.mjs +22 -0
  107. package/dist/_chunks/unpublish.mjs.map +1 -0
  108. package/dist/_chunks/update.mjs +47 -0
  109. package/dist/_chunks/update.mjs.map +1 -0
  110. package/dist/_chunks/update2.mjs +45 -0
  111. package/dist/_chunks/update2.mjs.map +1 -0
  112. package/dist/_chunks/update3.mjs +49 -0
  113. package/dist/_chunks/update3.mjs.map +1 -0
  114. package/dist/_chunks/update4.mjs +48 -0
  115. package/dist/_chunks/update4.mjs.map +1 -0
  116. package/dist/_chunks/whoami.mjs +31 -0
  117. package/dist/_chunks/whoami.mjs.map +1 -0
  118. package/dist/cli.d.mts +1 -0
  119. package/dist/cli.mjs +711 -0
  120. package/dist/cli.mjs.map +1 -0
  121. package/package.json +35 -0
@@ -0,0 +1,114 @@
1
+ import { a as POLL_INTERVAL_MS, t as AUTH_TIMEOUT_MS } from "./constants.mjs";
2
+ import { n as loadConfig, r as saveConfig } from "./config.mjs";
3
+ import { o as OatmealClient } from "../cli.mjs";
4
+ import * as p from "@clack/prompts";
5
+ import { randomBytes } from "node:crypto";
6
+ import { execSync } from "node:child_process";
7
+ //#region src/commands/login.ts
8
+ function parseLoginOptions(args) {
9
+ const options = {};
10
+ for (let i = 0; i < args.length; i++) switch (args[i]) {
11
+ case "--api-key":
12
+ options.apiKey = args[++i];
13
+ break;
14
+ case "--no-browser":
15
+ options.noBrowser = true;
16
+ break;
17
+ case "--base-url":
18
+ options.baseUrl = args[++i];
19
+ break;
20
+ case "--yes":
21
+ case "-y":
22
+ options.yes = true;
23
+ break;
24
+ }
25
+ return options;
26
+ }
27
+ async function runLogin(args) {
28
+ const options = parseLoginOptions(args);
29
+ const baseUrl = options.baseUrl ?? "https://oatmeal.app";
30
+ if (loadConfig() && !options.yes && !options.apiKey && !process.env.OATMEAL_API_KEY) {
31
+ const overwrite = await p.confirm({ message: "You are already logged in. Overwrite existing config?" });
32
+ if (p.isCancel(overwrite) || !overwrite) {
33
+ p.log.info("Login cancelled.");
34
+ return;
35
+ }
36
+ }
37
+ const key = options.apiKey ?? process.env.OATMEAL_API_KEY;
38
+ if (key) {
39
+ await validateAndSaveKey(key, baseUrl);
40
+ return;
41
+ }
42
+ if (options.noBrowser || !process.stdout.isTTY) {
43
+ const pastedKey = await p.password({ message: "Paste your API key:" });
44
+ if (p.isCancel(pastedKey)) {
45
+ p.log.info("Login cancelled.");
46
+ return;
47
+ }
48
+ await validateAndSaveKey(pastedKey, baseUrl);
49
+ return;
50
+ }
51
+ const deviceToken = randomBytes(32).toString("hex");
52
+ const authUrl = `${baseUrl}/cli-auth?token=${deviceToken}`;
53
+ p.log.info(`Opening browser to sign in...`);
54
+ p.log.info(authUrl);
55
+ try {
56
+ openBrowser(authUrl);
57
+ } catch {
58
+ p.log.warn("Could not open browser. Visit the URL above manually.");
59
+ }
60
+ const spinner = p.spinner();
61
+ spinner.start("Waiting for authentication...");
62
+ try {
63
+ const apiKey = await pollForKey(baseUrl, deviceToken);
64
+ spinner.stop("Authenticated!");
65
+ await validateAndSaveKey(apiKey, baseUrl);
66
+ } catch (error) {
67
+ spinner.stop("Authentication failed.");
68
+ throw error;
69
+ }
70
+ }
71
+ function openBrowser(url) {
72
+ const platform = process.platform;
73
+ execSync(`${platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open"} "${url}"`, { stdio: "ignore" });
74
+ }
75
+ async function pollForKey(baseUrl, deviceToken) {
76
+ const client = new OatmealClient({ baseUrl });
77
+ const start = Date.now();
78
+ while (Date.now() - start < AUTH_TIMEOUT_MS) {
79
+ const result = await client.get("/api/public/cli-auth/poll", { params: { token: deviceToken } });
80
+ if (result.status === "complete" && result.apiKey) return result.apiKey;
81
+ if (result.status === "expired") throw new Error("Authentication session expired. Please try again.");
82
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
83
+ }
84
+ throw new Error("Authentication timed out after 5 minutes. Please try again.");
85
+ }
86
+ async function validateAndSaveKey(apiKey, baseUrl) {
87
+ const client = new OatmealClient({
88
+ baseUrl,
89
+ apiKey
90
+ });
91
+ const spinner = p.spinner();
92
+ spinner.start("Validating API key...");
93
+ try {
94
+ const whoami = await client.get("/api/v1/whoami");
95
+ spinner.stop("Key validated!");
96
+ saveConfig({
97
+ apiKey,
98
+ baseUrl,
99
+ tenantId: whoami.tenantId,
100
+ keyId: whoami.keyId,
101
+ scopes: whoami.scopes
102
+ });
103
+ p.log.success(`Logged in! Key saved to ~/.oatmeal/config.json`);
104
+ p.log.info(`Tenant: ${whoami.tenantId}`);
105
+ p.log.info(`Scopes: ${whoami.scopes.join(", ")}`);
106
+ } catch (error) {
107
+ spinner.stop("Validation failed.");
108
+ throw error;
109
+ }
110
+ }
111
+ //#endregion
112
+ export { runLogin };
113
+
114
+ //# sourceMappingURL=login.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.mjs","names":[],"sources":["../../src/commands/login.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\"\nimport { execSync } from \"node:child_process\"\nimport * as p from \"@clack/prompts\"\nimport { OatmealClient } from \"../client.js\"\nimport { loadConfig, saveConfig } from \"../config.js\"\nimport { AUTH_TIMEOUT_MS, DEFAULT_BASE_URL, POLL_INTERVAL_MS } from \"../constants.js\"\nimport type { CliConfig, WhoAmIResponse } from \"../types.js\"\n\ninterface LoginOptions {\n apiKey?: string\n noBrowser?: boolean\n baseUrl?: string\n yes?: boolean\n}\n\nexport function parseLoginOptions(args: string[]): LoginOptions {\n const options: LoginOptions = {}\n for (let i = 0; i < args.length; i++) {\n switch (args[i]) {\n case \"--api-key\":\n options.apiKey = args[++i]\n break\n case \"--no-browser\":\n options.noBrowser = true\n break\n case \"--base-url\":\n options.baseUrl = args[++i]\n break\n case \"--yes\":\n case \"-y\":\n options.yes = true\n break\n }\n }\n return options\n}\n\nexport async function runLogin(args: string[]): Promise<void> {\n const options = parseLoginOptions(args)\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL\n\n const existingConfig = loadConfig()\n if (existingConfig && !options.yes && !options.apiKey && !process.env.OATMEAL_API_KEY) {\n const overwrite = await p.confirm({\n message: \"You are already logged in. Overwrite existing config?\",\n })\n if (p.isCancel(overwrite) || !overwrite) {\n p.log.info(\"Login cancelled.\")\n return\n }\n }\n\n const key = options.apiKey ?? process.env.OATMEAL_API_KEY\n if (key) {\n await validateAndSaveKey(key, baseUrl)\n return\n }\n\n if (options.noBrowser || !process.stdout.isTTY) {\n const pastedKey = await p.password({ message: \"Paste your API key:\" })\n if (p.isCancel(pastedKey)) {\n p.log.info(\"Login cancelled.\")\n return\n }\n await validateAndSaveKey(pastedKey, baseUrl)\n return\n }\n\n const deviceToken = randomBytes(32).toString(\"hex\")\n const authUrl = `${baseUrl}/cli-auth?token=${deviceToken}`\n\n p.log.info(`Opening browser to sign in...`)\n p.log.info(authUrl)\n\n try {\n openBrowser(authUrl)\n } catch {\n p.log.warn(\"Could not open browser. Visit the URL above manually.\")\n }\n\n const spinner = p.spinner()\n spinner.start(\"Waiting for authentication...\")\n\n try {\n const apiKey = await pollForKey(baseUrl, deviceToken)\n spinner.stop(\"Authenticated!\")\n await validateAndSaveKey(apiKey, baseUrl)\n } catch (error) {\n spinner.stop(\"Authentication failed.\")\n throw error\n }\n}\n\nfunction openBrowser(url: string): void {\n const platform = process.platform\n const cmd =\n platform === \"darwin\"\n ? \"open\"\n : platform === \"win32\"\n ? \"start\"\n : \"xdg-open\"\n execSync(`${cmd} \"${url}\"`, { stdio: \"ignore\" })\n}\n\nasync function pollForKey(baseUrl: string, deviceToken: string): Promise<string> {\n const client = new OatmealClient({ baseUrl })\n const start = Date.now()\n\n while (Date.now() - start < AUTH_TIMEOUT_MS) {\n const result = await client.get<{ status: string; apiKey?: string }>(\n \"/api/public/cli-auth/poll\",\n { params: { token: deviceToken } }\n )\n\n if (result.status === \"complete\" && result.apiKey) {\n return result.apiKey\n }\n\n if (result.status === \"expired\") {\n throw new Error(\"Authentication session expired. Please try again.\")\n }\n\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))\n }\n\n throw new Error(\"Authentication timed out after 5 minutes. Please try again.\")\n}\n\nasync function validateAndSaveKey(apiKey: string, baseUrl: string): Promise<void> {\n const client = new OatmealClient({ baseUrl, apiKey })\n\n const spinner = p.spinner()\n spinner.start(\"Validating API key...\")\n\n try {\n const whoami = await client.get<WhoAmIResponse>(\"/api/v1/whoami\")\n spinner.stop(\"Key validated!\")\n\n const config: CliConfig = {\n apiKey,\n baseUrl,\n tenantId: whoami.tenantId,\n keyId: whoami.keyId,\n scopes: whoami.scopes,\n }\n\n saveConfig(config)\n\n p.log.success(`Logged in! Key saved to ~/.oatmeal/config.json`)\n p.log.info(`Tenant: ${whoami.tenantId}`)\n p.log.info(`Scopes: ${whoami.scopes.join(\", \")}`)\n } catch (error) {\n spinner.stop(\"Validation failed.\")\n throw error\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import "./constants.mjs";
2
+ import { n as loadConfig, t as clearConfig } from "./config.mjs";
3
+ import * as p from "@clack/prompts";
4
+ //#region src/commands/logout.ts
5
+ async function runLogout() {
6
+ if (!loadConfig()) {
7
+ p.log.info("Not logged in.");
8
+ return;
9
+ }
10
+ clearConfig();
11
+ p.log.success("Logged out. Config removed.");
12
+ }
13
+ //#endregion
14
+ export { runLogout };
15
+
16
+ //# sourceMappingURL=logout.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.mjs","names":[],"sources":["../../src/commands/logout.ts"],"sourcesContent":["import * as p from \"@clack/prompts\"\nimport { clearConfig, loadConfig } from \"../config.js\"\n\nexport async function runLogout(): Promise<void> {\n const config = loadConfig()\n if (!config) {\n p.log.info(\"Not logged in.\")\n return\n }\n\n clearConfig()\n p.log.success(\"Logged out. Config removed.\")\n}\n"],"mappings":";;;;AAGA,eAAsB,YAA2B;AAE/C,KAAI,CADW,YAAY,EACd;AACX,IAAE,IAAI,KAAK,iBAAiB;AAC5B;;AAGF,cAAa;AACb,GAAE,IAAI,QAAQ,8BAA8B"}
@@ -0,0 +1,35 @@
1
+ import { n as formatJson, t as formatDetail } from "../cli.mjs";
2
+ //#region src/commands/browse/org.ts
3
+ async function runBrowseOrg(client, slug, options) {
4
+ if (!slug) {
5
+ console.error("Usage: oatmeal browse org <slug>");
6
+ process.exit(1);
7
+ }
8
+ const data = await client.get(`/api/public/orgs/${encodeURIComponent(slug)}`);
9
+ if (options.json) {
10
+ console.log(formatJson(data));
11
+ return;
12
+ }
13
+ console.log(formatDetail([
14
+ {
15
+ label: "Name",
16
+ value: data.name
17
+ },
18
+ {
19
+ label: "Slug",
20
+ value: data.slug
21
+ },
22
+ {
23
+ label: "Description",
24
+ value: data.description
25
+ },
26
+ {
27
+ label: "Hackathons",
28
+ value: String(data.hackathon_count ?? 0)
29
+ }
30
+ ]));
31
+ }
32
+ //#endregion
33
+ export { runBrowseOrg };
34
+
35
+ //# sourceMappingURL=org.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org.mjs","names":[],"sources":["../../src/commands/browse/org.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatDetail, formatJson } from \"../../output.js\"\nimport type { OrgProfile } from \"../../types.js\"\n\nexport async function runBrowseOrg(\n client: OatmealClient,\n slug: string,\n options: { json?: boolean }\n): Promise<void> {\n if (!slug) {\n console.error(\"Usage: oatmeal browse org <slug>\")\n process.exit(1)\n }\n\n const data = await client.get<OrgProfile>(\n `/api/public/orgs/${encodeURIComponent(slug)}`\n )\n\n if (options.json) {\n console.log(formatJson(data))\n return\n }\n\n console.log(\n formatDetail([\n { label: \"Name\", value: data.name },\n { label: \"Slug\", value: data.slug },\n { label: \"Description\", value: data.description },\n { label: \"Hackathons\", value: String(data.hackathon_count ?? 0) },\n ])\n )\n}\n"],"mappings":";;AAIA,eAAsB,aACpB,QACA,MACA,SACe;AACf,KAAI,CAAC,MAAM;AACT,UAAQ,MAAM,mCAAmC;AACjD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,OAAO,MAAM,OAAO,IACxB,oBAAoB,mBAAmB,KAAK,GAC7C;AAED,KAAI,QAAQ,MAAM;AAChB,UAAQ,IAAI,WAAW,KAAK,CAAC;AAC7B;;AAGF,SAAQ,IACN,aAAa;EACX;GAAE,OAAO;GAAQ,OAAO,KAAK;GAAM;EACnC;GAAE,OAAO;GAAQ,OAAO,KAAK;GAAM;EACnC;GAAE,OAAO;GAAe,OAAO,KAAK;GAAa;EACjD;GAAE,OAAO;GAAc,OAAO,OAAO,KAAK,mBAAmB,EAAA;;EAC9D,CAAC,CACH"}
@@ -0,0 +1,35 @@
1
+ import { i as formatTable, n as formatJson } from "../cli.mjs";
2
+ //#region src/commands/judging/pick-results.ts
3
+ async function runPickResults(client, hackathonId, options) {
4
+ const data = await client.get(`/api/dashboard/hackathons/${hackathonId}/judging/pick-results`);
5
+ if (options.json) {
6
+ console.log(formatJson(data));
7
+ return;
8
+ }
9
+ if (!data.picks?.length) {
10
+ console.log("No pick results available.");
11
+ return;
12
+ }
13
+ const rows = data.picks.map((pick) => ({
14
+ ...pick,
15
+ judges_list: pick.judges.join(", ")
16
+ }));
17
+ console.log(formatTable(rows, [
18
+ {
19
+ key: "submission_name",
20
+ label: "Submission"
21
+ },
22
+ {
23
+ key: "pick_count",
24
+ label: "Picks"
25
+ },
26
+ {
27
+ key: "judges_list",
28
+ label: "Judges"
29
+ }
30
+ ]));
31
+ }
32
+ //#endregion
33
+ export { runPickResults };
34
+
35
+ //# sourceMappingURL=pick-results.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick-results.mjs","names":[],"sources":["../../src/commands/judging/pick-results.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatJson, formatTable } from \"../../output.js\"\nimport type { PickResults } from \"../../types.js\"\n\nexport async function runPickResults(\n client: OatmealClient,\n hackathonId: string,\n options: { json?: boolean }\n): Promise<void> {\n const data = await client.get<PickResults>(\n `/api/dashboard/hackathons/${hackathonId}/judging/pick-results`\n )\n\n if (options.json) {\n console.log(formatJson(data))\n return\n }\n\n if (!data.picks?.length) {\n console.log(\"No pick results available.\")\n return\n }\n\n const rows = data.picks.map((pick) => ({\n ...pick,\n judges_list: pick.judges.join(\", \"),\n }))\n\n console.log(\n formatTable(rows, [\n { key: \"submission_name\", label: \"Submission\" },\n { key: \"pick_count\", label: \"Picks\" },\n { key: \"judges_list\", label: \"Judges\" },\n ])\n )\n}\n"],"mappings":";;AAIA,eAAsB,eACpB,QACA,aACA,SACe;CACf,MAAM,OAAO,MAAM,OAAO,IACxB,6BAA6B,YAAY,uBAC1C;AAED,KAAI,QAAQ,MAAM;AAChB,UAAQ,IAAI,WAAW,KAAK,CAAC;AAC7B;;AAGF,KAAI,CAAC,KAAK,OAAO,QAAQ;AACvB,UAAQ,IAAI,6BAA6B;AACzC;;CAGF,MAAM,OAAO,KAAK,MAAM,KAAK,UAAU;EACrC,GAAG;EACH,aAAa,KAAK,OAAO,KAAK,KAAA;EAC/B,EAAE;AAEH,SAAQ,IACN,YAAY,MAAM;EAChB;GAAE,KAAK;GAAmB,OAAO;GAAc;EAC/C;GAAE,KAAK;GAAc,OAAO;GAAS;EACrC;GAAE,KAAK;GAAe,OAAO;;EAC9B,CAAC,CACH"}
@@ -0,0 +1,22 @@
1
+ import { r as formatSuccess } from "../cli.mjs";
2
+ import * as p from "@clack/prompts";
3
+ //#region src/commands/results/publish.ts
4
+ async function runResultsPublish(client, hackathonId, options) {
5
+ if (!hackathonId) {
6
+ console.error("Usage: oatmeal results publish <hackathon-id>");
7
+ process.exit(1);
8
+ }
9
+ if (!options.yes) {
10
+ const confirm = await p.confirm({ message: "Publish results? This will make them visible to participants." });
11
+ if (p.isCancel(confirm) || !confirm) {
12
+ p.log.info("Cancelled.");
13
+ return;
14
+ }
15
+ }
16
+ await client.post(`/api/dashboard/hackathons/${hackathonId}/results/publish`);
17
+ console.log(formatSuccess("Results published"));
18
+ }
19
+ //#endregion
20
+ export { runResultsPublish };
21
+
22
+ //# sourceMappingURL=publish.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.mjs","names":[],"sources":["../../src/commands/results/publish.ts"],"sourcesContent":["import * as p from \"@clack/prompts\"\nimport type { OatmealClient } from \"../../client.js\"\nimport { formatSuccess } from \"../../output.js\"\n\nexport async function runResultsPublish(\n client: OatmealClient,\n hackathonId: string,\n options: { yes?: boolean }\n): Promise<void> {\n if (!hackathonId) {\n console.error(\"Usage: oatmeal results publish <hackathon-id>\")\n process.exit(1)\n }\n\n if (!options.yes) {\n const confirm = await p.confirm({\n message: \"Publish results? This will make them visible to participants.\",\n })\n if (p.isCancel(confirm) || !confirm) {\n p.log.info(\"Cancelled.\")\n return\n }\n }\n\n await client.post(`/api/dashboard/hackathons/${hackathonId}/results/publish`)\n console.log(formatSuccess(\"Results published\"))\n}\n"],"mappings":";;;AAIA,eAAsB,kBACpB,QACA,aACA,SACe;AACf,KAAI,CAAC,aAAa;AAChB,UAAQ,MAAM,gDAAgD;AAC9D,UAAQ,KAAK,EAAE;;AAGjB,KAAI,CAAC,QAAQ,KAAK;EAChB,MAAM,UAAU,MAAM,EAAE,QAAQ,EAC9B,SAAS,iEACV,CAAC;AACF,MAAI,EAAE,SAAS,QAAQ,IAAI,CAAC,SAAS;AACnC,KAAE,IAAI,KAAK,aAAa;AACxB;;;AAIJ,OAAM,OAAO,KAAK,6BAA6B,YAAY,kBAAkB;AAC7E,SAAQ,IAAI,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { r as formatSuccess } from "../cli.mjs";
2
+ //#region src/commands/judge-display/reorder.ts
3
+ async function runJudgeDisplayReorder(client, hackathonId, args) {
4
+ let ids = [];
5
+ for (let i = 0; i < args.length; i++) if (args[i] === "--ids") ids = args[++i]?.split(",").map((s) => s.trim()) ?? [];
6
+ if (!ids.length) {
7
+ console.error("Error: --ids is required (comma-separated profile IDs in desired order)");
8
+ process.exit(1);
9
+ }
10
+ await client.post(`/api/dashboard/hackathons/${hackathonId}/judges/display/reorder`, { profile_ids: ids });
11
+ console.log(formatSuccess(`Reordered ${ids.length} judge display profiles`));
12
+ }
13
+ //#endregion
14
+ export { runJudgeDisplayReorder };
15
+
16
+ //# sourceMappingURL=reorder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reorder.mjs","names":[],"sources":["../../src/commands/judge-display/reorder.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatSuccess } from \"../../output.js\"\n\nexport async function runJudgeDisplayReorder(\n client: OatmealClient,\n hackathonId: string,\n args: string[]\n): Promise<void> {\n let ids: string[] = []\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--ids\") {\n ids = args[++i]?.split(\",\").map((s) => s.trim()) ?? []\n }\n }\n\n if (!ids.length) {\n console.error(\"Error: --ids is required (comma-separated profile IDs in desired order)\")\n process.exit(1)\n }\n\n await client.post(\n `/api/dashboard/hackathons/${hackathonId}/judges/display/reorder`,\n { profile_ids: ids }\n )\n console.log(formatSuccess(`Reordered ${ids.length} judge display profiles`))\n}\n"],"mappings":";;AAGA,eAAsB,uBACpB,QACA,aACA,MACe;CACf,IAAI,MAAgB,EAAE;AACtB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAC/B,KAAI,KAAK,OAAO,QACd,OAAM,KAAK,EAAE,IAAI,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;AAI1D,KAAI,CAAC,IAAI,QAAQ;AACf,UAAQ,MAAM,0EAA0E;AACxF,UAAQ,KAAK,EAAE;;AAGjB,OAAM,OAAO,KACX,6BAA6B,YAAY,0BACzC,EAAE,aAAa,KAAK,CACrB;AACD,SAAQ,IAAI,cAAc,aAAa,IAAI,OAAO,yBAAyB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { r as formatSuccess } from "../cli.mjs";
2
+ //#region src/commands/prizes/reorder.ts
3
+ async function runPrizesReorder(client, hackathonId, args) {
4
+ let ids = [];
5
+ for (let i = 0; i < args.length; i++) if (args[i] === "--ids") ids = args[++i]?.split(",").map((s) => s.trim()) ?? [];
6
+ if (!ids.length) {
7
+ console.error("Error: --ids is required (comma-separated prize IDs in desired order)");
8
+ process.exit(1);
9
+ }
10
+ await client.post(`/api/dashboard/hackathons/${hackathonId}/prizes/reorder`, { prize_ids: ids });
11
+ console.log(formatSuccess(`Reordered ${ids.length} prizes`));
12
+ }
13
+ //#endregion
14
+ export { runPrizesReorder };
15
+
16
+ //# sourceMappingURL=reorder2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reorder2.mjs","names":[],"sources":["../../src/commands/prizes/reorder.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatSuccess } from \"../../output.js\"\n\nexport async function runPrizesReorder(\n client: OatmealClient,\n hackathonId: string,\n args: string[]\n): Promise<void> {\n let ids: string[] = []\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--ids\") {\n ids = args[++i]?.split(\",\").map((s) => s.trim()) ?? []\n }\n }\n\n if (!ids.length) {\n console.error(\"Error: --ids is required (comma-separated prize IDs in desired order)\")\n process.exit(1)\n }\n\n await client.post(`/api/dashboard/hackathons/${hackathonId}/prizes/reorder`, {\n prize_ids: ids,\n })\n console.log(formatSuccess(`Reordered ${ids.length} prizes`))\n}\n"],"mappings":";;AAGA,eAAsB,iBACpB,QACA,aACA,MACe;CACf,IAAI,MAAgB,EAAE;AACtB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAC/B,KAAI,KAAK,OAAO,QACd,OAAM,KAAK,EAAE,IAAI,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;AAI1D,KAAI,CAAC,IAAI,QAAQ;AACf,UAAQ,MAAM,wEAAwE;AACtF,UAAQ,KAAK,EAAE;;AAGjB,OAAM,OAAO,KAAK,6BAA6B,YAAY,kBAAkB,EAC3E,WAAW,KACZ,CAAC;AACF,SAAQ,IAAI,cAAc,aAAa,IAAI,OAAO,SAAS,CAAC"}
@@ -0,0 +1,15 @@
1
+ //#region src/commands/hackathons/resolve.ts
2
+ const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3
+ async function resolveHackathonId(client, idOrSlug) {
4
+ if (UUID_REGEX.test(idOrSlug)) return idOrSlug;
5
+ const match = (await client.get("/api/dashboard/hackathons", { params: {
6
+ q: idOrSlug,
7
+ limit: 1
8
+ } })).hackathons?.find((h) => h.slug === idOrSlug);
9
+ if (!match) throw new Error(`Hackathon not found: "${idOrSlug}". Use a UUID or exact slug.`);
10
+ return match.id;
11
+ }
12
+ //#endregion
13
+ export { resolveHackathonId as t };
14
+
15
+ //# sourceMappingURL=resolve.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.mjs","names":[],"sources":["../../src/commands/hackathons/resolve.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport type { Hackathon } from \"../../types.js\"\n\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport async function resolveHackathonId(\n client: OatmealClient,\n idOrSlug: string\n): Promise<string> {\n if (UUID_REGEX.test(idOrSlug)) {\n return idOrSlug\n }\n\n const data = await client.get<{ hackathons: Hackathon[] }>(\"/api/dashboard/hackathons\", {\n params: { q: idOrSlug, limit: 1 },\n })\n\n const match = data.hackathons?.find((h) => h.slug === idOrSlug)\n if (!match) {\n throw new Error(`Hackathon not found: \"${idOrSlug}\". Use a UUID or exact slug.`)\n }\n\n return match.id\n}\n"],"mappings":";AAGA,MAAM,aAAa;AAEnB,eAAsB,mBACpB,QACA,UACiB;AACjB,KAAI,WAAW,KAAK,SAAS,CAC3B,QAAO;CAOT,MAAM,SAJO,MAAM,OAAO,IAAiC,6BAA6B,EACtF,QAAQ;EAAE,GAAG;EAAU,OAAO;EAAG,EAClC,CAAC,EAEiB,YAAY,MAAM,MAAM,EAAE,SAAS,SAAS;AAC/D,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,yBAAyB,SAAS,8BAA8B;AAGlF,QAAO,MAAM"}
@@ -0,0 +1,46 @@
1
+ import { a as POLL_INTERVAL_MS } from "./constants.mjs";
2
+ import { n as formatJson } from "../cli.mjs";
3
+ //#region src/commands/jobs/result.ts
4
+ function parseJobResultOptions(args) {
5
+ const options = {};
6
+ for (let i = 0; i < args.length; i++) switch (args[i]) {
7
+ case "--poll":
8
+ options.poll = true;
9
+ break;
10
+ case "--json":
11
+ options.json = true;
12
+ break;
13
+ }
14
+ return options;
15
+ }
16
+ async function runJobsResult(client, jobId, args) {
17
+ if (!jobId) {
18
+ console.error("Usage: oatmeal jobs result <job-id>");
19
+ process.exit(1);
20
+ }
21
+ if (parseJobResultOptions(args).poll) {
22
+ let attempts = 0;
23
+ const maxAttempts = 60;
24
+ while (attempts < maxAttempts) {
25
+ const result = await client.get(`/api/v1/jobs/${jobId}/result`);
26
+ if (result.status === "completed" || result.result) {
27
+ console.log(formatJson(result));
28
+ return;
29
+ }
30
+ console.error(`Job still running (attempt ${++attempts}/${maxAttempts})...`);
31
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
32
+ }
33
+ console.error("Timed out waiting for job result.");
34
+ process.exit(1);
35
+ }
36
+ const result = await client.get(`/api/v1/jobs/${jobId}/result`);
37
+ if (result.status !== "completed" && !result.result) {
38
+ console.log(`Job is still ${result.status}. Use --poll to wait for completion.`);
39
+ return;
40
+ }
41
+ console.log(formatJson(result));
42
+ }
43
+ //#endregion
44
+ export { runJobsResult };
45
+
46
+ //# sourceMappingURL=result.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.mjs","names":[],"sources":["../../src/commands/jobs/result.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatJson } from \"../../output.js\"\nimport { POLL_INTERVAL_MS } from \"../../constants.js\"\n\ninterface JobResultOptions {\n poll?: boolean\n json?: boolean\n}\n\nexport function parseJobResultOptions(args: string[]): JobResultOptions {\n const options: JobResultOptions = {}\n for (let i = 0; i < args.length; i++) {\n switch (args[i]) {\n case \"--poll\":\n options.poll = true\n break\n case \"--json\":\n options.json = true\n break\n }\n }\n return options\n}\n\nexport async function runJobsResult(\n client: OatmealClient,\n jobId: string,\n args: string[]\n): Promise<void> {\n if (!jobId) {\n console.error(\"Usage: oatmeal jobs result <job-id>\")\n process.exit(1)\n }\n\n const options = parseJobResultOptions(args)\n\n if (options.poll) {\n let attempts = 0\n const maxAttempts = 60\n while (attempts < maxAttempts) {\n const result = await client.get<{ status: string; result?: unknown }>(\n `/api/v1/jobs/${jobId}/result`\n )\n if (result.status === \"completed\" || result.result) {\n console.log(formatJson(result))\n return\n }\n console.error(`Job still running (attempt ${++attempts}/${maxAttempts})...`)\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS))\n }\n console.error(\"Timed out waiting for job result.\")\n process.exit(1)\n }\n\n const result = await client.get<{ status: string; result?: unknown }>(\n `/api/v1/jobs/${jobId}/result`\n )\n\n if (result.status !== \"completed\" && !result.result) {\n console.log(`Job is still ${result.status}. Use --poll to wait for completion.`)\n return\n }\n\n console.log(formatJson(result))\n}\n"],"mappings":";;;AASA,SAAgB,sBAAsB,MAAkC;CACtE,MAAM,UAA4B,EAAE;AACpC,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAC/B,SAAQ,KAAK,IAAb;EACE,KAAK;AACH,WAAQ,OAAO;AACf;EACF,KAAK;AACH,WAAQ,OAAO;AACf;;AAGN,QAAO;;AAGT,eAAsB,cACpB,QACA,OACA,MACe;AACf,KAAI,CAAC,OAAO;AACV,UAAQ,MAAM,sCAAsC;AACpD,UAAQ,KAAK,EAAE;;AAKjB,KAFgB,sBAAsB,KAAK,CAE/B,MAAM;EAChB,IAAI,WAAW;EACf,MAAM,cAAc;AACpB,SAAO,WAAW,aAAa;GAC7B,MAAM,SAAS,MAAM,OAAO,IAC1B,gBAAgB,MAAM,SACvB;AACD,OAAI,OAAO,WAAW,eAAe,OAAO,QAAQ;AAClD,YAAQ,IAAI,WAAW,OAAO,CAAC;AAC/B;;AAEF,WAAQ,MAAM,8BAA8B,EAAE,SAAS,GAAG,YAAY,MAAM;AAC5E,SAAM,IAAI,SAAS,YAAY,WAAW,SAAS,iBAAiB,CAAC;;AAEvE,UAAQ,MAAM,oCAAoC;AAClD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,SAAS,MAAM,OAAO,IAC1B,gBAAgB,MAAM,SACvB;AAED,KAAI,OAAO,WAAW,eAAe,CAAC,OAAO,QAAQ;AACnD,UAAQ,IAAI,gBAAgB,OAAO,OAAO,sCAAsC;AAChF;;AAGF,SAAQ,IAAI,WAAW,OAAO,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { i as formatTable, n as formatJson } from "../cli.mjs";
2
+ //#region src/commands/browse/results.ts
3
+ async function runBrowseResults(client, slug, options) {
4
+ if (!slug) {
5
+ console.error("Usage: oatmeal browse results <slug>");
6
+ process.exit(1);
7
+ }
8
+ const data = await client.get(`/api/public/hackathons/${encodeURIComponent(slug)}/results`);
9
+ if (options.json) {
10
+ console.log(formatJson(data));
11
+ return;
12
+ }
13
+ if (!data.published) {
14
+ console.log("Results have not been published yet.");
15
+ return;
16
+ }
17
+ if (!data.rankings?.length) {
18
+ console.log("No rankings available.");
19
+ return;
20
+ }
21
+ console.log(formatTable(data.rankings, [
22
+ {
23
+ key: "rank",
24
+ label: "#"
25
+ },
26
+ {
27
+ key: "submission_name",
28
+ label: "Submission"
29
+ },
30
+ {
31
+ key: "team_name",
32
+ label: "Team"
33
+ },
34
+ {
35
+ key: "total_score",
36
+ label: "Score"
37
+ }
38
+ ]));
39
+ }
40
+ //#endregion
41
+ export { runBrowseResults };
42
+
43
+ //# sourceMappingURL=results.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results.mjs","names":[],"sources":["../../src/commands/browse/results.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatJson, formatTable } from \"../../output.js\"\nimport type { ResultsData } from \"../../types.js\"\n\nexport async function runBrowseResults(\n client: OatmealClient,\n slug: string,\n options: { json?: boolean }\n): Promise<void> {\n if (!slug) {\n console.error(\"Usage: oatmeal browse results <slug>\")\n process.exit(1)\n }\n\n const data = await client.get<ResultsData>(\n `/api/public/hackathons/${encodeURIComponent(slug)}/results`\n )\n\n if (options.json) {\n console.log(formatJson(data))\n return\n }\n\n if (!data.published) {\n console.log(\"Results have not been published yet.\")\n return\n }\n\n if (!data.rankings?.length) {\n console.log(\"No rankings available.\")\n return\n }\n\n console.log(\n formatTable(data.rankings, [\n { key: \"rank\", label: \"#\" },\n { key: \"submission_name\", label: \"Submission\" },\n { key: \"team_name\", label: \"Team\" },\n { key: \"total_score\", label: \"Score\" },\n ])\n )\n}\n"],"mappings":";;AAIA,eAAsB,iBACpB,QACA,MACA,SACe;AACf,KAAI,CAAC,MAAM;AACT,UAAQ,MAAM,uCAAuC;AACrD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,OAAO,MAAM,OAAO,IACxB,0BAA0B,mBAAmB,KAAK,CAAC,UACpD;AAED,KAAI,QAAQ,MAAM;AAChB,UAAQ,IAAI,WAAW,KAAK,CAAC;AAC7B;;AAGF,KAAI,CAAC,KAAK,WAAW;AACnB,UAAQ,IAAI,uCAAuC;AACnD;;AAGF,KAAI,CAAC,KAAK,UAAU,QAAQ;AAC1B,UAAQ,IAAI,yBAAyB;AACrC;;AAGF,SAAQ,IACN,YAAY,KAAK,UAAU;EACzB;GAAE,KAAK;GAAQ,OAAO;GAAK;EAC3B;GAAE,KAAK;GAAmB,OAAO;GAAc;EAC/C;GAAE,KAAK;GAAa,OAAO;GAAQ;EACnC;GAAE,KAAK;GAAe,OAAO;;EAC9B,CAAC,CACH"}
@@ -0,0 +1,35 @@
1
+ import { i as formatTable, n as formatJson } from "../cli.mjs";
2
+ //#region src/commands/browse/submissions.ts
3
+ async function runBrowseSubmissions(client, slug, options) {
4
+ if (!slug) {
5
+ console.error("Usage: oatmeal browse submissions <slug>");
6
+ process.exit(1);
7
+ }
8
+ const data = await client.get(`/api/public/hackathons/${encodeURIComponent(slug)}/submissions`);
9
+ if (options.json) {
10
+ console.log(formatJson(data));
11
+ return;
12
+ }
13
+ if (!data.submissions?.length) {
14
+ console.log("No submissions found.");
15
+ return;
16
+ }
17
+ console.log(formatTable(data.submissions, [
18
+ {
19
+ key: "name",
20
+ label: "Name"
21
+ },
22
+ {
23
+ key: "team_name",
24
+ label: "Team"
25
+ },
26
+ {
27
+ key: "submitted_at",
28
+ label: "Submitted"
29
+ }
30
+ ]));
31
+ }
32
+ //#endregion
33
+ export { runBrowseSubmissions };
34
+
35
+ //# sourceMappingURL=submissions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissions.mjs","names":[],"sources":["../../src/commands/browse/submissions.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatJson, formatTable } from \"../../output.js\"\nimport type { Submission } from \"../../types.js\"\n\nexport async function runBrowseSubmissions(\n client: OatmealClient,\n slug: string,\n options: { json?: boolean }\n): Promise<void> {\n if (!slug) {\n console.error(\"Usage: oatmeal browse submissions <slug>\")\n process.exit(1)\n }\n\n const data = await client.get<{ submissions: Submission[] }>(\n `/api/public/hackathons/${encodeURIComponent(slug)}/submissions`\n )\n\n if (options.json) {\n console.log(formatJson(data))\n return\n }\n\n if (!data.submissions?.length) {\n console.log(\"No submissions found.\")\n return\n }\n\n console.log(\n formatTable(data.submissions, [\n { key: \"name\", label: \"Name\" },\n { key: \"team_name\", label: \"Team\" },\n { key: \"submitted_at\", label: \"Submitted\" },\n ])\n )\n}\n"],"mappings":";;AAIA,eAAsB,qBACpB,QACA,MACA,SACe;AACf,KAAI,CAAC,MAAM;AACT,UAAQ,MAAM,2CAA2C;AACzD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,OAAO,MAAM,OAAO,IACxB,0BAA0B,mBAAmB,KAAK,CAAC,cACpD;AAED,KAAI,QAAQ,MAAM;AAChB,UAAQ,IAAI,WAAW,KAAK,CAAC;AAC7B;;AAGF,KAAI,CAAC,KAAK,aAAa,QAAQ;AAC7B,UAAQ,IAAI,wBAAwB;AACpC;;AAGF,SAAQ,IACN,YAAY,KAAK,aAAa;EAC5B;GAAE,KAAK;GAAQ,OAAO;GAAQ;EAC9B;GAAE,KAAK;GAAa,OAAO;GAAQ;EACnC;GAAE,KAAK;GAAgB,OAAO;;EAC/B,CAAC,CACH"}
@@ -0,0 +1,22 @@
1
+ import { r as formatSuccess } from "../cli.mjs";
2
+ import * as p from "@clack/prompts";
3
+ //#region src/commands/prizes/unassign.ts
4
+ async function runPrizesUnassign(client, hackathonId, prizeId, submissionId, options) {
5
+ if (!prizeId || !submissionId) {
6
+ console.error("Usage: oatmeal prizes unassign <hackathon-id> <prize-id> <submission-id>");
7
+ process.exit(1);
8
+ }
9
+ if (!options.yes) {
10
+ const confirm = await p.confirm({ message: `Unassign prize ${prizeId} from submission ${submissionId}?` });
11
+ if (p.isCancel(confirm) || !confirm) {
12
+ p.log.info("Cancelled.");
13
+ return;
14
+ }
15
+ }
16
+ await client.delete(`/api/dashboard/hackathons/${hackathonId}/prizes/${prizeId}/assign/${submissionId}`);
17
+ console.log(formatSuccess(`Unassigned prize ${prizeId}`));
18
+ }
19
+ //#endregion
20
+ export { runPrizesUnassign };
21
+
22
+ //# sourceMappingURL=unassign.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unassign.mjs","names":[],"sources":["../../src/commands/prizes/unassign.ts"],"sourcesContent":["import * as p from \"@clack/prompts\"\nimport type { OatmealClient } from \"../../client.js\"\nimport { formatSuccess } from \"../../output.js\"\n\nexport async function runPrizesUnassign(\n client: OatmealClient,\n hackathonId: string,\n prizeId: string,\n submissionId: string,\n options: { yes?: boolean }\n): Promise<void> {\n if (!prizeId || !submissionId) {\n console.error(\"Usage: oatmeal prizes unassign <hackathon-id> <prize-id> <submission-id>\")\n process.exit(1)\n }\n\n if (!options.yes) {\n const confirm = await p.confirm({ message: `Unassign prize ${prizeId} from submission ${submissionId}?` })\n if (p.isCancel(confirm) || !confirm) {\n p.log.info(\"Cancelled.\")\n return\n }\n }\n\n await client.delete(\n `/api/dashboard/hackathons/${hackathonId}/prizes/${prizeId}/assign/${submissionId}`\n )\n console.log(formatSuccess(`Unassigned prize ${prizeId}`))\n}\n"],"mappings":";;;AAIA,eAAsB,kBACpB,QACA,aACA,SACA,cACA,SACe;AACf,KAAI,CAAC,WAAW,CAAC,cAAc;AAC7B,UAAQ,MAAM,2EAA2E;AACzF,UAAQ,KAAK,EAAE;;AAGjB,KAAI,CAAC,QAAQ,KAAK;EAChB,MAAM,UAAU,MAAM,EAAE,QAAQ,EAAE,SAAS,kBAAkB,QAAQ,mBAAmB,aAAa,IAAI,CAAC;AAC1G,MAAI,EAAE,SAAS,QAAQ,IAAI,CAAC,SAAS;AACnC,KAAE,IAAI,KAAK,aAAa;AACxB;;;AAIJ,OAAM,OAAO,OACX,6BAA6B,YAAY,UAAU,QAAQ,UAAU,eACtE;AACD,SAAQ,IAAI,cAAc,oBAAoB,UAAU,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { r as formatSuccess } from "../cli.mjs";
2
+ import * as p from "@clack/prompts";
3
+ //#region src/commands/results/unpublish.ts
4
+ async function runResultsUnpublish(client, hackathonId, options) {
5
+ if (!hackathonId) {
6
+ console.error("Usage: oatmeal results unpublish <hackathon-id>");
7
+ process.exit(1);
8
+ }
9
+ if (!options.yes) {
10
+ const confirm = await p.confirm({ message: "Unpublish results?" });
11
+ if (p.isCancel(confirm) || !confirm) {
12
+ p.log.info("Cancelled.");
13
+ return;
14
+ }
15
+ }
16
+ await client.post(`/api/dashboard/hackathons/${hackathonId}/results/unpublish`);
17
+ console.log(formatSuccess("Results unpublished"));
18
+ }
19
+ //#endregion
20
+ export { runResultsUnpublish };
21
+
22
+ //# sourceMappingURL=unpublish.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpublish.mjs","names":[],"sources":["../../src/commands/results/unpublish.ts"],"sourcesContent":["import * as p from \"@clack/prompts\"\nimport type { OatmealClient } from \"../../client.js\"\nimport { formatSuccess } from \"../../output.js\"\n\nexport async function runResultsUnpublish(\n client: OatmealClient,\n hackathonId: string,\n options: { yes?: boolean }\n): Promise<void> {\n if (!hackathonId) {\n console.error(\"Usage: oatmeal results unpublish <hackathon-id>\")\n process.exit(1)\n }\n\n if (!options.yes) {\n const confirm = await p.confirm({ message: \"Unpublish results?\" })\n if (p.isCancel(confirm) || !confirm) {\n p.log.info(\"Cancelled.\")\n return\n }\n }\n\n await client.post(`/api/dashboard/hackathons/${hackathonId}/results/unpublish`)\n console.log(formatSuccess(\"Results unpublished\"))\n}\n"],"mappings":";;;AAIA,eAAsB,oBACpB,QACA,aACA,SACe;AACf,KAAI,CAAC,aAAa;AAChB,UAAQ,MAAM,kDAAkD;AAChE,UAAQ,KAAK,EAAE;;AAGjB,KAAI,CAAC,QAAQ,KAAK;EAChB,MAAM,UAAU,MAAM,EAAE,QAAQ,EAAE,SAAS,sBAAsB,CAAC;AAClE,MAAI,EAAE,SAAS,QAAQ,IAAI,CAAC,SAAS;AACnC,KAAE,IAAI,KAAK,aAAa;AACxB;;;AAIJ,OAAM,OAAO,KAAK,6BAA6B,YAAY,oBAAoB;AAC/E,SAAQ,IAAI,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { n as formatJson, r as formatSuccess } from "../cli.mjs";
2
+ import { t as resolveHackathonId } from "./resolve.mjs";
3
+ //#region src/commands/hackathons/update.ts
4
+ function parseUpdateOptions(args) {
5
+ const options = {};
6
+ for (let i = 0; i < args.length; i++) switch (args[i]) {
7
+ case "--name":
8
+ options.name = args[++i];
9
+ break;
10
+ case "--slug":
11
+ options.slug = args[++i];
12
+ break;
13
+ case "--description":
14
+ options.description = args[++i];
15
+ break;
16
+ case "--json":
17
+ options.json = true;
18
+ break;
19
+ }
20
+ return options;
21
+ }
22
+ async function runHackathonsUpdate(client, idOrSlug, args) {
23
+ if (!idOrSlug) {
24
+ console.error("Usage: oatmeal hackathons update <id-or-slug> [--name ...] [--slug ...] [--description ...]");
25
+ process.exit(1);
26
+ }
27
+ const options = parseUpdateOptions(args);
28
+ const id = await resolveHackathonId(client, idOrSlug);
29
+ const body = {};
30
+ if (options.name) body.name = options.name;
31
+ if (options.slug) body.slug = options.slug;
32
+ if (options.description) body.description = options.description;
33
+ if (Object.keys(body).length === 0) {
34
+ console.error("Error: provide at least one field to update (--name, --slug, --description)");
35
+ process.exit(1);
36
+ }
37
+ const hackathon = await client.patch(`/api/dashboard/hackathons/${id}`, body);
38
+ if (options.json) {
39
+ console.log(formatJson(hackathon));
40
+ return;
41
+ }
42
+ console.log(formatSuccess(`Updated hackathon "${hackathon.name}"`));
43
+ }
44
+ //#endregion
45
+ export { runHackathonsUpdate };
46
+
47
+ //# sourceMappingURL=update.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.mjs","names":[],"sources":["../../src/commands/hackathons/update.ts"],"sourcesContent":["import type { OatmealClient } from \"../../client.js\"\nimport { formatJson, formatSuccess } from \"../../output.js\"\nimport type { Hackathon } from \"../../types.js\"\nimport { resolveHackathonId } from \"./resolve.js\"\n\ninterface UpdateOptions {\n name?: string\n slug?: string\n description?: string\n json?: boolean\n}\n\nexport function parseUpdateOptions(args: string[]): UpdateOptions {\n const options: UpdateOptions = {}\n for (let i = 0; i < args.length; i++) {\n switch (args[i]) {\n case \"--name\":\n options.name = args[++i]\n break\n case \"--slug\":\n options.slug = args[++i]\n break\n case \"--description\":\n options.description = args[++i]\n break\n case \"--json\":\n options.json = true\n break\n }\n }\n return options\n}\n\nexport async function runHackathonsUpdate(\n client: OatmealClient,\n idOrSlug: string,\n args: string[]\n): Promise<void> {\n if (!idOrSlug) {\n console.error(\"Usage: oatmeal hackathons update <id-or-slug> [--name ...] [--slug ...] [--description ...]\")\n process.exit(1)\n }\n\n const options = parseUpdateOptions(args)\n const id = await resolveHackathonId(client, idOrSlug)\n\n const body: Record<string, string> = {}\n if (options.name) body.name = options.name\n if (options.slug) body.slug = options.slug\n if (options.description) body.description = options.description\n\n if (Object.keys(body).length === 0) {\n console.error(\"Error: provide at least one field to update (--name, --slug, --description)\")\n process.exit(1)\n }\n\n const hackathon = await client.patch<Hackathon>(`/api/dashboard/hackathons/${id}`, body)\n\n if (options.json) {\n console.log(formatJson(hackathon))\n return\n }\n\n console.log(formatSuccess(`Updated hackathon \"${hackathon.name}\"`))\n}\n"],"mappings":";;;AAYA,SAAgB,mBAAmB,MAA+B;CAChE,MAAM,UAAyB,EAAE;AACjC,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,IAC/B,SAAQ,KAAK,IAAb;EACE,KAAK;AACH,WAAQ,OAAO,KAAK,EAAE;AACtB;EACF,KAAK;AACH,WAAQ,OAAO,KAAK,EAAE;AACtB;EACF,KAAK;AACH,WAAQ,cAAc,KAAK,EAAE;AAC7B;EACF,KAAK;AACH,WAAQ,OAAO;AACf;;AAGN,QAAO;;AAGT,eAAsB,oBACpB,QACA,UACA,MACe;AACf,KAAI,CAAC,UAAU;AACb,UAAQ,MAAM,8FAA8F;AAC5G,UAAQ,KAAK,EAAE;;CAGjB,MAAM,UAAU,mBAAmB,KAAK;CACxC,MAAM,KAAK,MAAM,mBAAmB,QAAQ,SAAS;CAErD,MAAM,OAA+B,EAAE;AACvC,KAAI,QAAQ,KAAM,MAAK,OAAO,QAAQ;AACtC,KAAI,QAAQ,KAAM,MAAK,OAAO,QAAQ;AACtC,KAAI,QAAQ,YAAa,MAAK,cAAc,QAAQ;AAEpD,KAAI,OAAO,KAAK,KAAK,CAAC,WAAW,GAAG;AAClC,UAAQ,MAAM,8EAA8E;AAC5F,UAAQ,KAAK,EAAE;;CAGjB,MAAM,YAAY,MAAM,OAAO,MAAiB,6BAA6B,MAAM,KAAK;AAExF,KAAI,QAAQ,MAAM;AAChB,UAAQ,IAAI,WAAW,UAAU,CAAC;AAClC;;AAGF,SAAQ,IAAI,cAAc,sBAAsB,UAAU,KAAK,GAAG,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { n as formatJson, r as formatSuccess } from "../cli.mjs";
2
+ //#region src/commands/judge-display/update.ts
3
+ function parseJudgeDisplayUpdateOptions(args) {
4
+ const options = {};
5
+ for (let i = 0; i < args.length; i++) switch (args[i]) {
6
+ case "--name":
7
+ options.name = args[++i];
8
+ break;
9
+ case "--title":
10
+ options.title = args[++i];
11
+ break;
12
+ case "--bio":
13
+ options.bio = args[++i];
14
+ break;
15
+ case "--json":
16
+ options.json = true;
17
+ break;
18
+ }
19
+ return options;
20
+ }
21
+ async function runJudgeDisplayUpdate(client, hackathonId, profileId, args) {
22
+ if (!profileId) {
23
+ console.error("Usage: oatmeal judge-display update <hackathon-id> <profile-id> [--name ...]");
24
+ process.exit(1);
25
+ }
26
+ const options = parseJudgeDisplayUpdateOptions(args);
27
+ const body = {};
28
+ if (options.name) body.name = options.name;
29
+ if (options.title) body.title = options.title;
30
+ if (options.bio) body.bio = options.bio;
31
+ if (Object.keys(body).length === 0) {
32
+ console.error("Error: provide at least one field to update");
33
+ process.exit(1);
34
+ }
35
+ const profile = await client.patch(`/api/dashboard/hackathons/${hackathonId}/judges/display/${profileId}`, body);
36
+ if (options.json) {
37
+ console.log(formatJson(profile));
38
+ return;
39
+ }
40
+ console.log(formatSuccess(`Updated judge display profile "${profile.name}"`));
41
+ }
42
+ //#endregion
43
+ export { runJudgeDisplayUpdate };
44
+
45
+ //# sourceMappingURL=update2.mjs.map