@beezping/adapter-prisma 0.7.0 → 0.8.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 +11 -11
- package/dist/beezping-core.d.cts +20 -0
- package/dist/beezping-core.d.ts +20 -0
- package/dist/concurrency.d.cts +14 -0
- package/dist/concurrency.d.ts +14 -0
- package/dist/constants/schema.d.cts +239 -0
- package/dist/constants/schema.d.ts +239 -0
- package/dist/deep-link.d.cts +14 -0
- package/dist/deep-link.d.ts +14 -0
- package/dist/email.d.cts +8 -5
- package/dist/email.d.ts +8 -5
- package/dist/errors.d.cts +28 -14
- package/dist/errors.d.ts +28 -14
- package/dist/filters.d.cts +15 -7
- package/dist/filters.d.ts +15 -7
- package/dist/i18n.d.cts +18 -0
- package/dist/i18n.d.ts +18 -0
- package/dist/index.cjs +178 -868
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -213
- package/dist/index.d.ts +95 -213
- package/dist/index.js +175 -855
- package/dist/index.js.map +1 -1
- package/dist/schema.d.cts +12 -195
- package/dist/schema.d.ts +12 -195
- package/dist/screenshot-storage.d.cts +55 -30
- package/dist/screenshot-storage.d.ts +55 -30
- package/dist/store-helpers.d.cts +62 -34
- package/dist/store-helpers.d.ts +62 -34
- package/dist/type-utils.d.cts +8 -0
- package/dist/type-utils.d.ts +8 -0
- package/dist/types.d.cts +413 -154
- package/dist/types.d.ts +413 -154
- package/dist/wire.d.cts +42 -9
- package/dist/wire.d.ts +42 -9
- package/package.json +14 -10
- package/dist/siteping-core.d.cts +0 -17
- package/dist/siteping-core.d.ts +0 -17
package/dist/index.d.cts
CHANGED
|
@@ -1,189 +1,7 @@
|
|
|
1
|
-
import { FeedbackPayload,
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
/** HTTP methods served by `createSitepingHandler`. */
|
|
6
|
-
type SitepingHttpMethod = "GET" | "POST" | "PATCH" | "DELETE" | "OPTIONS";
|
|
7
|
-
|
|
8
|
-
/** Options of the built-in shared-secret policy (the historical `adapter-prisma` behavior). */
|
|
9
|
-
interface ApiKeyAccessOptions {
|
|
10
|
-
/**
|
|
11
|
-
* Shared secret expected as `Authorization: Bearer {apiKey}`.
|
|
12
|
-
*
|
|
13
|
-
* - **When set:** every request not listed in `publicEndpoints` must carry it (401 otherwise).
|
|
14
|
-
* - **When not set:** the API is public, except DELETE/PATCH while
|
|
15
|
-
* `requireAuthForDestructive` is on.
|
|
16
|
-
*/
|
|
17
|
-
apiKey?: string | undefined;
|
|
18
|
-
/** Methods that skip the key. Defaults to `['POST', 'OPTIONS']` when `apiKey` is set. */
|
|
19
|
-
publicEndpoints?: ReadonlyArray<SitepingHttpMethod>;
|
|
20
|
-
/**
|
|
21
|
-
* Whether DELETE/PATCH require `apiKey`. Defaults to `true`: without `apiKey`
|
|
22
|
-
* the handler refuses to start in production and answers 401 elsewhere.
|
|
23
|
-
* Set `false` only behind your own auth layer — or pass `access` instead.
|
|
24
|
-
*/
|
|
25
|
-
requireAuthForDestructive?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Blank `authorEmail` in responses to requests without a valid key.
|
|
28
|
-
* Defaults to `true` — reviewer emails are PII and GET must stay reachable
|
|
29
|
-
* by the widget.
|
|
30
|
-
*/
|
|
31
|
-
redactUnauthenticatedEmails?: boolean;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Outgoing webhook notifications for newly-created feedbacks.
|
|
36
|
-
*
|
|
37
|
-
* Plug a Slack, Discord, or generic HTTP endpoint into `createSitepingHandler`
|
|
38
|
-
* to receive a payload whenever a feedback is successfully persisted. Webhooks
|
|
39
|
-
* are dispatched as fire-and-forget (`void Promise.all(...)`) so a slow or
|
|
40
|
-
* down receiver never blocks the client response — the feedback is already in
|
|
41
|
-
* the DB by the time we dial out.
|
|
42
|
-
*
|
|
43
|
-
* - **Type-specific formatting**: Slack uses `{ text, blocks }`, Discord uses
|
|
44
|
-
* `{ content, embeds }`, generic posts the record as JSON (minus `clientId`).
|
|
45
|
-
* - **Untrusted input**: `message` and `authorName` come from anonymous
|
|
46
|
-
* visitors. Slack text is escaped and Discord mention parsing is disabled,
|
|
47
|
-
* so a public feedback form can never be turned into a channel-wide ping.
|
|
48
|
-
* - **Timeout**: 5s by default (overridable per webhook).
|
|
49
|
-
* - **Error handling**: `config.onError(err, feedback.id)` is invoked when
|
|
50
|
-
* present; otherwise we log a one-liner to `console.warn` so the issue is
|
|
51
|
-
* surfaced without crashing the request.
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
/** Supported webhook integrations — drives the JSON body shape. */
|
|
55
|
-
type WebhookType = "slack" | "discord" | "generic";
|
|
56
|
-
/**
|
|
57
|
-
* Outgoing webhook configuration.
|
|
58
|
-
*
|
|
59
|
-
* - `url` — required, the HTTPS endpoint to POST to.
|
|
60
|
-
* - `type` — payload format. Defaults to `"generic"` (raw JSON).
|
|
61
|
-
* - `headers` — extra headers merged on top of `Content-Type: application/json`.
|
|
62
|
-
* Useful for signed-payload schemes (`X-Signature`, bearer tokens, …).
|
|
63
|
-
* - `timeoutMs` — abort the fetch after this many ms. Defaults to 5000.
|
|
64
|
-
* - `onError` — invoked with the underlying error and the feedback id when
|
|
65
|
-
* the dispatch fails (network error, non-2xx, timeout). The webhook is
|
|
66
|
-
* fire-and-forget, so this is your only chance to observe failures.
|
|
67
|
-
*/
|
|
68
|
-
interface WebhookConfig {
|
|
69
|
-
url: string;
|
|
70
|
-
type?: WebhookType;
|
|
71
|
-
headers?: Record<string, string>;
|
|
72
|
-
timeoutMs?: number;
|
|
73
|
-
onError?: (err: Error, feedbackId: string) => void;
|
|
74
|
-
}
|
|
75
|
-
/** Block Kit envelope used by Slack incoming webhooks. */
|
|
76
|
-
interface SlackWebhookPayload {
|
|
77
|
-
text: string;
|
|
78
|
-
blocks: ReadonlyArray<SlackHeaderBlock | SlackSectionBlock | SlackContextBlock>;
|
|
79
|
-
}
|
|
80
|
-
interface SlackHeaderBlock {
|
|
81
|
-
type: "header";
|
|
82
|
-
text: {
|
|
83
|
-
type: "plain_text";
|
|
84
|
-
text: string;
|
|
85
|
-
emoji: true;
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
interface SlackSectionBlock {
|
|
89
|
-
type: "section";
|
|
90
|
-
text: {
|
|
91
|
-
type: "mrkdwn";
|
|
92
|
-
text: string;
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
interface SlackContextBlock {
|
|
96
|
-
type: "context";
|
|
97
|
-
elements: ReadonlyArray<{
|
|
98
|
-
type: "mrkdwn";
|
|
99
|
-
text: string;
|
|
100
|
-
}>;
|
|
101
|
-
}
|
|
102
|
-
/** Embed envelope used by Discord incoming webhooks. */
|
|
103
|
-
interface DiscordWebhookPayload {
|
|
104
|
-
content: string;
|
|
105
|
-
embeds: ReadonlyArray<{
|
|
106
|
-
title: string;
|
|
107
|
-
description: string;
|
|
108
|
-
color: number;
|
|
109
|
-
fields: ReadonlyArray<{
|
|
110
|
-
name: string;
|
|
111
|
-
value: string;
|
|
112
|
-
inline: boolean;
|
|
113
|
-
}>;
|
|
114
|
-
timestamp: string;
|
|
115
|
-
}>;
|
|
116
|
-
/**
|
|
117
|
-
* Mention parsing is switched off: `content` carries end-user text, so an
|
|
118
|
-
* author called `@everyone` must render as text, never as a notification.
|
|
119
|
-
*/
|
|
120
|
-
allowed_mentions: {
|
|
121
|
-
parse: ReadonlyArray<"roles" | "users" | "everyone">;
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Generic webhook body — the stored record as JSON. `clientId` is stripped like
|
|
126
|
-
* on every other output: it is the browser-local dedup secret and the POST
|
|
127
|
-
* replay path hands the full record to whoever presents it.
|
|
128
|
-
*/
|
|
129
|
-
type GenericWebhookPayload = Omit<FeedbackRecord, "clientId">;
|
|
130
|
-
/** Mapping from webhook type to its concrete body shape. */
|
|
131
|
-
interface WebhookPayloadMap {
|
|
132
|
-
slack: SlackWebhookPayload;
|
|
133
|
-
discord: DiscordWebhookPayload;
|
|
134
|
-
generic: GenericWebhookPayload;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Dispatch a single webhook. Fire-and-forget: never throws, never rejects.
|
|
138
|
-
*
|
|
139
|
-
* - Builds the type-specific payload.
|
|
140
|
-
* - POSTs with an `AbortSignal` timeout.
|
|
141
|
-
* - On any error (network, non-2xx, timeout, exception), invokes
|
|
142
|
-
* `config.onError(err, feedbackId)` if provided; otherwise logs a one-liner.
|
|
143
|
-
*/
|
|
144
|
-
declare function dispatchWebhook(config: WebhookConfig, feedback: FeedbackRecord): Promise<void>;
|
|
145
|
-
/**
|
|
146
|
-
* Dispatch every configured webhook in parallel. Awaiting the returned promise
|
|
147
|
-
* lets tests synchronize on completion, but production callers should drop the
|
|
148
|
-
* promise on the floor (`void dispatchWebhooks(...)`) so the HTTP response
|
|
149
|
-
* isn't held back on slow receivers.
|
|
150
|
-
*/
|
|
151
|
-
declare function dispatchWebhooks(configs: readonly WebhookConfig[], feedback: FeedbackRecord): Promise<void>;
|
|
152
|
-
/** One handler per HTTP method — mount them on any Fetch-API router. */
|
|
153
|
-
interface SitepingHandler {
|
|
154
|
-
OPTIONS: (request: Request) => Response;
|
|
155
|
-
POST: (request: Request) => Promise<Response>;
|
|
156
|
-
GET: (request: Request) => Promise<Response>;
|
|
157
|
-
PATCH: (request: Request) => Promise<Response>;
|
|
158
|
-
DELETE: (request: Request) => Promise<Response>;
|
|
159
|
-
}
|
|
160
|
-
interface FeedbackPatchInput {
|
|
161
|
-
id: string;
|
|
162
|
-
projectName: string;
|
|
163
|
-
status: FeedbackStatus;
|
|
164
|
-
}
|
|
165
|
-
interface FeedbackDeleteSingle {
|
|
166
|
-
id: string;
|
|
167
|
-
projectName: string;
|
|
168
|
-
}
|
|
169
|
-
interface FeedbackDeleteAll {
|
|
170
|
-
projectName: string;
|
|
171
|
-
deleteAll: true;
|
|
172
|
-
}
|
|
173
|
-
type FeedbackDeleteInput = FeedbackDeleteSingle | FeedbackDeleteAll;
|
|
174
|
-
interface GetQueryInput {
|
|
175
|
-
projectName: string;
|
|
176
|
-
/** Set to 1 by schema default when omitted from raw input. */
|
|
177
|
-
page: number;
|
|
178
|
-
/** Set to 50 by schema default when omitted from raw input. */
|
|
179
|
-
limit: number;
|
|
180
|
-
type?: FeedbackType | undefined;
|
|
181
|
-
status?: FeedbackStatus | undefined;
|
|
182
|
-
statuses?: FeedbackStatus[] | undefined;
|
|
183
|
-
search?: string | undefined;
|
|
184
|
-
url?: string | undefined;
|
|
185
|
-
urlPattern?: string | undefined;
|
|
186
|
-
}
|
|
1
|
+
import { FeedbackPayload, BeezpingStore, ScreenshotStorage, CommentCreateInput, CommentRecord, FeedbackCreateInput, FeedbackRecord, FeedbackQuery, FeedbackPage, FeedbackUpdateInput } from './beezping-core.cjs';
|
|
2
|
+
export { BeezpingStore, CommentCreateInput, CommentPayload, FeedbackCreateInput, FeedbackRecord, ScreenshotStorage, StoreDuplicateError, StoreLimitError, StoreNotFoundError, StorePersistenceError, StoreValueTooLongError, flattenAnnotation, isStorePersistence } from './beezping-core.cjs';
|
|
3
|
+
import { BeezpingApiKeyHandlerOptions, BeezpingPrincipal, BeezpingAccessHandlerOptions, BeezpingHandler } from '@beezping/server';
|
|
4
|
+
export { BeezpingAccessControl, BeezpingAction, BeezpingAuthorizationContext, BeezpingDeletionTarget, BeezpingHandler, BeezpingHandlerBaseOptions, BeezpingHttpMethod, BeezpingLifecycleHooks, BeezpingLogger, BeezpingPrincipal, BeezpingRequestContext, DiscordWebhookPayload, FeedbackDeleteInput, FeedbackPatchInput, GenericWebhookPayload, GetQueryInput, SlackWebhookPayload, WebhookConfig, WebhookPayloadMap, WebhookType, dispatchWebhook, dispatchWebhooks } from '@beezping/server';
|
|
187
5
|
|
|
188
6
|
/**
|
|
189
7
|
* @deprecated The create wire shape is core's `FeedbackPayload` — import
|
|
@@ -192,7 +10,7 @@ interface GetQueryInput {
|
|
|
192
10
|
type FeedbackCreateSchemaInput = FeedbackPayload;
|
|
193
11
|
|
|
194
12
|
/**
|
|
195
|
-
* Structural type for a Prisma model delegate (`prisma.
|
|
13
|
+
* Structural type for a Prisma model delegate (`prisma.beezpingFeedback`).
|
|
196
14
|
*
|
|
197
15
|
* Arguments are kept `unknown` so any Prisma version's generated client
|
|
198
16
|
* satisfies the constraint; the adapter assembles type-safe payloads
|
|
@@ -221,8 +39,15 @@ interface PrismaModelDelegate {
|
|
|
221
39
|
* defines the subset of methods the adapter actually uses, so it can be
|
|
222
40
|
* referenced in handler option types without importing `@prisma/client`.
|
|
223
41
|
*/
|
|
224
|
-
interface
|
|
225
|
-
|
|
42
|
+
interface BeezpingPrismaClient {
|
|
43
|
+
beezpingFeedback: PrismaModelDelegate;
|
|
44
|
+
/**
|
|
45
|
+
* Generated once the schema declares the `BeezpingComment` model
|
|
46
|
+
* (`npx @beezping/cli sync`). Optional, so a client generated from an older
|
|
47
|
+
* schema keeps type-checking: `PrismaStore` then has no threads and the
|
|
48
|
+
* handler answers comment writes with 501.
|
|
49
|
+
*/
|
|
50
|
+
beezpingComment?: PrismaModelDelegate | undefined;
|
|
226
51
|
}
|
|
227
52
|
/**
|
|
228
53
|
* Options accepted by `PrismaStore`.
|
|
@@ -253,7 +78,7 @@ interface PrismaStoreOptions {
|
|
|
253
78
|
screenshotStorage?: ScreenshotStorage | undefined;
|
|
254
79
|
}
|
|
255
80
|
/**
|
|
256
|
-
* Prisma-backed implementation of `
|
|
81
|
+
* Prisma-backed implementation of `BeezpingStore`.
|
|
257
82
|
*
|
|
258
83
|
* Wraps a PrismaClient to satisfy the abstract store interface.
|
|
259
84
|
*
|
|
@@ -262,7 +87,7 @@ interface PrismaStoreOptions {
|
|
|
262
87
|
* the database stays small. Without `screenshotStorage`, the data URL is
|
|
263
88
|
* persisted inline (logged once on first use as a heads-up).
|
|
264
89
|
*/
|
|
265
|
-
declare class PrismaStore implements
|
|
90
|
+
declare class PrismaStore implements BeezpingStore {
|
|
266
91
|
/** @internal */
|
|
267
92
|
private prisma;
|
|
268
93
|
private readonly screenshotStorage;
|
|
@@ -270,8 +95,31 @@ declare class PrismaStore implements SitepingStore {
|
|
|
270
95
|
private inlineFallbackWarned;
|
|
271
96
|
/** @internal */
|
|
272
97
|
private caseInsensitiveSearch;
|
|
273
|
-
|
|
274
|
-
|
|
98
|
+
/** Read shape of every feedback query — with the thread once the client has the comment model. */
|
|
99
|
+
private readonly include;
|
|
100
|
+
/**
|
|
101
|
+
* Add a comment to a feedback's thread — defined only when the client has
|
|
102
|
+
* the `BeezpingComment` delegate, unless a subclass defines its own. Without
|
|
103
|
+
* it the store has no threads, and the handler answers comment writes with
|
|
104
|
+
* 501 instead of every post failing with a Prisma error. Declared, not a
|
|
105
|
+
* field: a field would set it on every instance, hiding a subclass's method.
|
|
106
|
+
*/
|
|
107
|
+
readonly addComment?: (feedbackId: string, data: CommentCreateInput) => Promise<CommentRecord>;
|
|
108
|
+
/** Delete one comment from a feedback's thread — defined under the same condition as {@link addComment}. */
|
|
109
|
+
readonly deleteComment?: (feedbackId: string, commentId: string) => Promise<void>;
|
|
110
|
+
constructor(prisma: BeezpingPrismaClient, options?: PrismaStoreOptions);
|
|
111
|
+
createFeedback(data: FeedbackCreateInput): Promise<FeedbackRecord>;
|
|
112
|
+
/**
|
|
113
|
+
* Drop the screenshot uploaded by a replay of a stored clientId — unless the
|
|
114
|
+
* stored row references it. Uploads are keyed on clientId, so with a
|
|
115
|
+
* deterministic key (`feedback/${feedbackId}.jpg`) the replay wrote to the
|
|
116
|
+
* very object the existing row points at: deleting it would strip the
|
|
117
|
+
* surviving feedback of its screenshot. If the lookup itself fails the
|
|
118
|
+
* object is kept — an orphan beats data loss. Other insert failures never
|
|
119
|
+
* get here: with such a key, a retry on another instance may have rewritten
|
|
120
|
+
* the object and not yet inserted the row that will point at it.
|
|
121
|
+
*/
|
|
122
|
+
private discardUnreferencedUpload;
|
|
275
123
|
private insertFeedback;
|
|
276
124
|
/**
|
|
277
125
|
* Resolve the value to persist on `Feedback.screenshotUrl`.
|
|
@@ -296,13 +144,34 @@ declare class PrismaStore implements SitepingStore {
|
|
|
296
144
|
* logged and swallowed: an orphaned object is preferable to a delete that
|
|
297
145
|
* reports failure after the row is already gone. Inline `data:` URLs and
|
|
298
146
|
* stores without a `delete` hook are skipped.
|
|
147
|
+
*
|
|
148
|
+
* Deletes run through a pool of at most {@link SCREENSHOT_DELETE_CONCURRENCY}
|
|
149
|
+
* concurrent calls: a project delete may free thousands of objects, and one
|
|
150
|
+
* socket each at once would exhaust the file descriptors of a serverless
|
|
151
|
+
* function, orphaning most of them.
|
|
299
152
|
*/
|
|
300
153
|
private discardScreenshots;
|
|
301
154
|
/** URLs of the stored screenshots in `projectName` — only fetched when a `delete` hook can use them. */
|
|
302
155
|
private storedScreenshotUrls;
|
|
303
|
-
findByClientId(clientId: string): Promise<FeedbackRecord
|
|
156
|
+
findByClientId(clientId: string): Promise<FeedbackRecord | null>;
|
|
304
157
|
getFeedbacks(query: FeedbackQuery): Promise<FeedbackPage>;
|
|
305
|
-
updateFeedback(id: string, data: FeedbackUpdateInput): Promise<FeedbackRecord
|
|
158
|
+
updateFeedback(id: string, data: FeedbackUpdateInput): Promise<FeedbackRecord>;
|
|
159
|
+
/**
|
|
160
|
+
* Insert a comment. A replayed `clientId` returns the stored comment, looked
|
|
161
|
+
* up first so a replay never runs into the thread cap; a concurrent replay
|
|
162
|
+
* that wins the insert race surfaces as P2002 and is read back the same
|
|
163
|
+
* way. The `connect` turns a missing feedback into Prisma's P2025 on every
|
|
164
|
+
* provider, rather than each database's own foreign-key error. The cap on
|
|
165
|
+
* `client` comments is a count before the insert, so posts racing for the
|
|
166
|
+
* last free slot may overshoot it; a `team` comment skips it.
|
|
167
|
+
*/
|
|
168
|
+
private insertComment;
|
|
169
|
+
private findComment;
|
|
170
|
+
/**
|
|
171
|
+
* Delete one comment. Both ids go in one `deleteMany`, so a comment of
|
|
172
|
+
* another thread and an unknown one are the same zero-row miss.
|
|
173
|
+
*/
|
|
174
|
+
private removeComment;
|
|
306
175
|
deleteFeedback(id: string): Promise<void>;
|
|
307
176
|
deleteAllFeedbacks(projectName: string): Promise<void>;
|
|
308
177
|
/**
|
|
@@ -311,11 +180,12 @@ declare class PrismaStore implements SitepingStore {
|
|
|
311
180
|
*/
|
|
312
181
|
verifyProjectOwnership(id: string, projectName: string): Promise<boolean>;
|
|
313
182
|
}
|
|
314
|
-
|
|
183
|
+
/** How the handler reaches its data: a Prisma client, or any store. */
|
|
184
|
+
interface PrismaHandlerStoreOptions {
|
|
315
185
|
/** Prisma client — used when `store` is not provided. Wrapped in a `PrismaStore` internally. */
|
|
316
|
-
prisma?:
|
|
186
|
+
prisma?: BeezpingPrismaClient;
|
|
317
187
|
/** Abstract store — when provided, takes precedence over `prisma`. */
|
|
318
|
-
store?:
|
|
188
|
+
store?: BeezpingStore;
|
|
319
189
|
/**
|
|
320
190
|
* Optional storage backend for screenshots. Used only with `prisma`
|
|
321
191
|
* (ignored when a custom `store` is passed — that store is responsible
|
|
@@ -323,8 +193,6 @@ interface HandlerOptions extends ApiKeyAccessOptions {
|
|
|
323
193
|
* persisted inline on `Feedback.screenshotUrl` with a one-time warn.
|
|
324
194
|
*/
|
|
325
195
|
screenshotStorage?: ScreenshotStorage;
|
|
326
|
-
/** Allowed CORS origins — when set, validates the Origin header */
|
|
327
|
-
allowedOrigins?: ReadonlyArray<string> | undefined;
|
|
328
196
|
/**
|
|
329
197
|
* Override case-insensitive search behaviour for the built-in `PrismaStore`.
|
|
330
198
|
*
|
|
@@ -333,31 +201,45 @@ interface HandlerOptions extends ApiKeyAccessOptions {
|
|
|
333
201
|
* auto-detection and per-provider semantics.
|
|
334
202
|
*/
|
|
335
203
|
caseInsensitiveSearch?: boolean;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
204
|
+
}
|
|
205
|
+
/** Options of `createBeezpingHandler` under the `apiKey` policy — every `@beezping/server` option. */
|
|
206
|
+
interface HandlerOptions extends Omit<BeezpingApiKeyHandlerOptions, "store">, PrismaHandlerStoreOptions {
|
|
207
|
+
}
|
|
208
|
+
/** Options of `createBeezpingHandler` under a custom `access` policy (see `@beezping/server`). */
|
|
209
|
+
interface PrismaAccessHandlerOptions<Principal extends BeezpingPrincipal> extends Omit<BeezpingAccessHandlerOptions<Principal>, "store">, PrismaHandlerStoreOptions {
|
|
341
210
|
}
|
|
342
211
|
/**
|
|
343
|
-
* Create request handlers for the
|
|
212
|
+
* Create request handlers for the Beezping API endpoint — `@beezping/server`'s
|
|
213
|
+
* `createBeezpingHandler` over a Prisma-backed store, with every server option.
|
|
344
214
|
*
|
|
345
215
|
* Accepts either a `store` (abstract) or a `prisma` client (backwards compatible).
|
|
346
216
|
* When `prisma` is provided without `store`, it is wrapped in a `PrismaStore`.
|
|
347
|
-
* For custom auth (sessions, roles), lifecycle hooks or input transforms use
|
|
348
|
-
* `createSitepingHandler` from `@beezping/server` with a `PrismaStore`.
|
|
349
217
|
*
|
|
350
218
|
* **Rate limiting** is not handled by this library. Apply rate limiting at the
|
|
351
219
|
* framework or reverse-proxy level (e.g. Next.js middleware, Nginx, Cloudflare).
|
|
220
|
+
* The POST endpoint in particular should be rate-limited to prevent abuse, since
|
|
221
|
+
* the widget typically calls it from unauthenticated browser contexts.
|
|
222
|
+
*
|
|
223
|
+
* @example Next.js App Router — `app/api/beezping/route.ts`
|
|
224
|
+
* ```ts
|
|
225
|
+
* import { createBeezpingHandler } from '@beezping/adapter-prisma'
|
|
226
|
+
* import { prisma } from '@/lib/prisma'
|
|
227
|
+
*
|
|
228
|
+
* export const { GET, POST, PATCH, DELETE, OPTIONS } = createBeezpingHandler({ prisma })
|
|
229
|
+
* ```
|
|
352
230
|
*
|
|
353
|
-
* @example
|
|
231
|
+
* @example With abstract store
|
|
354
232
|
* ```ts
|
|
355
|
-
* import {
|
|
233
|
+
* import { createBeezpingHandler, PrismaStore } from '@beezping/adapter-prisma'
|
|
356
234
|
* import { prisma } from '@/lib/prisma'
|
|
357
235
|
*
|
|
358
|
-
*
|
|
236
|
+
* const store = new PrismaStore(prisma)
|
|
237
|
+
* export const { GET, POST, PATCH, DELETE, OPTIONS } = createBeezpingHandler({ store })
|
|
359
238
|
* ```
|
|
360
239
|
*/
|
|
361
|
-
declare function
|
|
240
|
+
declare function createBeezpingHandler<Principal extends BeezpingPrincipal>(options: PrismaAccessHandlerOptions<Principal>): BeezpingHandler;
|
|
241
|
+
declare function createBeezpingHandler(options: HandlerOptions): BeezpingHandler;
|
|
242
|
+
/** Options assembled at runtime, either policy. */
|
|
243
|
+
declare function createBeezpingHandler<Principal extends BeezpingPrincipal>(options: HandlerOptions | PrismaAccessHandlerOptions<Principal>): BeezpingHandler;
|
|
362
244
|
|
|
363
|
-
export { type
|
|
245
|
+
export { type BeezpingPrismaClient, type FeedbackCreateSchemaInput, type HandlerOptions, type PrismaAccessHandlerOptions, type PrismaModelDelegate, PrismaStore, type PrismaStoreOptions, createBeezpingHandler };
|