@shivaedev/webhooks 0.1.1 → 0.1.3
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 +50 -54
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -8,14 +8,12 @@ A sender can retry or send concurrent copies. Your application declares which ev
|
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
const sources = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
-
}),
|
|
11
|
+
github: githubSource({
|
|
12
|
+
key: Config.Redacted("GITHUB_WEBHOOK_SECRET"),
|
|
13
|
+
events: {
|
|
14
|
+
issues: webhookEvent(IssueEvent, ({ issue }) => [webhookJob(IndexIssue, { number: issue.number })]),
|
|
15
|
+
},
|
|
16
|
+
}),
|
|
19
17
|
};
|
|
20
18
|
```
|
|
21
19
|
|
|
@@ -41,48 +39,46 @@ import { webhookReceipts } from "@shivaedev/webhooks/webhookReceipts.ts";
|
|
|
41
39
|
|
|
42
40
|
const Jobs = makePgBoss("app/Jobs");
|
|
43
41
|
const IndexIssue = defineQueue({
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
name: "index-issue",
|
|
43
|
+
schema: Schema.Struct({ number: Schema.Number }),
|
|
46
44
|
});
|
|
47
45
|
const IssueEvent = Schema.Struct({
|
|
48
|
-
|
|
46
|
+
issue: Schema.Struct({ number: Schema.Number }),
|
|
49
47
|
});
|
|
50
48
|
const sources = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
},
|
|
58
|
-
}),
|
|
49
|
+
github: githubSource({
|
|
50
|
+
key: Config.Redacted("GITHUB_WEBHOOK_SECRET"),
|
|
51
|
+
events: {
|
|
52
|
+
issues: webhookEvent(IssueEvent, ({ issue }) => [webhookJob(IndexIssue, { number: issue.number })]),
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
59
55
|
};
|
|
60
56
|
|
|
61
57
|
const Host = appHost({
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
58
|
+
config: { databaseUrl },
|
|
59
|
+
migrations: {
|
|
60
|
+
loader,
|
|
61
|
+
components: [pgBossSchema(), webhookReceipts],
|
|
62
|
+
},
|
|
63
|
+
application: Effect.gen(function* () {
|
|
64
|
+
const sql = yield* SqlClient.SqlClient;
|
|
65
|
+
const jobs = Jobs.layer({
|
|
66
|
+
connectionString: Redacted.value(databaseUrl),
|
|
67
|
+
jobs: [IndexIssue],
|
|
68
|
+
migrate: false,
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
group: Api,
|
|
72
|
+
handlers,
|
|
73
|
+
sessions,
|
|
74
|
+
services: jobs,
|
|
75
|
+
routes: webhookRoute({ basePath: "/webhooks", jobs: Jobs, sources }).pipe(
|
|
76
|
+
Layer.provide(jobs),
|
|
77
|
+
Layer.provide(Layer.succeed(SqlClient.SqlClient, sql)),
|
|
78
|
+
Layer.orDie,
|
|
79
|
+
),
|
|
80
|
+
};
|
|
81
|
+
}),
|
|
86
82
|
});
|
|
87
83
|
```
|
|
88
84
|
|
|
@@ -90,17 +86,17 @@ const Host = appHost({
|
|
|
90
86
|
|
|
91
87
|
### Answers and retries
|
|
92
88
|
|
|
93
|
-
| Request
|
|
94
|
-
|
|
|
95
|
-
| Registered event maps to jobs
|
|
96
|
-
| Unlisted event, or mapping returns no jobs | 200
|
|
97
|
-
| Source and delivery ID already recorded
|
|
98
|
-
| Unregistered source
|
|
99
|
-
| Missing or wrong signature
|
|
100
|
-
| Missing delivery ID or event header
|
|
101
|
-
| Payload rejected by its Schema
|
|
102
|
-
| Body exceeds the host limit
|
|
103
|
-
| Database or enqueue failure
|
|
89
|
+
| Request | Status | Body |
|
|
90
|
+
| ------------------------------------------ | ------ | ------------------ |
|
|
91
|
+
| Registered event maps to jobs | 202 | `queued` |
|
|
92
|
+
| Unlisted event, or mapping returns no jobs | 200 | `ignored` |
|
|
93
|
+
| Source and delivery ID already recorded | 200 | `already queued` |
|
|
94
|
+
| Unregistered source | 404 | Empty |
|
|
95
|
+
| Missing or wrong signature | 401 | Empty |
|
|
96
|
+
| Missing delivery ID or event header | 400 | `Invalid delivery` |
|
|
97
|
+
| Payload rejected by its Schema | 400 | Empty |
|
|
98
|
+
| Body exceeds the host limit | 413 | Empty |
|
|
99
|
+
| Database or enqueue failure | 503 | Empty |
|
|
104
100
|
|
|
105
101
|
Refused requests create no receipt and no jobs. Signatures are checked before decoding; unlisted events are verified and recorded without decoding. The signing key, signature and raw body stay out of responses, logs and spans.
|
|
106
102
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/webhooks",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Verified webhook receipts and transactional job delivery over Effect HTTP",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -45,26 +45,26 @@
|
|
|
45
45
|
"README.md"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@shivaedev/github": "0.7.
|
|
49
|
-
"@shivaedev/http": "0.
|
|
50
|
-
"@shivaedev/jobs": "0.22.
|
|
51
|
-
"@shivaedev/sql": "0.
|
|
48
|
+
"@shivaedev/github": "0.7.2",
|
|
49
|
+
"@shivaedev/http": "0.2.0",
|
|
50
|
+
"@shivaedev/jobs": "0.22.1",
|
|
51
|
+
"@shivaedev/sql": "0.25.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@effect/platform-node": "4.0.
|
|
55
|
-
"@shivaedev/quality": "0.
|
|
56
|
-
"@shivaedev/server": "0.
|
|
57
|
-
"@shivaedev/test-sql": "0.
|
|
58
|
-
"@shivaedev/test-story": "0.
|
|
54
|
+
"@effect/platform-node": "4.0.6",
|
|
55
|
+
"@shivaedev/quality": "0.45.0",
|
|
56
|
+
"@shivaedev/server": "0.5.0",
|
|
57
|
+
"@shivaedev/test-sql": "0.11.0",
|
|
58
|
+
"@shivaedev/test-story": "0.24.0",
|
|
59
59
|
"@types/node": "24.19.2",
|
|
60
|
-
"effect": "4.0.
|
|
60
|
+
"effect": "4.0.6",
|
|
61
61
|
"pg-boss": "12.38.0",
|
|
62
62
|
"typescript": "7.0.2",
|
|
63
63
|
"vitest": "5.0.5"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@effect/platform-node": "4.0.
|
|
67
|
-
"effect": "4.0.
|
|
66
|
+
"@effect/platform-node": "4.0.6",
|
|
67
|
+
"effect": "4.0.6"
|
|
68
68
|
},
|
|
69
69
|
"peerDependenciesMeta": {
|
|
70
70
|
"@effect/platform-node": {
|