@bifos/dooray-cli 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -33
- package/dist/index.js +1315 -231
- package/package.json +2 -2
- package/skills/dooray-cli/SKILL.md +120 -17
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
27
|
+
var import_commander46 = require("commander");
|
|
28
28
|
var import_chalk7 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/commands/config.ts
|
|
@@ -127,10 +127,13 @@ async function setConfigValue(key, value) {
|
|
|
127
127
|
case "smtp-port":
|
|
128
128
|
config.smtpPort = parseInt(value, 10);
|
|
129
129
|
break;
|
|
130
|
+
case "track-last-run":
|
|
131
|
+
config.trackLastRun = value === "true";
|
|
132
|
+
break;
|
|
130
133
|
default:
|
|
131
134
|
throw new DoorayCliError(
|
|
132
135
|
`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${key}
|
|
133
|
-
\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD0A4: api-key, base-url, tenant-name, imap-host, imap-port, imap-username, imap-password, smtp-host, smtp-port`,
|
|
136
|
+
\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD0A4: api-key, base-url, tenant-name, imap-host, imap-port, imap-username, imap-password, smtp-host, smtp-port, track-last-run`,
|
|
134
137
|
EXIT_CONFIG_ERROR
|
|
135
138
|
);
|
|
136
139
|
}
|
|
@@ -200,6 +203,7 @@ var MEMBERS_DIR = (0, import_node_path2.join)(CACHE_DIR, "members");
|
|
|
200
203
|
var WORKFLOWS_DIR = (0, import_node_path2.join)(CACHE_DIR, "workflows");
|
|
201
204
|
var TAGS_DIR = (0, import_node_path2.join)(CACHE_DIR, "tags");
|
|
202
205
|
var MILESTONES_DIR = (0, import_node_path2.join)(CACHE_DIR, "milestones");
|
|
206
|
+
var MEMBER_GROUPS_DIR = (0, import_node_path2.join)(CACHE_DIR, "member-groups");
|
|
203
207
|
var WIKIS_PATH = (0, import_node_path2.join)(CACHE_DIR, "wikis.json");
|
|
204
208
|
async function ensureDir2(dir) {
|
|
205
209
|
await (0, import_promises2.mkdir)(dir, { recursive: true });
|
|
@@ -278,6 +282,15 @@ async function getMilestones(projectId) {
|
|
|
278
282
|
async function setMilestones(projectId, items) {
|
|
279
283
|
await writeJson(milestonesPath(projectId), { updatedAt: now(), data: items });
|
|
280
284
|
}
|
|
285
|
+
function memberGroupsPath(projectId) {
|
|
286
|
+
return (0, import_node_path2.join)(MEMBER_GROUPS_DIR, `${projectId}.json`);
|
|
287
|
+
}
|
|
288
|
+
async function getMemberGroups(projectId) {
|
|
289
|
+
return readJson(memberGroupsPath(projectId));
|
|
290
|
+
}
|
|
291
|
+
async function setMemberGroups(projectId, items) {
|
|
292
|
+
await writeJson(memberGroupsPath(projectId), { updatedAt: now(), data: items });
|
|
293
|
+
}
|
|
281
294
|
async function getWikis() {
|
|
282
295
|
return readJson(WIKIS_PATH);
|
|
283
296
|
}
|
|
@@ -317,8 +330,14 @@ async function getCacheStats() {
|
|
|
317
330
|
milestoneProjectCount = files.filter((f) => f.endsWith(".json")).length;
|
|
318
331
|
} catch {
|
|
319
332
|
}
|
|
333
|
+
let memberGroupProjectCount = 0;
|
|
334
|
+
try {
|
|
335
|
+
const files = await (0, import_promises2.readdir)(MEMBER_GROUPS_DIR);
|
|
336
|
+
memberGroupProjectCount = files.filter((f) => f.endsWith(".json")).length;
|
|
337
|
+
} catch {
|
|
338
|
+
}
|
|
320
339
|
const me = await getMe();
|
|
321
|
-
return { projectCount, memberProjectCount, workflowProjectCount, tagProjectCount, milestoneProjectCount, me: me?.data ?? null };
|
|
340
|
+
return { projectCount, memberProjectCount, workflowProjectCount, tagProjectCount, milestoneProjectCount, memberGroupProjectCount, me: me?.data ?? null };
|
|
322
341
|
}
|
|
323
342
|
|
|
324
343
|
// src/commands/cache.ts
|
|
@@ -509,6 +528,13 @@ var DoorayApiClient = class {
|
|
|
509
528
|
return toDoorayCliError(e);
|
|
510
529
|
}
|
|
511
530
|
}
|
|
531
|
+
async getPostComment(projectId, postId, logId) {
|
|
532
|
+
try {
|
|
533
|
+
return await this.api.get(`project/v1/projects/${projectId}/posts/${postId}/logs/${logId}`).json();
|
|
534
|
+
} catch (e) {
|
|
535
|
+
return toDoorayCliError(e);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
512
538
|
async createPostComment(projectId, postId, body) {
|
|
513
539
|
try {
|
|
514
540
|
return await this.api.post(`project/v1/projects/${projectId}/posts/${postId}/logs`, { json: body }).json();
|
|
@@ -551,6 +577,23 @@ var DoorayApiClient = class {
|
|
|
551
577
|
return toDoorayCliError(e);
|
|
552
578
|
}
|
|
553
579
|
}
|
|
580
|
+
async searchMembers(params) {
|
|
581
|
+
try {
|
|
582
|
+
return await this.api.get("common/v1/members", {
|
|
583
|
+
searchParams: {
|
|
584
|
+
...params.name && { name: params.name },
|
|
585
|
+
...params.externalEmailAddresses && { externalEmailAddresses: params.externalEmailAddresses },
|
|
586
|
+
...params.userCode && { userCode: params.userCode },
|
|
587
|
+
...params.userCodeExact && { userCodeExact: params.userCodeExact },
|
|
588
|
+
...params.idProviderUserId && { idProviderUserId: params.idProviderUserId },
|
|
589
|
+
...params.page != null && { page: params.page },
|
|
590
|
+
...params.size != null && { size: params.size }
|
|
591
|
+
}
|
|
592
|
+
}).json();
|
|
593
|
+
} catch (e) {
|
|
594
|
+
return toDoorayCliError(e);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
554
597
|
// ─── Workflows ──────────────────────────────────────
|
|
555
598
|
async getProjectWorkflows(projectId) {
|
|
556
599
|
try {
|
|
@@ -572,6 +615,19 @@ var DoorayApiClient = class {
|
|
|
572
615
|
return toDoorayCliError(e);
|
|
573
616
|
}
|
|
574
617
|
}
|
|
618
|
+
// ─── Member Groups ──────────────────────────────────
|
|
619
|
+
async getProjectMemberGroups(projectId, params) {
|
|
620
|
+
try {
|
|
621
|
+
return await this.api.get(`project/v1/projects/${projectId}/member-groups`, {
|
|
622
|
+
searchParams: {
|
|
623
|
+
...params?.page != null && { page: params.page },
|
|
624
|
+
...params?.size != null && { size: params.size }
|
|
625
|
+
}
|
|
626
|
+
}).json();
|
|
627
|
+
} catch (e) {
|
|
628
|
+
return toDoorayCliError(e);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
575
631
|
// ─── Milestones ─────────────────────────────────────
|
|
576
632
|
async getProjectMilestones(projectId, params) {
|
|
577
633
|
try {
|
|
@@ -745,18 +801,30 @@ var ME_TTL_MS = 864e5;
|
|
|
745
801
|
var TAGS_TTL_MS = 864e5;
|
|
746
802
|
var MILESTONES_TTL_MS = 864e5;
|
|
747
803
|
var RESOLVER_FETCH_PAGE_SIZE = 100;
|
|
804
|
+
var MEMBER_GROUPS_TTL_MS = 864e5;
|
|
748
805
|
var WIKIS_TTL_MS = 864e5;
|
|
749
806
|
|
|
750
807
|
// src/resolvers/me.ts
|
|
751
808
|
async function ensureMe(client) {
|
|
752
809
|
const entry = await getMe();
|
|
753
|
-
if (entry && !isExpired(entry.updatedAt, ME_TTL_MS)) {
|
|
810
|
+
if (entry && !isExpired(entry.updatedAt, ME_TTL_MS) && entry.data.orgId) {
|
|
754
811
|
return entry.data;
|
|
755
812
|
}
|
|
756
813
|
const res = await client.getMe();
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
|
|
814
|
+
const orgId = res.result.defaultOrganization?.id ?? "";
|
|
815
|
+
if (!orgId) {
|
|
816
|
+
throw new DoorayCliError(
|
|
817
|
+
"orgId\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (getMe \uC751\uB2F5\uC5D0 defaultOrganization.id \uB204\uB77D). dooray cache clear \uD6C4 \uC7AC\uC2DC\uB3C4\uD558\uC138\uC694.",
|
|
818
|
+
EXIT_PARAM_ERROR
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
const cached = {
|
|
822
|
+
id: res.result.id,
|
|
823
|
+
name: res.result.name,
|
|
824
|
+
orgId
|
|
825
|
+
};
|
|
826
|
+
await setMe(cached);
|
|
827
|
+
return cached;
|
|
760
828
|
}
|
|
761
829
|
|
|
762
830
|
// src/commands/doctor.ts
|
|
@@ -787,6 +855,7 @@ var doctorCommand = new import_commander3.Command("doctor").description("\uC124\
|
|
|
787
855
|
console.log(` \uC6CC\uD06C\uD50C\uB85C\uC6B0: ${stats.workflowProjectCount}\uAC1C \uD504\uB85C\uC81D\uD2B8`);
|
|
788
856
|
console.log(` Tag \uCE90\uC2DC (\uD504\uB85C\uC81D\uD2B8 \uC218): ${stats.tagProjectCount}`);
|
|
789
857
|
console.log(` Milestone \uCE90\uC2DC (\uD504\uB85C\uC81D\uD2B8 \uC218): ${stats.milestoneProjectCount}`);
|
|
858
|
+
console.log(` Member Group \uCE90\uC2DC (\uD504\uB85C\uC81D\uD2B8 \uC218): ${stats.memberGroupProjectCount}`);
|
|
790
859
|
const claudeDir = import_path.default.join(
|
|
791
860
|
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
792
861
|
".claude"
|
|
@@ -832,10 +901,10 @@ var import_chalk4 = __toESM(require("chalk"));
|
|
|
832
901
|
var import_path2 = __toESM(require("path"));
|
|
833
902
|
var import_promises5 = __toESM(require("fs/promises"));
|
|
834
903
|
var setupCommand = new import_commander4.Command("setup").description("\uB300\uD654\uD615 \uCD08\uAE30 \uC124\uC815 \uB9C8\uBC95\uC0AC").action(async () => {
|
|
835
|
-
const { input, select, password, confirm } = await import("@inquirer/prompts");
|
|
904
|
+
const { input: input2, select, password, confirm: confirm2 } = await import("@inquirer/prompts");
|
|
836
905
|
const existing = await getConfig();
|
|
837
906
|
try {
|
|
838
|
-
const tenantName = await
|
|
907
|
+
const tenantName = await input2({
|
|
839
908
|
message: "\uD14C\uB10C\uD2B8\uBA85\uC744 \uC785\uB825\uD558\uC138\uC694",
|
|
840
909
|
default: existing?.tenantName ?? DEFAULTS.tenantName,
|
|
841
910
|
theme: { prefix: "\u{1F3E2}" }
|
|
@@ -884,7 +953,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
884
953
|
);
|
|
885
954
|
}
|
|
886
955
|
}
|
|
887
|
-
const useMail = await
|
|
956
|
+
const useMail = await confirm2({
|
|
888
957
|
message: "\uBA54\uC77C \uAE30\uB2A5\uC744 \uC0AC\uC6A9\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
889
958
|
default: !!existing?.imapUsername,
|
|
890
959
|
theme: { prefix: "\u{1F4E7}" }
|
|
@@ -892,7 +961,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
892
961
|
let imapUsername;
|
|
893
962
|
let imapPassword;
|
|
894
963
|
if (useMail) {
|
|
895
|
-
imapUsername = await
|
|
964
|
+
imapUsername = await input2({
|
|
896
965
|
message: `IMAP \uC0AC\uC6A9\uC790 \uC774\uBA54\uC77C (\uD655\uC778: https://${tenantName}.dooray.com/setting/mail/general/read)`,
|
|
897
966
|
default: existing?.imapUsername,
|
|
898
967
|
theme: { prefix: "\u{1F4E8}" }
|
|
@@ -917,7 +986,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
917
986
|
)
|
|
918
987
|
);
|
|
919
988
|
} else {
|
|
920
|
-
const installSkill = await
|
|
989
|
+
const installSkill = await confirm2({
|
|
921
990
|
message: "Claude Code \uC2A4\uD0AC\uC744 \uC124\uCE58\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
922
991
|
default: true,
|
|
923
992
|
theme: { prefix: "\u{1F527}" }
|
|
@@ -942,6 +1011,11 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
942
1011
|
}
|
|
943
1012
|
}
|
|
944
1013
|
}
|
|
1014
|
+
const trackLastRun = await confirm2({
|
|
1015
|
+
message: "feedback --last \uBAA8\uB4DC \uD65C\uC131\uD654 (\uC9C1\uC804 \uBA85\uB839 \uC5D0\uB7EC\uB97C GitHub issue\uC5D0 \uC790\uB3D9 \uCCA8\uBD80)?",
|
|
1016
|
+
default: false,
|
|
1017
|
+
theme: { prefix: "\u{1F4CB}" }
|
|
1018
|
+
});
|
|
945
1019
|
const config = {
|
|
946
1020
|
version: 1,
|
|
947
1021
|
apiKey,
|
|
@@ -954,6 +1028,7 @@ var setupCommand = new import_commander4.Command("setup").description("\uB300\uD
|
|
|
954
1028
|
smtpHost: useMail ? DEFAULTS.smtpHost : existing?.smtpHost,
|
|
955
1029
|
smtpPort: useMail ? DEFAULTS.smtpPort : existing?.smtpPort
|
|
956
1030
|
};
|
|
1031
|
+
config.trackLastRun = trackLastRun;
|
|
957
1032
|
await saveConfig(config);
|
|
958
1033
|
console.log(
|
|
959
1034
|
import_chalk4.default.green(
|
|
@@ -1009,17 +1084,17 @@ async function ensurePrivateProjects(client) {
|
|
|
1009
1084
|
await setPrivateProjects(items);
|
|
1010
1085
|
return items;
|
|
1011
1086
|
}
|
|
1012
|
-
async function resolveProject(client,
|
|
1087
|
+
async function resolveProject(client, input2) {
|
|
1013
1088
|
const projects = await ensureProjects(client);
|
|
1014
|
-
const match = projects.find((p) => p.code ===
|
|
1089
|
+
const match = projects.find((p) => p.code === input2 || p.id === input2);
|
|
1015
1090
|
if (match) return match.id;
|
|
1016
1091
|
const privateCached = await getPrivateProjects();
|
|
1017
1092
|
if (privateCached && !isExpired(privateCached.updatedAt, PROJECTS_TTL_MS)) {
|
|
1018
|
-
const privateMatch = privateCached.data.find((p) => p.code ===
|
|
1093
|
+
const privateMatch = privateCached.data.find((p) => p.code === input2 || p.id === input2);
|
|
1019
1094
|
if (privateMatch) return privateMatch.id;
|
|
1020
1095
|
}
|
|
1021
1096
|
throw new DoorayCliError(
|
|
1022
|
-
`\uD504\uB85C\uC81D\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
1097
|
+
`\uD504\uB85C\uC81D\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input2}
|
|
1023
1098
|
\uAC1C\uC778 \uD504\uB85C\uC81D\uD2B8\uB77C\uBA74: dooray project list --type private \uB85C \uCE90\uC2DC\uB97C \uAC31\uC2E0\uD558\uC138\uC694`,
|
|
1024
1099
|
EXIT_PARAM_ERROR
|
|
1025
1100
|
);
|
|
@@ -1053,17 +1128,29 @@ function output(opts, data) {
|
|
|
1053
1128
|
// src/utils/spinner.ts
|
|
1054
1129
|
var import_ora = __toESM(require("ora"));
|
|
1055
1130
|
var current = null;
|
|
1131
|
+
var quiet = false;
|
|
1132
|
+
var noopSpinner = new Proxy({}, {
|
|
1133
|
+
get(_target, prop) {
|
|
1134
|
+
if (prop === "text" || prop === "prefixText" || prop === "suffixText") return "";
|
|
1135
|
+
if (prop === "isSpinning") return false;
|
|
1136
|
+
return () => noopSpinner;
|
|
1137
|
+
},
|
|
1138
|
+
set() {
|
|
1139
|
+
return true;
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
function setQuiet(value) {
|
|
1143
|
+
quiet = value;
|
|
1144
|
+
}
|
|
1056
1145
|
function startSpinner(text) {
|
|
1146
|
+
if (quiet) return noopSpinner;
|
|
1057
1147
|
current = (0, import_ora.default)({ text, stream: process.stderr }).start();
|
|
1058
1148
|
return current;
|
|
1059
1149
|
}
|
|
1060
1150
|
function stopSpinner(success, text) {
|
|
1061
1151
|
if (!current) return;
|
|
1062
|
-
if (success === false)
|
|
1063
|
-
|
|
1064
|
-
} else {
|
|
1065
|
-
current.succeed(text);
|
|
1066
|
-
}
|
|
1152
|
+
if (success === false) current.fail(text);
|
|
1153
|
+
else current.succeed(text);
|
|
1067
1154
|
current = null;
|
|
1068
1155
|
}
|
|
1069
1156
|
|
|
@@ -1095,27 +1182,27 @@ var projectListCommand = new import_commander5.Command("list").description("\uD5
|
|
|
1095
1182
|
var import_commander6 = require("commander");
|
|
1096
1183
|
|
|
1097
1184
|
// src/resolvers/match.ts
|
|
1098
|
-
function matchByName(items,
|
|
1099
|
-
const exact = items.filter((i) => i.name ===
|
|
1185
|
+
function matchByName(items, input2, label, renderCandidate) {
|
|
1186
|
+
const exact = items.filter((i) => i.name === input2);
|
|
1100
1187
|
if (exact.length === 1) return exact[0];
|
|
1101
1188
|
if (exact.length > 1) {
|
|
1102
1189
|
throw new DoorayCliError(
|
|
1103
|
-
`\uBCF5\uC218\uC758 ${label}\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4(\uC815\uD655\uC77C\uCE58): "${
|
|
1190
|
+
`\uBCF5\uC218\uC758 ${label}\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4(\uC815\uD655\uC77C\uCE58): "${input2}"
|
|
1104
1191
|
` + exact.map((i) => ` - ${renderCandidate(i)}`).join("\n"),
|
|
1105
1192
|
EXIT_PARAM_ERROR
|
|
1106
1193
|
);
|
|
1107
1194
|
}
|
|
1108
|
-
const partial = items.filter((i) => i.name.includes(
|
|
1195
|
+
const partial = items.filter((i) => i.name.includes(input2));
|
|
1109
1196
|
if (partial.length === 1) return partial[0];
|
|
1110
1197
|
if (partial.length > 1) {
|
|
1111
1198
|
throw new DoorayCliError(
|
|
1112
|
-
`\uBCF5\uC218\uC758 ${label}\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4: "${
|
|
1199
|
+
`\uBCF5\uC218\uC758 ${label}\uAC00 \uB9E4\uCE6D\uB429\uB2C8\uB2E4: "${input2}"
|
|
1113
1200
|
` + partial.map((i) => ` - ${renderCandidate(i)}`).join("\n"),
|
|
1114
1201
|
EXIT_PARAM_ERROR
|
|
1115
1202
|
);
|
|
1116
1203
|
}
|
|
1117
1204
|
throw new DoorayCliError(
|
|
1118
|
-
`${label}\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
1205
|
+
`${label}\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input2}`,
|
|
1119
1206
|
EXIT_PARAM_ERROR
|
|
1120
1207
|
);
|
|
1121
1208
|
}
|
|
@@ -1169,11 +1256,11 @@ async function buildMemberNameMap(client, projectId) {
|
|
|
1169
1256
|
}
|
|
1170
1257
|
return map;
|
|
1171
1258
|
}
|
|
1172
|
-
async function resolveMember(client, projectId,
|
|
1259
|
+
async function resolveMember(client, projectId, input2) {
|
|
1173
1260
|
const members = await ensureMembers(client, projectId);
|
|
1174
1261
|
const match = matchByName(
|
|
1175
1262
|
members,
|
|
1176
|
-
|
|
1263
|
+
input2,
|
|
1177
1264
|
"\uBA64\uBC84",
|
|
1178
1265
|
(m) => `${m.name} (${m.organizationMemberId})`
|
|
1179
1266
|
);
|
|
@@ -1219,17 +1306,17 @@ async function ensureWorkflows(client, projectId) {
|
|
|
1219
1306
|
await setWorkflows(projectId, items);
|
|
1220
1307
|
return items;
|
|
1221
1308
|
}
|
|
1222
|
-
async function resolveWorkflow(client, projectId,
|
|
1309
|
+
async function resolveWorkflow(client, projectId, input2) {
|
|
1223
1310
|
const workflows = await ensureWorkflows(client, projectId);
|
|
1224
|
-
const byClass = workflows.filter((w) => w.class ===
|
|
1311
|
+
const byClass = workflows.filter((w) => w.class === input2);
|
|
1225
1312
|
if (byClass.length === 1) return byClass[0].id;
|
|
1226
1313
|
if (byClass.length > 1) {
|
|
1227
1314
|
throw new DoorayCliError(
|
|
1228
|
-
`\uB3D9\uC77C class\uC758 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5EC\uB7EC \uAC1C\uC785\uB2C8\uB2E4: "${
|
|
1315
|
+
`\uB3D9\uC77C class\uC758 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5EC\uB7EC \uAC1C\uC785\uB2C8\uB2E4: "${input2}"`,
|
|
1229
1316
|
EXIT_PARAM_ERROR
|
|
1230
1317
|
);
|
|
1231
1318
|
}
|
|
1232
|
-
const match = matchByName(workflows,
|
|
1319
|
+
const match = matchByName(workflows, input2, "\uC6CC\uD06C\uD50C\uB85C\uC6B0", (w) => `${w.name} [${w.class}] (${w.id})`);
|
|
1233
1320
|
return match.id;
|
|
1234
1321
|
}
|
|
1235
1322
|
|
|
@@ -1255,9 +1342,194 @@ var projectWorkflowsCommand = new import_commander7.Command("workflows").descrip
|
|
|
1255
1342
|
});
|
|
1256
1343
|
});
|
|
1257
1344
|
|
|
1258
|
-
// src/commands/
|
|
1345
|
+
// src/commands/project/groups.ts
|
|
1259
1346
|
var import_commander8 = require("commander");
|
|
1260
1347
|
|
|
1348
|
+
// src/resolvers/member-group.ts
|
|
1349
|
+
async function fetchAllMemberGroups(client, projectId) {
|
|
1350
|
+
const all = [];
|
|
1351
|
+
let page = 0;
|
|
1352
|
+
const size = RESOLVER_FETCH_PAGE_SIZE;
|
|
1353
|
+
while (true) {
|
|
1354
|
+
const res = await client.getProjectMemberGroups(projectId, { page, size });
|
|
1355
|
+
for (const g of res.result) {
|
|
1356
|
+
all.push({ id: g.id, code: g.code });
|
|
1357
|
+
}
|
|
1358
|
+
const total = res.totalCount ?? all.length;
|
|
1359
|
+
if (all.length >= total) break;
|
|
1360
|
+
page++;
|
|
1361
|
+
}
|
|
1362
|
+
return all;
|
|
1363
|
+
}
|
|
1364
|
+
async function ensureMemberGroups(client, projectId) {
|
|
1365
|
+
const entry = await getMemberGroups(projectId);
|
|
1366
|
+
if (entry && !isExpired(entry.updatedAt, MEMBER_GROUPS_TTL_MS)) return entry.data;
|
|
1367
|
+
const items = await fetchAllMemberGroups(client, projectId);
|
|
1368
|
+
await setMemberGroups(projectId, items);
|
|
1369
|
+
return items;
|
|
1370
|
+
}
|
|
1371
|
+
async function resolveMemberGroup(client, projectId, input2) {
|
|
1372
|
+
const groups = await ensureMemberGroups(client, projectId);
|
|
1373
|
+
const adapter = groups.map((g) => ({ name: g.code, id: g.id, code: g.code }));
|
|
1374
|
+
const match = matchByName(adapter, input2, "\uADF8\uB8F9", (g) => `${g.code} (${g.id})`);
|
|
1375
|
+
return { id: match.id, code: match.code };
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// src/commands/project/groups.ts
|
|
1379
|
+
var projectGroupsCommand = new import_commander8.Command("groups").description("\uD504\uB85C\uC81D\uD2B8 \uBA64\uBC84 \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
|
|
1380
|
+
const globalOpts = projectGroupsCommand.optsWithGlobals();
|
|
1381
|
+
const config = await getConfigOrThrow();
|
|
1382
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1383
|
+
startSpinner("\uBA64\uBC84 \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1384
|
+
const projectId = await resolveProject(client, project);
|
|
1385
|
+
const groups = await ensureMemberGroups(client, projectId);
|
|
1386
|
+
stopSpinner(true, "\uBA64\uBC84 \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC644\uB8CC");
|
|
1387
|
+
output(globalOpts, {
|
|
1388
|
+
headers: ["ID", "Code"],
|
|
1389
|
+
rows: groups.map((g) => [g.id, g.code]),
|
|
1390
|
+
raw: groups,
|
|
1391
|
+
ids: groups.map((g) => g.id)
|
|
1392
|
+
});
|
|
1393
|
+
});
|
|
1394
|
+
|
|
1395
|
+
// src/commands/project/tags.ts
|
|
1396
|
+
var import_commander9 = require("commander");
|
|
1397
|
+
|
|
1398
|
+
// src/resolvers/tag.ts
|
|
1399
|
+
async function fetchAllTags(client, projectId) {
|
|
1400
|
+
const all = [];
|
|
1401
|
+
let page = 0;
|
|
1402
|
+
const size = RESOLVER_FETCH_PAGE_SIZE;
|
|
1403
|
+
while (true) {
|
|
1404
|
+
const res = await client.getProjectTags(projectId, { page, size });
|
|
1405
|
+
for (const t of res.result) {
|
|
1406
|
+
all.push({
|
|
1407
|
+
id: t.id,
|
|
1408
|
+
name: t.name ?? "",
|
|
1409
|
+
color: t.color ?? "",
|
|
1410
|
+
groupId: t.tagGroup?.id ?? null,
|
|
1411
|
+
groupName: t.tagGroup?.name ?? null,
|
|
1412
|
+
groupMandatory: t.tagGroup?.mandatory ?? false,
|
|
1413
|
+
groupSelectOne: t.tagGroup?.selectOne ?? false
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
const total = res.totalCount ?? all.length;
|
|
1417
|
+
if (all.length >= total) break;
|
|
1418
|
+
page++;
|
|
1419
|
+
}
|
|
1420
|
+
return all;
|
|
1421
|
+
}
|
|
1422
|
+
async function ensureTags(client, projectId) {
|
|
1423
|
+
const entry = await getTags(projectId);
|
|
1424
|
+
if (entry && !isExpired(entry.updatedAt, TAGS_TTL_MS)) return entry.data;
|
|
1425
|
+
const items = await fetchAllTags(client, projectId);
|
|
1426
|
+
await setTags(projectId, items);
|
|
1427
|
+
return items;
|
|
1428
|
+
}
|
|
1429
|
+
function buildMandatoryHint(allTags, missingGroupIds) {
|
|
1430
|
+
const lines = [];
|
|
1431
|
+
for (const groupId of missingGroupIds) {
|
|
1432
|
+
const groupTags = allTags.filter((t) => t.groupId === groupId);
|
|
1433
|
+
const groupName = groupTags[0]?.groupName ?? groupId;
|
|
1434
|
+
const candidates = groupTags.map((t) => t.name).join(", ");
|
|
1435
|
+
lines.push(` - "${groupName}": ${candidates || "(\uD0DC\uADF8 \uC5C6\uC74C)"}`);
|
|
1436
|
+
}
|
|
1437
|
+
return lines.join("\n");
|
|
1438
|
+
}
|
|
1439
|
+
async function validateMandatoryTags(client, projectId) {
|
|
1440
|
+
const allTags = await ensureTags(client, projectId);
|
|
1441
|
+
const missingGroupIds = [];
|
|
1442
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1443
|
+
for (const t of allTags) {
|
|
1444
|
+
if (t.groupMandatory && t.groupId && !seen.has(t.groupId)) {
|
|
1445
|
+
seen.add(t.groupId);
|
|
1446
|
+
missingGroupIds.push(t.groupId);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
if (missingGroupIds.length === 0) return;
|
|
1450
|
+
throw new DoorayCliError(
|
|
1451
|
+
`\uD544\uC218 \uD0DC\uADF8 \uADF8\uB8F9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (\uADF8\uB8F9\uB2F9 1\uAC1C \uC774\uC0C1 \uD544\uC694):
|
|
1452
|
+
` + buildMandatoryHint(allTags, missingGroupIds) + `
|
|
1453
|
+
|
|
1454
|
+
\uB2E4\uC2DC \uC2DC\uB3C4: --tag "<\uADF8\uB8F9>: <\uD6C4\uBCF4>" \uD615\uC2DD\uC73C\uB85C \uCD94\uAC00`,
|
|
1455
|
+
EXIT_PARAM_ERROR
|
|
1456
|
+
);
|
|
1457
|
+
}
|
|
1458
|
+
async function resolveTags(client, projectId, inputs) {
|
|
1459
|
+
const allTags = await ensureTags(client, projectId);
|
|
1460
|
+
const selected = inputs.map(
|
|
1461
|
+
(input2) => matchByName(
|
|
1462
|
+
allTags,
|
|
1463
|
+
input2,
|
|
1464
|
+
"\uD0DC\uADF8",
|
|
1465
|
+
(t) => t.groupName ? `${t.groupName} / ${t.name} (${t.id})` : `${t.name} (${t.id})`
|
|
1466
|
+
)
|
|
1467
|
+
);
|
|
1468
|
+
const mandatoryGroups = /* @__PURE__ */ new Map();
|
|
1469
|
+
for (const t of allTags) {
|
|
1470
|
+
if (t.groupMandatory && t.groupId) mandatoryGroups.set(t.groupId, t.groupName ?? t.groupId);
|
|
1471
|
+
}
|
|
1472
|
+
const coveredGroups = new Set(selected.map((t) => t.groupId).filter((g) => !!g));
|
|
1473
|
+
const missingIds = [];
|
|
1474
|
+
for (const [gid] of mandatoryGroups) {
|
|
1475
|
+
if (!coveredGroups.has(gid)) missingIds.push(gid);
|
|
1476
|
+
}
|
|
1477
|
+
if (missingIds.length > 0) {
|
|
1478
|
+
throw new DoorayCliError(
|
|
1479
|
+
`\uD544\uC218 \uD0DC\uADF8 \uADF8\uB8F9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (\uADF8\uB8F9\uB2F9 1\uAC1C \uC774\uC0C1 \uD544\uC694):
|
|
1480
|
+
` + buildMandatoryHint(allTags, missingIds),
|
|
1481
|
+
EXIT_PARAM_ERROR
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
const selectOneGroups = /* @__PURE__ */ new Map();
|
|
1485
|
+
for (const t of selected) {
|
|
1486
|
+
if (!t.groupSelectOne || !t.groupId) continue;
|
|
1487
|
+
const entry = selectOneGroups.get(t.groupId) ?? { name: t.groupName ?? t.groupId, tags: [] };
|
|
1488
|
+
entry.tags.push(t.name);
|
|
1489
|
+
selectOneGroups.set(t.groupId, entry);
|
|
1490
|
+
}
|
|
1491
|
+
const violators = [];
|
|
1492
|
+
for (const [, info] of selectOneGroups) {
|
|
1493
|
+
if (info.tags.length > 1) {
|
|
1494
|
+
violators.push(`${info.name} (\uC120\uD0DD: ${info.tags.join(", ")})`);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (violators.length > 0) {
|
|
1498
|
+
throw new DoorayCliError(
|
|
1499
|
+
`\uB2E4\uC74C \uD0DC\uADF8 \uADF8\uB8F9\uC740 1\uAC1C\uB9CC \uC120\uD0DD \uAC00\uB2A5\uD569\uB2C8\uB2E4:
|
|
1500
|
+
` + violators.map((v) => ` - ${v}`).join("\n"),
|
|
1501
|
+
EXIT_PARAM_ERROR
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
return selected.map((t) => t.id);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// src/commands/project/tags.ts
|
|
1508
|
+
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) => {
|
|
1509
|
+
const globalOpts = projectTagsCommand.optsWithGlobals();
|
|
1510
|
+
const config = await getConfigOrThrow();
|
|
1511
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1512
|
+
startSpinner("\uD0DC\uADF8 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1513
|
+
const projectId = await resolveProject(client, project);
|
|
1514
|
+
const tags = await ensureTags(client, projectId);
|
|
1515
|
+
stopSpinner(true, "\uD0DC\uADF8 \uBAA9\uB85D \uC870\uD68C \uC644\uB8CC");
|
|
1516
|
+
output(globalOpts, {
|
|
1517
|
+
headers: ["ID", "Color", "Name", "Group", "Mandatory"],
|
|
1518
|
+
rows: tags.map((t) => [
|
|
1519
|
+
t.id,
|
|
1520
|
+
t.color,
|
|
1521
|
+
t.name,
|
|
1522
|
+
t.groupName ?? "",
|
|
1523
|
+
t.groupMandatory ? "Y" : ""
|
|
1524
|
+
]),
|
|
1525
|
+
raw: tags,
|
|
1526
|
+
ids: tags.map((t) => t.id)
|
|
1527
|
+
});
|
|
1528
|
+
});
|
|
1529
|
+
|
|
1530
|
+
// src/commands/post/list.ts
|
|
1531
|
+
var import_commander10 = require("commander");
|
|
1532
|
+
|
|
1261
1533
|
// src/formatters/post.ts
|
|
1262
1534
|
function formatPostList(posts, opts) {
|
|
1263
1535
|
output(opts, {
|
|
@@ -1307,7 +1579,7 @@ function formatCommentList(comments, opts) {
|
|
|
1307
1579
|
}
|
|
1308
1580
|
|
|
1309
1581
|
// src/commands/post/list.ts
|
|
1310
|
-
var postListCommand = new
|
|
1582
|
+
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) => {
|
|
1311
1583
|
const globalOpts = postListCommand.optsWithGlobals();
|
|
1312
1584
|
const config = await getConfigOrThrow();
|
|
1313
1585
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1341,8 +1613,8 @@ var postListCommand = new import_commander8.Command("list").description("\uC5C5\
|
|
|
1341
1613
|
});
|
|
1342
1614
|
|
|
1343
1615
|
// src/commands/post/search.ts
|
|
1344
|
-
var
|
|
1345
|
-
var postSearchCommand = new
|
|
1616
|
+
var import_commander11 = require("commander");
|
|
1617
|
+
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) => {
|
|
1346
1618
|
const globalOpts = postSearchCommand.optsWithGlobals();
|
|
1347
1619
|
const config = await getConfigOrThrow();
|
|
1348
1620
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1354,7 +1626,7 @@ var postSearchCommand = new import_commander9.Command("search").description("\uC
|
|
|
1354
1626
|
});
|
|
1355
1627
|
|
|
1356
1628
|
// src/commands/post/get.ts
|
|
1357
|
-
var
|
|
1629
|
+
var import_commander12 = require("commander");
|
|
1358
1630
|
|
|
1359
1631
|
// src/resolvers/post.ts
|
|
1360
1632
|
async function resolvePost(client, projectId, postNumber) {
|
|
@@ -1372,12 +1644,16 @@ async function resolvePost(client, projectId, postNumber) {
|
|
|
1372
1644
|
|
|
1373
1645
|
// src/utils/dooray-url.ts
|
|
1374
1646
|
var TASK_URL_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/to\/(\d+)(?:[/?#].*)?$/;
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1647
|
+
var TASK_URL_ALT_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/(?:\d+)\/(\d+)(?:[/?#].*)?$/;
|
|
1648
|
+
function parseDoorayTaskUrl(input2) {
|
|
1649
|
+
const m1 = TASK_URL_RE.exec(input2);
|
|
1650
|
+
if (m1) return m1[1];
|
|
1651
|
+
const m2 = TASK_URL_ALT_RE.exec(input2);
|
|
1652
|
+
if (m2) return m2[1];
|
|
1653
|
+
return null;
|
|
1378
1654
|
}
|
|
1379
|
-
function isLikelyDoorayUrl(
|
|
1380
|
-
return /^https?:\/\//.test(
|
|
1655
|
+
function isLikelyDoorayUrl(input2) {
|
|
1656
|
+
return /^https?:\/\//.test(input2);
|
|
1381
1657
|
}
|
|
1382
1658
|
|
|
1383
1659
|
// src/resolvers/post-input.ts
|
|
@@ -1448,7 +1724,7 @@ async function resolvePostInput(client, args) {
|
|
|
1448
1724
|
}
|
|
1449
1725
|
|
|
1450
1726
|
// src/commands/post/get.ts
|
|
1451
|
-
var postGetCommand = new
|
|
1727
|
+
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) => {
|
|
1452
1728
|
const globalOpts = postGetCommand.optsWithGlobals();
|
|
1453
1729
|
const config = await getConfigOrThrow();
|
|
1454
1730
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1465,7 +1741,7 @@ var postGetCommand = new import_commander10.Command("get").description("\uC5C5\u
|
|
|
1465
1741
|
});
|
|
1466
1742
|
|
|
1467
1743
|
// src/commands/post/edit.ts
|
|
1468
|
-
var
|
|
1744
|
+
var import_commander13 = require("commander");
|
|
1469
1745
|
|
|
1470
1746
|
// src/editor/index.ts
|
|
1471
1747
|
var import_node_child_process = require("child_process");
|
|
@@ -1473,8 +1749,8 @@ var import_promises6 = __toESM(require("fs/promises"));
|
|
|
1473
1749
|
var import_tmp = __toESM(require("tmp"));
|
|
1474
1750
|
var import_js_yaml = __toESM(require("js-yaml"));
|
|
1475
1751
|
function openInEditor(content) {
|
|
1476
|
-
const
|
|
1477
|
-
if (!
|
|
1752
|
+
const editor2 = process.env.EDITOR;
|
|
1753
|
+
if (!editor2) {
|
|
1478
1754
|
throw new DoorayCliError(
|
|
1479
1755
|
"$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.",
|
|
1480
1756
|
EXIT_PARAM_ERROR
|
|
@@ -1484,7 +1760,7 @@ function openInEditor(content) {
|
|
|
1484
1760
|
return new Promise(async (resolve, reject) => {
|
|
1485
1761
|
try {
|
|
1486
1762
|
await import_promises6.default.writeFile(tmpFile.name, content, "utf-8");
|
|
1487
|
-
const child = (0, import_node_child_process.spawn)(
|
|
1763
|
+
const child = (0, import_node_child_process.spawn)(editor2, [tmpFile.name], {
|
|
1488
1764
|
stdio: "inherit"
|
|
1489
1765
|
});
|
|
1490
1766
|
child.on("error", (err) => {
|
|
@@ -1635,7 +1911,7 @@ async function resolveUsers(client, projectId, emails) {
|
|
|
1635
1911
|
}
|
|
1636
1912
|
return users;
|
|
1637
1913
|
}
|
|
1638
|
-
var postEditCommand = new
|
|
1914
|
+
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) => {
|
|
1639
1915
|
const config = await getConfigOrThrow();
|
|
1640
1916
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1641
1917
|
startSpinner("\uC5C5\uBB34 \uC870\uD68C \uC911...");
|
|
@@ -1709,86 +1985,7 @@ var postEditCommand = new import_commander11.Command("edit").description("\uC5C5
|
|
|
1709
1985
|
});
|
|
1710
1986
|
|
|
1711
1987
|
// src/commands/post/create.ts
|
|
1712
|
-
var
|
|
1713
|
-
|
|
1714
|
-
// src/resolvers/tag.ts
|
|
1715
|
-
async function fetchAllTags(client, projectId) {
|
|
1716
|
-
const all = [];
|
|
1717
|
-
let page = 0;
|
|
1718
|
-
const size = RESOLVER_FETCH_PAGE_SIZE;
|
|
1719
|
-
while (true) {
|
|
1720
|
-
const res = await client.getProjectTags(projectId, { page, size });
|
|
1721
|
-
for (const t of res.result) {
|
|
1722
|
-
all.push({
|
|
1723
|
-
id: t.id,
|
|
1724
|
-
name: t.name ?? "",
|
|
1725
|
-
groupId: t.tagGroup?.id ?? null,
|
|
1726
|
-
groupName: t.tagGroup?.name ?? null,
|
|
1727
|
-
groupMandatory: t.tagGroup?.mandatory ?? false,
|
|
1728
|
-
groupSelectOne: t.tagGroup?.selectOne ?? false
|
|
1729
|
-
});
|
|
1730
|
-
}
|
|
1731
|
-
const total = res.totalCount ?? all.length;
|
|
1732
|
-
if (all.length >= total) break;
|
|
1733
|
-
page++;
|
|
1734
|
-
}
|
|
1735
|
-
return all;
|
|
1736
|
-
}
|
|
1737
|
-
async function ensureTags(client, projectId) {
|
|
1738
|
-
const entry = await getTags(projectId);
|
|
1739
|
-
if (entry && !isExpired(entry.updatedAt, TAGS_TTL_MS)) return entry.data;
|
|
1740
|
-
const items = await fetchAllTags(client, projectId);
|
|
1741
|
-
await setTags(projectId, items);
|
|
1742
|
-
return items;
|
|
1743
|
-
}
|
|
1744
|
-
async function resolveTags(client, projectId, inputs) {
|
|
1745
|
-
const allTags = await ensureTags(client, projectId);
|
|
1746
|
-
const selected = inputs.map(
|
|
1747
|
-
(input) => matchByName(
|
|
1748
|
-
allTags,
|
|
1749
|
-
input,
|
|
1750
|
-
"\uD0DC\uADF8",
|
|
1751
|
-
(t) => t.groupName ? `${t.groupName} / ${t.name} (${t.id})` : `${t.name} (${t.id})`
|
|
1752
|
-
)
|
|
1753
|
-
);
|
|
1754
|
-
const mandatoryGroups = /* @__PURE__ */ new Map();
|
|
1755
|
-
for (const t of allTags) {
|
|
1756
|
-
if (t.groupMandatory && t.groupId) mandatoryGroups.set(t.groupId, t.groupName ?? t.groupId);
|
|
1757
|
-
}
|
|
1758
|
-
const coveredGroups = new Set(selected.map((t) => t.groupId).filter((g) => !!g));
|
|
1759
|
-
const missing = [];
|
|
1760
|
-
for (const [gid, gname] of mandatoryGroups) {
|
|
1761
|
-
if (!coveredGroups.has(gid)) missing.push(gname);
|
|
1762
|
-
}
|
|
1763
|
-
if (missing.length > 0) {
|
|
1764
|
-
throw new DoorayCliError(
|
|
1765
|
-
`\uD544\uC218 \uD0DC\uADF8 \uADF8\uB8F9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (\uADF8\uB8F9\uB2F9 1\uAC1C \uC774\uC0C1 \uD544\uC694):
|
|
1766
|
-
` + missing.map((g) => ` - ${g}`).join("\n"),
|
|
1767
|
-
EXIT_PARAM_ERROR
|
|
1768
|
-
);
|
|
1769
|
-
}
|
|
1770
|
-
const selectOneGroups = /* @__PURE__ */ new Map();
|
|
1771
|
-
for (const t of selected) {
|
|
1772
|
-
if (!t.groupSelectOne || !t.groupId) continue;
|
|
1773
|
-
const entry = selectOneGroups.get(t.groupId) ?? { name: t.groupName ?? t.groupId, tags: [] };
|
|
1774
|
-
entry.tags.push(t.name);
|
|
1775
|
-
selectOneGroups.set(t.groupId, entry);
|
|
1776
|
-
}
|
|
1777
|
-
const violators = [];
|
|
1778
|
-
for (const [, info] of selectOneGroups) {
|
|
1779
|
-
if (info.tags.length > 1) {
|
|
1780
|
-
violators.push(`${info.name} (\uC120\uD0DD: ${info.tags.join(", ")})`);
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
if (violators.length > 0) {
|
|
1784
|
-
throw new DoorayCliError(
|
|
1785
|
-
`\uB2E4\uC74C \uD0DC\uADF8 \uADF8\uB8F9\uC740 1\uAC1C\uB9CC \uC120\uD0DD \uAC00\uB2A5\uD569\uB2C8\uB2E4:
|
|
1786
|
-
` + violators.map((v) => ` - ${v}`).join("\n"),
|
|
1787
|
-
EXIT_PARAM_ERROR
|
|
1788
|
-
);
|
|
1789
|
-
}
|
|
1790
|
-
return selected.map((t) => t.id);
|
|
1791
|
-
}
|
|
1988
|
+
var import_commander14 = require("commander");
|
|
1792
1989
|
|
|
1793
1990
|
// src/resolvers/milestone.ts
|
|
1794
1991
|
async function fetchAllMilestones(client, projectId) {
|
|
@@ -1811,9 +2008,9 @@ async function ensureMilestones(client, projectId) {
|
|
|
1811
2008
|
await setMilestones(projectId, items);
|
|
1812
2009
|
return items;
|
|
1813
2010
|
}
|
|
1814
|
-
async function resolveMilestone(client, projectId,
|
|
2011
|
+
async function resolveMilestone(client, projectId, input2) {
|
|
1815
2012
|
const all = await ensureMilestones(client, projectId);
|
|
1816
|
-
const match = matchByName(all,
|
|
2013
|
+
const match = matchByName(all, input2, "\uB9C8\uC77C\uC2A4\uD1A4", (m) => `${m.name} (${m.id})`);
|
|
1817
2014
|
return match.id;
|
|
1818
2015
|
}
|
|
1819
2016
|
|
|
@@ -1837,13 +2034,13 @@ async function resolvePostRef(client, ref) {
|
|
|
1837
2034
|
// src/commands/post/create.ts
|
|
1838
2035
|
async function resolveUsers2(client, projectId, inputs) {
|
|
1839
2036
|
const users = [];
|
|
1840
|
-
for (const
|
|
1841
|
-
const memberId = await resolveMember(client, projectId,
|
|
2037
|
+
for (const input2 of inputs) {
|
|
2038
|
+
const memberId = await resolveMember(client, projectId, input2);
|
|
1842
2039
|
users.push({ type: "member", member: { organizationMemberId: memberId } });
|
|
1843
2040
|
}
|
|
1844
2041
|
return users;
|
|
1845
2042
|
}
|
|
1846
|
-
var postCreateCommand = new
|
|
2043
|
+
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) => {
|
|
1847
2044
|
const globalOpts = postCreateCommand.optsWithGlobals();
|
|
1848
2045
|
const config = await getConfigOrThrow();
|
|
1849
2046
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -1866,7 +2063,7 @@ var postCreateCommand = new import_commander12.Command("create").description("\u
|
|
|
1866
2063
|
const ccUsers = opts.cc ? await resolveUsers2(client, projectId, opts.cc) : [];
|
|
1867
2064
|
const tagInputs = (opts.tag ?? []).filter((s) => s.length > 0);
|
|
1868
2065
|
const [tagIds, parentPostId, milestoneId] = await Promise.all([
|
|
1869
|
-
tagInputs.length > 0 ? resolveTags(client, projectId, tagInputs) :
|
|
2066
|
+
tagInputs.length > 0 ? resolveTags(client, projectId, tagInputs) : validateMandatoryTags(client, projectId).then(() => void 0),
|
|
1870
2067
|
opts.parent ? resolvePostRef(client, opts.parent) : Promise.resolve(void 0),
|
|
1871
2068
|
opts.milestone ? resolveMilestone(client, projectId, opts.milestone) : Promise.resolve(void 0)
|
|
1872
2069
|
]);
|
|
@@ -1902,8 +2099,8 @@ var postCreateCommand = new import_commander12.Command("create").description("\u
|
|
|
1902
2099
|
});
|
|
1903
2100
|
|
|
1904
2101
|
// src/commands/post/done.ts
|
|
1905
|
-
var
|
|
1906
|
-
var postDoneCommand = new
|
|
2102
|
+
var import_commander15 = require("commander");
|
|
2103
|
+
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) => {
|
|
1907
2104
|
const config = await getConfigOrThrow();
|
|
1908
2105
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1909
2106
|
startSpinner("\uC5C5\uBB34 \uC644\uB8CC \uCC98\uB9AC \uC911...");
|
|
@@ -1920,8 +2117,8 @@ var postDoneCommand = new import_commander13.Command("done").description("\uC5C5
|
|
|
1920
2117
|
});
|
|
1921
2118
|
|
|
1922
2119
|
// src/commands/post/workflow.ts
|
|
1923
|
-
var
|
|
1924
|
-
var postWorkflowCommand = new
|
|
2120
|
+
var import_commander16 = require("commander");
|
|
2121
|
+
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) => {
|
|
1925
2122
|
const config = await getConfigOrThrow();
|
|
1926
2123
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
1927
2124
|
let workflowInput = opts.workflow;
|
|
@@ -1961,7 +2158,7 @@ var postWorkflowCommand = new import_commander14.Command("workflow").description
|
|
|
1961
2158
|
});
|
|
1962
2159
|
|
|
1963
2160
|
// src/commands/post/comment/list.ts
|
|
1964
|
-
var
|
|
2161
|
+
var import_commander17 = require("commander");
|
|
1965
2162
|
|
|
1966
2163
|
// src/utils/comment-enrich.ts
|
|
1967
2164
|
function enrichCommentCreators(comments, nameMap) {
|
|
@@ -1982,23 +2179,150 @@ function enrichCommentCreators(comments, nameMap) {
|
|
|
1982
2179
|
}
|
|
1983
2180
|
|
|
1984
2181
|
// src/commands/post/comment/list.ts
|
|
1985
|
-
var
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
const
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
2182
|
+
var PAGE_DEFAULT = "0";
|
|
2183
|
+
var SIZE_DEFAULT = "20";
|
|
2184
|
+
function parseSinceDate(input2) {
|
|
2185
|
+
const d = new Date(input2);
|
|
2186
|
+
if (isNaN(d.getTime())) {
|
|
2187
|
+
throw new DoorayCliError(
|
|
2188
|
+
`--since \uAC12\uC744 \uD30C\uC2F1\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: "${input2}" (ISO 8601 \uB610\uB294 YYYY-MM-DD)`,
|
|
2189
|
+
EXIT_PARAM_ERROR
|
|
2190
|
+
);
|
|
2191
|
+
}
|
|
2192
|
+
return d;
|
|
2193
|
+
}
|
|
2194
|
+
function validateExclusive(opts) {
|
|
2195
|
+
function err(msg) {
|
|
2196
|
+
return new DoorayCliError(msg, EXIT_PARAM_ERROR);
|
|
2197
|
+
}
|
|
2198
|
+
if (opts.latest) {
|
|
2199
|
+
if (opts.page && opts.page !== PAGE_DEFAULT) throw err("--latest\uC640 --page\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2200
|
+
if (opts.size && opts.size !== SIZE_DEFAULT) throw err("--latest\uC640 --size\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2201
|
+
if (opts.sort && opts.sort !== "asc") throw err("--latest\uC640 --sort\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2202
|
+
if (opts.reverse) throw err("--latest\uC640 --reverse\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2203
|
+
if (opts.since) throw err("--latest\uC640 --since\uB294 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2204
|
+
}
|
|
2205
|
+
if (opts.reverse && opts.sort && opts.sort !== "asc") {
|
|
2206
|
+
throw err("--reverse\uC640 --sort \uC635\uC158\uC740 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00");
|
|
2207
|
+
}
|
|
2208
|
+
if (opts.sort && opts.sort !== "asc" && opts.sort !== "desc") {
|
|
2209
|
+
throw err(`--sort\uB294 asc \uB610\uB294 desc\uB9CC \uD5C8\uC6A9\uD569\uB2C8\uB2E4: "${opts.sort}"`);
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
function resolveOrder(opts) {
|
|
2213
|
+
if (opts.reverse) return "-createdAt";
|
|
2214
|
+
if (opts.sort === "desc") return "-createdAt";
|
|
2215
|
+
return "createdAt";
|
|
2216
|
+
}
|
|
2217
|
+
async function fetchSince(client, projectId, postId, sinceDate) {
|
|
2218
|
+
const sinceMs = sinceDate.getTime();
|
|
2219
|
+
const collected = [];
|
|
2220
|
+
let page = 0;
|
|
2221
|
+
const size = 100;
|
|
2222
|
+
while (true) {
|
|
2223
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2224
|
+
page,
|
|
2225
|
+
size,
|
|
2226
|
+
order: "-createdAt"
|
|
2227
|
+
});
|
|
2228
|
+
const pageItems = res.result;
|
|
2229
|
+
const survivors = pageItems.filter((c) => new Date(c.createdAt).getTime() >= sinceMs);
|
|
2230
|
+
collected.push(...survivors);
|
|
2231
|
+
const hasOlder = pageItems.length > survivors.length;
|
|
2232
|
+
if (hasOlder) break;
|
|
2233
|
+
if (pageItems.length < size) break;
|
|
2234
|
+
page++;
|
|
2235
|
+
}
|
|
2236
|
+
return collected;
|
|
2237
|
+
}
|
|
2238
|
+
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) => {
|
|
2239
|
+
const globalOpts = commentListCommand.optsWithGlobals();
|
|
2240
|
+
const config = await getConfigOrThrow();
|
|
2241
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2242
|
+
validateExclusive(opts);
|
|
2243
|
+
if (opts.latest) {
|
|
2244
|
+
const n = Number(opts.latest);
|
|
2245
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
2246
|
+
throw new DoorayCliError("--latest\uB294 \uC591\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2247
|
+
}
|
|
2248
|
+
if (n > 100) {
|
|
2249
|
+
throw new DoorayCliError("--latest\uB294 \uCD5C\uB300 100\uAE4C\uC9C0 \uC9C0\uC6D0\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
const sinceDate = opts.since ? parseSinceDate(opts.since) : null;
|
|
2253
|
+
startSpinner("\uB313\uAE00 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
2254
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2255
|
+
projectArg: project,
|
|
2256
|
+
postNumberArg: postNumberStr,
|
|
2257
|
+
idOpt: opts.id,
|
|
2258
|
+
urlOpt: opts.url
|
|
2259
|
+
});
|
|
2260
|
+
const order = resolveOrder(opts);
|
|
2261
|
+
let comments;
|
|
2262
|
+
if (opts.latest) {
|
|
2263
|
+
const n = Number(opts.latest);
|
|
2264
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2265
|
+
page: 0,
|
|
2266
|
+
size: n,
|
|
2267
|
+
order: "-createdAt"
|
|
2268
|
+
});
|
|
2269
|
+
comments = res.result;
|
|
2270
|
+
} else if (sinceDate) {
|
|
2271
|
+
comments = await fetchSince(client, projectId, postId, sinceDate);
|
|
2272
|
+
if (order === "createdAt") comments = [...comments].reverse();
|
|
2273
|
+
} else {
|
|
2274
|
+
const res = await client.getPostComments(projectId, postId, {
|
|
2275
|
+
page: Number(opts.page),
|
|
2276
|
+
size: Number(opts.size),
|
|
2277
|
+
order
|
|
2278
|
+
});
|
|
2279
|
+
comments = res.result;
|
|
2280
|
+
}
|
|
2281
|
+
stopSpinner(true, "\uB313\uAE00 \uBAA9\uB85D \uC870\uD68C \uC644\uB8CC");
|
|
2282
|
+
if (opts.fromAuthor) {
|
|
2283
|
+
const memberId = await resolveMember(client, projectId, opts.fromAuthor);
|
|
2284
|
+
comments = comments.filter(
|
|
2285
|
+
(c) => c.creator?.member?.organizationMemberId === memberId
|
|
2286
|
+
);
|
|
2287
|
+
}
|
|
2288
|
+
if (!globalOpts.json) {
|
|
2289
|
+
let nameMap = /* @__PURE__ */ new Map();
|
|
2290
|
+
try {
|
|
2291
|
+
nameMap = await buildMemberNameMap(client, projectId);
|
|
2292
|
+
} catch {
|
|
2293
|
+
}
|
|
2294
|
+
comments = enrichCommentCreators(comments, nameMap);
|
|
2295
|
+
}
|
|
2296
|
+
formatCommentList(comments, globalOpts);
|
|
2297
|
+
});
|
|
2298
|
+
|
|
2299
|
+
// src/commands/post/comment/latest.ts
|
|
2300
|
+
var import_commander18 = require("commander");
|
|
2301
|
+
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) => {
|
|
2302
|
+
const globalOpts = commentLatestCommand.optsWithGlobals();
|
|
2303
|
+
const config = await getConfigOrThrow();
|
|
2304
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2305
|
+
const n = Number(opts.count);
|
|
2306
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
2307
|
+
throw new DoorayCliError("--count\uB294 \uC591\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2308
|
+
}
|
|
2309
|
+
if (n > 100) {
|
|
2310
|
+
throw new DoorayCliError("--count\uB294 \uCD5C\uB300 100\uAE4C\uC9C0 \uC9C0\uC6D0\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2311
|
+
}
|
|
2312
|
+
startSpinner("\uCD5C\uC2E0 \uB313\uAE00 \uC870\uD68C \uC911...");
|
|
2313
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2314
|
+
projectArg: project,
|
|
2315
|
+
postNumberArg: postNumberStr,
|
|
2316
|
+
idOpt: opts.id,
|
|
2317
|
+
urlOpt: opts.url
|
|
1995
2318
|
});
|
|
1996
2319
|
const res = await client.getPostComments(projectId, postId, {
|
|
1997
|
-
page:
|
|
1998
|
-
size:
|
|
2320
|
+
page: 0,
|
|
2321
|
+
size: Math.min(n, 100),
|
|
2322
|
+
order: "-createdAt"
|
|
1999
2323
|
});
|
|
2000
|
-
stopSpinner(true, "\
|
|
2001
|
-
let comments = res.result;
|
|
2324
|
+
stopSpinner(true, "\uC870\uD68C \uC644\uB8CC");
|
|
2325
|
+
let comments = res.result.slice(0, n);
|
|
2002
2326
|
if (!globalOpts.json) {
|
|
2003
2327
|
let nameMap = /* @__PURE__ */ new Map();
|
|
2004
2328
|
try {
|
|
@@ -2011,8 +2335,36 @@ var commentListCommand = new import_commander15.Command("list").description("\uB
|
|
|
2011
2335
|
});
|
|
2012
2336
|
|
|
2013
2337
|
// src/commands/post/comment/add.ts
|
|
2014
|
-
var
|
|
2015
|
-
|
|
2338
|
+
var import_commander19 = require("commander");
|
|
2339
|
+
|
|
2340
|
+
// src/utils/mention.ts
|
|
2341
|
+
function buildMemberMention(m, me) {
|
|
2342
|
+
const title = m.memberId === me.id ? "me" : "member";
|
|
2343
|
+
return `[@${m.name}](dooray://${me.orgId}/members/${m.memberId} "${title}")`;
|
|
2344
|
+
}
|
|
2345
|
+
function buildGroupMention(g, me) {
|
|
2346
|
+
return `[@${g.projectCode}/${g.code}](dooray://${me.orgId}/member-groups/${g.groupId})`;
|
|
2347
|
+
}
|
|
2348
|
+
function prependMentions(body, members, groups, me) {
|
|
2349
|
+
const parts = [];
|
|
2350
|
+
for (const m of members) parts.push(buildMemberMention(m, me));
|
|
2351
|
+
for (const g of groups) parts.push(buildGroupMention(g, me));
|
|
2352
|
+
if (parts.length === 0) return body;
|
|
2353
|
+
return parts.join(" ") + " " + body;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
// src/commands/post/comment/add.ts
|
|
2357
|
+
var commentAddCommand = new import_commander19.Command("add").description("\uB313\uAE00 \uCD94\uAC00").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray URL)").argument("[post-number]", "\uC5C5\uBB34 \uBC88\uD638 (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option(
|
|
2358
|
+
"--mention <name>",
|
|
2359
|
+
"\uBA64\uBC84 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, \uC774\uB984 \uBD80\uBD84\uC77C\uCE58)",
|
|
2360
|
+
(value, prev) => [...prev, value],
|
|
2361
|
+
[]
|
|
2362
|
+
).option(
|
|
2363
|
+
"--mention-group <code>",
|
|
2364
|
+
"\uADF8\uB8F9 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, code \uBD80\uBD84\uC77C\uCE58)",
|
|
2365
|
+
(value, prev) => [...prev, value],
|
|
2366
|
+
[]
|
|
2367
|
+
).action(async (project, postNumberStr, opts) => {
|
|
2016
2368
|
const globalOpts = commentAddCommand.optsWithGlobals();
|
|
2017
2369
|
const config = await getConfigOrThrow();
|
|
2018
2370
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2025,12 +2377,32 @@ var commentAddCommand = new import_commander16.Command("add").description("\uB31
|
|
|
2025
2377
|
}
|
|
2026
2378
|
}
|
|
2027
2379
|
startSpinner("\uB313\uAE00 \uCD94\uAC00 \uC911...");
|
|
2028
|
-
const { projectId, postId } = await resolvePostInput(client, {
|
|
2380
|
+
const { projectId, postId, projectCode } = await resolvePostInput(client, {
|
|
2029
2381
|
projectArg: project,
|
|
2030
2382
|
postNumberArg: postNumberStr,
|
|
2031
2383
|
idOpt: opts.id,
|
|
2032
2384
|
urlOpt: opts.url
|
|
2033
2385
|
});
|
|
2386
|
+
const mentionInputs = (opts.mention ?? []).filter((s) => s.length > 0);
|
|
2387
|
+
const groupInputs = (opts.mentionGroup ?? []).filter((s) => s.length > 0);
|
|
2388
|
+
if (mentionInputs.length > 0 || groupInputs.length > 0) {
|
|
2389
|
+
const me = await ensureMe(client);
|
|
2390
|
+
const memberIds = await Promise.all(
|
|
2391
|
+
mentionInputs.map((name) => resolveMember(client, projectId, name))
|
|
2392
|
+
);
|
|
2393
|
+
const nameMap = await buildMemberNameMap(client, projectId);
|
|
2394
|
+
const members = memberIds.map((memberId) => ({
|
|
2395
|
+
memberId,
|
|
2396
|
+
name: nameMap.get(memberId) ?? memberId
|
|
2397
|
+
}));
|
|
2398
|
+
const groups = await Promise.all(
|
|
2399
|
+
groupInputs.map(async (code) => {
|
|
2400
|
+
const g = await resolveMemberGroup(client, projectId, code);
|
|
2401
|
+
return { groupId: g.id, code: g.code, projectCode };
|
|
2402
|
+
})
|
|
2403
|
+
);
|
|
2404
|
+
bodyContent = prependMentions(bodyContent, members, groups, me);
|
|
2405
|
+
}
|
|
2034
2406
|
const res = await client.createPostComment(projectId, postId, {
|
|
2035
2407
|
body: { mimeType: "text/x-markdown", content: bodyContent }
|
|
2036
2408
|
});
|
|
@@ -2046,8 +2418,18 @@ var commentAddCommand = new import_commander16.Command("add").description("\uB31
|
|
|
2046
2418
|
});
|
|
2047
2419
|
|
|
2048
2420
|
// src/commands/post/comment/edit.ts
|
|
2049
|
-
var
|
|
2050
|
-
var commentEditCommand = new
|
|
2421
|
+
var import_commander20 = require("commander");
|
|
2422
|
+
var commentEditCommand = new import_commander20.Command("edit").description("\uB313\uAE00 \uC218\uC815 ($EDITOR \uB610\uB294 --body \uC635\uC158)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC / Dooray URL / \uB313\uAE00 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 \uB313\uAE00 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <commentId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 \uBCC0\uACBD (- \uC785\uB825 \uC2DC stdin, non-interactive)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin, non-interactive)").option(
|
|
2423
|
+
"--mention <name>",
|
|
2424
|
+
"\uBA64\uBC84 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, \uC774\uB984 \uBD80\uBD84\uC77C\uCE58)",
|
|
2425
|
+
(value, prev) => [...prev, value],
|
|
2426
|
+
[]
|
|
2427
|
+
).option(
|
|
2428
|
+
"--mention-group <code>",
|
|
2429
|
+
"\uADF8\uB8F9 \uBA58\uC158 (\uBC18\uBCF5 \uAC00\uB2A5, code \uBD80\uBD84\uC77C\uCE58)",
|
|
2430
|
+
(value, prev) => [...prev, value],
|
|
2431
|
+
[]
|
|
2432
|
+
).action(async (arg1, arg2, arg3, opts) => {
|
|
2051
2433
|
const config = await getConfigOrThrow();
|
|
2052
2434
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2053
2435
|
let projectArg;
|
|
@@ -2090,7 +2472,7 @@ var commentEditCommand = new import_commander17.Command("edit").description("\uB
|
|
|
2090
2472
|
);
|
|
2091
2473
|
}
|
|
2092
2474
|
startSpinner("\uB313\uAE00 \uC870\uD68C \uC911...");
|
|
2093
|
-
const { projectId, postId } = await resolvePostInput(client, {
|
|
2475
|
+
const { projectId, postId, projectCode } = await resolvePostInput(client, {
|
|
2094
2476
|
projectArg,
|
|
2095
2477
|
postNumberArg,
|
|
2096
2478
|
idOpt: opts.id,
|
|
@@ -2104,14 +2486,38 @@ var commentEditCommand = new import_commander17.Command("edit").description("\uB
|
|
|
2104
2486
|
`);
|
|
2105
2487
|
process.exit(1);
|
|
2106
2488
|
}
|
|
2489
|
+
const mentionInputs = (opts.mention ?? []).filter((s) => s.length > 0);
|
|
2490
|
+
const groupInputs = (opts.mentionGroup ?? []).filter((s) => s.length > 0);
|
|
2491
|
+
let mentionPrefix = "";
|
|
2492
|
+
if (mentionInputs.length > 0 || groupInputs.length > 0) {
|
|
2493
|
+
const me = await ensureMe(client);
|
|
2494
|
+
const memberIds = await Promise.all(
|
|
2495
|
+
mentionInputs.map((name) => resolveMember(client, projectId, name))
|
|
2496
|
+
);
|
|
2497
|
+
const nameMap = await buildMemberNameMap(client, projectId);
|
|
2498
|
+
const members = memberIds.map((memberId) => ({
|
|
2499
|
+
memberId,
|
|
2500
|
+
name: nameMap.get(memberId) ?? memberId
|
|
2501
|
+
}));
|
|
2502
|
+
const groups = await Promise.all(
|
|
2503
|
+
groupInputs.map(async (code) => {
|
|
2504
|
+
const g = await resolveMemberGroup(client, projectId, code);
|
|
2505
|
+
return { groupId: g.id, code: g.code, projectCode };
|
|
2506
|
+
})
|
|
2507
|
+
);
|
|
2508
|
+
mentionPrefix = prependMentions("", members, groups, me).trimEnd();
|
|
2509
|
+
}
|
|
2107
2510
|
let edited = await readBodyInputOrNull(opts);
|
|
2108
2511
|
if (edited == null) {
|
|
2109
|
-
const
|
|
2110
|
-
|
|
2111
|
-
|
|
2512
|
+
const rawContent = comment.body.content;
|
|
2513
|
+
const editorSeed = mentionPrefix ? mentionPrefix + " " + rawContent : rawContent;
|
|
2514
|
+
edited = await openInEditor(editorSeed);
|
|
2515
|
+
if (rawContent === edited) {
|
|
2112
2516
|
process.stdout.write("\uBCC0\uACBD\uC0AC\uD56D \uC5C6\uC74C\n");
|
|
2113
2517
|
return;
|
|
2114
2518
|
}
|
|
2519
|
+
} else if (mentionPrefix) {
|
|
2520
|
+
edited = mentionPrefix + " " + edited;
|
|
2115
2521
|
}
|
|
2116
2522
|
startSpinner("\uB313\uAE00 \uC218\uC815 \uC911...");
|
|
2117
2523
|
await client.updatePostComment(projectId, postId, commentId, {
|
|
@@ -2123,8 +2529,8 @@ var commentEditCommand = new import_commander17.Command("edit").description("\uB
|
|
|
2123
2529
|
});
|
|
2124
2530
|
|
|
2125
2531
|
// src/commands/post/comment/delete.ts
|
|
2126
|
-
var
|
|
2127
|
-
var commentDeleteCommand = new
|
|
2532
|
+
var import_commander21 = require("commander");
|
|
2533
|
+
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) => {
|
|
2128
2534
|
const config = await getConfigOrThrow();
|
|
2129
2535
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2130
2536
|
let projectArg;
|
|
@@ -2179,14 +2585,348 @@ var commentDeleteCommand = new import_commander18.Command("delete").description(
|
|
|
2179
2585
|
`);
|
|
2180
2586
|
});
|
|
2181
2587
|
|
|
2182
|
-
// src/commands/post/file/
|
|
2183
|
-
var
|
|
2588
|
+
// src/commands/post/comment/file/index.ts
|
|
2589
|
+
var import_commander26 = require("commander");
|
|
2590
|
+
|
|
2591
|
+
// src/commands/post/comment/file/list.ts
|
|
2592
|
+
var import_commander22 = require("commander");
|
|
2184
2593
|
function formatSize(bytes) {
|
|
2185
2594
|
if (bytes < 1024) return `${bytes}B`;
|
|
2186
2595
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
2187
2596
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
2188
2597
|
}
|
|
2189
|
-
var
|
|
2598
|
+
var listCommentFileCommand = new import_commander22.Command("list").description("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uBAA9\uB85D \uC870\uD68C").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 (positional \uBAA8\uB4DC)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
|
|
2599
|
+
const globalOpts = listCommentFileCommand.optsWithGlobals();
|
|
2600
|
+
const config = await getConfigOrThrow();
|
|
2601
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2602
|
+
let projectArg;
|
|
2603
|
+
let postNumberArg;
|
|
2604
|
+
let logId = opts.commentId;
|
|
2605
|
+
if (opts.id || opts.url) {
|
|
2606
|
+
if (arg2 || arg3) {
|
|
2607
|
+
throw new DoorayCliError(
|
|
2608
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --comment-id \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
|
|
2609
|
+
EXIT_PARAM_ERROR
|
|
2610
|
+
);
|
|
2611
|
+
}
|
|
2612
|
+
logId = logId ?? arg1;
|
|
2613
|
+
} else if (arg3) {
|
|
2614
|
+
projectArg = arg1;
|
|
2615
|
+
postNumberArg = arg2;
|
|
2616
|
+
logId = logId ?? arg3;
|
|
2617
|
+
} else if (arg1 && !arg2) {
|
|
2618
|
+
projectArg = arg1;
|
|
2619
|
+
if (!logId) {
|
|
2620
|
+
throw new DoorayCliError(
|
|
2621
|
+
"URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --comment-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
2622
|
+
EXIT_PARAM_ERROR
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
} else {
|
|
2626
|
+
projectArg = arg1;
|
|
2627
|
+
postNumberArg = arg2;
|
|
2628
|
+
if (!logId) {
|
|
2629
|
+
throw new DoorayCliError(
|
|
2630
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2631
|
+
EXIT_PARAM_ERROR
|
|
2632
|
+
);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
if (!logId) {
|
|
2636
|
+
throw new DoorayCliError("<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2637
|
+
}
|
|
2638
|
+
startSpinner("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
2639
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2640
|
+
projectArg,
|
|
2641
|
+
postNumberArg,
|
|
2642
|
+
idOpt: opts.id,
|
|
2643
|
+
urlOpt: opts.url
|
|
2644
|
+
});
|
|
2645
|
+
const res = await client.getPostComment(projectId, postId, logId);
|
|
2646
|
+
const files = res.result.files ?? [];
|
|
2647
|
+
stopSpinner(true, `\uCCA8\uBD80 \uD30C\uC77C ${files.length}\uAC1C`);
|
|
2648
|
+
if (files.length === 0) {
|
|
2649
|
+
if (globalOpts.json) {
|
|
2650
|
+
process.stdout.write("[]\n");
|
|
2651
|
+
} else if (!globalOpts.quiet) {
|
|
2652
|
+
process.stdout.write("\uCCA8\uBD80 \uC5C6\uC74C\n");
|
|
2653
|
+
}
|
|
2654
|
+
return;
|
|
2655
|
+
}
|
|
2656
|
+
output(globalOpts, {
|
|
2657
|
+
headers: ["\uD30C\uC77C\uBA85", "\uD06C\uAE30", "ID"],
|
|
2658
|
+
rows: files.map((f) => [f.name, formatSize(f.size), f.id]),
|
|
2659
|
+
raw: files,
|
|
2660
|
+
ids: files.map((f) => f.id)
|
|
2661
|
+
});
|
|
2662
|
+
});
|
|
2663
|
+
|
|
2664
|
+
// src/commands/post/comment/file/upload.ts
|
|
2665
|
+
var import_commander23 = require("commander");
|
|
2666
|
+
var import_node_path4 = require("path");
|
|
2667
|
+
|
|
2668
|
+
// src/utils/comment-files.ts
|
|
2669
|
+
function appendFileReference(body, fileName, fileId) {
|
|
2670
|
+
const safeName = fileName.replace(/[\[\]]/g, "");
|
|
2671
|
+
const ref = ``;
|
|
2672
|
+
if (body.length === 0) return ref;
|
|
2673
|
+
const trailing = body.endsWith("\n") ? "" : "\n";
|
|
2674
|
+
return `${body}${trailing}
|
|
2675
|
+
${ref}`;
|
|
2676
|
+
}
|
|
2677
|
+
function removeFileReference(body, fileId) {
|
|
2678
|
+
const escaped = fileId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2679
|
+
const refSource = `!\\[[^\\]]*\\]\\(/files/${escaped}\\)`;
|
|
2680
|
+
const lineRe = new RegExp(`^[ \\t]*${refSource}[ \\t]*$\\n?`, "gm");
|
|
2681
|
+
const inlineRe = new RegExp(refSource, "g");
|
|
2682
|
+
return body.replace(lineRe, "").replace(inlineRe, "");
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
// src/commands/post/comment/file/upload.ts
|
|
2686
|
+
var uploadCommentFileCommand = new import_commander23.Command("upload").description("\uB313\uAE00\uC5D0 \uD30C\uC77C \uC5C5\uB85C\uB4DC (post-level \uD30C\uC77C \uC5C5\uB85C\uB4DC + \uB313\uAE00 reference \uCD94\uAC00, ADR-024)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg3]", "\uB313\uAE00 ID (positional \uBAA8\uB4DC)").argument("[arg4]", "\uD30C\uC77C \uACBD\uB85C (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--file <path>", "\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uACBD\uB85C (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, arg4, opts) => {
|
|
2687
|
+
const globalOpts = uploadCommentFileCommand.optsWithGlobals();
|
|
2688
|
+
const config = await getConfigOrThrow();
|
|
2689
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2690
|
+
let projectArg;
|
|
2691
|
+
let postNumberArg;
|
|
2692
|
+
let logId = opts.commentId;
|
|
2693
|
+
let filePath = opts.file;
|
|
2694
|
+
if (opts.id || opts.url) {
|
|
2695
|
+
if (arg3 || arg4) {
|
|
2696
|
+
throw new DoorayCliError(
|
|
2697
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC640 \uD30C\uC77C \uACBD\uB85C \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
2698
|
+
EXIT_PARAM_ERROR
|
|
2699
|
+
);
|
|
2700
|
+
}
|
|
2701
|
+
logId = logId ?? arg1;
|
|
2702
|
+
filePath = filePath ?? arg2;
|
|
2703
|
+
} else if (arg4) {
|
|
2704
|
+
projectArg = arg1;
|
|
2705
|
+
postNumberArg = arg2;
|
|
2706
|
+
logId = logId ?? arg3;
|
|
2707
|
+
filePath = filePath ?? arg4;
|
|
2708
|
+
} else if (arg3) {
|
|
2709
|
+
projectArg = arg1;
|
|
2710
|
+
postNumberArg = arg2;
|
|
2711
|
+
logId = logId ?? arg3;
|
|
2712
|
+
} else if (arg1 && !arg2) {
|
|
2713
|
+
projectArg = arg1;
|
|
2714
|
+
} else {
|
|
2715
|
+
projectArg = arg1;
|
|
2716
|
+
postNumberArg = arg2;
|
|
2717
|
+
}
|
|
2718
|
+
if (!logId) {
|
|
2719
|
+
throw new DoorayCliError(
|
|
2720
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2721
|
+
EXIT_PARAM_ERROR
|
|
2722
|
+
);
|
|
2723
|
+
}
|
|
2724
|
+
if (!filePath) {
|
|
2725
|
+
throw new DoorayCliError(
|
|
2726
|
+
"<path>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 4\uBC88\uC9F8 \uB610\uB294 --file \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2727
|
+
EXIT_PARAM_ERROR
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2731
|
+
projectArg,
|
|
2732
|
+
postNumberArg,
|
|
2733
|
+
idOpt: opts.id,
|
|
2734
|
+
urlOpt: opts.url
|
|
2735
|
+
});
|
|
2736
|
+
startSpinner("\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC911...");
|
|
2737
|
+
const uploadRes = await client.uploadPostFile(projectId, postId, filePath);
|
|
2738
|
+
const fileId = uploadRes.result.id;
|
|
2739
|
+
const fileName = (0, import_node_path4.basename)(filePath);
|
|
2740
|
+
stopSpinner(true, "\uC5C5\uB85C\uB4DC \uC644\uB8CC");
|
|
2741
|
+
startSpinner("\uB313\uAE00 reference \uCD94\uAC00 \uC911...");
|
|
2742
|
+
try {
|
|
2743
|
+
const commentRes = await client.getPostComment(projectId, postId, logId);
|
|
2744
|
+
const currentBody = commentRes.result.body.content;
|
|
2745
|
+
const newBody = appendFileReference(currentBody, fileName, fileId);
|
|
2746
|
+
await client.updatePostComment(projectId, postId, logId, {
|
|
2747
|
+
body: { mimeType: "text/x-markdown", content: newBody }
|
|
2748
|
+
});
|
|
2749
|
+
stopSpinner(true, "reference \uCD94\uAC00 \uC644\uB8CC");
|
|
2750
|
+
} catch {
|
|
2751
|
+
stopSpinner(false, "");
|
|
2752
|
+
throw new DoorayCliError(
|
|
2753
|
+
`\uC5C5\uB85C\uB4DC OK / \uB313\uAE00 reference \uCD94\uAC00 \uC2E4\uD328. fileId=${fileId} \u2014 'dooray post comment file delete' \uB610\uB294 \uC218\uB3D9 PUT \uC73C\uB85C \uC815\uB9AC\uD558\uC138\uC694.`,
|
|
2754
|
+
EXIT_API_ERROR
|
|
2755
|
+
);
|
|
2756
|
+
}
|
|
2757
|
+
if (globalOpts.json) {
|
|
2758
|
+
printJson({ fileId, fileName, commentId: logId });
|
|
2759
|
+
} else if (globalOpts.quiet) {
|
|
2760
|
+
process.stdout.write(`${fileId}
|
|
2761
|
+
`);
|
|
2762
|
+
} else {
|
|
2763
|
+
process.stdout.write(`\uC5C5\uB85C\uB4DC + \uB313\uAE00 reference \uCD94\uAC00: fileId=${fileId}
|
|
2764
|
+
`);
|
|
2765
|
+
}
|
|
2766
|
+
});
|
|
2767
|
+
|
|
2768
|
+
// src/commands/post/comment/file/download.ts
|
|
2769
|
+
var import_commander24 = require("commander");
|
|
2770
|
+
var import_promises8 = require("fs/promises");
|
|
2771
|
+
var import_node_path5 = require("path");
|
|
2772
|
+
var downloadCommentFileCommand = new import_commander24.Command("download").description(
|
|
2773
|
+
"\uB313\uAE00\uC5D0 \uCCA8\uBD80\uB41C \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC (\uD604\uC7AC comment-id \uB294 \uBBF8\uC0AC\uC6A9 \u2014 \uBA58\uD0C8 \uBAA8\uB378 \uC77C\uAD00\uC131, \uBBF8\uB798 \uB313\uAE00 \uB2E8\uC704 \uAD8C\uD55C \uD638\uD658\uC6A9)"
|
|
2774
|
+
).argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uB313\uAE00 ID (positional \uBAA8\uB4DC)").argument("[arg4]", "\uD30C\uC77C ID (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("--out <path>", "\uC800\uC7A5 \uACBD\uB85C (\uBBF8\uC9C0\uC815 \uC2DC \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC6D0\uBCF8 \uD30C\uC77C\uBA85\uC73C\uB85C \uC800\uC7A5)", ".").action(async (arg1, arg2, arg3, arg4, opts) => {
|
|
2775
|
+
const config = await getConfigOrThrow();
|
|
2776
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2777
|
+
let projectArg;
|
|
2778
|
+
let postNumberArg;
|
|
2779
|
+
let _commentId = opts.commentId;
|
|
2780
|
+
let fileId = opts.fileId;
|
|
2781
|
+
if (opts.id || opts.url) {
|
|
2782
|
+
if (arg3 || arg4) {
|
|
2783
|
+
throw new DoorayCliError(
|
|
2784
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC640 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
2785
|
+
EXIT_PARAM_ERROR
|
|
2786
|
+
);
|
|
2787
|
+
}
|
|
2788
|
+
_commentId = _commentId ?? arg1;
|
|
2789
|
+
fileId = fileId ?? arg2;
|
|
2790
|
+
} else if (arg4) {
|
|
2791
|
+
projectArg = arg1;
|
|
2792
|
+
postNumberArg = arg2;
|
|
2793
|
+
_commentId = _commentId ?? arg3;
|
|
2794
|
+
fileId = fileId ?? arg4;
|
|
2795
|
+
} else if (arg3) {
|
|
2796
|
+
projectArg = arg1;
|
|
2797
|
+
postNumberArg = arg2;
|
|
2798
|
+
_commentId = _commentId ?? arg3;
|
|
2799
|
+
} else if (arg1 && !arg2) {
|
|
2800
|
+
projectArg = arg1;
|
|
2801
|
+
} else {
|
|
2802
|
+
projectArg = arg1;
|
|
2803
|
+
postNumberArg = arg2;
|
|
2804
|
+
}
|
|
2805
|
+
if (!fileId) {
|
|
2806
|
+
throw new DoorayCliError(
|
|
2807
|
+
"<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 4\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2808
|
+
EXIT_PARAM_ERROR
|
|
2809
|
+
);
|
|
2810
|
+
}
|
|
2811
|
+
startSpinner("\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
|
|
2812
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2813
|
+
projectArg,
|
|
2814
|
+
postNumberArg,
|
|
2815
|
+
idOpt: opts.id,
|
|
2816
|
+
urlOpt: opts.url
|
|
2817
|
+
});
|
|
2818
|
+
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, fileId);
|
|
2819
|
+
const safeName = (0, import_node_path5.basename)(fileName);
|
|
2820
|
+
const outputPath = (0, import_node_path5.join)(opts.out, safeName);
|
|
2821
|
+
await (0, import_promises8.writeFile)(outputPath, Buffer.from(buffer));
|
|
2822
|
+
stopSpinner(true, "\uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC");
|
|
2823
|
+
process.stdout.write(`${outputPath}
|
|
2824
|
+
`);
|
|
2825
|
+
});
|
|
2826
|
+
|
|
2827
|
+
// src/commands/post/comment/file/delete.ts
|
|
2828
|
+
var import_commander25 = require("commander");
|
|
2829
|
+
var deleteCommentFileCommand = new import_commander25.Command("delete").description("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uC0AD\uC81C (\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 + \uD30C\uC77C \uC0AD\uC81C, ADR-024)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uB313\uAE00 ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uB313\uAE00 ID (positional \uBAA8\uB4DC)").argument("[arg4]", "\uD30C\uC77C ID (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--comment-id <logId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("--yes", "\uD655\uC778 \uC5C6\uC774 \uC0AD\uC81C").action(async (arg1, arg2, arg3, arg4, opts) => {
|
|
2830
|
+
const config = await getConfigOrThrow();
|
|
2831
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2832
|
+
let projectArg;
|
|
2833
|
+
let postNumberArg;
|
|
2834
|
+
let logId = opts.commentId;
|
|
2835
|
+
let fileId = opts.fileId;
|
|
2836
|
+
if (opts.id || opts.url) {
|
|
2837
|
+
if (arg3 || arg4) {
|
|
2838
|
+
throw new DoorayCliError(
|
|
2839
|
+
"--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB313\uAE00 ID \uC640 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
2840
|
+
EXIT_PARAM_ERROR
|
|
2841
|
+
);
|
|
2842
|
+
}
|
|
2843
|
+
logId = logId ?? arg1;
|
|
2844
|
+
fileId = fileId ?? arg2;
|
|
2845
|
+
} else if (arg4) {
|
|
2846
|
+
projectArg = arg1;
|
|
2847
|
+
postNumberArg = arg2;
|
|
2848
|
+
logId = logId ?? arg3;
|
|
2849
|
+
fileId = fileId ?? arg4;
|
|
2850
|
+
} else if (arg3) {
|
|
2851
|
+
projectArg = arg1;
|
|
2852
|
+
postNumberArg = arg2;
|
|
2853
|
+
logId = logId ?? arg3;
|
|
2854
|
+
} else if (arg1 && !arg2) {
|
|
2855
|
+
projectArg = arg1;
|
|
2856
|
+
} else {
|
|
2857
|
+
projectArg = arg1;
|
|
2858
|
+
postNumberArg = arg2;
|
|
2859
|
+
}
|
|
2860
|
+
if (!logId) {
|
|
2861
|
+
throw new DoorayCliError(
|
|
2862
|
+
"<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2863
|
+
EXIT_PARAM_ERROR
|
|
2864
|
+
);
|
|
2865
|
+
}
|
|
2866
|
+
if (!fileId) {
|
|
2867
|
+
throw new DoorayCliError(
|
|
2868
|
+
"<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 4\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
|
|
2869
|
+
EXIT_PARAM_ERROR
|
|
2870
|
+
);
|
|
2871
|
+
}
|
|
2872
|
+
if (!opts.yes) {
|
|
2873
|
+
const { confirm: confirm2 } = await import("@inquirer/prompts");
|
|
2874
|
+
const ok = await confirm2({
|
|
2875
|
+
message: `\uB313\uAE00 \uBCF8\uBB38\uC5D0\uC11C reference \uB97C \uC81C\uAC70\uD558\uACE0 \uD30C\uC77C(${fileId})\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uAC19\uC740 post \uC758 \uB2E4\uB978 \uB313\uAE00\uC5D0\uC11C \uAC19\uC740 \uD30C\uC77C ID \uB97C \uCC38\uC870\uD558\uB294 \uACBD\uC6B0 broken \uB429\uB2C8\uB2E4. \uACC4\uC18D\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`
|
|
2876
|
+
});
|
|
2877
|
+
if (!ok) {
|
|
2878
|
+
process.stdout.write("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n");
|
|
2879
|
+
return;
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
const { projectId, postId } = await resolvePostInput(client, {
|
|
2883
|
+
projectArg,
|
|
2884
|
+
postNumberArg,
|
|
2885
|
+
idOpt: opts.id,
|
|
2886
|
+
urlOpt: opts.url
|
|
2887
|
+
});
|
|
2888
|
+
startSpinner("\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 \uC911...");
|
|
2889
|
+
try {
|
|
2890
|
+
const commentRes = await client.getPostComment(projectId, postId, logId);
|
|
2891
|
+
const currentBody = commentRes.result.body.content;
|
|
2892
|
+
const newBody = removeFileReference(currentBody, fileId);
|
|
2893
|
+
await client.updatePostComment(projectId, postId, logId, {
|
|
2894
|
+
body: { mimeType: "text/x-markdown", content: newBody }
|
|
2895
|
+
});
|
|
2896
|
+
stopSpinner(true, "reference \uC81C\uAC70 \uC644\uB8CC");
|
|
2897
|
+
} catch {
|
|
2898
|
+
stopSpinner(false, "");
|
|
2899
|
+
throw new DoorayCliError(
|
|
2900
|
+
`\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 \uC2E4\uD328. \uD30C\uC77C \uC0AD\uC81C\uB97C \uC9C4\uD589\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. fileId=${fileId}`,
|
|
2901
|
+
EXIT_API_ERROR
|
|
2902
|
+
);
|
|
2903
|
+
}
|
|
2904
|
+
startSpinner("\uD30C\uC77C \uC0AD\uC81C \uC911...");
|
|
2905
|
+
try {
|
|
2906
|
+
await client.deletePostFile(projectId, postId, fileId);
|
|
2907
|
+
stopSpinner(true, "\uD30C\uC77C \uC0AD\uC81C \uC644\uB8CC");
|
|
2908
|
+
} catch {
|
|
2909
|
+
stopSpinner(false, "");
|
|
2910
|
+
throw new DoorayCliError(
|
|
2911
|
+
`\uB313\uAE00 \uBCF8\uBB38 reference \uC81C\uAC70 OK / \uD30C\uC77C \uC0AD\uC81C \uC2E4\uD328. 'dooray post file delete' \uB85C \uD6C4\uCC98\uB9AC\uD558\uC138\uC694. fileId=${fileId}`,
|
|
2912
|
+
EXIT_API_ERROR
|
|
2913
|
+
);
|
|
2914
|
+
}
|
|
2915
|
+
process.stdout.write(`\uD30C\uC77C(${fileId})\uC774 \uB313\uAE00(${logId})\uC5D0\uC11C \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
2916
|
+
`);
|
|
2917
|
+
});
|
|
2918
|
+
|
|
2919
|
+
// src/commands/post/comment/file/index.ts
|
|
2920
|
+
var commentFileCommand = new import_commander26.Command("file").description("\uB313\uAE00 \uCCA8\uBD80 \uD30C\uC77C \uAD00\uB9AC (post-level files API + \uB313\uAE00 PUT \uD569\uC131, ADR-024)").addCommand(listCommentFileCommand).addCommand(uploadCommentFileCommand).addCommand(downloadCommentFileCommand).addCommand(deleteCommentFileCommand);
|
|
2921
|
+
|
|
2922
|
+
// src/commands/post/file/list.ts
|
|
2923
|
+
var import_commander27 = require("commander");
|
|
2924
|
+
function formatSize2(bytes) {
|
|
2925
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
2926
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
2927
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
2928
|
+
}
|
|
2929
|
+
var fileListCommand = new import_commander27.Command("list").description("\uC5C5\uBB34 \uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray URL)").argument("[post-number]", "\uC5C5\uBB34 \uBC88\uD638 (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").action(async (project, postNumberStr, opts) => {
|
|
2190
2930
|
const globalOpts = fileListCommand.optsWithGlobals();
|
|
2191
2931
|
const config = await getConfigOrThrow();
|
|
2192
2932
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2204,7 +2944,7 @@ var fileListCommand = new import_commander19.Command("list").description("\uC5C5
|
|
|
2204
2944
|
rows: res.result.map((f) => [
|
|
2205
2945
|
f.id,
|
|
2206
2946
|
f.name,
|
|
2207
|
-
|
|
2947
|
+
formatSize2(f.size),
|
|
2208
2948
|
f.mimeType,
|
|
2209
2949
|
f.createdAt
|
|
2210
2950
|
]),
|
|
@@ -2214,10 +2954,10 @@ var fileListCommand = new import_commander19.Command("list").description("\uC5C5
|
|
|
2214
2954
|
});
|
|
2215
2955
|
|
|
2216
2956
|
// src/commands/post/file/download.ts
|
|
2217
|
-
var
|
|
2218
|
-
var
|
|
2219
|
-
var
|
|
2220
|
-
var fileDownloadCommand = new
|
|
2957
|
+
var import_commander28 = require("commander");
|
|
2958
|
+
var import_promises9 = require("fs/promises");
|
|
2959
|
+
var import_node_path6 = require("path");
|
|
2960
|
+
var fileDownloadCommand = new import_commander28.Command("download").description("\uCCA8\uBD80\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uD30C\uC77C ID (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("-o, --output <dir>", "\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC", ".").action(async (arg1, arg2, arg3, opts) => {
|
|
2221
2961
|
const config = await getConfigOrThrow();
|
|
2222
2962
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2223
2963
|
let projectArg;
|
|
@@ -2264,18 +3004,18 @@ var fileDownloadCommand = new import_commander20.Command("download").description
|
|
|
2264
3004
|
urlOpt: opts.url
|
|
2265
3005
|
});
|
|
2266
3006
|
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, fileId);
|
|
2267
|
-
const outputPath = (0,
|
|
2268
|
-
await (0,
|
|
3007
|
+
const outputPath = (0, import_node_path6.join)(opts.output, fileName);
|
|
3008
|
+
await (0, import_promises9.writeFile)(outputPath, Buffer.from(buffer));
|
|
2269
3009
|
stopSpinner(true, "\uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC");
|
|
2270
3010
|
process.stdout.write(`${outputPath}
|
|
2271
3011
|
`);
|
|
2272
3012
|
});
|
|
2273
3013
|
|
|
2274
3014
|
// src/commands/post/file/download-all.ts
|
|
2275
|
-
var
|
|
2276
|
-
var
|
|
2277
|
-
var
|
|
2278
|
-
var fileDownloadAllCommand = new
|
|
3015
|
+
var import_commander29 = require("commander");
|
|
3016
|
+
var import_promises10 = require("fs/promises");
|
|
3017
|
+
var import_node_path7 = require("path");
|
|
3018
|
+
var fileDownloadAllCommand = new import_commander29.Command("download-all").description("\uC5C5\uBB34\uC758 \uBAA8\uB4E0 \uCCA8\uBD80\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray URL)").argument("[post-number]", "\uC5C5\uBB34 \uBC88\uD638 (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("-o, --output <dir>", "\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC", ".").action(async (project, postNumberStr, opts) => {
|
|
2279
3019
|
const config = await getConfigOrThrow();
|
|
2280
3020
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2281
3021
|
const spinner = startSpinner("\uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
@@ -2291,13 +3031,13 @@ var fileDownloadAllCommand = new import_commander21.Command("download-all").desc
|
|
|
2291
3031
|
process.stdout.write("\uCCA8\uBD80\uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n");
|
|
2292
3032
|
return;
|
|
2293
3033
|
}
|
|
2294
|
-
await (0,
|
|
3034
|
+
await (0, import_promises10.mkdir)(opts.output, { recursive: true });
|
|
2295
3035
|
const downloaded = [];
|
|
2296
3036
|
for (const file of res.result) {
|
|
2297
3037
|
spinner.text = `\uB2E4\uC6B4\uB85C\uB4DC \uC911: ${file.name} (${downloaded.length + 1}/${res.result.length})`;
|
|
2298
3038
|
const { buffer, fileName } = await client.downloadPostFile(projectId, postId, file.id);
|
|
2299
|
-
const outputPath = (0,
|
|
2300
|
-
await (0,
|
|
3039
|
+
const outputPath = (0, import_node_path7.join)(opts.output, fileName);
|
|
3040
|
+
await (0, import_promises10.writeFile)(outputPath, Buffer.from(buffer));
|
|
2301
3041
|
downloaded.push(outputPath);
|
|
2302
3042
|
}
|
|
2303
3043
|
stopSpinner(true, `${downloaded.length}\uAC1C \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC`);
|
|
@@ -2308,9 +3048,9 @@ var fileDownloadAllCommand = new import_commander21.Command("download-all").desc
|
|
|
2308
3048
|
});
|
|
2309
3049
|
|
|
2310
3050
|
// src/commands/post/file/upload.ts
|
|
2311
|
-
var
|
|
2312
|
-
var
|
|
2313
|
-
var fileUploadCommand = new
|
|
3051
|
+
var import_commander30 = require("commander");
|
|
3052
|
+
var import_node_path8 = require("path");
|
|
3053
|
+
var fileUploadCommand = new import_commander30.Command("upload").description("\uCCA8\uBD80\uD30C\uC77C \uC5C5\uB85C\uB4DC").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg3]", "\uD30C\uC77C \uACBD\uB85C (positional \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--file <path>", "\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uACBD\uB85C (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
|
|
2314
3054
|
const globalOpts = fileUploadCommand.optsWithGlobals();
|
|
2315
3055
|
const config = await getConfigOrThrow();
|
|
2316
3056
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2365,14 +3105,14 @@ var fileUploadCommand = new import_commander22.Command("upload").description("\u
|
|
|
2365
3105
|
process.stdout.write(`${res.result.id}
|
|
2366
3106
|
`);
|
|
2367
3107
|
} else {
|
|
2368
|
-
process.stdout.write(`\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC644\uB8CC: ${(0,
|
|
3108
|
+
process.stdout.write(`\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC644\uB8CC: ${(0, import_node_path8.basename)(filePath)} (ID: ${res.result.id})
|
|
2369
3109
|
`);
|
|
2370
3110
|
}
|
|
2371
3111
|
});
|
|
2372
3112
|
|
|
2373
3113
|
// src/commands/post/file/delete.ts
|
|
2374
|
-
var
|
|
2375
|
-
var fileDeleteCommand = new
|
|
3114
|
+
var import_commander31 = require("commander");
|
|
3115
|
+
var fileDeleteCommand = new import_commander31.Command("delete").description("\uCCA8\uBD80\uD30C\uC77C \uC0AD\uC81C").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg2]", "\uC5C5\uBB34 \uBC88\uD638 \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uD30C\uC77C ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <postId>", "Dooray post ID (project/post-number \uB300\uC2E0)").option("--url <url>", "Dooray \uC5C5\uBB34 URL (project/post-number \uB300\uC2E0)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
|
|
2376
3116
|
const config = await getConfigOrThrow();
|
|
2377
3117
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2378
3118
|
let projectArg;
|
|
@@ -2425,7 +3165,7 @@ var fileDeleteCommand = new import_commander23.Command("delete").description("\u
|
|
|
2425
3165
|
});
|
|
2426
3166
|
|
|
2427
3167
|
// src/commands/wiki/list.ts
|
|
2428
|
-
var
|
|
3168
|
+
var import_commander32 = require("commander");
|
|
2429
3169
|
|
|
2430
3170
|
// src/formatters/wiki.ts
|
|
2431
3171
|
function formatWikiList(wikis, opts) {
|
|
@@ -2468,7 +3208,7 @@ function formatWikiPageDetail(page, opts) {
|
|
|
2468
3208
|
}
|
|
2469
3209
|
|
|
2470
3210
|
// src/commands/wiki/list.ts
|
|
2471
|
-
var wikiListCommand = new
|
|
3211
|
+
var wikiListCommand = new import_commander32.Command("list").description("\uC704\uD0A4 \uBAA9\uB85D \uC870\uD68C").option("--page <number>", "\uD398\uC774\uC9C0 \uBC88\uD638", "0").option("--size <number>", "\uD398\uC774\uC9C0 \uD06C\uAE30", "20").action(async (opts) => {
|
|
2472
3212
|
const globalOpts = wikiListCommand.optsWithGlobals();
|
|
2473
3213
|
const config = await getConfigOrThrow();
|
|
2474
3214
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2482,7 +3222,7 @@ var wikiListCommand = new import_commander24.Command("list").description("\uC704
|
|
|
2482
3222
|
});
|
|
2483
3223
|
|
|
2484
3224
|
// src/commands/wiki/pages.ts
|
|
2485
|
-
var
|
|
3225
|
+
var import_commander33 = require("commander");
|
|
2486
3226
|
|
|
2487
3227
|
// src/resolvers/wiki.ts
|
|
2488
3228
|
async function resolveWiki(client, projectCode) {
|
|
@@ -2526,7 +3266,7 @@ async function resolveWikiHomePageId(client, wikiId) {
|
|
|
2526
3266
|
}
|
|
2527
3267
|
|
|
2528
3268
|
// src/commands/wiki/pages.ts
|
|
2529
|
-
var wikiPagesCommand = new
|
|
3269
|
+
var wikiPagesCommand = new import_commander33.Command("pages").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uBAA9\uB85D \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").option("--parent <page-id>", "\uBD80\uBAA8 \uD398\uC774\uC9C0 ID").action(async (project, opts) => {
|
|
2530
3270
|
const globalOpts = wikiPagesCommand.optsWithGlobals();
|
|
2531
3271
|
const config = await getConfigOrThrow();
|
|
2532
3272
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2538,8 +3278,8 @@ var wikiPagesCommand = new import_commander25.Command("pages").description("\uC7
|
|
|
2538
3278
|
});
|
|
2539
3279
|
|
|
2540
3280
|
// src/commands/wiki/page-get.ts
|
|
2541
|
-
var
|
|
2542
|
-
var wikiPageGetCommand = new
|
|
3281
|
+
var import_commander34 = require("commander");
|
|
3282
|
+
var wikiPageGetCommand = new import_commander34.Command("get").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uC0C1\uC138 \uC870\uD68C").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").argument("<page-id>", "\uD398\uC774\uC9C0 ID").action(async (project, pageId) => {
|
|
2543
3283
|
const globalOpts = wikiPageGetCommand.optsWithGlobals();
|
|
2544
3284
|
const config = await getConfigOrThrow();
|
|
2545
3285
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2551,8 +3291,8 @@ var wikiPageGetCommand = new import_commander26.Command("get").description("\uC7
|
|
|
2551
3291
|
});
|
|
2552
3292
|
|
|
2553
3293
|
// src/commands/wiki/page-create.ts
|
|
2554
|
-
var
|
|
2555
|
-
var wikiPageCreateCommand = new
|
|
3294
|
+
var import_commander35 = require("commander");
|
|
3295
|
+
var wikiPageCreateCommand = new import_commander35.Command("create").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uC0DD\uC131").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").requiredOption("--title <title>", "\uD398\uC774\uC9C0 \uC81C\uBAA9").option("--parent <page-id>", "\uBD80\uBAA8 \uD398\uC774\uC9C0 ID").option("--body <text>", "\uBCF8\uBB38 \uD14D\uC2A4\uD2B8 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").action(async (project, opts) => {
|
|
2556
3296
|
const globalOpts = wikiPageCreateCommand.optsWithGlobals();
|
|
2557
3297
|
const config = await getConfigOrThrow();
|
|
2558
3298
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2577,8 +3317,8 @@ var wikiPageCreateCommand = new import_commander27.Command("create").description
|
|
|
2577
3317
|
});
|
|
2578
3318
|
|
|
2579
3319
|
// src/commands/wiki/page-edit.ts
|
|
2580
|
-
var
|
|
2581
|
-
var wikiPageEditCommand = new
|
|
3320
|
+
var import_commander36 = require("commander");
|
|
3321
|
+
var wikiPageEditCommand = new import_commander36.Command("edit").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uC218\uC815 (\uD50C\uB798\uADF8 \uC5C6\uC73C\uBA74 $EDITOR)").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").argument("<page-id>", "\uD398\uC774\uC9C0 ID").option("--title <title>", "\uD398\uC774\uC9C0 \uC81C\uBAA9 (\uC9C0\uC815 \uC2DC $EDITOR \uC0DD\uB7B5)").option("--body <text>", "\uBCF8\uBB38 \uD14D\uC2A4\uD2B8 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").action(async (project, pageId, opts) => {
|
|
2582
3322
|
const config = await getConfigOrThrow();
|
|
2583
3323
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
2584
3324
|
const hasTitle = opts.title != null;
|
|
@@ -2631,10 +3371,10 @@ var wikiPageEditCommand = new import_commander28.Command("edit").description("\u
|
|
|
2631
3371
|
});
|
|
2632
3372
|
|
|
2633
3373
|
// src/commands/member/index.ts
|
|
2634
|
-
var
|
|
3374
|
+
var import_commander40 = require("commander");
|
|
2635
3375
|
|
|
2636
3376
|
// src/commands/member/get.ts
|
|
2637
|
-
var
|
|
3377
|
+
var import_commander37 = require("commander");
|
|
2638
3378
|
|
|
2639
3379
|
// src/formatters/member.ts
|
|
2640
3380
|
function formatMemberDetail(member, opts) {
|
|
@@ -2664,9 +3404,23 @@ function formatMemberList(rows, opts) {
|
|
|
2664
3404
|
ids: rows.map((r) => r.id)
|
|
2665
3405
|
});
|
|
2666
3406
|
}
|
|
3407
|
+
function formatMemberSearchResults(members, opts) {
|
|
3408
|
+
output(opts, {
|
|
3409
|
+
headers: ["ID", "Name", "UserCode", "Nickname", "Email"],
|
|
3410
|
+
rows: members.map((m) => [
|
|
3411
|
+
m.id,
|
|
3412
|
+
m.name,
|
|
3413
|
+
m.userCode ?? "",
|
|
3414
|
+
m.nickname ?? "",
|
|
3415
|
+
m.externalEmailAddress ?? ""
|
|
3416
|
+
]),
|
|
3417
|
+
raw: members,
|
|
3418
|
+
ids: members.map((m) => m.id)
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
2667
3421
|
|
|
2668
3422
|
// src/commands/member/get.ts
|
|
2669
|
-
var memberGetCommand = new
|
|
3423
|
+
var memberGetCommand = new import_commander37.Command("get").description("\uBA64\uBC84 \uC0C1\uC138 \uC815\uBCF4 \uC870\uD68C (organizationMemberId)").argument("<member-id>", "\uC870\uD68C\uD560 organization member ID").action(async (memberId) => {
|
|
2670
3424
|
const globalOpts = memberGetCommand.optsWithGlobals();
|
|
2671
3425
|
const config = await getConfigOrThrow();
|
|
2672
3426
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2675,8 +3429,8 @@ var memberGetCommand = new import_commander29.Command("get").description("\uBA64
|
|
|
2675
3429
|
});
|
|
2676
3430
|
|
|
2677
3431
|
// src/commands/member/list.ts
|
|
2678
|
-
var
|
|
2679
|
-
var memberListCommand = new
|
|
3432
|
+
var import_commander38 = require("commander");
|
|
3433
|
+
var memberListCommand = new import_commander38.Command("list").description("\uD504\uB85C\uC81D\uD2B8 \uBA64\uBC84 \uBAA9\uB85D").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
|
|
2680
3434
|
const globalOpts = memberListCommand.optsWithGlobals();
|
|
2681
3435
|
const config = await getConfigOrThrow();
|
|
2682
3436
|
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
@@ -2690,13 +3444,48 @@ var memberListCommand = new import_commander30.Command("list").description("\uD5
|
|
|
2690
3444
|
);
|
|
2691
3445
|
});
|
|
2692
3446
|
|
|
3447
|
+
// src/commands/member/search.ts
|
|
3448
|
+
var import_commander39 = require("commander");
|
|
3449
|
+
var memberSearchCommand = new import_commander39.Command("search").description("organization \uC804\uCCB4\uC5D0\uC11C \uBA64\uBC84 \uAC80\uC0C9").argument("[keyword]", "\uC774\uB984 \uAC80\uC0C9\uC5B4 (--email/--user-code \uBBF8\uC9C0\uC815 \uC2DC name\uC73C\uB85C \uAC80\uC0C9)").option("--email <email>", "\uC678\uBD80 \uC774\uBA54\uC77C (\uCF64\uB9C8 \uAD6C\uBD84 \uAC00\uB2A5, exact match)").option("--user-code <code>", "\uC0AC\uBC88 like \uAC80\uC0C9").option("--user-code-exact <code>", "\uC0AC\uBC88 exact match").option("--page <n>", "\uD398\uC774\uC9C0 (\uAE30\uBCF8 0)", "0").option("--size <n>", "\uD398\uC774\uC9C0 \uD06C\uAE30 (\uAE30\uBCF8 20, max 100)", "20").action(async (keyword, opts) => {
|
|
3450
|
+
const globalOpts = memberSearchCommand.optsWithGlobals();
|
|
3451
|
+
const filterCount = [keyword, opts.email, opts.userCode, opts.userCodeExact].filter(Boolean).length;
|
|
3452
|
+
if (filterCount === 0) {
|
|
3453
|
+
throw new DoorayCliError(
|
|
3454
|
+
"\uAC80\uC0C9 \uC870\uAC74\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. positional <keyword>(=name) \uB610\uB294 --email/--user-code/--user-code-exact \uC911 \uD558\uB098 \uC774\uC0C1.",
|
|
3455
|
+
EXIT_PARAM_ERROR
|
|
3456
|
+
);
|
|
3457
|
+
}
|
|
3458
|
+
if (keyword && (opts.email || opts.userCode || opts.userCodeExact)) {
|
|
3459
|
+
throw new DoorayCliError(
|
|
3460
|
+
"positional <keyword>(name)\uC640 --email/--user-code/--user-code-exact \uC635\uC158\uC740 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00.",
|
|
3461
|
+
EXIT_PARAM_ERROR
|
|
3462
|
+
);
|
|
3463
|
+
}
|
|
3464
|
+
const config = await getConfigOrThrow();
|
|
3465
|
+
const client = new DoorayApiClient(config.apiKey, config.baseUrl);
|
|
3466
|
+
const size = Math.min(Math.max(1, Number(opts.size) || 20), 100);
|
|
3467
|
+
const page = Math.max(0, Number(opts.page) || 0);
|
|
3468
|
+
startSpinner("\uBA64\uBC84 \uAC80\uC0C9 \uC911...");
|
|
3469
|
+
const res = await client.searchMembers({
|
|
3470
|
+
...keyword && { name: keyword },
|
|
3471
|
+
...opts.email && { externalEmailAddresses: opts.email },
|
|
3472
|
+
...opts.userCode && { userCode: opts.userCode },
|
|
3473
|
+
...opts.userCodeExact && { userCodeExact: opts.userCodeExact },
|
|
3474
|
+
page,
|
|
3475
|
+
size
|
|
3476
|
+
});
|
|
3477
|
+
stopSpinner(true, `${res.totalCount}\uAC74 (\uC774 \uD398\uC774\uC9C0 ${res.result.length})`);
|
|
3478
|
+
formatMemberSearchResults(res.result, globalOpts);
|
|
3479
|
+
});
|
|
3480
|
+
|
|
2693
3481
|
// src/commands/member/index.ts
|
|
2694
|
-
var memberCommand = new
|
|
3482
|
+
var memberCommand = new import_commander40.Command("member").description("Dooray \uBA64\uBC84 \uC870\uD68C");
|
|
2695
3483
|
memberCommand.addCommand(memberGetCommand);
|
|
2696
3484
|
memberCommand.addCommand(memberListCommand);
|
|
3485
|
+
memberCommand.addCommand(memberSearchCommand);
|
|
2697
3486
|
|
|
2698
3487
|
// src/commands/mail/list.ts
|
|
2699
|
-
var
|
|
3488
|
+
var import_commander41 = require("commander");
|
|
2700
3489
|
|
|
2701
3490
|
// src/api/imapClient.ts
|
|
2702
3491
|
var import_imapflow = require("imapflow");
|
|
@@ -2804,7 +3593,7 @@ async function getMail(config, uid) {
|
|
|
2804
3593
|
|
|
2805
3594
|
// src/commands/mail/list.ts
|
|
2806
3595
|
var import_chalk5 = __toESM(require("chalk"));
|
|
2807
|
-
var mailListCommand = new
|
|
3596
|
+
var mailListCommand = new import_commander41.Command("list").description("\uBA54\uC77C \uBAA9\uB85D \uC870\uD68C").option("--unread", "\uC548\uC77D\uC740 \uBA54\uC77C\uB9CC").option("--search <keyword>", "\uC81C\uBAA9 \uAC80\uC0C9").option("--size <number>", "\uC870\uD68C \uAC1C\uC218", "20").action(async (opts) => {
|
|
2808
3597
|
const globalOpts = mailListCommand.optsWithGlobals();
|
|
2809
3598
|
const config = await getConfigOrThrow();
|
|
2810
3599
|
startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
|
|
@@ -2836,9 +3625,9 @@ var mailListCommand = new import_commander32.Command("list").description("\uBA54
|
|
|
2836
3625
|
});
|
|
2837
3626
|
|
|
2838
3627
|
// src/commands/mail/get.ts
|
|
2839
|
-
var
|
|
3628
|
+
var import_commander42 = require("commander");
|
|
2840
3629
|
var import_chalk6 = __toESM(require("chalk"));
|
|
2841
|
-
var mailGetCommand = new
|
|
3630
|
+
var mailGetCommand = new import_commander42.Command("get").description("\uBA54\uC77C \uC0C1\uC138 \uC870\uD68C").argument("<uid>", "\uBA54\uC77C UID").action(async (uid) => {
|
|
2842
3631
|
const globalOpts = mailGetCommand.optsWithGlobals();
|
|
2843
3632
|
const config = await getConfigOrThrow();
|
|
2844
3633
|
startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
|
|
@@ -2869,8 +3658,8 @@ ${mail.body}
|
|
|
2869
3658
|
});
|
|
2870
3659
|
|
|
2871
3660
|
// src/commands/mail/send.ts
|
|
2872
|
-
var
|
|
2873
|
-
var
|
|
3661
|
+
var import_commander43 = require("commander");
|
|
3662
|
+
var import_promises11 = require("fs/promises");
|
|
2874
3663
|
|
|
2875
3664
|
// src/api/smtpClient.ts
|
|
2876
3665
|
var import_nodemailer = __toESM(require("nodemailer"));
|
|
@@ -2919,12 +3708,12 @@ async function sendMail(config, opts) {
|
|
|
2919
3708
|
}
|
|
2920
3709
|
|
|
2921
3710
|
// src/commands/mail/send.ts
|
|
2922
|
-
var mailSendCommand = new
|
|
3711
|
+
var mailSendCommand = new import_commander43.Command("send").description("\uBA54\uC77C \uBC1C\uC1A1").requiredOption("--to <addresses...>", "\uBC1B\uB294\uC0AC\uB78C \uC774\uBA54\uC77C (\uBCF5\uC218 \uAC00\uB2A5)").requiredOption("--subject <title>", "\uC81C\uBAA9").option("--body <text>", "\uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--bcc <addresses...>", "\uC228\uC740\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (opts) => {
|
|
2923
3712
|
const globalOpts = mailSendCommand.optsWithGlobals();
|
|
2924
3713
|
const config = await getConfigOrThrow();
|
|
2925
3714
|
let body = opts.body ?? "";
|
|
2926
3715
|
if (opts.bodyFile) {
|
|
2927
|
-
body = await (0,
|
|
3716
|
+
body = await (0, import_promises11.readFile)(opts.bodyFile, "utf-8");
|
|
2928
3717
|
}
|
|
2929
3718
|
if (!body) {
|
|
2930
3719
|
process.stderr.write("\uC624\uB958: --body \uB610\uB294 --body-file\uC744 \uC9C0\uC815\uD558\uC138\uC694\n");
|
|
@@ -2954,8 +3743,8 @@ var mailSendCommand = new import_commander34.Command("send").description("\uBA54
|
|
|
2954
3743
|
});
|
|
2955
3744
|
|
|
2956
3745
|
// src/commands/mail/reply.ts
|
|
2957
|
-
var
|
|
2958
|
-
var
|
|
3746
|
+
var import_commander44 = require("commander");
|
|
3747
|
+
var import_promises12 = require("fs/promises");
|
|
2959
3748
|
var import_imapflow2 = require("imapflow");
|
|
2960
3749
|
async function getMessageId(config, uid) {
|
|
2961
3750
|
const imap = getImapConfigOrThrow(config);
|
|
@@ -2982,12 +3771,12 @@ async function getMessageId(config, uid) {
|
|
|
2982
3771
|
await client.logout();
|
|
2983
3772
|
}
|
|
2984
3773
|
}
|
|
2985
|
-
var mailReplyCommand = new
|
|
3774
|
+
var mailReplyCommand = new import_commander44.Command("reply").description("\uBA54\uC77C \uB2F5\uC7A5").argument("<uid>", "\uC6D0\uBCF8 \uBA54\uC77C UID").option("--body <text>", "\uB2F5\uC7A5 \uBCF8\uBB38").option("--body-file <path>", "\uB2F5\uC7A5 \uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (uid, opts) => {
|
|
2986
3775
|
const globalOpts = mailReplyCommand.optsWithGlobals();
|
|
2987
3776
|
const config = await getConfigOrThrow();
|
|
2988
3777
|
let body = opts.body ?? "";
|
|
2989
3778
|
if (opts.bodyFile) {
|
|
2990
|
-
body = await (0,
|
|
3779
|
+
body = await (0, import_promises12.readFile)(opts.bodyFile, "utf-8");
|
|
2991
3780
|
}
|
|
2992
3781
|
if (!body) {
|
|
2993
3782
|
process.stderr.write("\uC624\uB958: --body \uB610\uB294 --body-file\uC744 \uC9C0\uC815\uD558\uC138\uC694\n");
|
|
@@ -3022,20 +3811,299 @@ var mailReplyCommand = new import_commander35.Command("reply").description("\uBA
|
|
|
3022
3811
|
}
|
|
3023
3812
|
});
|
|
3024
3813
|
|
|
3814
|
+
// src/commands/feedback.ts
|
|
3815
|
+
var import_commander45 = require("commander");
|
|
3816
|
+
var import_node_child_process2 = require("child_process");
|
|
3817
|
+
var import_node_util = require("util");
|
|
3818
|
+
var import_promises15 = require("fs/promises");
|
|
3819
|
+
var import_node_os4 = require("os");
|
|
3820
|
+
var import_node_path11 = require("path");
|
|
3821
|
+
var import_node_crypto = require("crypto");
|
|
3822
|
+
var import_prompts = require("@inquirer/prompts");
|
|
3823
|
+
|
|
3824
|
+
// src/utils/feedback-meta.ts
|
|
3825
|
+
var import_promises13 = require("fs/promises");
|
|
3826
|
+
var import_node_path9 = require("path");
|
|
3827
|
+
async function readCliVersion() {
|
|
3828
|
+
const entry = process.argv[1];
|
|
3829
|
+
const here = entry ? (0, import_node_path9.dirname)(entry) : process.cwd();
|
|
3830
|
+
const candidates = [
|
|
3831
|
+
(0, import_node_path9.join)(here, "package.json"),
|
|
3832
|
+
(0, import_node_path9.join)(here, "..", "package.json"),
|
|
3833
|
+
(0, import_node_path9.join)(here, "..", "..", "package.json")
|
|
3834
|
+
];
|
|
3835
|
+
for (const p of candidates) {
|
|
3836
|
+
try {
|
|
3837
|
+
const raw = await (0, import_promises13.readFile)(p, "utf-8");
|
|
3838
|
+
const pkg = JSON.parse(raw);
|
|
3839
|
+
if (pkg.name === "@bifos/dooray-cli" && typeof pkg.version === "string") {
|
|
3840
|
+
return pkg.version;
|
|
3841
|
+
}
|
|
3842
|
+
} catch {
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3845
|
+
return "unknown";
|
|
3846
|
+
}
|
|
3847
|
+
function collectMeta(version) {
|
|
3848
|
+
return {
|
|
3849
|
+
cliVersion: version,
|
|
3850
|
+
nodeVersion: process.version,
|
|
3851
|
+
os: process.platform,
|
|
3852
|
+
arch: process.arch
|
|
3853
|
+
};
|
|
3854
|
+
}
|
|
3855
|
+
function buildLastRunBlock(last) {
|
|
3856
|
+
return [
|
|
3857
|
+
"## \uC9C1\uC804 \uC2E4\uD589 (\uC790\uB3D9 \uCCA8\uBD80)",
|
|
3858
|
+
"",
|
|
3859
|
+
"```",
|
|
3860
|
+
`$ ${last.argv.join(" ")}`,
|
|
3861
|
+
last.errorMessage.replace(/```/g, "'''"),
|
|
3862
|
+
"```",
|
|
3863
|
+
"",
|
|
3864
|
+
`- exit code: ${last.exitCode}`,
|
|
3865
|
+
`- \uC2DC\uAC01: ${last.timestamp}`
|
|
3866
|
+
].join("\n");
|
|
3867
|
+
}
|
|
3868
|
+
function buildIssueBody(userBody, meta) {
|
|
3869
|
+
return [
|
|
3870
|
+
"## \uD658\uACBD",
|
|
3871
|
+
`- dooray-cli \uBC84\uC804: ${meta.cliVersion}`,
|
|
3872
|
+
`- Node: ${meta.nodeVersion}`,
|
|
3873
|
+
`- OS: ${meta.os} ${meta.arch}`,
|
|
3874
|
+
"",
|
|
3875
|
+
"## \uC0AC\uC6A9\uC790 \uD53C\uB4DC\uBC31",
|
|
3876
|
+
"",
|
|
3877
|
+
userBody.trim(),
|
|
3878
|
+
""
|
|
3879
|
+
].join("\n");
|
|
3880
|
+
}
|
|
3881
|
+
|
|
3882
|
+
// src/cache/last-run.ts
|
|
3883
|
+
var import_promises14 = require("fs/promises");
|
|
3884
|
+
var import_node_path10 = require("path");
|
|
3885
|
+
var import_node_os3 = require("os");
|
|
3886
|
+
var LAST_RUN_PATH = (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".dooray", "last-run.json");
|
|
3887
|
+
function isLastRun(obj) {
|
|
3888
|
+
if (typeof obj !== "object" || obj === null) return false;
|
|
3889
|
+
const o = obj;
|
|
3890
|
+
return Array.isArray(o.argv) && o.argv.every((a) => typeof a === "string") && typeof o.exitCode === "number" && typeof o.errorMessage === "string" && typeof o.timestamp === "string";
|
|
3891
|
+
}
|
|
3892
|
+
async function readLastRun() {
|
|
3893
|
+
try {
|
|
3894
|
+
const raw = await (0, import_promises14.readFile)(LAST_RUN_PATH, "utf-8");
|
|
3895
|
+
const parsed = JSON.parse(raw);
|
|
3896
|
+
return isLastRun(parsed) ? parsed : null;
|
|
3897
|
+
} catch {
|
|
3898
|
+
return null;
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
async function writeLastRun(data) {
|
|
3902
|
+
await (0, import_promises14.mkdir)((0, import_node_path10.join)((0, import_node_os3.homedir)(), ".dooray"), { recursive: true });
|
|
3903
|
+
const tmp2 = LAST_RUN_PATH + ".tmp";
|
|
3904
|
+
await (0, import_promises14.writeFile)(tmp2, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
3905
|
+
await (0, import_promises14.rename)(tmp2, LAST_RUN_PATH);
|
|
3906
|
+
}
|
|
3907
|
+
|
|
3908
|
+
// src/commands/feedback.ts
|
|
3909
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
3910
|
+
var TARGET_REPO = "jon890/dooray-cli";
|
|
3911
|
+
async function ensureGhInstalled() {
|
|
3912
|
+
try {
|
|
3913
|
+
await execFileAsync("gh", ["--version"]);
|
|
3914
|
+
} catch {
|
|
3915
|
+
throw new DoorayCliError(
|
|
3916
|
+
"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",
|
|
3917
|
+
EXIT_PARAM_ERROR
|
|
3918
|
+
);
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
async function readBody(opts) {
|
|
3922
|
+
if (opts.body) return opts.body;
|
|
3923
|
+
if (opts.bodyFile) return await (0, import_promises15.readFile)(opts.bodyFile, "utf-8");
|
|
3924
|
+
return void 0;
|
|
3925
|
+
}
|
|
3926
|
+
var feedbackCommand = new import_commander45.Command("feedback").description("dooray-cli\uC5D0 \uB300\uD55C GitHub issue \uB4F1\uB85D (gh CLI \uC704\uC784)").option("--title <text>", "\uC774\uC288 \uC81C\uBAA9 (\uC5C6\uC73C\uBA74 \uC778\uD130\uB799\uD2F0\uBE0C)").option("--body <text>", "\uC774\uC288 \uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option(
|
|
3927
|
+
"--label <name>",
|
|
3928
|
+
"\uB77C\uBCA8 (\uBC18\uBCF5 \uAC00\uB2A5)",
|
|
3929
|
+
(value, prev) => [...prev, value],
|
|
3930
|
+
[]
|
|
3931
|
+
).option("--last", "\uC9C1\uC804 \uC2E4\uD589\uD55C dooray \uBA85\uB839\uC758 argv + \uC5D0\uB7EC\uB97C \uBCF8\uBB38 \uC0C1\uB2E8\uC5D0 \uC790\uB3D9 \uCCA8\uBD80").option("--dry-run", "gh \uD638\uCD9C \uC5C6\uC774 \uBCF8\uBB38\uB9CC \uBBF8\uB9AC\uBCF4\uAE30").action(async (opts) => {
|
|
3932
|
+
let title = opts.title;
|
|
3933
|
+
let userBody = await readBody(opts);
|
|
3934
|
+
let labels = [...opts.label];
|
|
3935
|
+
if (opts.last) {
|
|
3936
|
+
const last = await readLastRun();
|
|
3937
|
+
if (!last) {
|
|
3938
|
+
throw new DoorayCliError(
|
|
3939
|
+
"\uAE30\uB85D\uB41C \uC9C1\uC804 \uC2E4\uD589\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. config.json\uC5D0 trackLastRun: true \uC124\uC815 \uD6C4 dooray \uBA85\uB839 \uC2E4\uD589 \uC2DC \uC790\uB3D9 \uAE30\uB85D\uB429\uB2C8\uB2E4.\n \uC124\uC815: dooray config set track-last-run true",
|
|
3940
|
+
EXIT_PARAM_ERROR
|
|
3941
|
+
);
|
|
3942
|
+
}
|
|
3943
|
+
const lastBlock = buildLastRunBlock(last);
|
|
3944
|
+
if (userBody == null) {
|
|
3945
|
+
userBody = await (0, import_prompts.editor)({
|
|
3946
|
+
message: "\uBCF8\uBB38 \uC791\uC131 ($EDITOR\uAC00 \uC5F4\uB9BC)",
|
|
3947
|
+
default: lastBlock + "\n\n"
|
|
3948
|
+
});
|
|
3949
|
+
} else {
|
|
3950
|
+
userBody = lastBlock + "\n\n" + userBody;
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3953
|
+
if (!title) {
|
|
3954
|
+
title = await (0, import_prompts.input)({ message: "\uC774\uC288 \uC81C\uBAA9" });
|
|
3955
|
+
}
|
|
3956
|
+
if (!title || !title.trim()) {
|
|
3957
|
+
throw new DoorayCliError("\uC81C\uBAA9\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
3958
|
+
}
|
|
3959
|
+
if (labels.length === 0 && !opts.title && !opts.body && !opts.bodyFile) {
|
|
3960
|
+
const labelInput = await (0, import_prompts.input)({
|
|
3961
|
+
message: "\uB77C\uBCA8 (\uCF64\uB9C8\uB85C \uC5EC\uB7EC \uAC1C, \uBE44\uC6B0\uBA74 \uC5C6\uC74C)",
|
|
3962
|
+
default: ""
|
|
3963
|
+
});
|
|
3964
|
+
labels = labelInput.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3965
|
+
}
|
|
3966
|
+
if (userBody == null) {
|
|
3967
|
+
userBody = await (0, import_prompts.editor)({
|
|
3968
|
+
message: "\uBCF8\uBB38 \uC791\uC131 ($EDITOR\uAC00 \uC5F4\uB9BC)",
|
|
3969
|
+
default: ""
|
|
3970
|
+
});
|
|
3971
|
+
}
|
|
3972
|
+
if (!userBody.trim()) {
|
|
3973
|
+
throw new DoorayCliError("\uBCF8\uBB38\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
3974
|
+
}
|
|
3975
|
+
const version = await readCliVersion();
|
|
3976
|
+
const meta = collectMeta(version);
|
|
3977
|
+
const issueBody = buildIssueBody(userBody, meta);
|
|
3978
|
+
if (opts.dryRun) {
|
|
3979
|
+
process.stdout.write("--- DRY RUN ---\n");
|
|
3980
|
+
process.stdout.write(`Repo: ${TARGET_REPO}
|
|
3981
|
+
`);
|
|
3982
|
+
process.stdout.write(`Title: ${title}
|
|
3983
|
+
`);
|
|
3984
|
+
process.stdout.write(
|
|
3985
|
+
`Labels: ${labels.length > 0 ? labels.join(", ") : "(\uC5C6\uC74C)"}
|
|
3986
|
+
`
|
|
3987
|
+
);
|
|
3988
|
+
process.stdout.write("Body:\n");
|
|
3989
|
+
process.stdout.write(issueBody);
|
|
3990
|
+
process.stdout.write("--- END ---\n");
|
|
3991
|
+
return;
|
|
3992
|
+
}
|
|
3993
|
+
const isInteractive = !opts.title;
|
|
3994
|
+
if (isInteractive) {
|
|
3995
|
+
process.stderr.write("\n--- \uBBF8\uB9AC\uBCF4\uAE30 ---\n");
|
|
3996
|
+
process.stderr.write(`Repo: ${TARGET_REPO}
|
|
3997
|
+
`);
|
|
3998
|
+
process.stderr.write(`Title: ${title}
|
|
3999
|
+
`);
|
|
4000
|
+
process.stderr.write(
|
|
4001
|
+
`Labels: ${labels.length > 0 ? labels.join(", ") : "(\uC5C6\uC74C)"}
|
|
4002
|
+
`
|
|
4003
|
+
);
|
|
4004
|
+
process.stderr.write("Body:\n");
|
|
4005
|
+
process.stderr.write(issueBody);
|
|
4006
|
+
process.stderr.write("--- \uB05D ---\n\n");
|
|
4007
|
+
const ok = await (0, import_prompts.confirm)({
|
|
4008
|
+
message: "\uC774 \uB0B4\uC6A9\uC73C\uB85C \uB4F1\uB85D\uD560\uAE4C\uC694?",
|
|
4009
|
+
default: true
|
|
4010
|
+
});
|
|
4011
|
+
if (!ok) {
|
|
4012
|
+
process.stderr.write("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n");
|
|
4013
|
+
return;
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
await ensureGhInstalled();
|
|
4017
|
+
const bodyFile = (0, import_node_path11.join)((0, import_node_os4.tmpdir)(), `dooray-feedback-${(0, import_node_crypto.randomUUID)()}.md`);
|
|
4018
|
+
await (0, import_promises15.writeFile)(bodyFile, issueBody);
|
|
4019
|
+
try {
|
|
4020
|
+
const args = [
|
|
4021
|
+
"issue",
|
|
4022
|
+
"create",
|
|
4023
|
+
"--repo",
|
|
4024
|
+
TARGET_REPO,
|
|
4025
|
+
"--title",
|
|
4026
|
+
title,
|
|
4027
|
+
"--body-file",
|
|
4028
|
+
bodyFile
|
|
4029
|
+
];
|
|
4030
|
+
for (const l of labels) {
|
|
4031
|
+
args.push("--label", l);
|
|
4032
|
+
}
|
|
4033
|
+
const { stdout } = await execFileAsync("gh", args);
|
|
4034
|
+
process.stdout.write(stdout);
|
|
4035
|
+
} catch (err) {
|
|
4036
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4037
|
+
throw new DoorayCliError(
|
|
4038
|
+
`GitHub issue \uC0DD\uC131 \uC2E4\uD328:
|
|
4039
|
+
${msg}
|
|
4040
|
+
|
|
4041
|
+
gh \uC778\uC99D \uC548 \uB418\uC5B4 \uC788\uC73C\uBA74: gh auth login`,
|
|
4042
|
+
EXIT_PARAM_ERROR
|
|
4043
|
+
);
|
|
4044
|
+
} finally {
|
|
4045
|
+
await (0, import_promises15.unlink)(bodyFile).catch(() => {
|
|
4046
|
+
});
|
|
4047
|
+
}
|
|
4048
|
+
});
|
|
4049
|
+
|
|
4050
|
+
// src/utils/argv-sanitize.ts
|
|
4051
|
+
var KEY_VALUE_PATTERNS = [
|
|
4052
|
+
/^(--api-key|--token|--password)=(.+)$/
|
|
4053
|
+
];
|
|
4054
|
+
var SEPARATED_KEYS = /* @__PURE__ */ new Set(["--api-key", "--token", "--password"]);
|
|
4055
|
+
function sanitizeArgv(argv) {
|
|
4056
|
+
const out = [];
|
|
4057
|
+
for (let i = 0; i < argv.length; i++) {
|
|
4058
|
+
const a = argv[i];
|
|
4059
|
+
let kvMatch = null;
|
|
4060
|
+
for (const re of KEY_VALUE_PATTERNS) {
|
|
4061
|
+
const m = re.exec(a);
|
|
4062
|
+
if (m) {
|
|
4063
|
+
kvMatch = m;
|
|
4064
|
+
break;
|
|
4065
|
+
}
|
|
4066
|
+
}
|
|
4067
|
+
if (kvMatch) {
|
|
4068
|
+
out.push(`${kvMatch[1]}=***`);
|
|
4069
|
+
continue;
|
|
4070
|
+
}
|
|
4071
|
+
if (SEPARATED_KEYS.has(a)) {
|
|
4072
|
+
out.push(a);
|
|
4073
|
+
if (i + 1 < argv.length) {
|
|
4074
|
+
out.push("***");
|
|
4075
|
+
i++;
|
|
4076
|
+
}
|
|
4077
|
+
continue;
|
|
4078
|
+
}
|
|
4079
|
+
if (/^Authorization\s*:/i.test(a) || /^Bearer\s+\S+/.test(a)) {
|
|
4080
|
+
out.push(a.replace(/(Authorization\s*:\s*).+/i, "$1***").replace(/^(Bearer\s+).+/i, "$1***"));
|
|
4081
|
+
continue;
|
|
4082
|
+
}
|
|
4083
|
+
out.push(a);
|
|
4084
|
+
}
|
|
4085
|
+
return out;
|
|
4086
|
+
}
|
|
4087
|
+
|
|
3025
4088
|
// src/index.ts
|
|
3026
|
-
var program = new
|
|
3027
|
-
program.name("dooray").description("Dooray REST API CLI").version("0.
|
|
4089
|
+
var program = new import_commander46.Command();
|
|
4090
|
+
program.name("dooray").description("Dooray REST API CLI").version("0.6.0").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "ID\uB9CC \uCD9C\uB825").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654");
|
|
3028
4091
|
program.hook("preAction", () => {
|
|
3029
4092
|
const opts = program.opts();
|
|
3030
4093
|
if (opts.color === false || process.env.NO_COLOR) {
|
|
3031
4094
|
import_chalk7.default.level = 0;
|
|
3032
4095
|
}
|
|
4096
|
+
if (opts.json || opts.quiet) {
|
|
4097
|
+
setQuiet(true);
|
|
4098
|
+
}
|
|
3033
4099
|
});
|
|
3034
|
-
var projectCommand = new
|
|
4100
|
+
var projectCommand = new import_commander46.Command("project").description("\uD504\uB85C\uC81D\uD2B8 \uAD00\uB828 \uBA85\uB839");
|
|
3035
4101
|
projectCommand.addCommand(projectListCommand);
|
|
3036
4102
|
projectCommand.addCommand(projectMembersCommand);
|
|
3037
4103
|
projectCommand.addCommand(projectWorkflowsCommand);
|
|
3038
|
-
|
|
4104
|
+
projectCommand.addCommand(projectGroupsCommand);
|
|
4105
|
+
projectCommand.addCommand(projectTagsCommand);
|
|
4106
|
+
var postCommand = new import_commander46.Command("post").description("\uC5C5\uBB34 \uAD00\uB828 \uBA85\uB839");
|
|
3039
4107
|
postCommand.addCommand(postListCommand);
|
|
3040
4108
|
postCommand.addCommand(postSearchCommand);
|
|
3041
4109
|
postCommand.addCommand(postGetCommand);
|
|
@@ -3043,28 +4111,30 @@ postCommand.addCommand(postEditCommand);
|
|
|
3043
4111
|
postCommand.addCommand(postCreateCommand);
|
|
3044
4112
|
postCommand.addCommand(postDoneCommand);
|
|
3045
4113
|
postCommand.addCommand(postWorkflowCommand);
|
|
3046
|
-
var commentCommand = new
|
|
4114
|
+
var commentCommand = new import_commander46.Command("comment").description("\uB313\uAE00 \uAD00\uB828 \uBA85\uB839");
|
|
3047
4115
|
commentCommand.addCommand(commentListCommand);
|
|
4116
|
+
commentCommand.addCommand(commentLatestCommand);
|
|
3048
4117
|
commentCommand.addCommand(commentAddCommand);
|
|
3049
4118
|
commentCommand.addCommand(commentEditCommand);
|
|
3050
4119
|
commentCommand.addCommand(commentDeleteCommand);
|
|
4120
|
+
commentCommand.addCommand(commentFileCommand);
|
|
3051
4121
|
postCommand.addCommand(commentCommand);
|
|
3052
|
-
var fileCommand = new
|
|
4122
|
+
var fileCommand = new import_commander46.Command("file").description("\uCCA8\uBD80\uD30C\uC77C \uAD00\uB828 \uBA85\uB839");
|
|
3053
4123
|
fileCommand.addCommand(fileListCommand);
|
|
3054
4124
|
fileCommand.addCommand(fileDownloadCommand);
|
|
3055
4125
|
fileCommand.addCommand(fileDownloadAllCommand);
|
|
3056
4126
|
fileCommand.addCommand(fileUploadCommand);
|
|
3057
4127
|
fileCommand.addCommand(fileDeleteCommand);
|
|
3058
4128
|
postCommand.addCommand(fileCommand);
|
|
3059
|
-
var wikiCommand = new
|
|
4129
|
+
var wikiCommand = new import_commander46.Command("wiki").description("\uC704\uD0A4 \uAD00\uB828 \uBA85\uB839");
|
|
3060
4130
|
wikiCommand.addCommand(wikiListCommand);
|
|
3061
4131
|
wikiCommand.addCommand(wikiPagesCommand);
|
|
3062
|
-
var wikiPageCommand = new
|
|
4132
|
+
var wikiPageCommand = new import_commander46.Command("page").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uAD00\uB828 \uBA85\uB839");
|
|
3063
4133
|
wikiPageCommand.addCommand(wikiPageGetCommand);
|
|
3064
4134
|
wikiPageCommand.addCommand(wikiPageCreateCommand);
|
|
3065
4135
|
wikiPageCommand.addCommand(wikiPageEditCommand);
|
|
3066
4136
|
wikiCommand.addCommand(wikiPageCommand);
|
|
3067
|
-
var mailCommand = new
|
|
4137
|
+
var mailCommand = new import_commander46.Command("mail").description("\uBA54\uC77C \uAD00\uB828 \uBA85\uB839");
|
|
3068
4138
|
mailCommand.addCommand(mailListCommand);
|
|
3069
4139
|
mailCommand.addCommand(mailGetCommand);
|
|
3070
4140
|
mailCommand.addCommand(mailSendCommand);
|
|
@@ -3078,11 +4148,25 @@ program.addCommand(projectCommand);
|
|
|
3078
4148
|
program.addCommand(postCommand);
|
|
3079
4149
|
program.addCommand(wikiCommand);
|
|
3080
4150
|
program.addCommand(mailCommand);
|
|
3081
|
-
program.
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
4151
|
+
program.addCommand(feedbackCommand);
|
|
4152
|
+
program.parseAsync().catch(async (err) => {
|
|
4153
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
4154
|
+
const exitCode = err instanceof DoorayCliError ? err.exitCode : 1;
|
|
4155
|
+
try {
|
|
4156
|
+
const config = await getConfig();
|
|
4157
|
+
const sanitized = sanitizeArgv(process.argv.slice(2));
|
|
4158
|
+
const firstNonFlag = sanitized.find((a) => !a.startsWith("-"));
|
|
4159
|
+
const isFeedbackCommand = firstNonFlag === "feedback";
|
|
4160
|
+
if (config?.trackLastRun && !isFeedbackCommand) {
|
|
4161
|
+
await writeLastRun({
|
|
4162
|
+
argv: ["dooray", ...sanitized],
|
|
4163
|
+
exitCode,
|
|
4164
|
+
errorMessage,
|
|
4165
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4166
|
+
});
|
|
4167
|
+
}
|
|
4168
|
+
} catch {
|
|
3085
4169
|
}
|
|
3086
|
-
process.stderr.write(import_chalk7.default.red(`\uC624\uB958: ${
|
|
3087
|
-
process.exit(
|
|
4170
|
+
process.stderr.write(import_chalk7.default.red(`\uC624\uB958: ${errorMessage}`) + "\n");
|
|
4171
|
+
process.exit(exitCode);
|
|
3088
4172
|
});
|