zitejs 0.9.126 → 0.9.127
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.
|
@@ -21,14 +21,55 @@ export type ZiteTrigger = {
|
|
|
21
21
|
/** The sentence the editor shows for what fires this endpoint, e.g. "When a task is completed in Asana". */
|
|
22
22
|
label?: string;
|
|
23
23
|
paused?: boolean;
|
|
24
|
+
every?: never;
|
|
24
25
|
} | {
|
|
25
|
-
|
|
26
|
-
/** `<n>m` (1–59) or `<n>h` (1–23) */
|
|
26
|
+
/** `<n>m` (1–59) or `<n>h` (1–23). What makes the trigger a poll. */
|
|
27
27
|
every: string;
|
|
28
|
+
/** The connection the poll checks, if any, so the editor can name it. */
|
|
29
|
+
integration?: string;
|
|
28
30
|
/** The sentence the editor shows for this poll, e.g. "Every 10 minutes, new Stripe charges". */
|
|
29
31
|
label?: string;
|
|
30
32
|
paused?: boolean;
|
|
31
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* What a provider trigger's `subscribe` export receives. Write it as
|
|
36
|
+
* `export const subscribe = (async input => { ... }) satisfies ZiteTriggerSubscribe`
|
|
37
|
+
* so the input is typed and a wrong return shape is a typecheck error.
|
|
38
|
+
*/
|
|
39
|
+
export type ZiteTriggerSubscribeInput = {
|
|
40
|
+
/** Where the provider must deliver, token included. */
|
|
41
|
+
notificationUrl: string;
|
|
42
|
+
/** The connection's name, as the trigger names it. */
|
|
43
|
+
integration: string;
|
|
44
|
+
endpointId: string;
|
|
45
|
+
/** A fresh 64-char hex secret, for providers that let the caller choose the signing secret. */
|
|
46
|
+
secret: string;
|
|
47
|
+
/** Set on a re-subscribe, including a renewal. */
|
|
48
|
+
previous: {
|
|
49
|
+
externalId: string;
|
|
50
|
+
state: Record<string, unknown>;
|
|
51
|
+
} | null;
|
|
52
|
+
};
|
|
53
|
+
export type ZiteTriggerSubscribeResult = {
|
|
54
|
+
/** The provider's id for the registration; what `unsubscribe` receives. */
|
|
55
|
+
externalId: string;
|
|
56
|
+
/** The signing secret, if the provider issued one or accepted `input.secret`. */
|
|
57
|
+
secret?: string;
|
|
58
|
+
/** Anything `unsubscribe` needs later; handed back to it and to the next `subscribe`. */
|
|
59
|
+
state?: Record<string, unknown>;
|
|
60
|
+
/** The provider's starting change marker, for notifications that only say something changed. */
|
|
61
|
+
cursor?: string;
|
|
62
|
+
/** ISO time the provider says the registration lapses, read from its response. */
|
|
63
|
+
expiresAt?: string;
|
|
64
|
+
};
|
|
65
|
+
export type ZiteTriggerUnsubscribeInput = {
|
|
66
|
+
externalId: string;
|
|
67
|
+
state: Record<string, unknown>;
|
|
68
|
+
integration: string;
|
|
69
|
+
endpointId: string;
|
|
70
|
+
};
|
|
71
|
+
export type ZiteTriggerSubscribe = (input: ZiteTriggerSubscribeInput) => Promise<ZiteTriggerSubscribeResult> | ZiteTriggerSubscribeResult;
|
|
72
|
+
export type ZiteTriggerUnsubscribe = (input: ZiteTriggerUnsubscribeInput) => Promise<void> | void;
|
|
32
73
|
/**
|
|
33
74
|
* What a poll-triggered run receives as `input.__poll`. Only on a fire from
|
|
34
75
|
* the poll's schedule; a request call to the same endpoint carries none.
|
|
@@ -159,7 +200,7 @@ export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream ext
|
|
|
159
200
|
validatesInput?: boolean;
|
|
160
201
|
execute: (params: {
|
|
161
202
|
input: TTrigger extends {
|
|
162
|
-
|
|
203
|
+
every: string;
|
|
163
204
|
} ? TInput & {
|
|
164
205
|
__poll?: ZitePollInput;
|
|
165
206
|
} : TTrigger extends {
|
|
@@ -136,7 +136,7 @@ const requestContext = { user: { id: "u1", email: "a@b.c" } };
|
|
|
136
136
|
(0, vitest_1.it)("hands a poll its cursor and seen ids, typed", async () => {
|
|
137
137
|
const endpoint = (0, index_js_1.createEndpoint)({
|
|
138
138
|
inputSchema: zod_1.z.object({}),
|
|
139
|
-
trigger: {
|
|
139
|
+
trigger: { every: "5m", integration: "stripe" },
|
|
140
140
|
execute: async ({ input }) => {
|
|
141
141
|
const seen = new Set(input.__poll?.seen);
|
|
142
142
|
const items = ["a", "b"].filter((id) => !seen.has(id));
|
|
@@ -158,6 +158,32 @@ const requestContext = { user: { id: "u1", email: "a@b.c" } };
|
|
|
158
158
|
},
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
|
+
(0, vitest_1.it)("types a trigger's registration exports and checks what subscribe returns", async () => {
|
|
162
|
+
const subscribe = (async (input) => ({
|
|
163
|
+
externalId: `hook-for-${input.endpointId}`,
|
|
164
|
+
secret: input.secret,
|
|
165
|
+
state: { repo: "acme/api" },
|
|
166
|
+
}));
|
|
167
|
+
const unsubscribe = (async (input) => {
|
|
168
|
+
(0, vitest_1.expect)(input.state.repo).toBe("acme/api");
|
|
169
|
+
});
|
|
170
|
+
// @ts-expect-error subscribe has to return the provider's id
|
|
171
|
+
void (async () => ({ secret: "s" }));
|
|
172
|
+
const registered = await subscribe({
|
|
173
|
+
notificationUrl: "https://x",
|
|
174
|
+
integration: "github",
|
|
175
|
+
endpointId: "onPush",
|
|
176
|
+
secret: "abc",
|
|
177
|
+
previous: null,
|
|
178
|
+
});
|
|
179
|
+
(0, vitest_1.expect)(registered.externalId).toBe("hook-for-onPush");
|
|
180
|
+
await unsubscribe({
|
|
181
|
+
externalId: registered.externalId,
|
|
182
|
+
state: registered.state ?? {},
|
|
183
|
+
integration: "github",
|
|
184
|
+
endpointId: "onPush",
|
|
185
|
+
});
|
|
186
|
+
});
|
|
161
187
|
(0, vitest_1.it)("hands a provider trigger's delivery its cursor and seen ids, typed", async () => {
|
|
162
188
|
const endpoint = (0, index_js_1.createEndpoint)({
|
|
163
189
|
inputSchema: zod_1.z.object({}),
|
package/dist/cjs/bundle/index.js
CHANGED
|
@@ -592,6 +592,10 @@ ${bodySection}
|
|
|
592
592
|
},
|
|
593
593
|
minify: false,
|
|
594
594
|
logLevel: 'silent',
|
|
595
|
+
// A script that imports an endpoint file's named exports (a trigger's
|
|
596
|
+
// subscribe/unsubscribe) must not carry the endpoint along with them:
|
|
597
|
+
// unused, its `createEndpoint(...)` and everything `execute` imports go.
|
|
598
|
+
pure: ['createEndpoint'],
|
|
595
599
|
plugins: [plugin],
|
|
596
600
|
});
|
|
597
601
|
if (result.errors.length > 0) {
|
|
@@ -21,14 +21,55 @@ export type ZiteTrigger = {
|
|
|
21
21
|
/** The sentence the editor shows for what fires this endpoint, e.g. "When a task is completed in Asana". */
|
|
22
22
|
label?: string;
|
|
23
23
|
paused?: boolean;
|
|
24
|
+
every?: never;
|
|
24
25
|
} | {
|
|
25
|
-
|
|
26
|
-
/** `<n>m` (1–59) or `<n>h` (1–23) */
|
|
26
|
+
/** `<n>m` (1–59) or `<n>h` (1–23). What makes the trigger a poll. */
|
|
27
27
|
every: string;
|
|
28
|
+
/** The connection the poll checks, if any, so the editor can name it. */
|
|
29
|
+
integration?: string;
|
|
28
30
|
/** The sentence the editor shows for this poll, e.g. "Every 10 minutes, new Stripe charges". */
|
|
29
31
|
label?: string;
|
|
30
32
|
paused?: boolean;
|
|
31
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* What a provider trigger's `subscribe` export receives. Write it as
|
|
36
|
+
* `export const subscribe = (async input => { ... }) satisfies ZiteTriggerSubscribe`
|
|
37
|
+
* so the input is typed and a wrong return shape is a typecheck error.
|
|
38
|
+
*/
|
|
39
|
+
export type ZiteTriggerSubscribeInput = {
|
|
40
|
+
/** Where the provider must deliver, token included. */
|
|
41
|
+
notificationUrl: string;
|
|
42
|
+
/** The connection's name, as the trigger names it. */
|
|
43
|
+
integration: string;
|
|
44
|
+
endpointId: string;
|
|
45
|
+
/** A fresh 64-char hex secret, for providers that let the caller choose the signing secret. */
|
|
46
|
+
secret: string;
|
|
47
|
+
/** Set on a re-subscribe, including a renewal. */
|
|
48
|
+
previous: {
|
|
49
|
+
externalId: string;
|
|
50
|
+
state: Record<string, unknown>;
|
|
51
|
+
} | null;
|
|
52
|
+
};
|
|
53
|
+
export type ZiteTriggerSubscribeResult = {
|
|
54
|
+
/** The provider's id for the registration; what `unsubscribe` receives. */
|
|
55
|
+
externalId: string;
|
|
56
|
+
/** The signing secret, if the provider issued one or accepted `input.secret`. */
|
|
57
|
+
secret?: string;
|
|
58
|
+
/** Anything `unsubscribe` needs later; handed back to it and to the next `subscribe`. */
|
|
59
|
+
state?: Record<string, unknown>;
|
|
60
|
+
/** The provider's starting change marker, for notifications that only say something changed. */
|
|
61
|
+
cursor?: string;
|
|
62
|
+
/** ISO time the provider says the registration lapses, read from its response. */
|
|
63
|
+
expiresAt?: string;
|
|
64
|
+
};
|
|
65
|
+
export type ZiteTriggerUnsubscribeInput = {
|
|
66
|
+
externalId: string;
|
|
67
|
+
state: Record<string, unknown>;
|
|
68
|
+
integration: string;
|
|
69
|
+
endpointId: string;
|
|
70
|
+
};
|
|
71
|
+
export type ZiteTriggerSubscribe = (input: ZiteTriggerSubscribeInput) => Promise<ZiteTriggerSubscribeResult> | ZiteTriggerSubscribeResult;
|
|
72
|
+
export type ZiteTriggerUnsubscribe = (input: ZiteTriggerUnsubscribeInput) => Promise<void> | void;
|
|
32
73
|
/**
|
|
33
74
|
* What a poll-triggered run receives as `input.__poll`. Only on a fire from
|
|
34
75
|
* the poll's schedule; a request call to the same endpoint carries none.
|
|
@@ -159,7 +200,7 @@ export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream ext
|
|
|
159
200
|
validatesInput?: boolean;
|
|
160
201
|
execute: (params: {
|
|
161
202
|
input: TTrigger extends {
|
|
162
|
-
|
|
203
|
+
every: string;
|
|
163
204
|
} ? TInput & {
|
|
164
205
|
__poll?: ZitePollInput;
|
|
165
206
|
} : TTrigger extends {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, afterEach, vi } from "vitest";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { createEndpoint, ZiteError } from "./index.js";
|
|
3
|
+
import { createEndpoint, ZiteError, } from "./index.js";
|
|
4
4
|
import { createTableClient } from "../runtime/index.js";
|
|
5
5
|
const requestContext = { user: { id: "u1", email: "a@b.c" } };
|
|
6
6
|
afterEach(() => {
|
|
@@ -134,7 +134,7 @@ describe("platform-triggered runs", () => {
|
|
|
134
134
|
it("hands a poll its cursor and seen ids, typed", async () => {
|
|
135
135
|
const endpoint = createEndpoint({
|
|
136
136
|
inputSchema: z.object({}),
|
|
137
|
-
trigger: {
|
|
137
|
+
trigger: { every: "5m", integration: "stripe" },
|
|
138
138
|
execute: async ({ input }) => {
|
|
139
139
|
const seen = new Set(input.__poll?.seen);
|
|
140
140
|
const items = ["a", "b"].filter((id) => !seen.has(id));
|
|
@@ -156,6 +156,32 @@ describe("platform-triggered runs", () => {
|
|
|
156
156
|
},
|
|
157
157
|
});
|
|
158
158
|
});
|
|
159
|
+
it("types a trigger's registration exports and checks what subscribe returns", async () => {
|
|
160
|
+
const subscribe = (async (input) => ({
|
|
161
|
+
externalId: `hook-for-${input.endpointId}`,
|
|
162
|
+
secret: input.secret,
|
|
163
|
+
state: { repo: "acme/api" },
|
|
164
|
+
}));
|
|
165
|
+
const unsubscribe = (async (input) => {
|
|
166
|
+
expect(input.state.repo).toBe("acme/api");
|
|
167
|
+
});
|
|
168
|
+
// @ts-expect-error subscribe has to return the provider's id
|
|
169
|
+
void (async () => ({ secret: "s" }));
|
|
170
|
+
const registered = await subscribe({
|
|
171
|
+
notificationUrl: "https://x",
|
|
172
|
+
integration: "github",
|
|
173
|
+
endpointId: "onPush",
|
|
174
|
+
secret: "abc",
|
|
175
|
+
previous: null,
|
|
176
|
+
});
|
|
177
|
+
expect(registered.externalId).toBe("hook-for-onPush");
|
|
178
|
+
await unsubscribe({
|
|
179
|
+
externalId: registered.externalId,
|
|
180
|
+
state: registered.state ?? {},
|
|
181
|
+
integration: "github",
|
|
182
|
+
endpointId: "onPush",
|
|
183
|
+
});
|
|
184
|
+
});
|
|
159
185
|
it("hands a provider trigger's delivery its cursor and seen ids, typed", async () => {
|
|
160
186
|
const endpoint = createEndpoint({
|
|
161
187
|
inputSchema: z.object({}),
|
package/dist/esm/bundle/index.js
CHANGED
|
@@ -554,6 +554,10 @@ ${bodySection}
|
|
|
554
554
|
},
|
|
555
555
|
minify: false,
|
|
556
556
|
logLevel: 'silent',
|
|
557
|
+
// A script that imports an endpoint file's named exports (a trigger's
|
|
558
|
+
// subscribe/unsubscribe) must not carry the endpoint along with them:
|
|
559
|
+
// unused, its `createEndpoint(...)` and everything `execute` imports go.
|
|
560
|
+
pure: ['createEndpoint'],
|
|
557
561
|
plugins: [plugin],
|
|
558
562
|
});
|
|
559
563
|
if (result.errors.length > 0) {
|