@sparkdotfi/common-reporters 0.0.1

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 (40) hide show
  1. package/dist/console/ConsoleReporter.js +41 -0
  2. package/dist/console/ConsoleReporter.test.js +40 -0
  3. package/dist/index.js +6 -0
  4. package/dist/pagerduty/PagerDutyClient.js +53 -0
  5. package/dist/pagerduty/PagerDutyReport.test.js +40 -0
  6. package/dist/pagerduty/PagerDutyReporter.js +28 -0
  7. package/dist/pagerduty/renderToPagerDuty.js +15 -0
  8. package/dist/slack/SlackReporter.js +29 -0
  9. package/dist/slack/SlackReporter.test.js +31 -0
  10. package/dist/slack/renderToSlack.js +51 -0
  11. package/dist/slack/renderToSlack.test.js +188 -0
  12. package/dist/templating.js +11 -0
  13. package/dist/types/console/ConsoleReporter.d.ts +11 -0
  14. package/dist/types/console/ConsoleReporter.d.ts.map +1 -0
  15. package/dist/types/console/ConsoleReporter.test.d.ts +2 -0
  16. package/dist/types/console/ConsoleReporter.test.d.ts.map +1 -0
  17. package/dist/types/index.d.ts +7 -0
  18. package/dist/types/index.d.ts.map +1 -0
  19. package/dist/types/pagerduty/PagerDutyClient.d.ts +13 -0
  20. package/dist/types/pagerduty/PagerDutyClient.d.ts.map +1 -0
  21. package/dist/types/pagerduty/PagerDutyReport.test.d.ts +2 -0
  22. package/dist/types/pagerduty/PagerDutyReport.test.d.ts.map +1 -0
  23. package/dist/types/pagerduty/PagerDutyReporter.d.ts +9 -0
  24. package/dist/types/pagerduty/PagerDutyReporter.d.ts.map +1 -0
  25. package/dist/types/pagerduty/renderToPagerDuty.d.ts +3 -0
  26. package/dist/types/pagerduty/renderToPagerDuty.d.ts.map +1 -0
  27. package/dist/types/slack/SlackReporter.d.ts +14 -0
  28. package/dist/types/slack/SlackReporter.d.ts.map +1 -0
  29. package/dist/types/slack/SlackReporter.test.d.ts +2 -0
  30. package/dist/types/slack/SlackReporter.test.d.ts.map +1 -0
  31. package/dist/types/slack/renderToSlack.d.ts +7 -0
  32. package/dist/types/slack/renderToSlack.d.ts.map +1 -0
  33. package/dist/types/slack/renderToSlack.test.d.ts +2 -0
  34. package/dist/types/slack/renderToSlack.test.d.ts.map +1 -0
  35. package/dist/types/templating.d.ts +12 -0
  36. package/dist/types/templating.d.ts.map +1 -0
  37. package/dist/types/types.d.ts +18 -0
  38. package/dist/types/types.d.ts.map +1 -0
  39. package/dist/types.js +1 -0
  40. package/package.json +45 -0
@@ -0,0 +1,41 @@
1
+ import { assertNever } from '@sparkdotfi/common-universal';
2
+ import { templating } from '../templating.js';
3
+ export class ConsoleReporter {
4
+ constructor(logger, logFunctionName) {
5
+ Object.defineProperty(this, "logFunctionName", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: logFunctionName
10
+ });
11
+ Object.defineProperty(this, "logger", {
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true,
15
+ value: void 0
16
+ });
17
+ this.logger = logger.for(this);
18
+ }
19
+ async report(report) {
20
+ const blocks = report.title ? [templating.text(`${report.title}\n`), ...report.content] : report.content;
21
+ this.logger[this.logFunctionName](renderToConsoleString(blocks));
22
+ }
23
+ }
24
+ function renderToConsoleString(content) {
25
+ const text = content
26
+ .map((block) => {
27
+ switch (block.type) {
28
+ case 'text':
29
+ return block.content;
30
+ case 'link':
31
+ return `${block.text} (${block.href})`;
32
+ default:
33
+ assertNever(block);
34
+ }
35
+ })
36
+ .join(' ');
37
+ return text
38
+ .split('\n')
39
+ .map((line) => line.trimStart())
40
+ .join('\n');
41
+ }
@@ -0,0 +1,40 @@
1
+ import { expect, mockFn, mockObject } from 'earl';
2
+ import { templating as t } from '../templating.js';
3
+ import { ConsoleReporter } from './ConsoleReporter.js';
4
+ describe(ConsoleReporter.name, () => {
5
+ it('joins title and content', async () => {
6
+ const logger = getMockLogger();
7
+ const reporter = new ConsoleReporter(logger, 'info');
8
+ await reporter.report({
9
+ title: 'some title',
10
+ content: [t.text('some description'), t.text('additional description')],
11
+ });
12
+ expect(logger.info).toHaveBeenOnlyCalledWith('some title\nsome description additional description');
13
+ });
14
+ it('allows for different logger function', async () => {
15
+ const logger = getMockLogger();
16
+ const reporter = new ConsoleReporter(logger, 'warn');
17
+ await reporter.report({
18
+ title: 'some title',
19
+ content: [t.text('some description')],
20
+ });
21
+ expect(logger.warn).toHaveBeenOnlyCalledWith('some title\nsome description');
22
+ expect(logger.info).not.toHaveBeenCalled();
23
+ });
24
+ it('sends message without title', async () => {
25
+ const logger = getMockLogger();
26
+ const reporter = new ConsoleReporter(logger, 'info');
27
+ await reporter.report({
28
+ content: [t.text('some description'), t.text('additional description')],
29
+ });
30
+ expect(logger.info).toHaveBeenOnlyCalledWith('some description additional description');
31
+ });
32
+ });
33
+ function getMockLogger() {
34
+ const mockLogger = mockObject({
35
+ info: mockFn(() => { }),
36
+ warn: mockFn(() => { }),
37
+ for: (_) => mockLogger,
38
+ });
39
+ return mockLogger;
40
+ }
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './templating.js';
2
+ export * from './types.js';
3
+ export { ConsoleReporter } from './console/ConsoleReporter.js';
4
+ export { PagerDutyClient } from './pagerduty/PagerDutyClient.js';
5
+ export { PagerDutyReporter } from './pagerduty/PagerDutyReporter.js';
6
+ export { SlackReporter } from './slack/SlackReporter.js';
@@ -0,0 +1,53 @@
1
+ import { api } from '@pagerduty/pdjs';
2
+ export class PagerDutyClient {
3
+ constructor(apiKey, requesterEmail) {
4
+ Object.defineProperty(this, "apiKey", {
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true,
8
+ value: apiKey
9
+ });
10
+ Object.defineProperty(this, "requesterEmail", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: requesterEmail
15
+ });
16
+ Object.defineProperty(this, "pdClient", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: void 0
21
+ });
22
+ this.pdClient = api({ token: apiKey });
23
+ }
24
+ async createIncident({ serviceId, title, description, uniqueKey, }) {
25
+ const res = await this.pdClient.post('/incidents', {
26
+ headers: {
27
+ From: this.requesterEmail,
28
+ },
29
+ data: {
30
+ incident: {
31
+ type: 'incident',
32
+ title,
33
+ body: {
34
+ type: 'incident_body',
35
+ details: description,
36
+ },
37
+ service: {
38
+ id: serviceId,
39
+ type: 'service_reference',
40
+ },
41
+ incident_key: uniqueKey,
42
+ },
43
+ },
44
+ });
45
+ // ignore if incident already exists
46
+ if (res.status === 400 && res.data.error.code === 2002) {
47
+ return;
48
+ }
49
+ if (!res.ok) {
50
+ throw new Error(`Failed to create incident: ${JSON.stringify(res.data)}`);
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,40 @@
1
+ import { Hash } from '@sparkdotfi/common-universal';
2
+ import { expect, mockFn, mockObject } from 'earl';
3
+ import { templating as t } from '../templating.js';
4
+ import { PagerDutyReporter } from './PagerDutyReporter.js';
5
+ describe(PagerDutyReporter.name, () => {
6
+ it('sends report', async () => {
7
+ const pdClient = getMockPagerDutyClient();
8
+ const reporter = new PagerDutyReporter(pdClient, 'service');
9
+ const content = [t.text('some content')];
10
+ const expectedHash = Hash.fromText('some content');
11
+ await reporter.report({
12
+ title: 'some title',
13
+ content,
14
+ });
15
+ expect(pdClient.createIncident).toHaveBeenOnlyCalledWith({
16
+ serviceId: 'service',
17
+ title: 'some title',
18
+ description: 'some content',
19
+ uniqueKey: expectedHash,
20
+ });
21
+ });
22
+ it('uses description for title if not provided', async () => {
23
+ const pdClient = getMockPagerDutyClient();
24
+ const reporter = new PagerDutyReporter(pdClient, 'service');
25
+ const content = [t.text('really long title'), t.text('with multiple parts'), t.link('href', 'and some link')];
26
+ const expectedDescription = 'really long title with multiple parts [href] and some link>';
27
+ await reporter.report({ content });
28
+ expect(pdClient.createIncident).toHaveBeenOnlyCalledWith({
29
+ serviceId: 'service',
30
+ title: 'really long title wi...',
31
+ description: expectedDescription,
32
+ uniqueKey: Hash.fromText(expectedDescription),
33
+ });
34
+ });
35
+ });
36
+ function getMockPagerDutyClient() {
37
+ return mockObject({
38
+ createIncident: mockFn(async (_data) => { }),
39
+ });
40
+ }
@@ -0,0 +1,28 @@
1
+ import { Hash } from '@sparkdotfi/common-universal';
2
+ import { renderToPagerdutyString } from './renderToPagerDuty.js';
3
+ export class PagerDutyReporter {
4
+ constructor(pagerDutyClient, serviceId) {
5
+ Object.defineProperty(this, "pagerDutyClient", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: pagerDutyClient
10
+ });
11
+ Object.defineProperty(this, "serviceId", {
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true,
15
+ value: serviceId
16
+ });
17
+ }
18
+ async report(report) {
19
+ const description = renderToPagerdutyString(report.content);
20
+ const uniqueKey = Hash.fromText(description);
21
+ await this.pagerDutyClient.createIncident({
22
+ serviceId: this.serviceId,
23
+ title: report.title ?? `${description.slice(0, 20)}...`,
24
+ description,
25
+ uniqueKey,
26
+ });
27
+ }
28
+ }
@@ -0,0 +1,15 @@
1
+ import { assertNever } from '@sparkdotfi/common-universal';
2
+ export function renderToPagerdutyString(node) {
3
+ return node
4
+ .map((block) => {
5
+ switch (block.type) {
6
+ case 'text':
7
+ return block.content;
8
+ case 'link':
9
+ return `[${block.href}] ${block.text}>`;
10
+ default:
11
+ assertNever(block);
12
+ }
13
+ })
14
+ .join(' ');
15
+ }
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { templating } from '../templating.js';
3
+ import { renderToSlackString } from './renderToSlack.js';
4
+ export class SlackReporter {
5
+ constructor(config, httpClient) {
6
+ Object.defineProperty(this, "config", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: config
11
+ });
12
+ Object.defineProperty(this, "httpClient", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: httpClient
17
+ });
18
+ }
19
+ async report(report) {
20
+ const text = renderToSlackString(this.getContentBlocks(report));
21
+ await this.httpClient.post(this.config.apiUrl, { text }, z.string());
22
+ }
23
+ getContentBlocks(report) {
24
+ if (report.title) {
25
+ return [templating.text(`${report.title}\n`, { bold: true }), ...report.content];
26
+ }
27
+ return report.content;
28
+ }
29
+ }
@@ -0,0 +1,31 @@
1
+ import { expect, mockFn, mockObject } from 'earl';
2
+ import { templating as t } from '../templating.js';
3
+ import { SlackReporter } from './SlackReporter.js';
4
+ describe(SlackReporter.name, () => {
5
+ it('joins title and content', async () => {
6
+ const httpClient = getMockHttpClient();
7
+ const reporter = new SlackReporter({ apiUrl: 'url' }, httpClient);
8
+ await reporter.report({
9
+ title: 'some title',
10
+ content: [t.text('some description'), t.text('additional description')],
11
+ });
12
+ expect(httpClient.post).toHaveBeenOnlyCalledWith('url', {
13
+ text: '> *some title*\n> some description additional description',
14
+ }, expect.anything());
15
+ });
16
+ it('sends message without title', async () => {
17
+ const httpClient = getMockHttpClient();
18
+ const reporter = new SlackReporter({ apiUrl: 'url' }, httpClient);
19
+ await reporter.report({
20
+ content: [t.text('some description'), t.text('additional description')],
21
+ });
22
+ expect(httpClient.post).toHaveBeenOnlyCalledWith('url', {
23
+ text: '> some description additional description',
24
+ }, expect.anything());
25
+ });
26
+ function getMockHttpClient() {
27
+ return mockObject({
28
+ post: mockFn((_url, _body, _schema) => 'some string'),
29
+ });
30
+ }
31
+ });
@@ -0,0 +1,51 @@
1
+ import { assertNever } from '@sparkdotfi/common-universal';
2
+ export function renderToSlackString(node) {
3
+ const text = node
4
+ .map((block) => {
5
+ switch (block.type) {
6
+ case 'text':
7
+ return applyFontStyle(block);
8
+ case 'link':
9
+ return `<${block.href}|${block.text}>`;
10
+ default:
11
+ assertNever(block);
12
+ }
13
+ })
14
+ .join(' ');
15
+ // we add block quotes to make the text more readable and aligned
16
+ const blockQuotes = text.split('\n').map((line) => {
17
+ return `> ${line.trim()}`;
18
+ });
19
+ return blockQuotes.join('\n');
20
+ }
21
+ export function applyFontStyle(block) {
22
+ const lines = block.content.split('\n');
23
+ if (lines.length === 1) {
24
+ return applyLineFontStyle(block.content, block.bold, block.italic);
25
+ }
26
+ return lines
27
+ .map((line) => {
28
+ const trimmedLine = line.trim();
29
+ if (trimmedLine.length === 0) {
30
+ return trimmedLine;
31
+ }
32
+ return applyLineFontStyle(trimmedLine, block.bold, block.italic);
33
+ })
34
+ .join('\n');
35
+ }
36
+ export function applyLineFontStyle(line, bold = false, italic = false) {
37
+ let result = line;
38
+ if (bold) {
39
+ result = applyBoldStyle(result);
40
+ }
41
+ if (italic) {
42
+ result = applyItalicStyle(result);
43
+ }
44
+ return result;
45
+ }
46
+ function applyBoldStyle(text) {
47
+ return `*${text}*`;
48
+ }
49
+ function applyItalicStyle(text) {
50
+ return `_${text}_`;
51
+ }
@@ -0,0 +1,188 @@
1
+ import { expect } from 'earl';
2
+ import { templating as t } from '../templating.js';
3
+ import { applyFontStyle, renderToSlackString } from './renderToSlack.js';
4
+ describe(renderToSlackString.name, () => {
5
+ it('renders content blocks', () => {
6
+ const content = [
7
+ t.text('Hello'),
8
+ t.text('World', { bold: true }),
9
+ t.text('!\n'),
10
+ t.link('https://basescan.org', 'Link to tx explorer'),
11
+ ];
12
+ const lines = ['> Hello *World* !', '> <https://basescan.org|Link to tx explorer>'];
13
+ expect(renderToSlackString(content)).toEqual(lines.join('\n'));
14
+ });
15
+ it('renders bold text with a newline correctly', () => {
16
+ const content = [t.text('Highlighted text\n', { bold: true }), t.text('text')];
17
+ expect(renderToSlackString(content)).toEqual('> *Highlighted text*\n' + '> text');
18
+ });
19
+ it('renders bold text with multiple newlines correctly', () => {
20
+ const content = [t.text('bold text\nmore bold text\n', { bold: true }), t.text('text')];
21
+ expect(renderToSlackString(content)).toEqual('> *bold text*\n' + '> *more bold text*\n' + '> text');
22
+ });
23
+ it('joins different blocks with space', () => {
24
+ const content = [
25
+ t.text('before link'),
26
+ t.link('https://google.com', 'click link'),
27
+ t.text('after link', { bold: true }),
28
+ ];
29
+ expect(renderToSlackString(content)).toEqual('> before link <https://google.com|click link> *after link*');
30
+ });
31
+ it('renders empty new lines correctly', () => {
32
+ const content = [
33
+ t.text('First'),
34
+ t.text('line'),
35
+ t.text('\n'),
36
+ t.text('\n'),
37
+ t.text('Third line'),
38
+ t.text('\n'),
39
+ t.text('Fourth line'),
40
+ ];
41
+ const lines = ['> First line', '> ', '> Third line', '> Fourth line'];
42
+ expect(renderToSlackString(content)).toEqual(lines.join('\n'));
43
+ });
44
+ it('renders new lines in correct order', () => {
45
+ const content = [
46
+ t.text('First'),
47
+ t.text('line'),
48
+ t.text('\nSecond line,'),
49
+ t.text('still second line\n'),
50
+ t.text('Third line'),
51
+ ];
52
+ const lines = ['> First line', '> Second line, still second line', '> Third line'];
53
+ expect(renderToSlackString(content)).toEqual(lines.join('\n'));
54
+ });
55
+ describe(applyFontStyle.name, () => {
56
+ describe('bold text', () => {
57
+ it('renders correctly', () => {
58
+ const block = {
59
+ type: 'text',
60
+ content: 'bold text',
61
+ bold: true,
62
+ };
63
+ expect(applyFontStyle(block)).toEqual('*bold text*');
64
+ });
65
+ it('renders with newline', () => {
66
+ const block = {
67
+ type: 'text',
68
+ content: 'bold text\n',
69
+ bold: true,
70
+ };
71
+ expect(applyFontStyle(block)).toEqual('*bold text*\n');
72
+ });
73
+ it('renders with multiple newlines', () => {
74
+ const block = {
75
+ type: 'text',
76
+ content: 'bold text\nmore bold text\n',
77
+ bold: true,
78
+ };
79
+ expect(applyFontStyle(block)).toEqual('*bold text*\n*more bold text*\n');
80
+ });
81
+ it('renders with empty string and newline', () => {
82
+ const block = {
83
+ type: 'text',
84
+ content: '\n',
85
+ bold: true,
86
+ };
87
+ expect(applyFontStyle(block)).toEqual('\n');
88
+ });
89
+ it('ignores empty parts', () => {
90
+ const block = {
91
+ type: 'text',
92
+ content: ' \n ',
93
+ bold: true,
94
+ };
95
+ expect(applyFontStyle(block)).toEqual('\n');
96
+ });
97
+ });
98
+ describe('italic text', () => {
99
+ it('renders correctly', () => {
100
+ const block = {
101
+ type: 'text',
102
+ content: 'italic text',
103
+ italic: true,
104
+ };
105
+ expect(applyFontStyle(block)).toEqual('_italic text_');
106
+ });
107
+ it('renders with newline', () => {
108
+ const block = {
109
+ type: 'text',
110
+ content: 'italic text\n',
111
+ italic: true,
112
+ };
113
+ expect(applyFontStyle(block)).toEqual('_italic text_\n');
114
+ });
115
+ it('renders with multiple newlines', () => {
116
+ const block = {
117
+ type: 'text',
118
+ content: 'italic text\nmore italic text\n',
119
+ italic: true,
120
+ };
121
+ expect(applyFontStyle(block)).toEqual('_italic text_\n_more italic text_\n');
122
+ });
123
+ it('renders with empty string and newline', () => {
124
+ const block = {
125
+ type: 'text',
126
+ content: '\n',
127
+ italic: true,
128
+ };
129
+ expect(applyFontStyle(block)).toEqual('\n');
130
+ });
131
+ it('ignores empty parts', () => {
132
+ const block = {
133
+ type: 'text',
134
+ content: ' \n ',
135
+ italic: true,
136
+ };
137
+ expect(applyFontStyle(block)).toEqual('\n');
138
+ });
139
+ });
140
+ describe('bold and italics text', () => {
141
+ it('renders correctly', () => {
142
+ const block = {
143
+ type: 'text',
144
+ content: 'bold and italic text',
145
+ bold: true,
146
+ italic: true,
147
+ };
148
+ expect(applyFontStyle(block)).toEqual('_*bold and italic text*_');
149
+ });
150
+ it('renders with newline', () => {
151
+ const block = {
152
+ type: 'text',
153
+ content: 'bold and italic text\n',
154
+ bold: true,
155
+ italic: true,
156
+ };
157
+ expect(applyFontStyle(block)).toEqual('_*bold and italic text*_\n');
158
+ });
159
+ it('renders with multiple newlines', () => {
160
+ const block = {
161
+ type: 'text',
162
+ content: 'bold and italic text\nmore bold and italic text\n',
163
+ bold: true,
164
+ italic: true,
165
+ };
166
+ expect(applyFontStyle(block)).toEqual('_*bold and italic text*_\n_*more bold and italic text*_\n');
167
+ });
168
+ it('renders with empty string and newline', () => {
169
+ const block = {
170
+ type: 'text',
171
+ content: '\n',
172
+ bold: true,
173
+ italic: true,
174
+ };
175
+ expect(applyFontStyle(block)).toEqual('\n');
176
+ });
177
+ it('ignores empty parts', () => {
178
+ const block = {
179
+ type: 'text',
180
+ content: ' \n ',
181
+ bold: true,
182
+ italic: true,
183
+ };
184
+ expect(applyFontStyle(block)).toEqual('\n');
185
+ });
186
+ });
187
+ });
188
+ });
@@ -0,0 +1,11 @@
1
+ function text(content, extra) {
2
+ return { type: 'text', content, ...(extra ?? {}) };
3
+ }
4
+ function link(href, text) {
5
+ return { type: 'link', href, text };
6
+ }
7
+ export const templating = {
8
+ text,
9
+ link,
10
+ newLine: text('\n'),
11
+ };
@@ -0,0 +1,11 @@
1
+ import { ILogger } from '@sparkdotfi/common-universal/logger';
2
+ import { IReporter, Report } from '../types.js';
3
+ export declare class ConsoleReporter implements IReporter {
4
+ private readonly logFunctionName;
5
+ private readonly logger;
6
+ constructor(logger: ILogger, logFunctionName: LogFunctionName);
7
+ report(report: Report): Promise<void>;
8
+ }
9
+ type LogFunctionName = Exclude<keyof ILogger, 'configure' | 'for' | 'tag'>;
10
+ export {};
11
+ //# sourceMappingURL=ConsoleReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleReporter.d.ts","sourceRoot":"","sources":["../../../src/console/ConsoleReporter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAA;AAE7D,OAAO,EAAgB,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE7D,qBAAa,eAAgB,YAAW,SAAS;IAK7C,OAAO,CAAC,QAAQ,CAAC,eAAe;IAJlC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,MAAM,EAAE,OAAO,EACE,eAAe,EAAE,eAAe;IAK7C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C;AAsBD,KAAK,eAAe,GAAG,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,GAAG,KAAK,GAAG,KAAK,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ConsoleReporter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleReporter.test.d.ts","sourceRoot":"","sources":["../../../src/console/ConsoleReporter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export * from './templating.js';
2
+ export * from './types.js';
3
+ export { ConsoleReporter } from './console/ConsoleReporter.js';
4
+ export { PagerDutyClient } from './pagerduty/PagerDutyClient.js';
5
+ export { PagerDutyReporter } from './pagerduty/PagerDutyReporter.js';
6
+ export { SlackReporter } from './slack/SlackReporter.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,13 @@
1
+ export declare class PagerDutyClient {
2
+ readonly apiKey: string;
3
+ private readonly requesterEmail;
4
+ private readonly pdClient;
5
+ constructor(apiKey: string, requesterEmail: string);
6
+ createIncident({ serviceId, title, description, uniqueKey, }: {
7
+ serviceId: string;
8
+ title: string;
9
+ description: string;
10
+ uniqueKey: string;
11
+ }): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=PagerDutyClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PagerDutyClient.d.ts","sourceRoot":"","sources":["../../../src/pagerduty/PagerDutyClient.ts"],"names":[],"mappings":"AAEA,qBAAa,eAAe;IAIxB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAJjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;gBAGtC,MAAM,EAAE,MAAM,EACN,cAAc,EAAE,MAAM;IAKnC,cAAc,CAAC,EACnB,SAAS,EACT,KAAK,EACL,WAAW,EACX,SAAS,GACV,EAAE;QACD,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;CA8BlB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PagerDutyReport.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PagerDutyReport.test.d.ts","sourceRoot":"","sources":["../../../src/pagerduty/PagerDutyReport.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { IReporter, Report } from '../types.js';
2
+ import { PagerDutyClient } from './PagerDutyClient.js';
3
+ export declare class PagerDutyReporter implements IReporter {
4
+ private readonly pagerDutyClient;
5
+ private readonly serviceId;
6
+ constructor(pagerDutyClient: PagerDutyClient, serviceId: string);
7
+ report(report: Report): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=PagerDutyReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PagerDutyReporter.d.ts","sourceRoot":"","sources":["../../../src/pagerduty/PagerDutyReporter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAGtD,qBAAa,iBAAkB,YAAW,SAAS;IAE/C,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM;IAG9B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAW5C"}
@@ -0,0 +1,3 @@
1
+ import { ContentBlock } from '../types.js';
2
+ export declare function renderToPagerdutyString(node: ContentBlock[]): string;
3
+ //# sourceMappingURL=renderToPagerDuty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderToPagerDuty.d.ts","sourceRoot":"","sources":["../../../src/pagerduty/renderToPagerDuty.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,CAapE"}
@@ -0,0 +1,14 @@
1
+ import { HttpClient } from '@sparkdotfi/common-universal/http-client';
2
+ import { IReporter, Report } from '../types.js';
3
+ interface SlackReporterConfig {
4
+ apiUrl: string;
5
+ }
6
+ export declare class SlackReporter implements IReporter {
7
+ private readonly config;
8
+ private readonly httpClient;
9
+ constructor(config: SlackReporterConfig, httpClient: HttpClient);
10
+ report(report: Report): Promise<void>;
11
+ private getContentBlocks;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=SlackReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlackReporter.d.ts","sourceRoot":"","sources":["../../../src/slack/SlackReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AAGrE,OAAO,EAAgB,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAG7D,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,qBAAa,aAAc,YAAW,SAAS;IAE3C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,UAAU;IAGnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,OAAO,CAAC,gBAAgB;CAMzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SlackReporter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlackReporter.test.d.ts","sourceRoot":"","sources":["../../../src/slack/SlackReporter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import { ContentBlock } from '../types.js';
2
+ export declare function renderToSlackString(node: ContentBlock[]): string;
3
+ export declare function applyFontStyle(block: Extract<ContentBlock, {
4
+ type: 'text';
5
+ }>): string;
6
+ export declare function applyLineFontStyle(line: string, bold?: boolean, italic?: boolean): string;
7
+ //# sourceMappingURL=renderToSlack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderToSlack.d.ts","sourceRoot":"","sources":["../../../src/slack/renderToSlack.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,CAoBhE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAcrF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,UAAQ,EAAE,MAAM,UAAQ,GAAG,MAAM,CASrF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=renderToSlack.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderToSlack.test.d.ts","sourceRoot":"","sources":["../../../src/slack/renderToSlack.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { ContentBlock } from './types.js';
2
+ declare function text(content: string, extra?: {
3
+ bold?: boolean;
4
+ }): ContentBlock;
5
+ declare function link(href: string, text: string): ContentBlock;
6
+ export declare const templating: {
7
+ text: typeof text;
8
+ link: typeof link;
9
+ newLine: ContentBlock;
10
+ };
11
+ export {};
12
+ //# sourceMappingURL=templating.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templating.d.ts","sourceRoot":"","sources":["../../src/templating.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,iBAAS,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAEvE;AAED,iBAAS,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAEtD;AAED,eAAO,MAAM,UAAU;;;;CAItB,CAAA"}
@@ -0,0 +1,18 @@
1
+ export type ContentBlock = {
2
+ type: 'text';
3
+ content: string;
4
+ bold?: boolean;
5
+ italic?: boolean;
6
+ } | {
7
+ type: 'link';
8
+ href: string;
9
+ text: string;
10
+ };
11
+ export interface Report {
12
+ title?: string;
13
+ content: ContentBlock[];
14
+ }
15
+ export interface IReporter {
16
+ report(report: Report): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,GACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAEL,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@sparkdotfi/common-reporters",
3
+ "version": "0.0.1",
4
+ "engines": {
5
+ "node": ">=18.0.0"
6
+ },
7
+ "type": "module",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/types/index.d.ts",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/sparkdotfi/spark-app.git",
13
+ "directory": "packages/common-reporters"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "@sparkdotfi/local-spark-monorepo": "./src/index.ts",
18
+ "types": "./dist/types/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": ["dist"],
23
+ "scripts": {
24
+ "lint": "eslint src",
25
+ "verify": "concurrently --names \"LINT,TEST,TYPECHECK,LINT-CUSTOM\" -c \"bgMagenta.bold,bgGreen.bold,bgBlue.bold,bgCyan.bold\" \"pnpm run lint\" \"pnpm run test --silent\" \"pnpm run typecheck\"",
26
+ "fix": "cd ../../ && pnpm run check:fix && cd - && pnpm run verify",
27
+ "test": "mocha src/**/*.test.ts",
28
+ "typecheck": "tsc --noEmit",
29
+ "build": "tsc -p tsconfig.json",
30
+ "clean": "rm -rf dist",
31
+ "prepublishOnly": "pnpm run clean && pnpm run build"
32
+ },
33
+ "devDependencies": {
34
+ "earl": "^1.3.0",
35
+ "mocha": "^10.8.2"
36
+ },
37
+ "dependencies": {
38
+ "@pagerduty/pdjs": "^2.2.4"
39
+ },
40
+ "peerDependencies": {
41
+ "@types/mocha": "^10.0.10",
42
+ "@sparkdotfi/common-universal": "workspace:^",
43
+ "zod": "^3.0"
44
+ }
45
+ }