@bifos/dooray-cli 0.5.4 → 0.6.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 +151 -43
- package/dist/index.js +780 -108
- package/package.json +2 -2
- package/skills/dooray-cli/SKILL.md +64 -17
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
27
|
+
var import_commander46 = require("commander");
|
|
28
28
|
var import_chalk7 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/commands/config.ts
|
|
@@ -127,10 +127,13 @@ async function setConfigValue(key, value) {
|
|
|
127
127
|
case "smtp-port":
|
|
128
128
|
config.smtpPort = parseInt(value, 10);
|
|
129
129
|
break;
|
|
130
|
+
case "track-last-run":
|
|
131
|
+
config.trackLastRun = value === "true";
|
|
132
|
+
break;
|
|
130
133
|
default:
|
|
131
134
|
throw new DoorayCliError(
|
|
132
135
|
`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${key}
|
|
133
|
-
\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD0A4: api-key, base-url, tenant-name, imap-host, imap-port, imap-username, imap-password, smtp-host, smtp-port`,
|
|
136
|
+
\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD0A4: api-key, base-url, tenant-name, imap-host, imap-port, imap-username, imap-password, smtp-host, smtp-port, track-last-run`,
|
|
134
137
|
EXIT_CONFIG_ERROR
|
|
135
138
|
);
|
|
136
139
|
}
|
|
@@ -525,6 +528,13 @@ var DoorayApiClient = class {
|
|
|
525
528
|
return toDoorayCliError(e);
|
|
526
529
|
}
|
|
527
530
|
}
|
|
531
|
+
async getPostComment(projectId, postId, logId) {
|
|
532
|
+
try {
|
|
533
|
+
return await this.api.get(`project/v1/projects/${projectId}/posts/${postId}/logs/${logId}`).json();
|
|
534
|
+
} catch (e) {
|
|
535
|
+
return toDoorayCliError(e);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
528
538
|
async createPostComment(projectId, postId, body) {
|
|
529
539
|
try {
|
|
530
540
|
return await this.api.post(`project/v1/projects/${projectId}/posts/${postId}/logs`, { json: body }).json();
|
|
@@ -567,6 +577,23 @@ var DoorayApiClient = class {
|
|
|
567
577
|
return toDoorayCliError(e);
|
|
568
578
|
}
|
|
569
579
|
}
|
|
580
|
+
async searchMembers(params) {
|
|
581
|
+
try {
|
|
582
|
+
return await this.api.get("common/v1/members", {
|
|
583
|
+
searchParams: {
|
|
584
|
+
...params.name && { name: params.name },
|
|
585
|
+
...params.externalEmailAddresses && { externalEmailAddresses: params.externalEmailAddresses },
|
|
586
|
+
...params.userCode && { userCode: params.userCode },
|
|
587
|
+
...params.userCodeExact && { userCodeExact: params.userCodeExact },
|
|
588
|
+
...params.idProviderUserId && { idProviderUserId: params.idProviderUserId },
|
|
589
|
+
...params.page != null && { page: params.page },
|
|
590
|
+
...params.size != null && { size: params.size }
|
|
591
|
+
}
|
|
592
|
+
}).json();
|
|
593
|
+
} catch (e) {
|
|
594
|
+
return toDoorayCliError(e);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
570
597
|
// ─── Workflows ──────────────────────────────────────
|
|
571
598
|
async getProjectWorkflows(projectId) {
|
|
572
599
|
try {
|
|
@@ -780,13 +807,24 @@ var WIKIS_TTL_MS = 864e5;
|
|
|
780
807
|
// src/resolvers/me.ts
|
|
781
808
|
async function ensureMe(client) {
|
|
782
809
|
const entry = await getMe();
|
|
783
|
-
if (entry && !isExpired(entry.updatedAt, ME_TTL_MS)) {
|
|
810
|
+
if (entry && !isExpired(entry.updatedAt, ME_TTL_MS) && entry.data.orgId) {
|
|
784
811
|
return entry.data;
|
|
785
812
|
}
|
|
786
813
|
const res = await client.getMe();
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
|
|
814
|
+
const orgId = res.result.defaultOrganization?.id ?? "";
|
|
815
|
+
if (!orgId) {
|
|
816
|
+
throw new DoorayCliError(
|
|
817
|
+
"orgId\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (getMe \uC751\uB2F5\uC5D0 defaultOrganization.id \uB204\uB77D). dooray cache clear \uD6C4 \uC7AC\uC2DC\uB3C4\uD558\uC138\uC694.",
|
|
818
|
+
EXIT_PARAM_ERROR
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
const cached = {
|
|
822
|
+
id: res.result.id,
|
|
823
|
+
name: res.result.name,
|
|
824
|
+
orgId
|
|
825
|
+
};
|
|
826
|
+
await setMe(cached);
|
|
827
|
+
return cached;
|
|
790
828
|
}
|
|
791
829
|
|
|
792
830
|
// src/commands/doctor.ts
|
|
@@ -973,6 +1011,11 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
973
1011
|
}
|
|
974
1012
|
}
|
|
975
1013
|
}
|
|
1014
|
+
const trackLastRun = await confirm2({
|
|
1015
|
+
message: "feedback --last \uBAA8\uB4DC \uD65C\uC131\uD654 (\uC9C1\uC804 \uBA85\uB839 \uC5D0\uB7EC\uB97C GitHub issue\uC5D0 \uC790\uB3D9 \uCCA8\uBD80)?",
|
|
1016
|
+
default: false,
|
|
1017
|
+
theme: { prefix: "\u{1F4CB}" }
|
|
1018
|
+
});
|
|
976
1019
|
const config = {
|
|
977
1020
|
version: 1,
|
|
978
1021
|
apiKey,
|
|
@@ -985,6 +1028,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
985
1028
|
smtpHost: useMail ? DEFAULTS.smtpHost : existing?.smtpHost,
|
|
986
1029
|
smtpPort: useMail ? DEFAULTS.smtpPort : existing?.smtpPort
|
|
987
1030
|
};
|
|
1031
|
+
config.trackLastRun = trackLastRun;
|
|
988
1032
|
await saveConfig(config);
|
|
989
1033
|
console.log(
|
|
990
1034
|
import_chalk4.default.green(
|
|
@@ -1084,17 +1128,29 @@ function output(opts, data) {
|
|
|
1084
1128
|
// src/utils/spinner.ts
|
|
1085
1129
|
var import_ora = __toESM(require("ora"));
|
|
1086
1130
|
var current = null;
|
|
1131
|
+
var quiet = false;
|
|
1132
|
+
var noopSpinner = new Proxy({}, {
|
|
1133
|
+
get(_target, prop) {
|
|
1134
|
+
if (prop === "text" || prop === "prefixText" || prop === "suffixText") return "";
|
|
1135
|
+
if (prop === "isSpinning") return false;
|
|
1136
|
+
return () => noopSpinner;
|
|
1137
|
+
},
|
|
1138
|
+
set() {
|
|
1139
|
+
return true;
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
function setQuiet(value) {
|
|
1143
|
+
quiet = value;
|
|
1144
|
+
}
|
|
1087
1145
|
function startSpinner(text) {
|
|
1146
|
+
if (quiet) return noopSpinner;
|
|
1088
1147
|
current = (0, import_ora.default)({ text, stream: process.stderr }).start();
|
|
1089
1148
|
return current;
|
|
1090
1149
|
}
|
|
1091
1150
|
function stopSpinner(success, text) {
|
|
1092
1151
|
if (!current) return;
|
|
1093
|
-
if (success === false)
|
|
1094
|
-
|
|
1095
|
-
} else {
|
|
1096
|
-
current.succeed(text);
|
|
1097
|
-
}
|
|
1152
|
+
if (success === false) current.fail(text);
|
|
1153
|
+
else current.succeed(text);
|
|
1098
1154
|
current = null;
|
|
1099
1155
|
}
|
|
1100
1156
|
|
|
@@ -1312,6 +1368,12 @@ async function ensureMemberGroups(client, projectId) {
|
|
|
1312
1368
|
await setMemberGroups(projectId, items);
|
|
1313
1369
|
return items;
|
|
1314
1370
|
}
|
|
1371
|
+
async function resolveMemberGroup(client, projectId, input2) {
|
|
1372
|
+
const groups = await ensureMemberGroups(client, projectId);
|
|
1373
|
+
const adapter = groups.map((g) => ({ name: g.code, id: g.id, code: g.code }));
|
|
1374
|
+
const match = matchByName(adapter, input2, "\uADF8\uB8F9", (g) => `${g.code} (${g.id})`);
|
|
1375
|
+
return { id: match.id, code: match.code };
|
|
1376
|
+
}
|
|
1315
1377
|
|
|
1316
1378
|
// src/commands/project/groups.ts
|
|
1317
1379
|
var projectGroupsCommand = new import_commander8.Command("groups").description("\uD504\uB85C\uC81D\uD2B8 \uBA64\uBC84 \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
|
|
@@ -1364,6 +1426,35 @@ async function ensureTags(client, projectId) {
|
|
|
1364
1426
|
await setTags(projectId, items);
|
|
1365
1427
|
return items;
|
|
1366
1428
|
}
|
|
1429
|
+
function buildMandatoryHint(allTags, missingGroupIds) {
|
|
1430
|
+
const lines = [];
|
|
1431
|
+
for (const groupId of missingGroupIds) {
|
|
1432
|
+
const groupTags = allTags.filter((t) => t.groupId === groupId);
|
|
1433
|
+
const groupName = groupTags[0]?.groupName ?? groupId;
|
|
1434
|
+
const candidates = groupTags.map((t) => t.name).join(", ");
|
|
1435
|
+
lines.push(` - "${groupName}": ${candidates || "(\uD0DC\uADF8 \uC5C6\uC74C)"}`);
|
|
1436
|
+
}
|
|
1437
|
+
return lines.join("\n");
|
|
1438
|
+
}
|
|
1439
|
+
async function validateMandatoryTags(client, projectId) {
|
|
1440
|
+
const allTags = await ensureTags(client, projectId);
|
|
1441
|
+
const missingGroupIds = [];
|
|
1442
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1443
|
+
for (const t of allTags) {
|
|
1444
|
+
if (t.groupMandatory && t.groupId && !seen.has(t.groupId)) {
|
|
1445
|
+
seen.add(t.groupId);
|
|
1446
|
+
missingGroupIds.push(t.groupId);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
if (missingGroupIds.length === 0) return;
|
|
1450
|
+
throw new DoorayCliError(
|
|
1451
|
+
`\uD544\uC218 \uD0DC\uADF8 \uADF8\uB8F9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (\uADF8\uB8F9\uB2F9 1\uAC1C \uC774\uC0C1 \uD544\uC694):
|
|
1452
|
+
` + buildMandatoryHint(allTags, missingGroupIds) + `
|
|
1453
|
+
|
|
1454
|
+
\uB2E4\uC2DC \uC2DC\uB3C4: --tag "<\uADF8\uB8F9>: <\uD6C4\uBCF4>" \uD615\uC2DD\uC73C\uB85C \uCD94\uAC00`,
|
|
1455
|
+
EXIT_PARAM_ERROR
|
|
1456
|
+
);
|
|
1457
|
+
}
|
|
1367
1458
|
async function resolveTags(client, projectId, inputs) {
|
|
1368
1459
|
const allTags = await ensureTags(client, projectId);
|
|
1369
1460
|
const selected = inputs.map(
|
|
@@ -1379,14 +1470,14 @@ async function resolveTags(client, projectId, inputs) {
|
|
|
1379
1470
|
if (t.groupMandatory && t.groupId) mandatoryGroups.set(t.groupId, t.groupName ?? t.groupId);
|
|
1380
1471
|
}
|
|
1381
1472
|
const coveredGroups = new Set(selected.map((t) => t.groupId).filter((g) => !!g));
|
|
1382
|
-
const
|
|
1383
|
-
for (const [gid
|
|
1384
|
-
if (!coveredGroups.has(gid))
|
|
1473
|
+
const missingIds = [];
|
|
1474
|
+
for (const [gid] of mandatoryGroups) {
|
|
1475
|
+
if (!coveredGroups.has(gid)) missingIds.push(gid);
|
|
1385
1476
|
}
|
|
1386
|
-
if (
|
|
1477
|
+
if (missingIds.length > 0) {
|
|
1387
1478
|
throw new DoorayCliError(
|
|
1388
1479
|
`\uD544\uC218 \uD0DC\uADF8 \uADF8\uB8F9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (\uADF8\uB8F9\uB2F9 1\uAC1C \uC774\uC0C1 \uD544\uC694):
|
|
1389
|
-
` +
|
|
1480
|
+
` + buildMandatoryHint(allTags, missingIds),
|
|
1390
1481
|
EXIT_PARAM_ERROR
|
|
1391
1482
|
);
|
|
1392
1483
|
}
|
|
@@ -1553,9 +1644,13 @@ async function resolvePost(client, projectId, postNumber) {
|
|
|
1553
1644
|
|
|
1554
1645
|
// src/utils/dooray-url.ts
|
|
1555
1646
|
var TASK_URL_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/to\/(\d+)(?:[/?#].*)?$/;
|
|
1647
|
+
var TASK_URL_ALT_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/(?:\d+)\/(\d+)(?:[/?#].*)?$/;
|
|
1556
1648
|
function parseDoorayTaskUrl(input2) {
|
|
1557
|
-
const
|
|
1558
|
-
|
|
1649
|
+
const m1 = TASK_URL_RE.exec(input2);
|
|
1650
|
+
if (m1) return m1[1];
|
|
1651
|
+
const m2 = TASK_URL_ALT_RE.exec(input2);
|
|
1652
|
+
if (m2) return m2[1];
|
|
1653
|
+
return null;
|
|
1559
1654
|
}
|
|
1560
1655
|
function isLikelyDoorayUrl(input2) {
|
|
1561
1656
|
return /^https?:\/\//.test(input2);
|
|
@@ -1968,7 +2063,7 @@ var postCreateCommand = new import_commander14.Command("create").description("\u
|
|
|
1968
2063
|
const ccUsers = opts.cc ? await resolveUsers2(client, projectId, opts.cc) : [];
|
|
1969
2064
|
const tagInputs = (opts.tag ?? []).filter((s) => s.length > 0);
|
|
1970
2065
|
const [tagIds, parentPostId, milestoneId] = await Promise.all([
|
|
1971
|
-
tagInputs.length > 0 ? resolveTags(client, projectId, tagInputs) :
|
|
2066
|
+
tagInputs.length > 0 ? resolveTags(client, projectId, tagInputs) : validateMandatoryTags(client, projectId).then(() => void 0),
|
|
1972
2067
|
opts.parent ? resolvePostRef(client, opts.parent) : Promise.resolve(void 0),
|
|
1973
2068
|
opts.milestone ? resolveMilestone(client, projectId, opts.milestone) : Promise.resolve(void 0)
|
|
1974
2069
|
]);
|
|
@@ -2241,7 +2336,35 @@ var commentLatestCommand = new import_commander18.Command("latest").description(
|
|
|
2241
2336
|
|
|
2242
2337
|
// src/commands/post/comment/add.ts
|
|
2243
2338
|
var import_commander19 = require("commander");
|
|
2244
|
-
|
|
2339
|
+
|
|
2340
|
+
// src/utils/mention.ts
|
|
2341
|
+
function buildMemberMention(m, me) {
|
|
2342
|
+
const title = m.memberId === me.id ? "me" : "member";
|
|
2343
|
+
return `[@${m.name}](dooray://${me.orgId}/members/${m.memberId} "${title}")`;
|
|
2344
|
+
}
|
|
2345
|
+
function buildGroupMention(g, me) {
|
|
2346
|
+
return `[@${g.projectCode}/${g.code}](dooray://${me.orgId}/member-groups/${g.groupId})`;
|
|
2347
|
+
}
|
|
2348
|
+
function prependMentions(body, members, groups, me) {
|
|
2349
|
+
const parts = [];
|
|
2350
|
+
for (const m of members) parts.push(buildMemberMention(m, me));
|
|
2351
|
+
for (const g of groups) parts.push(buildGroupMention(g, me));
|
|
2352
|
+
if (parts.length === 0) return body;
|
|
2353
|
+
return parts.join(" ") + " " + body;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
// src/commands/post/comment/add.ts
|
|
2357
|
+
var commentAddCommand = new import_commander19.Command("add").description("\uB313\uAE00 \uCD94\uAC00").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray URL)").argument("[post-number]", "\uC5C5\uBB34 \uBC88\uD638 (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option(
|
|
2358
|
+
"--mention <name>",
|
|
2359
|
+
"\uBA64\uBC84 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, \uC774\uB984 \uBD80\uBD84\uC77C\uCE58)",
|
|
2360
|
+
(value, prev) => [...prev, value],
|
|
2361
|
+
[]
|
|
2362
|
+
).option(
|
|
2363
|
+
"--mention-group <code>",
|
|
2364
|
+
"\uADF8\uB8F9 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, code \uBD80\uBD84\uC77C\uCE58)",
|
|
2365
|
+
(value, prev) => [...prev, value],
|
|
2366
|
+
[]
|
|
2367
|
+
).action(async (project, postNumberStr, opts) => {
|
|
2245
2368
|
const globalOpts = commentAddCommand.optsWithGlobals();
|
|
2246
2369
|
const config = await getConfigOrThrow();
|
|
2247
2370
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2254,12 +2377,32 @@ var commentAddCommand = new import_commander19.Command("add").description("\uB31
|
|
|
2254
2377
|
}
|
|
2255
2378
|
}
|
|
2256
2379
|
startSpinner("\uB313\uAE00 \uCD94\uAC00 \uC911...");
|
|
2257
|
-
const { projectId, postId } = await resolvePostInput(client, {
|
|
2380
|
+
const { projectId, postId, projectCode } = await resolvePostInput(client, {
|
|
2258
2381
|
projectArg: project,
|
|
2259
2382
|
postNumberArg: postNumberStr,
|
|
2260
2383
|
idOpt: opts.id,
|
|
2261
2384
|
urlOpt: opts.url
|
|
2262
2385
|
});
|
|
2386
|
+
const mentionInputs = (opts.mention ?? []).filter((s) => s.length > 0);
|
|
2387
|
+
const groupInputs = (opts.mentionGroup ?? []).filter((s) => s.length > 0);
|
|
2388
|
+
if (mentionInputs.length > 0 || groupInputs.length > 0) {
|
|
2389
|
+
const me = await ensureMe(client);
|
|
2390
|
+
const memberIds = await Promise.all(
|
|
2391
|
+
mentionInputs.map((name) => resolveMember(client, projectId, name))
|
|
2392
|
+
);
|
|
2393
|
+
const nameMap = await buildMemberNameMap(client, projectId);
|
|
2394
|
+
const members = memberIds.map((memberId) => ({
|
|
2395
|
+
memberId,
|
|
2396
|
+
name: nameMap.get(memberId) ?? memberId
|
|
2397
|
+
}));
|
|
2398
|
+
const groups = await Promise.all(
|
|
2399
|
+
groupInputs.map(async (code) => {
|
|
2400
|
+
const g = await resolveMemberGroup(client, projectId, code);
|
|
2401
|
+
return { groupId: g.id, code: g.code, projectCode };
|
|
2402
|
+
})
|
|
2403
|
+
);
|
|
2404
|
+
bodyContent = prependMentions(bodyContent, members, groups, me);
|
|
2405
|
+
}
|
|
2263
2406
|
const res = await client.createPostComment(projectId, postId, {
|
|
2264
2407
|
body: { mimeType: "text/x-markdown", content: bodyContent }
|
|
2265
2408
|
});
|
|
@@ -2276,7 +2419,17 @@ var commentAddCommand = new import_commander19.Command("add").description("\uB31
|
|
|
2276
2419
|
|
|
2277
2420
|
// src/commands/post/comment/edit.ts
|
|
2278
2421
|
var import_commander20 = require("commander");
|
|
2279
|
-
var commentEditCommand = new import_commander20.Command("edit").description("\uB313\uAE00 \uC218\uC815 ($EDITOR \uB610\uB294 --body \uC635\uC158)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC / Dooray URL / \uB313\uAE00 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 \uB313\uAE00 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <commentId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 \uBCC0\uACBD (- \uC785\uB825 \uC2DC stdin, non-interactive)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin, non-interactive)").
|
|
2422
|
+
var commentEditCommand = new import_commander20.Command("edit").description("\uB313\uAE00 \uC218\uC815 ($EDITOR \uB610\uB294 --body \uC635\uC158)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC / Dooray URL / \uB313\uAE00 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 \uB313\uAE00 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <commentId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 \uBCC0\uACBD (- \uC785\uB825 \uC2DC stdin, non-interactive)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin, non-interactive)").option(
|
|
2423
|
+
"--mention <name>",
|
|
2424
|
+
"\uBA64\uBC84 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, \uC774\uB984 \uBD80\uBD84\uC77C\uCE58)",
|
|
2425
|
+
(value, prev) => [...prev, value],
|
|
2426
|
+
[]
|
|
2427
|
+
).option(
|
|
2428
|
+
"--mention-group <code>",
|
|
2429
|
+
"\uADF8\uB8F9 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, code \uBD80\uBD84\uC77C\uCE58)",
|
|
2430
|
+
(value, prev) => [...prev, value],
|
|
2431
|
+
[]
|
|
2432
|
+
).action(async (arg1, arg2, arg3, opts) => {
|
|
2280
2433
|
const config = await getConfigOrThrow();
|
|
2281
2434
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2282
2435
|
let projectArg;
|
|
@@ -2319,7 +2472,7 @@ var commentEditCommand = new import_commander20.Command("edit").description("\uB
|
|
|
2319
2472
|
);
|
|
2320
2473
|
}
|
|
2321
2474
|
startSpinner("\uB313\uAE00 \uC870\uD68C \uC911...");
|
|
2322
|
-
const { projectId, postId } = await resolvePostInput(client, {
|
|
2475
|
+
const { projectId, postId, projectCode } = await resolvePostInput(client, {
|
|
2323
2476
|
projectArg,
|
|
2324
2477
|
postNumberArg,
|
|
2325
2478
|
idOpt: opts.id,
|
|
@@ -2333,14 +2486,38 @@ var commentEditCommand = new import_commander20.Command("edit").description("\uB
|
|
|
2333
2486
|
`);
|
|
2334
2487
|
process.exit(1);
|
|
2335
2488
|
}
|
|
2489
|
+
const mentionInputs = (opts.mention ?? []).filter((s) => s.length > 0);
|
|
2490
|
+
const groupInputs = (opts.mentionGroup ?? []).filter((s) => s.length > 0);
|
|
2491
|
+
let mentionPrefix = "";
|
|
2492
|
+
if (mentionInputs.length > 0 || groupInputs.length > 0) {
|
|
2493
|
+
const me = await ensureMe(client);
|
|
2494
|
+
const memberIds = await Promise.all(
|
|
2495
|
+
mentionInputs.map((name) => resolveMember(client, projectId, name))
|
|
2496
|
+
);
|
|
2497
|
+
const nameMap = await buildMemberNameMap(client, projectId);
|
|
2498
|
+
const members = memberIds.map((memberId) => ({
|
|
2499
|
+
memberId,
|
|
2500
|
+
name: nameMap.get(memberId) ?? memberId
|
|
2501
|
+
}));
|
|
2502
|
+
const groups = await Promise.all(
|
|
2503
|
+
groupInputs.map(async (code) => {
|
|
2504
|
+
const g = await resolveMemberGroup(client, projectId, code);
|
|
2505
|
+
return { groupId: g.id, code: g.code, projectCode };
|
|
2506
|
+
})
|
|
2507
|
+
);
|
|
2508
|
+
mentionPrefix = prependMentions("", members, groups, me).trimEnd();
|
|
2509
|
+
}
|
|
2336
2510
|
let edited = await readBodyInputOrNull(opts);
|
|
2337
2511
|
if (edited == null) {
|
|
2338
|
-
const
|
|
2339
|
-
|
|
2340
|
-
|
|
2512
|
+
const rawContent = comment.body.content;
|
|
2513
|
+
const editorSeed = mentionPrefix ? mentionPrefix + " " + rawContent : rawContent;
|
|
2514
|
+
edited = await openInEditor(editorSeed);
|
|
2515
|
+
if (rawContent === edited) {
|
|
2341
2516
|
process.stdout.write("\uBCC0\uACBD\uC0AC\uD56D \uC5C6\uC74C\n");
|
|
2342
2517
|
return;
|
|
2343
2518
|
}
|
|
2519
|
+
} else if (mentionPrefix) {
|
|
2520
|
+
edited = mentionPrefix + " " + edited;
|
|
2344
2521
|
}
|
|
2345
2522
|
startSpinner("\uB313\uAE00 \uC218\uC815 \uC911...");
|
|
2346
2523
|
await client.updatePostComment(projectId, postId, commentId, {
|
|
@@ -2408,14 +2585,348 @@ var commentDeleteCommand = new import_commander21.Command("delete").description(
|
|
|
2408
2585
|
`);
|
|
2409
2586
|
});
|
|
2410
2587
|
|
|
2411
|
-
// src/commands/post/file/
|
|
2588
|
+
// src/commands/post/comment/file/index.ts
|
|
2589
|
+
var import_commander26 = require("commander");
|
|
2590
|
+
|
|
2591
|
+
// src/commands/post/comment/file/list.ts
|
|
2412
2592
|
var import_commander22 = require("commander");
|
|
2413
2593
|
function formatSize(bytes) {
|
|
2414
2594
|
if (bytes < 1024) return `${bytes}B`;
|
|
2415
2595
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
2416
2596
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
2417
2597
|
}
|
|
2418
|
-
var
|
|
2598
|
+
var listCommentFileCommand = new import_commander22.Command("list").description("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uBAA9\uB85D \uC870\uD68C").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 (positional \uBAA8\uB4DC)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
|
|
2599
|
+
const globalOpts = listCommentFileCommand.optsWithGlobals();
|
|
2600
|
+
const config = await getConfigOrThrow();
|
|
2601
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2602
|
+
let projectArg;
|
|
2603
|
+
let postNumberArg;
|
|
2604
|
+
let logId = opts.commentId;
|
|
2605
|
+
if (opts.id || opts.url) {
|
|
2606
|
+
if (arg2 || arg3) {
|
|
2607
|
+
throw new DoorayCliError(
|
|
2608
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --comment-id \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
2609
|
+
EXIT_PARAM_ERROR
|
|
2610
|
+
);
|
|
2611
|
+
}
|
|
2612
|
+
logId = logId ?? arg1;
|
|
2613
|
+
} else if (arg3) {
|
|
2614
|
+
projectArg = arg1;
|
|
2615
|
+
postNumberArg = arg2;
|
|
2616
|
+
logId = logId ?? arg3;
|
|
2617
|
+
} else if (arg1 && !arg2) {
|
|
2618
|
+
projectArg = arg1;
|
|
2619
|
+
if (!logId) {
|
|
2620
|
+
throw new DoorayCliError(
|
|
2621
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --comment-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2622
|
+
EXIT_PARAM_ERROR
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
} else {
|
|
2626
|
+
projectArg = arg1;
|
|
2627
|
+
postNumberArg = arg2;
|
|
2628
|
+
if (!logId) {
|
|
2629
|
+
throw new DoorayCliError(
|
|
2630
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2631
|
+
EXIT_PARAM_ERROR
|
|
2632
|
+
);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
if (!logId) {
|
|
2636
|
+
throw new DoorayCliError("<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2637
|
+
}
|
|
2638
|
+
startSpinner("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
2639
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2640
|
+
projectArg,
|
|
2641
|
+
postNumberArg,
|
|
2642
|
+
idOpt: opts.id,
|
|
2643
|
+
urlOpt: opts.url
|
|
2644
|
+
});
|
|
2645
|
+
const res = await client.getPostComment(projectId, postId, logId);
|
|
2646
|
+
const files = res.result.files ?? [];
|
|
2647
|
+
stopSpinner(true, `\uCCA8\uBD80 \uD30C\uC77C ${files.length}\uAC1C`);
|
|
2648
|
+
if (files.length === 0) {
|
|
2649
|
+
if (globalOpts.json) {
|
|
2650
|
+
process.stdout.write("[]\n");
|
|
2651
|
+
} else if (!globalOpts.quiet) {
|
|
2652
|
+
process.stdout.write("\uCCA8\uBD80 \uC5C6\uC74C\n");
|
|
2653
|
+
}
|
|
2654
|
+
return;
|
|
2655
|
+
}
|
|
2656
|
+
output(globalOpts, {
|
|
2657
|
+
headers: ["\uD30C\uC77C\uBA85", "\uD06C\uAE30", "ID"],
|
|
2658
|
+
rows: files.map((f) => [f.name, formatSize(f.size), f.id]),
|
|
2659
|
+
raw: files,
|
|
2660
|
+
ids: files.map((f) => f.id)
|
|
2661
|
+
});
|
|
2662
|
+
});
|
|
2663
|
+
|
|
2664
|
+
// src/commands/post/comment/file/upload.ts
|
|
2665
|
+
var import_commander23 = require("commander");
|
|
2666
|
+
var import_node_path4 = require("path");
|
|
2667
|
+
|
|
2668
|
+
// src/utils/comment-files.ts
|
|
2669
|
+
function appendFileReference(body, fileName, fileId) {
|
|
2670
|
+
const safeName = fileName.replace(/[\[\]]/g, "");
|
|
2671
|
+
const ref = ``;
|
|
2672
|
+
if (body.length === 0) return ref;
|
|
2673
|
+
const trailing = body.endsWith("\n") ? "" : "\n";
|
|
2674
|
+
return `${body}${trailing}
|
|
2675
|
+
${ref}`;
|
|
2676
|
+
}
|
|
2677
|
+
function removeFileReference(body, fileId) {
|
|
2678
|
+
const escaped = fileId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2679
|
+
const refSource = `!\\[[^\\]]*\\]\\(/files/${escaped}\\)`;
|
|
2680
|
+
const lineRe = new RegExp(`^[ \\t]*${refSource}[ \\t]*$\\n?`, "gm");
|
|
2681
|
+
const inlineRe = new RegExp(refSource, "g");
|
|
2682
|
+
return body.replace(lineRe, "").replace(inlineRe, "");
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
// src/commands/post/comment/file/upload.ts
|
|
2686
|
+
var uploadCommentFileCommand = new import_commander23.Command("upload").description("\uB313\uAE00\uC5D0 \uD30C\uC77C \uC5C5\uB85C\uB4DC (post-level \uD30C\uC77C \uC5C5\uB85C\uB4DC + \uB313\uAE00 reference \uCD94\uAC00, ADR-024)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg3]", "\uB313\uAE00 ID (positional \uBAA8\uB4DC)").argument("[arg4]", "\uD30C\uC77C \uACBD\uB85C (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--file <path>", "\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uACBD\uB85C (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, arg4, opts) => {
|
|
2687
|
+
const globalOpts = uploadCommentFileCommand.optsWithGlobals();
|
|
2688
|
+
const config = await getConfigOrThrow();
|
|
2689
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2690
|
+
let projectArg;
|
|
2691
|
+
let postNumberArg;
|
|
2692
|
+
let logId = opts.commentId;
|
|
2693
|
+
let filePath = opts.file;
|
|
2694
|
+
if (opts.id || opts.url) {
|
|
2695
|
+
if (arg3 || arg4) {
|
|
2696
|
+
throw new DoorayCliError(
|
|
2697
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC640 \uD30C\uC77C \uACBD\uB85C \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
2698
|
+
EXIT_PARAM_ERROR
|
|
2699
|
+
);
|
|
2700
|
+
}
|
|
2701
|
+
logId = logId ?? arg1;
|
|
2702
|
+
filePath = filePath ?? arg2;
|
|
2703
|
+
} else if (arg4) {
|
|
2704
|
+
projectArg = arg1;
|
|
2705
|
+
postNumberArg = arg2;
|
|
2706
|
+
logId = logId ?? arg3;
|
|
2707
|
+
filePath = filePath ?? arg4;
|
|
2708
|
+
} else if (arg3) {
|
|
2709
|
+
projectArg = arg1;
|
|
2710
|
+
postNumberArg = arg2;
|
|
2711
|
+
logId = logId ?? arg3;
|
|
2712
|
+
} else if (arg1 && !arg2) {
|
|
2713
|
+
projectArg = arg1;
|
|
2714
|
+
} else {
|
|
2715
|
+
projectArg = arg1;
|
|
2716
|
+
postNumberArg = arg2;
|
|
2717
|
+
}
|
|
2718
|
+
if (!logId) {
|
|
2719
|
+
throw new DoorayCliError(
|
|
2720
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2721
|
+
EXIT_PARAM_ERROR
|
|
2722
|
+
);
|
|
2723
|
+
}
|
|
2724
|
+
if (!filePath) {
|
|
2725
|
+
throw new DoorayCliError(
|
|
2726
|
+
"<path>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 4\uBC88\uC9F8 \uB610\uB294 --file \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2727
|
+
EXIT_PARAM_ERROR
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2731
|
+
projectArg,
|
|
2732
|
+
postNumberArg,
|
|
2733
|
+
idOpt: opts.id,
|
|
2734
|
+
urlOpt: opts.url
|
|
2735
|
+
});
|
|
2736
|
+
startSpinner("\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC911...");
|
|
2737
|
+
const uploadRes = await client.uploadPostFile(projectId, postId, filePath);
|
|
2738
|
+
const fileId = uploadRes.result.id;
|
|
2739
|
+
const fileName = (0, import_node_path4.basename)(filePath);
|
|
2740
|
+
stopSpinner(true, "\uC5C5\uB85C\uB4DC \uC644\uB8CC");
|
|
2741
|
+
startSpinner("\uB313\uAE00 reference \uCD94\uAC00 \uC911...");
|
|
2742
|
+
try {
|
|
2743
|
+
const commentRes = await client.getPostComment(projectId, postId, logId);
|
|
2744
|
+
const currentBody = commentRes.result.body.content;
|
|
2745
|
+
const newBody = appendFileReference(currentBody, fileName, fileId);
|
|
2746
|
+
await client.updatePostComment(projectId, postId, logId, {
|
|
2747
|
+
body: { mimeType: "text/x-markdown", content: newBody }
|
|
2748
|
+
});
|
|
2749
|
+
stopSpinner(true, "reference \uCD94\uAC00 \uC644\uB8CC");
|
|
2750
|
+
} catch {
|
|
2751
|
+
stopSpinner(false, "");
|
|
2752
|
+
throw new DoorayCliError(
|
|
2753
|
+
`\uC5C5\uB85C\uB4DC OK / \uB313\uAE00 reference \uCD94\uAC00 \uC2E4\uD328. fileId=${fileId} \u2014 'dooray post comment file delete' \uB610\uB294 \uC218\uB3D9 PUT \uC73C\uB85C \uC815\uB9AC\uD558\uC138\uC694.`,
|
|
2754
|
+
EXIT_API_ERROR
|
|
2755
|
+
);
|
|
2756
|
+
}
|
|
2757
|
+
if (globalOpts.json) {
|
|
2758
|
+
printJson({ fileId, fileName, commentId: logId });
|
|
2759
|
+
} else if (globalOpts.quiet) {
|
|
2760
|
+
process.stdout.write(`${fileId}
|
|
2761
|
+
`);
|
|
2762
|
+
} else {
|
|
2763
|
+
process.stdout.write(`\uC5C5\uB85C\uB4DC + \uB313\uAE00 reference \uCD94\uAC00: fileId=${fileId}
|
|
2764
|
+
`);
|
|
2765
|
+
}
|
|
2766
|
+
});
|
|
2767
|
+
|
|
2768
|
+
// src/commands/post/comment/file/download.ts
|
|
2769
|
+
var import_commander24 = require("commander");
|
|
2770
|
+
var import_promises8 = require("fs/promises");
|
|
2771
|
+
var import_node_path5 = require("path");
|
|
2772
|
+
var downloadCommentFileCommand = new import_commander24.Command("download").description(
|
|
2773
|
+
"\uB313\uAE00\uC5D0 \uCCA8\uBD80\uB41C \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC (\uD604\uC7AC comment-id \uB294 \uBBF8\uC0AC\uC6A9 \u2014 \uBA58\uD0C8 \uBAA8\uB378 \uC77C\uAD00\uC131, \uBBF8\uB798 \uB313\uAE00 \uB2E8\uC704 \uAD8C\uD55C \uD638\uD658\uC6A9)"
|
|
2774
|
+
).argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uB313\uAE00 ID (positional \uBAA8\uB4DC)").argument("[arg4]", "\uD30C\uC77C ID (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("--out <path>", "\uC800\uC7A5 \uACBD\uB85C (\uBBF8\uC9C0\uC815 \uC2DC \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC6D0\uBCF8 \uD30C\uC77C\uBA85\uC73C\uB85C \uC800\uC7A5)", ".").action(async (arg1, arg2, arg3, arg4, opts) => {
|
|
2775
|
+
const config = await getConfigOrThrow();
|
|
2776
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2777
|
+
let projectArg;
|
|
2778
|
+
let postNumberArg;
|
|
2779
|
+
let _commentId = opts.commentId;
|
|
2780
|
+
let fileId = opts.fileId;
|
|
2781
|
+
if (opts.id || opts.url) {
|
|
2782
|
+
if (arg3 || arg4) {
|
|
2783
|
+
throw new DoorayCliError(
|
|
2784
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC640 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
2785
|
+
EXIT_PARAM_ERROR
|
|
2786
|
+
);
|
|
2787
|
+
}
|
|
2788
|
+
_commentId = _commentId ?? arg1;
|
|
2789
|
+
fileId = fileId ?? arg2;
|
|
2790
|
+
} else if (arg4) {
|
|
2791
|
+
projectArg = arg1;
|
|
2792
|
+
postNumberArg = arg2;
|
|
2793
|
+
_commentId = _commentId ?? arg3;
|
|
2794
|
+
fileId = fileId ?? arg4;
|
|
2795
|
+
} else if (arg3) {
|
|
2796
|
+
projectArg = arg1;
|
|
2797
|
+
postNumberArg = arg2;
|
|
2798
|
+
_commentId = _commentId ?? arg3;
|
|
2799
|
+
} else if (arg1 && !arg2) {
|
|
2800
|
+
projectArg = arg1;
|
|
2801
|
+
} else {
|
|
2802
|
+
projectArg = arg1;
|
|
2803
|
+
postNumberArg = arg2;
|
|
2804
|
+
}
|
|
2805
|
+
if (!fileId) {
|
|
2806
|
+
throw new DoorayCliError(
|
|
2807
|
+
"<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 4\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2808
|
+
EXIT_PARAM_ERROR
|
|
2809
|
+
);
|
|
2810
|
+
}
|
|
2811
|
+
startSpinner("\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
|
|
2812
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2813
|
+
projectArg,
|
|
2814
|
+
postNumberArg,
|
|
2815
|
+
idOpt: opts.id,
|
|
2816
|
+
urlOpt: opts.url
|
|
2817
|
+
});
|
|
2818
|
+
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, fileId);
|
|
2819
|
+
const safeName = (0, import_node_path5.basename)(fileName);
|
|
2820
|
+
const outputPath = (0, import_node_path5.join)(opts.out, safeName);
|
|
2821
|
+
await (0, import_promises8.writeFile)(outputPath, Buffer.from(buffer));
|
|
2822
|
+
stopSpinner(true, "\uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC");
|
|
2823
|
+
process.stdout.write(`${outputPath}
|
|
2824
|
+
`);
|
|
2825
|
+
});
|
|
2826
|
+
|
|
2827
|
+
// src/commands/post/comment/file/delete.ts
|
|
2828
|
+
var import_commander25 = require("commander");
|
|
2829
|
+
var deleteCommentFileCommand = new import_commander25.Command("delete").description("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uC0AD\uC81C (\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 + \uD30C\uC77C \uC0AD\uC81C, ADR-024)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uB313\uAE00 ID (positional \uBAA8\uB4DC)").argument("[arg4]", "\uD30C\uC77C ID (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("--yes", "\uD655\uC778 \uC5C6\uC774 \uC0AD\uC81C").action(async (arg1, arg2, arg3, arg4, opts) => {
|
|
2830
|
+
const config = await getConfigOrThrow();
|
|
2831
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2832
|
+
let projectArg;
|
|
2833
|
+
let postNumberArg;
|
|
2834
|
+
let logId = opts.commentId;
|
|
2835
|
+
let fileId = opts.fileId;
|
|
2836
|
+
if (opts.id || opts.url) {
|
|
2837
|
+
if (arg3 || arg4) {
|
|
2838
|
+
throw new DoorayCliError(
|
|
2839
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC640 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
2840
|
+
EXIT_PARAM_ERROR
|
|
2841
|
+
);
|
|
2842
|
+
}
|
|
2843
|
+
logId = logId ?? arg1;
|
|
2844
|
+
fileId = fileId ?? arg2;
|
|
2845
|
+
} else if (arg4) {
|
|
2846
|
+
projectArg = arg1;
|
|
2847
|
+
postNumberArg = arg2;
|
|
2848
|
+
logId = logId ?? arg3;
|
|
2849
|
+
fileId = fileId ?? arg4;
|
|
2850
|
+
} else if (arg3) {
|
|
2851
|
+
projectArg = arg1;
|
|
2852
|
+
postNumberArg = arg2;
|
|
2853
|
+
logId = logId ?? arg3;
|
|
2854
|
+
} else if (arg1 && !arg2) {
|
|
2855
|
+
projectArg = arg1;
|
|
2856
|
+
} else {
|
|
2857
|
+
projectArg = arg1;
|
|
2858
|
+
postNumberArg = arg2;
|
|
2859
|
+
}
|
|
2860
|
+
if (!logId) {
|
|
2861
|
+
throw new DoorayCliError(
|
|
2862
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2863
|
+
EXIT_PARAM_ERROR
|
|
2864
|
+
);
|
|
2865
|
+
}
|
|
2866
|
+
if (!fileId) {
|
|
2867
|
+
throw new DoorayCliError(
|
|
2868
|
+
"<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 4\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2869
|
+
EXIT_PARAM_ERROR
|
|
2870
|
+
);
|
|
2871
|
+
}
|
|
2872
|
+
if (!opts.yes) {
|
|
2873
|
+
const { confirm: confirm2 } = await import("@inquirer/prompts");
|
|
2874
|
+
const ok = await confirm2({
|
|
2875
|
+
message: `\uB313\uAE00 \uBCF8\uBB38\uC5D0\uC11C reference \uB97C \uC81C\uAC70\uD558\uACE0 \uD30C\uC77C(${fileId})\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uAC19\uC740 post \uC758 \uB2E4\uB978 \uB313\uAE00\uC5D0\uC11C \uAC19\uC740 \uD30C\uC77C ID \uB97C \uCC38\uC870\uD558\uB294 \uACBD\uC6B0 broken \uB429\uB2C8\uB2E4. \uACC4\uC18D\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`
|
|
2876
|
+
});
|
|
2877
|
+
if (!ok) {
|
|
2878
|
+
process.stdout.write("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n");
|
|
2879
|
+
return;
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2883
|
+
projectArg,
|
|
2884
|
+
postNumberArg,
|
|
2885
|
+
idOpt: opts.id,
|
|
2886
|
+
urlOpt: opts.url
|
|
2887
|
+
});
|
|
2888
|
+
startSpinner("\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 \uC911...");
|
|
2889
|
+
try {
|
|
2890
|
+
const commentRes = await client.getPostComment(projectId, postId, logId);
|
|
2891
|
+
const currentBody = commentRes.result.body.content;
|
|
2892
|
+
const newBody = removeFileReference(currentBody, fileId);
|
|
2893
|
+
await client.updatePostComment(projectId, postId, logId, {
|
|
2894
|
+
body: { mimeType: "text/x-markdown", content: newBody }
|
|
2895
|
+
});
|
|
2896
|
+
stopSpinner(true, "reference \uC81C\uAC70 \uC644\uB8CC");
|
|
2897
|
+
} catch {
|
|
2898
|
+
stopSpinner(false, "");
|
|
2899
|
+
throw new DoorayCliError(
|
|
2900
|
+
`\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 \uC2E4\uD328. \uD30C\uC77C \uC0AD\uC81C\uB97C \uC9C4\uD589\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. fileId=${fileId}`,
|
|
2901
|
+
EXIT_API_ERROR
|
|
2902
|
+
);
|
|
2903
|
+
}
|
|
2904
|
+
startSpinner("\uD30C\uC77C \uC0AD\uC81C \uC911...");
|
|
2905
|
+
try {
|
|
2906
|
+
await client.deletePostFile(projectId, postId, fileId);
|
|
2907
|
+
stopSpinner(true, "\uD30C\uC77C \uC0AD\uC81C \uC644\uB8CC");
|
|
2908
|
+
} catch {
|
|
2909
|
+
stopSpinner(false, "");
|
|
2910
|
+
throw new DoorayCliError(
|
|
2911
|
+
`\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 OK / \uD30C\uC77C \uC0AD\uC81C \uC2E4\uD328. 'dooray post file delete' \uB85C \uD6C4\uCC98\uB9AC\uD558\uC138\uC694. fileId=${fileId}`,
|
|
2912
|
+
EXIT_API_ERROR
|
|
2913
|
+
);
|
|
2914
|
+
}
|
|
2915
|
+
process.stdout.write(`\uD30C\uC77C(${fileId})\uC774 \uB313\uAE00(${logId})\uC5D0\uC11C \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
2916
|
+
`);
|
|
2917
|
+
});
|
|
2918
|
+
|
|
2919
|
+
// src/commands/post/comment/file/index.ts
|
|
2920
|
+
var commentFileCommand = new import_commander26.Command("file").description("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uAD00\uB9AC (post-level files API + \uB313\uAE00 PUT \uD569\uC131, ADR-024)").addCommand(listCommentFileCommand).addCommand(uploadCommentFileCommand).addCommand(downloadCommentFileCommand).addCommand(deleteCommentFileCommand);
|
|
2921
|
+
|
|
2922
|
+
// src/commands/post/file/list.ts
|
|
2923
|
+
var import_commander27 = require("commander");
|
|
2924
|
+
function formatSize2(bytes) {
|
|
2925
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
2926
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
2927
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
2928
|
+
}
|
|
2929
|
+
var fileListCommand = new import_commander27.Command("list").description("\uC5C5\uBB34 \uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray URL)").argument("[post-number]", "\uC5C5\uBB34 \uBC88\uD638 (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").action(async (project, postNumberStr, opts) => {
|
|
2419
2930
|
const globalOpts = fileListCommand.optsWithGlobals();
|
|
2420
2931
|
const config = await getConfigOrThrow();
|
|
2421
2932
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2433,7 +2944,7 @@ var fileListCommand = new import_commander22.Command("list").description("\uC5C5
|
|
|
2433
2944
|
rows: res.result.map((f) => [
|
|
2434
2945
|
f.id,
|
|
2435
2946
|
f.name,
|
|
2436
|
-
|
|
2947
|
+
formatSize2(f.size),
|
|
2437
2948
|
f.mimeType,
|
|
2438
2949
|
f.createdAt
|
|
2439
2950
|
]),
|
|
@@ -2443,10 +2954,10 @@ var fileListCommand = new import_commander22.Command("list").description("\uC5C5
|
|
|
2443
2954
|
});
|
|
2444
2955
|
|
|
2445
2956
|
// src/commands/post/file/download.ts
|
|
2446
|
-
var
|
|
2447
|
-
var
|
|
2448
|
-
var
|
|
2449
|
-
var fileDownloadCommand = new
|
|
2957
|
+
var import_commander28 = require("commander");
|
|
2958
|
+
var import_promises9 = require("fs/promises");
|
|
2959
|
+
var import_node_path6 = require("path");
|
|
2960
|
+
var fileDownloadCommand = new import_commander28.Command("download").description("\uCCA8\uBD80\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uD30C\uC77C ID (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("-o, --output <dir>", "\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC", ".").action(async (arg1, arg2, arg3, opts) => {
|
|
2450
2961
|
const config = await getConfigOrThrow();
|
|
2451
2962
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2452
2963
|
let projectArg;
|
|
@@ -2493,18 +3004,18 @@ var fileDownloadCommand = new import_commander23.Command("download").description
|
|
|
2493
3004
|
urlOpt: opts.url
|
|
2494
3005
|
});
|
|
2495
3006
|
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, fileId);
|
|
2496
|
-
const outputPath = (0,
|
|
2497
|
-
await (0,
|
|
3007
|
+
const outputPath = (0, import_node_path6.join)(opts.output, fileName);
|
|
3008
|
+
await (0, import_promises9.writeFile)(outputPath, Buffer.from(buffer));
|
|
2498
3009
|
stopSpinner(true, "\uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC");
|
|
2499
3010
|
process.stdout.write(`${outputPath}
|
|
2500
3011
|
`);
|
|
2501
3012
|
});
|
|
2502
3013
|
|
|
2503
3014
|
// src/commands/post/file/download-all.ts
|
|
2504
|
-
var
|
|
2505
|
-
var
|
|
2506
|
-
var
|
|
2507
|
-
var fileDownloadAllCommand = new
|
|
3015
|
+
var import_commander29 = require("commander");
|
|
3016
|
+
var import_promises10 = require("fs/promises");
|
|
3017
|
+
var import_node_path7 = require("path");
|
|
3018
|
+
var fileDownloadAllCommand = new import_commander29.Command("download-all").description("\uC5C5\uBB34\uC758 \uBAA8\uB4E0 \uCCA8\uBD80\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray URL)").argument("[post-number]", "\uC5C5\uBB34 \uBC88\uD638 (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("-o, --output <dir>", "\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC", ".").action(async (project, postNumberStr, opts) => {
|
|
2508
3019
|
const config = await getConfigOrThrow();
|
|
2509
3020
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2510
3021
|
const spinner = startSpinner("\uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
@@ -2520,13 +3031,13 @@ var fileDownloadAllCommand = new import_commander24.Command("download-all").desc
|
|
|
2520
3031
|
process.stdout.write("\uCCA8\uBD80\uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n");
|
|
2521
3032
|
return;
|
|
2522
3033
|
}
|
|
2523
|
-
await (0,
|
|
3034
|
+
await (0, import_promises10.mkdir)(opts.output, { recursive: true });
|
|
2524
3035
|
const downloaded = [];
|
|
2525
3036
|
for (const file of res.result) {
|
|
2526
3037
|
spinner.text = `\uB2E4\uC6B4\uB85C\uB4DC \uC911: ${file.name} (${downloaded.length + 1}/${res.result.length})`;
|
|
2527
3038
|
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, file.id);
|
|
2528
|
-
const outputPath = (0,
|
|
2529
|
-
await (0,
|
|
3039
|
+
const outputPath = (0, import_node_path7.join)(opts.output, fileName);
|
|
3040
|
+
await (0, import_promises10.writeFile)(outputPath, Buffer.from(buffer));
|
|
2530
3041
|
downloaded.push(outputPath);
|
|
2531
3042
|
}
|
|
2532
3043
|
stopSpinner(true, `${downloaded.length}\uAC1C \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC`);
|
|
@@ -2537,9 +3048,9 @@ var fileDownloadAllCommand = new import_commander24.Command("download-all").desc
|
|
|
2537
3048
|
});
|
|
2538
3049
|
|
|
2539
3050
|
// src/commands/post/file/upload.ts
|
|
2540
|
-
var
|
|
2541
|
-
var
|
|
2542
|
-
var fileUploadCommand = new
|
|
3051
|
+
var import_commander30 = require("commander");
|
|
3052
|
+
var import_node_path8 = require("path");
|
|
3053
|
+
var fileUploadCommand = new import_commander30.Command("upload").description("\uCCA8\uBD80\uD30C\uC77C \uC5C5\uB85C\uB4DC").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg3]", "\uD30C\uC77C \uACBD\uB85C (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--file <path>", "\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uACBD\uB85C (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
|
|
2543
3054
|
const globalOpts = fileUploadCommand.optsWithGlobals();
|
|
2544
3055
|
const config = await getConfigOrThrow();
|
|
2545
3056
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2594,14 +3105,14 @@ var fileUploadCommand = new import_commander25.Command("upload").description("\u
|
|
|
2594
3105
|
process.stdout.write(`${res.result.id}
|
|
2595
3106
|
`);
|
|
2596
3107
|
} else {
|
|
2597
|
-
process.stdout.write(`\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC644\uB8CC: ${(0,
|
|
3108
|
+
process.stdout.write(`\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC644\uB8CC: ${(0, import_node_path8.basename)(filePath)} (ID: ${res.result.id})
|
|
2598
3109
|
`);
|
|
2599
3110
|
}
|
|
2600
3111
|
});
|
|
2601
3112
|
|
|
2602
3113
|
// src/commands/post/file/delete.ts
|
|
2603
|
-
var
|
|
2604
|
-
var fileDeleteCommand = new
|
|
3114
|
+
var import_commander31 = require("commander");
|
|
3115
|
+
var fileDeleteCommand = new import_commander31.Command("delete").description("\uCCA8\uBD80\uD30C\uC77C \uC0AD\uC81C").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uD30C\uC77C ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
|
|
2605
3116
|
const config = await getConfigOrThrow();
|
|
2606
3117
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2607
3118
|
let projectArg;
|
|
@@ -2654,7 +3165,7 @@ var fileDeleteCommand = new import_commander26.Command("delete").description("\u
|
|
|
2654
3165
|
});
|
|
2655
3166
|
|
|
2656
3167
|
// src/commands/wiki/list.ts
|
|
2657
|
-
var
|
|
3168
|
+
var import_commander32 = require("commander");
|
|
2658
3169
|
|
|
2659
3170
|
// src/formatters/wiki.ts
|
|
2660
3171
|
function formatWikiList(wikis, opts) {
|
|
@@ -2697,7 +3208,7 @@ function formatWikiPageDetail(page, opts) {
|
|
|
2697
3208
|
}
|
|
2698
3209
|
|
|
2699
3210
|
// src/commands/wiki/list.ts
|
|
2700
|
-
var wikiListCommand = new
|
|
3211
|
+
var wikiListCommand = new import_commander32.Command("list").description("\uC704\uD0A4 \uBAA9\uB85D \uC870\uD68C").option("--page <number>", "\uD398\uC774\uC9C0 \uBC88\uD638", "0").option("--size <number>", "\uD398\uC774\uC9C0 \uD06C\uAE30", "20").action(async (opts) => {
|
|
2701
3212
|
const globalOpts = wikiListCommand.optsWithGlobals();
|
|
2702
3213
|
const config = await getConfigOrThrow();
|
|
2703
3214
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2711,7 +3222,7 @@ var wikiListCommand = new import_commander27.Command("list").description("\uC704
|
|
|
2711
3222
|
});
|
|
2712
3223
|
|
|
2713
3224
|
// src/commands/wiki/pages.ts
|
|
2714
|
-
var
|
|
3225
|
+
var import_commander33 = require("commander");
|
|
2715
3226
|
|
|
2716
3227
|
// src/resolvers/wiki.ts
|
|
2717
3228
|
async function resolveWiki(client, projectCode) {
|
|
@@ -2755,7 +3266,7 @@ async function resolveWikiHomePageId(client, wikiId) {
|
|
|
2755
3266
|
}
|
|
2756
3267
|
|
|
2757
3268
|
// src/commands/wiki/pages.ts
|
|
2758
|
-
var wikiPagesCommand = new
|
|
3269
|
+
var wikiPagesCommand = new import_commander33.Command("pages").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uBAA9\uB85D \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").option("--parent <page-id>", "\uBD80\uBAA8 \uD398\uC774\uC9C0 ID").action(async (project, opts) => {
|
|
2759
3270
|
const globalOpts = wikiPagesCommand.optsWithGlobals();
|
|
2760
3271
|
const config = await getConfigOrThrow();
|
|
2761
3272
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2767,8 +3278,8 @@ var wikiPagesCommand = new import_commander28.Command("pages").description("\uC7
|
|
|
2767
3278
|
});
|
|
2768
3279
|
|
|
2769
3280
|
// src/commands/wiki/page-get.ts
|
|
2770
|
-
var
|
|
2771
|
-
var wikiPageGetCommand = new
|
|
3281
|
+
var import_commander34 = require("commander");
|
|
3282
|
+
var wikiPageGetCommand = new import_commander34.Command("get").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uC0C1\uC138 \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").argument("<page-id>", "\uD398\uC774\uC9C0 ID").action(async (project, pageId) => {
|
|
2772
3283
|
const globalOpts = wikiPageGetCommand.optsWithGlobals();
|
|
2773
3284
|
const config = await getConfigOrThrow();
|
|
2774
3285
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2780,8 +3291,8 @@ var wikiPageGetCommand = new import_commander29.Command("get").description("\uC7
|
|
|
2780
3291
|
});
|
|
2781
3292
|
|
|
2782
3293
|
// src/commands/wiki/page-create.ts
|
|
2783
|
-
var
|
|
2784
|
-
var wikiPageCreateCommand = new
|
|
3294
|
+
var import_commander35 = require("commander");
|
|
3295
|
+
var wikiPageCreateCommand = new import_commander35.Command("create").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uC0DD\uC131").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").requiredOption("--title <title>", "\uD398\uC774\uC9C0 \uC81C\uBAA9").option("--parent <page-id>", "\uBD80\uBAA8 \uD398\uC774\uC9C0 ID").option("--body <text>", "\uBCF8\uBB38 \uD14D\uC2A4\uD2B8 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").action(async (project, opts) => {
|
|
2785
3296
|
const globalOpts = wikiPageCreateCommand.optsWithGlobals();
|
|
2786
3297
|
const config = await getConfigOrThrow();
|
|
2787
3298
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2806,8 +3317,8 @@ var wikiPageCreateCommand = new import_commander30.Command("create").description
|
|
|
2806
3317
|
});
|
|
2807
3318
|
|
|
2808
3319
|
// src/commands/wiki/page-edit.ts
|
|
2809
|
-
var
|
|
2810
|
-
var wikiPageEditCommand = new
|
|
3320
|
+
var import_commander36 = require("commander");
|
|
3321
|
+
var wikiPageEditCommand = new import_commander36.Command("edit").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uC218\uC815 (\uD50C\uB798\uADF8 \uC5C6\uC73C\uBA74 $EDITOR)").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").argument("<page-id>", "\uD398\uC774\uC9C0 ID").option("--title <title>", "\uD398\uC774\uC9C0 \uC81C\uBAA9 (\uC9C0\uC815 \uC2DC $EDITOR \uC0DD\uB7B5)").option("--body <text>", "\uBCF8\uBB38 \uD14D\uC2A4\uD2B8 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").action(async (project, pageId, opts) => {
|
|
2811
3322
|
const config = await getConfigOrThrow();
|
|
2812
3323
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2813
3324
|
const hasTitle = opts.title != null;
|
|
@@ -2860,10 +3371,10 @@ var wikiPageEditCommand = new import_commander31.Command("edit").description("\u
|
|
|
2860
3371
|
});
|
|
2861
3372
|
|
|
2862
3373
|
// src/commands/member/index.ts
|
|
2863
|
-
var
|
|
3374
|
+
var import_commander40 = require("commander");
|
|
2864
3375
|
|
|
2865
3376
|
// src/commands/member/get.ts
|
|
2866
|
-
var
|
|
3377
|
+
var import_commander37 = require("commander");
|
|
2867
3378
|
|
|
2868
3379
|
// src/formatters/member.ts
|
|
2869
3380
|
function formatMemberDetail(member, opts) {
|
|
@@ -2893,9 +3404,23 @@ function formatMemberList(rows, opts) {
|
|
|
2893
3404
|
ids: rows.map((r) => r.id)
|
|
2894
3405
|
});
|
|
2895
3406
|
}
|
|
3407
|
+
function formatMemberSearchResults(members, opts) {
|
|
3408
|
+
output(opts, {
|
|
3409
|
+
headers: ["ID", "Name", "UserCode", "Nickname", "Email"],
|
|
3410
|
+
rows: members.map((m) => [
|
|
3411
|
+
m.id,
|
|
3412
|
+
m.name,
|
|
3413
|
+
m.userCode ?? "",
|
|
3414
|
+
m.nickname ?? "",
|
|
3415
|
+
m.externalEmailAddress ?? ""
|
|
3416
|
+
]),
|
|
3417
|
+
raw: members,
|
|
3418
|
+
ids: members.map((m) => m.id)
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
2896
3421
|
|
|
2897
3422
|
// src/commands/member/get.ts
|
|
2898
|
-
var memberGetCommand = new
|
|
3423
|
+
var memberGetCommand = new import_commander37.Command("get").description("\uBA64\uBC84 \uC0C1\uC138 \uC815\uBCF4 \uC870\uD68C (organizationMemberId)").argument("<member-id>", "\uC870\uD68C\uD560 organization member ID").action(async (memberId) => {
|
|
2899
3424
|
const globalOpts = memberGetCommand.optsWithGlobals();
|
|
2900
3425
|
const config = await getConfigOrThrow();
|
|
2901
3426
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2904,8 +3429,8 @@ var memberGetCommand = new import_commander32.Command("get").description("\uBA64
|
|
|
2904
3429
|
});
|
|
2905
3430
|
|
|
2906
3431
|
// src/commands/member/list.ts
|
|
2907
|
-
var
|
|
2908
|
-
var memberListCommand = new
|
|
3432
|
+
var import_commander38 = require("commander");
|
|
3433
|
+
var memberListCommand = new import_commander38.Command("list").description("\uD504\uB85C\uC81D\uD2B8 \uBA64\uBC84 \uBAA9\uB85D").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
|
|
2909
3434
|
const globalOpts = memberListCommand.optsWithGlobals();
|
|
2910
3435
|
const config = await getConfigOrThrow();
|
|
2911
3436
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2919,13 +3444,48 @@ var memberListCommand = new import_commander33.Command("list").description("\uD5
|
|
|
2919
3444
|
);
|
|
2920
3445
|
});
|
|
2921
3446
|
|
|
3447
|
+
// src/commands/member/search.ts
|
|
3448
|
+
var import_commander39 = require("commander");
|
|
3449
|
+
var memberSearchCommand = new import_commander39.Command("search").description("organization \uC804\uCCB4\uC5D0\uC11C \uBA64\uBC84 \uAC80\uC0C9").argument("[keyword]", "\uC774\uB984 \uAC80\uC0C9\uC5B4 (--email/--user-code \uBBF8\uC9C0\uC815 \uC2DC name\uC73C\uB85C \uAC80\uC0C9)").option("--email <email>", "\uC678\uBD80 \uC774\uBA54\uC77C (\uCF64\uB9C8 \uAD6C\uBD84 \uAC00\uB2A5, exact match)").option("--user-code <code>", "\uC0AC\uBC88 like \uAC80\uC0C9").option("--user-code-exact <code>", "\uC0AC\uBC88 exact match").option("--page <n>", "\uD398\uC774\uC9C0 (\uAE30\uBCF8 0)", "0").option("--size <n>", "\uD398\uC774\uC9C0 \uD06C\uAE30 (\uAE30\uBCF8 20, max 100)", "20").action(async (keyword, opts) => {
|
|
3450
|
+
const globalOpts = memberSearchCommand.optsWithGlobals();
|
|
3451
|
+
const filterCount = [keyword, opts.email, opts.userCode, opts.userCodeExact].filter(Boolean).length;
|
|
3452
|
+
if (filterCount === 0) {
|
|
3453
|
+
throw new DoorayCliError(
|
|
3454
|
+
"\uAC80\uC0C9 \uC870\uAC74\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. positional <keyword>(=name) \uB610\uB294 --email/--user-code/--user-code-exact \uC911 \uD558\uB098 \uC774\uC0C1.",
|
|
3455
|
+
EXIT_PARAM_ERROR
|
|
3456
|
+
);
|
|
3457
|
+
}
|
|
3458
|
+
if (keyword && (opts.email || opts.userCode || opts.userCodeExact)) {
|
|
3459
|
+
throw new DoorayCliError(
|
|
3460
|
+
"positional <keyword>(name)\uC640 --email/--user-code/--user-code-exact \uC635\uC158\uC740 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00.",
|
|
3461
|
+
EXIT_PARAM_ERROR
|
|
3462
|
+
);
|
|
3463
|
+
}
|
|
3464
|
+
const config = await getConfigOrThrow();
|
|
3465
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
3466
|
+
const size = Math.min(Math.max(1, Number(opts.size) || 20), 100);
|
|
3467
|
+
const page = Math.max(0, Number(opts.page) || 0);
|
|
3468
|
+
startSpinner("\uBA64\uBC84 \uAC80\uC0C9 \uC911...");
|
|
3469
|
+
const res = await client.searchMembers({
|
|
3470
|
+
...keyword && { name: keyword },
|
|
3471
|
+
...opts.email && { externalEmailAddresses: opts.email },
|
|
3472
|
+
...opts.userCode && { userCode: opts.userCode },
|
|
3473
|
+
...opts.userCodeExact && { userCodeExact: opts.userCodeExact },
|
|
3474
|
+
page,
|
|
3475
|
+
size
|
|
3476
|
+
});
|
|
3477
|
+
stopSpinner(true, `${res.totalCount}\uAC74 (\uC774 \uD398\uC774\uC9C0 ${res.result.length})`);
|
|
3478
|
+
formatMemberSearchResults(res.result, globalOpts);
|
|
3479
|
+
});
|
|
3480
|
+
|
|
2922
3481
|
// src/commands/member/index.ts
|
|
2923
|
-
var memberCommand = new
|
|
3482
|
+
var memberCommand = new import_commander40.Command("member").description("Dooray \uBA64\uBC84 \uC870\uD68C");
|
|
2924
3483
|
memberCommand.addCommand(memberGetCommand);
|
|
2925
3484
|
memberCommand.addCommand(memberListCommand);
|
|
3485
|
+
memberCommand.addCommand(memberSearchCommand);
|
|
2926
3486
|
|
|
2927
3487
|
// src/commands/mail/list.ts
|
|
2928
|
-
var
|
|
3488
|
+
var import_commander41 = require("commander");
|
|
2929
3489
|
|
|
2930
3490
|
// src/api/imapClient.ts
|
|
2931
3491
|
var import_imapflow = require("imapflow");
|
|
@@ -3033,7 +3593,7 @@ async function getMail(config, uid) {
|
|
|
3033
3593
|
|
|
3034
3594
|
// src/commands/mail/list.ts
|
|
3035
3595
|
var import_chalk5 = __toESM(require("chalk"));
|
|
3036
|
-
var mailListCommand = new
|
|
3596
|
+
var mailListCommand = new import_commander41.Command("list").description("\uBA54\uC77C \uBAA9\uB85D \uC870\uD68C").option("--unread", "\uC548\uC77D\uC740 \uBA54\uC77C\uB9CC").option("--search <keyword>", "\uC81C\uBAA9 \uAC80\uC0C9").option("--size <number>", "\uC870\uD68C \uAC1C\uC218", "20").action(async (opts) => {
|
|
3037
3597
|
const globalOpts = mailListCommand.optsWithGlobals();
|
|
3038
3598
|
const config = await getConfigOrThrow();
|
|
3039
3599
|
startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
|
|
@@ -3065,9 +3625,9 @@ var mailListCommand = new import_commander35.Command("list").description("\uBA54
|
|
|
3065
3625
|
});
|
|
3066
3626
|
|
|
3067
3627
|
// src/commands/mail/get.ts
|
|
3068
|
-
var
|
|
3628
|
+
var import_commander42 = require("commander");
|
|
3069
3629
|
var import_chalk6 = __toESM(require("chalk"));
|
|
3070
|
-
var mailGetCommand = new
|
|
3630
|
+
var mailGetCommand = new import_commander42.Command("get").description("\uBA54\uC77C \uC0C1\uC138 \uC870\uD68C").argument("<uid>", "\uBA54\uC77C UID").action(async (uid) => {
|
|
3071
3631
|
const globalOpts = mailGetCommand.optsWithGlobals();
|
|
3072
3632
|
const config = await getConfigOrThrow();
|
|
3073
3633
|
startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
|
|
@@ -3098,8 +3658,8 @@ ${mail.body}
|
|
|
3098
3658
|
});
|
|
3099
3659
|
|
|
3100
3660
|
// src/commands/mail/send.ts
|
|
3101
|
-
var
|
|
3102
|
-
var
|
|
3661
|
+
var import_commander43 = require("commander");
|
|
3662
|
+
var import_promises11 = require("fs/promises");
|
|
3103
3663
|
|
|
3104
3664
|
// src/api/smtpClient.ts
|
|
3105
3665
|
var import_nodemailer = __toESM(require("nodemailer"));
|
|
@@ -3148,12 +3708,12 @@ async function sendMail(config, opts) {
|
|
|
3148
3708
|
}
|
|
3149
3709
|
|
|
3150
3710
|
// src/commands/mail/send.ts
|
|
3151
|
-
var mailSendCommand = new
|
|
3711
|
+
var mailSendCommand = new import_commander43.Command("send").description("\uBA54\uC77C \uBC1C\uC1A1").requiredOption("--to <addresses...>", "\uBC1B\uB294\uC0AC\uB78C \uC774\uBA54\uC77C (\uBCF5\uC218 \uAC00\uB2A5)").requiredOption("--subject <title>", "\uC81C\uBAA9").option("--body <text>", "\uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--bcc <addresses...>", "\uC228\uC740\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (opts) => {
|
|
3152
3712
|
const globalOpts = mailSendCommand.optsWithGlobals();
|
|
3153
3713
|
const config = await getConfigOrThrow();
|
|
3154
3714
|
let body = opts.body ?? "";
|
|
3155
3715
|
if (opts.bodyFile) {
|
|
3156
|
-
body = await (0,
|
|
3716
|
+
body = await (0, import_promises11.readFile)(opts.bodyFile, "utf-8");
|
|
3157
3717
|
}
|
|
3158
3718
|
if (!body) {
|
|
3159
3719
|
process.stderr.write("\uC624\uB958: --body \uB610\uB294 --body-file\uC744 \uC9C0\uC815\uD558\uC138\uC694\n");
|
|
@@ -3183,8 +3743,8 @@ var mailSendCommand = new import_commander37.Command("send").description("\uBA54
|
|
|
3183
3743
|
});
|
|
3184
3744
|
|
|
3185
3745
|
// src/commands/mail/reply.ts
|
|
3186
|
-
var
|
|
3187
|
-
var
|
|
3746
|
+
var import_commander44 = require("commander");
|
|
3747
|
+
var import_promises12 = require("fs/promises");
|
|
3188
3748
|
var import_imapflow2 = require("imapflow");
|
|
3189
3749
|
async function getMessageId(config, uid) {
|
|
3190
3750
|
const imap = getImapConfigOrThrow(config);
|
|
@@ -3211,12 +3771,12 @@ async function getMessageId(config, uid) {
|
|
|
3211
3771
|
await client.logout();
|
|
3212
3772
|
}
|
|
3213
3773
|
}
|
|
3214
|
-
var mailReplyCommand = new
|
|
3774
|
+
var mailReplyCommand = new import_commander44.Command("reply").description("\uBA54\uC77C \uB2F5\uC7A5").argument("<uid>", "\uC6D0\uBCF8 \uBA54\uC77C UID").option("--body <text>", "\uB2F5\uC7A5 \uBCF8\uBB38").option("--body-file <path>", "\uB2F5\uC7A5 \uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (uid, opts) => {
|
|
3215
3775
|
const globalOpts = mailReplyCommand.optsWithGlobals();
|
|
3216
3776
|
const config = await getConfigOrThrow();
|
|
3217
3777
|
let body = opts.body ?? "";
|
|
3218
3778
|
if (opts.bodyFile) {
|
|
3219
|
-
body = await (0,
|
|
3779
|
+
body = await (0, import_promises12.readFile)(opts.bodyFile, "utf-8");
|
|
3220
3780
|
}
|
|
3221
3781
|
if (!body) {
|
|
3222
3782
|
process.stderr.write("\uC624\uB958: --body \uB610\uB294 --body-file\uC744 \uC9C0\uC815\uD558\uC138\uC694\n");
|
|
@@ -3252,29 +3812,29 @@ var mailReplyCommand = new import_commander38.Command("reply").description("\uBA
|
|
|
3252
3812
|
});
|
|
3253
3813
|
|
|
3254
3814
|
// src/commands/feedback.ts
|
|
3255
|
-
var
|
|
3815
|
+
var import_commander45 = require("commander");
|
|
3256
3816
|
var import_node_child_process2 = require("child_process");
|
|
3257
3817
|
var import_node_util = require("util");
|
|
3258
|
-
var
|
|
3259
|
-
var
|
|
3260
|
-
var
|
|
3818
|
+
var import_promises15 = require("fs/promises");
|
|
3819
|
+
var import_node_os4 = require("os");
|
|
3820
|
+
var import_node_path11 = require("path");
|
|
3261
3821
|
var import_node_crypto = require("crypto");
|
|
3262
3822
|
var import_prompts = require("@inquirer/prompts");
|
|
3263
3823
|
|
|
3264
3824
|
// src/utils/feedback-meta.ts
|
|
3265
|
-
var
|
|
3266
|
-
var
|
|
3825
|
+
var import_promises13 = require("fs/promises");
|
|
3826
|
+
var import_node_path9 = require("path");
|
|
3267
3827
|
async function readCliVersion() {
|
|
3268
3828
|
const entry = process.argv[1];
|
|
3269
|
-
const here = entry ? (0,
|
|
3829
|
+
const here = entry ? (0, import_node_path9.dirname)(entry) : process.cwd();
|
|
3270
3830
|
const candidates = [
|
|
3271
|
-
(0,
|
|
3272
|
-
(0,
|
|
3273
|
-
(0,
|
|
3831
|
+
(0, import_node_path9.join)(here, "package.json"),
|
|
3832
|
+
(0, import_node_path9.join)(here, "..", "package.json"),
|
|
3833
|
+
(0, import_node_path9.join)(here, "..", "..", "package.json")
|
|
3274
3834
|
];
|
|
3275
3835
|
for (const p of candidates) {
|
|
3276
3836
|
try {
|
|
3277
|
-
const raw = await (0,
|
|
3837
|
+
const raw = await (0, import_promises13.readFile)(p, "utf-8");
|
|
3278
3838
|
const pkg = JSON.parse(raw);
|
|
3279
3839
|
if (pkg.name === "@bifos/dooray-cli" && typeof pkg.version === "string") {
|
|
3280
3840
|
return pkg.version;
|
|
@@ -3292,6 +3852,19 @@ function collectMeta(version) {
|
|
|
3292
3852
|
arch: process.arch
|
|
3293
3853
|
};
|
|
3294
3854
|
}
|
|
3855
|
+
function buildLastRunBlock(last) {
|
|
3856
|
+
return [
|
|
3857
|
+
"## \uC9C1\uC804 \uC2E4\uD589 (\uC790\uB3D9 \uCCA8\uBD80)",
|
|
3858
|
+
"",
|
|
3859
|
+
"```",
|
|
3860
|
+
`$ ${last.argv.join(" ")}`,
|
|
3861
|
+
last.errorMessage.replace(/```/g, "'''"),
|
|
3862
|
+
"```",
|
|
3863
|
+
"",
|
|
3864
|
+
`- exit code: ${last.exitCode}`,
|
|
3865
|
+
`- \uC2DC\uAC01: ${last.timestamp}`
|
|
3866
|
+
].join("\n");
|
|
3867
|
+
}
|
|
3295
3868
|
function buildIssueBody(userBody, meta) {
|
|
3296
3869
|
return [
|
|
3297
3870
|
"## \uD658\uACBD",
|
|
@@ -3306,6 +3879,32 @@ function buildIssueBody(userBody, meta) {
|
|
|
3306
3879
|
].join("\n");
|
|
3307
3880
|
}
|
|
3308
3881
|
|
|
3882
|
+
// src/cache/last-run.ts
|
|
3883
|
+
var import_promises14 = require("fs/promises");
|
|
3884
|
+
var import_node_path10 = require("path");
|
|
3885
|
+
var import_node_os3 = require("os");
|
|
3886
|
+
var LAST_RUN_PATH = (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".dooray", "last-run.json");
|
|
3887
|
+
function isLastRun(obj) {
|
|
3888
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
3889
|
+
const o = obj;
|
|
3890
|
+
return Array.isArray(o.argv) && o.argv.every((a) => typeof a === "string") && typeof o.exitCode === "number" && typeof o.errorMessage === "string" && typeof o.timestamp === "string";
|
|
3891
|
+
}
|
|
3892
|
+
async function readLastRun() {
|
|
3893
|
+
try {
|
|
3894
|
+
const raw = await (0, import_promises14.readFile)(LAST_RUN_PATH, "utf-8");
|
|
3895
|
+
const parsed = JSON.parse(raw);
|
|
3896
|
+
return isLastRun(parsed) ? parsed : null;
|
|
3897
|
+
} catch {
|
|
3898
|
+
return null;
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
async function writeLastRun(data) {
|
|
3902
|
+
await (0, import_promises14.mkdir)((0, import_node_path10.join)((0, import_node_os3.homedir)(), ".dooray"), { recursive: true });
|
|
3903
|
+
const tmp2 = LAST_RUN_PATH + ".tmp";
|
|
3904
|
+
await (0, import_promises14.writeFile)(tmp2, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
3905
|
+
await (0, import_promises14.rename)(tmp2, LAST_RUN_PATH);
|
|
3906
|
+
}
|
|
3907
|
+
|
|
3309
3908
|
// src/commands/feedback.ts
|
|
3310
3909
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
3311
3910
|
var TARGET_REPO = "jon890/dooray-cli";
|
|
@@ -3321,18 +3920,36 @@ async function ensureGhInstalled() {
|
|
|
3321
3920
|
}
|
|
3322
3921
|
async function readBody(opts) {
|
|
3323
3922
|
if (opts.body) return opts.body;
|
|
3324
|
-
if (opts.bodyFile) return await (0,
|
|
3923
|
+
if (opts.bodyFile) return await (0, import_promises15.readFile)(opts.bodyFile, "utf-8");
|
|
3325
3924
|
return void 0;
|
|
3326
3925
|
}
|
|
3327
|
-
var feedbackCommand = new
|
|
3926
|
+
var feedbackCommand = new import_commander45.Command("feedback").description("dooray-cli\uC5D0 \uB300\uD55C GitHub issue \uB4F1\uB85D (gh CLI \uC704\uC784)").option("--title <text>", "\uC774\uC288 \uC81C\uBAA9 (\uC5C6\uC73C\uBA74 \uC778\uD130\uB799\uD2F0\uBE0C)").option("--body <text>", "\uC774\uC288 \uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option(
|
|
3328
3927
|
"--label <name>",
|
|
3329
3928
|
"\uB77C\uBCA8 (\uBC18\uBCF5 \uAC00\uB2A5)",
|
|
3330
3929
|
(value, prev) => [...prev, value],
|
|
3331
3930
|
[]
|
|
3332
|
-
).option("--dry-run", "gh \uD638\uCD9C \uC5C6\uC774 \uBCF8\uBB38\uB9CC \uBBF8\uB9AC\uBCF4\uAE30").action(async (opts) => {
|
|
3931
|
+
).option("--last", "\uC9C1\uC804 \uC2E4\uD589\uD55C dooray \uBA85\uB839\uC758 argv + \uC5D0\uB7EC\uB97C \uBCF8\uBB38 \uC0C1\uB2E8\uC5D0 \uC790\uB3D9 \uCCA8\uBD80").option("--dry-run", "gh \uD638\uCD9C \uC5C6\uC774 \uBCF8\uBB38\uB9CC \uBBF8\uB9AC\uBCF4\uAE30").action(async (opts) => {
|
|
3333
3932
|
let title = opts.title;
|
|
3334
3933
|
let userBody = await readBody(opts);
|
|
3335
3934
|
let labels = [...opts.label];
|
|
3935
|
+
if (opts.last) {
|
|
3936
|
+
const last = await readLastRun();
|
|
3937
|
+
if (!last) {
|
|
3938
|
+
throw new DoorayCliError(
|
|
3939
|
+
"\uAE30\uB85D\uB41C \uC9C1\uC804 \uC2E4\uD589\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. config.json\uC5D0 trackLastRun: true \uC124\uC815 \uD6C4 dooray \uBA85\uB839 \uC2E4\uD589 \uC2DC \uC790\uB3D9 \uAE30\uB85D\uB429\uB2C8\uB2E4.\n \uC124\uC815: dooray config set track-last-run true",
|
|
3940
|
+
EXIT_PARAM_ERROR
|
|
3941
|
+
);
|
|
3942
|
+
}
|
|
3943
|
+
const lastBlock = buildLastRunBlock(last);
|
|
3944
|
+
if (userBody == null) {
|
|
3945
|
+
userBody = await (0, import_prompts.editor)({
|
|
3946
|
+
message: "\uBCF8\uBB38 \uC791\uC131 ($EDITOR\uAC00 \uC5F4\uB9BC)",
|
|
3947
|
+
default: lastBlock + "\n\n"
|
|
3948
|
+
});
|
|
3949
|
+
} else {
|
|
3950
|
+
userBody = lastBlock + "\n\n" + userBody;
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3336
3953
|
if (!title) {
|
|
3337
3954
|
title = await (0, import_prompts.input)({ message: "\uC774\uC288 \uC81C\uBAA9" });
|
|
3338
3955
|
}
|
|
@@ -3397,8 +4014,8 @@ var feedbackCommand = new import_commander39.Command("feedback").description("do
|
|
|
3397
4014
|
}
|
|
3398
4015
|
}
|
|
3399
4016
|
await ensureGhInstalled();
|
|
3400
|
-
const bodyFile = (0,
|
|
3401
|
-
await (0,
|
|
4017
|
+
const bodyFile = (0, import_node_path11.join)((0, import_node_os4.tmpdir)(), `dooray-feedback-${(0, import_node_crypto.randomUUID)()}.md`);
|
|
4018
|
+
await (0, import_promises15.writeFile)(bodyFile, issueBody);
|
|
3402
4019
|
try {
|
|
3403
4020
|
const args = [
|
|
3404
4021
|
"issue",
|
|
@@ -3425,27 +4042,68 @@ gh \uC778\uC99D \uC548 \uB418\uC5B4 \uC788\uC73C\uBA74: gh auth login`,
|
|
|
3425
4042
|
EXIT_PARAM_ERROR
|
|
3426
4043
|
);
|
|
3427
4044
|
} finally {
|
|
3428
|
-
await (0,
|
|
4045
|
+
await (0, import_promises15.unlink)(bodyFile).catch(() => {
|
|
3429
4046
|
});
|
|
3430
4047
|
}
|
|
3431
4048
|
});
|
|
3432
4049
|
|
|
4050
|
+
// src/utils/argv-sanitize.ts
|
|
4051
|
+
var KEY_VALUE_PATTERNS = [
|
|
4052
|
+
/^(--api-key|--token|--password)=(.+)$/
|
|
4053
|
+
];
|
|
4054
|
+
var SEPARATED_KEYS = /* @__PURE__ */ new Set(["--api-key", "--token", "--password"]);
|
|
4055
|
+
function sanitizeArgv(argv) {
|
|
4056
|
+
const out = [];
|
|
4057
|
+
for (let i = 0; i < argv.length; i++) {
|
|
4058
|
+
const a = argv[i];
|
|
4059
|
+
let kvMatch = null;
|
|
4060
|
+
for (const re of KEY_VALUE_PATTERNS) {
|
|
4061
|
+
const m = re.exec(a);
|
|
4062
|
+
if (m) {
|
|
4063
|
+
kvMatch = m;
|
|
4064
|
+
break;
|
|
4065
|
+
}
|
|
4066
|
+
}
|
|
4067
|
+
if (kvMatch) {
|
|
4068
|
+
out.push(`${kvMatch[1]}=***`);
|
|
4069
|
+
continue;
|
|
4070
|
+
}
|
|
4071
|
+
if (SEPARATED_KEYS.has(a)) {
|
|
4072
|
+
out.push(a);
|
|
4073
|
+
if (i + 1 < argv.length) {
|
|
4074
|
+
out.push("***");
|
|
4075
|
+
i++;
|
|
4076
|
+
}
|
|
4077
|
+
continue;
|
|
4078
|
+
}
|
|
4079
|
+
if (/^Authorization\s*:/i.test(a) || /^Bearer\s+\S+/.test(a)) {
|
|
4080
|
+
out.push(a.replace(/(Authorization\s*:\s*).+/i, "$1***").replace(/^(Bearer\s+).+/i, "$1***"));
|
|
4081
|
+
continue;
|
|
4082
|
+
}
|
|
4083
|
+
out.push(a);
|
|
4084
|
+
}
|
|
4085
|
+
return out;
|
|
4086
|
+
}
|
|
4087
|
+
|
|
3433
4088
|
// src/index.ts
|
|
3434
|
-
var program = new
|
|
3435
|
-
program.name("dooray").description("Dooray REST API CLI").version("0.
|
|
4089
|
+
var program = new import_commander46.Command();
|
|
4090
|
+
program.name("dooray").description("Dooray REST API CLI").version("0.6.0").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "ID\uB9CC \uCD9C\uB825").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654");
|
|
3436
4091
|
program.hook("preAction", () => {
|
|
3437
4092
|
const opts = program.opts();
|
|
3438
4093
|
if (opts.color === false || process.env.NO_COLOR) {
|
|
3439
4094
|
import_chalk7.default.level = 0;
|
|
3440
4095
|
}
|
|
4096
|
+
if (opts.json || opts.quiet) {
|
|
4097
|
+
setQuiet(true);
|
|
4098
|
+
}
|
|
3441
4099
|
});
|
|
3442
|
-
var projectCommand = new
|
|
4100
|
+
var projectCommand = new import_commander46.Command("project").description("\uD504\uB85C\uC81D\uD2B8 \uAD00\uB828 \uBA85\uB839");
|
|
3443
4101
|
projectCommand.addCommand(projectListCommand);
|
|
3444
4102
|
projectCommand.addCommand(projectMembersCommand);
|
|
3445
4103
|
projectCommand.addCommand(projectWorkflowsCommand);
|
|
3446
4104
|
projectCommand.addCommand(projectGroupsCommand);
|
|
3447
4105
|
projectCommand.addCommand(projectTagsCommand);
|
|
3448
|
-
var postCommand = new
|
|
4106
|
+
var postCommand = new import_commander46.Command("post").description("\uC5C5\uBB34 \uAD00\uB828 \uBA85\uB839");
|
|
3449
4107
|
postCommand.addCommand(postListCommand);
|
|
3450
4108
|
postCommand.addCommand(postSearchCommand);
|
|
3451
4109
|
postCommand.addCommand(postGetCommand);
|
|
@@ -3453,29 +4111,30 @@ postCommand.addCommand(postEditCommand);
|
|
|
3453
4111
|
postCommand.addCommand(postCreateCommand);
|
|
3454
4112
|
postCommand.addCommand(postDoneCommand);
|
|
3455
4113
|
postCommand.addCommand(postWorkflowCommand);
|
|
3456
|
-
var commentCommand = new
|
|
4114
|
+
var commentCommand = new import_commander46.Command("comment").description("\uB313\uAE00 \uAD00\uB828 \uBA85\uB839");
|
|
3457
4115
|
commentCommand.addCommand(commentListCommand);
|
|
3458
4116
|
commentCommand.addCommand(commentLatestCommand);
|
|
3459
4117
|
commentCommand.addCommand(commentAddCommand);
|
|
3460
4118
|
commentCommand.addCommand(commentEditCommand);
|
|
3461
4119
|
commentCommand.addCommand(commentDeleteCommand);
|
|
4120
|
+
commentCommand.addCommand(commentFileCommand);
|
|
3462
4121
|
postCommand.addCommand(commentCommand);
|
|
3463
|
-
var fileCommand = new
|
|
4122
|
+
var fileCommand = new import_commander46.Command("file").description("\uCCA8\uBD80\uD30C\uC77C \uAD00\uB828 \uBA85\uB839");
|
|
3464
4123
|
fileCommand.addCommand(fileListCommand);
|
|
3465
4124
|
fileCommand.addCommand(fileDownloadCommand);
|
|
3466
4125
|
fileCommand.addCommand(fileDownloadAllCommand);
|
|
3467
4126
|
fileCommand.addCommand(fileUploadCommand);
|
|
3468
4127
|
fileCommand.addCommand(fileDeleteCommand);
|
|
3469
4128
|
postCommand.addCommand(fileCommand);
|
|
3470
|
-
var wikiCommand = new
|
|
4129
|
+
var wikiCommand = new import_commander46.Command("wiki").description("\uC704\uD0A4 \uAD00\uB828 \uBA85\uB839");
|
|
3471
4130
|
wikiCommand.addCommand(wikiListCommand);
|
|
3472
4131
|
wikiCommand.addCommand(wikiPagesCommand);
|
|
3473
|
-
var wikiPageCommand = new
|
|
4132
|
+
var wikiPageCommand = new import_commander46.Command("page").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uAD00\uB828 \uBA85\uB839");
|
|
3474
4133
|
wikiPageCommand.addCommand(wikiPageGetCommand);
|
|
3475
4134
|
wikiPageCommand.addCommand(wikiPageCreateCommand);
|
|
3476
4135
|
wikiPageCommand.addCommand(wikiPageEditCommand);
|
|
3477
4136
|
wikiCommand.addCommand(wikiPageCommand);
|
|
3478
|
-
var mailCommand = new
|
|
4137
|
+
var mailCommand = new import_commander46.Command("mail").description("\uBA54\uC77C \uAD00\uB828 \uBA85\uB839");
|
|
3479
4138
|
mailCommand.addCommand(mailListCommand);
|
|
3480
4139
|
mailCommand.addCommand(mailGetCommand);
|
|
3481
4140
|
mailCommand.addCommand(mailSendCommand);
|
|
@@ -3490,11 +4149,24 @@ program.addCommand(postCommand);
|
|
|
3490
4149
|
program.addCommand(wikiCommand);
|
|
3491
4150
|
program.addCommand(mailCommand);
|
|
3492
4151
|
program.addCommand(feedbackCommand);
|
|
3493
|
-
program.parseAsync().catch((err) => {
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
4152
|
+
program.parseAsync().catch(async (err) => {
|
|
4153
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
4154
|
+
const exitCode = err instanceof DoorayCliError ? err.exitCode : 1;
|
|
4155
|
+
try {
|
|
4156
|
+
const config = await getConfig();
|
|
4157
|
+
const sanitized = sanitizeArgv(process.argv.slice(2));
|
|
4158
|
+
const firstNonFlag = sanitized.find((a) => !a.startsWith("-"));
|
|
4159
|
+
const isFeedbackCommand = firstNonFlag === "feedback";
|
|
4160
|
+
if (config?.trackLastRun && !isFeedbackCommand) {
|
|
4161
|
+
await writeLastRun({
|
|
4162
|
+
argv: ["dooray", ...sanitized],
|
|
4163
|
+
exitCode,
|
|
4164
|
+
errorMessage,
|
|
4165
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4166
|
+
});
|
|
4167
|
+
}
|
|
4168
|
+
} catch {
|
|
3497
4169
|
}
|
|
3498
|
-
process.stderr.write(import_chalk7.default.red(`\uC624\uB958: ${
|
|
3499
|
-
process.exit(
|
|
4170
|
+
process.stderr.write(import_chalk7.default.red(`\uC624\uB958: ${errorMessage}`) + "\n");
|
|
4171
|
+
process.exit(exitCode);
|
|
3500
4172
|
});
|