@stackable-labs/sdk-extension-contracts 2.23.0 → 2.24.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/dist/index.d.ts +64 -9
- package/dist/index.js +25 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -436,14 +436,36 @@ interface IdentityEvent {
|
|
|
436
436
|
timestamp: ISOTimestamp;
|
|
437
437
|
};
|
|
438
438
|
}
|
|
439
|
-
/** Base claims sent to extend
|
|
439
|
+
/** Base claims sent to identity.extend handlers before JWT signing */
|
|
440
440
|
interface IdentityBaseClaims {
|
|
441
441
|
external_id: string;
|
|
442
442
|
email?: string;
|
|
443
443
|
name?: string;
|
|
444
444
|
[key: string]: unknown;
|
|
445
445
|
}
|
|
446
|
-
/**
|
|
446
|
+
/** Standard JWT claims (host/Lambda always allow these; declaration is redundant). */
|
|
447
|
+
declare const STANDARD_IDENTITY_CLAIM_KEYS: ReadonlySet<string>;
|
|
448
|
+
/** RFC 7519 registered + Zendesk-managed claims — host-side sanitizer always
|
|
449
|
+
* wins on collision, so these must never appear in manifest.identityClaims. */
|
|
450
|
+
declare const RESERVED_IDENTITY_CLAIM_KEYS: ReadonlySet<string>;
|
|
451
|
+
/** Valid identityClaims key format: lowercase identifier, ≤64 chars. */
|
|
452
|
+
declare const IDENTITY_CLAIM_KEY_PATTERN: RegExp;
|
|
453
|
+
/** Maximum number of custom identityClaims entries per extension. */
|
|
454
|
+
declare const IDENTITY_CLAIMS_MAX_KEYS = 20;
|
|
455
|
+
/** Maximum length of any single string value sent through identity.extend / custom_claims. */
|
|
456
|
+
declare const IDENTITY_CLAIM_MAX_STRING_VALUE_LEN = 256;
|
|
457
|
+
/**
|
|
458
|
+
* Handler type for useExtendIdentity. Use with useCallback for memoized handlers.
|
|
459
|
+
*
|
|
460
|
+
* Returned keys are filtered host-side against the extension's
|
|
461
|
+
* `manifest.identityClaims` declaration:
|
|
462
|
+
* - Standard JWT overrides (`external_id`, `email`, `name`) always allowed
|
|
463
|
+
* - Custom keys must be declared in `manifest.identityClaims`
|
|
464
|
+
* - Undeclared keys are dropped with a console.warn
|
|
465
|
+
*
|
|
466
|
+
* Values must be `string | number | boolean` for inclusion in the signed JWT;
|
|
467
|
+
* non-primitive values are dropped by the Lambda sanitizer.
|
|
468
|
+
*/
|
|
447
469
|
type ExtendIdentityHandler = (claims: IdentityBaseClaims) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
448
470
|
|
|
449
471
|
/**
|
|
@@ -549,6 +571,23 @@ interface ContextData {
|
|
|
549
571
|
/** Keys managed exclusively by the host RPC layer — must not appear in surface-level context */
|
|
550
572
|
declare const RESERVED_CONTEXT_KEYS: readonly ["identity", "messaging", "settings"];
|
|
551
573
|
type ReservedContextKey = typeof RESERVED_CONTEXT_KEYS[number];
|
|
574
|
+
/**
|
|
575
|
+
* Payload sent from extension → host for `identity.extend`.
|
|
576
|
+
*
|
|
577
|
+
* `patch` is a partial set of claims the extension wants to merge into its
|
|
578
|
+
* cached enrichment slot on the host. Host filters the patch against
|
|
579
|
+
* `manifest.identityClaims` (same rules as the initial-login enrichment path),
|
|
580
|
+
* re-signs the JWT, updates `identityState.user.metadata`, and broadcasts
|
|
581
|
+
* `identity:refresh`.
|
|
582
|
+
*/
|
|
583
|
+
interface IdentityExtendPayload {
|
|
584
|
+
patch: Record<string, unknown>;
|
|
585
|
+
}
|
|
586
|
+
/** Response returned to the extension after the host completes the re-sign flow. */
|
|
587
|
+
interface IdentityExtendResponse {
|
|
588
|
+
/** The newly-signed JWT — same token that was pushed to outbound auth (Zendesk). */
|
|
589
|
+
token: string;
|
|
590
|
+
}
|
|
552
591
|
/** Union of all capability call types */
|
|
553
592
|
type CapabilityCall = {
|
|
554
593
|
type: 'context.read';
|
|
@@ -565,10 +604,8 @@ type CapabilityCall = {
|
|
|
565
604
|
type: 'actions.invoke';
|
|
566
605
|
payload: ActionInvokePayload;
|
|
567
606
|
} | {
|
|
568
|
-
type: 'extend
|
|
569
|
-
payload:
|
|
570
|
-
claims: IdentityBaseClaims;
|
|
571
|
-
};
|
|
607
|
+
type: 'identity.extend';
|
|
608
|
+
payload: IdentityExtendPayload;
|
|
572
609
|
};
|
|
573
610
|
type CapabilityType = CapabilityCall['type'];
|
|
574
611
|
|
|
@@ -694,7 +731,7 @@ interface InstanceOption {
|
|
|
694
731
|
* Extensions declare required permissions in their manifest.
|
|
695
732
|
* Host enforces: capability calls must be a subset of granted permissions.
|
|
696
733
|
*/
|
|
697
|
-
declare const PERMISSIONS: readonly ["context:read", "data:query", "data:fetch", "actions:toast", "actions:invoke", "
|
|
734
|
+
declare const PERMISSIONS: readonly ["context:read", "data:query", "data:fetch", "actions:toast", "actions:invoke", "identity:extend", "events:identity", "events:messaging", "events:activity"];
|
|
698
735
|
type Permission = (typeof PERMISSIONS)[number];
|
|
699
736
|
/**
|
|
700
737
|
* Maps capability types (dot notation, used in code) to the permission
|
|
@@ -706,7 +743,7 @@ declare const CAPABILITY_PERMISSION_MAP: {
|
|
|
706
743
|
readonly 'data.fetch': "data:fetch";
|
|
707
744
|
readonly 'actions.toast': "actions:toast";
|
|
708
745
|
readonly 'actions.invoke': "actions:invoke";
|
|
709
|
-
readonly 'extend
|
|
746
|
+
readonly 'identity.extend': "identity:extend";
|
|
710
747
|
};
|
|
711
748
|
/** Capability key type — dot-notation API names (e.g., 'data.query', 'actions.toast') */
|
|
712
749
|
type Capability = keyof typeof CAPABILITY_PERMISSION_MAP;
|
|
@@ -751,6 +788,24 @@ interface ExtensionManifest {
|
|
|
751
788
|
permissions: Permission[];
|
|
752
789
|
/** Specific events this extension listens for (e.g. ["identity:login", "messaging:postback:Buy Now"]) */
|
|
753
790
|
events?: EventType[];
|
|
791
|
+
/**
|
|
792
|
+
* Specific custom identity claim keys this extension contributes via
|
|
793
|
+
* `useExtendIdentity`. Required (non-empty) when `permissions` includes
|
|
794
|
+
* `identity:extend` and the handler returns custom keys.
|
|
795
|
+
*
|
|
796
|
+
* Standard JWT claims (`external_id`, `email`, `name`) are exempt — they're
|
|
797
|
+
* always allowed as overrides without explicit declaration.
|
|
798
|
+
*
|
|
799
|
+
* Constraints (enforced at runtime by the host; install-time bundle scan
|
|
800
|
+
* adds the upload-side gate):
|
|
801
|
+
* - Keys must match /^[a-z_][a-z0-9_]{0,63}$/ (snake_case, ≤64 chars)
|
|
802
|
+
* - Reserved JWT/Zendesk claim names rejected
|
|
803
|
+
* - Max 20 declared keys per extension
|
|
804
|
+
*
|
|
805
|
+
* Returned-but-undeclared keys are dropped at runtime with a console.warn.
|
|
806
|
+
* Example: ["loyalty_tier", "verified", "preferred_pronoun"]
|
|
807
|
+
*/
|
|
808
|
+
identityClaims?: string[];
|
|
754
809
|
/**
|
|
755
810
|
* Hostnames this extension is permitted to reach via data.fetch.
|
|
756
811
|
* Prefer exact hostnames. Use `*.<suffix>` wildcards only if you need any
|
|
@@ -1111,4 +1166,4 @@ interface Order {
|
|
|
1111
1166
|
declare const TEMPLATE_FLAVORS: readonly ["minimal", "starter", "kitchen-sink"];
|
|
1112
1167
|
type TemplateFlavor = typeof TEMPLATE_FLAVORS[number];
|
|
1113
1168
|
|
|
1114
|
-
export { ACTIVITY_EVENT, ALLOWED_ICONS, type ActionInvokePayload, type ActionPayloadMap, type ActivityEvent, type ActivityEventHandler, type ActivityEventType, type Address, type AllowedIconName, type ApiError, type ApiRequest, type ApiResponse, CAPABILITY_PERMISSION_MAP, type Capability, type CapabilityCall, type CapabilityRequest, type CapabilityResponse, type CapabilityType, type ContextData, type ConversationField, type ConversationTags, type Customer, type DataField, type DataFieldType, EVENT_HOOK_PERMISSION_MAP, type EncryptedPayload, type EventDomain, type EventHook, type EventType, type ExtendIdentityHandler, type ExtendIdentityRequest, type ExtendIdentityResponse, type ExtensionGroup, type ExtensionManifest, type ExtensionRegistryEntry, type FetchRequest, type FetchRequestInit, type FetchResponse, type HostToSandboxMessage, IDENTITY_EVENT, INVOKE_ACTION, type IdentityBaseClaims, type IdentityEvent, type IdentityEventType, type IdentityState, type InstanceConfig, type InstanceOption, type InvokeAction, type MarketplaceExtension, type MessagingContext, type MessagingEvent, type MessagingEventHandler, type MessagingEventType, type MessagingPostbackEvent, type MessengerCommand, type NamedEntity, type NewConversationPayload, type Order, type OrderAction, type OrderItem, type OrderStatus, type OrderStatuses, PERMISSIONS, type Permission, type Price, RESERVED_CONTEXT_KEYS, type ReservedContextKey, SURFACE_TARGET, type SandboxToHostMessage, type Shipment, type SurfaceContext, type SurfaceLifecycleMessage, type SurfaceTarget, TEMPLATE_FLAVORS, type Target, type TemplateFlavor, type Theme, type ToastPayload, type UITag, type UITagCategory, UI_TAGS, UI_TAG_ATTRIBUTES, UI_TAG_ATTRIBUTE_VALUES, UI_TAG_CATEGORIES, UI_TAG_CHILDREN, UI_TAG_CHILD_ONLY, UI_TAG_COMPOUND, UI_TAG_DEFINITIONS, UI_TAG_SELF_CLOSING, type UserIdentity, type WellKnownActivityEvent, type WidgetAction, tagToComponentName };
|
|
1169
|
+
export { ACTIVITY_EVENT, ALLOWED_ICONS, type ActionInvokePayload, type ActionPayloadMap, type ActivityEvent, type ActivityEventHandler, type ActivityEventType, type Address, type AllowedIconName, type ApiError, type ApiRequest, type ApiResponse, CAPABILITY_PERMISSION_MAP, type Capability, type CapabilityCall, type CapabilityRequest, type CapabilityResponse, type CapabilityType, type ContextData, type ConversationField, type ConversationTags, type Customer, type DataField, type DataFieldType, EVENT_HOOK_PERMISSION_MAP, type EncryptedPayload, type EventDomain, type EventHook, type EventType, type ExtendIdentityHandler, type ExtendIdentityRequest, type ExtendIdentityResponse, type ExtensionGroup, type ExtensionManifest, type ExtensionRegistryEntry, type FetchRequest, type FetchRequestInit, type FetchResponse, type HostToSandboxMessage, IDENTITY_CLAIMS_MAX_KEYS, IDENTITY_CLAIM_KEY_PATTERN, IDENTITY_CLAIM_MAX_STRING_VALUE_LEN, IDENTITY_EVENT, INVOKE_ACTION, type IdentityBaseClaims, type IdentityEvent, type IdentityEventType, type IdentityExtendPayload, type IdentityExtendResponse, type IdentityState, type InstanceConfig, type InstanceOption, type InvokeAction, type MarketplaceExtension, type MessagingContext, type MessagingEvent, type MessagingEventHandler, type MessagingEventType, type MessagingPostbackEvent, type MessengerCommand, type NamedEntity, type NewConversationPayload, type Order, type OrderAction, type OrderItem, type OrderStatus, type OrderStatuses, PERMISSIONS, type Permission, type Price, RESERVED_CONTEXT_KEYS, RESERVED_IDENTITY_CLAIM_KEYS, type ReservedContextKey, STANDARD_IDENTITY_CLAIM_KEYS, SURFACE_TARGET, type SandboxToHostMessage, type Shipment, type SurfaceContext, type SurfaceLifecycleMessage, type SurfaceTarget, TEMPLATE_FLAVORS, type Target, type TemplateFlavor, type Theme, type ToastPayload, type UITag, type UITagCategory, UI_TAGS, UI_TAG_ATTRIBUTES, UI_TAG_ATTRIBUTE_VALUES, UI_TAG_CATEGORIES, UI_TAG_CHILDREN, UI_TAG_CHILD_ONLY, UI_TAG_COMPOUND, UI_TAG_DEFINITIONS, UI_TAG_SELF_CLOSING, type UserIdentity, type WellKnownActivityEvent, type WidgetAction, tagToComponentName };
|
package/dist/index.js
CHANGED
|
@@ -405,6 +405,27 @@ var IDENTITY_EVENT = {
|
|
|
405
405
|
REFRESH: "refresh",
|
|
406
406
|
EXPIRED: "expired"
|
|
407
407
|
};
|
|
408
|
+
var STANDARD_IDENTITY_CLAIM_KEYS = /* @__PURE__ */ new Set(["external_id", "email", "name"]);
|
|
409
|
+
var RESERVED_IDENTITY_CLAIM_KEYS = /* @__PURE__ */ new Set([
|
|
410
|
+
// RFC 7519 registered claims
|
|
411
|
+
"iss",
|
|
412
|
+
"sub",
|
|
413
|
+
"aud",
|
|
414
|
+
"exp",
|
|
415
|
+
"nbf",
|
|
416
|
+
"iat",
|
|
417
|
+
"jti",
|
|
418
|
+
// Zendesk Messaging standard claims (Lambda sets these unconditionally)
|
|
419
|
+
"scope",
|
|
420
|
+
"external_id",
|
|
421
|
+
"email",
|
|
422
|
+
"email_verified",
|
|
423
|
+
"name",
|
|
424
|
+
"user_fields"
|
|
425
|
+
]);
|
|
426
|
+
var IDENTITY_CLAIM_KEY_PATTERN = /^[a-z_][a-z0-9_]{0,63}$/;
|
|
427
|
+
var IDENTITY_CLAIMS_MAX_KEYS = 20;
|
|
428
|
+
var IDENTITY_CLAIM_MAX_STRING_VALUE_LEN = 256;
|
|
408
429
|
|
|
409
430
|
// src/activity.ts
|
|
410
431
|
var ACTIVITY_EVENT = {
|
|
@@ -424,10 +445,10 @@ var PERMISSIONS = [
|
|
|
424
445
|
"data:fetch",
|
|
425
446
|
"actions:toast",
|
|
426
447
|
"actions:invoke",
|
|
448
|
+
"identity:extend",
|
|
427
449
|
"events:identity",
|
|
428
450
|
"events:messaging",
|
|
429
|
-
"events:activity"
|
|
430
|
-
"extend:identity"
|
|
451
|
+
"events:activity"
|
|
431
452
|
];
|
|
432
453
|
var CAPABILITY_PERMISSION_MAP = {
|
|
433
454
|
"context.read": "context:read",
|
|
@@ -435,7 +456,7 @@ var CAPABILITY_PERMISSION_MAP = {
|
|
|
435
456
|
"data.fetch": "data:fetch",
|
|
436
457
|
"actions.toast": "actions:toast",
|
|
437
458
|
"actions.invoke": "actions:invoke",
|
|
438
|
-
"extend
|
|
459
|
+
"identity.extend": "identity:extend"
|
|
439
460
|
};
|
|
440
461
|
var EVENT_HOOK_PERMISSION_MAP = {
|
|
441
462
|
useIdentityEvent: "events:identity",
|
|
@@ -454,4 +475,4 @@ var SURFACE_TARGET = {
|
|
|
454
475
|
// src/scaffold.ts
|
|
455
476
|
var TEMPLATE_FLAVORS = ["minimal", "starter", "kitchen-sink"];
|
|
456
477
|
|
|
457
|
-
export { ACTIVITY_EVENT, ALLOWED_ICONS, CAPABILITY_PERMISSION_MAP, EVENT_HOOK_PERMISSION_MAP, EXTENSION_CATEGORY, EXTENSION_VISIBILITY, IDENTITY_EVENT, INVOKE_ACTION, PERMISSIONS, RESERVED_CONTEXT_KEYS, SURFACE_TARGET, TEMPLATE_FLAVORS, UI_TAGS, UI_TAG_ATTRIBUTES, UI_TAG_ATTRIBUTE_VALUES, UI_TAG_CATEGORIES, UI_TAG_CHILDREN, UI_TAG_CHILD_ONLY, UI_TAG_COMPOUND, UI_TAG_DEFINITIONS, UI_TAG_SELF_CLOSING, asClerkOrgId, asClerkUserId, asISOTimestamp, tagToComponentName };
|
|
478
|
+
export { ACTIVITY_EVENT, ALLOWED_ICONS, CAPABILITY_PERMISSION_MAP, EVENT_HOOK_PERMISSION_MAP, EXTENSION_CATEGORY, EXTENSION_VISIBILITY, IDENTITY_CLAIMS_MAX_KEYS, IDENTITY_CLAIM_KEY_PATTERN, IDENTITY_CLAIM_MAX_STRING_VALUE_LEN, IDENTITY_EVENT, INVOKE_ACTION, PERMISSIONS, RESERVED_CONTEXT_KEYS, RESERVED_IDENTITY_CLAIM_KEYS, STANDARD_IDENTITY_CLAIM_KEYS, SURFACE_TARGET, TEMPLATE_FLAVORS, UI_TAGS, UI_TAG_ATTRIBUTES, UI_TAG_ATTRIBUTE_VALUES, UI_TAG_CATEGORIES, UI_TAG_CHILDREN, UI_TAG_CHILD_ONLY, UI_TAG_COMPOUND, UI_TAG_DEFINITIONS, UI_TAG_SELF_CLOSING, asClerkOrgId, asClerkUserId, asISOTimestamp, tagToComponentName };
|