@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.
- package/README.md +30 -0
- package/dist/aliases.d.ts +2 -0
- package/dist/errors.d.ts +27 -0
- package/dist/generated.d.ts +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1721 -0
- package/dist/payin/definition.d.ts +81 -0
- package/dist/payin/schema.d.ts +72 -0
- package/dist/protocol/base.d.ts +164 -0
- package/dist/protocol/constants.d.ts +2 -0
- package/dist/protocol/envelope.d.ts +65 -0
- package/dist/registry.d.ts +43 -0
- package/dist/sdk.d.ts +76 -0
- package/dist/shared.d.ts +9 -0
- package/package.json +45 -0
|
@@ -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,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;
|
package/dist/shared.d.ts
ADDED
|
@@ -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
|
+
}
|