@rhseung/ps-cli 1.7.5 → 1.9.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.
- package/README.md +55 -12
- package/dist/chunk-D5PTJ4WQ.js +210 -0
- package/dist/chunk-EGPBBIJ2.js +251 -0
- package/dist/{chunk-F4LZ6ENP.js → chunk-JZK2464U.js} +1037 -118
- package/dist/chunk-SBBC4CBS.js +414 -0
- package/dist/{chunk-VIHXBCOZ.js → chunk-TTTS4CDS.js} +1 -1
- package/dist/chunk-XV6UUPQC.js +288 -0
- package/dist/{chunk-4ISG24GW.js → chunk-YH6VDCNG.js} +173 -15
- package/dist/chunk-YXLVFZZH.js +370 -0
- package/dist/commands/archive.js +6 -195
- package/dist/commands/config.js +74 -188
- package/dist/commands/fetch.js +7 -394
- package/dist/commands/init.js +50 -10
- package/dist/commands/open.js +6 -93
- package/dist/commands/run.js +59 -47
- package/dist/commands/search.js +296 -125
- package/dist/commands/stats.js +333 -84
- package/dist/commands/submit.js +7 -245
- package/dist/commands/test.js +7 -371
- package/dist/index.js +90 -52
- package/package.json +2 -1
- package/dist/chunk-7MQMPJ3X.js +0 -88
- package/dist/chunk-A6STXEAE.js +0 -54
- package/dist/chunk-ASMT3CRD.js +0 -500
- package/dist/chunk-GCOFFYJ3.js +0 -47
package/dist/commands/fetch.js
CHANGED
|
@@ -1,400 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
Command,
|
|
10
|
-
CommandBuilder,
|
|
11
|
-
CommandDef,
|
|
12
|
-
getAutoOpenEditor,
|
|
13
|
-
getEditor,
|
|
14
|
-
getSolvingDirPath,
|
|
15
|
-
getTierColor,
|
|
16
|
-
getTierImageUrl,
|
|
17
|
-
getTierName,
|
|
18
|
-
resolveProblemContext
|
|
19
|
-
} from "../chunk-F4LZ6ENP.js";
|
|
20
|
-
import {
|
|
21
|
-
__decorateClass,
|
|
22
|
-
getLanguageConfig,
|
|
23
|
-
getSupportedLanguages,
|
|
24
|
-
getSupportedLanguagesString
|
|
25
|
-
} from "../chunk-7MQMPJ3X.js";
|
|
26
|
-
|
|
27
|
-
// src/commands/fetch.tsx
|
|
28
|
-
import { StatusMessage, Alert } from "@inkjs/ui";
|
|
29
|
-
import { Spinner } from "@inkjs/ui";
|
|
30
|
-
import { Box as Box2 } from "ink";
|
|
31
|
-
|
|
32
|
-
// src/components/problem-dashboard.tsx
|
|
33
|
-
import { Box, Text } from "ink";
|
|
34
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
35
|
-
function ProblemDashboard({ problem }) {
|
|
36
|
-
const tierName = getTierName(problem.level);
|
|
37
|
-
const tierColor = getTierColor(problem.level);
|
|
38
|
-
const borderColorString = typeof tierColor === "string" ? tierColor : "#ff7ca8";
|
|
39
|
-
const textColorString = borderColorString;
|
|
40
|
-
return /* @__PURE__ */ jsx(
|
|
41
|
-
Box,
|
|
42
|
-
{
|
|
43
|
-
flexDirection: "column",
|
|
44
|
-
borderStyle: "round",
|
|
45
|
-
borderColor: borderColorString,
|
|
46
|
-
paddingX: 1,
|
|
47
|
-
alignSelf: "flex-start",
|
|
48
|
-
children: /* @__PURE__ */ jsxs(Text, { bold: true, color: textColorString, children: [
|
|
49
|
-
tierName,
|
|
50
|
-
" ",
|
|
51
|
-
/* @__PURE__ */ jsxs(Text, { color: "white", children: [
|
|
52
|
-
"#",
|
|
53
|
-
problem.id,
|
|
54
|
-
": ",
|
|
55
|
-
problem.title
|
|
56
|
-
] })
|
|
57
|
-
] })
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// src/hooks/use-fetch-problem.ts
|
|
63
|
-
import { execaCommand } from "execa";
|
|
64
|
-
import { useEffect, useState } from "react";
|
|
65
|
-
|
|
66
|
-
// src/services/file-generator.ts
|
|
67
|
-
import { mkdir, writeFile, readFile } from "fs/promises";
|
|
68
|
-
import { join, dirname } from "path";
|
|
69
|
-
import { fileURLToPath } from "url";
|
|
70
|
-
function parseTimeLimitToMs(timeLimit) {
|
|
71
|
-
if (!timeLimit) return void 0;
|
|
72
|
-
const match = timeLimit.match(/([\d.]+)/);
|
|
73
|
-
if (!match) return void 0;
|
|
74
|
-
const seconds = parseFloat(match[1]);
|
|
75
|
-
if (Number.isNaN(seconds)) return void 0;
|
|
76
|
-
return Math.round(seconds * 1e3);
|
|
77
|
-
}
|
|
78
|
-
function ensureTrailingNewline(content) {
|
|
79
|
-
if (!content || content.trim().length === 0) {
|
|
80
|
-
return content;
|
|
81
|
-
}
|
|
82
|
-
const trimmed = content.trimEnd();
|
|
83
|
-
if (trimmed.length === 0) {
|
|
84
|
-
return content;
|
|
85
|
-
}
|
|
86
|
-
const lines = trimmed.split("\n");
|
|
87
|
-
const lastLine = lines[lines.length - 1];
|
|
88
|
-
const isListItem = /^[\s]*[-*]\s/.test(lastLine) || /^[\s]*\d+[.)]\s/.test(lastLine);
|
|
89
|
-
const isTableRow = /^\s*\|.+\|\s*$/.test(lastLine);
|
|
90
|
-
const isCodeBlock = trimmed.endsWith("```");
|
|
91
|
-
if (isListItem || isTableRow || isCodeBlock) {
|
|
92
|
-
return trimmed + "\n";
|
|
93
|
-
}
|
|
94
|
-
if (!content.endsWith("\n")) {
|
|
95
|
-
return content + "\n";
|
|
96
|
-
}
|
|
97
|
-
return content;
|
|
98
|
-
}
|
|
99
|
-
function getProjectRoot() {
|
|
100
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
101
|
-
const __dirname = dirname(__filename);
|
|
102
|
-
if (__dirname.includes("dist")) {
|
|
103
|
-
return join(__dirname, "../..");
|
|
104
|
-
}
|
|
105
|
-
return join(__dirname, "../..");
|
|
106
|
-
}
|
|
107
|
-
async function generateProblemFiles(problem, language = "python") {
|
|
108
|
-
const problemDir = getSolvingDirPath(problem.id, process.cwd(), problem);
|
|
109
|
-
await mkdir(problemDir, { recursive: true });
|
|
110
|
-
const langConfig = getLanguageConfig(language);
|
|
111
|
-
const projectRoot = getProjectRoot();
|
|
112
|
-
const templatePath = join(projectRoot, "templates", langConfig.templateFile);
|
|
113
|
-
const solutionPath = join(problemDir, `solution.${langConfig.extension}`);
|
|
114
|
-
try {
|
|
115
|
-
const templateContent = await readFile(templatePath, "utf-8");
|
|
116
|
-
await writeFile(solutionPath, templateContent, "utf-8");
|
|
117
|
-
} catch {
|
|
118
|
-
await writeFile(
|
|
119
|
-
solutionPath,
|
|
120
|
-
`// Problem ${problem.id}: ${problem.title}
|
|
121
|
-
`,
|
|
122
|
-
"utf-8"
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
const testcasesDir = join(problemDir, "testcases");
|
|
126
|
-
for (let i = 0; i < problem.testCases.length; i++) {
|
|
127
|
-
const testCase = problem.testCases[i];
|
|
128
|
-
const caseDir = join(testcasesDir, String(i + 1));
|
|
129
|
-
await mkdir(caseDir, { recursive: true });
|
|
130
|
-
const inputPath = join(caseDir, "input.txt");
|
|
131
|
-
const outputPath = join(caseDir, "output.txt");
|
|
132
|
-
await writeFile(inputPath, testCase.input, "utf-8");
|
|
133
|
-
await writeFile(outputPath, testCase.output, "utf-8");
|
|
134
|
-
}
|
|
135
|
-
const tierName = getTierName(problem.level);
|
|
136
|
-
const tierImageUrl = getTierImageUrl(problem.level);
|
|
137
|
-
const tags = problem.tags.length > 0 ? problem.tags.join(", ") : "\uC5C6\uC74C";
|
|
138
|
-
const headers = [];
|
|
139
|
-
const values = [];
|
|
140
|
-
headers.push("\uB09C\uC774\uB3C4");
|
|
141
|
-
values.push(`<img src="${tierImageUrl}" alt="${tierName}" width="20" />`);
|
|
142
|
-
if (problem.timeLimit) {
|
|
143
|
-
headers.push("\uC2DC\uAC04 \uC81C\uD55C");
|
|
144
|
-
values.push(problem.timeLimit);
|
|
145
|
-
}
|
|
146
|
-
if (problem.memoryLimit) {
|
|
147
|
-
headers.push("\uBA54\uBAA8\uB9AC \uC81C\uD55C");
|
|
148
|
-
values.push(problem.memoryLimit);
|
|
149
|
-
}
|
|
150
|
-
if (problem.submissions) {
|
|
151
|
-
headers.push("\uC81C\uCD9C");
|
|
152
|
-
values.push(problem.submissions);
|
|
153
|
-
}
|
|
154
|
-
if (problem.accepted) {
|
|
155
|
-
headers.push("\uC815\uB2F5");
|
|
156
|
-
values.push(problem.accepted);
|
|
157
|
-
}
|
|
158
|
-
if (problem.acceptedUsers) {
|
|
159
|
-
headers.push("\uB9DE\uD78C \uC0AC\uB78C");
|
|
160
|
-
values.push(problem.acceptedUsers);
|
|
161
|
-
}
|
|
162
|
-
if (problem.acceptedRate) {
|
|
163
|
-
headers.push("\uC815\uB2F5 \uBE44\uC728");
|
|
164
|
-
values.push(problem.acceptedRate);
|
|
165
|
-
}
|
|
166
|
-
let infoTable = "";
|
|
167
|
-
if (headers.length > 0) {
|
|
168
|
-
const headerRow = `| ${headers.join(" | ")} |`;
|
|
169
|
-
const separatorRow = `|${headers.map(() => "---").join("|")}|`;
|
|
170
|
-
const valueRow = `| ${values.join(" | ")} |`;
|
|
171
|
-
infoTable = `
|
|
172
|
-
${headerRow}
|
|
173
|
-
${separatorRow}
|
|
174
|
-
${valueRow}
|
|
175
|
-
`;
|
|
176
|
-
}
|
|
177
|
-
const description = ensureTrailingNewline(problem.description || "\uC124\uBA85 \uC5C6\uC74C");
|
|
178
|
-
const inputFormat = ensureTrailingNewline(
|
|
179
|
-
problem.inputFormat || "\uC785\uB825 \uD615\uC2DD \uC5C6\uC74C"
|
|
180
|
-
);
|
|
181
|
-
const outputFormat = ensureTrailingNewline(
|
|
182
|
-
problem.outputFormat || "\uCD9C\uB825 \uD615\uC2DD \uC5C6\uC74C"
|
|
183
|
-
);
|
|
184
|
-
const readmeContent = `# [${problem.id}: ${problem.title}](https://www.acmicpc.net/problem/${problem.id})
|
|
185
|
-
|
|
186
|
-
${infoTable}## \uBB38\uC81C \uC124\uBA85
|
|
187
|
-
${description}## \uC785\uB825
|
|
188
|
-
${inputFormat}## \uCD9C\uB825
|
|
189
|
-
${outputFormat}
|
|
190
|
-
|
|
191
|
-
## \uC608\uC81C
|
|
192
|
-
${problem.testCases.map(
|
|
193
|
-
(tc, i) => `### \uC608\uC81C ${i + 1}
|
|
194
|
-
|
|
195
|
-
**\uC785\uB825:**
|
|
196
|
-
\`\`\`
|
|
197
|
-
${tc.input.trimEnd()}
|
|
198
|
-
\`\`\`
|
|
199
|
-
|
|
200
|
-
**\uCD9C\uB825:**
|
|
201
|
-
\`\`\`
|
|
202
|
-
${tc.output.trimEnd()}
|
|
203
|
-
\`\`\`
|
|
204
|
-
`
|
|
205
|
-
).join("\n")}
|
|
206
|
-
|
|
207
|
-
## \uD0DC\uADF8
|
|
208
|
-
${tags}
|
|
209
|
-
`;
|
|
210
|
-
const readmePath = join(problemDir, "README.md");
|
|
211
|
-
await writeFile(readmePath, readmeContent, "utf-8");
|
|
212
|
-
const meta = {
|
|
213
|
-
id: problem.id,
|
|
214
|
-
title: problem.title,
|
|
215
|
-
level: problem.level,
|
|
216
|
-
tags: problem.tags,
|
|
217
|
-
timeLimit: problem.timeLimit,
|
|
218
|
-
timeLimitMs: parseTimeLimitToMs(problem.timeLimit),
|
|
219
|
-
memoryLimit: problem.memoryLimit
|
|
220
|
-
};
|
|
221
|
-
const metaPath = join(problemDir, "meta.json");
|
|
222
|
-
await writeFile(metaPath, JSON.stringify(meta, null, 2), "utf-8");
|
|
223
|
-
return problemDir;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// src/hooks/use-fetch-problem.ts
|
|
227
|
-
function useFetchProblem({
|
|
228
|
-
problemId,
|
|
229
|
-
language,
|
|
230
|
-
onComplete
|
|
231
|
-
}) {
|
|
232
|
-
const [status, setStatus] = useState(
|
|
233
|
-
"loading"
|
|
234
|
-
);
|
|
235
|
-
const [problem, setProblem] = useState(null);
|
|
236
|
-
const [error, setError] = useState(null);
|
|
237
|
-
const [message, setMessage] = useState("\uBB38\uC81C \uC815\uBCF4\uB97C \uAC00\uC838\uC624\uB294 \uC911...");
|
|
238
|
-
useEffect(() => {
|
|
239
|
-
async function fetchProblem() {
|
|
240
|
-
try {
|
|
241
|
-
setMessage("Solved.ac\uC5D0\uC11C \uBB38\uC81C \uC815\uBCF4\uB97C \uAC00\uC838\uC624\uB294 \uC911...");
|
|
242
|
-
const solvedAcData = await getProblem(problemId);
|
|
243
|
-
setMessage("BOJ\uC5D0\uC11C \uBB38\uC81C \uC0C1\uC138 \uC815\uBCF4\uB97C \uAC00\uC838\uC624\uB294 \uC911...");
|
|
244
|
-
const scrapedData = await scrapeProblem(problemId);
|
|
245
|
-
if (!scrapedData.title && !solvedAcData.titleKo) {
|
|
246
|
-
throw new Error(
|
|
247
|
-
`\uBB38\uC81C ${problemId}\uC758 \uC81C\uBAA9\uC744 \uAC00\uC838\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBB38\uC81C\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uAC70\uB098 \uC811\uADFC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
const combinedProblem = {
|
|
251
|
-
id: problemId,
|
|
252
|
-
title: solvedAcData.titleKo || scrapedData.title,
|
|
253
|
-
level: solvedAcData.level,
|
|
254
|
-
tier: getTierName(solvedAcData.level),
|
|
255
|
-
tags: solvedAcData.tags.map(
|
|
256
|
-
(tag) => tag.displayNames.find((d) => d.language === "ko")?.name || tag.displayNames[0]?.name || tag.key
|
|
257
|
-
),
|
|
258
|
-
timeLimit: scrapedData.timeLimit,
|
|
259
|
-
memoryLimit: scrapedData.memoryLimit,
|
|
260
|
-
submissions: scrapedData.submissions,
|
|
261
|
-
accepted: scrapedData.accepted,
|
|
262
|
-
acceptedUsers: scrapedData.acceptedUsers,
|
|
263
|
-
acceptedRate: scrapedData.acceptedRate,
|
|
264
|
-
description: scrapedData.description,
|
|
265
|
-
inputFormat: scrapedData.inputFormat,
|
|
266
|
-
outputFormat: scrapedData.outputFormat,
|
|
267
|
-
testCases: scrapedData.testCases
|
|
268
|
-
};
|
|
269
|
-
setProblem(combinedProblem);
|
|
270
|
-
setMessage("\uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uB294 \uC911...");
|
|
271
|
-
const problemDir = await generateProblemFiles(
|
|
272
|
-
combinedProblem,
|
|
273
|
-
language
|
|
274
|
-
);
|
|
275
|
-
setStatus("success");
|
|
276
|
-
setMessage(`\uBB38\uC81C \uD30C\uC77C\uC774 \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${problemDir}`);
|
|
277
|
-
if (getAutoOpenEditor()) {
|
|
278
|
-
try {
|
|
279
|
-
const editor = getEditor();
|
|
280
|
-
await execaCommand(`${editor} ${problemDir}`, {
|
|
281
|
-
shell: true,
|
|
282
|
-
detached: true,
|
|
283
|
-
stdio: "ignore"
|
|
284
|
-
});
|
|
285
|
-
setMessage(
|
|
286
|
-
`\uBB38\uC81C \uD30C\uC77C\uC774 \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${problemDir}
|
|
287
|
-
${editor}\uB85C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.`
|
|
288
|
-
);
|
|
289
|
-
} catch (err) {
|
|
290
|
-
console.warn(
|
|
291
|
-
`\uC5D0\uB514\uD130\uB97C \uC5F4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${err instanceof Error ? err.message : String(err)}`
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
setTimeout(() => {
|
|
296
|
-
onComplete?.();
|
|
297
|
-
}, 2e3);
|
|
298
|
-
} catch (err) {
|
|
299
|
-
setStatus("error");
|
|
300
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
301
|
-
setTimeout(() => {
|
|
302
|
-
onComplete?.();
|
|
303
|
-
}, 2e3);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
void fetchProblem();
|
|
307
|
-
}, [problemId, language, onComplete]);
|
|
308
|
-
return {
|
|
309
|
-
status,
|
|
310
|
-
problem,
|
|
311
|
-
error,
|
|
312
|
-
message
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// src/commands/fetch.tsx
|
|
317
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
318
|
-
function FetchView({
|
|
319
|
-
problemId,
|
|
320
|
-
language = "python",
|
|
321
|
-
onComplete
|
|
322
|
-
}) {
|
|
323
|
-
const { status, problem, error, message } = useFetchProblem({
|
|
324
|
-
problemId,
|
|
325
|
-
language,
|
|
326
|
-
onComplete
|
|
327
|
-
});
|
|
328
|
-
if (status === "loading") {
|
|
329
|
-
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
330
|
-
/* @__PURE__ */ jsx2(Spinner, { label: message }),
|
|
331
|
-
problem && /* @__PURE__ */ jsx2(ProblemDashboard, { problem })
|
|
332
|
-
] });
|
|
333
|
-
}
|
|
334
|
-
if (status === "error") {
|
|
335
|
-
return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsxs2(Alert, { variant: "error", children: [
|
|
336
|
-
"\uC624\uB958 \uBC1C\uC0DD: ",
|
|
337
|
-
error
|
|
338
|
-
] }) });
|
|
339
|
-
}
|
|
340
|
-
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: "100%", children: [
|
|
341
|
-
problem && /* @__PURE__ */ jsx2(Box2, { alignSelf: "flex-start", children: /* @__PURE__ */ jsx2(ProblemDashboard, { problem }) }),
|
|
342
|
-
/* @__PURE__ */ jsx2(StatusMessage, { variant: "success", children: message })
|
|
343
|
-
] });
|
|
344
|
-
}
|
|
345
|
-
var FetchCommand = class extends Command {
|
|
346
|
-
async execute(args, flags) {
|
|
347
|
-
const context = await resolveProblemContext(args, { requireId: true });
|
|
348
|
-
if (context.problemId === null) {
|
|
349
|
-
console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
350
|
-
console.error(`\uC0AC\uC6A9\uBC95: ps fetch <\uBB38\uC81C\uBC88\uD638> [\uC635\uC158]`);
|
|
351
|
-
console.error(`\uB3C4\uC6C0\uB9D0: ps fetch --help`);
|
|
352
|
-
console.error(
|
|
353
|
-
`\uD78C\uD2B8: problems/{\uBB38\uC81C\uBC88\uD638} \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC2E4\uD589\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uBB38\uC81C \uBC88\uD638\uB97C \uCD94\uB860\uD569\uB2C8\uB2E4.`
|
|
354
|
-
);
|
|
355
|
-
process.exit(1);
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
const validLanguages = getSupportedLanguages();
|
|
359
|
-
const language = flags.language;
|
|
360
|
-
if (language && !validLanguages.includes(language)) {
|
|
361
|
-
console.error(
|
|
362
|
-
`\uC624\uB958: \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC5B8\uC5B4\uC785\uB2C8\uB2E4. (${getSupportedLanguagesString()})`
|
|
363
|
-
);
|
|
364
|
-
process.exit(1);
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
await this.renderView(FetchView, {
|
|
368
|
-
problemId: context.problemId,
|
|
369
|
-
language: language || "python"
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
};
|
|
373
|
-
FetchCommand = __decorateClass([
|
|
374
|
-
CommandDef({
|
|
375
|
-
name: "fetch",
|
|
376
|
-
description: `\uBC31\uC900 \uBB38\uC81C\uB97C \uAC00\uC838\uC640\uC11C \uB85C\uCEEC\uC5D0 \uD30C\uC77C\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.
|
|
377
|
-
- Solved.ac API\uC640 BOJ \uD06C\uB864\uB9C1\uC744 \uD1B5\uD574 \uBB38\uC81C \uC815\uBCF4 \uC218\uC9D1
|
|
378
|
-
- \uBB38\uC81C \uC124\uBA85, \uC785\uCD9C\uB825 \uD615\uC2DD, \uC608\uC81C \uC785\uCD9C\uB825 \uD30C\uC77C \uC790\uB3D9 \uC0DD\uC131
|
|
379
|
-
- \uC120\uD0DD\uD55C \uC5B8\uC5B4\uC758 \uC194\uB8E8\uC158 \uD15C\uD50C\uB9BF \uD30C\uC77C \uC0DD\uC131
|
|
380
|
-
- README.md\uC5D0 \uBB38\uC81C \uC815\uBCF4, \uD1B5\uACC4, \uD0DC\uADF8 \uB4F1 \uD3EC\uD568`,
|
|
381
|
-
flags: [
|
|
382
|
-
{
|
|
383
|
-
name: "language",
|
|
384
|
-
options: {
|
|
385
|
-
shortFlag: "l",
|
|
386
|
-
description: `\uC5B8\uC5B4 \uC120\uD0DD (${getSupportedLanguagesString()})
|
|
387
|
-
\uAE30\uBCF8\uAC12: python`
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
],
|
|
391
|
-
autoDetectProblemId: false,
|
|
392
|
-
requireProblemId: true,
|
|
393
|
-
examples: ["fetch 1000", "fetch 1000 --language python", "fetch 1000 -l cpp"]
|
|
394
|
-
})
|
|
395
|
-
], FetchCommand);
|
|
396
|
-
var fetch_default = CommandBuilder.fromClass(FetchCommand);
|
|
3
|
+
FetchCommand,
|
|
4
|
+
FetchView,
|
|
5
|
+
fetch_default
|
|
6
|
+
} from "../chunk-SBBC4CBS.js";
|
|
7
|
+
import "../chunk-YH6VDCNG.js";
|
|
8
|
+
import "../chunk-JZK2464U.js";
|
|
397
9
|
export {
|
|
398
10
|
FetchCommand,
|
|
11
|
+
FetchView,
|
|
399
12
|
fetch_default as default
|
|
400
13
|
};
|
package/dist/commands/init.js
CHANGED
|
@@ -3,18 +3,18 @@ import {
|
|
|
3
3
|
Command,
|
|
4
4
|
CommandBuilder,
|
|
5
5
|
CommandDef,
|
|
6
|
+
__decorateClass,
|
|
6
7
|
getArchiveDir,
|
|
7
8
|
getArchiveStrategy,
|
|
8
9
|
getAutoOpenEditor,
|
|
9
10
|
getDefaultLanguage,
|
|
10
11
|
getEditor,
|
|
12
|
+
getIncludeTag,
|
|
11
13
|
getSolvedAcHandle,
|
|
12
|
-
getSolvingDir
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
getSupportedLanguages
|
|
17
|
-
} from "../chunk-7MQMPJ3X.js";
|
|
14
|
+
getSolvingDir,
|
|
15
|
+
getSupportedLanguages,
|
|
16
|
+
icons
|
|
17
|
+
} from "../chunk-JZK2464U.js";
|
|
18
18
|
|
|
19
19
|
// src/commands/init.tsx
|
|
20
20
|
import {
|
|
@@ -42,6 +42,7 @@ function useInit({ onComplete }) {
|
|
|
42
42
|
const [language, setLanguage] = useState(getDefaultLanguage());
|
|
43
43
|
const [editor, setEditorValue] = useState(getEditor());
|
|
44
44
|
const [autoOpen, setAutoOpen] = useState(getAutoOpenEditor());
|
|
45
|
+
const [includeTag, setIncludeTag] = useState(getIncludeTag());
|
|
45
46
|
const [handle, setHandle] = useState(getSolvedAcHandle() || "");
|
|
46
47
|
const [handleInputMode, setHandleInputMode] = useState(false);
|
|
47
48
|
const [created, setCreated] = useState([]);
|
|
@@ -82,6 +83,8 @@ function useInit({ onComplete }) {
|
|
|
82
83
|
if (projectConfig.editor) setEditorValue(projectConfig.editor);
|
|
83
84
|
if (projectConfig.autoOpenEditor !== void 0)
|
|
84
85
|
setAutoOpen(projectConfig.autoOpenEditor);
|
|
86
|
+
if (projectConfig.includeTag !== void 0)
|
|
87
|
+
setIncludeTag(projectConfig.includeTag);
|
|
85
88
|
if (projectConfig.solvedAcHandle)
|
|
86
89
|
setHandle(projectConfig.solvedAcHandle);
|
|
87
90
|
} catch {
|
|
@@ -105,6 +108,8 @@ function useInit({ onComplete }) {
|
|
|
105
108
|
return "\uC5D0\uB514\uD130 \uC124\uC815";
|
|
106
109
|
case "auto-open":
|
|
107
110
|
return "\uC790\uB3D9 \uC5D0\uB514\uD130 \uC5F4\uAE30";
|
|
111
|
+
case "include-tag":
|
|
112
|
+
return "README\uC5D0 \uC54C\uACE0\uB9AC\uC998 \uBD84\uB958 \uD3EC\uD568";
|
|
108
113
|
case "handle":
|
|
109
114
|
return "Solved.ac \uD578\uB4E4 (\uC120\uD0DD)";
|
|
110
115
|
default:
|
|
@@ -133,6 +138,8 @@ function useInit({ onComplete }) {
|
|
|
133
138
|
return editor;
|
|
134
139
|
case "auto-open":
|
|
135
140
|
return autoOpen ? "\uC608" : "\uC544\uB2C8\uC624";
|
|
141
|
+
case "include-tag":
|
|
142
|
+
return includeTag ? "\uC608" : "\uC544\uB2C8\uC624";
|
|
136
143
|
case "handle":
|
|
137
144
|
return handle || "(\uC2A4\uD0B5)";
|
|
138
145
|
default:
|
|
@@ -145,6 +152,7 @@ function useInit({ onComplete }) {
|
|
|
145
152
|
language,
|
|
146
153
|
editor,
|
|
147
154
|
autoOpen,
|
|
155
|
+
includeTag,
|
|
148
156
|
handle,
|
|
149
157
|
archiveStrategy
|
|
150
158
|
]
|
|
@@ -160,7 +168,8 @@ function useInit({ onComplete }) {
|
|
|
160
168
|
archiveStrategy,
|
|
161
169
|
defaultLanguage: language,
|
|
162
170
|
editor,
|
|
163
|
-
autoOpenEditor: autoOpen
|
|
171
|
+
autoOpenEditor: autoOpen,
|
|
172
|
+
includeTag
|
|
164
173
|
};
|
|
165
174
|
const handleToUse = overrideHandle ?? handle;
|
|
166
175
|
if (handleToUse && typeof handleToUse === "string" && handleToUse.trim().length > 0) {
|
|
@@ -286,6 +295,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
286
295
|
language,
|
|
287
296
|
editor,
|
|
288
297
|
autoOpen,
|
|
298
|
+
includeTag,
|
|
289
299
|
handle,
|
|
290
300
|
onComplete
|
|
291
301
|
]
|
|
@@ -306,6 +316,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
306
316
|
"language",
|
|
307
317
|
"editor",
|
|
308
318
|
"auto-open",
|
|
319
|
+
"include-tag",
|
|
309
320
|
"handle",
|
|
310
321
|
"done"
|
|
311
322
|
];
|
|
@@ -335,6 +346,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
335
346
|
language,
|
|
336
347
|
editor,
|
|
337
348
|
autoOpen,
|
|
349
|
+
includeTag,
|
|
338
350
|
handle,
|
|
339
351
|
handleInputMode,
|
|
340
352
|
created,
|
|
@@ -345,6 +357,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
345
357
|
setLanguage,
|
|
346
358
|
setEditorValue,
|
|
347
359
|
setAutoOpen,
|
|
360
|
+
setIncludeTag,
|
|
348
361
|
setHandle,
|
|
349
362
|
setHandleInputMode,
|
|
350
363
|
setConfirmExit,
|
|
@@ -389,6 +402,7 @@ function InitView({ onComplete }) {
|
|
|
389
402
|
setLanguage,
|
|
390
403
|
setEditorValue,
|
|
391
404
|
setAutoOpen,
|
|
405
|
+
setIncludeTag,
|
|
392
406
|
setHandle,
|
|
393
407
|
setHandleInputMode,
|
|
394
408
|
setConfirmExit,
|
|
@@ -563,6 +577,28 @@ function InitView({ onComplete }) {
|
|
|
563
577
|
)
|
|
564
578
|
);
|
|
565
579
|
}
|
|
580
|
+
case "include-tag": {
|
|
581
|
+
const options = [
|
|
582
|
+
{ label: "\uC608", value: "true" },
|
|
583
|
+
{ label: "\uC544\uB2C8\uC624", value: "false" }
|
|
584
|
+
];
|
|
585
|
+
return renderQuestionCard(
|
|
586
|
+
getStepLabel(currentStep),
|
|
587
|
+
/* @__PURE__ */ jsx(
|
|
588
|
+
Select,
|
|
589
|
+
{
|
|
590
|
+
options,
|
|
591
|
+
onChange: (value) => {
|
|
592
|
+
setIncludeTag(value === "true");
|
|
593
|
+
moveToNextStep(
|
|
594
|
+
value === "true" ? "\uC608" : "\uC544\uB2C8\uC624",
|
|
595
|
+
getStepLabel(currentStep)
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
)
|
|
600
|
+
);
|
|
601
|
+
}
|
|
566
602
|
case "handle": {
|
|
567
603
|
if (handleInputMode) {
|
|
568
604
|
return renderQuestionCard(
|
|
@@ -610,7 +646,7 @@ function InitView({ onComplete }) {
|
|
|
610
646
|
case "done": {
|
|
611
647
|
const createdItemsText = created.length > 0 ? `
|
|
612
648
|
\uC0DD\uC131\uB41C \uD56D\uBAA9:
|
|
613
|
-
${created.map((item) =>
|
|
649
|
+
${created.map((item) => `${icons.solving} ${item}`).join("\n")}` : "";
|
|
614
650
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
615
651
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Alert, { variant: "success", children: [
|
|
616
652
|
"\uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 \uC644\uB8CC",
|
|
@@ -635,7 +671,10 @@ ${created.map((item) => `\u2022 ${item}`).join("\n")}` : "";
|
|
|
635
671
|
const version = getVersion();
|
|
636
672
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
637
673
|
/* @__PURE__ */ jsxs(Box, { marginBottom: completedSteps.length > 0 ? 1 : 0, children: [
|
|
638
|
-
/* @__PURE__ */
|
|
674
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
|
|
675
|
+
icons.init,
|
|
676
|
+
" ps-cli \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654"
|
|
677
|
+
] }),
|
|
639
678
|
version && /* @__PURE__ */ jsxs(Text, { color: "gray", dimColor: true, children: [
|
|
640
679
|
" ",
|
|
641
680
|
"v",
|
|
@@ -660,7 +699,8 @@ InitCommand = __decorateClass([
|
|
|
660
699
|
name: "init",
|
|
661
700
|
description: `\uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uB97C ps-cli \uD504\uB85C\uC81D\uD2B8\uB85C \uB300\uD654\uD615\uC73C\uB85C \uCD08\uAE30\uD654\uD569\uB2C8\uB2E4.
|
|
662
701
|
- \uB2E8\uACC4\uBCC4\uB85C \uC124\uC815\uC744 \uBB3C\uC5B4\uBD05\uB2C8\uB2E4
|
|
663
|
-
- \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC, \uAE30\uBCF8 \uC5B8\uC5B4, \uC5D0\uB514\uD130 \uB4F1\uC744 \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4`,
|
|
702
|
+
- \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC, \uAE30\uBCF8 \uC5B8\uC5B4, \uC5D0\uB514\uD130, \uD0DC\uADF8 \uD3EC\uD568 \uC5EC\uBD80 \uB4F1\uC744 \uC124\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4`,
|
|
703
|
+
flags: [],
|
|
664
704
|
autoDetectProblemId: false,
|
|
665
705
|
examples: ["init"]
|
|
666
706
|
})
|
package/dist/commands/open.js
CHANGED
|
@@ -1,100 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
OpenCommand,
|
|
4
|
+
OpenView,
|
|
5
|
+
open_default
|
|
6
|
+
} from "../chunk-XV6UUPQC.js";
|
|
5
7
|
import "../chunk-QGMWUOJ3.js";
|
|
6
|
-
import
|
|
7
|
-
Command,
|
|
8
|
-
CommandBuilder,
|
|
9
|
-
CommandDef,
|
|
10
|
-
resolveProblemContext
|
|
11
|
-
} from "../chunk-F4LZ6ENP.js";
|
|
12
|
-
import {
|
|
13
|
-
__decorateClass
|
|
14
|
-
} from "../chunk-7MQMPJ3X.js";
|
|
15
|
-
|
|
16
|
-
// src/commands/open.tsx
|
|
17
|
-
import { StatusMessage, Alert } from "@inkjs/ui";
|
|
18
|
-
import { Spinner } from "@inkjs/ui";
|
|
19
|
-
import { Text, Box } from "ink";
|
|
20
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
-
function OpenView({ problemId, onComplete }) {
|
|
22
|
-
const { status, error, url } = useOpenBrowser({
|
|
23
|
-
problemId,
|
|
24
|
-
onComplete
|
|
25
|
-
});
|
|
26
|
-
if (status === "loading") {
|
|
27
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
28
|
-
/* @__PURE__ */ jsx(Spinner, { label: "\uBE0C\uB77C\uC6B0\uC800\uB97C \uC5EC\uB294 \uC911..." }),
|
|
29
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
30
|
-
"\uBB38\uC81C #",
|
|
31
|
-
problemId
|
|
32
|
-
] }) })
|
|
33
|
-
] });
|
|
34
|
-
}
|
|
35
|
-
if (status === "error") {
|
|
36
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
37
|
-
/* @__PURE__ */ jsxs(Alert, { variant: "error", children: [
|
|
38
|
-
"\uBE0C\uB77C\uC6B0\uC800\uB97C \uC5F4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ",
|
|
39
|
-
error
|
|
40
|
-
] }),
|
|
41
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
42
|
-
"URL: ",
|
|
43
|
-
url
|
|
44
|
-
] }) })
|
|
45
|
-
] });
|
|
46
|
-
}
|
|
47
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "100%", children: [
|
|
48
|
-
/* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: "\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uBB38\uC81C \uD398\uC774\uC9C0\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4!" }),
|
|
49
|
-
/* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
50
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
51
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\uBB38\uC81C \uBC88\uD638:" }),
|
|
52
|
-
" ",
|
|
53
|
-
problemId
|
|
54
|
-
] }),
|
|
55
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
56
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "URL:" }),
|
|
57
|
-
" ",
|
|
58
|
-
/* @__PURE__ */ jsx(Text, { color: "blue", underline: true, children: url })
|
|
59
|
-
] })
|
|
60
|
-
] })
|
|
61
|
-
] });
|
|
62
|
-
}
|
|
63
|
-
var OpenCommand = class extends Command {
|
|
64
|
-
async execute(args, _flags) {
|
|
65
|
-
const context = await resolveProblemContext(args, { requireId: true });
|
|
66
|
-
if (context.problemId === null) {
|
|
67
|
-
console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
68
|
-
console.error(`\uC0AC\uC6A9\uBC95: ps open <\uBB38\uC81C\uBC88\uD638>`);
|
|
69
|
-
console.error(`\uB3C4\uC6C0\uB9D0: ps open --help`);
|
|
70
|
-
console.error(
|
|
71
|
-
`\uD78C\uD2B8: problems/{\uBB38\uC81C\uBC88\uD638} \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC2E4\uD589\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uBB38\uC81C \uBC88\uD638\uB97C \uCD94\uB860\uD569\uB2C8\uB2E4.`
|
|
72
|
-
);
|
|
73
|
-
process.exit(1);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
await this.renderView(OpenView, {
|
|
77
|
-
problemId: context.problemId
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
OpenCommand = __decorateClass([
|
|
82
|
-
CommandDef({
|
|
83
|
-
name: "open",
|
|
84
|
-
description: `\uBC31\uC900 \uBB38\uC81C \uD398\uC774\uC9C0\uB97C \uBE0C\uB77C\uC6B0\uC800\uB85C \uC5FD\uB2C8\uB2E4.
|
|
85
|
-
- \uBB38\uC81C \uBC88\uD638\uB97C \uC778\uC790\uB85C \uC804\uB2EC\uD558\uAC70\uB098
|
|
86
|
-
- \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC2E4\uD589\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uBB38\uC81C \uBC88\uD638\uB97C \uCD94\uB860\uD569\uB2C8\uB2E4.`,
|
|
87
|
-
autoDetectProblemId: true,
|
|
88
|
-
requireProblemId: true,
|
|
89
|
-
examples: [
|
|
90
|
-
"open 1000 # 1000\uBC88 \uBB38\uC81C \uC5F4\uAE30",
|
|
91
|
-
"open # \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC2E4\uD589 \uC2DC \uC790\uB3D9 \uCD94\uB860",
|
|
92
|
-
"open --help # \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC"
|
|
93
|
-
]
|
|
94
|
-
})
|
|
95
|
-
], OpenCommand);
|
|
96
|
-
var open_default = CommandBuilder.fromClass(OpenCommand);
|
|
8
|
+
import "../chunk-JZK2464U.js";
|
|
97
9
|
export {
|
|
98
10
|
OpenCommand,
|
|
11
|
+
OpenView,
|
|
99
12
|
open_default as default
|
|
100
13
|
};
|