xquik-convex 0.2.0 → 0.2.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.
- package/README.md +1 -1
- package/dist/client.d.ts +103 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +73 -0
- package/dist/client.js.map +1 -0
- package/dist/component/_generated/api.d.ts +4 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/access.d.ts +1 -1
- package/dist/component/access.d.ts.map +1 -1
- package/dist/component/access.js +3 -3
- package/dist/component/access.js.map +1 -1
- package/dist/component/crons.d.ts +3 -2
- package/dist/component/crons.d.ts.map +1 -1
- package/dist/component/crons.js +6 -3
- package/dist/component/crons.js.map +1 -1
- package/dist/component/delivery.d.ts +51 -16
- package/dist/component/delivery.d.ts.map +1 -1
- package/dist/component/delivery.js +71 -41
- package/dist/component/delivery.js.map +1 -1
- package/dist/component/events.d.ts +3 -19
- package/dist/component/events.d.ts.map +1 -1
- package/dist/component/events.js +21 -17
- package/dist/component/events.js.map +1 -1
- package/dist/component/http.d.ts +3 -3
- package/dist/component/http.d.ts.map +1 -1
- package/dist/component/http.js +46 -23
- package/dist/component/http.js.map +1 -1
- package/dist/component/job.d.ts +101 -0
- package/dist/component/job.d.ts.map +1 -0
- package/dist/component/job.js +102 -0
- package/dist/component/job.js.map +1 -0
- package/dist/component/jobs.d.ts +36 -107
- package/dist/component/jobs.d.ts.map +1 -1
- package/dist/component/jobs.js +109 -121
- package/dist/component/jobs.js.map +1 -1
- package/dist/component/operation.d.ts +6 -3
- package/dist/component/operation.d.ts.map +1 -1
- package/dist/component/operation.js +8 -3
- package/dist/component/operation.js.map +1 -1
- package/dist/component/operations.d.ts +1331 -190
- package/dist/component/operations.d.ts.map +1 -1
- package/dist/component/operations.js +2 -191
- package/dist/component/operations.js.map +1 -1
- package/dist/component/registry.d.ts +14 -0
- package/dist/component/registry.d.ts.map +1 -0
- package/dist/component/registry.js +154 -0
- package/dist/component/registry.js.map +1 -0
- package/dist/component/registry.json +14402 -46998
- package/dist/component/request.d.ts +12 -18
- package/dist/component/request.d.ts.map +1 -1
- package/dist/component/request.js +94 -169
- package/dist/component/request.js.map +1 -1
- package/dist/component/schema.d.ts +37 -36
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +30 -29
- package/dist/component/schema.js.map +1 -1
- package/dist/component/shape.d.ts +12 -10
- package/dist/component/shape.d.ts.map +1 -1
- package/dist/component/shape.js +30 -18
- package/dist/component/shape.js.map +1 -1
- package/dist/component/values.d.ts +10 -8
- package/dist/component/values.d.ts.map +1 -1
- package/dist/component/values.js +15 -10
- package/dist/component/values.js.map +1 -1
- package/dist/component/webhooks.d.ts +49 -39
- package/dist/component/webhooks.d.ts.map +1 -1
- package/dist/component/webhooks.js +91 -77
- package/dist/component/webhooks.js.map +1 -1
- package/dist/test.d.ts +41 -40
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +5 -3
- package/dist/test.js.map +1 -1
- package/package.json +26 -10
- package/src/client.ts +129 -0
- package/src/component/_generated/api.ts +4 -0
- package/src/component/access.ts +3 -3
- package/src/component/crons.ts +7 -4
- package/src/component/delivery.ts +93 -42
- package/src/component/events.ts +23 -18
- package/src/component/http.ts +59 -21
- package/src/component/job.ts +131 -0
- package/src/component/jobs.ts +131 -143
- package/src/component/operation.ts +16 -5
- package/src/component/operations.ts +193 -191
- package/src/component/registry.json +14402 -46998
- package/src/component/registry.ts +184 -0
- package/src/component/request.ts +121 -170
- package/src/component/schema.ts +33 -34
- package/src/component/shape.ts +49 -25
- package/src/component/values.ts +19 -10
- package/src/component/webhooks.ts +120 -78
- package/src/test.ts +8 -5
- package/dist/client/index.d.ts +0 -85
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -50
- package/dist/client/index.js.map +0 -1
- package/src/client/index.ts +0 -97
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Twitter API & X data in Convex with Xquik
|
|
2
2
|
|
|
3
|
-
[](https://www.convex.dev/components/convex-xquik)
|
|
4
4
|
|
|
5
5
|
A Convex component for every public Xquik X API operation, signed webhooks & live event queries.
|
|
6
6
|
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { FunctionArgs, FunctionReference, FunctionReturnType, GenericActionCtx, GenericDataModel, GenericMutationCtx } from "convex/server";
|
|
2
|
+
import type { ComponentApi } from "./component/_generated/component.js";
|
|
3
|
+
import type { EventFields } from "./component/values.js";
|
|
4
|
+
import type { Infer } from "convex/values";
|
|
5
|
+
declare const eventDoc: import("convex/values").VObject<{
|
|
6
|
+
monitorId?: string;
|
|
7
|
+
data: import("convex/values").Value;
|
|
8
|
+
streamEventId: string;
|
|
9
|
+
eventType: string;
|
|
10
|
+
occurredAt: number;
|
|
11
|
+
_creationTime: number;
|
|
12
|
+
_id: string;
|
|
13
|
+
}, {
|
|
14
|
+
data: import("convex/values").VAny<import("convex/values").Value, "required", string>;
|
|
15
|
+
eventType: import("convex/values").VString<string, "required">;
|
|
16
|
+
monitorId: import("convex/values").VString<string | undefined, "optional">;
|
|
17
|
+
occurredAt: import("convex/values").VFloat64<number, "required">;
|
|
18
|
+
streamEventId: import("convex/values").VString<string, "required">;
|
|
19
|
+
_creationTime: import("convex/values").VFloat64<number, "required">;
|
|
20
|
+
_id: import("convex/values").VString<string, "required">;
|
|
21
|
+
}, "required", "data" | "_creationTime" | "_id" | "streamEventId" | "eventType" | "monitorId" | "occurredAt" | `data.${string}`>;
|
|
22
|
+
type EventDoc = Infer<typeof eventDoc>;
|
|
23
|
+
type OperationName = keyof ComponentApi["operations"];
|
|
24
|
+
type OperationArgs<Name extends OperationName> = FunctionArgs<ComponentApi["operations"][Name]>;
|
|
25
|
+
type OperationResult<Name extends OperationName> = FunctionReturnType<ComponentApi["operations"][Name]>;
|
|
26
|
+
type ActionCtx = Pick<GenericActionCtx<GenericDataModel>, "runAction">;
|
|
27
|
+
type MutationCtx = Pick<GenericMutationCtx<GenericDataModel>, "runMutation">;
|
|
28
|
+
type EventHandler = FunctionReference<"mutation", "internal" | "public", {
|
|
29
|
+
event: EventFields;
|
|
30
|
+
}>;
|
|
31
|
+
type EventTypes = FunctionArgs<ComponentApi["webhooks"]["create"]>["eventTypes"];
|
|
32
|
+
interface Schedule {
|
|
33
|
+
readonly key?: string;
|
|
34
|
+
readonly everyMs?: number;
|
|
35
|
+
readonly delayMs?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calls the Xquik component from your app's mutations and actions.
|
|
39
|
+
*
|
|
40
|
+
* @see https://docs.xquik.com/guides/convex#call-the-twitter-api-from-a-convex-action
|
|
41
|
+
*/
|
|
42
|
+
declare class Xquik {
|
|
43
|
+
readonly component: ComponentApi;
|
|
44
|
+
/**
|
|
45
|
+
* @param {ComponentApi} component The mounted component, `components.xquik` from `./_generated/api`.
|
|
46
|
+
* @see https://docs.xquik.com/guides/convex#install-the-component
|
|
47
|
+
*/
|
|
48
|
+
constructor(component: ComponentApi);
|
|
49
|
+
/**
|
|
50
|
+
* Schedules an operation as a durable job and returns its job ID.
|
|
51
|
+
*
|
|
52
|
+
* While a job with the same `key` is scheduled or running, the call returns that job's ID.
|
|
53
|
+
* Reads and writes that take an `Idempotency-Key` retry on a 429, a 5xx or a network error.
|
|
54
|
+
*
|
|
55
|
+
* @param {MutationCtx} ctx The mutation context that schedules the job.
|
|
56
|
+
* @param {Name} operation The operation name, such as `"getUser"`.
|
|
57
|
+
* @param {OperationArgs<Name>} args The operation's arguments, typed from its schema.
|
|
58
|
+
* @param {Schedule} [options] `key` keeps 1 scheduled job per key. `everyMs` repeats the job, at 60,000 ms or more.
|
|
59
|
+
* `delayMs` starts it later.
|
|
60
|
+
* @returns {Promise<string>} The job ID.
|
|
61
|
+
* @see https://docs.xquik.com/guides/convex#schedule-durable-twitter-api-jobs
|
|
62
|
+
*/
|
|
63
|
+
schedule<Name extends OperationName>(ctx: MutationCtx, operation: Name, args: OperationArgs<Name>, options?: Schedule): Promise<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Creates an Xquik webhook for the event types and an endpoint in the component that receives it.
|
|
66
|
+
*
|
|
67
|
+
* @param {ActionCtx} ctx The action context that calls Xquik.
|
|
68
|
+
* @param {{ eventTypes: Readonly<EventTypes>, onEvent?: EventHandler }} args `eventTypes` to deliver, and `onEvent`, a mutation that runs once for each `streamEventId` this endpoint receives. A retry or the `webhook.test` alert does not run it.
|
|
69
|
+
* @returns {Promise<{ endpointId: string, url: string, webhookId: string }>} The endpoint ID, its URL and the Xquik webhook ID.
|
|
70
|
+
* @see https://docs.xquik.com/guides/convex#receive-signed-twitter-webhook-events
|
|
71
|
+
*/
|
|
72
|
+
createWebhook(ctx: ActionCtx, args: {
|
|
73
|
+
readonly eventTypes: Readonly<EventTypes>;
|
|
74
|
+
readonly onEvent?: FunctionReference<"mutation", "internal" | "public", {
|
|
75
|
+
event: EventFields;
|
|
76
|
+
}>;
|
|
77
|
+
}): Promise<{
|
|
78
|
+
endpointId: string;
|
|
79
|
+
url: string;
|
|
80
|
+
webhookId: string;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Adds an endpoint for a webhook you created elsewhere, with its signing secret.
|
|
84
|
+
*
|
|
85
|
+
* @param {MutationCtx} ctx The mutation context that stores the endpoint.
|
|
86
|
+
* @param {{ secret: string, onEvent?: EventHandler }} args The webhook's `secret`, and `onEvent`, a mutation that runs once for each `streamEventId` this endpoint receives. A retry or the `webhook.test` alert does not run it.
|
|
87
|
+
* @returns {Promise<{ endpointId: string, url: string }>} The endpoint ID and the URL to give Xquik.
|
|
88
|
+
* @see https://docs.xquik.com/guides/convex#register-a-webhook-made-elsewhere
|
|
89
|
+
*/
|
|
90
|
+
addWebhook(ctx: MutationCtx, args: {
|
|
91
|
+
readonly secret: string;
|
|
92
|
+
readonly onEvent?: FunctionReference<"mutation", "internal" | "public", {
|
|
93
|
+
event: EventFields;
|
|
94
|
+
}>;
|
|
95
|
+
}): Promise<{
|
|
96
|
+
endpointId: string;
|
|
97
|
+
url: string;
|
|
98
|
+
}>;
|
|
99
|
+
}
|
|
100
|
+
export { eventDoc, Xquik };
|
|
101
|
+
export { eventFields, type EventFields } from "./component/values.js";
|
|
102
|
+
export type { EventDoc, EventHandler, EventTypes, OperationArgs, OperationName, OperationResult, Schedule };
|
|
103
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createFunctionHandle } from "convex/server";
|
|
2
|
+
import schema from "./component/schema.js";
|
|
3
|
+
import { v } from "convex/values";
|
|
4
|
+
const eventDoc = schema.tables.events.validator.extend({ _creationTime: v.number(), _id: v.string() });
|
|
5
|
+
/**
|
|
6
|
+
* Calls the Xquik component from your app's mutations and actions.
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.xquik.com/guides/convex#call-the-twitter-api-from-a-convex-action
|
|
9
|
+
*/
|
|
10
|
+
class Xquik {
|
|
11
|
+
component;
|
|
12
|
+
/**
|
|
13
|
+
* @param {ComponentApi} component The mounted component, `components.xquik` from `./_generated/api`.
|
|
14
|
+
* @see https://docs.xquik.com/guides/convex#install-the-component
|
|
15
|
+
*/
|
|
16
|
+
constructor(component) {
|
|
17
|
+
this.component = component;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Schedules an operation as a durable job and returns its job ID.
|
|
21
|
+
*
|
|
22
|
+
* While a job with the same `key` is scheduled or running, the call returns that job's ID.
|
|
23
|
+
* Reads and writes that take an `Idempotency-Key` retry on a 429, a 5xx or a network error.
|
|
24
|
+
*
|
|
25
|
+
* @param {MutationCtx} ctx The mutation context that schedules the job.
|
|
26
|
+
* @param {Name} operation The operation name, such as `"getUser"`.
|
|
27
|
+
* @param {OperationArgs<Name>} args The operation's arguments, typed from its schema.
|
|
28
|
+
* @param {Schedule} [options] `key` keeps 1 scheduled job per key. `everyMs` repeats the job, at 60,000 ms or more.
|
|
29
|
+
* `delayMs` starts it later.
|
|
30
|
+
* @returns {Promise<string>} The job ID.
|
|
31
|
+
* @see https://docs.xquik.com/guides/convex#schedule-durable-twitter-api-jobs
|
|
32
|
+
*/
|
|
33
|
+
async schedule(ctx, operation, args, options = {}) {
|
|
34
|
+
const job = { args, operation };
|
|
35
|
+
return await ctx.runMutation(this.component.jobs.enqueue, Object.assign(job, options));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates an Xquik webhook for the event types and an endpoint in the component that receives it.
|
|
39
|
+
*
|
|
40
|
+
* @param {ActionCtx} ctx The action context that calls Xquik.
|
|
41
|
+
* @param {{ eventTypes: Readonly<EventTypes>, onEvent?: EventHandler }} args `eventTypes` to deliver, and `onEvent`, a mutation that runs once for each `streamEventId` this endpoint receives. A retry or the `webhook.test` alert does not run it.
|
|
42
|
+
* @returns {Promise<{ endpointId: string, url: string, webhookId: string }>} The endpoint ID, its URL and the Xquik webhook ID.
|
|
43
|
+
* @see https://docs.xquik.com/guides/convex#receive-signed-twitter-webhook-events
|
|
44
|
+
*/
|
|
45
|
+
async createWebhook(ctx, args) {
|
|
46
|
+
const eventTypes = [...args.eventTypes];
|
|
47
|
+
if (typeof args.onEvent !== "object") {
|
|
48
|
+
return await ctx.runAction(this.component.webhooks.create, { eventTypes });
|
|
49
|
+
}
|
|
50
|
+
return await ctx.runAction(this.component.webhooks.create, {
|
|
51
|
+
eventTypes,
|
|
52
|
+
onEvent: await createFunctionHandle(args.onEvent),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Adds an endpoint for a webhook you created elsewhere, with its signing secret.
|
|
57
|
+
*
|
|
58
|
+
* @param {MutationCtx} ctx The mutation context that stores the endpoint.
|
|
59
|
+
* @param {{ secret: string, onEvent?: EventHandler }} args The webhook's `secret`, and `onEvent`, a mutation that runs once for each `streamEventId` this endpoint receives. A retry or the `webhook.test` alert does not run it.
|
|
60
|
+
* @returns {Promise<{ endpointId: string, url: string }>} The endpoint ID and the URL to give Xquik.
|
|
61
|
+
* @see https://docs.xquik.com/guides/convex#register-a-webhook-made-elsewhere
|
|
62
|
+
*/
|
|
63
|
+
async addWebhook(ctx, args) {
|
|
64
|
+
const { onEvent, secret } = args;
|
|
65
|
+
if (typeof onEvent !== "object") {
|
|
66
|
+
return await ctx.runMutation(this.component.webhooks.add, { secret });
|
|
67
|
+
}
|
|
68
|
+
return await ctx.runMutation(this.component.webhooks.add, { onEvent: await createFunctionHandle(onEvent), secret });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export { eventDoc, Xquik };
|
|
72
|
+
export { eventFields } from "./component/values.js";
|
|
73
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,MAAM,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAuBvG;;;;GAIG;AACH,MAAM,KAAK;IACO,SAAS,CAAe;IAExC;;;OAGG;IACH,YAAmB,SAAuB;QACxC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;;;OAaG;IACI,KAAK,CAAC,QAAQ,CACnB,GAAgB,EAChB,SAAe,EACf,IAAyB,EACzB,UAAoB,EAAE;QAEtB,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAChC,OAAO,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACzF,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,aAAa,CACxB,GAAc,EACd,IAGC;QAED,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE;YACzD,UAAU;YACV,OAAO,EAAE,MAAM,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,UAAU,CACrB,GAAgB,EAChB,IAGC;QAED,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACtH,CAAC;CACF;AAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAoB,MAAM,uBAAuB,CAAC"}
|
|
@@ -11,9 +11,11 @@ import type * as crons from "../crons.js";
|
|
|
11
11
|
import type * as delivery from "../delivery.js";
|
|
12
12
|
import type * as events from "../events.js";
|
|
13
13
|
import type * as http from "../http.js";
|
|
14
|
+
import type * as job from "../job.js";
|
|
14
15
|
import type * as jobs from "../jobs.js";
|
|
15
16
|
import type * as operation from "../operation.js";
|
|
16
17
|
import type * as operations from "../operations.js";
|
|
18
|
+
import type * as registry from "../registry.js";
|
|
17
19
|
import type * as request from "../request.js";
|
|
18
20
|
import type * as shape from "../shape.js";
|
|
19
21
|
import type * as values from "../values.js";
|
|
@@ -25,9 +27,11 @@ declare const fullApi: ApiFromModules<{
|
|
|
25
27
|
delivery: typeof delivery;
|
|
26
28
|
events: typeof events;
|
|
27
29
|
http: typeof http;
|
|
30
|
+
job: typeof job;
|
|
28
31
|
jobs: typeof jobs;
|
|
29
32
|
operation: typeof operation;
|
|
30
33
|
operations: typeof operations;
|
|
34
|
+
registry: typeof registry;
|
|
31
35
|
request: typeof request;
|
|
32
36
|
shape: typeof shape;
|
|
33
37
|
values: typeof values;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,QAAQ,CAAC;CAC3B,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,GAAG,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,UAAU,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,KAAK,KAAK,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,QAAA,MAAM,OAAO,EAAE,cAAc,CAAC;IAC5B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,GAAG,EAAE,OAAO,GAAG,CAAC;IAChB,IAAI,EAAE,OAAO,IAAI,CAAC;IAClB,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,MAAM,EAAE,OAAO,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,QAAQ,CAAC;CAC3B,CAAiB,CAAC;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,EAAE,SAAS,CACzB,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,CACjB,CAAC;AAElB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAC9B,OAAO,OAAO,EACd,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CACnB,CAAC;AAElB,eAAO,MAAM,UAAU,EAAqC,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/component/_generated/api.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB;;;;;;;GAOG;AAsBH,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,OAAO,GAeR,MAAa,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAGZ,MAAa,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAGjB,MAAa,CAAC;AAElB,MAAM,CAAC,MAAM,UAAU,GAAG,iBAAiB,EAAmB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export default function requireApiKey(apiKey: string | undefined): string;
|
|
2
2
|
//# sourceMappingURL=access.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/component/access.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/component/access.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CASxE"}
|
package/dist/component/access.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ConvexError } from "convex/values";
|
|
2
|
-
export function requireApiKey(apiKey) {
|
|
3
|
-
if (apiKey
|
|
2
|
+
export default function requireApiKey(apiKey) {
|
|
3
|
+
if (typeof apiKey !== "string" || apiKey === "") {
|
|
4
4
|
throw new ConvexError({
|
|
5
|
-
status: 401,
|
|
6
5
|
error: "missing_api_key",
|
|
7
6
|
message: "Set XQUIK_API_KEY in the Convex dashboard and pass it to the xquik component in convex.config.ts.",
|
|
7
|
+
status: 401,
|
|
8
8
|
});
|
|
9
9
|
}
|
|
10
10
|
return apiKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/component/access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,UAAU,aAAa,CAAC,MAA0B;
|
|
1
|
+
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/component/access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,MAA0B;IAC9D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,WAAW,CAAC;YACpB,KAAK,EAAE,iBAAiB;YACxB,OAAO,EAAE,mGAAmG;YAC5G,MAAM,EAAE,GAAG;SACZ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crons.d.ts","sourceRoot":"","sources":["../../src/component/crons.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"crons.d.ts","sourceRoot":"","sources":["../../src/component/crons.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;;AAS3C,wBAA0B"}
|
package/dist/component/crons.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { cronJobs } from "convex/server";
|
|
2
2
|
import { internal } from "./_generated/api.js";
|
|
3
|
-
|
|
4
|
-
crons
|
|
5
|
-
|
|
3
|
+
function schedule() {
|
|
4
|
+
const crons = cronJobs();
|
|
5
|
+
crons.interval("purge expired webhook nonces", { minutes: 10 }, internal.webhooks.purge, {});
|
|
6
|
+
return crons;
|
|
7
|
+
}
|
|
8
|
+
export default schedule();
|
|
6
9
|
//# sourceMappingURL=crons.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crons.js","sourceRoot":"","sources":["../../src/component/crons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"crons.js","sourceRoot":"","sources":["../../src/component/crons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,SAAS,QAAQ;IACf,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,KAAK,CAAC,QAAQ,CAAC,8BAA8B,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7F,OAAO,KAAK,CAAC;AACf,CAAC;AAED,eAAe,QAAQ,EAAE,CAAC"}
|
|
@@ -1,25 +1,60 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export type Check = {
|
|
1
|
+
import type { EventFields } from "./values.js";
|
|
2
|
+
import type { Infer } from "convex/values";
|
|
3
|
+
declare const NONCE_TTL_MS: number;
|
|
4
|
+
type Check = {
|
|
6
5
|
readonly ok: true;
|
|
7
6
|
readonly nonce: string;
|
|
8
7
|
} | {
|
|
9
8
|
readonly ok: false;
|
|
10
9
|
readonly reason: string;
|
|
11
10
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
readonly id: string;
|
|
15
|
-
readonly type: string;
|
|
16
|
-
}): EventFields | null;
|
|
17
|
-
export type Delivery = {
|
|
18
|
-
readonly kind: "test";
|
|
11
|
+
declare const deliveryValidator: import("convex/values").VUnion<{
|
|
12
|
+
kind: "test";
|
|
19
13
|
} | {
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
event: {
|
|
15
|
+
monitorId?: string;
|
|
16
|
+
data: import("convex/values").Value;
|
|
17
|
+
streamEventId: string;
|
|
18
|
+
eventType: string;
|
|
19
|
+
occurredAt: number;
|
|
20
|
+
};
|
|
21
|
+
kind: "event";
|
|
22
|
+
}, [import("convex/values").VObject<{
|
|
23
|
+
kind: "test";
|
|
24
|
+
}, {
|
|
25
|
+
kind: import("convex/values").VLiteral<"test", "required">;
|
|
26
|
+
}, "required", "kind">, import("convex/values").VObject<{
|
|
27
|
+
event: {
|
|
28
|
+
monitorId?: string;
|
|
29
|
+
data: import("convex/values").Value;
|
|
30
|
+
streamEventId: string;
|
|
31
|
+
eventType: string;
|
|
32
|
+
occurredAt: number;
|
|
33
|
+
};
|
|
34
|
+
kind: "event";
|
|
35
|
+
}, {
|
|
36
|
+
event: import("convex/values").VObject<{
|
|
37
|
+
monitorId?: string;
|
|
38
|
+
data: import("convex/values").Value;
|
|
39
|
+
streamEventId: string;
|
|
40
|
+
eventType: string;
|
|
41
|
+
occurredAt: number;
|
|
42
|
+
}, {
|
|
43
|
+
data: import("convex/values").VAny<import("convex/values").Value, "required", string>;
|
|
44
|
+
eventType: import("convex/values").VString<string, "required">;
|
|
45
|
+
monitorId: import("convex/values").VString<string | undefined, "optional">;
|
|
46
|
+
occurredAt: import("convex/values").VFloat64<number, "required">;
|
|
47
|
+
streamEventId: import("convex/values").VString<string, "required">;
|
|
48
|
+
}, "required", "data" | "streamEventId" | "eventType" | "monitorId" | "occurredAt" | `data.${string}`>;
|
|
49
|
+
kind: import("convex/values").VLiteral<"event", "required">;
|
|
50
|
+
}, "required", "event" | "kind" | "event.data" | "event.streamEventId" | "event.eventType" | "event.monitorId" | "event.occurredAt" | `event.data.${string}`>], "required", "event" | "kind" | "event.data" | "event.streamEventId" | "event.eventType" | "event.monitorId" | "event.occurredAt" | `event.data.${string}`>;
|
|
51
|
+
type Delivery = Infer<typeof deliveryValidator>;
|
|
52
|
+
type Reading = Delivery | {
|
|
53
|
+
readonly kind: "invalid";
|
|
22
54
|
};
|
|
23
|
-
|
|
24
|
-
|
|
55
|
+
declare function check(secret: string, headers: Readonly<Headers>, body: Readonly<ArrayBuffer>, now: number): Promise<Check>;
|
|
56
|
+
declare function readDelivery(raw: string): Reading;
|
|
57
|
+
declare function pulledEvents(result: unknown): EventFields[];
|
|
58
|
+
export { check, deliveryValidator, NONCE_TTL_MS, pulledEvents, readDelivery };
|
|
59
|
+
export type { Check, Delivery, Reading };
|
|
25
60
|
//# sourceMappingURL=delivery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/component/delivery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/component/delivery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAM3C,QAAA,MAAM,YAAY,QAAmC,CAAC;AAQtD,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7G,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0TAGtB,CAAC;AAEF,KAAK,QAAQ,GAAG,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEhD,KAAK,OAAO,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAoBvD,iBAAe,KAAK,CAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,EAC1B,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC3B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,KAAK,CAAC,CAchB;AA+BD,iBAAS,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAU1C;AAED,iBAAS,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,EAAE,CAKpD;AAED,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAC9E,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -1,56 +1,86 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { eventFields, toValue } from "./values.js";
|
|
2
2
|
import { isList, isRecord } from "./shape.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { parseOrText } from "./request.js";
|
|
4
|
+
import { v } from "convex/values";
|
|
5
|
+
const TOLERANCE_MS = 300_000;
|
|
6
|
+
const WINDOWS_PER_NONCE = 2;
|
|
7
|
+
const NONCE_TTL_MS = WINDOWS_PER_NONCE * TOLERANCE_MS;
|
|
8
|
+
const HEX_PER_BYTE = 2;
|
|
9
|
+
const TIMESTAMP = /^\d{1,16}$/u;
|
|
10
|
+
const NONCE = /^[0-9a-f]{32}$/u;
|
|
11
|
+
const SIGNATURE = /^sha256=(?<mac>[0-9a-f]{64})$/u;
|
|
6
12
|
const encoder = new TextEncoder();
|
|
13
|
+
const deliveryValidator = v.union(v.object({ kind: v.literal("test") }), v.object({ event: eventFields, kind: v.literal("event") }));
|
|
7
14
|
function bytes(hex) {
|
|
8
|
-
return Uint8Array.from({ length: hex.length /
|
|
15
|
+
return Uint8Array.from({ length: hex.length / HEX_PER_BYTE }, (_item, index) => {
|
|
16
|
+
const start = index * HEX_PER_BYTE;
|
|
17
|
+
return Number.parseInt(hex.slice(start, start + HEX_PER_BYTE), 16);
|
|
18
|
+
});
|
|
9
19
|
}
|
|
10
|
-
|
|
20
|
+
async function verify(secret, signed, mac, body) {
|
|
21
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { hash: "SHA-256", name: "HMAC" }, false, [
|
|
22
|
+
"verify",
|
|
23
|
+
]);
|
|
24
|
+
const prefix = encoder.encode(signed);
|
|
25
|
+
const message = new Uint8Array(prefix.length + body.byteLength);
|
|
26
|
+
message.set(prefix);
|
|
27
|
+
message.set(new Uint8Array(body), prefix.length);
|
|
28
|
+
return await crypto.subtle.verify("HMAC", key, bytes(mac), message);
|
|
29
|
+
}
|
|
30
|
+
async function check(secret, headers, body, now) {
|
|
11
31
|
const timestamp = String(headers.get("x-xquik-timestamp"));
|
|
12
32
|
const nonce = String(headers.get("x-xquik-nonce"));
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
33
|
+
const signature = SIGNATURE.exec(String(headers.get("x-xquik-signature")));
|
|
34
|
+
if (!TIMESTAMP.test(timestamp) || Math.abs(now - Number(timestamp)) > TOLERANCE_MS) {
|
|
15
35
|
return { ok: false, reason: "stale timestamp" };
|
|
16
36
|
}
|
|
17
|
-
if (
|
|
37
|
+
if (!NONCE.test(nonce) || signature === null) {
|
|
18
38
|
return { ok: false, reason: "bad signature" };
|
|
19
39
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
if (await verify(secret, `${timestamp}.${nonce}.`, String(signature[1]), body)) {
|
|
41
|
+
return { nonce, ok: true };
|
|
42
|
+
}
|
|
43
|
+
return { ok: false, reason: "bad signature" };
|
|
44
|
+
}
|
|
45
|
+
function timeOf(value) {
|
|
46
|
+
if (typeof value === "string") {
|
|
47
|
+
return Date.parse(value);
|
|
48
|
+
}
|
|
49
|
+
return Number.NaN;
|
|
50
|
+
}
|
|
51
|
+
function monitorOf(monitorId) {
|
|
52
|
+
if (typeof monitorId === "string") {
|
|
53
|
+
return { monitorId };
|
|
54
|
+
}
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
function readEvent(item, names) {
|
|
58
|
+
if (!isRecord(item)) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const { [names.id]: streamEventId, [names.type]: eventType, data, monitorId, occurredAt } = item;
|
|
62
|
+
const time = timeOf(occurredAt);
|
|
63
|
+
if (typeof streamEventId !== "string" || typeof eventType !== "string" || Number.isNaN(time)) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
return [Object.assign(monitorOf(monitorId), { data: toValue(data), eventType, occurredAt: time, streamEventId })];
|
|
67
|
+
}
|
|
68
|
+
function readDelivery(raw) {
|
|
46
69
|
const body = parseOrText(raw);
|
|
47
|
-
if (isRecord(body) && body["eventType"] === "webhook.test")
|
|
70
|
+
if (isRecord(body) && body["eventType"] === "webhook.test") {
|
|
48
71
|
return { kind: "test" };
|
|
49
|
-
|
|
50
|
-
|
|
72
|
+
}
|
|
73
|
+
const [event] = readEvent(body, { id: "streamEventId", type: "eventType" });
|
|
74
|
+
if (!event) {
|
|
75
|
+
return { kind: "invalid" };
|
|
76
|
+
}
|
|
77
|
+
return { event, kind: "event" };
|
|
51
78
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
79
|
+
function pulledEvents(result) {
|
|
80
|
+
if (!isRecord(result) || !isList(result["events"])) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
return result["events"].flatMap((item) => readEvent(item, { id: "id", type: "type" }));
|
|
55
84
|
}
|
|
85
|
+
export { check, deliveryValidator, NONCE_TTL_MS, pulledEvents, readDelivery };
|
|
56
86
|
//# sourceMappingURL=delivery.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/component/delivery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/component/delivery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,YAAY,GAAG,OAAO,CAAC;AAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,YAAY,GAAG,iBAAiB,GAAG,YAAY,CAAC;AACtD,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,SAAS,GAAG,aAAa,CAAC;AAChC,MAAM,KAAK,GAAG,iBAAiB,CAAC;AAChC,MAAM,SAAS,GAAG,gCAAgC,CAAC;AAEnD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAIlC,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAC/B,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EACrC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAC3D,CAAC;AAMF,SAAS,KAAK,CAAC,GAAW;IACxB,OAAO,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,YAAY,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7E,MAAM,KAAK,GAAG,KAAK,GAAG,YAAY,CAAC;QACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,MAAc,EAAE,MAAc,EAAE,GAAW,EAAE,IAA2B;IAC5F,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE;QACjH,QAAQ;KACT,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,KAAK,CAClB,MAAc,EACd,OAA0B,EAC1B,IAA2B,EAC3B,GAAW;IAEX,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,EAAE,CAAC;QACnF,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChD,CAAC;IACD,IAAI,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,SAAS,IAAI,KAAK,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,SAAkB;IACnC,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,SAAS,EAAE,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,SAAS,CAChB,IAAa,EACb,KAAqD;IAErD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACjG,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7F,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;AACpH,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,cAAc,EAAE,CAAC;QAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,YAAY,CAAC,MAAe;IACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
monitorId?: string;
|
|
3
|
-
data: import("convex/values").Value;
|
|
4
|
-
streamEventId: string;
|
|
5
|
-
eventType: string;
|
|
6
|
-
occurredAt: number;
|
|
7
|
-
_creationTime: number;
|
|
8
|
-
_id: import("convex/values").GenericId<"events">;
|
|
9
|
-
}, {
|
|
10
|
-
streamEventId: import("convex/values").VString<string, "required">;
|
|
11
|
-
eventType: import("convex/values").VString<string, "required">;
|
|
12
|
-
occurredAt: import("convex/values").VFloat64<number, "required">;
|
|
13
|
-
monitorId: import("convex/values").VString<string | undefined, "optional">;
|
|
14
|
-
data: import("convex/values").VAny<import("convex/values").Value, "required", string>;
|
|
15
|
-
_id: import("convex/values").VId<import("convex/values").GenericId<"events">, "required">;
|
|
16
|
-
_creationTime: import("convex/values").VFloat64<number, "required">;
|
|
17
|
-
}, "required", "data" | "_creationTime" | "_id" | "streamEventId" | "eventType" | "monitorId" | "occurredAt" | `data.${string}`>;
|
|
18
|
-
export declare const list: import("convex/server").RegisteredQuery<"public", {
|
|
1
|
+
declare const list: import("convex/server").RegisteredQuery<"public", {
|
|
19
2
|
filter?: {
|
|
20
3
|
eventType: string;
|
|
21
4
|
} | {
|
|
@@ -38,7 +21,7 @@ export declare const list: import("convex/server").RegisteredQuery<"public", {
|
|
|
38
21
|
eventType: string;
|
|
39
22
|
occurredAt: number;
|
|
40
23
|
}>>>;
|
|
41
|
-
|
|
24
|
+
declare const get: import("convex/server").RegisteredQuery<"public", {
|
|
42
25
|
streamEventId: string;
|
|
43
26
|
}, Promise<{
|
|
44
27
|
_id: import("convex/values").GenericId<"events">;
|
|
@@ -49,4 +32,5 @@ export declare const get: import("convex/server").RegisteredQuery<"public", {
|
|
|
49
32
|
eventType: string;
|
|
50
33
|
occurredAt: number;
|
|
51
34
|
} | null>>;
|
|
35
|
+
export { get, list };
|
|
52
36
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/component/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/component/events.ts"],"names":[],"mappings":"AAaA,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;IAkBR,CAAC;AAEH,QAAA,MAAM,GAAG;;;;;;;;;;UAUP,CAAC;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC"}
|