@payabli/component-contracts 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.
@@ -0,0 +1,81 @@
1
+ import type { Infer, InferEvents } from '../protocol/envelope.js';
2
+ import { payinEvents, payinOptionsSchema } from './schema.js';
3
+ import type { PayInSuccessPayload } from './schema.js';
4
+ export * from './schema.js';
5
+ /**
6
+ * The partner-facing options type IS the wire schema's type: one definition
7
+ * serves the SDK surface and payhub's validator.
8
+ */
9
+ export type PayInOptions = Infer<typeof payinOptionsSchema>;
10
+ /**
11
+ * Event payload types are INFERRED from the shared wire schemas, so the
12
+ * partner-facing surface and the wire validators are one definition.
13
+ * `success` is the one exception: it comes from SUBMIT_RESULT.data, which the
14
+ * base protocol types openly and PayIn narrows. Partners consume the full map
15
+ * as `PayInEvents` (see `aliases.ts`).
16
+ */
17
+ declare module '../registry.js' {
18
+ interface ComponentDefinitions {
19
+ payin: ComponentDefinition<PayInOptions, InferEvents<typeof payinEvents> & {
20
+ success: PayInSuccessPayload;
21
+ }>;
22
+ }
23
+ }
24
+ /**
25
+ * Wire type → emitter event, with the shared schema from `./schema.js` as the
26
+ * only validator.
27
+ */
28
+ export declare const payInEventSchemas: {
29
+ METHOD_CHANGE: {
30
+ event: "methodChange";
31
+ schema: import("zod/v4/mini").ZodMiniObject<{
32
+ method: import("zod/v4/mini").ZodMiniEnum<{
33
+ card: "card";
34
+ ach: "ach";
35
+ check: "check";
36
+ applepay: "applepay";
37
+ googlepay: "googlepay";
38
+ }>;
39
+ }, import("zod/v4/core").$strip>;
40
+ };
41
+ WALLET_AVAILABLE: {
42
+ event: "walletAvailable";
43
+ schema: import("zod/v4/mini").ZodMiniObject<{
44
+ applepay: import("zod/v4/mini").ZodMiniBoolean<boolean>;
45
+ googlepay: import("zod/v4/mini").ZodMiniBoolean<boolean>;
46
+ }, import("zod/v4/core").$strip>;
47
+ };
48
+ CARD_BRAND_CHANGE: {
49
+ event: "cardBrandChange";
50
+ schema: import("zod/v4/mini").ZodMiniObject<{
51
+ brand: import("zod/v4/mini").ZodMiniEnum<{
52
+ unknown: "unknown";
53
+ Visa: "Visa";
54
+ Mastercard: "Mastercard";
55
+ Amex: "Amex";
56
+ Discover: "Discover";
57
+ Jcb: "Jcb";
58
+ Diners: "Diners";
59
+ }>;
60
+ }, import("zod/v4/core").$strip>;
61
+ };
62
+ VALIDATION_STATUS: {
63
+ event: "validationStatus";
64
+ schema: import("zod/v4/mini").ZodMiniObject<{
65
+ status: import("zod/v4/mini").ZodMiniEnum<{
66
+ verified: "verified";
67
+ pending: "pending";
68
+ failed: "failed";
69
+ warning: "warning";
70
+ }>;
71
+ message: import("zod/v4/mini").ZodMiniOptional<import("zod/v4/mini").ZodMiniString<string>>;
72
+ }, import("zod/v4/core").$strip>;
73
+ };
74
+ VENDOR_CREATED: {
75
+ event: "vendorCreated";
76
+ schema: import("zod/v4/mini").ZodMiniObject<{
77
+ vendorId: import("zod/v4/mini").ZodMiniString<string>;
78
+ }, import("zod/v4/core").$strip>;
79
+ };
80
+ };
81
+ export declare const payInDescriptor: import("../registry.js").ComponentDescriptor<"payin">;
@@ -0,0 +1,72 @@
1
+ import * as z from 'zod/v4/mini';
2
+ /**
3
+ * PayIn's wire contract: its event schemas, options schema, and vocabulary.
4
+ * PayIn-specific on purpose — a payout component defines its own methods in
5
+ * its own folder.
6
+ */
7
+ export declare const PAYMENT_METHODS: readonly ["card", "ach", "check", "applepay", "googlepay"];
8
+ export type PaymentMethodName = (typeof PAYMENT_METHODS)[number];
9
+ /**
10
+ * A card network. Not a payment method. Accepted brands are session config
11
+ * (`Session/init` acceptedCardBrands), not a client option: the API owns them
12
+ * and payhub reads them from bootstrap.
13
+ */
14
+ export declare const CARD_BRANDS: readonly ["Visa", "Mastercard", "Amex", "Discover", "Jcb", "Diners"];
15
+ export type CardBrand = (typeof CARD_BRANDS)[number];
16
+ /**
17
+ * Client-side UI behavior only. Business configuration — operation, methods,
18
+ * amount, required fields, billing address — belongs to `Session/init` on the
19
+ * partner's server, and its types belong to the API's generated SDK.
20
+ *
21
+ * The SDK sends this in CONFIG_SET.options and payhub parses with this same
22
+ * object (via the descriptor's `optionsSchema`).
23
+ */
24
+ export declare const payinOptionsSchema: z.ZodMiniObject<{
25
+ showSubmitButton: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
26
+ }, z.core.$strip>;
27
+ /** PayIn's own inbound events, beyond the base set every component shares. */
28
+ export declare const payinEvents: {
29
+ readonly METHOD_CHANGE: z.ZodMiniObject<{
30
+ method: z.ZodMiniEnum<{
31
+ card: "card";
32
+ ach: "ach";
33
+ check: "check";
34
+ applepay: "applepay";
35
+ googlepay: "googlepay";
36
+ }>;
37
+ }, z.core.$strip>;
38
+ readonly WALLET_AVAILABLE: z.ZodMiniObject<{
39
+ applepay: z.ZodMiniBoolean<boolean>;
40
+ googlepay: z.ZodMiniBoolean<boolean>;
41
+ }, z.core.$strip>;
42
+ readonly CARD_BRAND_CHANGE: z.ZodMiniObject<{
43
+ brand: z.ZodMiniEnum<{
44
+ unknown: "unknown";
45
+ Visa: "Visa";
46
+ Mastercard: "Mastercard";
47
+ Amex: "Amex";
48
+ Discover: "Discover";
49
+ Jcb: "Jcb";
50
+ Diners: "Diners";
51
+ }>;
52
+ }, z.core.$strip>;
53
+ readonly VALIDATION_STATUS: z.ZodMiniObject<{
54
+ status: z.ZodMiniEnum<{
55
+ verified: "verified";
56
+ pending: "pending";
57
+ failed: "failed";
58
+ warning: "warning";
59
+ }>;
60
+ message: z.ZodMiniOptional<z.ZodMiniString<string>>;
61
+ }, z.core.$strip>;
62
+ readonly VENDOR_CREATED: z.ZodMiniObject<{
63
+ vendorId: z.ZodMiniString<string>;
64
+ }, z.core.$strip>;
65
+ };
66
+ /**
67
+ * SUBMIT_RESULT.data for PayIn. Open on purpose: the transaction result grows
68
+ * fields the SDK does not interpret, and it forwards all of them.
69
+ */
70
+ export type PayInSuccessPayload = {
71
+ transactionId?: string;
72
+ } & Record<string, unknown>;
@@ -0,0 +1,164 @@
1
+ import * as z from 'zod/v4/mini';
2
+ import type { ProtocolMessageEvent } from './envelope.js';
3
+ export declare const componentErrorSchema: z.ZodMiniObject<{
4
+ code: z.ZodMiniString<string>;
5
+ message: z.ZodMiniString<string>;
6
+ recoverable: z.ZodMiniBoolean<boolean>;
7
+ details: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>;
8
+ }, z.core.$strip>;
9
+ export type ComponentError = z.infer<typeof componentErrorSchema>;
10
+ /**
11
+ * Client-side appearance, shared by every component. The SDK sends it in
12
+ * CONFIG_SET and payhub parses it with this same object, so the layout
13
+ * vocabulary exists in exactly one place.
14
+ */
15
+ export declare const appearanceSchema: z.ZodMiniObject<{
16
+ layout: z.ZodMiniOptional<z.ZodMiniEnum<{
17
+ tabs: "tabs";
18
+ accordion: "accordion";
19
+ stacked: "stacked";
20
+ minimal: "minimal";
21
+ }>>;
22
+ layoutVariant: z.ZodMiniOptional<z.ZodMiniEnum<{
23
+ compact: "compact";
24
+ standard: "standard";
25
+ wide: "wide";
26
+ }>>;
27
+ labelStyle: z.ZodMiniOptional<z.ZodMiniEnum<{
28
+ above: "above";
29
+ floating: "floating";
30
+ outlined: "outlined";
31
+ }>>;
32
+ mode: z.ZodMiniOptional<z.ZodMiniEnum<{
33
+ light: "light";
34
+ dark: "dark";
35
+ system: "system";
36
+ }>>;
37
+ tokens: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
38
+ labels: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
39
+ }, z.core.$strip>;
40
+ export type AppearanceOptions = z.infer<typeof appearanceSchema>;
41
+ /**
42
+ * Inbound wire messages: iframe → parent SDK. One schema per wire type, and
43
+ * this map is the only definition. Payhub emits through these objects and the
44
+ * SDK validates with the same objects, so agreement between the two sides is
45
+ * shared, not tested.
46
+ */
47
+ export declare const baseInboundEvents: {
48
+ readonly READY: z.ZodMiniObject<{
49
+ fields: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
50
+ methods: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
51
+ }, z.core.$strip>;
52
+ readonly RENDERED: z.ZodMiniObject<{}, z.core.$strip>;
53
+ readonly CONFIG_REQUEST: z.ZodMiniObject<{}, z.core.$strip>;
54
+ readonly PREFILL_REQUEST: z.ZodMiniObject<{}, z.core.$strip>;
55
+ readonly RESIZE: z.ZodMiniObject<{
56
+ height: z.ZodMiniNumber<number>;
57
+ }, z.core.$strip>;
58
+ readonly STATE_CHANGE: z.ZodMiniObject<{
59
+ isValid: z.ZodMiniBoolean<boolean>;
60
+ completeness: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
61
+ fields: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniObject<{
62
+ valid: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
63
+ touched: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
64
+ }, z.core.$strip>>>;
65
+ }, z.core.$strip>;
66
+ readonly SUBMIT_RESULT: z.ZodMiniDiscriminatedUnion<[z.ZodMiniObject<{
67
+ success: z.ZodMiniLiteral<true>;
68
+ data: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>;
69
+ }, z.core.$strip>, z.ZodMiniObject<{
70
+ success: z.ZodMiniLiteral<false>;
71
+ error: z.ZodMiniObject<{
72
+ code: z.ZodMiniString<string>;
73
+ message: z.ZodMiniString<string>;
74
+ recoverable: z.ZodMiniBoolean<boolean>;
75
+ details: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>;
76
+ }, z.core.$strip>;
77
+ }, z.core.$strip>], "success">;
78
+ readonly ERROR: z.ZodMiniObject<{
79
+ code: z.ZodMiniString<string>;
80
+ message: z.ZodMiniString<string>;
81
+ recoverable: z.ZodMiniBoolean<boolean>;
82
+ details: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>;
83
+ }, z.core.$strip>;
84
+ readonly LOADING: z.ZodMiniObject<{
85
+ state: z.ZodMiniEnum<{
86
+ bootstrapping: "bootstrapping";
87
+ submitting: "submitting";
88
+ validating: "validating";
89
+ }>;
90
+ }, z.core.$strip>;
91
+ };
92
+ export type BaseInboundType = keyof typeof baseInboundEvents;
93
+ /**
94
+ * Outbound wire messages: parent SDK → iframe. `options` is a plain record
95
+ * here because its shape is per-component: payhub validates it with the
96
+ * `optionsSchema` on the component's descriptor.
97
+ */
98
+ export declare const outboundMessages: {
99
+ readonly CONFIG_SET: z.ZodMiniObject<{
100
+ sessionToken: z.ZodMiniString<string>;
101
+ options: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>;
102
+ appearance: z.ZodMiniOptional<z.ZodMiniObject<{
103
+ layout: z.ZodMiniOptional<z.ZodMiniEnum<{
104
+ tabs: "tabs";
105
+ accordion: "accordion";
106
+ stacked: "stacked";
107
+ minimal: "minimal";
108
+ }>>;
109
+ layoutVariant: z.ZodMiniOptional<z.ZodMiniEnum<{
110
+ compact: "compact";
111
+ standard: "standard";
112
+ wide: "wide";
113
+ }>>;
114
+ labelStyle: z.ZodMiniOptional<z.ZodMiniEnum<{
115
+ above: "above";
116
+ floating: "floating";
117
+ outlined: "outlined";
118
+ }>>;
119
+ mode: z.ZodMiniOptional<z.ZodMiniEnum<{
120
+ light: "light";
121
+ dark: "dark";
122
+ system: "system";
123
+ }>>;
124
+ tokens: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
125
+ labels: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
126
+ }, z.core.$strip>>;
127
+ }, z.core.$strip>;
128
+ readonly PREFILL_SET: z.ZodMiniObject<{
129
+ prefill: z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>;
130
+ }, z.core.$strip>;
131
+ readonly FOCUS_REQUEST: z.ZodMiniObject<{
132
+ field: z.ZodMiniOptional<z.ZodMiniString<string>>;
133
+ }, z.core.$strip>;
134
+ readonly BLUR_REQUEST: z.ZodMiniObject<{}, z.core.$strip>;
135
+ readonly SUBMIT_REQUEST: z.ZodMiniObject<{}, z.core.$strip>;
136
+ readonly SESSION_UPDATE: z.ZodMiniObject<{
137
+ sessionToken: z.ZodMiniString<string>;
138
+ replace: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
139
+ }, z.core.$strip>;
140
+ readonly DESTROY: z.ZodMiniObject<{}, z.core.$strip>;
141
+ readonly PROTOCOL_ERROR: z.ZodMiniObject<{
142
+ originalType: z.ZodMiniString<string>;
143
+ reason: z.ZodMiniString<string>;
144
+ }, z.core.$strip>;
145
+ };
146
+ export type OutboundType = keyof typeof outboundMessages;
147
+ export type OutboundPayloads = {
148
+ [K in OutboundType]: z.infer<(typeof outboundMessages)[K]>;
149
+ };
150
+ /**
151
+ * The emitter events every component shares, keyed by the names partners
152
+ * subscribe to. Payload types come from the wire schemas above, so the partner
153
+ * surface cannot drift from what the wire actually carries.
154
+ */
155
+ export type BaseComponentEventMap = {
156
+ ready: z.infer<(typeof baseInboundEvents)['READY']>;
157
+ rendered: Record<string, never>;
158
+ message: ProtocolMessageEvent;
159
+ success: Record<string, unknown>;
160
+ change: z.infer<(typeof baseInboundEvents)['STATE_CHANGE']>;
161
+ error: ComponentError;
162
+ loading: z.infer<(typeof baseInboundEvents)['LOADING']>;
163
+ resize: z.infer<(typeof baseInboundEvents)['RESIZE']>;
164
+ };
@@ -0,0 +1,2 @@
1
+ export declare const MESSAGE_SOURCE: "payabli";
2
+ export declare const MESSAGE_VERSION: 1;
@@ -0,0 +1,65 @@
1
+ import * as z from 'zod/v4/mini';
2
+ /**
3
+ * Any zod schema whose output is `T`. The alias keeps consumers off zod
4
+ * internals: descriptors and schema maps are typed against this.
5
+ */
6
+ export type WireSchema<T = unknown> = z.core.$ZodType<T>;
7
+ export type Infer<S extends WireSchema> = z.infer<S>;
8
+ export type ParseResult<T> = {
9
+ ok: true;
10
+ value: T;
11
+ } | {
12
+ ok: false;
13
+ reason: string;
14
+ };
15
+ export declare const eventEnvelopeSchema: z.ZodMiniObject<{
16
+ source: z.ZodMiniLiteral<"payabli">;
17
+ version: z.ZodMiniLiteral<1>;
18
+ type: z.ZodMiniString<string>;
19
+ instanceId: z.ZodMiniString<string>;
20
+ payload: z.ZodMiniOptional<z.ZodMiniUnknown>;
21
+ }, z.core.$strip>;
22
+ export type EventEnvelope = z.infer<typeof eventEnvelopeSchema>;
23
+ /**
24
+ * Reads a raw postMessage payload as a protocol envelope. Anything that is not
25
+ * an envelope of this protocol version returns null: the `message` event is a
26
+ * channel shared with the whole page, so foreign traffic is dropped, not
27
+ * reported.
28
+ */
29
+ export declare function parseEnvelope(data: unknown): EventEnvelope | null;
30
+ /**
31
+ * Validates one payload against its wire schema and reports failures in the
32
+ * `ParseResult` shape the SDK turns into PROTOCOL_ERROR messages.
33
+ */
34
+ export declare function parsePayload<S extends WireSchema>(schema: S, value: unknown, path: string): ParseResult<z.infer<S>>;
35
+ export type SchemaMap = Record<string, WireSchema>;
36
+ type SnakeToCamel<S extends string> = S extends `${infer Head}_${infer Tail}` ? `${Lowercase<Head>}${Capitalize<SnakeToCamel<Tail>>}` : Lowercase<S>;
37
+ /**
38
+ * The partner-facing event map a wire schema map defines: wire types become
39
+ * camelCase event names (`METHOD_CHANGE` → `methodChange`) and payload types
40
+ * are inferred from the schemas. One definition serves both the wire and the
41
+ * partner surface, so they cannot drift.
42
+ */
43
+ export type InferEvents<Events extends SchemaMap> = {
44
+ [K in keyof Events & string as SnakeToCamel<K>]: Infer<Events[K]>;
45
+ };
46
+ /** The discriminated union of `{ type, payload }` pairs a schema map defines. */
47
+ export type MessageOf<Events extends SchemaMap> = {
48
+ [K in keyof Events & string]: {
49
+ type: K;
50
+ payload: z.infer<Events[K]>;
51
+ };
52
+ }[keyof Events & string];
53
+ /**
54
+ * Validates one envelope against a schema map and returns the typed message.
55
+ * Own-property lookup only: a wire type like "constructor" must resolve to
56
+ * "unknown type", never to Object.prototype.
57
+ */
58
+ export declare function parseMessage<Events extends SchemaMap>(envelope: EventEnvelope, events: Events): ParseResult<MessageOf<Events>>;
59
+ /** The SDK's `message` debug event: every message it received or sent. */
60
+ export type ProtocolMessageEvent = {
61
+ direction: 'inbound' | 'outbound';
62
+ type: string;
63
+ payload: Record<string, unknown>;
64
+ };
65
+ export {};
@@ -0,0 +1,43 @@
1
+ import type { WireSchema } from './protocol/envelope.js';
2
+ import type { EventMap } from './shared.js';
3
+ export interface ComponentDefinition<Options, Events> {
4
+ options: Options;
5
+ events: Events;
6
+ }
7
+ /** Component folders add entries through declaration merging. */
8
+ export interface ComponentDefinitions {
9
+ }
10
+ export type ComponentType = Extract<keyof ComponentDefinitions, string>;
11
+ type DefinitionOptions<T extends ComponentType> = ComponentDefinitions[T] extends ComponentDefinition<infer Options, unknown> ? Options : never;
12
+ type DefinitionEvents<T extends ComponentType> = ComponentDefinitions[T] extends ComponentDefinition<unknown, infer Events> ? Events : never;
13
+ export type ComponentOptions<T extends ComponentType> = T extends ComponentType ? DefinitionOptions<T> : never;
14
+ export type ComponentEventMap<T extends ComponentType> = T extends ComponentType ? EventMap & DefinitionEvents<T> : never;
15
+ export type ComponentEventKey<T extends ComponentType> = keyof ComponentEventMap<T>;
16
+ export type ComponentEventName<T extends ComponentType> = T extends ComponentType ? Extract<ComponentEventKey<T>, string> : never;
17
+ /**
18
+ * Routes one wire type to the emitter event it becomes. The schema is the
19
+ * shared wire contract from the component's own `schema.ts` — the same object
20
+ * payhub emits through, so the two sides cannot drift.
21
+ */
22
+ export type EventSchemaDescriptor<EventName extends string = string> = {
23
+ event: EventName;
24
+ schema: WireSchema<Record<string, unknown>>;
25
+ };
26
+ export type ComponentDescriptor<T extends ComponentType = ComponentType> = {
27
+ type: T;
28
+ displayName: string;
29
+ embedPath: `/embed/${string}`;
30
+ /**
31
+ * Wire schema for CONFIG_SET.options. Payhub parses the options payload
32
+ * with this same object, so the partner-facing options type and the
33
+ * validator cannot drift.
34
+ */
35
+ optionsSchema: WireSchema<ComponentOptions<T>>;
36
+ eventSchemas: Readonly<Record<string, EventSchemaDescriptor<ComponentEventName<T>>>>;
37
+ };
38
+ export declare const componentDescriptors: ReadonlyMap<ComponentType, ComponentDescriptor>;
39
+ /** Kept in registration order to preserve the former COMPONENT_TYPES value. */
40
+ export declare const componentTypes: ComponentType[];
41
+ export declare function register<T extends ComponentType>(descriptor: ComponentDescriptor<T>): ComponentDescriptor<T>;
42
+ export declare function getComponentDescriptor<T extends ComponentType>(type: T): ComponentDescriptor<T> | undefined;
43
+ export {};
package/dist/sdk.d.ts ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The partner-facing SDK surface, defined once.
3
+ *
4
+ * The CDN script implements these types (`ComponentInstance implements
5
+ * ComponentHandle`, `PayabliFactory implements PayabliInstance`) and the npm
6
+ * wrapper re-exports them, so the surface the wrapper advertises is the one
7
+ * the script is compiled against.
8
+ */
9
+ import type { ComponentEventKey, ComponentEventMap, ComponentOptions, ComponentType } from './registry.js';
10
+ import type { AppearanceOptions } from './protocol/base.js';
11
+ export interface Session {
12
+ /** Session JWT returned by `POST /v2/{entryName}/Session/init`. */
13
+ sessionToken: string;
14
+ /**
15
+ * Signed render token from the same response. The SDK puts it in the iframe URL as the
16
+ * `rt` parameter, where it identifies the entrypoint and carries the origin allowlist.
17
+ * It authenticates no API call. Every refresh returns a fresh one.
18
+ */
19
+ renderToken: string;
20
+ /** Organization or paypoint slug the session belongs to. Used to build the refresh URL. */
21
+ entryName: string;
22
+ environment: string;
23
+ /** ISO 8601 expiry of `sessionToken`. The SDK refreshes at ~80% of the remaining time. */
24
+ expiresAt: string;
25
+ }
26
+ export interface PayabliConfig {
27
+ session: Session;
28
+ }
29
+ export interface CreateOptions<T extends ComponentType = ComponentType> {
30
+ appearance?: AppearanceOptions;
31
+ options?: ComponentOptions<T>;
32
+ prefill?: Record<string, string>;
33
+ locale?: string;
34
+ timeout?: number;
35
+ }
36
+ export type MountOptions = {
37
+ height?: number;
38
+ maxHeight?: number;
39
+ };
40
+ export type SessionEventPayload = {
41
+ code: string;
42
+ message: string;
43
+ recoverable: boolean;
44
+ details?: Record<string, unknown>;
45
+ };
46
+ export type SessionEventMap = {
47
+ sessionExpired: SessionEventPayload;
48
+ sessionError: SessionEventPayload;
49
+ };
50
+ export type SessionEventKey = keyof SessionEventMap;
51
+ export type ComponentHandle<T extends ComponentType = ComponentType> = {
52
+ mount: (target: string | HTMLElement, options?: MountOptions) => void;
53
+ unmount: () => void;
54
+ submit: () => Promise<Record<string, unknown>>;
55
+ focus: (field?: string) => void;
56
+ blur: () => void;
57
+ update: (options: CreateOptions<T>) => void;
58
+ destroy: () => void;
59
+ on: <K extends ComponentEventKey<T>>(event: K, handler: (payload: ComponentEventMap<T>[K]) => void, options?: {
60
+ signal?: AbortSignal;
61
+ }) => () => void;
62
+ off: <K extends ComponentEventKey<T>>(event: K, handler: (payload: ComponentEventMap<T>[K]) => void) => void;
63
+ addEventListener: <K extends ComponentEventKey<T>>(event: K, handler: (payload: ComponentEventMap<T>[K]) => void, options?: {
64
+ signal?: AbortSignal;
65
+ }) => void;
66
+ removeEventListener: <K extends ComponentEventKey<T>>(event: K, handler: (payload: ComponentEventMap<T>[K]) => void) => void;
67
+ };
68
+ export type PayabliInstance = {
69
+ create: <T extends ComponentType>(type: T, options?: CreateOptions<T>) => ComponentHandle<T>;
70
+ on: <K extends SessionEventKey>(event: K, handler: (payload: SessionEventMap[K]) => void, options?: {
71
+ signal?: AbortSignal;
72
+ }) => () => void;
73
+ updateSession: (session: Session) => void;
74
+ destroy: () => void;
75
+ };
76
+ export type PayabliConstructor = (config: PayabliConfig) => PayabliInstance;
@@ -0,0 +1,9 @@
1
+ import type { BaseComponentEventMap } from './protocol/base.js';
2
+ export declare const BASE_COMPONENT_EVENT_NAMES: readonly ["ready", "rendered", "message", "success", "change", "error", "loading", "resize"];
3
+ /**
4
+ * The events every component shares. A component definition adds its own on
5
+ * top through `ComponentDefinitions` (see `registry.ts`).
6
+ */
7
+ export type EventMap = BaseComponentEventMap;
8
+ export type EventKey = keyof EventMap;
9
+ export type Listener<T> = (payload: T) => void;
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@payabli/component-contracts",
3
+ "version": "0.1.0",
4
+ "description": "Wire schemas, component registry, and partner-facing types shared by the Payabli embedded components SDK and payhub.",
5
+ "private": false,
6
+ "license": "UNLICENSED",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/payabli/components-web.git",
10
+ "directory": "packages/component-contracts"
11
+ },
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "main": "dist/index.js",
15
+ "module": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "default": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "!dist/__tests__"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "dependencies": {
32
+ "zod": "^4.4.3"
33
+ },
34
+ "devDependencies": {
35
+ "tslib": "^2.8.1"
36
+ },
37
+ "scripts": {
38
+ "generate": "node scripts/generate-registry.mjs",
39
+ "build": "pnpm generate && rm -rf dist && rollup -c && tsc -p tsconfig.build.json --emitDeclarationOnly",
40
+ "lint": "pnpm generate && eslint src",
41
+ "typecheck": "pnpm generate && tsc -p tsconfig.json --noEmit",
42
+ "test": "pnpm generate && vitest run && pnpm build && node scripts/test-published-esm.mjs",
43
+ "pack:check": "publint && attw --pack . --profile esm-only"
44
+ }
45
+ }