bananareporter 0.2.0 → 0.3.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 CHANGED
@@ -26,8 +26,8 @@
26
26
  - **Multiple output formats**: output file can be a JSON, JSONL or CSV (via `--format`) _more coming soon_
27
27
  - **Configurable**: data to be imported can be filtered using the configuration file and each option can be overridden per source
28
28
  - **Sources Supported**
29
- - GitLab: commits
30
- - GitHub: commits
29
+ - [GitLab](./docs/sources/gitlab.md): commits
30
+ - [GitHub](./docs/sources/github.md): commits
31
31
  - todo.txt: tasks
32
32
  - **[Request a new source](https://github.com/nya1/bananareporter/issues/new?assignees=&labels=enhancement&template=new-source-request.md&title=)**
33
33
 
@@ -67,14 +67,15 @@ sources:
67
67
  bananareporter --from 2023-01-01 --to 2023-03-01 -c bananareporter.yaml
68
68
  ```
69
69
 
70
- In the current directory you will find the output as `bananareporter_$FROM__$TO.json`, can be changed with `--out`
70
+ In the current directory you will find the output as `bananareporter_$FROM__$TO.json` (can be changed with `--out`)
71
71
 
72
72
  Example of output (json) with gitlab and github sources:
73
73
 
74
74
  ```json
75
75
  [
76
76
  {
77
- "date": "2022-07-13T07:51:21.730Z",
77
+ "id": "c12ba180bfecf45fcdcc40d6104d1f1b7ad409dc",
78
+ "date": "2023-01-13T07:51:21.730Z",
78
79
  "username": "johndoe",
79
80
  "description": "chore: update changelog and swagger branch:work git:aa33b04",
80
81
  "projectId": "3318214",
@@ -82,8 +83,9 @@ Example of output (json) with gitlab and github sources:
82
83
  "type": "gitlab"
83
84
  },
84
85
  {
85
- "date": "2022-07-14T10:50:10.230Z",
86
- "username": "johndoe2",
86
+ "id": "6e1b66a1dea89e957d8c44943f942be4874c0641",
87
+ "date": "2023-01-14T10:50:10.230Z",
88
+ "username": "johndoe",
87
89
  "description": "refactor: compare date function branch:work git:ia1f241",
88
90
  "projectId": "928544",
89
91
  "projectName": "awesome-backend",
@@ -100,7 +102,7 @@ $ npm install -g bananareporter
100
102
  $ bananareporter COMMAND
101
103
  running command...
102
104
  $ bananareporter (--version)
103
- bananareporter/0.2.0 linux-x64 node-v18.14.2
105
+ bananareporter/0.3.0 linux-x64 node-v18.15.0
104
106
  $ bananareporter --help [COMMAND]
105
107
  USAGE
106
108
  $ bananareporter COMMAND
@@ -130,7 +132,7 @@ DESCRIPTION
130
132
  Display help for bananareporter.
131
133
  ```
132
134
 
133
- _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.7/src/commands/help.ts)_
135
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.2.8/src/commands/help.ts)_
134
136
 
135
137
  ## `bananareporter run`
136
138
 
@@ -143,7 +145,7 @@ USAGE
143
145
 
144
146
  FLAGS
145
147
  -c, --config=<value> config file location, by default ~/.config/bananareporter/config.yaml
146
- -o, --out=<value> (required) [default: ./bananareporter_$FROM__$TO.json] file path to save the output
148
+ -o, --out=<value> (required) [default: ./bananareporter_$FROM__$TO.json] file path or directory to save the output
147
149
  --delay=<value> [default: 300] global delay in millisecons between http requests
148
150
  --format=<option> (required) [default: json] output file format
149
151
  <options: json|jsonl|csv>
@@ -159,5 +161,5 @@ EXAMPLES
159
161
  report with 138 entries saved to ./bananareporter.json
160
162
  ```
161
163
 
162
- _See code: [dist/commands/run/index.ts](https://github.com/nya1/bananareporter/blob/v0.2.0/dist/commands/run/index.ts)_
164
+ _See code: [dist/commands/run/index.ts](https://github.com/nya1/bananareporter/blob/v0.3.0/dist/commands/run/index.ts)_
163
165
  <!-- commandsstop -->
@@ -14,4 +14,5 @@ export default class Run extends Command {
14
14
  'disable-welcome-emoji': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
15
  };
16
16
  run(): Promise<void>;
17
+ catch(error: Error): Promise<void>;
17
18
  }
@@ -13,6 +13,8 @@ const lodash_1 = require("lodash");
13
13
  const logger_1 = require("../../util/logger");
14
14
  const github_1 = require("../../integrations/github");
15
15
  const todotxt_1 = require("../../integrations/todotxt");
16
+ const zod_1 = require("zod");
17
+ const node_path_1 = require("node:path");
16
18
  class Run extends core_1.Command {
17
19
  static dateStringValidation(input) {
18
20
  if (!dayjs(input).isValid()) {
@@ -97,23 +99,47 @@ class Run extends core_1.Command {
97
99
  }
98
100
  const fileExt = `.${validatedConfig.format}`;
99
101
  let outFile = validatedConfig.out;
102
+ logger_1.logger.debug(`Run.flags.out.default ${Run.flags.out.default}`);
103
+ logger_1.logger.debug(`fileExt ${fileExt}`);
104
+ logger_1.logger.debug(`outFile ${outFile}`);
105
+ // if --out was provided and it's a directory
106
+ // use the default file name
107
+ try {
108
+ if ((0, node_fs_1.statSync)(outFile).isDirectory()) {
109
+ outFile = (0, node_path_1.resolve)(outFile, Run.flags.out.default);
110
+ logger_1.logger.debug(`outFile is a directory, updated to ${outFile}`);
111
+ }
112
+ }
113
+ catch (error) {
114
+ logger_1.logger.debug('statSync error', error);
115
+ }
100
116
  // add file extension
101
117
  if (!outFile.endsWith(fileExt)) {
102
118
  if (outFile === Run.flags.out.default) {
103
119
  outFile = outFile
104
- .replace(`.${Run.flags.format.default}`, fileExt)
105
- .replace('$FROM', validatedConfig.from)
106
- .replace('$TO', validatedConfig.to);
120
+ .replace(`.${Run.flags.format.default}`, fileExt);
107
121
  }
108
122
  else {
109
123
  outFile += fileExt;
110
124
  }
111
125
  }
126
+ if (outFile.includes('$FROM') || outFile.includes('$TO')) {
127
+ outFile = outFile
128
+ .replace('$FROM', validatedConfig.from)
129
+ .replace('$TO', validatedConfig.to);
130
+ }
112
131
  logger_1.logger.debug(`run saving to ${outFile} with file content of size ${outputStr.length}`);
113
132
  (0, node_fs_1.writeFileSync)(outFile, outputStr);
114
133
  this.log(`report with ${reportList.length} entries saved to ${outFile}`);
115
134
  // this.log(`run! ${flags.config} ${JSON.stringify(configContent)}`)
116
135
  }
136
+ async catch(error) {
137
+ if (error instanceof zod_1.z.ZodError) {
138
+ const errMsg = error.issues.map(i => `${i.message}: ${i.path.join(', ')}`).join('\n');
139
+ throw new TypeError(`validation failed, ${errMsg}`);
140
+ }
141
+ throw error;
142
+ }
117
143
  }
118
144
  exports.default = Run;
119
145
  Run.description = 'Run report';
@@ -143,7 +169,7 @@ Run.flags = {
143
169
  out: core_1.Flags.file({
144
170
  char: 'o',
145
171
  aliases: ['output'],
146
- description: 'file path to save the output',
172
+ description: 'file path or directory to save the output',
147
173
  required: true,
148
174
  default: './bananareporter_$FROM__$TO.json',
149
175
  }),
@@ -24,15 +24,11 @@ export declare const BananaConfig: z.ZodEffects<z.ZodEffects<z.ZodObject<{
24
24
  */
25
25
  sources: z.ZodArray<z.ZodObject<{
26
26
  type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
27
- }, "passthrough", z.ZodTypeAny, {
28
- type: "gitlab" | "github" | "todo.txt";
29
- } & {
30
- [k: string]: unknown;
31
- }, {
32
- type: "gitlab" | "github" | "todo.txt";
33
- } & {
34
- [k: string]: unknown;
35
- }>, "atleastone">;
27
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
28
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
29
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
30
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
31
+ }, z.ZodTypeAny, "passthrough">>, "atleastone">;
36
32
  }, "strip", z.ZodTypeAny, {
37
33
  format: "json" | "csv" | "jsonl";
38
34
  from: string;
@@ -41,32 +37,24 @@ export declare const BananaConfig: z.ZodEffects<z.ZodEffects<z.ZodObject<{
41
37
  to: string;
42
38
  configFileLocation: string;
43
39
  delay: number;
44
- sources: [{
45
- type: "gitlab" | "github" | "todo.txt";
46
- } & {
47
- [k: string]: unknown;
48
- }, ...({
49
- type: "gitlab" | "github" | "todo.txt";
50
- } & {
51
- [k: string]: unknown;
52
- })[]];
40
+ sources: [z.objectOutputType<{
41
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
42
+ }, z.ZodTypeAny, "passthrough">, ...z.objectOutputType<{
43
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
44
+ }, z.ZodTypeAny, "passthrough">[]];
53
45
  }, {
54
- includeRawObject?: boolean | undefined;
55
- delay?: number | undefined;
56
46
  format: "json" | "csv" | "jsonl";
57
47
  from: string;
58
48
  out: string;
59
49
  to: string;
60
50
  configFileLocation: string;
61
- sources: [{
62
- type: "gitlab" | "github" | "todo.txt";
63
- } & {
64
- [k: string]: unknown;
65
- }, ...({
66
- type: "gitlab" | "github" | "todo.txt";
67
- } & {
68
- [k: string]: unknown;
69
- })[]];
51
+ sources: [z.objectInputType<{
52
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
53
+ }, z.ZodTypeAny, "passthrough">, ...z.objectInputType<{
54
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
55
+ }, z.ZodTypeAny, "passthrough">[]];
56
+ includeRawObject?: boolean | undefined;
57
+ delay?: number | undefined;
70
58
  }>, {
71
59
  format: "json" | "csv" | "jsonl";
72
60
  from: string;
@@ -75,32 +63,24 @@ export declare const BananaConfig: z.ZodEffects<z.ZodEffects<z.ZodObject<{
75
63
  to: string;
76
64
  configFileLocation: string;
77
65
  delay: number;
78
- sources: [{
79
- type: "gitlab" | "github" | "todo.txt";
80
- } & {
81
- [k: string]: unknown;
82
- }, ...({
83
- type: "gitlab" | "github" | "todo.txt";
84
- } & {
85
- [k: string]: unknown;
86
- })[]];
66
+ sources: [z.objectOutputType<{
67
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
68
+ }, z.ZodTypeAny, "passthrough">, ...z.objectOutputType<{
69
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
70
+ }, z.ZodTypeAny, "passthrough">[]];
87
71
  }, {
88
- includeRawObject?: boolean | undefined;
89
- delay?: number | undefined;
90
72
  format: "json" | "csv" | "jsonl";
91
73
  from: string;
92
74
  out: string;
93
75
  to: string;
94
76
  configFileLocation: string;
95
- sources: [{
96
- type: "gitlab" | "github" | "todo.txt";
97
- } & {
98
- [k: string]: unknown;
99
- }, ...({
100
- type: "gitlab" | "github" | "todo.txt";
101
- } & {
102
- [k: string]: unknown;
103
- })[]];
77
+ sources: [z.objectInputType<{
78
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
79
+ }, z.ZodTypeAny, "passthrough">, ...z.objectInputType<{
80
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
81
+ }, z.ZodTypeAny, "passthrough">[]];
82
+ includeRawObject?: boolean | undefined;
83
+ delay?: number | undefined;
104
84
  }>, {
105
85
  format: "json" | "csv" | "jsonl";
106
86
  from: string;
@@ -109,32 +89,24 @@ export declare const BananaConfig: z.ZodEffects<z.ZodEffects<z.ZodObject<{
109
89
  to: string;
110
90
  configFileLocation: string;
111
91
  delay: number;
112
- sources: [{
113
- type: "gitlab" | "github" | "todo.txt";
114
- } & {
115
- [k: string]: unknown;
116
- }, ...({
117
- type: "gitlab" | "github" | "todo.txt";
118
- } & {
119
- [k: string]: unknown;
120
- })[]];
92
+ sources: [z.objectOutputType<{
93
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
94
+ }, z.ZodTypeAny, "passthrough">, ...z.objectOutputType<{
95
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
96
+ }, z.ZodTypeAny, "passthrough">[]];
121
97
  }, {
122
- includeRawObject?: boolean | undefined;
123
- delay?: number | undefined;
124
98
  format: "json" | "csv" | "jsonl";
125
99
  from: string;
126
100
  out: string;
127
101
  to: string;
128
102
  configFileLocation: string;
129
- sources: [{
130
- type: "gitlab" | "github" | "todo.txt";
131
- } & {
132
- [k: string]: unknown;
133
- }, ...({
134
- type: "gitlab" | "github" | "todo.txt";
135
- } & {
136
- [k: string]: unknown;
137
- })[]];
103
+ sources: [z.objectInputType<{
104
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
105
+ }, z.ZodTypeAny, "passthrough">, ...z.objectInputType<{
106
+ type: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
107
+ }, z.ZodTypeAny, "passthrough">[]];
108
+ includeRawObject?: boolean | undefined;
109
+ delay?: number | undefined;
138
110
  }>;
139
111
  export type BananaConfig = z.infer<typeof BananaConfig>;
140
112
  export declare function loadAndValidateConfig(input: unknown): BananaConfig;
@@ -3,13 +3,18 @@ import { BananaConfig } from '../core';
3
3
  export declare const SourceType: z.ZodEnum<["gitlab", "github", "todo.txt"]>;
4
4
  export type SourceType = z.infer<typeof SourceType>;
5
5
  export interface CommonBananaReporterObj {
6
+ id: string;
6
7
  date: string;
7
8
  description: string;
8
9
  username?: string;
9
10
  projectId?: string;
10
11
  projectName?: string;
11
12
  type: SourceType;
12
- __raw: any;
13
+ /**
14
+ * the raw source object,
15
+ * included only when --include-raw-object is provided
16
+ */
17
+ __raw?: any;
13
18
  }
14
19
  export declare abstract class IntegrationBase {
15
20
  static type: SourceType;
@@ -167,9 +167,10 @@ export declare const GithubConfig: z.ZodObject<{
167
167
  to: z.ZodOptional<z.ZodString>;
168
168
  delay: z.ZodOptional<z.ZodNumber>;
169
169
  }, "strip", z.ZodTypeAny, {
170
- from?: string | undefined;
171
- to?: string | undefined;
172
- delay?: number | undefined;
170
+ protocol: "http" | "https";
171
+ committerUsername: string;
172
+ domain: string;
173
+ apiVersion: string;
173
174
  token?: string | undefined;
174
175
  filters?: [{
175
176
  on: string;
@@ -178,15 +179,11 @@ export declare const GithubConfig: z.ZodObject<{
178
179
  on: string;
179
180
  regex: string;
180
181
  }[]] | undefined;
181
- protocol: "http" | "https";
182
- committerUsername: string;
183
- domain: string;
184
- apiVersion: string;
185
- }, {
186
182
  from?: string | undefined;
187
- protocol?: "http" | "https" | undefined;
188
183
  to?: string | undefined;
189
184
  delay?: number | undefined;
185
+ }, {
186
+ committerUsername: string;
190
187
  token?: string | undefined;
191
188
  filters?: [{
192
189
  on: string;
@@ -197,7 +194,10 @@ export declare const GithubConfig: z.ZodObject<{
197
194
  }[]] | undefined;
198
195
  domain?: string | undefined;
199
196
  apiVersion?: string | undefined;
200
- committerUsername: string;
197
+ protocol?: "http" | "https" | undefined;
198
+ from?: string | undefined;
199
+ to?: string | undefined;
200
+ delay?: number | undefined;
201
201
  }>;
202
202
  export declare class GithubIntegration extends IntegrationBase {
203
203
  static type: "github";
@@ -65,6 +65,7 @@ class GithubIntegration extends base_1.IntegrationBase {
65
65
  async fetchData() {
66
66
  let page = 1;
67
67
  let commitList = [];
68
+ const commitShaList = new Set();
68
69
  while (page > 0) {
69
70
  logger_1.logger.debug(`github integration working on ${page}`);
70
71
  /* eslint-disable no-await-in-loop */
@@ -79,7 +80,12 @@ class GithubIntegration extends base_1.IntegrationBase {
79
80
  break;
80
81
  }
81
82
  // eslint-disable-next-line unicorn/prefer-spread
82
- commitList = commitList.concat(commits.items);
83
+ commitList = commitList.concat(
84
+ // remove duplicate items
85
+ commits.items.filter(c => !commitShaList.has(c.sha)));
86
+ for (const c of commits.items) {
87
+ commitShaList.add(c.sha);
88
+ }
83
89
  logger_1.logger.debug(`github integration commitList ${commitList.length} (added ${commits.items.length} commits)`);
84
90
  page += 1;
85
91
  await (0, common_1.delay)(this.delayToUse);
@@ -126,6 +132,7 @@ class GithubIntegration extends base_1.IntegrationBase {
126
132
  const projectName = rawData.repository.name;
127
133
  const description = `${rawData.commit.message} git:${rawData.sha.slice(0, 7)}`;
128
134
  return {
135
+ id: rawData.sha,
129
136
  date: rawData.commit.committer.date,
130
137
  username: rawData.commit.committer.name,
131
138
  description,
@@ -54,9 +54,12 @@ export declare const GitlabConfig: z.ZodObject<{
54
54
  to: z.ZodOptional<z.ZodString>;
55
55
  delay: z.ZodOptional<z.ZodNumber>;
56
56
  }, "strip", z.ZodTypeAny, {
57
- from?: string | undefined;
58
- to?: string | undefined;
59
- delay?: number | undefined;
57
+ protocol: "http" | "https";
58
+ committerUsername: string;
59
+ token: string;
60
+ domain: string;
61
+ apiVersion: string;
62
+ apiBasePath: string;
60
63
  userId?: number | undefined;
61
64
  filters?: [{
62
65
  on: string;
@@ -65,17 +68,12 @@ export declare const GitlabConfig: z.ZodObject<{
65
68
  on: string;
66
69
  regex: string;
67
70
  }[]] | undefined;
68
- protocol: "http" | "https";
69
- committerUsername: string;
70
- token: string;
71
- domain: string;
72
- apiVersion: string;
73
- apiBasePath: string;
74
- }, {
75
71
  from?: string | undefined;
76
- protocol?: "http" | "https" | undefined;
77
72
  to?: string | undefined;
78
73
  delay?: number | undefined;
74
+ }, {
75
+ committerUsername: string;
76
+ token: string;
79
77
  userId?: number | undefined;
80
78
  filters?: [{
81
79
  on: string;
@@ -86,9 +84,11 @@ export declare const GitlabConfig: z.ZodObject<{
86
84
  }[]] | undefined;
87
85
  domain?: string | undefined;
88
86
  apiVersion?: string | undefined;
87
+ protocol?: "http" | "https" | undefined;
89
88
  apiBasePath?: string | undefined;
90
- committerUsername: string;
91
- token: string;
89
+ from?: string | undefined;
90
+ to?: string | undefined;
91
+ delay?: number | undefined;
92
92
  }>;
93
93
  export declare class GitlabIntegration extends IntegrationBase {
94
94
  static type: "gitlab";
@@ -88,6 +88,7 @@ class GitlabIntegration extends base_1.IntegrationBase {
88
88
  let page = 1;
89
89
  let eventList = [];
90
90
  const projectIds = new Set();
91
+ const commitShaList = new Set();
91
92
  while (page > 0) {
92
93
  logger_1.logger.debug(`gitlab integration working on ${page}`);
93
94
  /* eslint-disable no-await-in-loop */
@@ -101,11 +102,14 @@ class GitlabIntegration extends base_1.IntegrationBase {
101
102
  logger_1.logger.debug('gitlab integration no more events to process');
102
103
  break;
103
104
  }
105
+ // eslint-disable-next-line unicorn/prefer-spread
106
+ eventList = eventList.concat(
107
+ // remove duplicated commits
108
+ events.filter(e => !commitShaList.has(e.push_data.commit_to)));
104
109
  for (const e of events) {
110
+ commitShaList.add(e.push_data.commit_to);
105
111
  projectIds.add(e.project_id);
106
112
  }
107
- // eslint-disable-next-line unicorn/prefer-spread
108
- eventList = eventList.concat(events);
109
113
  logger_1.logger.debug(`gitlab integration eventList ${eventList.length} (added ${events.length} events)`);
110
114
  page += 1;
111
115
  await (0, common_1.delay)(this.delayToUse);
@@ -240,6 +244,7 @@ class GitlabIntegration extends base_1.IntegrationBase {
240
244
  const projectName = projectDetails === null || projectDetails === void 0 ? void 0 : projectDetails.path;
241
245
  const description = `${rawData.push_data.commit_title} branch:${rawData.push_data.ref} git:${rawData.push_data.commit_to.slice(0, 7)}`;
242
246
  return {
247
+ id: `${String(rawData.push_data.commit_to)}`,
243
248
  date: rawData.created_at,
244
249
  username: rawData.author_username,
245
250
  description,
@@ -18,8 +18,7 @@ export declare const TodoTxtConfig: z.ZodObject<{
18
18
  from: z.ZodOptional<z.ZodString>;
19
19
  to: z.ZodOptional<z.ZodString>;
20
20
  }, "strip", z.ZodTypeAny, {
21
- from?: string | undefined;
22
- to?: string | undefined;
21
+ file: string;
23
22
  filters?: [{
24
23
  on: string;
25
24
  regex: string;
@@ -27,11 +26,10 @@ export declare const TodoTxtConfig: z.ZodObject<{
27
26
  on: string;
28
27
  regex: string;
29
28
  }[]] | undefined;
30
- file: string;
31
- }, {
32
- file?: string | undefined;
33
29
  from?: string | undefined;
34
30
  to?: string | undefined;
31
+ }, {
32
+ file?: string | undefined;
35
33
  filters?: [{
36
34
  on: string;
37
35
  regex: string;
@@ -39,6 +37,8 @@ export declare const TodoTxtConfig: z.ZodObject<{
39
37
  on: string;
40
38
  regex: string;
41
39
  }[]] | undefined;
40
+ from?: string | undefined;
41
+ to?: string | undefined;
42
42
  }>;
43
43
  export declare class TodoTxtIntegration extends IntegrationBase {
44
44
  static type: "todo.txt";
@@ -47,5 +47,5 @@ export declare class TodoTxtIntegration extends IntegrationBase {
47
47
  private bananaReporterConfig;
48
48
  constructor(_rawConfig: unknown, bananaReporterConfig: BananaConfig);
49
49
  fetchData(): Promise<CommonBananaReporterObj[]>;
50
- toBananaReporterObj(rawData: Task): CommonBananaReporterObj;
50
+ toBananaReporterObj(rawData: Task, index?: number): CommonBananaReporterObj;
51
51
  }
@@ -73,14 +73,15 @@ class TodoTxtIntegration extends base_1.IntegrationBase {
73
73
  return regex.test(value);
74
74
  });
75
75
  }
76
- const formattedData = filteredTasks.map(e => this.toBananaReporterObj(e));
76
+ const formattedData = filteredTasks.map((e, i) => this.toBananaReporterObj(e, i));
77
77
  return formattedData;
78
78
  }
79
- toBananaReporterObj(rawData) {
79
+ toBananaReporterObj(rawData, index) {
80
80
  var _a;
81
81
  const projectName = (_a = rawData.projects) === null || _a === void 0 ? void 0 : _a.map(p => p.replace('+', '')).join(',');
82
82
  const description = `${rawData.description}`;
83
83
  return {
84
+ id: `${index}`,
84
85
  date: rawData.completion || rawData.creation || '',
85
86
  description,
86
87
  projectName,
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.2.0",
2
+ "version": "0.3.0",
3
3
  "commands": {
4
4
  "run": {
5
5
  "id": "run",
@@ -44,7 +44,7 @@
44
44
  "name": "out",
45
45
  "type": "option",
46
46
  "char": "o",
47
- "description": "file path to save the output",
47
+ "description": "file path or directory to save the output",
48
48
  "required": true,
49
49
  "multiple": false,
50
50
  "default": "./bananareporter_$FROM__$TO.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bananareporter",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Easily generate a report from multiple sources",
5
5
  "author": "nya1",
6
6
  "bin": {
@@ -27,14 +27,14 @@
27
27
  "object-path": "^0.11.8",
28
28
  "papaparse": "^5.4.0",
29
29
  "winston": "^3.8.2",
30
- "zod": "^3.21.0"
30
+ "zod": "^3.21.4"
31
31
  },
32
32
  "devDependencies": {
33
- "@oclif/test": "^2.3.8",
33
+ "@oclif/test": "^2.3.10",
34
34
  "@types/chai": "^4",
35
35
  "@types/js-yaml": "^4.0.5",
36
36
  "@types/mocha": "^9.1.1",
37
- "@types/node": "^18.14.6",
37
+ "@types/node": "^18.15.3",
38
38
  "@types/node-fetch": "^2.6.2",
39
39
  "@types/object-path": "^0.11.1",
40
40
  "@types/papaparse": "^5.3.7",