@rallycry/conveyor-incidents 0.1.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 +87 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.js +157 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# @rallycry/conveyor-incidents
|
|
2
|
+
|
|
3
|
+
Typed TypeScript client for reporting incidents to [Conveyor](https://conveyor.rallycry.gg) via the public REST API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @rallycry/conveyor-incidents
|
|
9
|
+
# or
|
|
10
|
+
bun add @rallycry/conveyor-incidents
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { ConveyorIncidents } from "@rallycry/conveyor-incidents";
|
|
17
|
+
|
|
18
|
+
const incidents = new ConveyorIncidents({
|
|
19
|
+
apiKey: process.env.CONVEYOR_INCIDENT_TOKEN!, // cvyr_... project token with "incident" scope
|
|
20
|
+
projectId: process.env.CONVEYOR_PROJECT_ID!,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const { incidentId, attachmentResults } = await incidents.report({
|
|
24
|
+
title: "Checkout service returned 500",
|
|
25
|
+
description: "Happened on release v1.4.2 under load.",
|
|
26
|
+
severity: "high",
|
|
27
|
+
source: "prod-web", // stable values let the server dedup repeats
|
|
28
|
+
fingerprintKey: "checkout-500-v1.4.2",
|
|
29
|
+
attachments: [
|
|
30
|
+
{
|
|
31
|
+
fileName: "stack.txt",
|
|
32
|
+
mimeType: "text/plain",
|
|
33
|
+
content: stackTrace, // string or Uint8Array
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### About `source` and `fingerprintKey`
|
|
40
|
+
|
|
41
|
+
Conveyor deduplicates reports by a fingerprint derived from `(projectId, source, fingerprintKey)` — or by `(projectId, source, title)` if `fingerprintKey` is omitted. **Use stable values** for `source` (e.g. `"prod-web"`, not `"node-pid-1234"`) so that repeat reports collapse into a single incident instead of creating noise.
|
|
42
|
+
|
|
43
|
+
### Error handling
|
|
44
|
+
|
|
45
|
+
- The main `report()` call throws `ConveyorIncidentsError` on non-2xx responses; it exposes `.status` and `.body`.
|
|
46
|
+
- Attachment upload failures are captured per-file in `attachmentResults` and never throw — inspect `ok` and `error`.
|
|
47
|
+
|
|
48
|
+
### Node `<18`
|
|
49
|
+
|
|
50
|
+
Pass a `fetch` polyfill via `opts.fetch` if your runtime lacks a global `fetch`.
|
|
51
|
+
|
|
52
|
+
## API
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
new ConveyorIncidents({
|
|
56
|
+
apiKey: string;
|
|
57
|
+
projectId: string;
|
|
58
|
+
baseUrl?: string; // default: "https://conveyor.rallycry.gg"
|
|
59
|
+
fetch?: typeof fetch;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
client.report({
|
|
63
|
+
title: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
severity?: "critical" | "high" | "medium" | "low"; // default: "medium"
|
|
66
|
+
source?: string; // default: "client"
|
|
67
|
+
fingerprintKey?: string;
|
|
68
|
+
plan?: string;
|
|
69
|
+
attachments?: Array<{
|
|
70
|
+
fileName: string;
|
|
71
|
+
mimeType: string;
|
|
72
|
+
content: Uint8Array | string; // strings are utf-8 encoded
|
|
73
|
+
}>;
|
|
74
|
+
}): Promise<{
|
|
75
|
+
incidentId: string;
|
|
76
|
+
attachmentResults: Array<{
|
|
77
|
+
fileName: string;
|
|
78
|
+
ok: boolean;
|
|
79
|
+
fileId?: string;
|
|
80
|
+
error?: string;
|
|
81
|
+
}>;
|
|
82
|
+
}>;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
declare class ConveyorIncidentsError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly body: unknown;
|
|
4
|
+
constructor(message: string, status: number, body: unknown);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
type IncidentSeverity = "critical" | "high" | "medium" | "low";
|
|
8
|
+
interface ConveyorIncidentsOptions {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
projectId: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
}
|
|
14
|
+
interface IncidentAttachment {
|
|
15
|
+
fileName: string;
|
|
16
|
+
mimeType: string;
|
|
17
|
+
content: Uint8Array | string;
|
|
18
|
+
}
|
|
19
|
+
interface ReportIncidentInput {
|
|
20
|
+
title: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
severity?: IncidentSeverity;
|
|
23
|
+
source?: string;
|
|
24
|
+
fingerprintKey?: string;
|
|
25
|
+
plan?: string;
|
|
26
|
+
attachments?: IncidentAttachment[];
|
|
27
|
+
}
|
|
28
|
+
interface AttachmentResult {
|
|
29
|
+
fileName: string;
|
|
30
|
+
ok: boolean;
|
|
31
|
+
fileId?: string;
|
|
32
|
+
error?: string;
|
|
33
|
+
}
|
|
34
|
+
interface ReportIncidentResult {
|
|
35
|
+
incidentId: string;
|
|
36
|
+
attachmentResults: AttachmentResult[];
|
|
37
|
+
}
|
|
38
|
+
declare class ConveyorIncidents {
|
|
39
|
+
private readonly apiKey;
|
|
40
|
+
private readonly projectId;
|
|
41
|
+
private readonly baseUrl;
|
|
42
|
+
private readonly fetchImpl;
|
|
43
|
+
constructor(opts: ConveyorIncidentsOptions);
|
|
44
|
+
report(input: ReportIncidentInput): Promise<ReportIncidentResult>;
|
|
45
|
+
private uploadAttachment;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { type AttachmentResult, ConveyorIncidents, ConveyorIncidentsError, type ConveyorIncidentsOptions, type IncidentAttachment, type IncidentSeverity, type ReportIncidentInput, type ReportIncidentResult };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var ConveyorIncidentsError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
body;
|
|
5
|
+
constructor(message, status, body) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "ConveyorIncidentsError";
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.body = body;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// src/index.ts
|
|
14
|
+
var DEFAULT_BASE_URL = "https://conveyor.rallycry.gg";
|
|
15
|
+
var DEFAULT_SOURCE = "client";
|
|
16
|
+
var DEFAULT_SEVERITY = "medium";
|
|
17
|
+
var ConveyorIncidents = class {
|
|
18
|
+
apiKey;
|
|
19
|
+
projectId;
|
|
20
|
+
baseUrl;
|
|
21
|
+
fetchImpl;
|
|
22
|
+
constructor(opts) {
|
|
23
|
+
if (!opts.apiKey) {
|
|
24
|
+
throw new Error("ConveyorIncidents: apiKey is required");
|
|
25
|
+
}
|
|
26
|
+
if (!opts.projectId) {
|
|
27
|
+
throw new Error("ConveyorIncidents: projectId is required");
|
|
28
|
+
}
|
|
29
|
+
const resolvedFetch = opts.fetch ?? globalThis.fetch;
|
|
30
|
+
if (typeof resolvedFetch !== "function") {
|
|
31
|
+
throw new Error("ConveyorIncidents: no global fetch available \u2014 pass opts.fetch on Node <18");
|
|
32
|
+
}
|
|
33
|
+
this.apiKey = opts.apiKey;
|
|
34
|
+
this.projectId = opts.projectId;
|
|
35
|
+
this.baseUrl = stripTrailingSlash(opts.baseUrl ?? DEFAULT_BASE_URL);
|
|
36
|
+
this.fetchImpl = resolvedFetch;
|
|
37
|
+
}
|
|
38
|
+
async report(input) {
|
|
39
|
+
const body = {
|
|
40
|
+
projectId: this.projectId,
|
|
41
|
+
source: input.source ?? DEFAULT_SOURCE,
|
|
42
|
+
severity: input.severity ?? DEFAULT_SEVERITY,
|
|
43
|
+
title: input.title,
|
|
44
|
+
description: input.description,
|
|
45
|
+
plan: input.plan,
|
|
46
|
+
fingerprintKey: input.fingerprintKey
|
|
47
|
+
};
|
|
48
|
+
const res = await this.fetchImpl(`${this.baseUrl}/api/incidents/report`, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify(body)
|
|
55
|
+
});
|
|
56
|
+
const payload = await readJson(res);
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
throw new ConveyorIncidentsError(
|
|
59
|
+
`Failed to report incident: ${res.status} ${res.statusText}`,
|
|
60
|
+
res.status,
|
|
61
|
+
payload
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
const incidentId = payload && typeof payload === "object" && "incidentId" in payload ? String(payload.incidentId) : void 0;
|
|
65
|
+
if (!incidentId) {
|
|
66
|
+
throw new ConveyorIncidentsError(
|
|
67
|
+
"Invalid response from /api/incidents/report: missing incidentId",
|
|
68
|
+
res.status,
|
|
69
|
+
payload
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const attachmentResults = [];
|
|
73
|
+
if (input.attachments && input.attachments.length > 0) {
|
|
74
|
+
for (const attachment of input.attachments) {
|
|
75
|
+
attachmentResults.push(await this.uploadAttachment(incidentId, attachment));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { incidentId, attachmentResults };
|
|
79
|
+
}
|
|
80
|
+
async uploadAttachment(incidentId, attachment) {
|
|
81
|
+
try {
|
|
82
|
+
const contentBase64 = toBase64(attachment.content);
|
|
83
|
+
const res = await this.fetchImpl(
|
|
84
|
+
`${this.baseUrl}/api/incidents/${encodeURIComponent(incidentId)}/files`,
|
|
85
|
+
{
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "application/json",
|
|
89
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
fileName: attachment.fileName,
|
|
93
|
+
mimeType: attachment.mimeType,
|
|
94
|
+
contentBase64
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
const payload = await readJson(res);
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
return {
|
|
101
|
+
fileName: attachment.fileName,
|
|
102
|
+
ok: false,
|
|
103
|
+
error: formatErrorBody(res.status, res.statusText, payload)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const fileId = payload && typeof payload === "object" && "fileId" in payload ? String(payload.fileId) : void 0;
|
|
107
|
+
return { fileName: attachment.fileName, ok: true, fileId };
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
fileName: attachment.fileName,
|
|
111
|
+
ok: false,
|
|
112
|
+
error: err instanceof Error ? err.message : String(err)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
function stripTrailingSlash(url) {
|
|
118
|
+
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
119
|
+
}
|
|
120
|
+
async function readJson(res) {
|
|
121
|
+
const text = await res.text();
|
|
122
|
+
if (!text) return void 0;
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(text);
|
|
125
|
+
} catch {
|
|
126
|
+
return text;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function formatErrorBody(status, statusText, body) {
|
|
130
|
+
const prefix = `${status} ${statusText}`.trim();
|
|
131
|
+
if (body && typeof body === "object" && "error" in body) {
|
|
132
|
+
return `${prefix}: ${String(body.error)}`;
|
|
133
|
+
}
|
|
134
|
+
if (typeof body === "string" && body.length > 0) {
|
|
135
|
+
return `${prefix}: ${body}`;
|
|
136
|
+
}
|
|
137
|
+
return prefix;
|
|
138
|
+
}
|
|
139
|
+
function toBase64(content) {
|
|
140
|
+
const bytes = typeof content === "string" ? new TextEncoder().encode(content) : content;
|
|
141
|
+
return bytesToBase64(bytes);
|
|
142
|
+
}
|
|
143
|
+
function bytesToBase64(bytes) {
|
|
144
|
+
if (typeof Buffer !== "undefined") {
|
|
145
|
+
return Buffer.from(bytes).toString("base64");
|
|
146
|
+
}
|
|
147
|
+
let binary = "";
|
|
148
|
+
for (const byte of bytes) {
|
|
149
|
+
binary += String.fromCharCode(byte);
|
|
150
|
+
}
|
|
151
|
+
return btoa(binary);
|
|
152
|
+
}
|
|
153
|
+
export {
|
|
154
|
+
ConveyorIncidents,
|
|
155
|
+
ConveyorIncidentsError
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/index.ts"],"sourcesContent":["export class ConveyorIncidentsError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"ConveyorIncidentsError\";\n this.status = status;\n this.body = body;\n }\n}\n","import { ConveyorIncidentsError } from \"./errors.js\";\n\nexport { ConveyorIncidentsError } from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://conveyor.rallycry.gg\";\nconst DEFAULT_SOURCE = \"client\";\nconst DEFAULT_SEVERITY: IncidentSeverity = \"medium\";\n\nexport type IncidentSeverity = \"critical\" | \"high\" | \"medium\" | \"low\";\n\nexport interface ConveyorIncidentsOptions {\n apiKey: string;\n projectId: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n}\n\nexport interface IncidentAttachment {\n fileName: string;\n mimeType: string;\n content: Uint8Array | string;\n}\n\nexport interface ReportIncidentInput {\n title: string;\n description?: string;\n severity?: IncidentSeverity;\n source?: string;\n fingerprintKey?: string;\n plan?: string;\n attachments?: IncidentAttachment[];\n}\n\nexport interface AttachmentResult {\n fileName: string;\n ok: boolean;\n fileId?: string;\n error?: string;\n}\n\nexport interface ReportIncidentResult {\n incidentId: string;\n attachmentResults: AttachmentResult[];\n}\n\nexport class ConveyorIncidents {\n private readonly apiKey: string;\n private readonly projectId: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(opts: ConveyorIncidentsOptions) {\n if (!opts.apiKey) {\n throw new Error(\"ConveyorIncidents: apiKey is required\");\n }\n if (!opts.projectId) {\n throw new Error(\"ConveyorIncidents: projectId is required\");\n }\n const resolvedFetch = opts.fetch ?? globalThis.fetch;\n if (typeof resolvedFetch !== \"function\") {\n throw new Error(\"ConveyorIncidents: no global fetch available — pass opts.fetch on Node <18\");\n }\n this.apiKey = opts.apiKey;\n this.projectId = opts.projectId;\n this.baseUrl = stripTrailingSlash(opts.baseUrl ?? DEFAULT_BASE_URL);\n this.fetchImpl = resolvedFetch;\n }\n\n async report(input: ReportIncidentInput): Promise<ReportIncidentResult> {\n const body = {\n projectId: this.projectId,\n source: input.source ?? DEFAULT_SOURCE,\n severity: input.severity ?? DEFAULT_SEVERITY,\n title: input.title,\n description: input.description,\n plan: input.plan,\n fingerprintKey: input.fingerprintKey,\n };\n\n const res = await this.fetchImpl(`${this.baseUrl}/api/incidents/report`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n const payload = await readJson(res);\n\n if (!res.ok) {\n throw new ConveyorIncidentsError(\n `Failed to report incident: ${res.status} ${res.statusText}`,\n res.status,\n payload,\n );\n }\n\n const incidentId =\n payload && typeof payload === \"object\" && \"incidentId\" in payload\n ? String((payload as { incidentId: unknown }).incidentId)\n : undefined;\n\n if (!incidentId) {\n throw new ConveyorIncidentsError(\n \"Invalid response from /api/incidents/report: missing incidentId\",\n res.status,\n payload,\n );\n }\n\n const attachmentResults: AttachmentResult[] = [];\n if (input.attachments && input.attachments.length > 0) {\n for (const attachment of input.attachments) {\n attachmentResults.push(await this.uploadAttachment(incidentId, attachment));\n }\n }\n\n return { incidentId, attachmentResults };\n }\n\n private async uploadAttachment(\n incidentId: string,\n attachment: IncidentAttachment,\n ): Promise<AttachmentResult> {\n try {\n const contentBase64 = toBase64(attachment.content);\n const res = await this.fetchImpl(\n `${this.baseUrl}/api/incidents/${encodeURIComponent(incidentId)}/files`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n fileName: attachment.fileName,\n mimeType: attachment.mimeType,\n contentBase64,\n }),\n },\n );\n\n const payload = await readJson(res);\n\n if (!res.ok) {\n return {\n fileName: attachment.fileName,\n ok: false,\n error: formatErrorBody(res.status, res.statusText, payload),\n };\n }\n\n const fileId =\n payload && typeof payload === \"object\" && \"fileId\" in payload\n ? String((payload as { fileId: unknown }).fileId)\n : undefined;\n\n return { fileName: attachment.fileName, ok: true, fileId };\n } catch (err) {\n return {\n fileName: attachment.fileName,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n}\n\nfunction stripTrailingSlash(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\nasync function readJson(res: Response): Promise<unknown> {\n const text = await res.text();\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction formatErrorBody(status: number, statusText: string, body: unknown): string {\n const prefix = `${status} ${statusText}`.trim();\n if (body && typeof body === \"object\" && \"error\" in body) {\n return `${prefix}: ${String((body as { error: unknown }).error)}`;\n }\n if (typeof body === \"string\" && body.length > 0) {\n return `${prefix}: ${body}`;\n }\n return prefix;\n}\n\nfunction toBase64(content: Uint8Array | string): string {\n const bytes = typeof content === \"string\" ? new TextEncoder().encode(content) : content;\n return bytesToBase64(bytes);\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(bytes).toString(\"base64\");\n }\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rallycry/conveyor-incidents",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Typed TypeScript client for Conveyor's public incidents REST API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"client",
|
|
7
|
+
"conveyor",
|
|
8
|
+
"incidents",
|
|
9
|
+
"rallycry"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"prepublishOnly": "tsup",
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"build:js": "tsup --no-dts --no-clean",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"test": "vitest run --passWithNoTests",
|
|
27
|
+
"test:unit": "vitest run --passWithNoTests",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"lint": "oxlint -c ../../.oxlintrc.json src",
|
|
30
|
+
"lint:fix": "oxlint -c ../../.oxlintrc.json --fix src",
|
|
31
|
+
"typecheck": "tsgo --noEmit"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"tsup": "^8.0.0",
|
|
35
|
+
"typescript": "^5.3.0",
|
|
36
|
+
"vitest": "^4.0.17"
|
|
37
|
+
}
|
|
38
|
+
}
|