@siteping/adapter-kit 0.1.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 +32 -0
- package/dist/chunk-YQHAD24P.js +97 -0
- package/dist/chunk-YQHAD24P.js.map +1 -0
- package/dist/errors.d.cts +41 -0
- package/dist/errors.d.ts +41 -0
- package/dist/filters.d.cts +33 -0
- package/dist/filters.d.ts +33 -0
- package/dist/i18n.d.cts +67 -0
- package/dist/i18n.d.ts +67 -0
- package/dist/index.cjs +256 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.cts +263 -0
- package/dist/schema.d.ts +263 -0
- package/dist/screenshot-storage.d.cts +61 -0
- package/dist/screenshot-storage.d.ts +61 -0
- package/dist/siteping-core-testing.d.cts +40 -0
- package/dist/siteping-core-testing.d.ts +40 -0
- package/dist/siteping-core.d.cts +16 -0
- package/dist/siteping-core.d.ts +16 -0
- package/dist/store-helpers.d.cts +87 -0
- package/dist/store-helpers.d.ts +87 -0
- package/dist/testing.cjs +484 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +1 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.js +433 -0
- package/dist/testing.js.map +1 -0
- package/dist/type-utils.d.cts +58 -0
- package/dist/type-utils.d.ts +58 -0
- package/dist/types.d.cts +840 -0
- package/dist/types.d.ts +840 -0
- package/dist/wire.d.cts +35 -0
- package/dist/wire.d.ts +35 -0
- package/package.json +77 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared conformance test suite for `SitepingStore` implementations.
|
|
3
|
+
*
|
|
4
|
+
* Adapters import this and run it with their store factory to verify they
|
|
5
|
+
* satisfy the full store contract — no need to write the same 40+ tests
|
|
6
|
+
* from scratch.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { testSitepingStore } from './siteping-core-testing.js'
|
|
11
|
+
* import { DrizzleStore } from '../src/index.js'
|
|
12
|
+
*
|
|
13
|
+
* testSitepingStore(() => new DrizzleStore(db))
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
import type { SitepingStore } from "./types.js";
|
|
17
|
+
/** Tuning knobs for backends whose documented contract legitimately varies. */
|
|
18
|
+
export interface StoreConformanceOptions {
|
|
19
|
+
/**
|
|
20
|
+
* How `createFeedback` reacts to a duplicate `clientId` — both are valid
|
|
21
|
+
* per the `SitepingStore` contract:
|
|
22
|
+
* - `"return"` (default): idempotently return the existing record.
|
|
23
|
+
* - `"throw"`: throw `StoreDuplicateError` (matched via `isStoreDuplicate`).
|
|
24
|
+
*/
|
|
25
|
+
duplicateBehavior?: "return" | "throw" | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Whether `search` matches case-insensitively. Defaults to `true` (the
|
|
28
|
+
* in-memory pipeline's behavior). Set to `false` for SQL backends whose
|
|
29
|
+
* collation is case-sensitive — the suite then only asserts same-case
|
|
30
|
+
* substring matching.
|
|
31
|
+
*/
|
|
32
|
+
caseInsensitiveSearch?: boolean | undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Run the full `SitepingStore` conformance test suite.
|
|
36
|
+
*
|
|
37
|
+
* @param factory — called before each test to create a fresh, empty store instance. May be async.
|
|
38
|
+
* @param options — contract variations, see {@link StoreConformanceOptions}.
|
|
39
|
+
*/
|
|
40
|
+
export declare function testSitepingStore(factory: () => SitepingStore | Promise<SitepingStore>, options?: StoreConformanceOptions): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type { SitepingErrorCode } from "./errors.cjs";
|
|
2
|
+
export { SitepingAuthError, SitepingError, SitepingNetworkError, SitepingValidationError } from "./errors.cjs";
|
|
3
|
+
export type { FilterResult } from "./filters.cjs";
|
|
4
|
+
export { applyFeedbackFilters } from "./filters.cjs";
|
|
5
|
+
export type { I18n, LocaleLoaders, TranslateFunction } from "./i18n.cjs";
|
|
6
|
+
export { createI18n, interpolate, tWithParams } from "./i18n.cjs";
|
|
7
|
+
export type { FieldDef, IndexDef, ModelDef, PrismaNativeType, PrismaScalarType, RelationDef, RelationKind, RelationOnDelete, SitepingModelFieldName, SitepingModelName, } from "./schema.cjs";
|
|
8
|
+
export { isRelationField, isScalarField, SITEPING_MODELS } from "./schema.cjs";
|
|
9
|
+
export type { ScreenshotStorage } from "./screenshot-storage.cjs";
|
|
10
|
+
export type { CollectionStore, CollectionStoreBackend } from "./store-helpers.cjs";
|
|
11
|
+
export { buildAnnotationRecord, buildFeedbackRecord, createCollectionStore } from "./store-helpers.cjs";
|
|
12
|
+
export type { AssertEqual, IfEquals, Prettify, Serialized } from "./type-utils.cjs";
|
|
13
|
+
export { hasOwn, isRecord } from "./type-utils.cjs";
|
|
14
|
+
export type { AnchorData, AnnotationCreateInput, AnnotationPayload, AnnotationRecord, AnnotationResponse, BuiltinLocale, ClosedFeedbackStatus, ConsoleDiagnosticEntry, ConsoleDiagnosticLevel, DiagnosticsCaptureOptions, DiagnosticsSnapshot, FeedbackCreateInput, FeedbackPage, FeedbackPayload, FeedbackQuery, FeedbackRecord, FeedbackResponse, FeedbackResponseList, FeedbackStatus, FeedbackType, FeedbackUpdateInput, NetworkDiagnosticEntry, OpenFeedbackStatus, PageScope, RectData, ScreenshotRegion, SitepingBaseConfig, SitepingConfig, SitepingDeepLinkOptions, SitepingHeadersOption, SitepingHttpConfig, SitepingIdentity, SitepingInstance, SitepingLocale, SitepingPosition, SitepingPublicEventListener, SitepingPublicEvents, SitepingSkipReason, SitepingStore, SitepingStoreConfig, SitepingTheme, SitepingUnsubscribe, } from "./types.cjs";
|
|
15
|
+
export { BUILTIN_LOCALES, CLOSED_FEEDBACK_STATUSES, CONSOLE_DIAGNOSTIC_LEVELS, FEEDBACK_STATUSES, FEEDBACK_TYPES, flattenAnnotation, isClosedStatus, isStoreDuplicate, isStoreNotFound, isStorePersistence, OPEN_FEEDBACK_STATUSES, StoreDuplicateError, StoreNotFoundError, StorePersistenceError, toFeedbackUpdate, } from "./types.cjs";
|
|
16
|
+
export { errorFromResponse, feedbackQueryToSearchParams, networkErrorFromException } from "./wire.cjs";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type { SitepingErrorCode } from "./errors.js";
|
|
2
|
+
export { SitepingAuthError, SitepingError, SitepingNetworkError, SitepingValidationError } from "./errors.js";
|
|
3
|
+
export type { FilterResult } from "./filters.js";
|
|
4
|
+
export { applyFeedbackFilters } from "./filters.js";
|
|
5
|
+
export type { I18n, LocaleLoaders, TranslateFunction } from "./i18n.js";
|
|
6
|
+
export { createI18n, interpolate, tWithParams } from "./i18n.js";
|
|
7
|
+
export type { FieldDef, IndexDef, ModelDef, PrismaNativeType, PrismaScalarType, RelationDef, RelationKind, RelationOnDelete, SitepingModelFieldName, SitepingModelName, } from "./schema.js";
|
|
8
|
+
export { isRelationField, isScalarField, SITEPING_MODELS } from "./schema.js";
|
|
9
|
+
export type { ScreenshotStorage } from "./screenshot-storage.js";
|
|
10
|
+
export type { CollectionStore, CollectionStoreBackend } from "./store-helpers.js";
|
|
11
|
+
export { buildAnnotationRecord, buildFeedbackRecord, createCollectionStore } from "./store-helpers.js";
|
|
12
|
+
export type { AssertEqual, IfEquals, Prettify, Serialized } from "./type-utils.js";
|
|
13
|
+
export { hasOwn, isRecord } from "./type-utils.js";
|
|
14
|
+
export type { AnchorData, AnnotationCreateInput, AnnotationPayload, AnnotationRecord, AnnotationResponse, BuiltinLocale, ClosedFeedbackStatus, ConsoleDiagnosticEntry, ConsoleDiagnosticLevel, DiagnosticsCaptureOptions, DiagnosticsSnapshot, FeedbackCreateInput, FeedbackPage, FeedbackPayload, FeedbackQuery, FeedbackRecord, FeedbackResponse, FeedbackResponseList, FeedbackStatus, FeedbackType, FeedbackUpdateInput, NetworkDiagnosticEntry, OpenFeedbackStatus, PageScope, RectData, ScreenshotRegion, SitepingBaseConfig, SitepingConfig, SitepingDeepLinkOptions, SitepingHeadersOption, SitepingHttpConfig, SitepingIdentity, SitepingInstance, SitepingLocale, SitepingPosition, SitepingPublicEventListener, SitepingPublicEvents, SitepingSkipReason, SitepingStore, SitepingStoreConfig, SitepingTheme, SitepingUnsubscribe, } from "./types.js";
|
|
15
|
+
export { BUILTIN_LOCALES, CLOSED_FEEDBACK_STATUSES, CONSOLE_DIAGNOSTIC_LEVELS, FEEDBACK_STATUSES, FEEDBACK_TYPES, flattenAnnotation, isClosedStatus, isStoreDuplicate, isStoreNotFound, isStorePersistence, OPEN_FEEDBACK_STATUSES, StoreDuplicateError, StoreNotFoundError, StorePersistenceError, toFeedbackUpdate, } from "./types.js";
|
|
16
|
+
export { errorFromResponse, feedbackQueryToSearchParams, networkErrorFromException } from "./wire.js";
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record-construction helpers and the collection-store engine.
|
|
3
|
+
*
|
|
4
|
+
* Every snapshot-style adapter (memory, localStorage, flat file, KV, …)
|
|
5
|
+
* needs the same three ingredients: turn a `FeedbackCreateInput` into a
|
|
6
|
+
* `FeedbackRecord` (null-normalizing optional fields, stamping ids and
|
|
7
|
+
* timestamps), filter/paginate with `applyFeedbackFilters`, and implement
|
|
8
|
+
* the dedup/update/delete choreography of the `SitepingStore` contract.
|
|
9
|
+
*
|
|
10
|
+
* `buildFeedbackRecord` / `buildAnnotationRecord` cover the first part for
|
|
11
|
+
* any adapter. `createCollectionStore` covers all of it: give it `load`,
|
|
12
|
+
* `persist`, and `generateId`, and it returns a fully conformant
|
|
13
|
+
* `SitepingStore` — writing a new snapshot adapter is ~20 lines plus its
|
|
14
|
+
* storage specifics.
|
|
15
|
+
*/
|
|
16
|
+
import type { AnnotationCreateInput, AnnotationRecord, FeedbackCreateInput, FeedbackRecord, SitepingStore } from "./types.cjs";
|
|
17
|
+
/**
|
|
18
|
+
* Build a persisted `AnnotationRecord` from its create input — normalizes
|
|
19
|
+
* the optional anchor fields to `null` and stamps identity/timestamp.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildAnnotationRecord(input: AnnotationCreateInput, ctx: {
|
|
22
|
+
id: string;
|
|
23
|
+
feedbackId: string;
|
|
24
|
+
now: Date;
|
|
25
|
+
}): AnnotationRecord;
|
|
26
|
+
/**
|
|
27
|
+
* Build a persisted `FeedbackRecord` (with its annotations) from a create
|
|
28
|
+
* input — normalizes every optional field to `null` and stamps ids and
|
|
29
|
+
* timestamps. Adapters without external screenshot storage keep the data
|
|
30
|
+
* URL inline on `screenshotUrl`, which is what this helper does; adapters
|
|
31
|
+
* with a `ScreenshotStorage` upload first and override `screenshotUrl`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildFeedbackRecord(input: FeedbackCreateInput, ctx: {
|
|
34
|
+
id: string;
|
|
35
|
+
annotationId: () => string;
|
|
36
|
+
now?: Date;
|
|
37
|
+
}): FeedbackRecord;
|
|
38
|
+
/**
|
|
39
|
+
* Storage primitives behind a collection store. `load`/`persist` may be
|
|
40
|
+
* sync or async — the engine awaits both, so in-memory arrays, localStorage
|
|
41
|
+
* and async KV stores all fit the same three functions.
|
|
42
|
+
*/
|
|
43
|
+
export interface CollectionStoreBackend {
|
|
44
|
+
/** Return the current full snapshot of feedback records. */
|
|
45
|
+
load(): FeedbackRecord[] | Promise<FeedbackRecord[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Persist the full snapshot. Throw `StorePersistenceError` when the write
|
|
48
|
+
* is lost (quota, storage disabled, …) — never swallow the failure.
|
|
49
|
+
*/
|
|
50
|
+
persist(feedbacks: FeedbackRecord[]): void | Promise<void>;
|
|
51
|
+
/** Generate a unique id for a new feedback or annotation record. */
|
|
52
|
+
generateId(): string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A `SitepingStore` with the optional `verifyProjectOwnership` guaranteed —
|
|
56
|
+
* what `createCollectionStore` returns.
|
|
57
|
+
*/
|
|
58
|
+
export type CollectionStore = SitepingStore & Required<Pick<SitepingStore, "verifyProjectOwnership">>;
|
|
59
|
+
/**
|
|
60
|
+
* Build a fully conformant `SitepingStore` on top of a snapshot backend.
|
|
61
|
+
*
|
|
62
|
+
* The engine implements the whole store contract: clientId dedup (idempotent
|
|
63
|
+
* create), newest-first ordering, the standard filter/pagination pipeline,
|
|
64
|
+
* `StoreNotFoundError` on missing update/delete, project-scoped bulk delete,
|
|
65
|
+
* and `verifyProjectOwnership`. When `persist` fails during `createFeedback`
|
|
66
|
+
* and the record carries an inline screenshot, the engine retries once
|
|
67
|
+
* without the screenshot (by far the heaviest field) so the text feedback
|
|
68
|
+
* survives a storage-quota hit; if that also fails, the error propagates —
|
|
69
|
+
* returning the record would claim a success that was never persisted.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* export class MemoryStore implements SitepingStore {
|
|
74
|
+
* private feedbacks: FeedbackRecord[] = [];
|
|
75
|
+
* private readonly store = createCollectionStore({
|
|
76
|
+
* load: () => this.feedbacks,
|
|
77
|
+
* persist: (next) => {
|
|
78
|
+
* this.feedbacks = next;
|
|
79
|
+
* },
|
|
80
|
+
* generateId: () => crypto.randomUUID(),
|
|
81
|
+
* });
|
|
82
|
+
* createFeedback = this.store.createFeedback;
|
|
83
|
+
* // …delegate the remaining methods the same way
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function createCollectionStore(backend: CollectionStoreBackend): CollectionStore;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record-construction helpers and the collection-store engine.
|
|
3
|
+
*
|
|
4
|
+
* Every snapshot-style adapter (memory, localStorage, flat file, KV, …)
|
|
5
|
+
* needs the same three ingredients: turn a `FeedbackCreateInput` into a
|
|
6
|
+
* `FeedbackRecord` (null-normalizing optional fields, stamping ids and
|
|
7
|
+
* timestamps), filter/paginate with `applyFeedbackFilters`, and implement
|
|
8
|
+
* the dedup/update/delete choreography of the `SitepingStore` contract.
|
|
9
|
+
*
|
|
10
|
+
* `buildFeedbackRecord` / `buildAnnotationRecord` cover the first part for
|
|
11
|
+
* any adapter. `createCollectionStore` covers all of it: give it `load`,
|
|
12
|
+
* `persist`, and `generateId`, and it returns a fully conformant
|
|
13
|
+
* `SitepingStore` — writing a new snapshot adapter is ~20 lines plus its
|
|
14
|
+
* storage specifics.
|
|
15
|
+
*/
|
|
16
|
+
import type { AnnotationCreateInput, AnnotationRecord, FeedbackCreateInput, FeedbackRecord, SitepingStore } from "./types.js";
|
|
17
|
+
/**
|
|
18
|
+
* Build a persisted `AnnotationRecord` from its create input — normalizes
|
|
19
|
+
* the optional anchor fields to `null` and stamps identity/timestamp.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildAnnotationRecord(input: AnnotationCreateInput, ctx: {
|
|
22
|
+
id: string;
|
|
23
|
+
feedbackId: string;
|
|
24
|
+
now: Date;
|
|
25
|
+
}): AnnotationRecord;
|
|
26
|
+
/**
|
|
27
|
+
* Build a persisted `FeedbackRecord` (with its annotations) from a create
|
|
28
|
+
* input — normalizes every optional field to `null` and stamps ids and
|
|
29
|
+
* timestamps. Adapters without external screenshot storage keep the data
|
|
30
|
+
* URL inline on `screenshotUrl`, which is what this helper does; adapters
|
|
31
|
+
* with a `ScreenshotStorage` upload first and override `screenshotUrl`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildFeedbackRecord(input: FeedbackCreateInput, ctx: {
|
|
34
|
+
id: string;
|
|
35
|
+
annotationId: () => string;
|
|
36
|
+
now?: Date;
|
|
37
|
+
}): FeedbackRecord;
|
|
38
|
+
/**
|
|
39
|
+
* Storage primitives behind a collection store. `load`/`persist` may be
|
|
40
|
+
* sync or async — the engine awaits both, so in-memory arrays, localStorage
|
|
41
|
+
* and async KV stores all fit the same three functions.
|
|
42
|
+
*/
|
|
43
|
+
export interface CollectionStoreBackend {
|
|
44
|
+
/** Return the current full snapshot of feedback records. */
|
|
45
|
+
load(): FeedbackRecord[] | Promise<FeedbackRecord[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Persist the full snapshot. Throw `StorePersistenceError` when the write
|
|
48
|
+
* is lost (quota, storage disabled, …) — never swallow the failure.
|
|
49
|
+
*/
|
|
50
|
+
persist(feedbacks: FeedbackRecord[]): void | Promise<void>;
|
|
51
|
+
/** Generate a unique id for a new feedback or annotation record. */
|
|
52
|
+
generateId(): string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A `SitepingStore` with the optional `verifyProjectOwnership` guaranteed —
|
|
56
|
+
* what `createCollectionStore` returns.
|
|
57
|
+
*/
|
|
58
|
+
export type CollectionStore = SitepingStore & Required<Pick<SitepingStore, "verifyProjectOwnership">>;
|
|
59
|
+
/**
|
|
60
|
+
* Build a fully conformant `SitepingStore` on top of a snapshot backend.
|
|
61
|
+
*
|
|
62
|
+
* The engine implements the whole store contract: clientId dedup (idempotent
|
|
63
|
+
* create), newest-first ordering, the standard filter/pagination pipeline,
|
|
64
|
+
* `StoreNotFoundError` on missing update/delete, project-scoped bulk delete,
|
|
65
|
+
* and `verifyProjectOwnership`. When `persist` fails during `createFeedback`
|
|
66
|
+
* and the record carries an inline screenshot, the engine retries once
|
|
67
|
+
* without the screenshot (by far the heaviest field) so the text feedback
|
|
68
|
+
* survives a storage-quota hit; if that also fails, the error propagates —
|
|
69
|
+
* returning the record would claim a success that was never persisted.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* export class MemoryStore implements SitepingStore {
|
|
74
|
+
* private feedbacks: FeedbackRecord[] = [];
|
|
75
|
+
* private readonly store = createCollectionStore({
|
|
76
|
+
* load: () => this.feedbacks,
|
|
77
|
+
* persist: (next) => {
|
|
78
|
+
* this.feedbacks = next;
|
|
79
|
+
* },
|
|
80
|
+
* generateId: () => crypto.randomUUID(),
|
|
81
|
+
* });
|
|
82
|
+
* createFeedback = this.store.createFeedback;
|
|
83
|
+
* // …delegate the remaining methods the same way
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function createCollectionStore(backend: CollectionStoreBackend): CollectionStore;
|