@shortcut-cli/shortcut-cli 3.8.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +121 -2
  2. package/build/bin/{short-api.js → short-api.cjs} +12 -10
  3. package/build/bin/short-create.cjs +58 -0
  4. package/build/bin/{short-doc.js → short-doc.cjs} +8 -9
  5. package/build/bin/{short-docs.js → short-docs.cjs} +18 -19
  6. package/build/bin/{short-epic.js → short-epic.cjs} +8 -9
  7. package/build/bin/short-epics.cjs +36 -0
  8. package/build/bin/{short-find.js → short-find.cjs} +1 -1
  9. package/build/bin/{short-install.js → short-install.cjs} +8 -9
  10. package/build/bin/short-iteration.cjs +184 -0
  11. package/build/bin/short-iterations.cjs +66 -0
  12. package/build/bin/{short-members.js → short-members.cjs} +6 -7
  13. package/build/bin/{short-projects.js → short-projects.cjs} +7 -8
  14. package/build/bin/{short-search.js → short-search.cjs} +20 -25
  15. package/build/bin/{short-story.js → short-story.cjs} +47 -46
  16. package/build/bin/{short-workflows.js → short-workflows.cjs} +5 -6
  17. package/build/bin/short-workspace.cjs +64 -0
  18. package/build/bin/short.cjs +10 -0
  19. package/build/lib/client.cjs +11 -0
  20. package/build/lib/{configure.js → configure.cjs} +3 -3
  21. package/build/lib/{spinner.js → spinner.cjs} +1 -1
  22. package/build/lib/{stories.js → stories.cjs} +73 -69
  23. package/build/{package.js → package.cjs} +1 -1
  24. package/package.json +67 -67
  25. package/build/bin/short-create.js +0 -56
  26. package/build/bin/short-epics.js +0 -37
  27. package/build/bin/short-workspace.js +0 -64
  28. package/build/bin/short.js +0 -11
  29. package/build/lib/client.js +0 -11
  30. /package/build/_virtual/{rolldown_runtime.js → rolldown_runtime.cjs} +0 -0
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_configure = require('../lib/configure.cjs');
5
+ const require_lib_client = require('../lib/client.cjs');
6
+ const require_lib_stories = require('../lib/stories.cjs');
7
+ let commander = require("commander");
8
+ let child_process = require("child_process");
9
+ let chalk = require("chalk");
10
+ chalk = require_rolldown_runtime.__toESM(chalk);
11
+
12
+ //#region src/bin/short-iteration.ts
13
+ const config = require_lib_configure.loadConfig();
14
+ const spin = require_lib_spinner.default();
15
+ const log = console.log;
16
+ const program = new commander.Command().usage("[command] [options]").description("view, create, update, or delete iterations");
17
+ program.command("view <id>").description("view an iteration by id").option("-O, --open", "Open iteration in browser").action(viewIteration);
18
+ program.command("create").description("create a new iteration").option("-n, --name [text]", "Set name of iteration, required", "").option("-d, --description [text]", "Set description of iteration", "").option("--start-date [date]", "Set start date (YYYY-MM-DD), required", "").option("--end-date [date]", "Set end date (YYYY-MM-DD), required", "").option("-T, --team [id|name]", "Set team/group of iteration", "").option("-I, --idonly", "Print only ID of iteration result").option("-O, --open", "Open iteration in browser").action(createIteration);
19
+ program.command("update <id>").description("update an existing iteration").option("-n, --name [text]", "Set name of iteration", "").option("-d, --description [text]", "Set description of iteration", "").option("--start-date [date]", "Set start date (YYYY-MM-DD)", "").option("--end-date [date]", "Set end date (YYYY-MM-DD)", "").option("-T, --team [id|name]", "Set team/group of iteration", "").option("-O, --open", "Open iteration in browser").action(updateIteration);
20
+ program.command("delete <id>").description("delete an iteration").action(deleteIteration);
21
+ program.command("stories <id>").description("list stories in an iteration").option("-f, --format [template]", "Format each story output by template", "").action(listIterationStories);
22
+ program.parse(process.argv);
23
+ async function viewIteration(id, options) {
24
+ spin.start();
25
+ try {
26
+ const iteration = await require_lib_client.default.getIteration(parseInt(id, 10)).then((r) => r.data);
27
+ spin.stop(true);
28
+ printIteration(iteration);
29
+ if (options.open) (0, child_process.exec)(`open https://app.shortcut.com/${config.urlSlug}/iteration/${iteration.id}`);
30
+ } catch (e) {
31
+ spin.stop(true);
32
+ const error = e;
33
+ if (error.response?.status === 404) log(`Iteration #${id} not found`);
34
+ else log("Error fetching iteration:", error.message ?? String(e));
35
+ process.exit(1);
36
+ }
37
+ }
38
+ async function createIteration(options) {
39
+ const entities = await require_lib_stories.default.fetchEntities();
40
+ if (!options.idonly) spin.start();
41
+ const iterationData = {
42
+ name: options.name || "",
43
+ start_date: options.startDate || "",
44
+ end_date: options.endDate || ""
45
+ };
46
+ if (options.description) iterationData.description = options.description;
47
+ if (options.team) {
48
+ const group = require_lib_stories.default.findGroup(entities, options.team);
49
+ if (group?.id) iterationData.group_ids = [group.id];
50
+ }
51
+ if (!iterationData.name) {
52
+ if (!options.idonly) spin.stop(true);
53
+ log("Must provide --name");
54
+ process.exit(1);
55
+ }
56
+ if (!iterationData.start_date) {
57
+ if (!options.idonly) spin.stop(true);
58
+ log("Must provide --start-date");
59
+ process.exit(1);
60
+ }
61
+ if (!iterationData.end_date) {
62
+ if (!options.idonly) spin.stop(true);
63
+ log("Must provide --end-date");
64
+ process.exit(1);
65
+ }
66
+ let iteration;
67
+ try {
68
+ iteration = await require_lib_client.default.createIteration(iterationData).then((r) => r.data);
69
+ } catch (e) {
70
+ if (!options.idonly) spin.stop(true);
71
+ log("Error creating iteration:", e.message ?? String(e));
72
+ process.exit(1);
73
+ }
74
+ if (!options.idonly) spin.stop(true);
75
+ if (iteration) if (options.idonly) log(iteration.id);
76
+ else {
77
+ printIteration(iteration);
78
+ if (options.open) (0, child_process.exec)(`open https://app.shortcut.com/${config.urlSlug}/iteration/${iteration.id}`);
79
+ }
80
+ }
81
+ async function updateIteration(id, options) {
82
+ const entities = await require_lib_stories.default.fetchEntities();
83
+ spin.start();
84
+ const updateData = {};
85
+ if (options.name) updateData.name = options.name;
86
+ if (options.description) updateData.description = options.description;
87
+ if (options.startDate) updateData.start_date = options.startDate;
88
+ if (options.endDate) updateData.end_date = options.endDate;
89
+ if (options.team) {
90
+ const group = require_lib_stories.default.findGroup(entities, options.team);
91
+ if (group?.id) updateData.group_ids = [group.id];
92
+ }
93
+ if (Object.keys(updateData).length === 0) {
94
+ spin.stop(true);
95
+ log("No updates provided. Use --name, --description, --start-date, --end-date, or --team");
96
+ process.exit(1);
97
+ }
98
+ let iteration;
99
+ try {
100
+ iteration = await require_lib_client.default.updateIteration(parseInt(id, 10), updateData).then((r) => r.data);
101
+ } catch (e) {
102
+ spin.stop(true);
103
+ const error = e;
104
+ if (error.response?.status === 404) log(`Iteration #${id} not found`);
105
+ else log("Error updating iteration:", error.message ?? String(e));
106
+ process.exit(1);
107
+ }
108
+ spin.stop(true);
109
+ if (iteration) {
110
+ printIteration(iteration);
111
+ if (options.open) (0, child_process.exec)(`open https://app.shortcut.com/${config.urlSlug}/iteration/${iteration.id}`);
112
+ }
113
+ }
114
+ async function deleteIteration(id) {
115
+ spin.start();
116
+ try {
117
+ await require_lib_client.default.deleteIteration(parseInt(id, 10));
118
+ spin.stop(true);
119
+ log(`Iteration #${id} deleted successfully`);
120
+ } catch (e) {
121
+ spin.stop(true);
122
+ const error = e;
123
+ if (error.response?.status === 404) log(`Iteration #${id} not found`);
124
+ else log("Error deleting iteration:", error.message ?? String(e));
125
+ process.exit(1);
126
+ }
127
+ }
128
+ async function listIterationStories(id, options) {
129
+ spin.start();
130
+ try {
131
+ const [stories, entities] = await Promise.all([require_lib_client.default.listIterationStories(parseInt(id, 10)).then((r) => r.data), require_lib_stories.default.fetchEntities()]);
132
+ spin.stop(true);
133
+ if (stories.length === 0) {
134
+ log(`No stories found in iteration #${id}`);
135
+ return;
136
+ }
137
+ log(chalk.default.bold(`Stories in iteration #${id}:`));
138
+ log();
139
+ stories.forEach((story) => {
140
+ const hydrated = require_lib_stories.default.hydrateStory(entities, story);
141
+ if (options.format) require_lib_stories.default.printFormattedStory({ format: options.format })(hydrated);
142
+ else {
143
+ const state = hydrated.state?.name ?? "Unknown";
144
+ const owners = hydrated.owners?.map((o) => o?.profile.mention_name).filter(Boolean).join(", ");
145
+ log(`${chalk.default.bold("#" + story.id)} ${chalk.default.blue(story.name)}`);
146
+ log(` Type: ${story.story_type} | State: ${state} | Owners: ${owners || "_"}`);
147
+ log(` Points: ${story.estimate ?? "_"}`);
148
+ log();
149
+ }
150
+ });
151
+ } catch (e) {
152
+ spin.stop(true);
153
+ const error = e;
154
+ if (error.response?.status === 404) log(`Iteration #${id} not found`);
155
+ else log("Error fetching stories:", error.message ?? String(e));
156
+ process.exit(1);
157
+ }
158
+ }
159
+ function printIteration(iteration) {
160
+ const stats = iteration.stats;
161
+ const totalStories = stats.num_stories_done + stats.num_stories_started + stats.num_stories_unstarted + stats.num_stories_backlog;
162
+ const completionPct = stats.num_points > 0 ? Math.round(stats.num_points_done / stats.num_points * 100) : 0;
163
+ log(chalk.default.blue.bold(`#${iteration.id}`) + chalk.default.blue(` ${iteration.name}`));
164
+ if (iteration.description) log(chalk.default.bold("Description:") + ` ${iteration.description}`);
165
+ log(chalk.default.bold("Status:") + ` ${formatStatus(iteration.status)}`);
166
+ log(chalk.default.bold("Start Date:") + ` ${iteration.start_date}`);
167
+ log(chalk.default.bold("End Date:") + ` ${iteration.end_date}`);
168
+ if (iteration.group_ids && iteration.group_ids.length > 0) log(chalk.default.bold("Teams:") + ` ${iteration.group_ids.join(", ")}`);
169
+ log(chalk.default.bold("Stories:") + ` ${totalStories} (${stats.num_stories_done} done)`);
170
+ log(chalk.default.bold("Points:") + ` ${stats.num_points} (${stats.num_points_done} done)`);
171
+ log(chalk.default.bold("Completion:") + ` ${completionPct}%`);
172
+ log(chalk.default.bold("URL:") + ` ${iteration.app_url}`);
173
+ log();
174
+ }
175
+ function formatStatus(status) {
176
+ switch (status) {
177
+ case "started": return chalk.default.green(status);
178
+ case "done": return chalk.default.gray(status);
179
+ case "unstarted":
180
+ default: return chalk.default.yellow(status);
181
+ }
182
+ }
183
+
184
+ //#endregion
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_configure = require('../lib/configure.cjs');
5
+ const require_lib_client = require('../lib/client.cjs');
6
+ let commander = require("commander");
7
+ let chalk = require("chalk");
8
+ chalk = require_rolldown_runtime.__toESM(chalk);
9
+
10
+ //#region src/bin/short-iterations.ts
11
+ const config = require_lib_configure.loadConfig();
12
+ const log = console.log;
13
+ const spin = require_lib_spinner.default();
14
+ const opts = new commander.Command().description("Display iterations available for stories").option("-S, --status [status]", "Filter by status (unstarted, started, done)", "").option("-T, --team [id|name]", "Filter by team/group id or name", "").option("-C, --current", "Show only current/active iterations", false).option("-t, --title [query]", "Filter iterations with name containing query", "").option("-d, --detailed", "Show more details for each iteration", false).option("-f, --format [template]", "Format each iteration output by template", "").parse(process.argv).opts();
15
+ const main = async () => {
16
+ spin.start();
17
+ const [iterations, groups] = await Promise.all([require_lib_client.default.listIterations(null).then((r) => r.data), require_lib_client.default.listGroups().then((r) => r.data)]);
18
+ spin.stop(true);
19
+ const textMatch = new RegExp(opts.title ?? "", "i");
20
+ const statusMatch = opts.status ? new RegExp(opts.status, "i") : null;
21
+ const groupsById = new Map(groups.map((g) => [g.id, g]));
22
+ const now = /* @__PURE__ */ new Date();
23
+ iterations.filter((iteration) => {
24
+ if (!iteration.name.match(textMatch)) return false;
25
+ if (statusMatch && !iteration.status.match(statusMatch)) return false;
26
+ if (opts.team) {
27
+ const teamMatch = new RegExp(opts.team, "i");
28
+ if (!iteration.group_ids?.map((id) => groupsById.get(id)).find((g) => g && (g.id.match(teamMatch) || g.name.match(teamMatch)))) return false;
29
+ }
30
+ if (opts.current) {
31
+ const start = new Date(iteration.start_date);
32
+ const end = new Date(iteration.end_date);
33
+ if (now < start || now > end) return false;
34
+ }
35
+ return true;
36
+ }).sort((a, b) => {
37
+ return new Date(b.start_date).getTime() - new Date(a.start_date).getTime();
38
+ }).forEach((iteration) => printItem(iteration, groupsById));
39
+ };
40
+ const printItem = (iteration, groupsById) => {
41
+ const stats = iteration.stats;
42
+ const groups = iteration.group_ids?.map((id) => groupsById.get(id)?.name).filter(Boolean) ?? [];
43
+ const totalStories = stats.num_stories_done + stats.num_stories_started + stats.num_stories_unstarted + stats.num_stories_backlog;
44
+ let defaultFormat = `#%id %t\nStatus:\t\t%s\nStart:\t\t%start\nEnd:\t\t%end\n`;
45
+ defaultFormat += `Teams:\t\t%teams\n`;
46
+ defaultFormat += `Stories:\t%stories (%done done)\nPoints:\t\t%points (%pdone done)\n`;
47
+ if (opts.detailed) {
48
+ defaultFormat += `Completion:\t%completion%\n`;
49
+ defaultFormat += `URL:\t\t%url\n`;
50
+ }
51
+ const format = opts.format || defaultFormat;
52
+ const url = `https://app.shortcut.com/${config.urlSlug}/iteration/${iteration.id}`;
53
+ const completionPct = stats.num_points > 0 ? Math.round(stats.num_points_done / stats.num_points * 100) : 0;
54
+ log(format.replace(/%id/, chalk.default.bold(`${iteration.id}`)).replace(/%t/, chalk.default.blue(`${iteration.name}`)).replace(/%s/, formatStatus(iteration.status)).replace(/%start/, `${iteration.start_date}`).replace(/%end/, `${iteration.end_date}`).replace(/%teams/, groups.join(", ") || "_").replace(/%stories/, `${totalStories}`).replace(/%done/, `${stats.num_stories_done}`).replace(/%points/, `${stats.num_points}`).replace(/%pdone/, `${stats.num_points_done}`).replace(/%completion/, `${completionPct}`).replace(/%url/, url));
55
+ };
56
+ const formatStatus = (status) => {
57
+ switch (status) {
58
+ case "started": return chalk.default.green(status);
59
+ case "done": return chalk.default.gray(status);
60
+ case "unstarted":
61
+ default: return chalk.default.yellow(status);
62
+ }
63
+ };
64
+ main();
65
+
66
+ //#endregion
@@ -1,27 +1,26 @@
1
1
  #!/usr/bin/env node
2
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
3
- const require_lib_spinner = require('../lib/spinner.js');
4
- const require_lib_client = require('../lib/client.js');
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_client = require('../lib/client.cjs');
5
5
  let commander = require("commander");
6
- commander = require_rolldown_runtime.__toESM(commander);
7
6
  let chalk = require("chalk");
8
7
  chalk = require_rolldown_runtime.__toESM(chalk);
9
8
 
10
9
  //#region src/bin/short-members.ts
11
10
  const spin = require_lib_spinner.default("Loading... %s ");
12
11
  const log = console.log;
13
- const program = commander.default.description("Display members available for stories").option("-s, --search [query]", "List members with name containing query", "").option("-d, --disabled", "List members including disabled", "").parse(process.argv);
12
+ const opts = new commander.Command().description("Display members available for stories").option("-s, --search [query]", "List members with name containing query", "").option("-d, --disabled", "List members including disabled", "").parse(process.argv).opts();
14
13
  const main = async () => {
15
14
  spin.start();
16
15
  const members = await require_lib_client.default.listMembers(null).then((r) => r.data);
17
16
  spin.stop(true);
18
- const ownerMatch = new RegExp(program.search, "i");
17
+ const ownerMatch = new RegExp(opts.search ?? "", "i");
19
18
  members.filter((o) => {
20
19
  return !!`${o.profile.name} ${o.profile.mention_name}`.match(ownerMatch);
21
20
  }).map(printMember);
22
21
  };
23
22
  const printMember = (member) => {
24
- if (member.disabled && !program.disabled) return;
23
+ if (member.disabled && !opts.disabled) return;
25
24
  log(chalk.default.bold(`#${member.id}`));
26
25
  log(chalk.default.bold("Name: ") + ` ${member.profile.name}`);
27
26
  log(chalk.default.bold("Mention Name: ") + ` ${member.profile.mention_name}`);
@@ -1,33 +1,32 @@
1
1
  #!/usr/bin/env node
2
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
3
- const require_lib_spinner = require('../lib/spinner.js');
4
- const require_lib_client = require('../lib/client.js');
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_client = require('../lib/client.cjs');
5
5
  let commander = require("commander");
6
- commander = require_rolldown_runtime.__toESM(commander);
7
6
  let chalk = require("chalk");
8
7
  chalk = require_rolldown_runtime.__toESM(chalk);
9
8
 
10
9
  //#region src/bin/short-projects.ts
11
10
  const spin = require_lib_spinner.default();
12
11
  const log = console.log;
13
- const program = commander.default.description("Display projects available for stories").option("-a, --archived", "List only projects including archived", "").option("-d, --detailed", "List more details for each project", "").option("-t, --title [query]", "List projects with name/title containing query", "").parse(process.argv);
12
+ const opts = new commander.Command().description("Display projects available for stories").option("-a, --archived", "List only projects including archived", "").option("-d, --detailed", "List more details for each project", "").option("-t, --title [query]", "List projects with name/title containing query", "").parse(process.argv).opts();
14
13
  const main = async () => {
15
14
  spin.start();
16
15
  const projects = await require_lib_client.default.listProjects().then((r) => r.data);
17
16
  spin.stop(true);
18
- const textMatch = new RegExp(program.title, "i");
17
+ const textMatch = new RegExp(opts.title ?? "", "i");
19
18
  projects.filter((o) => {
20
19
  return !!`${o.name} ${o.name}`.match(textMatch);
21
20
  }).map(printItem);
22
21
  };
23
22
  const printItem = (proj) => {
24
- if (proj.archived && !program.archived) return;
23
+ if (proj.archived && !opts.archived) return;
25
24
  log(chalk.default.bold(`#${proj.id}`) + chalk.default.blue(` ${proj.name}`));
26
25
  log(chalk.default.bold("Points: ") + ` ${proj.stats.num_points}`);
27
26
  log(chalk.default.bold("Stories: ") + ` ${proj.stats.num_stories}`);
28
27
  log(chalk.default.bold("Started: ") + ` ${proj.start_time}`);
29
28
  if (proj.archived) log(chalk.default.bold("Archived: ") + ` ${proj.archived}`);
30
- if (program.detailed) log(chalk.default.bold("Description: ") + ` ${proj.description}`);
29
+ if (opts.detailed) log(chalk.default.bold("Description: ") + ` ${proj.description}`);
31
30
  log();
32
31
  };
33
32
  main();
@@ -1,16 +1,14 @@
1
1
  #!/usr/bin/env node
2
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
3
- const require_lib_spinner = require('../lib/spinner.js');
4
- const require_lib_configure = require('../lib/configure.js');
5
- const require_lib_stories = require('../lib/stories.js');
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_configure = require('../lib/configure.cjs');
5
+ const require_lib_stories = require('../lib/stories.cjs');
6
6
  let commander = require("commander");
7
- commander = require_rolldown_runtime.__toESM(commander);
8
7
 
9
8
  //#region src/bin/short-search.ts
10
- var _process$argv$;
11
9
  const spin = require_lib_spinner.default("Finding... %s ");
12
10
  const log = console.log;
13
- const program = commander.default.description(`Search through Shortcut stories. Arguments (non-flag/options) will be
11
+ const program = new commander.Command().description(`Search through Shortcut stories. Arguments (non-flag/options) will be
14
12
  passed to Shortcut story search API as search operators. Passing '%self%' as
15
13
  a search operator argument will be replaced by your mention name. Note that
16
14
  passing search operators and options (e.g. --owner foobar) will use the
@@ -18,36 +16,33 @@ const program = commander.default.description(`Search through Shortcut stories.
18
16
 
19
17
  Refer to https://help.shortcut.com/hc/en-us/articles/360000046646-Search-Operators
20
18
  for more details about search operators.`).usage("[options] [SEARCH OPERATORS]").option("-a, --archived", "Include archived Stories").option("-c, --created [operator][date]", "Stories created within criteria (operator is one of <|>|=)", "").option("-q, --quiet", "Print only story output, no loading dialog", "").option("-l, --label [id|name]", "Stories with label id/name, by regex", "").option("-o, --owner [name]", "Stories with owner, by regex", "").option("-p, --project [id]", "Stories in project", "").option("-s, --state [id|name]", "Stories in workflow state id/name, by regex", "").option("--epic [id|name]", "Stories in epic id/name, by regex", "").option("-i, --iteration [id|name]", "Stories in iteration id/name, by regex", "").option("-S, --save [name]", "Save search configuration as workspace").option("-t, --text [name]", "Stories with text in name, by regex", "").option("-e, --estimate [operator][number]", "Stories estimated within criteria (operator is one of <|>|=)", "").option("-u, --updated [operator][date]", "Stories updated within criteria (operator is one of <|>|=)", "").option("-y, --type [name]", "Stories of type, by regex", "").option("-r, --sort [field]", "Sort stories by field (accessor[:asc|desc][,next])", "state.position:asc,position:asc").option("-f, --format [template]", "Format each story output by template", "");
21
- const getWorkspaceOptions = (program$1) => {
22
- const blacklistedKeys = [
23
- "Command",
24
- "commands",
25
- "Option",
26
- "options",
27
- "rawArgs",
28
- "save"
29
- ];
30
- return Object.entries(program$1).filter(([key]) => !(blacklistedKeys.includes(key) || key.startsWith("_"))).reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {});
19
+ const getWorkspaceOptions = (opts) => {
20
+ const blacklistedKeys = ["save"];
21
+ return Object.entries(opts).filter(([key]) => !blacklistedKeys.includes(key)).reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {});
31
22
  };
32
23
  const main = async () => {
33
24
  program.parse(process.argv);
34
- if (!program.quiet) {
25
+ const opts = program.opts();
26
+ if (!opts.quiet) {
35
27
  if (!program.args.length) log("Fetching all stories for search since no search operators were passed ...");
36
28
  spin.start();
37
29
  }
38
30
  let stories = [];
39
31
  try {
40
- stories = await require_lib_stories.default.listStories(program);
32
+ stories = await require_lib_stories.default.listStories({
33
+ ...opts,
34
+ args: program.args
35
+ });
41
36
  } catch (e) {
42
37
  log("Error fetching stories:", e);
43
38
  }
44
- if (!program.quiet) spin.stop(true);
45
- stories.map(require_lib_stories.default.printFormattedStory(program));
46
- if (!program.save) return;
47
- const name = program.save === true ? "default" : program.save;
48
- if (require_lib_configure.default.saveWorkspace(name, getWorkspaceOptions(program))) log("Saved query as %s workspace", name);
39
+ if (!opts.quiet) spin.stop(true);
40
+ stories.map(require_lib_stories.default.printFormattedStory(opts));
41
+ if (!opts.save) return;
42
+ const name = opts.save === true ? "default" : opts.save;
43
+ if (require_lib_configure.default.saveWorkspace(name, getWorkspaceOptions(opts))) log("Saved query as %s workspace", name);
49
44
  };
50
- if ((_process$argv$ = process.argv[1]) === null || _process$argv$ === void 0 ? void 0 : _process$argv$.includes("short-search")) main();
45
+ if (process.argv[1]?.includes("short-search")) main();
51
46
 
52
47
  //#endregion
53
48
  exports.main = main;
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
3
- const require_lib_spinner = require('../lib/spinner.js');
4
- const require_lib_configure = require('../lib/configure.js');
5
- const require_lib_client = require('../lib/client.js');
6
- const require_lib_stories = require('../lib/stories.js');
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_configure = require('../lib/configure.cjs');
5
+ const require_lib_client = require('../lib/client.cjs');
6
+ const require_lib_stories = require('../lib/stories.cjs');
7
7
  let commander = require("commander");
8
- commander = require_rolldown_runtime.__toESM(commander);
9
8
  let debug = require("debug");
10
9
  debug = require_rolldown_runtime.__toESM(debug);
11
10
  let path = require("path");
@@ -26,35 +25,37 @@ const spin = require_lib_spinner.default();
26
25
  const log = console.log;
27
26
  const logError = console.error;
28
27
  const debug$1 = (0, debug.default)("short");
29
- const program = commander.default.usage("[options] <id>").description("Update and/or display story details").option("-a, --archived", "Update story as archived").option("-c, --comment [text]", "Add comment to story", "").option("-d, --description [text]", "Update description of story", "").option("-D, --download", "Download all attached files", "").option("--download-dir [path]", "Directory to download files to", ".").option("-e, --estimate [number]", "Update estimate of story", "").option("--epic [id|name]", "Set epic of story").option("-i, --iteration [id|name]", "Set iteration of story").option("-f, --format [template]", "Format the story output by template", "").option("--from-git", "Fetch story parsed by ID from current git branch").option("--git-branch", "Checkout git branch from story slug <mention-name>/ch<id>/<type>-<title>\n as required by the Git integration: https://bit.ly/2RKO1FF").option("--git-branch-short", "Checkout git branch from story slug <mention-name>/ch<id>/<title>").option("-I, --idonly", "Print only ID of story results", "").option("-l, --label [id|name]", "Stories with label id/name, by regex", "").option("--move-after [id]", "Move story to position below story ID").option("--move-before [id]", "Move story to position above story ID").option("--move-down [n]", "Move story position downward by n stories").option("--move-up [n]", "Move story position upward by n stories").option("-o, --owners [id|name]", "Update owners of story, comma-separated", "").option("-O, --open", "Open story in browser").option("--oe, --open-epic", "Open story's epic in browser").option("--oi, --open-iteration", "Open story's iteration in browser").option("--op, --open-project", "Open story's project in browser").option("-q, --quiet", "Print only story output, no loading dialog", "").option("-s, --state [id|name]", "Update workflow state of story", "").option("-t, --title [text]", "Update title/name of story", "").option("-T, --team [id|name]", "Update team/group of story", "").option("--task [text]", "Create new task on story").option("--task-complete [text]", "Toggle completion of task on story matching text").option("-y, --type [name]", "Update type of story", "").parse(process.argv);
28
+ const program = new commander.Command().usage("[options] <id>").description("Update and/or display story details").option("-a, --archived", "Update story as archived").option("-c, --comment [text]", "Add comment to story", "").option("-d, --description [text]", "Update description of story", "").option("-D, --download", "Download all attached files", "").option("--download-dir [path]", "Directory to download files to", ".").option("-e, --estimate [number]", "Update estimate of story", "").option("--epic [id|name]", "Set epic of story").option("-i, --iteration [id|name]", "Set iteration of story").option("-f, --format [template]", "Format the story output by template", "").option("--from-git", "Fetch story parsed by ID from current git branch").option("--git-branch", "Checkout git branch from story slug <mention-name>/ch<id>/<type>-<title>\n as required by the Git integration: https://bit.ly/2RKO1FF").option("--git-branch-short", "Checkout git branch from story slug <mention-name>/ch<id>/<title>").option("-I, --idonly", "Print only ID of story results", "").option("-l, --label [id|name]", "Stories with label id/name, by regex", "").option("--move-after [id]", "Move story to position below story ID").option("--move-before [id]", "Move story to position above story ID").option("--move-down [n]", "Move story position downward by n stories").option("--move-up [n]", "Move story position upward by n stories").option("-o, --owners [id|name]", "Update owners of story, comma-separated", "").option("-O, --open", "Open story in browser").option("--oe, --open-epic", "Open story's epic in browser").option("--oi, --open-iteration", "Open story's iteration in browser").option("--op, --open-project", "Open story's project in browser").option("-q, --quiet", "Print only story output, no loading dialog", "").option("-s, --state [id|name]", "Update workflow state of story", "").option("-t, --title [text]", "Update title/name of story", "").option("-T, --team [id|name]", "Update team/group of story", "").option("--task [text]", "Create new task on story").option("--task-complete [text]", "Toggle completion of task on story matching text").option("-y, --type [name]", "Update type of story", "").parse(process.argv);
29
+ const opts = program.opts();
30
30
  const main = async () => {
31
31
  const entities = await require_lib_stories.default.fetchEntities();
32
- if (!(program.idonly || program.quiet)) spin.start();
32
+ if (!(opts.idonly || opts.quiet)) spin.start();
33
33
  debug$1("constructing story update");
34
34
  const update = {};
35
- if (program.archived) update.archived = true;
36
- if (program.state) update.workflow_state_id = (require_lib_stories.default.findState(entities, program.state) || {}).id;
37
- if (program.estimate) update.estimate = parseInt(program.estimate, 10);
38
- if (program.title) update.name = program.title;
39
- if (program.description) update.description = `${program.description}`;
40
- if (program.type) {
41
- const typeMatch = new RegExp(program.type, "i");
42
- update.story_type = [
35
+ if (opts.archived) update.archived = true;
36
+ if (opts.state) update.workflow_state_id = require_lib_stories.default.findState(entities, opts.state)?.id;
37
+ if (opts.estimate) update.estimate = parseInt(opts.estimate, 10);
38
+ if (opts.title) update.name = opts.title;
39
+ if (opts.description) update.description = `${opts.description}`;
40
+ if (opts.type) {
41
+ const storyTypes = [
43
42
  "feature",
44
43
  "bug",
45
44
  "chore"
46
- ].filter((t) => !!t.match(typeMatch))[0];
45
+ ];
46
+ const typeMatch = new RegExp(opts.type, "i");
47
+ update.story_type = storyTypes.find((t) => t.match(typeMatch));
47
48
  }
48
- if (program.owners) update.owner_ids = require_lib_stories.default.findOwnerIds(entities, program.owners);
49
- if (program.epic) update.epic_id = (require_lib_stories.default.findEpic(entities, program.epic) || {}).id;
50
- if (program.iteration) update.iteration_id = (require_lib_stories.default.findIteration(entities, program.iteration) || {}).id;
51
- if (program.label) update.labels = require_lib_stories.default.findLabelNames(entities, program.label);
52
- if (program.team) update.group_id = (require_lib_stories.default.findGroup(entities, program.team) || {}).id;
53
- const hasPositionUpdate = program.moveAfter !== void 0 || program.moveBefore !== void 0 || program.moveDown !== void 0 || program.moveUp !== void 0;
49
+ if (opts.owners) update.owner_ids = require_lib_stories.default.findOwnerIds(entities, opts.owners);
50
+ if (opts.epic) update.epic_id = require_lib_stories.default.findEpic(entities, opts.epic)?.id;
51
+ if (opts.iteration) update.iteration_id = require_lib_stories.default.findIteration(entities, opts.iteration)?.id;
52
+ if (opts.label) update.labels = require_lib_stories.default.findLabelNames(entities, opts.label);
53
+ if (opts.team) update.group_id = require_lib_stories.default.findGroup(entities, opts.team)?.id;
54
+ const hasPositionUpdate = opts.moveAfter !== void 0 || opts.moveBefore !== void 0 || opts.moveDown !== void 0 || opts.moveUp !== void 0;
54
55
  const hasUpdate = Object.keys(update).length > 0 || hasPositionUpdate;
55
56
  debug$1("constructed story update", update);
56
57
  const gitID = [];
57
- if (program.fromGit || !program.args.length) {
58
+ if (opts.fromGit || !program.args.length) {
58
59
  debug$1("fetching story ID from git");
59
60
  let branch = "";
60
61
  try {
@@ -77,9 +78,9 @@ const main = async () => {
77
78
  const id = parseInt(_id, 10);
78
79
  let story;
79
80
  try {
80
- if (program.comment) {
81
+ if (opts.comment) {
81
82
  debug$1("request comment create");
82
- await require_lib_client.default.createStoryComment(id, { text: program.comment });
83
+ await require_lib_client.default.createStoryComment(id, { text: opts.comment });
83
84
  debug$1("response comment create");
84
85
  }
85
86
  } catch (e) {
@@ -88,9 +89,9 @@ const main = async () => {
88
89
  process.exit(3);
89
90
  }
90
91
  try {
91
- if (program.task) {
92
+ if (opts.task) {
92
93
  debug$1("request task create");
93
- await require_lib_client.default.createTask(id, { description: program.task });
94
+ await require_lib_client.default.createTask(id, { description: opts.task });
94
95
  debug$1("response task create");
95
96
  }
96
97
  } catch (e) {
@@ -108,9 +109,9 @@ const main = async () => {
108
109
  process.exit(4);
109
110
  }
110
111
  try {
111
- if (program.taskComplete) {
112
+ if (opts.taskComplete) {
112
113
  debug$1("calculating task(s) to complete");
113
- const descMatch = new RegExp(program.taskComplete, "i");
114
+ const descMatch = new RegExp(opts.taskComplete, "i");
114
115
  const tasks = story.tasks.filter((t) => t.description.match(descMatch));
115
116
  const updatedTaskIds = tasks.map((t) => t.id);
116
117
  debug$1("request tasks complete", updatedTaskIds);
@@ -136,10 +137,10 @@ const main = async () => {
136
137
  });
137
138
  const siblingIds = siblings.map((s) => s.id);
138
139
  const storyIndex = siblingIds.indexOf(~~id);
139
- if (program.moveAfter) update.after_id = ~~program.moveAfter;
140
- else if (program.moveBefore) update.before_id = ~~program.moveBefore;
141
- else if (program.moveUp) update.before_id = siblingIds[Math.max(0, storyIndex - (~~program.moveUp || 1))];
142
- else if (program.moveDown) update.after_id = siblingIds[Math.min(siblings.length - 1, storyIndex + (~~program.moveDown || 1))];
140
+ if (opts.moveAfter) update.after_id = ~~opts.moveAfter;
141
+ else if (opts.moveBefore) update.before_id = ~~opts.moveBefore;
142
+ else if (opts.moveUp) update.before_id = siblingIds[Math.max(0, storyIndex - (~~opts.moveUp || 1))];
143
+ else if (opts.moveDown) update.after_id = siblingIds[Math.min(siblings.length - 1, storyIndex + (~~opts.moveDown || 1))];
143
144
  debug$1("constructed story position update", update);
144
145
  }
145
146
  debug$1("request story update");
@@ -153,28 +154,28 @@ const main = async () => {
153
154
  process.exit(5);
154
155
  }
155
156
  if (story) story = require_lib_stories.default.hydrateStory(entities, story);
156
- if (!program.idonly) spin.stop(true);
157
+ if (!opts.idonly) spin.stop(true);
157
158
  if (story) {
158
159
  printStory(story, entities);
159
- if (program.open) openURL(require_lib_stories.default.storyURL(story));
160
- if (program.openEpic) {
160
+ if (opts.open) openURL(require_lib_stories.default.storyURL(story));
161
+ if (opts.openEpic) {
161
162
  if (!story.epic_id) {
162
163
  logError("This story is not part of an epic.");
163
164
  process.exit(21);
164
165
  }
165
166
  openURL(require_lib_stories.default.buildURL("epic", story.epic_id));
166
167
  }
167
- if (program.openIteration) {
168
+ if (opts.openIteration) {
168
169
  if (!story.iteration_id) {
169
170
  logError("This story is not part of an iteration.");
170
171
  process.exit(22);
171
172
  }
172
173
  openURL(require_lib_stories.default.buildURL("iteration", story.iteration_id));
173
174
  }
174
- if (program.openProject) openURL(require_lib_stories.default.buildURL("project", story.project_id));
175
+ if (opts.openProject) openURL(require_lib_stories.default.buildURL("project", story.project_id));
175
176
  }
176
- if (program.download) downloadFiles(story);
177
- if (story && program.gitBranch) {
177
+ if (opts.download) downloadFiles(story);
178
+ if (story && opts.gitBranch) {
178
179
  if (!config.mentionName) {
179
180
  stopSpinner();
180
181
  require_lib_stories.default.checkoutStoryBranch(story, `${story.story_type}-${story.id}-`);
@@ -183,7 +184,7 @@ const main = async () => {
183
184
  process.exit(10);
184
185
  }
185
186
  require_lib_stories.default.checkoutStoryBranch(story);
186
- } else if (story && program.gitBranchShort) require_lib_stories.default.checkoutStoryBranch(story, `${config.mentionName}/sc-${story.id}/`);
187
+ } else if (story && opts.gitBranchShort) require_lib_stories.default.checkoutStoryBranch(story, `${config.mentionName}/sc-${story.id}/`);
187
188
  });
188
189
  stopSpinner();
189
190
  };
@@ -191,11 +192,11 @@ const openURL = (url) => {
191
192
  (0, child_process.execSync)(`${os.default.platform() === "darwin" ? "open" : "xdg-open"} '${url}'`);
192
193
  };
193
194
  const stopSpinner = () => {
194
- if (!(program.idonly || program.quiet)) spin.stop(true);
195
+ if (!(opts.idonly || opts.quiet)) spin.stop(true);
195
196
  };
196
197
  const downloadFiles = (story) => story.files.map((file) => {
197
198
  https.default.get(require_lib_stories.default.fileURL(file), (res) => {
198
- const filePath = path.default.join(program.downloadDir, file.name);
199
+ const filePath = path.default.join(opts.downloadDir ?? ".", file.name);
199
200
  log(chalk.default.bold("Downloading file to: ") + filePath);
200
201
  const stream = fs.default.createWriteStream(filePath);
201
202
  res.pipe(stream);
@@ -203,8 +204,8 @@ const downloadFiles = (story) => story.files.map((file) => {
203
204
  });
204
205
  });
205
206
  const printStory = (story, entities) => {
206
- if (program.idonly) return log(story.id);
207
- if (program.format) return require_lib_stories.default.printFormattedStory(program)(story);
207
+ if (opts.idonly) return log(story.id);
208
+ if (opts.format) return require_lib_stories.default.printFormattedStory(opts)(story);
208
209
  require_lib_stories.default.printDetailedStory(story, entities);
209
210
  };
210
211
  main();
@@ -1,16 +1,15 @@
1
1
  #!/usr/bin/env node
2
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
3
- const require_lib_spinner = require('../lib/spinner.js');
4
- const require_lib_client = require('../lib/client.js');
2
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
3
+ const require_lib_spinner = require('../lib/spinner.cjs');
4
+ const require_lib_client = require('../lib/client.cjs');
5
5
  let commander = require("commander");
6
- commander = require_rolldown_runtime.__toESM(commander);
7
6
  let chalk = require("chalk");
8
7
  chalk = require_rolldown_runtime.__toESM(chalk);
9
8
 
10
9
  //#region src/bin/short-workflows.ts
11
10
  const spin = require_lib_spinner.default();
12
11
  const log = console.log;
13
- const program = commander.default.description("Display workflows/states available for stories").option("-s, --search [query]", "List states containing query", "").parse(process.argv);
12
+ const opts = new commander.Command().description("Display workflows/states available for stories").option("-s, --search [query]", "List states containing query", "").parse(process.argv).opts();
14
13
  const main = async () => {
15
14
  spin.start();
16
15
  const wfs = await require_lib_client.default.listWorkflows().then((r) => r.data);
@@ -23,7 +22,7 @@ const printWf = (wf) => {
23
22
  wf.states.map(printWfState);
24
23
  };
25
24
  const printWfState = (state) => {
26
- if (!state.name.match(new RegExp(program.search, "i"))) return;
25
+ if (!state.name.match(new RegExp(opts.search ?? "", "i"))) return;
27
26
  log(chalk.default.bold(` #${state.id}`) + ` ${state.name}`);
28
27
  log(` Type: \t${state.type}`);
29
28
  log(` Stories:\t${state.num_stories}`);