@siteping/server 0.1.1 → 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/deep-link.d.cts +10 -0
- package/dist/deep-link.d.ts +10 -0
- package/dist/errors.d.cts +46 -16
- package/dist/errors.d.ts +46 -16
- package/dist/i18n.d.cts +14 -10
- package/dist/i18n.d.ts +14 -10
- package/dist/index.cjs +536 -259
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +156 -71
- package/dist/index.d.ts +156 -71
- package/dist/index.js +536 -259
- package/dist/index.js.map +1 -1
- package/dist/logger.d.cts +30 -0
- package/dist/logger.d.ts +30 -0
- package/dist/schema.d.cts +31 -0
- package/dist/schema.d.ts +31 -0
- package/dist/screenshot-storage.d.cts +14 -17
- package/dist/screenshot-storage.d.ts +14 -17
- package/dist/siteping-core.d.cts +8 -5
- package/dist/siteping-core.d.ts +8 -5
- package/dist/store-helpers.d.cts +13 -9
- package/dist/store-helpers.d.ts +13 -9
- package/dist/text.d.cts +28 -0
- package/dist/text.d.ts +28 -0
- package/dist/types.d.cts +114 -37
- package/dist/types.d.ts +114 -37
- package/dist/wire.d.cts +6 -1
- package/dist/wire.d.ts +6 -1
- package/openapi.json +1532 -0
- package/package.json +9 -7
package/README.md
CHANGED
package/dist/deep-link.d.cts
CHANGED
|
@@ -5,6 +5,16 @@ import type { FeedbackRecord } from "./types.cjs";
|
|
|
5
5
|
* feedback (`javascript:…`, `data:…`) would turn into a live link.
|
|
6
6
|
*/
|
|
7
7
|
export declare function parseHttpUrl(url: string, base?: string): URL | null;
|
|
8
|
+
/**
|
|
9
|
+
* Whether a screenshot URL is safe to render as an `<img src>`, in the
|
|
10
|
+
* widget's panel and the dashboard alike. A store can hold any string there
|
|
11
|
+
* (a direct store caller, a custom `ScreenshotStorage`, a migrated database):
|
|
12
|
+
* a `javascript:`, `data:text/html` or `data:image/svg+xml` URL — SVG can
|
|
13
|
+
* carry external `<image href>` references — or an arbitrary host would make
|
|
14
|
+
* the viewer fetch from it, leaking their IP and user agent. Browsers never
|
|
15
|
+
* run scripts from an `<img>`, but the fetch itself still happens.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isSafeImageUrl(url: string): boolean;
|
|
8
18
|
/**
|
|
9
19
|
* Link that opens a feedback's page with the widget focused on it —
|
|
10
20
|
* `?<param>=<id>`, read by the widget's `deepLink` option. Relative record
|
package/dist/deep-link.d.ts
CHANGED
|
@@ -5,6 +5,16 @@ import type { FeedbackRecord } from "./types.js";
|
|
|
5
5
|
* feedback (`javascript:…`, `data:…`) would turn into a live link.
|
|
6
6
|
*/
|
|
7
7
|
export declare function parseHttpUrl(url: string, base?: string): URL | null;
|
|
8
|
+
/**
|
|
9
|
+
* Whether a screenshot URL is safe to render as an `<img src>`, in the
|
|
10
|
+
* widget's panel and the dashboard alike. A store can hold any string there
|
|
11
|
+
* (a direct store caller, a custom `ScreenshotStorage`, a migrated database):
|
|
12
|
+
* a `javascript:`, `data:text/html` or `data:image/svg+xml` URL — SVG can
|
|
13
|
+
* carry external `<image href>` references — or an arbitrary host would make
|
|
14
|
+
* the viewer fetch from it, leaking their IP and user agent. Browsers never
|
|
15
|
+
* run scripts from an `<img>`, but the fetch itself still happens.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isSafeImageUrl(url: string): boolean;
|
|
8
18
|
/**
|
|
9
19
|
* Link that opens a feedback's page with the widget focused on it —
|
|
10
20
|
* `?<param>=<id>`, read by the widget's `deepLink` option. Relative record
|
package/dist/errors.d.cts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Typed error hierarchy for Siteping client/server boundaries.
|
|
3
3
|
*
|
|
4
|
-
* Consumers
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Consumers match an error with a guard — `isSitepingError`,
|
|
5
|
+
* `isSitepingConfigError`, a store guard such as `isStoreNotFound` — then
|
|
6
|
+
* read `code` / `retryable` instead of pattern-matching messages. The guards
|
|
7
|
+
* are structural, never `instanceof`: every published package bundles its
|
|
8
|
+
* own copy of these classes (tsup `noExternal`), so an error one package
|
|
9
|
+
* throws fails `instanceof` against another's class. The widget and the
|
|
10
|
+
* dashboard export the guard and the types, not the classes.
|
|
8
11
|
*
|
|
9
12
|
* Usage on the widget side (api-client.ts):
|
|
10
13
|
* - fetch failures / aborts / timeouts → `SitepingNetworkError` (retryable)
|
|
11
|
-
* - HTTP 4xx (except 401/403)
|
|
14
|
+
* - HTTP 4xx (except 401/403/408/429) → `SitepingValidationError` (not retryable)
|
|
12
15
|
* - HTTP 401 / 403 → `SitepingAuthError` (not retryable)
|
|
13
|
-
* -
|
|
16
|
+
* - HTTP 5xx / 408 / 429 → `SitepingError` code `"SERVER"` (retryable)
|
|
14
17
|
*
|
|
15
18
|
* Store mode (store-client.ts): a `createFeedback` that does not settle in
|
|
16
|
-
* time → `SitepingError` with code `"TIMEOUT"` (retryable)
|
|
19
|
+
* time → `SitepingError` with code `"TIMEOUT"` (retryable); a reply to a
|
|
20
|
+
* store that keeps no comments → `"SERVER"`, not retryable.
|
|
17
21
|
*
|
|
18
|
-
* `retryable`
|
|
19
|
-
* their own retry/queue/backoff
|
|
20
|
-
*
|
|
22
|
+
* `retryable` says whether the same request may succeed later, unchanged —
|
|
23
|
+
* meta information for host apps that wire their own retry/queue/backoff
|
|
24
|
+
* strategy; the widget already retries and queues transient failures itself.
|
|
21
25
|
*/
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
* literal value; the base class accepts a wider string so userland can
|
|
25
|
-
* extend the hierarchy without colliding with built-ins.
|
|
26
|
-
*/
|
|
27
|
-
export type SitepingErrorCode = "NETWORK" | "VALIDATION" | "AUTH" | "SERVER" | "TIMEOUT" | (string & {});
|
|
26
|
+
/** Discriminant string carried by every `SitepingError`. */
|
|
27
|
+
export type SitepingErrorCode = "NETWORK" | "VALIDATION" | "AUTH" | "SERVER" | "TIMEOUT";
|
|
28
28
|
export declare class SitepingError<TCode extends SitepingErrorCode = SitepingErrorCode> extends Error {
|
|
29
29
|
readonly code: TCode;
|
|
30
30
|
readonly retryable: boolean;
|
|
@@ -53,3 +53,33 @@ export declare class SitepingAuthError extends SitepingError<"AUTH"> {
|
|
|
53
53
|
readonly status: 401 | 403;
|
|
54
54
|
constructor(message: string, status: 401 | 403);
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Every error the widget and the dashboard report for a failed call, told
|
|
58
|
+
* apart by `code`: narrowing on it reaches a subclass's own fields, such as
|
|
59
|
+
* an `AUTH` error's `status`.
|
|
60
|
+
*/
|
|
61
|
+
export type SitepingClientError = SitepingNetworkError | SitepingValidationError | SitepingAuthError | SitepingError<"SERVER" | "TIMEOUT">;
|
|
62
|
+
/**
|
|
63
|
+
* Whether `error` is a `SitepingError` (any subclass) — matched on its
|
|
64
|
+
* fields, a known `code` and a boolean `retryable`, so it holds for an error
|
|
65
|
+
* another package's copy of the class threw. Anything else reaching an
|
|
66
|
+
* `onError` (a store's own error, a panel action's) fails it.
|
|
67
|
+
*/
|
|
68
|
+
export declare function isSitepingError(error: unknown): error is SitepingClientError;
|
|
69
|
+
/** Stable codes of the errors a handler factory throws for options it cannot run with. */
|
|
70
|
+
export type SitepingConfigErrorCode = "CONFIG_STORE_MISSING" | "CONFIG_MAX_BODY_BYTES_INVALID" | "CONFIG_OWNERSHIP_CHECK_MISSING" | "CONFIG_WEBHOOK_TIMEOUT_INVALID" | "CONFIG_API_KEY_REQUIRED";
|
|
71
|
+
/**
|
|
72
|
+
* Thrown by `createSitepingHandler` while it is created, never per request,
|
|
73
|
+
* when its options cannot run safely. The message says how to fix it; branch
|
|
74
|
+
* on `code`, after {@link isSitepingConfigError}.
|
|
75
|
+
*/
|
|
76
|
+
export declare class SitepingConfigError extends Error {
|
|
77
|
+
readonly code: SitepingConfigErrorCode;
|
|
78
|
+
constructor(code: SitepingConfigErrorCode, message: string);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether `error` is a `SitepingConfigError` — matched on its `name` and a
|
|
82
|
+
* `CONFIG_` code rather than `instanceof`, for the same cross-bundle reason
|
|
83
|
+
* as {@link isSitepingError}.
|
|
84
|
+
*/
|
|
85
|
+
export declare function isSitepingConfigError(error: unknown): error is SitepingConfigError;
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Typed error hierarchy for Siteping client/server boundaries.
|
|
3
3
|
*
|
|
4
|
-
* Consumers
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Consumers match an error with a guard — `isSitepingError`,
|
|
5
|
+
* `isSitepingConfigError`, a store guard such as `isStoreNotFound` — then
|
|
6
|
+
* read `code` / `retryable` instead of pattern-matching messages. The guards
|
|
7
|
+
* are structural, never `instanceof`: every published package bundles its
|
|
8
|
+
* own copy of these classes (tsup `noExternal`), so an error one package
|
|
9
|
+
* throws fails `instanceof` against another's class. The widget and the
|
|
10
|
+
* dashboard export the guard and the types, not the classes.
|
|
8
11
|
*
|
|
9
12
|
* Usage on the widget side (api-client.ts):
|
|
10
13
|
* - fetch failures / aborts / timeouts → `SitepingNetworkError` (retryable)
|
|
11
|
-
* - HTTP 4xx (except 401/403)
|
|
14
|
+
* - HTTP 4xx (except 401/403/408/429) → `SitepingValidationError` (not retryable)
|
|
12
15
|
* - HTTP 401 / 403 → `SitepingAuthError` (not retryable)
|
|
13
|
-
* -
|
|
16
|
+
* - HTTP 5xx / 408 / 429 → `SitepingError` code `"SERVER"` (retryable)
|
|
14
17
|
*
|
|
15
18
|
* Store mode (store-client.ts): a `createFeedback` that does not settle in
|
|
16
|
-
* time → `SitepingError` with code `"TIMEOUT"` (retryable)
|
|
19
|
+
* time → `SitepingError` with code `"TIMEOUT"` (retryable); a reply to a
|
|
20
|
+
* store that keeps no comments → `"SERVER"`, not retryable.
|
|
17
21
|
*
|
|
18
|
-
* `retryable`
|
|
19
|
-
* their own retry/queue/backoff
|
|
20
|
-
*
|
|
22
|
+
* `retryable` says whether the same request may succeed later, unchanged —
|
|
23
|
+
* meta information for host apps that wire their own retry/queue/backoff
|
|
24
|
+
* strategy; the widget already retries and queues transient failures itself.
|
|
21
25
|
*/
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
* literal value; the base class accepts a wider string so userland can
|
|
25
|
-
* extend the hierarchy without colliding with built-ins.
|
|
26
|
-
*/
|
|
27
|
-
export type SitepingErrorCode = "NETWORK" | "VALIDATION" | "AUTH" | "SERVER" | "TIMEOUT" | (string & {});
|
|
26
|
+
/** Discriminant string carried by every `SitepingError`. */
|
|
27
|
+
export type SitepingErrorCode = "NETWORK" | "VALIDATION" | "AUTH" | "SERVER" | "TIMEOUT";
|
|
28
28
|
export declare class SitepingError<TCode extends SitepingErrorCode = SitepingErrorCode> extends Error {
|
|
29
29
|
readonly code: TCode;
|
|
30
30
|
readonly retryable: boolean;
|
|
@@ -53,3 +53,33 @@ export declare class SitepingAuthError extends SitepingError<"AUTH"> {
|
|
|
53
53
|
readonly status: 401 | 403;
|
|
54
54
|
constructor(message: string, status: 401 | 403);
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Every error the widget and the dashboard report for a failed call, told
|
|
58
|
+
* apart by `code`: narrowing on it reaches a subclass's own fields, such as
|
|
59
|
+
* an `AUTH` error's `status`.
|
|
60
|
+
*/
|
|
61
|
+
export type SitepingClientError = SitepingNetworkError | SitepingValidationError | SitepingAuthError | SitepingError<"SERVER" | "TIMEOUT">;
|
|
62
|
+
/**
|
|
63
|
+
* Whether `error` is a `SitepingError` (any subclass) — matched on its
|
|
64
|
+
* fields, a known `code` and a boolean `retryable`, so it holds for an error
|
|
65
|
+
* another package's copy of the class threw. Anything else reaching an
|
|
66
|
+
* `onError` (a store's own error, a panel action's) fails it.
|
|
67
|
+
*/
|
|
68
|
+
export declare function isSitepingError(error: unknown): error is SitepingClientError;
|
|
69
|
+
/** Stable codes of the errors a handler factory throws for options it cannot run with. */
|
|
70
|
+
export type SitepingConfigErrorCode = "CONFIG_STORE_MISSING" | "CONFIG_MAX_BODY_BYTES_INVALID" | "CONFIG_OWNERSHIP_CHECK_MISSING" | "CONFIG_WEBHOOK_TIMEOUT_INVALID" | "CONFIG_API_KEY_REQUIRED";
|
|
71
|
+
/**
|
|
72
|
+
* Thrown by `createSitepingHandler` while it is created, never per request,
|
|
73
|
+
* when its options cannot run safely. The message says how to fix it; branch
|
|
74
|
+
* on `code`, after {@link isSitepingConfigError}.
|
|
75
|
+
*/
|
|
76
|
+
export declare class SitepingConfigError extends Error {
|
|
77
|
+
readonly code: SitepingConfigErrorCode;
|
|
78
|
+
constructor(code: SitepingConfigErrorCode, message: string);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether `error` is a `SitepingConfigError` — matched on its `name` and a
|
|
82
|
+
* `CONFIG_` code rather than `instanceof`, for the same cross-bundle reason
|
|
83
|
+
* as {@link isSitepingError}.
|
|
84
|
+
*/
|
|
85
|
+
export declare function isSitepingConfigError(error: unknown): error is SitepingConfigError;
|
package/dist/i18n.d.cts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* dictionary file) exists. Adding a locale cannot silently fall back to
|
|
13
13
|
* English anymore.
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import type { BuiltinLocale } from "./types.cjs";
|
|
16
16
|
/**
|
|
17
17
|
* Lazy dictionary loaders for every non-English built-in locale. Use static
|
|
18
18
|
* `() => import("./xx.cjs").then((m) => m.xx)` thunks — bundlers keep
|
|
@@ -26,7 +26,8 @@ export interface I18n<T> {
|
|
|
26
26
|
/**
|
|
27
27
|
* Create a translation function for the given locale.
|
|
28
28
|
*
|
|
29
|
-
* Locale resolution:
|
|
29
|
+
* Locale resolution, per key: `registerLocale` override > built-in
|
|
30
|
+
* dictionary of the language > English fallback.
|
|
30
31
|
* Non-English built-in locales are lazy-loaded via `loadLocale` — call
|
|
31
32
|
* `await loadLocale(locale)` at init if you want the UI to render in the
|
|
32
33
|
* target language immediately; until the dictionary lands, keys resolve
|
|
@@ -34,17 +35,20 @@ export interface I18n<T> {
|
|
|
34
35
|
*/
|
|
35
36
|
createT(locale: string): TranslateFunction<T>;
|
|
36
37
|
/**
|
|
37
|
-
* Dynamically import a built-in locale and register it. Returns the
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* partial custom dictionary comes back partial
|
|
38
|
+
* Dynamically import a built-in locale (once) and register it. Returns the
|
|
39
|
+
* locale as `createT` resolves it — the built-in dictionary with any
|
|
40
|
+
* `registerLocale` overrides on top — or `null` for a code that is neither
|
|
41
|
+
* built in nor registered. A custom code never hits a loader: it comes
|
|
42
|
+
* back as registered, so a partial custom dictionary comes back partial.
|
|
42
43
|
*/
|
|
43
44
|
loadLocale(locale: string): Promise<Partial<T> | null>;
|
|
44
45
|
/**
|
|
45
|
-
* Register
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Register translations at runtime, for a new locale or over a built-in
|
|
47
|
+
* one. Partial dictionaries are welcome: the keys given override the
|
|
48
|
+
* built-in dictionary (whenever it loads), every other key keeps its
|
|
49
|
+
* built-in value, then falls back to English — so overriding a single
|
|
50
|
+
* string never requires copying the whole catalog. Calls for the same
|
|
51
|
+
* code accumulate.
|
|
48
52
|
*/
|
|
49
53
|
registerLocale(code: string, translations: Partial<T>): void;
|
|
50
54
|
}
|
package/dist/i18n.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* dictionary file) exists. Adding a locale cannot silently fall back to
|
|
13
13
|
* English anymore.
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import type { BuiltinLocale } from "./types.js";
|
|
16
16
|
/**
|
|
17
17
|
* Lazy dictionary loaders for every non-English built-in locale. Use static
|
|
18
18
|
* `() => import("./xx.js").then((m) => m.xx)` thunks — bundlers keep
|
|
@@ -26,7 +26,8 @@ export interface I18n<T> {
|
|
|
26
26
|
/**
|
|
27
27
|
* Create a translation function for the given locale.
|
|
28
28
|
*
|
|
29
|
-
* Locale resolution:
|
|
29
|
+
* Locale resolution, per key: `registerLocale` override > built-in
|
|
30
|
+
* dictionary of the language > English fallback.
|
|
30
31
|
* Non-English built-in locales are lazy-loaded via `loadLocale` — call
|
|
31
32
|
* `await loadLocale(locale)` at init if you want the UI to render in the
|
|
32
33
|
* target language immediately; until the dictionary lands, keys resolve
|
|
@@ -34,17 +35,20 @@ export interface I18n<T> {
|
|
|
34
35
|
*/
|
|
35
36
|
createT(locale: string): TranslateFunction<T>;
|
|
36
37
|
/**
|
|
37
|
-
* Dynamically import a built-in locale and register it. Returns the
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* partial custom dictionary comes back partial
|
|
38
|
+
* Dynamically import a built-in locale (once) and register it. Returns the
|
|
39
|
+
* locale as `createT` resolves it — the built-in dictionary with any
|
|
40
|
+
* `registerLocale` overrides on top — or `null` for a code that is neither
|
|
41
|
+
* built in nor registered. A custom code never hits a loader: it comes
|
|
42
|
+
* back as registered, so a partial custom dictionary comes back partial.
|
|
42
43
|
*/
|
|
43
44
|
loadLocale(locale: string): Promise<Partial<T> | null>;
|
|
44
45
|
/**
|
|
45
|
-
* Register
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Register translations at runtime, for a new locale or over a built-in
|
|
47
|
+
* one. Partial dictionaries are welcome: the keys given override the
|
|
48
|
+
* built-in dictionary (whenever it loads), every other key keeps its
|
|
49
|
+
* built-in value, then falls back to English — so overriding a single
|
|
50
|
+
* string never requires copying the whole catalog. Calls for the same
|
|
51
|
+
* code accumulate.
|
|
48
52
|
*/
|
|
49
53
|
registerLocale(code: string, translations: Partial<T>): void;
|
|
50
54
|
}
|