@shipeasy/sdk 3.0.1 → 4.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 +52 -0
- package/dist/client/index.d.mts +165 -7
- package/dist/client/index.d.ts +165 -7
- package/dist/client/index.js +396 -51
- package/dist/client/index.mjs +393 -51
- package/dist/server/index.d.mts +130 -2
- package/dist/server/index.d.ts +130 -2
- package/dist/server/index.js +312 -2
- package/dist/server/index.mjs +311 -2
- package/package.json +1 -1
package/dist/server/index.d.mts
CHANGED
|
@@ -1,4 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
type SeeExtras = Record<string, string | number | boolean | null | undefined>;
|
|
2
|
+
type SeeKind = "caught" | "uncaught" | "unhandled_rejection" | "network" | "violation";
|
|
3
|
+
/** Built by `causesThe(subject).to(outcome)` — never constructed by hand. */
|
|
4
|
+
interface Consequence {
|
|
5
|
+
readonly __seConsequence: true;
|
|
6
|
+
readonly subject: string;
|
|
7
|
+
readonly outcome: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Non-exception problem, built by `violation(name)`. A plain branded object
|
|
11
|
+
* (not an Error subclass) so `.message()` can be a builder method without
|
|
12
|
+
* colliding with `Error.prototype.message`.
|
|
13
|
+
*/
|
|
14
|
+
interface Violation {
|
|
15
|
+
readonly __seViolation: true;
|
|
16
|
+
readonly violationName: string;
|
|
17
|
+
readonly violationMessage?: string;
|
|
18
|
+
/** Attach free-form detail. Variable data goes HERE (or in extras), never in the name. */
|
|
19
|
+
message(msg: string): Violation;
|
|
20
|
+
}
|
|
21
|
+
/** Wire shape — the `type:"error"` RawEvent variant accepted by POST /collect. */
|
|
22
|
+
interface SeeErrorEvent {
|
|
23
|
+
type: "error";
|
|
24
|
+
kind: SeeKind;
|
|
25
|
+
/** Error class/name (e.g. "TypeError") or the violation name. */
|
|
26
|
+
error_type: string;
|
|
27
|
+
message: string;
|
|
28
|
+
stack?: string;
|
|
29
|
+
/** Consequence: "<error_type> causes the <subject> to <outcome>". */
|
|
30
|
+
subject: string;
|
|
31
|
+
outcome: string;
|
|
32
|
+
extras?: Record<string, string | number | boolean>;
|
|
33
|
+
url?: string;
|
|
34
|
+
user_id?: string;
|
|
35
|
+
anonymous_id?: string;
|
|
36
|
+
side: "client" | "server";
|
|
37
|
+
env?: string;
|
|
38
|
+
sdk_version: string;
|
|
39
|
+
ts: number;
|
|
40
|
+
}
|
|
41
|
+
interface SeeExtrasTail {
|
|
42
|
+
/** Attach debugging metadata. Callable repeatedly — keys merge, later wins. */
|
|
43
|
+
extras(extras: SeeExtras): SeeExtrasTail;
|
|
44
|
+
}
|
|
45
|
+
interface SeeOutcomeStep {
|
|
46
|
+
/** The user-visible impact: `.causes_the("checkout").to("use cached prices")`. */
|
|
47
|
+
to(outcome: string): SeeExtrasTail;
|
|
48
|
+
}
|
|
49
|
+
interface SeeChain {
|
|
50
|
+
/** Start the consequence sentence — the product surface affected. */
|
|
51
|
+
causes_the(subject: string): SeeOutcomeStep;
|
|
52
|
+
/** camelCase alias of {@link SeeChain.causes_the}. */
|
|
53
|
+
causesThe(subject: string): SeeOutcomeStep;
|
|
54
|
+
}
|
|
55
|
+
interface SeeViolationChain extends SeeChain {
|
|
56
|
+
/** Free-form detail. Variable data goes here (or extras), never in the name. */
|
|
57
|
+
message(msg: string): SeeViolationChain;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare const version = "4.0.0";
|
|
2
61
|
interface User {
|
|
3
62
|
user_id?: string;
|
|
4
63
|
anonymous_id?: string;
|
|
@@ -51,11 +110,24 @@ interface FlagsClientOptions {
|
|
|
51
110
|
* for tests; production callers should rely on init()/initOnce().
|
|
52
111
|
*/
|
|
53
112
|
initialBlob?: FlagsBlob;
|
|
113
|
+
/**
|
|
114
|
+
* Per-evaluation usage telemetry. ON by default — each getFlag/getConfig/
|
|
115
|
+
* getExperiment/getKillswitch (and the per-key evaluate() loop) fires one
|
|
116
|
+
* fire-and-forget beacon counted by Cloudflare's native per-path analytics.
|
|
117
|
+
* Pass `true` to disable. NOTE: on Cloudflare Workers each beacon is an
|
|
118
|
+
* outbound subrequest (cap 50 free / 1000 paid per invocation), so disable
|
|
119
|
+
* this on hot request paths that evaluate many flags per request.
|
|
120
|
+
*/
|
|
121
|
+
disableTelemetry?: boolean;
|
|
122
|
+
/** Override the telemetry beacon host. Defaults to {@link DEFAULT_TELEMETRY_URL}. */
|
|
123
|
+
telemetryUrl?: string;
|
|
54
124
|
}
|
|
55
125
|
declare class FlagsClient {
|
|
56
126
|
private readonly apiKey;
|
|
57
127
|
private readonly baseUrl;
|
|
58
128
|
private readonly env;
|
|
129
|
+
private readonly telemetry;
|
|
130
|
+
private readonly seeLimiter;
|
|
59
131
|
private flagsBlob;
|
|
60
132
|
private expsBlob;
|
|
61
133
|
private flagsEtag;
|
|
@@ -75,6 +147,12 @@ declare class FlagsClient {
|
|
|
75
147
|
getConfig<T = unknown>(name: string, decode?: (raw: unknown) => T): T | undefined;
|
|
76
148
|
getExperiment<P extends Record<string, unknown>>(name: string, user: User, defaultParams: P, decode?: (raw: unknown) => P): ExperimentResult<P>;
|
|
77
149
|
track(userId: string, eventName: string, props?: Record<string, unknown>): void;
|
|
150
|
+
/**
|
|
151
|
+
* Report a structured error into the errors primitive. Fire-and-forget —
|
|
152
|
+
* never blocks or throws into the request path. Spam-guarded by a 30s
|
|
153
|
+
* dedup window + per-process cap.
|
|
154
|
+
*/
|
|
155
|
+
reportError(problem: unknown, consequence: Consequence, extras?: SeeExtras, kind?: SeeKind): void;
|
|
78
156
|
/**
|
|
79
157
|
* Evaluate all flags, configs, and experiments for a user against the locally
|
|
80
158
|
* cached blob (no network call). Applies ?se_ks_* / ?se_cf_* / ?se_exp_*
|
|
@@ -147,6 +225,12 @@ interface ShipeasyServerConfig {
|
|
|
147
225
|
user?: User;
|
|
148
226
|
/** i18n profile to load for SSR translations, e.g. "en:prod". Defaults to "en:prod". */
|
|
149
227
|
i18nDefaultProfile?: string;
|
|
228
|
+
/**
|
|
229
|
+
* Disable per-evaluation usage telemetry. ON by default. On Cloudflare
|
|
230
|
+
* Workers each beacon is an outbound subrequest, so disable on hot SSR paths
|
|
231
|
+
* that evaluate many flags per request. See {@link FlagsClientOptions.disableTelemetry}.
|
|
232
|
+
*/
|
|
233
|
+
disableTelemetry?: boolean;
|
|
150
234
|
}
|
|
151
235
|
interface ShipeasyServerHandle {
|
|
152
236
|
flags: Record<string, boolean>;
|
|
@@ -211,5 +295,49 @@ declare const flags: {
|
|
|
211
295
|
*/
|
|
212
296
|
evaluate(user: User, rawUrl?: string): BootstrapPayload;
|
|
213
297
|
};
|
|
298
|
+
interface SeeApi {
|
|
299
|
+
/**
|
|
300
|
+
* Report a handled problem and its product consequence:
|
|
301
|
+
*
|
|
302
|
+
* ```ts
|
|
303
|
+
* import { see } from "@shipeasy/sdk/server";
|
|
304
|
+
*
|
|
305
|
+
* try {
|
|
306
|
+
* await chargeCard(order);
|
|
307
|
+
* } catch (e) {
|
|
308
|
+
* see(e).causes_the("payment").to("use the backup processor").extras({ order_id: order.id });
|
|
309
|
+
* await chargeViaBackup(order);
|
|
310
|
+
* }
|
|
311
|
+
* ```
|
|
312
|
+
*
|
|
313
|
+
* The chain dispatches on the next microtask — fire-and-forget into the
|
|
314
|
+
* errors primitive (grouped by fingerprint, near-real-time timeseries).
|
|
315
|
+
* If you don't know the consequence of an exception, don't catch it.
|
|
316
|
+
*/
|
|
317
|
+
(problem: unknown): SeeChain;
|
|
318
|
+
/**
|
|
319
|
+
* Report a non-exception problem. Prefer passing a caught Error to `see()`
|
|
320
|
+
* when one exists. The name is a stable identifier (it participates in the
|
|
321
|
+
* issue fingerprint) — variable data goes in `.message()` or `.extras()`.
|
|
322
|
+
*
|
|
323
|
+
* ```ts
|
|
324
|
+
* if (results.length > LIMIT) {
|
|
325
|
+
* see.Violation("large query").causes_the("search results").to("be trimmed");
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
Violation(name: string): SeeViolationChain;
|
|
330
|
+
/**
|
|
331
|
+
* Mark an exception as expected control flow — documents the expectation and
|
|
332
|
+
* reports nothing. The reason must start with "because".
|
|
333
|
+
*/
|
|
334
|
+
ControlFlowException(err: unknown, because: string): void;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Structured error reporter — the whole grammar hangs off this one import.
|
|
338
|
+
* Safe to import anywhere; a call before `shipeasy({ serverKey })` warns and
|
|
339
|
+
* drops (never throws).
|
|
340
|
+
*/
|
|
341
|
+
declare const see: SeeApi;
|
|
214
342
|
|
|
215
|
-
export { type BootstrapHtmlOptions, type BootstrapPayload, type ExperimentResult, type FetchLabelsOptions, FlagsClient, type FlagsClientEnv, type FlagsClientOptions, type I18nForRequest, type LabelFile, type ShipeasyServerConfig, type ShipeasyServerHandle, type User, _resetShipeasyServerForTests, configureShipeasyServer, fetchLabelsForSSR, flags, getBootstrapHtml, getShipeasyServerClient, i18n, shipeasy, version };
|
|
343
|
+
export { type BootstrapHtmlOptions, type BootstrapPayload, type Consequence, type ExperimentResult, type FetchLabelsOptions, FlagsClient, type FlagsClientEnv, type FlagsClientOptions, type I18nForRequest, type LabelFile, type SeeApi, type SeeChain, type SeeErrorEvent, type SeeExtras, type SeeKind, type SeeViolationChain, type ShipeasyServerConfig, type ShipeasyServerHandle, type User, type Violation, _resetShipeasyServerForTests, configureShipeasyServer, fetchLabelsForSSR, flags, getBootstrapHtml, getShipeasyServerClient, i18n, see, shipeasy, version };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
type SeeExtras = Record<string, string | number | boolean | null | undefined>;
|
|
2
|
+
type SeeKind = "caught" | "uncaught" | "unhandled_rejection" | "network" | "violation";
|
|
3
|
+
/** Built by `causesThe(subject).to(outcome)` — never constructed by hand. */
|
|
4
|
+
interface Consequence {
|
|
5
|
+
readonly __seConsequence: true;
|
|
6
|
+
readonly subject: string;
|
|
7
|
+
readonly outcome: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Non-exception problem, built by `violation(name)`. A plain branded object
|
|
11
|
+
* (not an Error subclass) so `.message()` can be a builder method without
|
|
12
|
+
* colliding with `Error.prototype.message`.
|
|
13
|
+
*/
|
|
14
|
+
interface Violation {
|
|
15
|
+
readonly __seViolation: true;
|
|
16
|
+
readonly violationName: string;
|
|
17
|
+
readonly violationMessage?: string;
|
|
18
|
+
/** Attach free-form detail. Variable data goes HERE (or in extras), never in the name. */
|
|
19
|
+
message(msg: string): Violation;
|
|
20
|
+
}
|
|
21
|
+
/** Wire shape — the `type:"error"` RawEvent variant accepted by POST /collect. */
|
|
22
|
+
interface SeeErrorEvent {
|
|
23
|
+
type: "error";
|
|
24
|
+
kind: SeeKind;
|
|
25
|
+
/** Error class/name (e.g. "TypeError") or the violation name. */
|
|
26
|
+
error_type: string;
|
|
27
|
+
message: string;
|
|
28
|
+
stack?: string;
|
|
29
|
+
/** Consequence: "<error_type> causes the <subject> to <outcome>". */
|
|
30
|
+
subject: string;
|
|
31
|
+
outcome: string;
|
|
32
|
+
extras?: Record<string, string | number | boolean>;
|
|
33
|
+
url?: string;
|
|
34
|
+
user_id?: string;
|
|
35
|
+
anonymous_id?: string;
|
|
36
|
+
side: "client" | "server";
|
|
37
|
+
env?: string;
|
|
38
|
+
sdk_version: string;
|
|
39
|
+
ts: number;
|
|
40
|
+
}
|
|
41
|
+
interface SeeExtrasTail {
|
|
42
|
+
/** Attach debugging metadata. Callable repeatedly — keys merge, later wins. */
|
|
43
|
+
extras(extras: SeeExtras): SeeExtrasTail;
|
|
44
|
+
}
|
|
45
|
+
interface SeeOutcomeStep {
|
|
46
|
+
/** The user-visible impact: `.causes_the("checkout").to("use cached prices")`. */
|
|
47
|
+
to(outcome: string): SeeExtrasTail;
|
|
48
|
+
}
|
|
49
|
+
interface SeeChain {
|
|
50
|
+
/** Start the consequence sentence — the product surface affected. */
|
|
51
|
+
causes_the(subject: string): SeeOutcomeStep;
|
|
52
|
+
/** camelCase alias of {@link SeeChain.causes_the}. */
|
|
53
|
+
causesThe(subject: string): SeeOutcomeStep;
|
|
54
|
+
}
|
|
55
|
+
interface SeeViolationChain extends SeeChain {
|
|
56
|
+
/** Free-form detail. Variable data goes here (or extras), never in the name. */
|
|
57
|
+
message(msg: string): SeeViolationChain;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare const version = "4.0.0";
|
|
2
61
|
interface User {
|
|
3
62
|
user_id?: string;
|
|
4
63
|
anonymous_id?: string;
|
|
@@ -51,11 +110,24 @@ interface FlagsClientOptions {
|
|
|
51
110
|
* for tests; production callers should rely on init()/initOnce().
|
|
52
111
|
*/
|
|
53
112
|
initialBlob?: FlagsBlob;
|
|
113
|
+
/**
|
|
114
|
+
* Per-evaluation usage telemetry. ON by default — each getFlag/getConfig/
|
|
115
|
+
* getExperiment/getKillswitch (and the per-key evaluate() loop) fires one
|
|
116
|
+
* fire-and-forget beacon counted by Cloudflare's native per-path analytics.
|
|
117
|
+
* Pass `true` to disable. NOTE: on Cloudflare Workers each beacon is an
|
|
118
|
+
* outbound subrequest (cap 50 free / 1000 paid per invocation), so disable
|
|
119
|
+
* this on hot request paths that evaluate many flags per request.
|
|
120
|
+
*/
|
|
121
|
+
disableTelemetry?: boolean;
|
|
122
|
+
/** Override the telemetry beacon host. Defaults to {@link DEFAULT_TELEMETRY_URL}. */
|
|
123
|
+
telemetryUrl?: string;
|
|
54
124
|
}
|
|
55
125
|
declare class FlagsClient {
|
|
56
126
|
private readonly apiKey;
|
|
57
127
|
private readonly baseUrl;
|
|
58
128
|
private readonly env;
|
|
129
|
+
private readonly telemetry;
|
|
130
|
+
private readonly seeLimiter;
|
|
59
131
|
private flagsBlob;
|
|
60
132
|
private expsBlob;
|
|
61
133
|
private flagsEtag;
|
|
@@ -75,6 +147,12 @@ declare class FlagsClient {
|
|
|
75
147
|
getConfig<T = unknown>(name: string, decode?: (raw: unknown) => T): T | undefined;
|
|
76
148
|
getExperiment<P extends Record<string, unknown>>(name: string, user: User, defaultParams: P, decode?: (raw: unknown) => P): ExperimentResult<P>;
|
|
77
149
|
track(userId: string, eventName: string, props?: Record<string, unknown>): void;
|
|
150
|
+
/**
|
|
151
|
+
* Report a structured error into the errors primitive. Fire-and-forget —
|
|
152
|
+
* never blocks or throws into the request path. Spam-guarded by a 30s
|
|
153
|
+
* dedup window + per-process cap.
|
|
154
|
+
*/
|
|
155
|
+
reportError(problem: unknown, consequence: Consequence, extras?: SeeExtras, kind?: SeeKind): void;
|
|
78
156
|
/**
|
|
79
157
|
* Evaluate all flags, configs, and experiments for a user against the locally
|
|
80
158
|
* cached blob (no network call). Applies ?se_ks_* / ?se_cf_* / ?se_exp_*
|
|
@@ -147,6 +225,12 @@ interface ShipeasyServerConfig {
|
|
|
147
225
|
user?: User;
|
|
148
226
|
/** i18n profile to load for SSR translations, e.g. "en:prod". Defaults to "en:prod". */
|
|
149
227
|
i18nDefaultProfile?: string;
|
|
228
|
+
/**
|
|
229
|
+
* Disable per-evaluation usage telemetry. ON by default. On Cloudflare
|
|
230
|
+
* Workers each beacon is an outbound subrequest, so disable on hot SSR paths
|
|
231
|
+
* that evaluate many flags per request. See {@link FlagsClientOptions.disableTelemetry}.
|
|
232
|
+
*/
|
|
233
|
+
disableTelemetry?: boolean;
|
|
150
234
|
}
|
|
151
235
|
interface ShipeasyServerHandle {
|
|
152
236
|
flags: Record<string, boolean>;
|
|
@@ -211,5 +295,49 @@ declare const flags: {
|
|
|
211
295
|
*/
|
|
212
296
|
evaluate(user: User, rawUrl?: string): BootstrapPayload;
|
|
213
297
|
};
|
|
298
|
+
interface SeeApi {
|
|
299
|
+
/**
|
|
300
|
+
* Report a handled problem and its product consequence:
|
|
301
|
+
*
|
|
302
|
+
* ```ts
|
|
303
|
+
* import { see } from "@shipeasy/sdk/server";
|
|
304
|
+
*
|
|
305
|
+
* try {
|
|
306
|
+
* await chargeCard(order);
|
|
307
|
+
* } catch (e) {
|
|
308
|
+
* see(e).causes_the("payment").to("use the backup processor").extras({ order_id: order.id });
|
|
309
|
+
* await chargeViaBackup(order);
|
|
310
|
+
* }
|
|
311
|
+
* ```
|
|
312
|
+
*
|
|
313
|
+
* The chain dispatches on the next microtask — fire-and-forget into the
|
|
314
|
+
* errors primitive (grouped by fingerprint, near-real-time timeseries).
|
|
315
|
+
* If you don't know the consequence of an exception, don't catch it.
|
|
316
|
+
*/
|
|
317
|
+
(problem: unknown): SeeChain;
|
|
318
|
+
/**
|
|
319
|
+
* Report a non-exception problem. Prefer passing a caught Error to `see()`
|
|
320
|
+
* when one exists. The name is a stable identifier (it participates in the
|
|
321
|
+
* issue fingerprint) — variable data goes in `.message()` or `.extras()`.
|
|
322
|
+
*
|
|
323
|
+
* ```ts
|
|
324
|
+
* if (results.length > LIMIT) {
|
|
325
|
+
* see.Violation("large query").causes_the("search results").to("be trimmed");
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
Violation(name: string): SeeViolationChain;
|
|
330
|
+
/**
|
|
331
|
+
* Mark an exception as expected control flow — documents the expectation and
|
|
332
|
+
* reports nothing. The reason must start with "because".
|
|
333
|
+
*/
|
|
334
|
+
ControlFlowException(err: unknown, because: string): void;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Structured error reporter — the whole grammar hangs off this one import.
|
|
338
|
+
* Safe to import anywhere; a call before `shipeasy({ serverKey })` warns and
|
|
339
|
+
* drops (never throws).
|
|
340
|
+
*/
|
|
341
|
+
declare const see: SeeApi;
|
|
214
342
|
|
|
215
|
-
export { type BootstrapHtmlOptions, type BootstrapPayload, type ExperimentResult, type FetchLabelsOptions, FlagsClient, type FlagsClientEnv, type FlagsClientOptions, type I18nForRequest, type LabelFile, type ShipeasyServerConfig, type ShipeasyServerHandle, type User, _resetShipeasyServerForTests, configureShipeasyServer, fetchLabelsForSSR, flags, getBootstrapHtml, getShipeasyServerClient, i18n, shipeasy, version };
|
|
343
|
+
export { type BootstrapHtmlOptions, type BootstrapPayload, type Consequence, type ExperimentResult, type FetchLabelsOptions, FlagsClient, type FlagsClientEnv, type FlagsClientOptions, type I18nForRequest, type LabelFile, type SeeApi, type SeeChain, type SeeErrorEvent, type SeeExtras, type SeeKind, type SeeViolationChain, type ShipeasyServerConfig, type ShipeasyServerHandle, type User, type Violation, _resetShipeasyServerForTests, configureShipeasyServer, fetchLabelsForSSR, flags, getBootstrapHtml, getShipeasyServerClient, i18n, see, shipeasy, version };
|