@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 CHANGED
@@ -1,12 +1,12 @@
1
1
  [![npm version](https://img.shields.io/npm/v/@beezping/adapter-prisma)](https://www.npmjs.com/package/@beezping/adapter-prisma)
2
- [![Docs](https://img.shields.io/badge/docs-siteping.dev-0066ff)](https://siteping.dev/docs/adapters/prisma)
2
+ [![Docs](https://img.shields.io/badge/docs-github.com/guidomodarelli/beezping-0066ff)](https://github.com/guidomodarelli/beezping/tree/main/apps/demo/content/docs/adapters/prisma.mdx)
3
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)
4
4
 
5
5
  # @beezping/adapter-prisma
6
6
 
7
- The production server adapter for [SitePing](https://github.com/NeosiaNexus/SitePing) — one endpoint that validates, authenticates, and persists client feedback in your database.
7
+ The production server adapter for [Beezping](https://github.com/guidomodarelli/beezping) — one endpoint that validates, authenticates, and persists client feedback in your database.
8
8
 
9
- **[Documentation](https://siteping.dev/docs/adapters/prisma)** · **[live demo](https://siteping.dev/demo)**
9
+ **[Documentation](https://github.com/guidomodarelli/beezping/tree/main/apps/demo/content/docs/adapters/prisma.mdx)** · **[live demo](https://github.com/guidomodarelli/beezping/tree/main/apps/demo)**
10
10
 
11
11
  ## Install
12
12
 
@@ -14,18 +14,18 @@ The production server adapter for [SitePing](https://github.com/NeosiaNexus/Site
14
14
  npm install @beezping/adapter-prisma
15
15
  ```
16
16
 
17
- **Peer dependency:** `@prisma/client` ^5 || ^6 || ^7 · Node ≥ 20.
17
+ **Optional peer dependency:** `@prisma/client` ^5 || ^6 || ^7, needed only for the `prisma` option · Node ≥ 20.
18
18
 
19
19
  ## Quick start
20
20
 
21
21
  ```ts
22
- // app/api/siteping/route.ts — Next.js App Router
23
- import { createSitepingHandler } from "@beezping/adapter-prisma";
22
+ // app/api/beezping/route.ts — Next.js App Router
23
+ import { createBeezpingHandler } from "@beezping/adapter-prisma";
24
24
  import { prisma } from "@/lib/prisma";
25
25
 
26
- export const { GET, POST, PATCH, DELETE, OPTIONS } = createSitepingHandler({
26
+ export const { GET, POST, PATCH, DELETE, OPTIONS } = createBeezpingHandler({
27
27
  prisma,
28
- apiKey: process.env.SITEPING_API_KEY, // Bearer auth
28
+ apiKey: process.env.BEEZPING_API_KEY, // Bearer auth
29
29
  allowedOrigins: ["https://my-site.com"], // exact-match CORS
30
30
  });
31
31
  ```
@@ -37,12 +37,12 @@ The handlers are Web-standard `Request` → `Response` — mount them from any f
37
37
  - **Safe by default** — status changes and deletes require the `apiKey`; in production the factory refuses to start without one. Author emails are redacted for unauthenticated readers and `clientId` never leaves the server
38
38
  - **Screenshot storage hook** — upload images to S3/R2/GCS instead of inlining data URLs
39
39
  - **Webhooks** — Slack, Discord, or generic POST on each new feedback (5 s timeout, never blocks the submission)
40
- - **Any store behind the same HTTP surface** — pass `store` instead of `prisma` to mount an in-memory or custom store with identical validation and auth
40
+ - **Built on [`@beezping/server`](https://github.com/guidomodarelli/beezping/tree/main/apps/demo/content/docs/server.mdx)** — every server option works here too (custom `access`, lifecycle hooks, `waitUntil`…), and a non-Prisma store can mount through `@beezping/server` alone
41
41
 
42
42
  ## Documentation
43
43
 
44
- All options with their real defaults, the full HTTP reference (bodies, query params, errors, validation limits), the exact Prisma schema, and the security model: **[siteping.dev/docs/adapters/prisma](https://siteping.dev/docs/adapters/prisma)**.
44
+ The Prisma options, the exact Prisma schema and screenshot storage: **[github.com/guidomodarelli/beezping/docs/adapters/prisma](https://github.com/guidomodarelli/beezping/tree/main/apps/demo/content/docs/adapters/prisma.mdx)**. The security model and the full HTTP reference (bodies, query params, errors, validation limits): **[github.com/guidomodarelli/beezping/docs/server](https://github.com/guidomodarelli/beezping/tree/main/apps/demo/content/docs/server.mdx)**.
45
45
 
46
46
  ## License
47
47
 
48
- [MIT](https://github.com/NeosiaNexus/SitePing/blob/main/LICENSE)
48
+ [MIT](https://github.com/guidomodarelli/beezping/blob/main/LICENSE)
@@ -0,0 +1,20 @@
1
+ export { settleWithConcurrencyLimit } from "./concurrency.cjs";
2
+ export { buildDeepLink, parseHttpUrl } from "./deep-link.cjs";
3
+ export { EMAIL_PATTERN, isValidEmail } from "./email.cjs";
4
+ export type { BeezpingErrorCode } from "./errors.cjs";
5
+ export { BeezpingAuthError, BeezpingError, BeezpingNetworkError, BeezpingValidationError } from "./errors.cjs";
6
+ export type { FilterResult, Pagination } from "./filters.cjs";
7
+ export { applyFeedbackFilters, clampPagination, DEFAULT_PAGE_LIMIT, isUnreachableOffset, MAX_PAGE_LIMIT, matchesFeedbackQuery, } from "./filters.cjs";
8
+ export type { I18n, LocaleLoaders, TranslateFunction } from "./i18n.cjs";
9
+ export { canonicalizeLocale, createI18n, interpolate, intlLocale, tWithParams } from "./i18n.cjs";
10
+ export type { BeezpingModelFieldName, BeezpingModelName, FieldDef, IndexDef, ModelDef, PrismaNativeType, PrismaScalarType, RelationDef, RelationKind, RelationOnDelete, } from "./schema.cjs";
11
+ export { BEEZPING_MODELS, isRelationField, isScalarField } from "./schema.cjs";
12
+ export type { ScreenshotStorage } from "./screenshot-storage.cjs";
13
+ export { SCREENSHOT_DELETE_CONCURRENCY, screenshotMimeType } from "./screenshot-storage.cjs";
14
+ export type { CollectionStore, CollectionStoreBackend } from "./store-helpers.cjs";
15
+ export { buildAnnotationRecord, buildCommentRecord, buildFeedbackRecord, createCollectionStore, } from "./store-helpers.cjs";
16
+ export type { AssertEqual, IfEquals, Prettify, Serialized } from "./type-utils.cjs";
17
+ export { hasOwn, isRecord } from "./type-utils.cjs";
18
+ export type { AnchorData, AnnotationCreateInput, AnnotationPayload, AnnotationRecord, AnnotationResponse, BeezpingBaseConfig, BeezpingCapabilities, BeezpingConfig, BeezpingDeepLinkOptions, BeezpingHeadersOption, BeezpingHttpConfig, BeezpingIdentity, BeezpingInstance, BeezpingLocale, BeezpingPanelAction, BeezpingPanelActionContext, BeezpingPanelActionFeedback, BeezpingPanelButtonAction, BeezpingPanelLinkAction, BeezpingPosition, BeezpingPublicEventListener, BeezpingPublicEvents, BeezpingSkipReason, BeezpingStore, BeezpingStoreConfig, BeezpingTheme, BeezpingUnsubscribe, BuiltinLocale, ClosedFeedbackStatus, CommentAuthorRole, CommentCreateInput, CommentDeletePayload, CommentPayload, CommentRecord, CommentResponse, ConsoleDiagnosticEntry, ConsoleDiagnosticLevel, DiagnosticsCaptureOptions, DiagnosticsSnapshot, FeedbackCreateInput, FeedbackCreateOutcome, FeedbackListPermissions, FeedbackPage, FeedbackPayload, FeedbackPermissions, FeedbackQuery, FeedbackRecord, FeedbackResponse, FeedbackResponseList, FeedbackStatus, FeedbackType, FeedbackUpdateInput, NetworkDiagnosticEntry, OpenFeedbackStatus, PageScope, RectData, ScreenshotRegion, } from "./types.cjs";
19
+ export { ANCHOR_ELEMENT_ID_MAX, ANCHOR_ELEMENT_TAG_MAX, BUILTIN_LOCALES, CLOSED_FEEDBACK_STATUSES, COMMENT_AUTHOR_ROLES, COMMENT_BODY_MAX_LENGTH, CONSOLE_DIAGNOSTIC_LEVELS, FEEDBACK_STATUSES, FEEDBACK_TYPES, flattenAnnotation, IDENTITY_FIELD_MAX_LENGTH, isClosedStatus, isStoreDuplicate, isStoreLimit, isStoreNotFound, isStorePersistence, isStoreValueTooLong, MAX_COMMENTS_PER_FEEDBACK, OPEN_FEEDBACK_STATUSES, StoreDuplicateError, StoreLimitError, StoreNotFoundError, StorePersistenceError, StoreValueTooLongError, toFeedbackUpdate, } from "./types.cjs";
20
+ export { errorFromResponse, feedbackQueryToSearchParams, isCommentGone, isThreadFull, mergeRequestHeaders, networkErrorFromException, newClientId, withSearchParams, } from "./wire.cjs";
@@ -0,0 +1,20 @@
1
+ export { settleWithConcurrencyLimit } from "./concurrency.js";
2
+ export { buildDeepLink, parseHttpUrl } from "./deep-link.js";
3
+ export { EMAIL_PATTERN, isValidEmail } from "./email.js";
4
+ export type { BeezpingErrorCode } from "./errors.js";
5
+ export { BeezpingAuthError, BeezpingError, BeezpingNetworkError, BeezpingValidationError } from "./errors.js";
6
+ export type { FilterResult, Pagination } from "./filters.js";
7
+ export { applyFeedbackFilters, clampPagination, DEFAULT_PAGE_LIMIT, isUnreachableOffset, MAX_PAGE_LIMIT, matchesFeedbackQuery, } from "./filters.js";
8
+ export type { I18n, LocaleLoaders, TranslateFunction } from "./i18n.js";
9
+ export { canonicalizeLocale, createI18n, interpolate, intlLocale, tWithParams } from "./i18n.js";
10
+ export type { BeezpingModelFieldName, BeezpingModelName, FieldDef, IndexDef, ModelDef, PrismaNativeType, PrismaScalarType, RelationDef, RelationKind, RelationOnDelete, } from "./schema.js";
11
+ export { BEEZPING_MODELS, isRelationField, isScalarField } from "./schema.js";
12
+ export type { ScreenshotStorage } from "./screenshot-storage.js";
13
+ export { SCREENSHOT_DELETE_CONCURRENCY, screenshotMimeType } from "./screenshot-storage.js";
14
+ export type { CollectionStore, CollectionStoreBackend } from "./store-helpers.js";
15
+ export { buildAnnotationRecord, buildCommentRecord, buildFeedbackRecord, createCollectionStore, } from "./store-helpers.js";
16
+ export type { AssertEqual, IfEquals, Prettify, Serialized } from "./type-utils.js";
17
+ export { hasOwn, isRecord } from "./type-utils.js";
18
+ export type { AnchorData, AnnotationCreateInput, AnnotationPayload, AnnotationRecord, AnnotationResponse, BeezpingBaseConfig, BeezpingCapabilities, BeezpingConfig, BeezpingDeepLinkOptions, BeezpingHeadersOption, BeezpingHttpConfig, BeezpingIdentity, BeezpingInstance, BeezpingLocale, BeezpingPanelAction, BeezpingPanelActionContext, BeezpingPanelActionFeedback, BeezpingPanelButtonAction, BeezpingPanelLinkAction, BeezpingPosition, BeezpingPublicEventListener, BeezpingPublicEvents, BeezpingSkipReason, BeezpingStore, BeezpingStoreConfig, BeezpingTheme, BeezpingUnsubscribe, BuiltinLocale, ClosedFeedbackStatus, CommentAuthorRole, CommentCreateInput, CommentDeletePayload, CommentPayload, CommentRecord, CommentResponse, ConsoleDiagnosticEntry, ConsoleDiagnosticLevel, DiagnosticsCaptureOptions, DiagnosticsSnapshot, FeedbackCreateInput, FeedbackCreateOutcome, FeedbackListPermissions, FeedbackPage, FeedbackPayload, FeedbackPermissions, FeedbackQuery, FeedbackRecord, FeedbackResponse, FeedbackResponseList, FeedbackStatus, FeedbackType, FeedbackUpdateInput, NetworkDiagnosticEntry, OpenFeedbackStatus, PageScope, RectData, ScreenshotRegion, } from "./types.js";
19
+ export { ANCHOR_ELEMENT_ID_MAX, ANCHOR_ELEMENT_TAG_MAX, BUILTIN_LOCALES, CLOSED_FEEDBACK_STATUSES, COMMENT_AUTHOR_ROLES, COMMENT_BODY_MAX_LENGTH, CONSOLE_DIAGNOSTIC_LEVELS, FEEDBACK_STATUSES, FEEDBACK_TYPES, flattenAnnotation, IDENTITY_FIELD_MAX_LENGTH, isClosedStatus, isStoreDuplicate, isStoreLimit, isStoreNotFound, isStorePersistence, isStoreValueTooLong, MAX_COMMENTS_PER_FEEDBACK, OPEN_FEEDBACK_STATUSES, StoreDuplicateError, StoreLimitError, StoreNotFoundError, StorePersistenceError, StoreValueTooLongError, toFeedbackUpdate, } from "./types.js";
20
+ export { errorFromResponse, feedbackQueryToSearchParams, isCommentGone, isThreadFull, mergeRequestHeaders, networkErrorFromException, newClientId, withSearchParams, } from "./wire.js";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Run `task` over every item with at most `concurrency` calls in flight and
3
+ * settle each call on its own, like `Promise.allSettled` over a bounded pool.
4
+ *
5
+ * Each call runs inside its own promise, so a task that throws synchronously
6
+ * is settled as a rejection instead of stopping the pool, and one failure
7
+ * never skips the remaining items.
8
+ *
9
+ * @param items - Inputs, processed in order.
10
+ * @param concurrency - Maximum number of simultaneous `task` calls (at least 1).
11
+ * @param task - Operation to run for each item.
12
+ * @returns The settled result of every call, in the order of `items`.
13
+ */
14
+ export declare function settleWithConcurrencyLimit<Item, Result>(items: readonly Item[], concurrency: number, task: (item: Item) => Promise<Result>): Promise<Array<PromiseSettledResult<Result>>>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Run `task` over every item with at most `concurrency` calls in flight and
3
+ * settle each call on its own, like `Promise.allSettled` over a bounded pool.
4
+ *
5
+ * Each call runs inside its own promise, so a task that throws synchronously
6
+ * is settled as a rejection instead of stopping the pool, and one failure
7
+ * never skips the remaining items.
8
+ *
9
+ * @param items - Inputs, processed in order.
10
+ * @param concurrency - Maximum number of simultaneous `task` calls (at least 1).
11
+ * @param task - Operation to run for each item.
12
+ * @returns The settled result of every call, in the order of `items`.
13
+ */
14
+ export declare function settleWithConcurrencyLimit<Item, Result>(items: readonly Item[], concurrency: number, task: (item: Item) => Promise<Result>): Promise<Array<PromiseSettledResult<Result>>>;
@@ -0,0 +1,239 @@
1
+ declare const _BEEZPING_MODELS: {
2
+ readonly BeezpingFeedback: {
3
+ readonly fields: {
4
+ readonly id: {
5
+ readonly type: "String";
6
+ readonly isId: true;
7
+ readonly default: "cuid()";
8
+ };
9
+ readonly projectName: {
10
+ readonly type: "String";
11
+ };
12
+ readonly type: {
13
+ readonly type: "String";
14
+ };
15
+ readonly message: {
16
+ readonly type: "String";
17
+ readonly nativeType: "Text";
18
+ };
19
+ readonly status: {
20
+ readonly type: "String";
21
+ readonly default: "\"open\"";
22
+ };
23
+ readonly url: {
24
+ readonly type: "String";
25
+ };
26
+ readonly urlPattern: {
27
+ readonly type: "String";
28
+ readonly optional: true;
29
+ };
30
+ readonly screenshotUrl: {
31
+ readonly type: "String";
32
+ readonly optional: true;
33
+ readonly nativeType: "Text";
34
+ };
35
+ readonly screenshotRegion: {
36
+ readonly type: "Json";
37
+ readonly optional: true;
38
+ };
39
+ readonly diagnostics: {
40
+ readonly type: "Json";
41
+ readonly optional: true;
42
+ };
43
+ readonly viewport: {
44
+ readonly type: "String";
45
+ };
46
+ readonly userAgent: {
47
+ readonly type: "String";
48
+ };
49
+ readonly authorName: {
50
+ readonly type: "String";
51
+ };
52
+ readonly authorEmail: {
53
+ readonly type: "String";
54
+ };
55
+ readonly clientId: {
56
+ readonly type: "String";
57
+ readonly isUnique: true;
58
+ };
59
+ readonly resolvedAt: {
60
+ readonly type: "DateTime";
61
+ readonly optional: true;
62
+ };
63
+ readonly createdAt: {
64
+ readonly type: "DateTime";
65
+ readonly default: "now()";
66
+ };
67
+ readonly updatedAt: {
68
+ readonly type: "DateTime";
69
+ readonly isUpdatedAt: true;
70
+ };
71
+ readonly annotations: {
72
+ readonly type: "BeezpingAnnotation";
73
+ readonly relation: {
74
+ readonly kind: "1-to-many";
75
+ readonly model: "BeezpingAnnotation";
76
+ };
77
+ };
78
+ readonly comments: {
79
+ readonly type: "BeezpingComment";
80
+ readonly relation: {
81
+ readonly kind: "1-to-many";
82
+ readonly model: "BeezpingComment";
83
+ };
84
+ };
85
+ };
86
+ readonly indexes: readonly [{
87
+ readonly fields: readonly ["projectName"];
88
+ }, {
89
+ readonly fields: readonly ["projectName", "status", "createdAt"];
90
+ }, {
91
+ readonly fields: readonly ["projectName", "url"];
92
+ }];
93
+ };
94
+ readonly BeezpingAnnotation: {
95
+ readonly fields: {
96
+ readonly id: {
97
+ readonly type: "String";
98
+ readonly isId: true;
99
+ readonly default: "cuid()";
100
+ };
101
+ readonly feedbackId: {
102
+ readonly type: "String";
103
+ };
104
+ readonly feedback: {
105
+ readonly type: "BeezpingFeedback";
106
+ readonly relation: {
107
+ readonly kind: "many-to-1";
108
+ readonly model: "BeezpingFeedback";
109
+ readonly fields: readonly ["feedbackId"];
110
+ readonly references: readonly ["id"];
111
+ readonly onDelete: "Cascade";
112
+ };
113
+ };
114
+ readonly cssSelector: {
115
+ readonly type: "String";
116
+ readonly nativeType: "Text";
117
+ };
118
+ readonly xpath: {
119
+ readonly type: "String";
120
+ readonly nativeType: "Text";
121
+ };
122
+ readonly textSnippet: {
123
+ readonly type: "String";
124
+ readonly nativeType: "Text";
125
+ };
126
+ readonly elementTag: {
127
+ readonly type: "String";
128
+ };
129
+ readonly elementId: {
130
+ readonly type: "String";
131
+ readonly optional: true;
132
+ };
133
+ readonly textPrefix: {
134
+ readonly type: "String";
135
+ readonly nativeType: "Text";
136
+ };
137
+ readonly textSuffix: {
138
+ readonly type: "String";
139
+ readonly nativeType: "Text";
140
+ };
141
+ readonly fingerprint: {
142
+ readonly type: "String";
143
+ };
144
+ readonly neighborText: {
145
+ readonly type: "String";
146
+ readonly nativeType: "Text";
147
+ };
148
+ readonly anchorKey: {
149
+ readonly type: "String";
150
+ readonly optional: true;
151
+ };
152
+ readonly xPct: {
153
+ readonly type: "Float";
154
+ };
155
+ readonly yPct: {
156
+ readonly type: "Float";
157
+ };
158
+ readonly wPct: {
159
+ readonly type: "Float";
160
+ };
161
+ readonly hPct: {
162
+ readonly type: "Float";
163
+ };
164
+ readonly scrollX: {
165
+ readonly type: "Float";
166
+ };
167
+ readonly scrollY: {
168
+ readonly type: "Float";
169
+ };
170
+ readonly viewportW: {
171
+ readonly type: "Int";
172
+ };
173
+ readonly viewportH: {
174
+ readonly type: "Int";
175
+ };
176
+ readonly devicePixelRatio: {
177
+ readonly type: "Float";
178
+ readonly default: "1";
179
+ };
180
+ readonly createdAt: {
181
+ readonly type: "DateTime";
182
+ readonly default: "now()";
183
+ };
184
+ };
185
+ readonly indexes: readonly [{
186
+ readonly fields: readonly ["feedbackId"];
187
+ }];
188
+ };
189
+ readonly BeezpingComment: {
190
+ readonly fields: {
191
+ readonly id: {
192
+ readonly type: "String";
193
+ readonly isId: true;
194
+ readonly default: "cuid()";
195
+ };
196
+ readonly feedbackId: {
197
+ readonly type: "String";
198
+ };
199
+ readonly feedback: {
200
+ readonly type: "BeezpingFeedback";
201
+ readonly relation: {
202
+ readonly kind: "many-to-1";
203
+ readonly model: "BeezpingFeedback";
204
+ readonly fields: readonly ["feedbackId"];
205
+ readonly references: readonly ["id"];
206
+ readonly onDelete: "Cascade";
207
+ };
208
+ };
209
+ readonly body: {
210
+ readonly type: "String";
211
+ readonly nativeType: "Text";
212
+ };
213
+ readonly authorName: {
214
+ readonly type: "String";
215
+ };
216
+ readonly authorEmail: {
217
+ readonly type: "String";
218
+ };
219
+ readonly authorRole: {
220
+ readonly type: "String";
221
+ readonly default: "\"client\"";
222
+ };
223
+ readonly clientId: {
224
+ readonly type: "String";
225
+ readonly isUnique: true;
226
+ };
227
+ readonly createdAt: {
228
+ readonly type: "DateTime";
229
+ readonly default: "now()";
230
+ };
231
+ };
232
+ readonly indexes: readonly [{
233
+ readonly fields: readonly ["feedbackId", "createdAt"];
234
+ }];
235
+ };
236
+ };
237
+ /** Map of Beezping models keyed by model name — frozen at runtime. */
238
+ export declare const BEEZPING_MODELS: typeof _BEEZPING_MODELS;
239
+ export {};
@@ -0,0 +1,239 @@
1
+ declare const _BEEZPING_MODELS: {
2
+ readonly BeezpingFeedback: {
3
+ readonly fields: {
4
+ readonly id: {
5
+ readonly type: "String";
6
+ readonly isId: true;
7
+ readonly default: "cuid()";
8
+ };
9
+ readonly projectName: {
10
+ readonly type: "String";
11
+ };
12
+ readonly type: {
13
+ readonly type: "String";
14
+ };
15
+ readonly message: {
16
+ readonly type: "String";
17
+ readonly nativeType: "Text";
18
+ };
19
+ readonly status: {
20
+ readonly type: "String";
21
+ readonly default: "\"open\"";
22
+ };
23
+ readonly url: {
24
+ readonly type: "String";
25
+ };
26
+ readonly urlPattern: {
27
+ readonly type: "String";
28
+ readonly optional: true;
29
+ };
30
+ readonly screenshotUrl: {
31
+ readonly type: "String";
32
+ readonly optional: true;
33
+ readonly nativeType: "Text";
34
+ };
35
+ readonly screenshotRegion: {
36
+ readonly type: "Json";
37
+ readonly optional: true;
38
+ };
39
+ readonly diagnostics: {
40
+ readonly type: "Json";
41
+ readonly optional: true;
42
+ };
43
+ readonly viewport: {
44
+ readonly type: "String";
45
+ };
46
+ readonly userAgent: {
47
+ readonly type: "String";
48
+ };
49
+ readonly authorName: {
50
+ readonly type: "String";
51
+ };
52
+ readonly authorEmail: {
53
+ readonly type: "String";
54
+ };
55
+ readonly clientId: {
56
+ readonly type: "String";
57
+ readonly isUnique: true;
58
+ };
59
+ readonly resolvedAt: {
60
+ readonly type: "DateTime";
61
+ readonly optional: true;
62
+ };
63
+ readonly createdAt: {
64
+ readonly type: "DateTime";
65
+ readonly default: "now()";
66
+ };
67
+ readonly updatedAt: {
68
+ readonly type: "DateTime";
69
+ readonly isUpdatedAt: true;
70
+ };
71
+ readonly annotations: {
72
+ readonly type: "BeezpingAnnotation";
73
+ readonly relation: {
74
+ readonly kind: "1-to-many";
75
+ readonly model: "BeezpingAnnotation";
76
+ };
77
+ };
78
+ readonly comments: {
79
+ readonly type: "BeezpingComment";
80
+ readonly relation: {
81
+ readonly kind: "1-to-many";
82
+ readonly model: "BeezpingComment";
83
+ };
84
+ };
85
+ };
86
+ readonly indexes: readonly [{
87
+ readonly fields: readonly ["projectName"];
88
+ }, {
89
+ readonly fields: readonly ["projectName", "status", "createdAt"];
90
+ }, {
91
+ readonly fields: readonly ["projectName", "url"];
92
+ }];
93
+ };
94
+ readonly BeezpingAnnotation: {
95
+ readonly fields: {
96
+ readonly id: {
97
+ readonly type: "String";
98
+ readonly isId: true;
99
+ readonly default: "cuid()";
100
+ };
101
+ readonly feedbackId: {
102
+ readonly type: "String";
103
+ };
104
+ readonly feedback: {
105
+ readonly type: "BeezpingFeedback";
106
+ readonly relation: {
107
+ readonly kind: "many-to-1";
108
+ readonly model: "BeezpingFeedback";
109
+ readonly fields: readonly ["feedbackId"];
110
+ readonly references: readonly ["id"];
111
+ readonly onDelete: "Cascade";
112
+ };
113
+ };
114
+ readonly cssSelector: {
115
+ readonly type: "String";
116
+ readonly nativeType: "Text";
117
+ };
118
+ readonly xpath: {
119
+ readonly type: "String";
120
+ readonly nativeType: "Text";
121
+ };
122
+ readonly textSnippet: {
123
+ readonly type: "String";
124
+ readonly nativeType: "Text";
125
+ };
126
+ readonly elementTag: {
127
+ readonly type: "String";
128
+ };
129
+ readonly elementId: {
130
+ readonly type: "String";
131
+ readonly optional: true;
132
+ };
133
+ readonly textPrefix: {
134
+ readonly type: "String";
135
+ readonly nativeType: "Text";
136
+ };
137
+ readonly textSuffix: {
138
+ readonly type: "String";
139
+ readonly nativeType: "Text";
140
+ };
141
+ readonly fingerprint: {
142
+ readonly type: "String";
143
+ };
144
+ readonly neighborText: {
145
+ readonly type: "String";
146
+ readonly nativeType: "Text";
147
+ };
148
+ readonly anchorKey: {
149
+ readonly type: "String";
150
+ readonly optional: true;
151
+ };
152
+ readonly xPct: {
153
+ readonly type: "Float";
154
+ };
155
+ readonly yPct: {
156
+ readonly type: "Float";
157
+ };
158
+ readonly wPct: {
159
+ readonly type: "Float";
160
+ };
161
+ readonly hPct: {
162
+ readonly type: "Float";
163
+ };
164
+ readonly scrollX: {
165
+ readonly type: "Float";
166
+ };
167
+ readonly scrollY: {
168
+ readonly type: "Float";
169
+ };
170
+ readonly viewportW: {
171
+ readonly type: "Int";
172
+ };
173
+ readonly viewportH: {
174
+ readonly type: "Int";
175
+ };
176
+ readonly devicePixelRatio: {
177
+ readonly type: "Float";
178
+ readonly default: "1";
179
+ };
180
+ readonly createdAt: {
181
+ readonly type: "DateTime";
182
+ readonly default: "now()";
183
+ };
184
+ };
185
+ readonly indexes: readonly [{
186
+ readonly fields: readonly ["feedbackId"];
187
+ }];
188
+ };
189
+ readonly BeezpingComment: {
190
+ readonly fields: {
191
+ readonly id: {
192
+ readonly type: "String";
193
+ readonly isId: true;
194
+ readonly default: "cuid()";
195
+ };
196
+ readonly feedbackId: {
197
+ readonly type: "String";
198
+ };
199
+ readonly feedback: {
200
+ readonly type: "BeezpingFeedback";
201
+ readonly relation: {
202
+ readonly kind: "many-to-1";
203
+ readonly model: "BeezpingFeedback";
204
+ readonly fields: readonly ["feedbackId"];
205
+ readonly references: readonly ["id"];
206
+ readonly onDelete: "Cascade";
207
+ };
208
+ };
209
+ readonly body: {
210
+ readonly type: "String";
211
+ readonly nativeType: "Text";
212
+ };
213
+ readonly authorName: {
214
+ readonly type: "String";
215
+ };
216
+ readonly authorEmail: {
217
+ readonly type: "String";
218
+ };
219
+ readonly authorRole: {
220
+ readonly type: "String";
221
+ readonly default: "\"client\"";
222
+ };
223
+ readonly clientId: {
224
+ readonly type: "String";
225
+ readonly isUnique: true;
226
+ };
227
+ readonly createdAt: {
228
+ readonly type: "DateTime";
229
+ readonly default: "now()";
230
+ };
231
+ };
232
+ readonly indexes: readonly [{
233
+ readonly fields: readonly ["feedbackId", "createdAt"];
234
+ }];
235
+ };
236
+ };
237
+ /** Map of Beezping models keyed by model name — frozen at runtime. */
238
+ export declare const BEEZPING_MODELS: typeof _BEEZPING_MODELS;
239
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { FeedbackRecord } from "./types.cjs";
2
+ /**
3
+ * `url` resolved against `base`, when the result is an http(s) URL. A
4
+ * record's `url` is client-supplied: without the scheme allowlist, a crafted
5
+ * feedback (`javascript:…`, `data:…`) would turn into a live link.
6
+ */
7
+ export declare function parseHttpUrl(url: string, base?: string): URL | null;
8
+ /**
9
+ * Link that opens a feedback's page with the widget focused on it —
10
+ * `?<param>=<id>`, read by the widget's `deepLink` option. Relative record
11
+ * URLs (the widget stores `location.pathname` by default) resolve against
12
+ * `base`. Null when there is no safe http(s) target.
13
+ */
14
+ export declare function buildDeepLink(record: Pick<FeedbackRecord, "id" | "url">, param: string, base?: string): string | null;
@@ -0,0 +1,14 @@
1
+ import type { FeedbackRecord } from "./types.js";
2
+ /**
3
+ * `url` resolved against `base`, when the result is an http(s) URL. A
4
+ * record's `url` is client-supplied: without the scheme allowlist, a crafted
5
+ * feedback (`javascript:…`, `data:…`) would turn into a live link.
6
+ */
7
+ export declare function parseHttpUrl(url: string, base?: string): URL | null;
8
+ /**
9
+ * Link that opens a feedback's page with the widget focused on it —
10
+ * `?<param>=<id>`, read by the widget's `deepLink` option. Relative record
11
+ * URLs (the widget stores `location.pathname` by default) resolve against
12
+ * `base`. Null when there is no safe http(s) target.
13
+ */
14
+ export declare function buildDeepLink(record: Pick<FeedbackRecord, "id" | "url">, param: string, base?: string): string | null;