@cross-deck/node 1.13.0 → 1.14.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/CHANGELOG.md +4 -0
- package/dist/auto-events/index.d.mts +1 -1
- package/dist/auto-events/index.d.ts +1 -1
- package/dist/{crossdeck-server-CjnIok-o.d.mts → crossdeck-server-NL1p6hlR.d.mts} +35 -1
- package/dist/{crossdeck-server-CjnIok-o.d.ts → crossdeck-server-NL1p6hlR.d.ts} +35 -1
- package/dist/index.cjs +38 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +38 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.14.0] — 2026-07-27
|
|
10
|
+
|
|
11
|
+
- **`campaignLink()` — stamp an outbound email link so its click binds to the recipient's identity on landing.** You know the recipient's email at send time; pass it with the link's destination and Crossdeck returns the same URL carrying a one-time arrival ticket (`cd_ref`). Put the returned URL in the email (Resend, HubSpot, your own SMTP — any tool). When the recipient clicks and lands on a page running `@cross-deck/web`, the SDK reads the ticket automatically (v1.10.0+) and binds that session to the person, so the post-click journey joins their identity. Server-side only — it mints an identity bind, so it requires a secret key. Degrades honestly: without the web SDK on the landing page the deep session stitch softens, but the server-side email funnel still lands by identity. Wraps `POST /v1/campaign/email-link`.
|
|
12
|
+
|
|
9
13
|
## [1.13.0] — 2026-07-26
|
|
10
14
|
|
|
11
15
|
- **Crossdeck Trust — the gate now carries the browser's human-proof token.** `GateInput` gains an optional `token`: pass the attestation minted by the Crossdeck Trust panel in the browser (`Crossdeck.trust.panel(...)` / `<CrossdeckTrust>` in `@cross-deck/web`) and `gate()` forwards it as `challengeToken` to `/v1/trust/gate`, completing the SDK-native round trip. A real browser carries one; a server-to-server bot has none — that absence is scored, and in strict mode (`requireHumanProof`) a tokenless + suspicious attempt is the confident block. Optional and fail-open: omitting it never blocks on its own, and `gate()` remains fail-open by contract (a glitch returns `{ action: "allow", degraded: true }`, never a throw or a false block).
|
|
@@ -654,6 +654,25 @@ interface AliasResult {
|
|
|
654
654
|
mergePending: boolean;
|
|
655
655
|
env: Environment;
|
|
656
656
|
}
|
|
657
|
+
/** Input to `campaignLink` — stamp an outbound email link with an identity-bind ticket. */
|
|
658
|
+
interface CampaignLinkInput {
|
|
659
|
+
/** The recipient's email address. The person is resolved from it once, at stamp time.
|
|
660
|
+
* Rides the request body only — never a URL/query (it is PII). */
|
|
661
|
+
email: string;
|
|
662
|
+
/** The absolute http(s) destination the recipient should land on. */
|
|
663
|
+
url: string;
|
|
664
|
+
/** Optional provenance for later enrichment (e.g. "resend", "hubspot"). Never required. */
|
|
665
|
+
rail?: string;
|
|
666
|
+
}
|
|
667
|
+
/** Result of `campaignLink` — the same destination with the arrival ticket appended. */
|
|
668
|
+
interface CampaignLinkResult {
|
|
669
|
+
object: "campaign_link";
|
|
670
|
+
/** The stamped URL to put in the email. Carries only an opaque `cd_ref` ticket. */
|
|
671
|
+
url: string;
|
|
672
|
+
/** How long the ticket stays live (a campaign's useful life). */
|
|
673
|
+
expiresInDays: number;
|
|
674
|
+
env: Environment;
|
|
675
|
+
}
|
|
657
676
|
interface IngestResponse {
|
|
658
677
|
object: "list";
|
|
659
678
|
received: number;
|
|
@@ -1578,6 +1597,21 @@ declare class CrossdeckServer extends EventEmitter {
|
|
|
1578
1597
|
identify(userId: string, anonymousId: string, options?: IdentifyOptions & RequestOptions): Promise<AliasResult>;
|
|
1579
1598
|
aliasIdentity(input: AliasIdentityInput, options?: RequestOptions): Promise<AliasResult>;
|
|
1580
1599
|
forget(hints: IdentityHints, options?: RequestOptions): Promise<ForgetResult>;
|
|
1600
|
+
/**
|
|
1601
|
+
* Stamp an outbound email link so its click binds to the recipient on landing.
|
|
1602
|
+
*
|
|
1603
|
+
* You know the recipient's email at send time; pass it with the link's destination
|
|
1604
|
+
* and Crossdeck returns the same URL carrying a one-time arrival ticket (`cd_ref`).
|
|
1605
|
+
* Put the returned URL in the email. When the recipient clicks and lands on a page
|
|
1606
|
+
* running `@cross-deck/web`, the SDK reads the ticket automatically and binds that
|
|
1607
|
+
* session to the person — the post-click journey then joins their identity.
|
|
1608
|
+
*
|
|
1609
|
+
* Rail-agnostic: works for Resend, HubSpot, your own SMTP, anything. Server-side
|
|
1610
|
+
* only (it mints an identity bind, so a secret key is required). If the landing page
|
|
1611
|
+
* has no Crossdeck web SDK, the deep session stitch softens but the server-side
|
|
1612
|
+
* email funnel (via the rail adapter) still lands by identity.
|
|
1613
|
+
*/
|
|
1614
|
+
campaignLink(input: CampaignLinkInput, options?: RequestOptions): Promise<CampaignLinkResult>;
|
|
1581
1615
|
/**
|
|
1582
1616
|
* Fetch a customer's entitlements from Crossdeck and warm the cache.
|
|
1583
1617
|
*
|
|
@@ -2128,4 +2162,4 @@ declare class CrossdeckServer extends EventEmitter {
|
|
|
2128
2162
|
private normalizeIngestEvent;
|
|
2129
2163
|
}
|
|
2130
2164
|
|
|
2131
|
-
export { type
|
|
2165
|
+
export { type IdentifyOptions as $, type AliasIdentityInput as A, type BlockVerdict as B, CROSSDECK_API_VERSION as C, type CrossdeckServerOptions as D, CrossdeckValidationError as E, DEFAULT_BASE_URL as F, DEFAULT_TIMEOUT_MS as G, type Diagnostics as H, type EntitlementCacheOptions as I, type EntitlementMutationResult as J, type EntitlementStore as K, type EntitlementsListResponse as L, type EntitlementsListener as M, type Environment as N, type ErrorCaptureConfig as O, type ErrorLevel as P, type EventProperties as Q, type ForgetResult as R, type GateInput as S, type GateVerdict as T, type GrantDuration as U, type GrantEntitlementInput as V, type GroupMembership as W, type HeartbeatResponse as X, type HttpRequestInfo as Y, type HttpResponseInfo as Z, type HttpRetriesConfig as _, type AliasResult as a, type IdentityHints as a0, type IngestOptions as a1, type IngestResponse as a2, type OwnerStatusInput as a3, type PublicEntitlement as a4, type PurchaseResult as a5, type RequestOptions as a6, type ResolveInput as a7, type ResolveResult as a8, type RevokeEntitlementInput as a9, type RuntimeHost as aa, type RuntimeInfo as ab, type ServerEvent as ac, type StackFrame as ad, type StoredEntitlements as ae, type SyncPurchaseInput as af, makeCrossdeckError as ag, type AuditDecision as b, type AuditEntry as c, type Breadcrumb as d, type BreadcrumbCategory as e, type BreadcrumbLevel as f, type CampaignLinkInput as g, type CampaignLinkResult as h, type CapturedError as i, type Contract as j, type ContractAppliesTo as k, type ContractFailureInput as l, type ContractPillar as m, type ContractStatus as n, type ContractTestRef as o, CrossdeckAuthenticationError as p, CrossdeckConfigurationError as q, CrossdeckContracts as r, CrossdeckError as s, type CrossdeckErrorPayload as t, type CrossdeckErrorType as u, CrossdeckInternalError as v, CrossdeckNetworkError as w, CrossdeckPermissionError as x, CrossdeckRateLimitError as y, CrossdeckServer as z };
|
|
@@ -654,6 +654,25 @@ interface AliasResult {
|
|
|
654
654
|
mergePending: boolean;
|
|
655
655
|
env: Environment;
|
|
656
656
|
}
|
|
657
|
+
/** Input to `campaignLink` — stamp an outbound email link with an identity-bind ticket. */
|
|
658
|
+
interface CampaignLinkInput {
|
|
659
|
+
/** The recipient's email address. The person is resolved from it once, at stamp time.
|
|
660
|
+
* Rides the request body only — never a URL/query (it is PII). */
|
|
661
|
+
email: string;
|
|
662
|
+
/** The absolute http(s) destination the recipient should land on. */
|
|
663
|
+
url: string;
|
|
664
|
+
/** Optional provenance for later enrichment (e.g. "resend", "hubspot"). Never required. */
|
|
665
|
+
rail?: string;
|
|
666
|
+
}
|
|
667
|
+
/** Result of `campaignLink` — the same destination with the arrival ticket appended. */
|
|
668
|
+
interface CampaignLinkResult {
|
|
669
|
+
object: "campaign_link";
|
|
670
|
+
/** The stamped URL to put in the email. Carries only an opaque `cd_ref` ticket. */
|
|
671
|
+
url: string;
|
|
672
|
+
/** How long the ticket stays live (a campaign's useful life). */
|
|
673
|
+
expiresInDays: number;
|
|
674
|
+
env: Environment;
|
|
675
|
+
}
|
|
657
676
|
interface IngestResponse {
|
|
658
677
|
object: "list";
|
|
659
678
|
received: number;
|
|
@@ -1578,6 +1597,21 @@ declare class CrossdeckServer extends EventEmitter {
|
|
|
1578
1597
|
identify(userId: string, anonymousId: string, options?: IdentifyOptions & RequestOptions): Promise<AliasResult>;
|
|
1579
1598
|
aliasIdentity(input: AliasIdentityInput, options?: RequestOptions): Promise<AliasResult>;
|
|
1580
1599
|
forget(hints: IdentityHints, options?: RequestOptions): Promise<ForgetResult>;
|
|
1600
|
+
/**
|
|
1601
|
+
* Stamp an outbound email link so its click binds to the recipient on landing.
|
|
1602
|
+
*
|
|
1603
|
+
* You know the recipient's email at send time; pass it with the link's destination
|
|
1604
|
+
* and Crossdeck returns the same URL carrying a one-time arrival ticket (`cd_ref`).
|
|
1605
|
+
* Put the returned URL in the email. When the recipient clicks and lands on a page
|
|
1606
|
+
* running `@cross-deck/web`, the SDK reads the ticket automatically and binds that
|
|
1607
|
+
* session to the person — the post-click journey then joins their identity.
|
|
1608
|
+
*
|
|
1609
|
+
* Rail-agnostic: works for Resend, HubSpot, your own SMTP, anything. Server-side
|
|
1610
|
+
* only (it mints an identity bind, so a secret key is required). If the landing page
|
|
1611
|
+
* has no Crossdeck web SDK, the deep session stitch softens but the server-side
|
|
1612
|
+
* email funnel (via the rail adapter) still lands by identity.
|
|
1613
|
+
*/
|
|
1614
|
+
campaignLink(input: CampaignLinkInput, options?: RequestOptions): Promise<CampaignLinkResult>;
|
|
1581
1615
|
/**
|
|
1582
1616
|
* Fetch a customer's entitlements from Crossdeck and warm the cache.
|
|
1583
1617
|
*
|
|
@@ -2128,4 +2162,4 @@ declare class CrossdeckServer extends EventEmitter {
|
|
|
2128
2162
|
private normalizeIngestEvent;
|
|
2129
2163
|
}
|
|
2130
2164
|
|
|
2131
|
-
export { type
|
|
2165
|
+
export { type IdentifyOptions as $, type AliasIdentityInput as A, type BlockVerdict as B, CROSSDECK_API_VERSION as C, type CrossdeckServerOptions as D, CrossdeckValidationError as E, DEFAULT_BASE_URL as F, DEFAULT_TIMEOUT_MS as G, type Diagnostics as H, type EntitlementCacheOptions as I, type EntitlementMutationResult as J, type EntitlementStore as K, type EntitlementsListResponse as L, type EntitlementsListener as M, type Environment as N, type ErrorCaptureConfig as O, type ErrorLevel as P, type EventProperties as Q, type ForgetResult as R, type GateInput as S, type GateVerdict as T, type GrantDuration as U, type GrantEntitlementInput as V, type GroupMembership as W, type HeartbeatResponse as X, type HttpRequestInfo as Y, type HttpResponseInfo as Z, type HttpRetriesConfig as _, type AliasResult as a, type IdentityHints as a0, type IngestOptions as a1, type IngestResponse as a2, type OwnerStatusInput as a3, type PublicEntitlement as a4, type PurchaseResult as a5, type RequestOptions as a6, type ResolveInput as a7, type ResolveResult as a8, type RevokeEntitlementInput as a9, type RuntimeHost as aa, type RuntimeInfo as ab, type ServerEvent as ac, type StackFrame as ad, type StoredEntitlements as ae, type SyncPurchaseInput as af, makeCrossdeckError as ag, type AuditDecision as b, type AuditEntry as c, type Breadcrumb as d, type BreadcrumbCategory as e, type BreadcrumbLevel as f, type CampaignLinkInput as g, type CampaignLinkResult as h, type CapturedError as i, type Contract as j, type ContractAppliesTo as k, type ContractFailureInput as l, type ContractPillar as m, type ContractStatus as n, type ContractTestRef as o, CrossdeckAuthenticationError as p, CrossdeckConfigurationError as q, CrossdeckContracts as r, CrossdeckError as s, type CrossdeckErrorPayload as t, type CrossdeckErrorType as u, CrossdeckInternalError as v, CrossdeckNetworkError as w, CrossdeckPermissionError as x, CrossdeckRateLimitError as y, CrossdeckServer as z };
|
package/dist/index.cjs
CHANGED
|
@@ -387,7 +387,7 @@ function byteLength(s) {
|
|
|
387
387
|
var https = __toESM(require("https"));
|
|
388
388
|
|
|
389
389
|
// src/_version.ts
|
|
390
|
-
var SDK_VERSION = "1.
|
|
390
|
+
var SDK_VERSION = "1.14.0";
|
|
391
391
|
var SDK_NAME = "@cross-deck/node";
|
|
392
392
|
|
|
393
393
|
// src/_diagnostic-telemetry.ts
|
|
@@ -3048,6 +3048,43 @@ var CrossdeckServer = class extends import_node_events.EventEmitter {
|
|
|
3048
3048
|
timeoutMs: options?.timeoutMs
|
|
3049
3049
|
});
|
|
3050
3050
|
}
|
|
3051
|
+
/**
|
|
3052
|
+
* Stamp an outbound email link so its click binds to the recipient on landing.
|
|
3053
|
+
*
|
|
3054
|
+
* You know the recipient's email at send time; pass it with the link's destination
|
|
3055
|
+
* and Crossdeck returns the same URL carrying a one-time arrival ticket (`cd_ref`).
|
|
3056
|
+
* Put the returned URL in the email. When the recipient clicks and lands on a page
|
|
3057
|
+
* running `@cross-deck/web`, the SDK reads the ticket automatically and binds that
|
|
3058
|
+
* session to the person — the post-click journey then joins their identity.
|
|
3059
|
+
*
|
|
3060
|
+
* Rail-agnostic: works for Resend, HubSpot, your own SMTP, anything. Server-side
|
|
3061
|
+
* only (it mints an identity bind, so a secret key is required). If the landing page
|
|
3062
|
+
* has no Crossdeck web SDK, the deep session stitch softens but the server-side
|
|
3063
|
+
* email funnel (via the rail adapter) still lands by identity.
|
|
3064
|
+
*/
|
|
3065
|
+
async campaignLink(input, options) {
|
|
3066
|
+
if (!input.email) {
|
|
3067
|
+
throw new CrossdeckError({
|
|
3068
|
+
type: "invalid_request_error",
|
|
3069
|
+
code: "missing_email",
|
|
3070
|
+
message: "campaignLink requires the recipient's email."
|
|
3071
|
+
});
|
|
3072
|
+
}
|
|
3073
|
+
if (!input.url) {
|
|
3074
|
+
throw new CrossdeckError({
|
|
3075
|
+
type: "invalid_request_error",
|
|
3076
|
+
code: "missing_url",
|
|
3077
|
+
message: "campaignLink requires the link's destination url."
|
|
3078
|
+
});
|
|
3079
|
+
}
|
|
3080
|
+
const body = { email: input.email, url: input.url };
|
|
3081
|
+
if (input.rail) body.rail = input.rail;
|
|
3082
|
+
return this.http.request("POST", "/campaign/email-link", {
|
|
3083
|
+
body,
|
|
3084
|
+
signal: options?.signal,
|
|
3085
|
+
timeoutMs: options?.timeoutMs
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3051
3088
|
// ============================================================
|
|
3052
3089
|
// Entitlements — direct HTTP + TTL cache (v1.0.0+)
|
|
3053
3090
|
//
|