@bifos/dooray-cli 0.5.2 → 0.5.4
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 +76 -0
- package/dist/index.js +1219 -130
- package/package.json +6 -3
- package/skills/dooray-cli/SKILL.md +106 -5
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_commander40 = require("commander");
|
|
28
28
|
var import_chalk7 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/commands/config.ts
|
|
@@ -198,6 +198,9 @@ var PROJECTS_PATH = (0, import_node_path2.join)(CACHE_DIR, "projects.json");
|
|
|
198
198
|
var PROJECTS_PRIVATE_PATH = (0, import_node_path2.join)(CACHE_DIR, "projects-private.json");
|
|
199
199
|
var MEMBERS_DIR = (0, import_node_path2.join)(CACHE_DIR, "members");
|
|
200
200
|
var WORKFLOWS_DIR = (0, import_node_path2.join)(CACHE_DIR, "workflows");
|
|
201
|
+
var TAGS_DIR = (0, import_node_path2.join)(CACHE_DIR, "tags");
|
|
202
|
+
var MILESTONES_DIR = (0, import_node_path2.join)(CACHE_DIR, "milestones");
|
|
203
|
+
var MEMBER_GROUPS_DIR = (0, import_node_path2.join)(CACHE_DIR, "member-groups");
|
|
201
204
|
var WIKIS_PATH = (0, import_node_path2.join)(CACHE_DIR, "wikis.json");
|
|
202
205
|
async function ensureDir2(dir) {
|
|
203
206
|
await (0, import_promises2.mkdir)(dir, { recursive: true });
|
|
@@ -258,6 +261,33 @@ async function getWorkflows(projectId) {
|
|
|
258
261
|
async function setWorkflows(projectId, items) {
|
|
259
262
|
await writeJson(workflowsPath(projectId), { updatedAt: now(), data: items });
|
|
260
263
|
}
|
|
264
|
+
function tagsPath(projectId) {
|
|
265
|
+
return (0, import_node_path2.join)(TAGS_DIR, `${projectId}.json`);
|
|
266
|
+
}
|
|
267
|
+
async function getTags(projectId) {
|
|
268
|
+
return readJson(tagsPath(projectId));
|
|
269
|
+
}
|
|
270
|
+
async function setTags(projectId, items) {
|
|
271
|
+
await writeJson(tagsPath(projectId), { updatedAt: now(), data: items });
|
|
272
|
+
}
|
|
273
|
+
function milestonesPath(projectId) {
|
|
274
|
+
return (0, import_node_path2.join)(MILESTONES_DIR, `${projectId}.json`);
|
|
275
|
+
}
|
|
276
|
+
async function getMilestones(projectId) {
|
|
277
|
+
return readJson(milestonesPath(projectId));
|
|
278
|
+
}
|
|
279
|
+
async function setMilestones(projectId, items) {
|
|
280
|
+
await writeJson(milestonesPath(projectId), { updatedAt: now(), data: items });
|
|
281
|
+
}
|
|
282
|
+
function memberGroupsPath(projectId) {
|
|
283
|
+
return (0, import_node_path2.join)(MEMBER_GROUPS_DIR, `${projectId}.json`);
|
|
284
|
+
}
|
|
285
|
+
async function getMemberGroups(projectId) {
|
|
286
|
+
return readJson(memberGroupsPath(projectId));
|
|
287
|
+
}
|
|
288
|
+
async function setMemberGroups(projectId, items) {
|
|
289
|
+
await writeJson(memberGroupsPath(projectId), { updatedAt: now(), data: items });
|
|
290
|
+
}
|
|
261
291
|
async function getWikis() {
|
|
262
292
|
return readJson(WIKIS_PATH);
|
|
263
293
|
}
|
|
@@ -285,8 +315,26 @@ async function getCacheStats() {
|
|
|
285
315
|
workflowProjectCount = files.filter((f) => f.endsWith(".json")).length;
|
|
286
316
|
} catch {
|
|
287
317
|
}
|
|
318
|
+
let tagProjectCount = 0;
|
|
319
|
+
try {
|
|
320
|
+
const files = await (0, import_promises2.readdir)(TAGS_DIR);
|
|
321
|
+
tagProjectCount = files.filter((f) => f.endsWith(".json")).length;
|
|
322
|
+
} catch {
|
|
323
|
+
}
|
|
324
|
+
let milestoneProjectCount = 0;
|
|
325
|
+
try {
|
|
326
|
+
const files = await (0, import_promises2.readdir)(MILESTONES_DIR);
|
|
327
|
+
milestoneProjectCount = files.filter((f) => f.endsWith(".json")).length;
|
|
328
|
+
} catch {
|
|
329
|
+
}
|
|
330
|
+
let memberGroupProjectCount = 0;
|
|
331
|
+
try {
|
|
332
|
+
const files = await (0, import_promises2.readdir)(MEMBER_GROUPS_DIR);
|
|
333
|
+
memberGroupProjectCount = files.filter((f) => f.endsWith(".json")).length;
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
288
336
|
const me = await getMe();
|
|
289
|
-
return { projectCount, memberProjectCount, workflowProjectCount, me: me?.data ?? null };
|
|
337
|
+
return { projectCount, memberProjectCount, workflowProjectCount, tagProjectCount, milestoneProjectCount, memberGroupProjectCount, me: me?.data ?? null };
|
|
290
338
|
}
|
|
291
339
|
|
|
292
340
|
// src/commands/cache.ts
|
|
@@ -417,6 +465,13 @@ var DoorayApiClient = class {
|
|
|
417
465
|
return toDoorayCliError(e);
|
|
418
466
|
}
|
|
419
467
|
}
|
|
468
|
+
async getPostStandalone(postId) {
|
|
469
|
+
try {
|
|
470
|
+
return await this.api.get(`project/v1/posts/${postId}`).json();
|
|
471
|
+
} catch (e) {
|
|
472
|
+
return toDoorayCliError(e);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
420
475
|
async createPost(projectId, body) {
|
|
421
476
|
try {
|
|
422
477
|
return await this.api.post(`project/v1/projects/${projectId}/posts`, { json: body }).json();
|
|
@@ -520,6 +575,45 @@ var DoorayApiClient = class {
|
|
|
520
575
|
return toDoorayCliError(e);
|
|
521
576
|
}
|
|
522
577
|
}
|
|
578
|
+
// ─── Tags ───────────────────────────────────────────
|
|
579
|
+
async getProjectTags(projectId, params) {
|
|
580
|
+
try {
|
|
581
|
+
return await this.api.get(`project/v1/projects/${projectId}/tags`, {
|
|
582
|
+
searchParams: {
|
|
583
|
+
...params?.page != null && { page: params.page },
|
|
584
|
+
...params?.size != null && { size: params.size }
|
|
585
|
+
}
|
|
586
|
+
}).json();
|
|
587
|
+
} catch (e) {
|
|
588
|
+
return toDoorayCliError(e);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
// ─── Member Groups ──────────────────────────────────
|
|
592
|
+
async getProjectMemberGroups(projectId, params) {
|
|
593
|
+
try {
|
|
594
|
+
return await this.api.get(`project/v1/projects/${projectId}/member-groups`, {
|
|
595
|
+
searchParams: {
|
|
596
|
+
...params?.page != null && { page: params.page },
|
|
597
|
+
...params?.size != null && { size: params.size }
|
|
598
|
+
}
|
|
599
|
+
}).json();
|
|
600
|
+
} catch (e) {
|
|
601
|
+
return toDoorayCliError(e);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
// ─── Milestones ─────────────────────────────────────
|
|
605
|
+
async getProjectMilestones(projectId, params) {
|
|
606
|
+
try {
|
|
607
|
+
return await this.api.get(`project/v1/projects/${projectId}/milestones`, {
|
|
608
|
+
searchParams: {
|
|
609
|
+
...params?.page != null && { page: params.page },
|
|
610
|
+
...params?.size != null && { size: params.size }
|
|
611
|
+
}
|
|
612
|
+
}).json();
|
|
613
|
+
} catch (e) {
|
|
614
|
+
return toDoorayCliError(e);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
523
617
|
// ─── Wiki ───────────────────────────────────────────
|
|
524
618
|
async getWikis(params) {
|
|
525
619
|
try {
|
|
@@ -677,6 +771,10 @@ var PROJECTS_TTL_MS = 36e5;
|
|
|
677
771
|
var MEMBERS_TTL_MS = 36e5;
|
|
678
772
|
var WORKFLOWS_TTL_MS = 864e5;
|
|
679
773
|
var ME_TTL_MS = 864e5;
|
|
774
|
+
var TAGS_TTL_MS = 864e5;
|
|
775
|
+
var MILESTONES_TTL_MS = 864e5;
|
|
776
|
+
var RESOLVER_FETCH_PAGE_SIZE = 100;
|
|
777
|
+
var MEMBER_GROUPS_TTL_MS = 864e5;
|
|
680
778
|
var WIKIS_TTL_MS = 864e5;
|
|
681
779
|
|
|
682
780
|
// src/resolvers/me.ts
|
|
@@ -717,6 +815,9 @@ var doctorCommand = new import_commander3.Command("doctor").description("\uC124\
|
|
|
717
815
|
console.log(` \uD504\uB85C\uC81D\uD2B8: ${stats.projectCount}\uAC1C`);
|
|
718
816
|
console.log(` \uBA64\uBC84: ${stats.memberProjectCount}\uAC1C \uD504\uB85C\uC81D\uD2B8`);
|
|
719
817
|
console.log(` \uC6CC\uD06C\uD50C\uB85C\uC6B0: ${stats.workflowProjectCount}\uAC1C \uD504\uB85C\uC81D\uD2B8`);
|
|
818
|
+
console.log(` Tag \uCE90\uC2DC (\uD504\uB85C\uC81D\uD2B8 \uC218): ${stats.tagProjectCount}`);
|
|
819
|
+
console.log(` Milestone \uCE90\uC2DC (\uD504\uB85C\uC81D\uD2B8 \uC218): ${stats.milestoneProjectCount}`);
|
|
820
|
+
console.log(` Member Group \uCE90\uC2DC (\uD504\uB85C\uC81D\uD2B8 \uC218): ${stats.memberGroupProjectCount}`);
|
|
720
821
|
const claudeDir = import_path.default.join(
|
|
721
822
|
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
722
823
|
".claude"
|
|
@@ -762,10 +863,10 @@ var import_chalk4 = __toESM(require("chalk"));
|
|
|
762
863
|
var import_path2 = __toESM(require("path"));
|
|
763
864
|
var import_promises5 = __toESM(require("fs/promises"));
|
|
764
865
|
var setupCommand = new import_commander4.Command("setup").description("\uB300\uD654\uD615 \uCD08\uAE30 \uC124\uC815 \uB9C8\uBC95\uC0AC").action(async () => {
|
|
765
|
-
const { input, select, password, confirm } = await import("@inquirer/prompts");
|
|
866
|
+
const { input: input2, select, password, confirm: confirm2 } = await import("@inquirer/prompts");
|
|
766
867
|
const existing = await getConfig();
|
|
767
868
|
try {
|
|
768
|
-
const tenantName = await
|
|
869
|
+
const tenantName = await input2({
|
|
769
870
|
message: "\uD14C\uB10C\uD2B8\uBA85\uC744 \uC785\uB825\uD558\uC138\uC694",
|
|
770
871
|
default: existing?.tenantName ?? DEFAULTS.tenantName,
|
|
771
872
|
theme: { prefix: "\u{1F3E2}" }
|
|
@@ -814,7 +915,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
814
915
|
);
|
|
815
916
|
}
|
|
816
917
|
}
|
|
817
|
-
const useMail = await
|
|
918
|
+
const useMail = await confirm2({
|
|
818
919
|
message: "\uBA54\uC77C \uAE30\uB2A5\uC744 \uC0AC\uC6A9\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
819
920
|
default: !!existing?.imapUsername,
|
|
820
921
|
theme: { prefix: "\u{1F4E7}" }
|
|
@@ -822,7 +923,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
822
923
|
let imapUsername;
|
|
823
924
|
let imapPassword;
|
|
824
925
|
if (useMail) {
|
|
825
|
-
imapUsername = await
|
|
926
|
+
imapUsername = await input2({
|
|
826
927
|
message: `IMAP \uC0AC\uC6A9\uC790 \uC774\uBA54\uC77C (\uD655\uC778: https://${tenantName}.dooray.com/setting/mail/general/read)`,
|
|
827
928
|
default: existing?.imapUsername,
|
|
828
929
|
theme: { prefix: "\u{1F4E8}" }
|
|
@@ -847,7 +948,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
847
948
|
)
|
|
848
949
|
);
|
|
849
950
|
} else {
|
|
850
|
-
const installSkill = await
|
|
951
|
+
const installSkill = await confirm2({
|
|
851
952
|
message: "Claude Code \uC2A4\uD0AC\uC744 \uC124\uCE58\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
852
953
|
default: true,
|
|
853
954
|
theme: { prefix: "\u{1F527}" }
|
|
@@ -939,17 +1040,17 @@ async function ensurePrivateProjects(client) {
|
|
|
939
1040
|
await setPrivateProjects(items);
|
|
940
1041
|
return items;
|
|
941
1042
|
}
|
|
942
|
-
async function resolveProject(client,
|
|
1043
|
+
async function resolveProject(client, input2) {
|
|
943
1044
|
const projects = await ensureProjects(client);
|
|
944
|
-
const match = projects.find((p) => p.code ===
|
|
1045
|
+
const match = projects.find((p) => p.code === input2 || p.id === input2);
|
|
945
1046
|
if (match) return match.id;
|
|
946
1047
|
const privateCached = await getPrivateProjects();
|
|
947
1048
|
if (privateCached && !isExpired(privateCached.updatedAt, PROJECTS_TTL_MS)) {
|
|
948
|
-
const privateMatch = privateCached.data.find((p) => p.code ===
|
|
1049
|
+
const privateMatch = privateCached.data.find((p) => p.code === input2 || p.id === input2);
|
|
949
1050
|
if (privateMatch) return privateMatch.id;
|
|
950
1051
|
}
|
|
951
1052
|
throw new DoorayCliError(
|
|
952
|
-
`\uD504\uB85C\uC81D\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
1053
|
+
`\uD504\uB85C\uC81D\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input2}
|
|
953
1054
|
\uAC1C\uC778 \uD504\uB85C\uC81D\uD2B8\uB77C\uBA74: dooray project list --type private \uB85C \uCE90\uC2DC\uB97C \uAC31\uC2E0\uD558\uC138\uC694`,
|
|
954
1055
|
EXIT_PARAM_ERROR
|
|
955
1056
|
);
|
|
@@ -1024,6 +1125,32 @@ var projectListCommand = new import_commander5.Command("list").description("\uD5
|
|
|
1024
1125
|
// src/commands/project/members.ts
|
|
1025
1126
|
var import_commander6 = require("commander");
|
|
1026
1127
|
|
|
1128
|
+
// src/resolvers/match.ts
|
|
1129
|
+
function matchByName(items, input2, label, renderCandidate) {
|
|
1130
|
+
const exact = items.filter((i) => i.name === input2);
|
|
1131
|
+
if (exact.length === 1) return exact[0];
|
|
1132
|
+
if (exact.length > 1) {
|
|
1133
|
+
throw new DoorayCliError(
|
|
1134
|
+
`\uBCF5\uC218\uC758 ${label}\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4(\uC815\uD655\uC77C\uCE58): "${input2}"
|
|
1135
|
+
` + exact.map((i) => ` - ${renderCandidate(i)}`).join("\n"),
|
|
1136
|
+
EXIT_PARAM_ERROR
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
const partial = items.filter((i) => i.name.includes(input2));
|
|
1140
|
+
if (partial.length === 1) return partial[0];
|
|
1141
|
+
if (partial.length > 1) {
|
|
1142
|
+
throw new DoorayCliError(
|
|
1143
|
+
`\uBCF5\uC218\uC758 ${label}\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4: "${input2}"
|
|
1144
|
+
` + partial.map((i) => ` - ${renderCandidate(i)}`).join("\n"),
|
|
1145
|
+
EXIT_PARAM_ERROR
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
throw new DoorayCliError(
|
|
1149
|
+
`${label}\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input2}`,
|
|
1150
|
+
EXIT_PARAM_ERROR
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1027
1154
|
// src/resolvers/member.ts
|
|
1028
1155
|
async function fetchAllMembers(client, projectId) {
|
|
1029
1156
|
const memberIds = [];
|
|
@@ -1065,22 +1192,23 @@ async function ensureMembers(client, projectId) {
|
|
|
1065
1192
|
await setMembers(projectId, items);
|
|
1066
1193
|
return items;
|
|
1067
1194
|
}
|
|
1068
|
-
async function
|
|
1195
|
+
async function buildMemberNameMap(client, projectId) {
|
|
1069
1196
|
const members = await ensureMembers(client, projectId);
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
const candidates = byName.map((m) => ` - ${m.name} (${m.organizationMemberId})`).join("\n");
|
|
1074
|
-
throw new DoorayCliError(
|
|
1075
|
-
`\uBCF5\uC218\uC758 \uBA64\uBC84\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4: "${input}"
|
|
1076
|
-
${candidates}`,
|
|
1077
|
-
EXIT_PARAM_ERROR
|
|
1078
|
-
);
|
|
1197
|
+
const map = /* @__PURE__ */ new Map();
|
|
1198
|
+
for (const m of members) {
|
|
1199
|
+
if (m.name) map.set(m.organizationMemberId, m.name);
|
|
1079
1200
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1201
|
+
return map;
|
|
1202
|
+
}
|
|
1203
|
+
async function resolveMember(client, projectId, input2) {
|
|
1204
|
+
const members = await ensureMembers(client, projectId);
|
|
1205
|
+
const match = matchByName(
|
|
1206
|
+
members,
|
|
1207
|
+
input2,
|
|
1208
|
+
"\uBA64\uBC84",
|
|
1209
|
+
(m) => `${m.name} (${m.organizationMemberId})`
|
|
1083
1210
|
);
|
|
1211
|
+
return match.organizationMemberId;
|
|
1084
1212
|
}
|
|
1085
1213
|
|
|
1086
1214
|
// src/commands/project/members.ts
|
|
@@ -1122,14 +1250,18 @@ async function ensureWorkflows(client, projectId) {
|
|
|
1122
1250
|
await setWorkflows(projectId, items);
|
|
1123
1251
|
return items;
|
|
1124
1252
|
}
|
|
1125
|
-
async function resolveWorkflow(client, projectId,
|
|
1253
|
+
async function resolveWorkflow(client, projectId, input2) {
|
|
1126
1254
|
const workflows = await ensureWorkflows(client, projectId);
|
|
1127
|
-
const
|
|
1128
|
-
if (
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1255
|
+
const byClass = workflows.filter((w) => w.class === input2);
|
|
1256
|
+
if (byClass.length === 1) return byClass[0].id;
|
|
1257
|
+
if (byClass.length > 1) {
|
|
1258
|
+
throw new DoorayCliError(
|
|
1259
|
+
`\uB3D9\uC77C class\uC758 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5EC\uB7EC \uAC1C\uC785\uB2C8\uB2E4: "${input2}"`,
|
|
1260
|
+
EXIT_PARAM_ERROR
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
const match = matchByName(workflows, input2, "\uC6CC\uD06C\uD50C\uB85C\uC6B0", (w) => `${w.name} [${w.class}] (${w.id})`);
|
|
1264
|
+
return match.id;
|
|
1133
1265
|
}
|
|
1134
1266
|
|
|
1135
1267
|
// src/commands/project/workflows.ts
|
|
@@ -1154,9 +1286,159 @@ var projectWorkflowsCommand = new import_commander7.Command("workflows").descrip
|
|
|
1154
1286
|
});
|
|
1155
1287
|
});
|
|
1156
1288
|
|
|
1157
|
-
// src/commands/
|
|
1289
|
+
// src/commands/project/groups.ts
|
|
1158
1290
|
var import_commander8 = require("commander");
|
|
1159
1291
|
|
|
1292
|
+
// src/resolvers/member-group.ts
|
|
1293
|
+
async function fetchAllMemberGroups(client, projectId) {
|
|
1294
|
+
const all = [];
|
|
1295
|
+
let page = 0;
|
|
1296
|
+
const size = RESOLVER_FETCH_PAGE_SIZE;
|
|
1297
|
+
while (true) {
|
|
1298
|
+
const res = await client.getProjectMemberGroups(projectId, { page, size });
|
|
1299
|
+
for (const g of res.result) {
|
|
1300
|
+
all.push({ id: g.id, code: g.code });
|
|
1301
|
+
}
|
|
1302
|
+
const total = res.totalCount ?? all.length;
|
|
1303
|
+
if (all.length >= total) break;
|
|
1304
|
+
page++;
|
|
1305
|
+
}
|
|
1306
|
+
return all;
|
|
1307
|
+
}
|
|
1308
|
+
async function ensureMemberGroups(client, projectId) {
|
|
1309
|
+
const entry = await getMemberGroups(projectId);
|
|
1310
|
+
if (entry && !isExpired(entry.updatedAt, MEMBER_GROUPS_TTL_MS)) return entry.data;
|
|
1311
|
+
const items = await fetchAllMemberGroups(client, projectId);
|
|
1312
|
+
await setMemberGroups(projectId, items);
|
|
1313
|
+
return items;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
// src/commands/project/groups.ts
|
|
1317
|
+
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) => {
|
|
1318
|
+
const globalOpts = projectGroupsCommand.optsWithGlobals();
|
|
1319
|
+
const config = await getConfigOrThrow();
|
|
1320
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1321
|
+
startSpinner("\uBA64\uBC84 \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1322
|
+
const projectId = await resolveProject(client, project);
|
|
1323
|
+
const groups = await ensureMemberGroups(client, projectId);
|
|
1324
|
+
stopSpinner(true, "\uBA64\uBC84 \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC644\uB8CC");
|
|
1325
|
+
output(globalOpts, {
|
|
1326
|
+
headers: ["ID", "Code"],
|
|
1327
|
+
rows: groups.map((g) => [g.id, g.code]),
|
|
1328
|
+
raw: groups,
|
|
1329
|
+
ids: groups.map((g) => g.id)
|
|
1330
|
+
});
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
// src/commands/project/tags.ts
|
|
1334
|
+
var import_commander9 = require("commander");
|
|
1335
|
+
|
|
1336
|
+
// src/resolvers/tag.ts
|
|
1337
|
+
async function fetchAllTags(client, projectId) {
|
|
1338
|
+
const all = [];
|
|
1339
|
+
let page = 0;
|
|
1340
|
+
const size = RESOLVER_FETCH_PAGE_SIZE;
|
|
1341
|
+
while (true) {
|
|
1342
|
+
const res = await client.getProjectTags(projectId, { page, size });
|
|
1343
|
+
for (const t of res.result) {
|
|
1344
|
+
all.push({
|
|
1345
|
+
id: t.id,
|
|
1346
|
+
name: t.name ?? "",
|
|
1347
|
+
color: t.color ?? "",
|
|
1348
|
+
groupId: t.tagGroup?.id ?? null,
|
|
1349
|
+
groupName: t.tagGroup?.name ?? null,
|
|
1350
|
+
groupMandatory: t.tagGroup?.mandatory ?? false,
|
|
1351
|
+
groupSelectOne: t.tagGroup?.selectOne ?? false
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
const total = res.totalCount ?? all.length;
|
|
1355
|
+
if (all.length >= total) break;
|
|
1356
|
+
page++;
|
|
1357
|
+
}
|
|
1358
|
+
return all;
|
|
1359
|
+
}
|
|
1360
|
+
async function ensureTags(client, projectId) {
|
|
1361
|
+
const entry = await getTags(projectId);
|
|
1362
|
+
if (entry && !isExpired(entry.updatedAt, TAGS_TTL_MS)) return entry.data;
|
|
1363
|
+
const items = await fetchAllTags(client, projectId);
|
|
1364
|
+
await setTags(projectId, items);
|
|
1365
|
+
return items;
|
|
1366
|
+
}
|
|
1367
|
+
async function resolveTags(client, projectId, inputs) {
|
|
1368
|
+
const allTags = await ensureTags(client, projectId);
|
|
1369
|
+
const selected = inputs.map(
|
|
1370
|
+
(input2) => matchByName(
|
|
1371
|
+
allTags,
|
|
1372
|
+
input2,
|
|
1373
|
+
"\uD0DC\uADF8",
|
|
1374
|
+
(t) => t.groupName ? `${t.groupName} / ${t.name} (${t.id})` : `${t.name} (${t.id})`
|
|
1375
|
+
)
|
|
1376
|
+
);
|
|
1377
|
+
const mandatoryGroups = /* @__PURE__ */ new Map();
|
|
1378
|
+
for (const t of allTags) {
|
|
1379
|
+
if (t.groupMandatory && t.groupId) mandatoryGroups.set(t.groupId, t.groupName ?? t.groupId);
|
|
1380
|
+
}
|
|
1381
|
+
const coveredGroups = new Set(selected.map((t) => t.groupId).filter((g) => !!g));
|
|
1382
|
+
const missing = [];
|
|
1383
|
+
for (const [gid, gname] of mandatoryGroups) {
|
|
1384
|
+
if (!coveredGroups.has(gid)) missing.push(gname);
|
|
1385
|
+
}
|
|
1386
|
+
if (missing.length > 0) {
|
|
1387
|
+
throw new DoorayCliError(
|
|
1388
|
+
`\uD544\uC218 \uD0DC\uADF8 \uADF8\uB8F9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (\uADF8\uB8F9\uB2F9 1\uAC1C \uC774\uC0C1 \uD544\uC694):
|
|
1389
|
+
` + missing.map((g) => ` - ${g}`).join("\n"),
|
|
1390
|
+
EXIT_PARAM_ERROR
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
const selectOneGroups = /* @__PURE__ */ new Map();
|
|
1394
|
+
for (const t of selected) {
|
|
1395
|
+
if (!t.groupSelectOne || !t.groupId) continue;
|
|
1396
|
+
const entry = selectOneGroups.get(t.groupId) ?? { name: t.groupName ?? t.groupId, tags: [] };
|
|
1397
|
+
entry.tags.push(t.name);
|
|
1398
|
+
selectOneGroups.set(t.groupId, entry);
|
|
1399
|
+
}
|
|
1400
|
+
const violators = [];
|
|
1401
|
+
for (const [, info] of selectOneGroups) {
|
|
1402
|
+
if (info.tags.length > 1) {
|
|
1403
|
+
violators.push(`${info.name} (\uC120\uD0DD: ${info.tags.join(", ")})`);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
if (violators.length > 0) {
|
|
1407
|
+
throw new DoorayCliError(
|
|
1408
|
+
`\uB2E4\uC74C \uD0DC\uADF8 \uADF8\uB8F9\uC740 1\uAC1C\uB9CC \uC120\uD0DD \uAC00\uB2A5\uD569\uB2C8\uB2E4:
|
|
1409
|
+
` + violators.map((v) => ` - ${v}`).join("\n"),
|
|
1410
|
+
EXIT_PARAM_ERROR
|
|
1411
|
+
);
|
|
1412
|
+
}
|
|
1413
|
+
return selected.map((t) => t.id);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
// src/commands/project/tags.ts
|
|
1417
|
+
var projectTagsCommand = new import_commander9.Command("tags").description("\uD504\uB85C\uC81D\uD2B8 \uD0DC\uADF8 \uBAA9\uB85D \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
|
|
1418
|
+
const globalOpts = projectTagsCommand.optsWithGlobals();
|
|
1419
|
+
const config = await getConfigOrThrow();
|
|
1420
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1421
|
+
startSpinner("\uD0DC\uADF8 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1422
|
+
const projectId = await resolveProject(client, project);
|
|
1423
|
+
const tags = await ensureTags(client, projectId);
|
|
1424
|
+
stopSpinner(true, "\uD0DC\uADF8 \uBAA9\uB85D \uC870\uD68C \uC644\uB8CC");
|
|
1425
|
+
output(globalOpts, {
|
|
1426
|
+
headers: ["ID", "Color", "Name", "Group", "Mandatory"],
|
|
1427
|
+
rows: tags.map((t) => [
|
|
1428
|
+
t.id,
|
|
1429
|
+
t.color,
|
|
1430
|
+
t.name,
|
|
1431
|
+
t.groupName ?? "",
|
|
1432
|
+
t.groupMandatory ? "Y" : ""
|
|
1433
|
+
]),
|
|
1434
|
+
raw: tags,
|
|
1435
|
+
ids: tags.map((t) => t.id)
|
|
1436
|
+
});
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
// src/commands/post/list.ts
|
|
1440
|
+
var import_commander10 = require("commander");
|
|
1441
|
+
|
|
1160
1442
|
// src/formatters/post.ts
|
|
1161
1443
|
function formatPostList(posts, opts) {
|
|
1162
1444
|
output(opts, {
|
|
@@ -1206,7 +1488,7 @@ function formatCommentList(comments, opts) {
|
|
|
1206
1488
|
}
|
|
1207
1489
|
|
|
1208
1490
|
// src/commands/post/list.ts
|
|
1209
|
-
var postListCommand = new
|
|
1491
|
+
var postListCommand = new import_commander10.Command("list").description("\uC5C5\uBB34 \uBAA9\uB85D \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").option("--subject <keyword>", "\uC81C\uBAA9 \uD0A4\uC6CC\uB4DC \uD544\uD130\uB9C1").option("--all", "\uC804\uCCB4 \uD398\uC774\uC9C0\uB124\uC774\uC158 (\uBAA8\uB4E0 \uACB0\uACFC \uC870\uD68C)").option("--page <number>", "\uD398\uC774\uC9C0 \uBC88\uD638", "0").option("--size <number>", "\uD398\uC774\uC9C0 \uD06C\uAE30", "20").action(async (project, opts) => {
|
|
1210
1492
|
const globalOpts = postListCommand.optsWithGlobals();
|
|
1211
1493
|
const config = await getConfigOrThrow();
|
|
1212
1494
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1240,8 +1522,8 @@ var postListCommand = new import_commander8.Command("list").description("\uC5C5\
|
|
|
1240
1522
|
});
|
|
1241
1523
|
|
|
1242
1524
|
// src/commands/post/search.ts
|
|
1243
|
-
var
|
|
1244
|
-
var postSearchCommand = new
|
|
1525
|
+
var import_commander11 = require("commander");
|
|
1526
|
+
var postSearchCommand = new import_commander11.Command("search").description("\uC5C5\uBB34 \uAC80\uC0C9 (\uC81C\uBAA9 \uD0A4\uC6CC\uB4DC)").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").argument("<keyword>", "\uAC80\uC0C9 \uD0A4\uC6CC\uB4DC").action(async (project, keyword) => {
|
|
1245
1527
|
const globalOpts = postSearchCommand.optsWithGlobals();
|
|
1246
1528
|
const config = await getConfigOrThrow();
|
|
1247
1529
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1253,7 +1535,7 @@ var postSearchCommand = new import_commander9.Command("search").description("\uC
|
|
|
1253
1535
|
});
|
|
1254
1536
|
|
|
1255
1537
|
// src/commands/post/get.ts
|
|
1256
|
-
var
|
|
1538
|
+
var import_commander12 = require("commander");
|
|
1257
1539
|
|
|
1258
1540
|
// src/resolvers/post.ts
|
|
1259
1541
|
async function resolvePost(client, projectId, postNumber) {
|
|
@@ -1269,21 +1551,102 @@ async function resolvePost(client, projectId, postNumber) {
|
|
|
1269
1551
|
return res.result[0].id;
|
|
1270
1552
|
}
|
|
1271
1553
|
|
|
1554
|
+
// src/utils/dooray-url.ts
|
|
1555
|
+
var TASK_URL_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/to\/(\d+)(?:[/?#].*)?$/;
|
|
1556
|
+
function parseDoorayTaskUrl(input2) {
|
|
1557
|
+
const m = TASK_URL_RE.exec(input2);
|
|
1558
|
+
return m ? m[1] : null;
|
|
1559
|
+
}
|
|
1560
|
+
function isLikelyDoorayUrl(input2) {
|
|
1561
|
+
return /^https?:\/\//.test(input2);
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// src/resolvers/post-input.ts
|
|
1565
|
+
var INPUT_HELP = "\uC5C5\uBB34\uB97C \uC2DD\uBCC4\uD560 \uC815\uBCF4\uAC00 \uBD80\uC871\uD569\uB2C8\uB2E4. \uB2E4\uC74C \uC911 \uD558\uB098\uB97C \uC785\uB825\uD558\uC138\uC694:\n - <project> <post-number> \uC608: tc-ocr 337\n - --id <postId> \uC608: --id 4319587406666362045\n - <Dooray URL> \uC608: https://x.dooray.com/task/to/4319587406666362045";
|
|
1566
|
+
async function resolveByPostId(client, postId) {
|
|
1567
|
+
const res = await client.getPostStandalone(postId);
|
|
1568
|
+
const d = res.result;
|
|
1569
|
+
return {
|
|
1570
|
+
projectId: d.project.id,
|
|
1571
|
+
projectCode: d.project.code,
|
|
1572
|
+
postId: d.id,
|
|
1573
|
+
postNumber: d.number
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
async function resolvePostInput(client, args) {
|
|
1577
|
+
const { projectArg, postNumberArg, idOpt, urlOpt } = args;
|
|
1578
|
+
const hasPositional = !!projectArg || !!postNumberArg;
|
|
1579
|
+
if (idOpt && urlOpt) {
|
|
1580
|
+
throw new DoorayCliError(
|
|
1581
|
+
"--id\uC640 --url\uC740 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
1582
|
+
EXIT_PARAM_ERROR
|
|
1583
|
+
);
|
|
1584
|
+
}
|
|
1585
|
+
if ((idOpt || urlOpt) && hasPositional) {
|
|
1586
|
+
throw new DoorayCliError(
|
|
1587
|
+
"--id/--url\uACFC positional \uC778\uC790(<project> <post-number>)\uB294 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
1588
|
+
EXIT_PARAM_ERROR
|
|
1589
|
+
);
|
|
1590
|
+
}
|
|
1591
|
+
if (urlOpt) {
|
|
1592
|
+
const postId = parseDoorayTaskUrl(urlOpt);
|
|
1593
|
+
if (!postId) {
|
|
1594
|
+
throw new DoorayCliError(
|
|
1595
|
+
`--url \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: "${urlOpt}"
|
|
1596
|
+
\uC608: https://x.dooray.com/task/to/4319587406666362045`,
|
|
1597
|
+
EXIT_PARAM_ERROR
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
return resolveByPostId(client, postId);
|
|
1601
|
+
}
|
|
1602
|
+
if (idOpt) {
|
|
1603
|
+
return resolveByPostId(client, idOpt);
|
|
1604
|
+
}
|
|
1605
|
+
if (projectArg && !postNumberArg && isLikelyDoorayUrl(projectArg)) {
|
|
1606
|
+
const postId = parseDoorayTaskUrl(projectArg);
|
|
1607
|
+
if (!postId) {
|
|
1608
|
+
throw new DoorayCliError(
|
|
1609
|
+
`Dooray URL \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: "${projectArg}"
|
|
1610
|
+
\uC608: https://x.dooray.com/task/to/4319587406666362045`,
|
|
1611
|
+
EXIT_PARAM_ERROR
|
|
1612
|
+
);
|
|
1613
|
+
}
|
|
1614
|
+
return resolveByPostId(client, postId);
|
|
1615
|
+
}
|
|
1616
|
+
if (projectArg && postNumberArg) {
|
|
1617
|
+
const projectId = await resolveProject(client, projectArg);
|
|
1618
|
+
const num = Number(postNumberArg);
|
|
1619
|
+
if (!Number.isFinite(num) || num <= 0) {
|
|
1620
|
+
throw new DoorayCliError(
|
|
1621
|
+
`<post-number>\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: "${postNumberArg}"`,
|
|
1622
|
+
EXIT_PARAM_ERROR
|
|
1623
|
+
);
|
|
1624
|
+
}
|
|
1625
|
+
const postId = await resolvePost(client, projectId, num);
|
|
1626
|
+
return { projectId, projectCode: projectArg, postId, postNumber: num };
|
|
1627
|
+
}
|
|
1628
|
+
throw new DoorayCliError(INPUT_HELP, EXIT_PARAM_ERROR);
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1272
1631
|
// src/commands/post/get.ts
|
|
1273
|
-
var postGetCommand = new
|
|
1632
|
+
var postGetCommand = new import_commander12.Command("get").description("\uC5C5\uBB34 \uC0C1\uC138 \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) => {
|
|
1274
1633
|
const globalOpts = postGetCommand.optsWithGlobals();
|
|
1275
1634
|
const config = await getConfigOrThrow();
|
|
1276
1635
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1277
1636
|
startSpinner("\uC5C5\uBB34 \uC870\uD68C \uC911...");
|
|
1278
|
-
const projectId = await
|
|
1279
|
-
|
|
1637
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
1638
|
+
projectArg: project,
|
|
1639
|
+
postNumberArg: postNumberStr,
|
|
1640
|
+
idOpt: opts.id,
|
|
1641
|
+
urlOpt: opts.url
|
|
1642
|
+
});
|
|
1280
1643
|
const res = await client.getPost(projectId, postId);
|
|
1281
1644
|
stopSpinner(true, "\uC5C5\uBB34 \uC870\uD68C \uC644\uB8CC");
|
|
1282
1645
|
formatPostDetail(res.result, globalOpts);
|
|
1283
1646
|
});
|
|
1284
1647
|
|
|
1285
1648
|
// src/commands/post/edit.ts
|
|
1286
|
-
var
|
|
1649
|
+
var import_commander13 = require("commander");
|
|
1287
1650
|
|
|
1288
1651
|
// src/editor/index.ts
|
|
1289
1652
|
var import_node_child_process = require("child_process");
|
|
@@ -1291,8 +1654,8 @@ var import_promises6 = __toESM(require("fs/promises"));
|
|
|
1291
1654
|
var import_tmp = __toESM(require("tmp"));
|
|
1292
1655
|
var import_js_yaml = __toESM(require("js-yaml"));
|
|
1293
1656
|
function openInEditor(content) {
|
|
1294
|
-
const
|
|
1295
|
-
if (!
|
|
1657
|
+
const editor2 = process.env.EDITOR;
|
|
1658
|
+
if (!editor2) {
|
|
1296
1659
|
throw new DoorayCliError(
|
|
1297
1660
|
"$EDITOR \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. export EDITOR=vim \uB4F1\uC73C\uB85C \uC124\uC815\uD574\uC8FC\uC138\uC694.",
|
|
1298
1661
|
EXIT_PARAM_ERROR
|
|
@@ -1302,7 +1665,7 @@ function openInEditor(content) {
|
|
|
1302
1665
|
return new Promise(async (resolve, reject) => {
|
|
1303
1666
|
try {
|
|
1304
1667
|
await import_promises6.default.writeFile(tmpFile.name, content, "utf-8");
|
|
1305
|
-
const child = (0, import_node_child_process.spawn)(
|
|
1668
|
+
const child = (0, import_node_child_process.spawn)(editor2, [tmpFile.name], {
|
|
1306
1669
|
stdio: "inherit"
|
|
1307
1670
|
});
|
|
1308
1671
|
child.on("error", (err) => {
|
|
@@ -1453,12 +1816,16 @@ async function resolveUsers(client, projectId, emails) {
|
|
|
1453
1816
|
}
|
|
1454
1817
|
return users;
|
|
1455
1818
|
}
|
|
1456
|
-
var postEditCommand = new
|
|
1819
|
+
var postEditCommand = new import_commander13.Command("edit").description("\uC5C5\uBB34 \uC218\uC815 ($EDITOR \uB610\uB294 --title/--body \uC635\uC158)").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("--title <title>", "\uC81C\uBAA9 \uBCC0\uACBD (non-interactive)").option("--subject <subject>", "--title\uC758 deprecated alias").option("--body <text>", "\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)").action(async (project, postNumberStr, opts) => {
|
|
1457
1820
|
const config = await getConfigOrThrow();
|
|
1458
1821
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1459
1822
|
startSpinner("\uC5C5\uBB34 \uC870\uD68C \uC911...");
|
|
1460
|
-
const projectId = await
|
|
1461
|
-
|
|
1823
|
+
const { projectId, postId, postNumber } = await resolvePostInput(client, {
|
|
1824
|
+
projectArg: project,
|
|
1825
|
+
postNumberArg: postNumberStr,
|
|
1826
|
+
idOpt: opts.id,
|
|
1827
|
+
urlOpt: opts.url
|
|
1828
|
+
});
|
|
1462
1829
|
const res = await client.getPost(projectId, postId);
|
|
1463
1830
|
const post = res.result;
|
|
1464
1831
|
const members = await ensureMembers(client, projectId);
|
|
@@ -1518,21 +1885,67 @@ var postEditCommand = new import_commander11.Command("edit").description("\uC5C5
|
|
|
1518
1885
|
});
|
|
1519
1886
|
stopSpinner(true, "\uC5C5\uBB34 \uC218\uC815 \uC644\uB8CC");
|
|
1520
1887
|
}
|
|
1521
|
-
process.stdout.write(`#${
|
|
1888
|
+
process.stdout.write(`#${postNumber} \uC5C5\uBB34\uAC00 \uC218\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
1522
1889
|
`);
|
|
1523
1890
|
});
|
|
1524
1891
|
|
|
1525
1892
|
// src/commands/post/create.ts
|
|
1526
|
-
var
|
|
1893
|
+
var import_commander14 = require("commander");
|
|
1894
|
+
|
|
1895
|
+
// src/resolvers/milestone.ts
|
|
1896
|
+
async function fetchAllMilestones(client, projectId) {
|
|
1897
|
+
const all = [];
|
|
1898
|
+
let page = 0;
|
|
1899
|
+
const size = RESOLVER_FETCH_PAGE_SIZE;
|
|
1900
|
+
while (true) {
|
|
1901
|
+
const res = await client.getProjectMilestones(projectId, { page, size });
|
|
1902
|
+
for (const m of res.result) all.push({ id: m.id, name: m.name });
|
|
1903
|
+
const total = res.totalCount ?? all.length;
|
|
1904
|
+
if (all.length >= total) break;
|
|
1905
|
+
page++;
|
|
1906
|
+
}
|
|
1907
|
+
return all;
|
|
1908
|
+
}
|
|
1909
|
+
async function ensureMilestones(client, projectId) {
|
|
1910
|
+
const entry = await getMilestones(projectId);
|
|
1911
|
+
if (entry && !isExpired(entry.updatedAt, MILESTONES_TTL_MS)) return entry.data;
|
|
1912
|
+
const items = await fetchAllMilestones(client, projectId);
|
|
1913
|
+
await setMilestones(projectId, items);
|
|
1914
|
+
return items;
|
|
1915
|
+
}
|
|
1916
|
+
async function resolveMilestone(client, projectId, input2) {
|
|
1917
|
+
const all = await ensureMilestones(client, projectId);
|
|
1918
|
+
const match = matchByName(all, input2, "\uB9C8\uC77C\uC2A4\uD1A4", (m) => `${m.name} (${m.id})`);
|
|
1919
|
+
return match.id;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
// src/resolvers/postRef.ts
|
|
1923
|
+
async function resolvePostRef(client, ref) {
|
|
1924
|
+
if (ref.includes("/")) {
|
|
1925
|
+
const [code, numStr] = ref.split("/", 2);
|
|
1926
|
+
const num = Number(numStr);
|
|
1927
|
+
if (!code || !Number.isFinite(num) || num <= 0) {
|
|
1928
|
+
throw new DoorayCliError(
|
|
1929
|
+
`--parent \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: "${ref}" (\uC608: "tc-ocr/337" \uB610\uB294 raw postId)`,
|
|
1930
|
+
EXIT_PARAM_ERROR
|
|
1931
|
+
);
|
|
1932
|
+
}
|
|
1933
|
+
const projectId = await resolveProject(client, code);
|
|
1934
|
+
return resolvePost(client, projectId, num);
|
|
1935
|
+
}
|
|
1936
|
+
return ref;
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
// src/commands/post/create.ts
|
|
1527
1940
|
async function resolveUsers2(client, projectId, inputs) {
|
|
1528
1941
|
const users = [];
|
|
1529
|
-
for (const
|
|
1530
|
-
const memberId = await resolveMember(client, projectId,
|
|
1942
|
+
for (const input2 of inputs) {
|
|
1943
|
+
const memberId = await resolveMember(client, projectId, input2);
|
|
1531
1944
|
users.push({ type: "member", member: { organizationMemberId: memberId } });
|
|
1532
1945
|
}
|
|
1533
1946
|
return users;
|
|
1534
1947
|
}
|
|
1535
|
-
var postCreateCommand = new
|
|
1948
|
+
var postCreateCommand = new import_commander14.Command("create").description("\uC5C5\uBB34 \uC0DD\uC131").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").option("--title <title>", "\uC5C5\uBB34 \uC81C\uBAA9").option("--subject <subject>", "--title\uC758 deprecated alias").option("--to <members...>", "\uB2F4\uB2F9\uC790 (\uC774\uB984 \uB610\uB294 \uC774\uBA54\uC77C, \uC5EC\uB7EC \uBA85 \uAC00\uB2A5)").option("--cc <members...>", "\uCC38\uC870\uC790 (\uC774\uB984 \uB610\uB294 \uC774\uBA54\uC77C, \uC5EC\uB7EC \uBA85 \uAC00\uB2A5)").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)").option("--priority <level>", "\uC6B0\uC120\uC21C\uC704 (highest, high, normal, low, lowest)", "normal").option("--due-date <date>", "\uB9C8\uAC10\uC77C (ISO 8601 \uD615\uC2DD)").option("--tag <name>", "\uD0DC\uADF8 \uC774\uB984 (\uBC18\uBCF5 \uAC00\uB2A5)", (value, prev) => [...prev, value], []).option("--parent <ref>", "\uBD80\uBAA8 \uC5C5\uBB34 (project/number \uB610\uB294 postId)").option("--workflow <name>", "\uCD08\uAE30 \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC774\uB984 \uB610\uB294 class").option("--milestone <name>", "\uB9C8\uC77C\uC2A4\uD1A4 \uC774\uB984").action(async (project, opts) => {
|
|
1536
1949
|
const globalOpts = postCreateCommand.optsWithGlobals();
|
|
1537
1950
|
const config = await getConfigOrThrow();
|
|
1538
1951
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1553,14 +1966,33 @@ var postCreateCommand = new import_commander12.Command("create").description("\u
|
|
|
1553
1966
|
const projectId = await resolveProject(client, project);
|
|
1554
1967
|
const toUsers = opts.to ? await resolveUsers2(client, projectId, opts.to) : [];
|
|
1555
1968
|
const ccUsers = opts.cc ? await resolveUsers2(client, projectId, opts.cc) : [];
|
|
1969
|
+
const tagInputs = (opts.tag ?? []).filter((s) => s.length > 0);
|
|
1970
|
+
const [tagIds, parentPostId, milestoneId] = await Promise.all([
|
|
1971
|
+
tagInputs.length > 0 ? resolveTags(client, projectId, tagInputs) : Promise.resolve(void 0),
|
|
1972
|
+
opts.parent ? resolvePostRef(client, opts.parent) : Promise.resolve(void 0),
|
|
1973
|
+
opts.milestone ? resolveMilestone(client, projectId, opts.milestone) : Promise.resolve(void 0)
|
|
1974
|
+
]);
|
|
1556
1975
|
const res = await client.createPost(projectId, {
|
|
1557
1976
|
subject,
|
|
1558
1977
|
body: { mimeType: "text/x-markdown", content: bodyContent },
|
|
1559
1978
|
users: { to: toUsers, cc: ccUsers },
|
|
1560
1979
|
priority: opts.priority,
|
|
1561
|
-
...opts.dueDate && { dueDate: opts.dueDate, dueDateFlag: true }
|
|
1980
|
+
...opts.dueDate && { dueDate: opts.dueDate, dueDateFlag: true },
|
|
1981
|
+
...parentPostId && { parentPostId },
|
|
1982
|
+
...milestoneId && { milestoneId },
|
|
1983
|
+
...tagIds && tagIds.length > 0 && { tagIds }
|
|
1562
1984
|
});
|
|
1563
1985
|
stopSpinner(true, "\uC5C5\uBB34 \uC0DD\uC131 \uC644\uB8CC");
|
|
1986
|
+
if (opts.workflow) {
|
|
1987
|
+
try {
|
|
1988
|
+
const workflowId = await resolveWorkflow(client, projectId, opts.workflow);
|
|
1989
|
+
await client.setPostWorkflow(projectId, res.result.id, workflowId);
|
|
1990
|
+
} catch (err) {
|
|
1991
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1992
|
+
process.stderr.write(`\u26A0 \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC124\uC815 \uC2E4\uD328 (post\uB294 \uC0DD\uC131\uB428): ${msg}
|
|
1993
|
+
`);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1564
1996
|
if (globalOpts.json) {
|
|
1565
1997
|
printJson(res.result);
|
|
1566
1998
|
} else if (globalOpts.quiet) {
|
|
@@ -1572,54 +2004,244 @@ var postCreateCommand = new import_commander12.Command("create").description("\u
|
|
|
1572
2004
|
});
|
|
1573
2005
|
|
|
1574
2006
|
// src/commands/post/done.ts
|
|
1575
|
-
var
|
|
1576
|
-
var postDoneCommand = new
|
|
2007
|
+
var import_commander15 = require("commander");
|
|
2008
|
+
var postDoneCommand = new import_commander15.Command("done").description("\uC5C5\uBB34 \uC644\uB8CC \uCC98\uB9AC").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) => {
|
|
1577
2009
|
const config = await getConfigOrThrow();
|
|
1578
2010
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1579
2011
|
startSpinner("\uC5C5\uBB34 \uC644\uB8CC \uCC98\uB9AC \uC911...");
|
|
1580
|
-
const projectId = await
|
|
1581
|
-
|
|
2012
|
+
const { projectId, postId, postNumber } = await resolvePostInput(client, {
|
|
2013
|
+
projectArg: project,
|
|
2014
|
+
postNumberArg: postNumberStr,
|
|
2015
|
+
idOpt: opts.id,
|
|
2016
|
+
urlOpt: opts.url
|
|
2017
|
+
});
|
|
1582
2018
|
await client.setPostDone(projectId, postId);
|
|
1583
2019
|
stopSpinner(true, "\uC5C5\uBB34 \uC644\uB8CC \uCC98\uB9AC \uC644\uB8CC");
|
|
1584
|
-
process.stdout.write(`#${
|
|
2020
|
+
process.stdout.write(`#${postNumber} \uC5C5\uBB34\uAC00 \uC644\uB8CC \uCC98\uB9AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
1585
2021
|
`);
|
|
1586
2022
|
});
|
|
1587
2023
|
|
|
1588
2024
|
// src/commands/post/workflow.ts
|
|
1589
|
-
var
|
|
1590
|
-
var postWorkflowCommand = new
|
|
2025
|
+
var import_commander16 = require("commander");
|
|
2026
|
+
var postWorkflowCommand = new import_commander16.Command("workflow").description("\uC5C5\uBB34 \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBCC0\uACBD").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)").argument("[workflow]", "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC774\uB984 \uB610\uB294 \uD074\uB798\uC2A4 (\uB610\uB294 --workflow \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("--workflow <name>", "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC774\uB984 (positional \uB300\uCCB4)").action(async (project, postNumber, workflowArg, opts) => {
|
|
1591
2027
|
const config = await getConfigOrThrow();
|
|
1592
2028
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2029
|
+
let workflowInput = opts.workflow;
|
|
2030
|
+
let projectArg = project;
|
|
2031
|
+
let postNumberArg = postNumber;
|
|
2032
|
+
if (!workflowInput) {
|
|
2033
|
+
if (workflowArg) {
|
|
2034
|
+
workflowInput = workflowArg;
|
|
2035
|
+
} else if ((opts.id || opts.url) && projectArg && !postNumberArg) {
|
|
2036
|
+
workflowInput = projectArg;
|
|
2037
|
+
projectArg = void 0;
|
|
2038
|
+
} else if (!opts.id && !opts.url && projectArg && postNumberArg && !workflowArg) {
|
|
2039
|
+
if (isLikelyDoorayUrl(projectArg)) {
|
|
2040
|
+
workflowInput = postNumberArg;
|
|
2041
|
+
postNumberArg = void 0;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
if (!workflowInput) {
|
|
2046
|
+
throw new DoorayCliError(
|
|
2047
|
+
"workflow\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional \uB610\uB294 --workflow\uB85C \uC785\uB825\uD558\uC138\uC694.",
|
|
2048
|
+
EXIT_PARAM_ERROR
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
1593
2051
|
startSpinner("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBCC0\uACBD \uC911...");
|
|
1594
|
-
const projectId = await
|
|
1595
|
-
|
|
1596
|
-
|
|
2052
|
+
const { projectId, postId, postNumber: resolvedPostNumber } = await resolvePostInput(client, {
|
|
2053
|
+
projectArg,
|
|
2054
|
+
postNumberArg,
|
|
2055
|
+
idOpt: opts.id,
|
|
2056
|
+
urlOpt: opts.url
|
|
2057
|
+
});
|
|
2058
|
+
const workflowId = await resolveWorkflow(client, projectId, workflowInput);
|
|
1597
2059
|
await client.setPostWorkflow(projectId, postId, workflowId);
|
|
1598
2060
|
stopSpinner(true, "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBCC0\uACBD \uC644\uB8CC");
|
|
1599
|
-
process.stdout.write(`#${
|
|
2061
|
+
process.stdout.write(`#${resolvedPostNumber} \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 "${workflowInput}"(\uC73C)\uB85C \uBCC0\uACBD\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
1600
2062
|
`);
|
|
1601
2063
|
});
|
|
1602
2064
|
|
|
1603
2065
|
// src/commands/post/comment/list.ts
|
|
1604
|
-
var
|
|
1605
|
-
|
|
2066
|
+
var import_commander17 = require("commander");
|
|
2067
|
+
|
|
2068
|
+
// src/utils/comment-enrich.ts
|
|
2069
|
+
function enrichCommentCreators(comments, nameMap) {
|
|
2070
|
+
return comments.map((c) => {
|
|
2071
|
+
const id = c.creator?.member?.organizationMemberId;
|
|
2072
|
+
const existing = c.creator?.member?.name;
|
|
2073
|
+
if (existing || !id) return c;
|
|
2074
|
+
const filled = nameMap.get(id);
|
|
2075
|
+
if (!filled) return c;
|
|
2076
|
+
return {
|
|
2077
|
+
...c,
|
|
2078
|
+
creator: {
|
|
2079
|
+
...c.creator,
|
|
2080
|
+
member: { ...c.creator.member, name: filled }
|
|
2081
|
+
}
|
|
2082
|
+
};
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
// src/commands/post/comment/list.ts
|
|
2087
|
+
var PAGE_DEFAULT = "0";
|
|
2088
|
+
var SIZE_DEFAULT = "20";
|
|
2089
|
+
function parseSinceDate(input2) {
|
|
2090
|
+
const d = new Date(input2);
|
|
2091
|
+
if (isNaN(d.getTime())) {
|
|
2092
|
+
throw new DoorayCliError(
|
|
2093
|
+
`--since \uAC12\uC744 \uD30C\uC2F1\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: "${input2}" (ISO 8601 \uB610\uB294 YYYY-MM-DD)`,
|
|
2094
|
+
EXIT_PARAM_ERROR
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
return d;
|
|
2098
|
+
}
|
|
2099
|
+
function validateExclusive(opts) {
|
|
2100
|
+
function err(msg) {
|
|
2101
|
+
return new DoorayCliError(msg, EXIT_PARAM_ERROR);
|
|
2102
|
+
}
|
|
2103
|
+
if (opts.latest) {
|
|
2104
|
+
if (opts.page && opts.page !== PAGE_DEFAULT) throw err("--latest\uC640 --page\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2105
|
+
if (opts.size && opts.size !== SIZE_DEFAULT) throw err("--latest\uC640 --size\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2106
|
+
if (opts.sort && opts.sort !== "asc") throw err("--latest\uC640 --sort\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2107
|
+
if (opts.reverse) throw err("--latest\uC640 --reverse\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2108
|
+
if (opts.since) throw err("--latest\uC640 --since\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2109
|
+
}
|
|
2110
|
+
if (opts.reverse && opts.sort && opts.sort !== "asc") {
|
|
2111
|
+
throw err("--reverse\uC640 --sort \uC635\uC158\uC740 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2112
|
+
}
|
|
2113
|
+
if (opts.sort && opts.sort !== "asc" && opts.sort !== "desc") {
|
|
2114
|
+
throw err(`--sort\uB294 asc \uB610\uB294 desc\uB9CC \uD5C8\uC6A9\uD569\uB2C8\uB2E4: "${opts.sort}"`);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
function resolveOrder(opts) {
|
|
2118
|
+
if (opts.reverse) return "-createdAt";
|
|
2119
|
+
if (opts.sort === "desc") return "-createdAt";
|
|
2120
|
+
return "createdAt";
|
|
2121
|
+
}
|
|
2122
|
+
async function fetchSince(client, projectId, postId, sinceDate) {
|
|
2123
|
+
const sinceMs = sinceDate.getTime();
|
|
2124
|
+
const collected = [];
|
|
2125
|
+
let page = 0;
|
|
2126
|
+
const size = 100;
|
|
2127
|
+
while (true) {
|
|
2128
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2129
|
+
page,
|
|
2130
|
+
size,
|
|
2131
|
+
order: "-createdAt"
|
|
2132
|
+
});
|
|
2133
|
+
const pageItems = res.result;
|
|
2134
|
+
const survivors = pageItems.filter((c) => new Date(c.createdAt).getTime() >= sinceMs);
|
|
2135
|
+
collected.push(...survivors);
|
|
2136
|
+
const hasOlder = pageItems.length > survivors.length;
|
|
2137
|
+
if (hasOlder) break;
|
|
2138
|
+
if (pageItems.length < size) break;
|
|
2139
|
+
page++;
|
|
2140
|
+
}
|
|
2141
|
+
return collected;
|
|
2142
|
+
}
|
|
2143
|
+
var commentListCommand = new import_commander17.Command("list").description("\uB313\uAE00 \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)").option("--page <number>", "\uD398\uC774\uC9C0 \uBC88\uD638", PAGE_DEFAULT).option("--size <number>", "\uD398\uC774\uC9C0 \uD06C\uAE30", SIZE_DEFAULT).option("--sort <order>", "\uC815\uB82C (asc/desc), \uAE30\uBCF8 asc", "asc").option("--reverse", "--sort desc \uC758 alias").option("--latest <n>", "\uCD5C\uC2E0 N\uAC1C (--sort desc + size=N + page=0 \uB2E8\uCD95, \uCD5C\uB300 100)").option("--since <iso>", "\uC774 \uC2DC\uAC04 \uC774\uD6C4 \uB313\uAE00\uB9CC (ISO 8601 \uB610\uB294 YYYY-MM-DD)").option("--from-author <name>", "\uC791\uC131\uC790 \uC774\uB984\uC73C\uB85C \uD544\uD130 (\uBD80\uBD84\uC77C\uCE58)").action(async (project, postNumberStr, opts) => {
|
|
1606
2144
|
const globalOpts = commentListCommand.optsWithGlobals();
|
|
1607
2145
|
const config = await getConfigOrThrow();
|
|
1608
2146
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2147
|
+
validateExclusive(opts);
|
|
2148
|
+
if (opts.latest) {
|
|
2149
|
+
const n = Number(opts.latest);
|
|
2150
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
2151
|
+
throw new DoorayCliError("--latest\uB294 \uC591\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2152
|
+
}
|
|
2153
|
+
if (n > 100) {
|
|
2154
|
+
throw new DoorayCliError("--latest\uB294 \uCD5C\uB300 100\uAE4C\uC9C0 \uC9C0\uC6D0\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
const sinceDate = opts.since ? parseSinceDate(opts.since) : null;
|
|
1609
2158
|
startSpinner("\uB313\uAE00 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1610
|
-
const projectId = await
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
2159
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2160
|
+
projectArg: project,
|
|
2161
|
+
postNumberArg: postNumberStr,
|
|
2162
|
+
idOpt: opts.id,
|
|
2163
|
+
urlOpt: opts.url
|
|
1615
2164
|
});
|
|
2165
|
+
const order = resolveOrder(opts);
|
|
2166
|
+
let comments;
|
|
2167
|
+
if (opts.latest) {
|
|
2168
|
+
const n = Number(opts.latest);
|
|
2169
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2170
|
+
page: 0,
|
|
2171
|
+
size: n,
|
|
2172
|
+
order: "-createdAt"
|
|
2173
|
+
});
|
|
2174
|
+
comments = res.result;
|
|
2175
|
+
} else if (sinceDate) {
|
|
2176
|
+
comments = await fetchSince(client, projectId, postId, sinceDate);
|
|
2177
|
+
if (order === "createdAt") comments = [...comments].reverse();
|
|
2178
|
+
} else {
|
|
2179
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2180
|
+
page: Number(opts.page),
|
|
2181
|
+
size: Number(opts.size),
|
|
2182
|
+
order
|
|
2183
|
+
});
|
|
2184
|
+
comments = res.result;
|
|
2185
|
+
}
|
|
1616
2186
|
stopSpinner(true, "\uB313\uAE00 \uBAA9\uB85D \uC870\uD68C \uC644\uB8CC");
|
|
1617
|
-
|
|
2187
|
+
if (opts.fromAuthor) {
|
|
2188
|
+
const memberId = await resolveMember(client, projectId, opts.fromAuthor);
|
|
2189
|
+
comments = comments.filter(
|
|
2190
|
+
(c) => c.creator?.member?.organizationMemberId === memberId
|
|
2191
|
+
);
|
|
2192
|
+
}
|
|
2193
|
+
if (!globalOpts.json) {
|
|
2194
|
+
let nameMap = /* @__PURE__ */ new Map();
|
|
2195
|
+
try {
|
|
2196
|
+
nameMap = await buildMemberNameMap(client, projectId);
|
|
2197
|
+
} catch {
|
|
2198
|
+
}
|
|
2199
|
+
comments = enrichCommentCreators(comments, nameMap);
|
|
2200
|
+
}
|
|
2201
|
+
formatCommentList(comments, globalOpts);
|
|
2202
|
+
});
|
|
2203
|
+
|
|
2204
|
+
// src/commands/post/comment/latest.ts
|
|
2205
|
+
var import_commander18 = require("commander");
|
|
2206
|
+
var commentLatestCommand = new import_commander18.Command("latest").description("\uCD5C\uC2E0 \uB313\uAE00 1\uAC1C \uC870\uD68C (= comment list --latest 1)").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("-n, --count <n>", "\uCD5C\uC2E0 N\uAC1C (\uAE30\uBCF8 1)", "1").action(async (project, postNumberStr, opts) => {
|
|
2207
|
+
const globalOpts = commentLatestCommand.optsWithGlobals();
|
|
2208
|
+
const config = await getConfigOrThrow();
|
|
2209
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2210
|
+
const n = Number(opts.count);
|
|
2211
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
2212
|
+
throw new DoorayCliError("--count\uB294 \uC591\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2213
|
+
}
|
|
2214
|
+
if (n > 100) {
|
|
2215
|
+
throw new DoorayCliError("--count\uB294 \uCD5C\uB300 100\uAE4C\uC9C0 \uC9C0\uC6D0\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2216
|
+
}
|
|
2217
|
+
startSpinner("\uCD5C\uC2E0 \uB313\uAE00 \uC870\uD68C \uC911...");
|
|
2218
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2219
|
+
projectArg: project,
|
|
2220
|
+
postNumberArg: postNumberStr,
|
|
2221
|
+
idOpt: opts.id,
|
|
2222
|
+
urlOpt: opts.url
|
|
2223
|
+
});
|
|
2224
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2225
|
+
page: 0,
|
|
2226
|
+
size: Math.min(n, 100),
|
|
2227
|
+
order: "-createdAt"
|
|
2228
|
+
});
|
|
2229
|
+
stopSpinner(true, "\uC870\uD68C \uC644\uB8CC");
|
|
2230
|
+
let comments = res.result.slice(0, n);
|
|
2231
|
+
if (!globalOpts.json) {
|
|
2232
|
+
let nameMap = /* @__PURE__ */ new Map();
|
|
2233
|
+
try {
|
|
2234
|
+
nameMap = await buildMemberNameMap(client, projectId);
|
|
2235
|
+
} catch {
|
|
2236
|
+
}
|
|
2237
|
+
comments = enrichCommentCreators(comments, nameMap);
|
|
2238
|
+
}
|
|
2239
|
+
formatCommentList(comments, globalOpts);
|
|
1618
2240
|
});
|
|
1619
2241
|
|
|
1620
2242
|
// src/commands/post/comment/add.ts
|
|
1621
|
-
var
|
|
1622
|
-
var commentAddCommand = new
|
|
2243
|
+
var import_commander19 = require("commander");
|
|
2244
|
+
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)").action(async (project, postNumberStr, opts) => {
|
|
1623
2245
|
const globalOpts = commentAddCommand.optsWithGlobals();
|
|
1624
2246
|
const config = await getConfigOrThrow();
|
|
1625
2247
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1632,8 +2254,12 @@ var commentAddCommand = new import_commander16.Command("add").description("\uB31
|
|
|
1632
2254
|
}
|
|
1633
2255
|
}
|
|
1634
2256
|
startSpinner("\uB313\uAE00 \uCD94\uAC00 \uC911...");
|
|
1635
|
-
const projectId = await
|
|
1636
|
-
|
|
2257
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2258
|
+
projectArg: project,
|
|
2259
|
+
postNumberArg: postNumberStr,
|
|
2260
|
+
idOpt: opts.id,
|
|
2261
|
+
urlOpt: opts.url
|
|
2262
|
+
});
|
|
1637
2263
|
const res = await client.createPostComment(projectId, postId, {
|
|
1638
2264
|
body: { mimeType: "text/x-markdown", content: bodyContent }
|
|
1639
2265
|
});
|
|
@@ -1649,13 +2275,56 @@ var commentAddCommand = new import_commander16.Command("add").description("\uB31
|
|
|
1649
2275
|
});
|
|
1650
2276
|
|
|
1651
2277
|
// src/commands/post/comment/edit.ts
|
|
1652
|
-
var
|
|
1653
|
-
var commentEditCommand = new
|
|
2278
|
+
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)").action(async (arg1, arg2, arg3, opts) => {
|
|
1654
2280
|
const config = await getConfigOrThrow();
|
|
1655
2281
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2282
|
+
let projectArg;
|
|
2283
|
+
let postNumberArg;
|
|
2284
|
+
let commentId = opts.commentId;
|
|
2285
|
+
if (opts.id || opts.url) {
|
|
2286
|
+
if (arg2 || arg3) {
|
|
2287
|
+
throw new DoorayCliError(
|
|
2288
|
+
"--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.",
|
|
2289
|
+
EXIT_PARAM_ERROR
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2292
|
+
commentId = commentId ?? arg1;
|
|
2293
|
+
} else if (arg3) {
|
|
2294
|
+
projectArg = arg1;
|
|
2295
|
+
postNumberArg = arg2;
|
|
2296
|
+
commentId = commentId ?? arg3;
|
|
2297
|
+
} else if (arg1 && !arg2) {
|
|
2298
|
+
projectArg = arg1;
|
|
2299
|
+
if (!commentId) {
|
|
2300
|
+
throw new DoorayCliError(
|
|
2301
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --comment-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2302
|
+
EXIT_PARAM_ERROR
|
|
2303
|
+
);
|
|
2304
|
+
}
|
|
2305
|
+
} else {
|
|
2306
|
+
projectArg = arg1;
|
|
2307
|
+
postNumberArg = arg2;
|
|
2308
|
+
if (!commentId) {
|
|
2309
|
+
throw new DoorayCliError(
|
|
2310
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2311
|
+
EXIT_PARAM_ERROR
|
|
2312
|
+
);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
if (!commentId) {
|
|
2316
|
+
throw new DoorayCliError(
|
|
2317
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2318
|
+
EXIT_PARAM_ERROR
|
|
2319
|
+
);
|
|
2320
|
+
}
|
|
1656
2321
|
startSpinner("\uB313\uAE00 \uC870\uD68C \uC911...");
|
|
1657
|
-
const projectId = await
|
|
1658
|
-
|
|
2322
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2323
|
+
projectArg,
|
|
2324
|
+
postNumberArg,
|
|
2325
|
+
idOpt: opts.id,
|
|
2326
|
+
urlOpt: opts.url
|
|
2327
|
+
});
|
|
1659
2328
|
const comments = await client.getPostComments(projectId, postId);
|
|
1660
2329
|
const comment = comments.result.find((c) => c.id === commentId);
|
|
1661
2330
|
stopSpinner(true, "\uB313\uAE00 \uC870\uD68C \uC644\uB8CC");
|
|
@@ -1683,13 +2352,56 @@ var commentEditCommand = new import_commander17.Command("edit").description("\uB
|
|
|
1683
2352
|
});
|
|
1684
2353
|
|
|
1685
2354
|
// src/commands/post/comment/delete.ts
|
|
1686
|
-
var
|
|
1687
|
-
var commentDeleteCommand = new
|
|
2355
|
+
var import_commander21 = require("commander");
|
|
2356
|
+
var commentDeleteCommand = new import_commander21.Command("delete").description("\uB313\uAE00 \uC0AD\uC81C").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)").action(async (arg1, arg2, arg3, opts) => {
|
|
1688
2357
|
const config = await getConfigOrThrow();
|
|
1689
2358
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2359
|
+
let projectArg;
|
|
2360
|
+
let postNumberArg;
|
|
2361
|
+
let commentId = opts.commentId;
|
|
2362
|
+
if (opts.id || opts.url) {
|
|
2363
|
+
if (arg2 || arg3) {
|
|
2364
|
+
throw new DoorayCliError(
|
|
2365
|
+
"--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.",
|
|
2366
|
+
EXIT_PARAM_ERROR
|
|
2367
|
+
);
|
|
2368
|
+
}
|
|
2369
|
+
commentId = commentId ?? arg1;
|
|
2370
|
+
} else if (arg3) {
|
|
2371
|
+
projectArg = arg1;
|
|
2372
|
+
postNumberArg = arg2;
|
|
2373
|
+
commentId = commentId ?? arg3;
|
|
2374
|
+
} else if (arg1 && !arg2) {
|
|
2375
|
+
projectArg = arg1;
|
|
2376
|
+
if (!commentId) {
|
|
2377
|
+
throw new DoorayCliError(
|
|
2378
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --comment-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2379
|
+
EXIT_PARAM_ERROR
|
|
2380
|
+
);
|
|
2381
|
+
}
|
|
2382
|
+
} else {
|
|
2383
|
+
projectArg = arg1;
|
|
2384
|
+
postNumberArg = arg2;
|
|
2385
|
+
if (!commentId) {
|
|
2386
|
+
throw new DoorayCliError(
|
|
2387
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2388
|
+
EXIT_PARAM_ERROR
|
|
2389
|
+
);
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
if (!commentId) {
|
|
2393
|
+
throw new DoorayCliError(
|
|
2394
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2395
|
+
EXIT_PARAM_ERROR
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
1690
2398
|
startSpinner("\uB313\uAE00 \uC0AD\uC81C \uC911...");
|
|
1691
|
-
const projectId = await
|
|
1692
|
-
|
|
2399
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2400
|
+
projectArg,
|
|
2401
|
+
postNumberArg,
|
|
2402
|
+
idOpt: opts.id,
|
|
2403
|
+
urlOpt: opts.url
|
|
2404
|
+
});
|
|
1693
2405
|
await client.deletePostComment(projectId, postId, commentId);
|
|
1694
2406
|
stopSpinner(true, "\uB313\uAE00 \uC0AD\uC81C \uC644\uB8CC");
|
|
1695
2407
|
process.stdout.write(`\uB313\uAE00\uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${commentId}
|
|
@@ -1697,19 +2409,23 @@ var commentDeleteCommand = new import_commander18.Command("delete").description(
|
|
|
1697
2409
|
});
|
|
1698
2410
|
|
|
1699
2411
|
// src/commands/post/file/list.ts
|
|
1700
|
-
var
|
|
2412
|
+
var import_commander22 = require("commander");
|
|
1701
2413
|
function formatSize(bytes) {
|
|
1702
2414
|
if (bytes < 1024) return `${bytes}B`;
|
|
1703
2415
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
1704
2416
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
1705
2417
|
}
|
|
1706
|
-
var fileListCommand = new
|
|
2418
|
+
var fileListCommand = new import_commander22.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) => {
|
|
1707
2419
|
const globalOpts = fileListCommand.optsWithGlobals();
|
|
1708
2420
|
const config = await getConfigOrThrow();
|
|
1709
2421
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1710
2422
|
startSpinner("\uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1711
|
-
const projectId = await
|
|
1712
|
-
|
|
2423
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2424
|
+
projectArg: project,
|
|
2425
|
+
postNumberArg: postNumberStr,
|
|
2426
|
+
idOpt: opts.id,
|
|
2427
|
+
urlOpt: opts.url
|
|
2428
|
+
});
|
|
1713
2429
|
const res = await client.getPostFiles(projectId, postId);
|
|
1714
2430
|
stopSpinner(true, `\uCCA8\uBD80\uD30C\uC77C ${res.result.length}\uAC1C`);
|
|
1715
2431
|
output(globalOpts, {
|
|
@@ -1727,15 +2443,55 @@ var fileListCommand = new import_commander19.Command("list").description("\uC5C5
|
|
|
1727
2443
|
});
|
|
1728
2444
|
|
|
1729
2445
|
// src/commands/post/file/download.ts
|
|
1730
|
-
var
|
|
2446
|
+
var import_commander23 = require("commander");
|
|
1731
2447
|
var import_promises8 = require("fs/promises");
|
|
1732
2448
|
var import_node_path4 = require("path");
|
|
1733
|
-
var fileDownloadCommand = new
|
|
2449
|
+
var fileDownloadCommand = new import_commander23.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) => {
|
|
1734
2450
|
const config = await getConfigOrThrow();
|
|
1735
2451
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2452
|
+
let projectArg;
|
|
2453
|
+
let postNumberArg;
|
|
2454
|
+
let fileId = opts.fileId;
|
|
2455
|
+
if (opts.id || opts.url) {
|
|
2456
|
+
if (arg2 || arg3) {
|
|
2457
|
+
throw new DoorayCliError(
|
|
2458
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --file-id \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
2459
|
+
EXIT_PARAM_ERROR
|
|
2460
|
+
);
|
|
2461
|
+
}
|
|
2462
|
+
fileId = fileId ?? arg1;
|
|
2463
|
+
} else if (arg3) {
|
|
2464
|
+
projectArg = arg1;
|
|
2465
|
+
postNumberArg = arg2;
|
|
2466
|
+
fileId = fileId ?? arg3;
|
|
2467
|
+
} else if (arg1 && !arg2) {
|
|
2468
|
+
projectArg = arg1;
|
|
2469
|
+
if (!fileId) {
|
|
2470
|
+
throw new DoorayCliError(
|
|
2471
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --file-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2472
|
+
EXIT_PARAM_ERROR
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
} else {
|
|
2476
|
+
projectArg = arg1;
|
|
2477
|
+
postNumberArg = arg2;
|
|
2478
|
+
if (!fileId) {
|
|
2479
|
+
throw new DoorayCliError(
|
|
2480
|
+
"<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2481
|
+
EXIT_PARAM_ERROR
|
|
2482
|
+
);
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
if (!fileId) {
|
|
2486
|
+
throw new DoorayCliError("\uD30C\uC77C ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2487
|
+
}
|
|
1736
2488
|
startSpinner("\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
|
|
1737
|
-
const projectId = await
|
|
1738
|
-
|
|
2489
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2490
|
+
projectArg,
|
|
2491
|
+
postNumberArg,
|
|
2492
|
+
idOpt: opts.id,
|
|
2493
|
+
urlOpt: opts.url
|
|
2494
|
+
});
|
|
1739
2495
|
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, fileId);
|
|
1740
2496
|
const outputPath = (0, import_node_path4.join)(opts.output, fileName);
|
|
1741
2497
|
await (0, import_promises8.writeFile)(outputPath, Buffer.from(buffer));
|
|
@@ -1745,15 +2501,19 @@ var fileDownloadCommand = new import_commander20.Command("download").description
|
|
|
1745
2501
|
});
|
|
1746
2502
|
|
|
1747
2503
|
// src/commands/post/file/download-all.ts
|
|
1748
|
-
var
|
|
2504
|
+
var import_commander24 = require("commander");
|
|
1749
2505
|
var import_promises9 = require("fs/promises");
|
|
1750
2506
|
var import_node_path5 = require("path");
|
|
1751
|
-
var fileDownloadAllCommand = new
|
|
2507
|
+
var fileDownloadAllCommand = new import_commander24.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) => {
|
|
1752
2508
|
const config = await getConfigOrThrow();
|
|
1753
2509
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1754
2510
|
const spinner = startSpinner("\uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1755
|
-
const projectId = await
|
|
1756
|
-
|
|
2511
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2512
|
+
projectArg: project,
|
|
2513
|
+
postNumberArg: postNumberStr,
|
|
2514
|
+
idOpt: opts.id,
|
|
2515
|
+
urlOpt: opts.url
|
|
2516
|
+
});
|
|
1757
2517
|
const res = await client.getPostFiles(projectId, postId);
|
|
1758
2518
|
if (res.result.length === 0) {
|
|
1759
2519
|
stopSpinner(true, "\uCCA8\uBD80\uD30C\uC77C \uC5C6\uC74C");
|
|
@@ -1777,15 +2537,55 @@ var fileDownloadAllCommand = new import_commander21.Command("download-all").desc
|
|
|
1777
2537
|
});
|
|
1778
2538
|
|
|
1779
2539
|
// src/commands/post/file/upload.ts
|
|
1780
|
-
var
|
|
2540
|
+
var import_commander25 = require("commander");
|
|
1781
2541
|
var import_node_path6 = require("path");
|
|
1782
|
-
var fileUploadCommand = new
|
|
2542
|
+
var fileUploadCommand = new import_commander25.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) => {
|
|
1783
2543
|
const globalOpts = fileUploadCommand.optsWithGlobals();
|
|
1784
2544
|
const config = await getConfigOrThrow();
|
|
1785
2545
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2546
|
+
let projectArg;
|
|
2547
|
+
let postNumberArg;
|
|
2548
|
+
let filePath = opts.file;
|
|
2549
|
+
if (opts.id || opts.url) {
|
|
2550
|
+
if (arg2 || arg3) {
|
|
2551
|
+
throw new DoorayCliError(
|
|
2552
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD30C\uC77C \uACBD\uB85C \uC678 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --file \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
2553
|
+
EXIT_PARAM_ERROR
|
|
2554
|
+
);
|
|
2555
|
+
}
|
|
2556
|
+
filePath = filePath ?? arg1;
|
|
2557
|
+
} else if (arg3) {
|
|
2558
|
+
projectArg = arg1;
|
|
2559
|
+
postNumberArg = arg2;
|
|
2560
|
+
filePath = filePath ?? arg3;
|
|
2561
|
+
} else if (arg1 && !arg2) {
|
|
2562
|
+
projectArg = arg1;
|
|
2563
|
+
if (!filePath) {
|
|
2564
|
+
throw new DoorayCliError(
|
|
2565
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --file \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2566
|
+
EXIT_PARAM_ERROR
|
|
2567
|
+
);
|
|
2568
|
+
}
|
|
2569
|
+
} else {
|
|
2570
|
+
projectArg = arg1;
|
|
2571
|
+
postNumberArg = arg2;
|
|
2572
|
+
if (!filePath) {
|
|
2573
|
+
throw new DoorayCliError(
|
|
2574
|
+
"<file-path>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --file \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2575
|
+
EXIT_PARAM_ERROR
|
|
2576
|
+
);
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
if (!filePath) {
|
|
2580
|
+
throw new DoorayCliError("\uD30C\uC77C \uACBD\uB85C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2581
|
+
}
|
|
1786
2582
|
startSpinner("\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC911...");
|
|
1787
|
-
const projectId = await
|
|
1788
|
-
|
|
2583
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2584
|
+
projectArg,
|
|
2585
|
+
postNumberArg,
|
|
2586
|
+
idOpt: opts.id,
|
|
2587
|
+
urlOpt: opts.url
|
|
2588
|
+
});
|
|
1789
2589
|
const res = await client.uploadPostFile(projectId, postId, filePath);
|
|
1790
2590
|
stopSpinner(true, "\uC5C5\uB85C\uB4DC \uC644\uB8CC");
|
|
1791
2591
|
if (globalOpts.json) {
|
|
@@ -1800,13 +2600,53 @@ var fileUploadCommand = new import_commander22.Command("upload").description("\u
|
|
|
1800
2600
|
});
|
|
1801
2601
|
|
|
1802
2602
|
// src/commands/post/file/delete.ts
|
|
1803
|
-
var
|
|
1804
|
-
var fileDeleteCommand = new
|
|
2603
|
+
var import_commander26 = require("commander");
|
|
2604
|
+
var fileDeleteCommand = new import_commander26.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) => {
|
|
1805
2605
|
const config = await getConfigOrThrow();
|
|
1806
2606
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2607
|
+
let projectArg;
|
|
2608
|
+
let postNumberArg;
|
|
2609
|
+
let fileId = opts.fileId;
|
|
2610
|
+
if (opts.id || opts.url) {
|
|
2611
|
+
if (arg2 || arg3) {
|
|
2612
|
+
throw new DoorayCliError(
|
|
2613
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --file-id \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
2614
|
+
EXIT_PARAM_ERROR
|
|
2615
|
+
);
|
|
2616
|
+
}
|
|
2617
|
+
fileId = fileId ?? arg1;
|
|
2618
|
+
} else if (arg3) {
|
|
2619
|
+
projectArg = arg1;
|
|
2620
|
+
postNumberArg = arg2;
|
|
2621
|
+
fileId = fileId ?? arg3;
|
|
2622
|
+
} else if (arg1 && !arg2) {
|
|
2623
|
+
projectArg = arg1;
|
|
2624
|
+
if (!fileId) {
|
|
2625
|
+
throw new DoorayCliError(
|
|
2626
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --file-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2627
|
+
EXIT_PARAM_ERROR
|
|
2628
|
+
);
|
|
2629
|
+
}
|
|
2630
|
+
} else {
|
|
2631
|
+
projectArg = arg1;
|
|
2632
|
+
postNumberArg = arg2;
|
|
2633
|
+
if (!fileId) {
|
|
2634
|
+
throw new DoorayCliError(
|
|
2635
|
+
"<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2636
|
+
EXIT_PARAM_ERROR
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
if (!fileId) {
|
|
2641
|
+
throw new DoorayCliError("\uD30C\uC77C ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2642
|
+
}
|
|
1807
2643
|
startSpinner("\uD30C\uC77C \uC0AD\uC81C \uC911...");
|
|
1808
|
-
const projectId = await
|
|
1809
|
-
|
|
2644
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2645
|
+
projectArg,
|
|
2646
|
+
postNumberArg,
|
|
2647
|
+
idOpt: opts.id,
|
|
2648
|
+
urlOpt: opts.url
|
|
2649
|
+
});
|
|
1810
2650
|
await client.deletePostFile(projectId, postId, fileId);
|
|
1811
2651
|
stopSpinner(true, "\uC0AD\uC81C \uC644\uB8CC");
|
|
1812
2652
|
process.stdout.write(`\uD30C\uC77C(${fileId})\uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
@@ -1814,7 +2654,7 @@ var fileDeleteCommand = new import_commander23.Command("delete").description("\u
|
|
|
1814
2654
|
});
|
|
1815
2655
|
|
|
1816
2656
|
// src/commands/wiki/list.ts
|
|
1817
|
-
var
|
|
2657
|
+
var import_commander27 = require("commander");
|
|
1818
2658
|
|
|
1819
2659
|
// src/formatters/wiki.ts
|
|
1820
2660
|
function formatWikiList(wikis, opts) {
|
|
@@ -1857,7 +2697,7 @@ function formatWikiPageDetail(page, opts) {
|
|
|
1857
2697
|
}
|
|
1858
2698
|
|
|
1859
2699
|
// src/commands/wiki/list.ts
|
|
1860
|
-
var wikiListCommand = new
|
|
2700
|
+
var wikiListCommand = new import_commander27.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) => {
|
|
1861
2701
|
const globalOpts = wikiListCommand.optsWithGlobals();
|
|
1862
2702
|
const config = await getConfigOrThrow();
|
|
1863
2703
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1871,7 +2711,7 @@ var wikiListCommand = new import_commander24.Command("list").description("\uC704
|
|
|
1871
2711
|
});
|
|
1872
2712
|
|
|
1873
2713
|
// src/commands/wiki/pages.ts
|
|
1874
|
-
var
|
|
2714
|
+
var import_commander28 = require("commander");
|
|
1875
2715
|
|
|
1876
2716
|
// src/resolvers/wiki.ts
|
|
1877
2717
|
async function resolveWiki(client, projectCode) {
|
|
@@ -1915,7 +2755,7 @@ async function resolveWikiHomePageId(client, wikiId) {
|
|
|
1915
2755
|
}
|
|
1916
2756
|
|
|
1917
2757
|
// src/commands/wiki/pages.ts
|
|
1918
|
-
var wikiPagesCommand = new
|
|
2758
|
+
var wikiPagesCommand = new import_commander28.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) => {
|
|
1919
2759
|
const globalOpts = wikiPagesCommand.optsWithGlobals();
|
|
1920
2760
|
const config = await getConfigOrThrow();
|
|
1921
2761
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1927,8 +2767,8 @@ var wikiPagesCommand = new import_commander25.Command("pages").description("\uC7
|
|
|
1927
2767
|
});
|
|
1928
2768
|
|
|
1929
2769
|
// src/commands/wiki/page-get.ts
|
|
1930
|
-
var
|
|
1931
|
-
var wikiPageGetCommand = new
|
|
2770
|
+
var import_commander29 = require("commander");
|
|
2771
|
+
var wikiPageGetCommand = new import_commander29.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) => {
|
|
1932
2772
|
const globalOpts = wikiPageGetCommand.optsWithGlobals();
|
|
1933
2773
|
const config = await getConfigOrThrow();
|
|
1934
2774
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1940,8 +2780,8 @@ var wikiPageGetCommand = new import_commander26.Command("get").description("\uC7
|
|
|
1940
2780
|
});
|
|
1941
2781
|
|
|
1942
2782
|
// src/commands/wiki/page-create.ts
|
|
1943
|
-
var
|
|
1944
|
-
var wikiPageCreateCommand = new
|
|
2783
|
+
var import_commander30 = require("commander");
|
|
2784
|
+
var wikiPageCreateCommand = new import_commander30.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) => {
|
|
1945
2785
|
const globalOpts = wikiPageCreateCommand.optsWithGlobals();
|
|
1946
2786
|
const config = await getConfigOrThrow();
|
|
1947
2787
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1966,8 +2806,8 @@ var wikiPageCreateCommand = new import_commander27.Command("create").description
|
|
|
1966
2806
|
});
|
|
1967
2807
|
|
|
1968
2808
|
// src/commands/wiki/page-edit.ts
|
|
1969
|
-
var
|
|
1970
|
-
var wikiPageEditCommand = new
|
|
2809
|
+
var import_commander31 = require("commander");
|
|
2810
|
+
var wikiPageEditCommand = new import_commander31.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) => {
|
|
1971
2811
|
const config = await getConfigOrThrow();
|
|
1972
2812
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1973
2813
|
const hasTitle = opts.title != null;
|
|
@@ -2019,8 +2859,73 @@ var wikiPageEditCommand = new import_commander28.Command("edit").description("\u
|
|
|
2019
2859
|
`);
|
|
2020
2860
|
});
|
|
2021
2861
|
|
|
2862
|
+
// src/commands/member/index.ts
|
|
2863
|
+
var import_commander34 = require("commander");
|
|
2864
|
+
|
|
2865
|
+
// src/commands/member/get.ts
|
|
2866
|
+
var import_commander32 = require("commander");
|
|
2867
|
+
|
|
2868
|
+
// src/formatters/member.ts
|
|
2869
|
+
function formatMemberDetail(member, opts) {
|
|
2870
|
+
if (opts.json) {
|
|
2871
|
+
printJson(member);
|
|
2872
|
+
return;
|
|
2873
|
+
}
|
|
2874
|
+
if (opts.quiet) {
|
|
2875
|
+
process.stdout.write(member.id + "\n");
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
const lines = [
|
|
2879
|
+
`\uC774\uB984: ${member.name}`,
|
|
2880
|
+
...member.englishName ? [`\uC601\uBB38\uBA85: ${member.englishName}`] : [],
|
|
2881
|
+
...member.nickname ? [`\uBCC4\uBA85: ${member.nickname}`] : [],
|
|
2882
|
+
...member.userCode ? [`\uC0AC\uBC88/ID: ${member.userCode}`] : [],
|
|
2883
|
+
...member.externalEmailAddress ? [`\uC678\uBD80 \uC774\uBA54\uC77C: ${member.externalEmailAddress}`] : [],
|
|
2884
|
+
`member-id: ${member.id}`
|
|
2885
|
+
];
|
|
2886
|
+
process.stdout.write(lines.join("\n") + "\n");
|
|
2887
|
+
}
|
|
2888
|
+
function formatMemberList(rows, opts) {
|
|
2889
|
+
output(opts, {
|
|
2890
|
+
headers: ["ID", "Name", "Role"],
|
|
2891
|
+
rows: rows.map((r) => [r.id, r.name, r.role ?? ""]),
|
|
2892
|
+
raw: rows,
|
|
2893
|
+
ids: rows.map((r) => r.id)
|
|
2894
|
+
});
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
// src/commands/member/get.ts
|
|
2898
|
+
var memberGetCommand = new import_commander32.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
|
+
const globalOpts = memberGetCommand.optsWithGlobals();
|
|
2900
|
+
const config = await getConfigOrThrow();
|
|
2901
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2902
|
+
const res = await client.getMemberDetail(memberId);
|
|
2903
|
+
formatMemberDetail(res.result, globalOpts);
|
|
2904
|
+
});
|
|
2905
|
+
|
|
2906
|
+
// src/commands/member/list.ts
|
|
2907
|
+
var import_commander33 = require("commander");
|
|
2908
|
+
var memberListCommand = new import_commander33.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
|
+
const globalOpts = memberListCommand.optsWithGlobals();
|
|
2910
|
+
const config = await getConfigOrThrow();
|
|
2911
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2912
|
+
startSpinner("\uBA64\uBC84 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
2913
|
+
const projectId = await resolveProject(client, project);
|
|
2914
|
+
const members = await ensureMembers(client, projectId);
|
|
2915
|
+
stopSpinner(true, `${members.length}\uBA85`);
|
|
2916
|
+
formatMemberList(
|
|
2917
|
+
members.map((m) => ({ id: m.organizationMemberId, name: m.name })),
|
|
2918
|
+
globalOpts
|
|
2919
|
+
);
|
|
2920
|
+
});
|
|
2921
|
+
|
|
2922
|
+
// src/commands/member/index.ts
|
|
2923
|
+
var memberCommand = new import_commander34.Command("member").description("Dooray \uBA64\uBC84 \uC870\uD68C");
|
|
2924
|
+
memberCommand.addCommand(memberGetCommand);
|
|
2925
|
+
memberCommand.addCommand(memberListCommand);
|
|
2926
|
+
|
|
2022
2927
|
// src/commands/mail/list.ts
|
|
2023
|
-
var
|
|
2928
|
+
var import_commander35 = require("commander");
|
|
2024
2929
|
|
|
2025
2930
|
// src/api/imapClient.ts
|
|
2026
2931
|
var import_imapflow = require("imapflow");
|
|
@@ -2128,7 +3033,7 @@ async function getMail(config, uid) {
|
|
|
2128
3033
|
|
|
2129
3034
|
// src/commands/mail/list.ts
|
|
2130
3035
|
var import_chalk5 = __toESM(require("chalk"));
|
|
2131
|
-
var mailListCommand = new
|
|
3036
|
+
var mailListCommand = new import_commander35.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) => {
|
|
2132
3037
|
const globalOpts = mailListCommand.optsWithGlobals();
|
|
2133
3038
|
const config = await getConfigOrThrow();
|
|
2134
3039
|
startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
|
|
@@ -2160,9 +3065,9 @@ var mailListCommand = new import_commander29.Command("list").description("\uBA54
|
|
|
2160
3065
|
});
|
|
2161
3066
|
|
|
2162
3067
|
// src/commands/mail/get.ts
|
|
2163
|
-
var
|
|
3068
|
+
var import_commander36 = require("commander");
|
|
2164
3069
|
var import_chalk6 = __toESM(require("chalk"));
|
|
2165
|
-
var mailGetCommand = new
|
|
3070
|
+
var mailGetCommand = new import_commander36.Command("get").description("\uBA54\uC77C \uC0C1\uC138 \uC870\uD68C").argument("<uid>", "\uBA54\uC77C UID").action(async (uid) => {
|
|
2166
3071
|
const globalOpts = mailGetCommand.optsWithGlobals();
|
|
2167
3072
|
const config = await getConfigOrThrow();
|
|
2168
3073
|
startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
|
|
@@ -2193,7 +3098,7 @@ ${mail.body}
|
|
|
2193
3098
|
});
|
|
2194
3099
|
|
|
2195
3100
|
// src/commands/mail/send.ts
|
|
2196
|
-
var
|
|
3101
|
+
var import_commander37 = require("commander");
|
|
2197
3102
|
var import_promises10 = require("fs/promises");
|
|
2198
3103
|
|
|
2199
3104
|
// src/api/smtpClient.ts
|
|
@@ -2243,7 +3148,7 @@ async function sendMail(config, opts) {
|
|
|
2243
3148
|
}
|
|
2244
3149
|
|
|
2245
3150
|
// src/commands/mail/send.ts
|
|
2246
|
-
var mailSendCommand = new
|
|
3151
|
+
var mailSendCommand = new import_commander37.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) => {
|
|
2247
3152
|
const globalOpts = mailSendCommand.optsWithGlobals();
|
|
2248
3153
|
const config = await getConfigOrThrow();
|
|
2249
3154
|
let body = opts.body ?? "";
|
|
@@ -2278,7 +3183,7 @@ var mailSendCommand = new import_commander31.Command("send").description("\uBA54
|
|
|
2278
3183
|
});
|
|
2279
3184
|
|
|
2280
3185
|
// src/commands/mail/reply.ts
|
|
2281
|
-
var
|
|
3186
|
+
var import_commander38 = require("commander");
|
|
2282
3187
|
var import_promises11 = require("fs/promises");
|
|
2283
3188
|
var import_imapflow2 = require("imapflow");
|
|
2284
3189
|
async function getMessageId(config, uid) {
|
|
@@ -2306,7 +3211,7 @@ async function getMessageId(config, uid) {
|
|
|
2306
3211
|
await client.logout();
|
|
2307
3212
|
}
|
|
2308
3213
|
}
|
|
2309
|
-
var mailReplyCommand = new
|
|
3214
|
+
var mailReplyCommand = new import_commander38.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) => {
|
|
2310
3215
|
const globalOpts = mailReplyCommand.optsWithGlobals();
|
|
2311
3216
|
const config = await getConfigOrThrow();
|
|
2312
3217
|
let body = opts.body ?? "";
|
|
@@ -2346,20 +3251,201 @@ var mailReplyCommand = new import_commander32.Command("reply").description("\uBA
|
|
|
2346
3251
|
}
|
|
2347
3252
|
});
|
|
2348
3253
|
|
|
3254
|
+
// src/commands/feedback.ts
|
|
3255
|
+
var import_commander39 = require("commander");
|
|
3256
|
+
var import_node_child_process2 = require("child_process");
|
|
3257
|
+
var import_node_util = require("util");
|
|
3258
|
+
var import_promises13 = require("fs/promises");
|
|
3259
|
+
var import_node_os3 = require("os");
|
|
3260
|
+
var import_node_path8 = require("path");
|
|
3261
|
+
var import_node_crypto = require("crypto");
|
|
3262
|
+
var import_prompts = require("@inquirer/prompts");
|
|
3263
|
+
|
|
3264
|
+
// src/utils/feedback-meta.ts
|
|
3265
|
+
var import_promises12 = require("fs/promises");
|
|
3266
|
+
var import_node_path7 = require("path");
|
|
3267
|
+
async function readCliVersion() {
|
|
3268
|
+
const entry = process.argv[1];
|
|
3269
|
+
const here = entry ? (0, import_node_path7.dirname)(entry) : process.cwd();
|
|
3270
|
+
const candidates = [
|
|
3271
|
+
(0, import_node_path7.join)(here, "package.json"),
|
|
3272
|
+
(0, import_node_path7.join)(here, "..", "package.json"),
|
|
3273
|
+
(0, import_node_path7.join)(here, "..", "..", "package.json")
|
|
3274
|
+
];
|
|
3275
|
+
for (const p of candidates) {
|
|
3276
|
+
try {
|
|
3277
|
+
const raw = await (0, import_promises12.readFile)(p, "utf-8");
|
|
3278
|
+
const pkg = JSON.parse(raw);
|
|
3279
|
+
if (pkg.name === "@bifos/dooray-cli" && typeof pkg.version === "string") {
|
|
3280
|
+
return pkg.version;
|
|
3281
|
+
}
|
|
3282
|
+
} catch {
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
return "unknown";
|
|
3286
|
+
}
|
|
3287
|
+
function collectMeta(version) {
|
|
3288
|
+
return {
|
|
3289
|
+
cliVersion: version,
|
|
3290
|
+
nodeVersion: process.version,
|
|
3291
|
+
os: process.platform,
|
|
3292
|
+
arch: process.arch
|
|
3293
|
+
};
|
|
3294
|
+
}
|
|
3295
|
+
function buildIssueBody(userBody, meta) {
|
|
3296
|
+
return [
|
|
3297
|
+
"## \uD658\uACBD",
|
|
3298
|
+
`- dooray-cli \uBC84\uC804: ${meta.cliVersion}`,
|
|
3299
|
+
`- Node: ${meta.nodeVersion}`,
|
|
3300
|
+
`- OS: ${meta.os} ${meta.arch}`,
|
|
3301
|
+
"",
|
|
3302
|
+
"## \uC0AC\uC6A9\uC790 \uD53C\uB4DC\uBC31",
|
|
3303
|
+
"",
|
|
3304
|
+
userBody.trim(),
|
|
3305
|
+
""
|
|
3306
|
+
].join("\n");
|
|
3307
|
+
}
|
|
3308
|
+
|
|
3309
|
+
// src/commands/feedback.ts
|
|
3310
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
3311
|
+
var TARGET_REPO = "jon890/dooray-cli";
|
|
3312
|
+
async function ensureGhInstalled() {
|
|
3313
|
+
try {
|
|
3314
|
+
await execFileAsync("gh", ["--version"]);
|
|
3315
|
+
} catch {
|
|
3316
|
+
throw new DoorayCliError(
|
|
3317
|
+
"gh CLI\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n \uC124\uCE58: brew install gh (\uB610\uB294 https://cli.github.com)\n \uC124\uCE58 \uD6C4: gh auth login",
|
|
3318
|
+
EXIT_PARAM_ERROR
|
|
3319
|
+
);
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
async function readBody(opts) {
|
|
3323
|
+
if (opts.body) return opts.body;
|
|
3324
|
+
if (opts.bodyFile) return await (0, import_promises13.readFile)(opts.bodyFile, "utf-8");
|
|
3325
|
+
return void 0;
|
|
3326
|
+
}
|
|
3327
|
+
var feedbackCommand = new import_commander39.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
|
+
"--label <name>",
|
|
3329
|
+
"\uB77C\uBCA8 (\uBC18\uBCF5 \uAC00\uB2A5)",
|
|
3330
|
+
(value, prev) => [...prev, value],
|
|
3331
|
+
[]
|
|
3332
|
+
).option("--dry-run", "gh \uD638\uCD9C \uC5C6\uC774 \uBCF8\uBB38\uB9CC \uBBF8\uB9AC\uBCF4\uAE30").action(async (opts) => {
|
|
3333
|
+
let title = opts.title;
|
|
3334
|
+
let userBody = await readBody(opts);
|
|
3335
|
+
let labels = [...opts.label];
|
|
3336
|
+
if (!title) {
|
|
3337
|
+
title = await (0, import_prompts.input)({ message: "\uC774\uC288 \uC81C\uBAA9" });
|
|
3338
|
+
}
|
|
3339
|
+
if (!title || !title.trim()) {
|
|
3340
|
+
throw new DoorayCliError("\uC81C\uBAA9\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
3341
|
+
}
|
|
3342
|
+
if (labels.length === 0 && !opts.title && !opts.body && !opts.bodyFile) {
|
|
3343
|
+
const labelInput = await (0, import_prompts.input)({
|
|
3344
|
+
message: "\uB77C\uBCA8 (\uCF64\uB9C8\uB85C \uC5EC\uB7EC \uAC1C, \uBE44\uC6B0\uBA74 \uC5C6\uC74C)",
|
|
3345
|
+
default: ""
|
|
3346
|
+
});
|
|
3347
|
+
labels = labelInput.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3348
|
+
}
|
|
3349
|
+
if (userBody == null) {
|
|
3350
|
+
userBody = await (0, import_prompts.editor)({
|
|
3351
|
+
message: "\uBCF8\uBB38 \uC791\uC131 ($EDITOR\uAC00 \uC5F4\uB9BC)",
|
|
3352
|
+
default: ""
|
|
3353
|
+
});
|
|
3354
|
+
}
|
|
3355
|
+
if (!userBody.trim()) {
|
|
3356
|
+
throw new DoorayCliError("\uBCF8\uBB38\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
3357
|
+
}
|
|
3358
|
+
const version = await readCliVersion();
|
|
3359
|
+
const meta = collectMeta(version);
|
|
3360
|
+
const issueBody = buildIssueBody(userBody, meta);
|
|
3361
|
+
if (opts.dryRun) {
|
|
3362
|
+
process.stdout.write("--- DRY RUN ---\n");
|
|
3363
|
+
process.stdout.write(`Repo: ${TARGET_REPO}
|
|
3364
|
+
`);
|
|
3365
|
+
process.stdout.write(`Title: ${title}
|
|
3366
|
+
`);
|
|
3367
|
+
process.stdout.write(
|
|
3368
|
+
`Labels: ${labels.length > 0 ? labels.join(", ") : "(\uC5C6\uC74C)"}
|
|
3369
|
+
`
|
|
3370
|
+
);
|
|
3371
|
+
process.stdout.write("Body:\n");
|
|
3372
|
+
process.stdout.write(issueBody);
|
|
3373
|
+
process.stdout.write("--- END ---\n");
|
|
3374
|
+
return;
|
|
3375
|
+
}
|
|
3376
|
+
const isInteractive = !opts.title;
|
|
3377
|
+
if (isInteractive) {
|
|
3378
|
+
process.stderr.write("\n--- \uBBF8\uB9AC\uBCF4\uAE30 ---\n");
|
|
3379
|
+
process.stderr.write(`Repo: ${TARGET_REPO}
|
|
3380
|
+
`);
|
|
3381
|
+
process.stderr.write(`Title: ${title}
|
|
3382
|
+
`);
|
|
3383
|
+
process.stderr.write(
|
|
3384
|
+
`Labels: ${labels.length > 0 ? labels.join(", ") : "(\uC5C6\uC74C)"}
|
|
3385
|
+
`
|
|
3386
|
+
);
|
|
3387
|
+
process.stderr.write("Body:\n");
|
|
3388
|
+
process.stderr.write(issueBody);
|
|
3389
|
+
process.stderr.write("--- \uB05D ---\n\n");
|
|
3390
|
+
const ok = await (0, import_prompts.confirm)({
|
|
3391
|
+
message: "\uC774 \uB0B4\uC6A9\uC73C\uB85C \uB4F1\uB85D\uD560\uAE4C\uC694?",
|
|
3392
|
+
default: true
|
|
3393
|
+
});
|
|
3394
|
+
if (!ok) {
|
|
3395
|
+
process.stderr.write("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n");
|
|
3396
|
+
return;
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
await ensureGhInstalled();
|
|
3400
|
+
const bodyFile = (0, import_node_path8.join)((0, import_node_os3.tmpdir)(), `dooray-feedback-${(0, import_node_crypto.randomUUID)()}.md`);
|
|
3401
|
+
await (0, import_promises13.writeFile)(bodyFile, issueBody);
|
|
3402
|
+
try {
|
|
3403
|
+
const args = [
|
|
3404
|
+
"issue",
|
|
3405
|
+
"create",
|
|
3406
|
+
"--repo",
|
|
3407
|
+
TARGET_REPO,
|
|
3408
|
+
"--title",
|
|
3409
|
+
title,
|
|
3410
|
+
"--body-file",
|
|
3411
|
+
bodyFile
|
|
3412
|
+
];
|
|
3413
|
+
for (const l of labels) {
|
|
3414
|
+
args.push("--label", l);
|
|
3415
|
+
}
|
|
3416
|
+
const { stdout } = await execFileAsync("gh", args);
|
|
3417
|
+
process.stdout.write(stdout);
|
|
3418
|
+
} catch (err) {
|
|
3419
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3420
|
+
throw new DoorayCliError(
|
|
3421
|
+
`GitHub issue \uC0DD\uC131 \uC2E4\uD328:
|
|
3422
|
+
${msg}
|
|
3423
|
+
|
|
3424
|
+
gh \uC778\uC99D \uC548 \uB418\uC5B4 \uC788\uC73C\uBA74: gh auth login`,
|
|
3425
|
+
EXIT_PARAM_ERROR
|
|
3426
|
+
);
|
|
3427
|
+
} finally {
|
|
3428
|
+
await (0, import_promises13.unlink)(bodyFile).catch(() => {
|
|
3429
|
+
});
|
|
3430
|
+
}
|
|
3431
|
+
});
|
|
3432
|
+
|
|
2349
3433
|
// src/index.ts
|
|
2350
|
-
var program = new
|
|
2351
|
-
program.name("dooray").description("Dooray REST API CLI").version("0.5.
|
|
3434
|
+
var program = new import_commander40.Command();
|
|
3435
|
+
program.name("dooray").description("Dooray REST API CLI").version("0.5.4").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "ID\uB9CC \uCD9C\uB825").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654");
|
|
2352
3436
|
program.hook("preAction", () => {
|
|
2353
3437
|
const opts = program.opts();
|
|
2354
3438
|
if (opts.color === false || process.env.NO_COLOR) {
|
|
2355
3439
|
import_chalk7.default.level = 0;
|
|
2356
3440
|
}
|
|
2357
3441
|
});
|
|
2358
|
-
var projectCommand = new
|
|
3442
|
+
var projectCommand = new import_commander40.Command("project").description("\uD504\uB85C\uC81D\uD2B8 \uAD00\uB828 \uBA85\uB839");
|
|
2359
3443
|
projectCommand.addCommand(projectListCommand);
|
|
2360
3444
|
projectCommand.addCommand(projectMembersCommand);
|
|
2361
3445
|
projectCommand.addCommand(projectWorkflowsCommand);
|
|
2362
|
-
|
|
3446
|
+
projectCommand.addCommand(projectGroupsCommand);
|
|
3447
|
+
projectCommand.addCommand(projectTagsCommand);
|
|
3448
|
+
var postCommand = new import_commander40.Command("post").description("\uC5C5\uBB34 \uAD00\uB828 \uBA85\uB839");
|
|
2363
3449
|
postCommand.addCommand(postListCommand);
|
|
2364
3450
|
postCommand.addCommand(postSearchCommand);
|
|
2365
3451
|
postCommand.addCommand(postGetCommand);
|
|
@@ -2367,40 +3453,43 @@ postCommand.addCommand(postEditCommand);
|
|
|
2367
3453
|
postCommand.addCommand(postCreateCommand);
|
|
2368
3454
|
postCommand.addCommand(postDoneCommand);
|
|
2369
3455
|
postCommand.addCommand(postWorkflowCommand);
|
|
2370
|
-
var commentCommand = new
|
|
3456
|
+
var commentCommand = new import_commander40.Command("comment").description("\uB313\uAE00 \uAD00\uB828 \uBA85\uB839");
|
|
2371
3457
|
commentCommand.addCommand(commentListCommand);
|
|
3458
|
+
commentCommand.addCommand(commentLatestCommand);
|
|
2372
3459
|
commentCommand.addCommand(commentAddCommand);
|
|
2373
3460
|
commentCommand.addCommand(commentEditCommand);
|
|
2374
3461
|
commentCommand.addCommand(commentDeleteCommand);
|
|
2375
3462
|
postCommand.addCommand(commentCommand);
|
|
2376
|
-
var fileCommand = new
|
|
3463
|
+
var fileCommand = new import_commander40.Command("file").description("\uCCA8\uBD80\uD30C\uC77C \uAD00\uB828 \uBA85\uB839");
|
|
2377
3464
|
fileCommand.addCommand(fileListCommand);
|
|
2378
3465
|
fileCommand.addCommand(fileDownloadCommand);
|
|
2379
3466
|
fileCommand.addCommand(fileDownloadAllCommand);
|
|
2380
3467
|
fileCommand.addCommand(fileUploadCommand);
|
|
2381
3468
|
fileCommand.addCommand(fileDeleteCommand);
|
|
2382
3469
|
postCommand.addCommand(fileCommand);
|
|
2383
|
-
var wikiCommand = new
|
|
3470
|
+
var wikiCommand = new import_commander40.Command("wiki").description("\uC704\uD0A4 \uAD00\uB828 \uBA85\uB839");
|
|
2384
3471
|
wikiCommand.addCommand(wikiListCommand);
|
|
2385
3472
|
wikiCommand.addCommand(wikiPagesCommand);
|
|
2386
|
-
var wikiPageCommand = new
|
|
3473
|
+
var wikiPageCommand = new import_commander40.Command("page").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uAD00\uB828 \uBA85\uB839");
|
|
2387
3474
|
wikiPageCommand.addCommand(wikiPageGetCommand);
|
|
2388
3475
|
wikiPageCommand.addCommand(wikiPageCreateCommand);
|
|
2389
3476
|
wikiPageCommand.addCommand(wikiPageEditCommand);
|
|
2390
3477
|
wikiCommand.addCommand(wikiPageCommand);
|
|
2391
|
-
var mailCommand = new
|
|
3478
|
+
var mailCommand = new import_commander40.Command("mail").description("\uBA54\uC77C \uAD00\uB828 \uBA85\uB839");
|
|
2392
3479
|
mailCommand.addCommand(mailListCommand);
|
|
2393
3480
|
mailCommand.addCommand(mailGetCommand);
|
|
2394
3481
|
mailCommand.addCommand(mailSendCommand);
|
|
2395
3482
|
mailCommand.addCommand(mailReplyCommand);
|
|
2396
3483
|
program.addCommand(setupCommand);
|
|
2397
3484
|
program.addCommand(configCommand);
|
|
3485
|
+
program.addCommand(memberCommand);
|
|
2398
3486
|
program.addCommand(cacheCommand);
|
|
2399
3487
|
program.addCommand(doctorCommand);
|
|
2400
3488
|
program.addCommand(projectCommand);
|
|
2401
3489
|
program.addCommand(postCommand);
|
|
2402
3490
|
program.addCommand(wikiCommand);
|
|
2403
3491
|
program.addCommand(mailCommand);
|
|
3492
|
+
program.addCommand(feedbackCommand);
|
|
2404
3493
|
program.parseAsync().catch((err) => {
|
|
2405
3494
|
if (err instanceof DoorayCliError) {
|
|
2406
3495
|
process.stderr.write(import_chalk7.default.red(`\uC624\uB958: ${err.message}`) + "\n");
|