forgeframe 0.0.1 → 0.0.3
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 +62 -8
- package/dist/communication/messenger.d.ts +6 -0
- package/dist/constants.d.ts +1 -5
- package/dist/core/component.d.ts +5 -0
- package/dist/core/consumer.d.ts +39 -0
- package/dist/core/host.d.ts +43 -3
- package/dist/forgeframe.js +815 -600
- package/dist/forgeframe.umd.cjs +2 -2
- package/dist/index.d.ts +14 -3
- package/dist/props/index.d.ts +1 -1
- package/dist/props/normalize.d.ts +11 -0
- package/dist/props/schema.d.ts +11 -3
- package/dist/types.d.ts +2 -2
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -55,6 +55,7 @@ Imagine a payment company (like Stripe) wants to let merchants embed a checkout
|
|
|
55
55
|
## Table of Contents
|
|
56
56
|
|
|
57
57
|
- [Installation](#installation)
|
|
58
|
+
- [Start Here (Most Users)](#start-here-most-users)
|
|
58
59
|
- [Quick Start](#quick-start)
|
|
59
60
|
- [Step-by-Step Guide](#step-by-step-guide)
|
|
60
61
|
- [1. Define a Component](#1-define-a-component)
|
|
@@ -63,8 +64,8 @@ Imagine a payment company (like Stripe) wants to let merchants embed a checkout
|
|
|
63
64
|
- [4. Handle Events](#4-handle-events)
|
|
64
65
|
- [Props System](#props-system)
|
|
65
66
|
- [Host Window API (hostProps)](#host-window-api-hostprops)
|
|
66
|
-
- [Templates](#templates)
|
|
67
|
-
- [React Integration](#react-integration)
|
|
67
|
+
- [Templates (Advanced)](#templates-advanced)
|
|
68
|
+
- [React Integration (Optional)](#react-integration-optional)
|
|
68
69
|
- [Advanced Features](#advanced-features)
|
|
69
70
|
- [API Reference](#api-reference)
|
|
70
71
|
- [TypeScript](#typescript)
|
|
@@ -80,6 +81,17 @@ npm install forgeframe
|
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
84
|
+
## Start Here (Most Users)
|
|
85
|
+
|
|
86
|
+
Use this path for typical integrations:
|
|
87
|
+
|
|
88
|
+
1. Follow [Quick Start](#quick-start) to get a working component.
|
|
89
|
+
2. Use [Step-by-Step Guide](#step-by-step-guide) to add typed props and callbacks.
|
|
90
|
+
3. Use [Props System](#props-system) and [Host Window API (hostProps)](#host-window-api-hostprops) as your primary references.
|
|
91
|
+
4. Treat sections marked **Advanced** as optional unless you specifically need them.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
83
95
|
## Quick Start
|
|
84
96
|
|
|
85
97
|
> **`Consumer`**
|
|
@@ -108,7 +120,7 @@ await payment.render('#payment-container');
|
|
|
108
120
|
> **`Host`**
|
|
109
121
|
|
|
110
122
|
```typescript
|
|
111
|
-
import { type HostProps } from 'forgeframe';
|
|
123
|
+
import ForgeFrame, { type HostProps } from 'forgeframe';
|
|
112
124
|
|
|
113
125
|
interface PaymentProps {
|
|
114
126
|
amount: number;
|
|
@@ -121,6 +133,10 @@ declare global {
|
|
|
121
133
|
}
|
|
122
134
|
}
|
|
123
135
|
|
|
136
|
+
// Required when the host page doesn't use ForgeFrame.create().
|
|
137
|
+
// If your host defines a component via create(), init is handled automatically.
|
|
138
|
+
ForgeFrame.initHost();
|
|
139
|
+
|
|
124
140
|
const { amount, onSuccess, close } = window.hostProps;
|
|
125
141
|
|
|
126
142
|
document.getElementById('total')!.textContent = `$${amount}`;
|
|
@@ -180,7 +196,7 @@ const LoginForm = ForgeFrame.create<LoginProps>({
|
|
|
180
196
|
The host page runs inside the iframe at the URL you specified. It receives props via `window.hostProps`.
|
|
181
197
|
|
|
182
198
|
```typescript
|
|
183
|
-
import { type HostProps } from 'forgeframe';
|
|
199
|
+
import ForgeFrame, { type HostProps } from 'forgeframe';
|
|
184
200
|
|
|
185
201
|
interface LoginProps {
|
|
186
202
|
email?: string;
|
|
@@ -194,6 +210,10 @@ declare global {
|
|
|
194
210
|
}
|
|
195
211
|
}
|
|
196
212
|
|
|
213
|
+
// Required when the host page doesn't use ForgeFrame.create().
|
|
214
|
+
// If your host defines a component via create(), init is handled automatically.
|
|
215
|
+
ForgeFrame.initHost();
|
|
216
|
+
|
|
197
217
|
const { email, onLogin, onCancel, close } = window.hostProps;
|
|
198
218
|
|
|
199
219
|
if (email) document.getElementById('email')!.value = email;
|
|
@@ -218,7 +238,8 @@ document.getElementById('cancel')!.onclick = async () => {
|
|
|
218
238
|
<summary>Explanation</summary>
|
|
219
239
|
|
|
220
240
|
- **`HostProps<LoginProps>`**: Combines your props with built-in methods (`close`, `resize`, etc.)
|
|
221
|
-
- **`
|
|
241
|
+
- **`ForgeFrame.initHost()`**: Flushes host initialization so the consumer can complete render. Only required when the host page doesn't use `ForgeFrame.create()` — if your host defines a component via `create()`, init is handled automatically.
|
|
242
|
+
- **`window.hostProps`**: Contains all props passed from the consumer plus built-in methods
|
|
222
243
|
- **`close()`**: Built-in method to close the iframe/popup
|
|
223
244
|
|
|
224
245
|
</details>
|
|
@@ -272,6 +293,8 @@ await instance.render('#container');
|
|
|
272
293
|
| `resize` | Component was resized |
|
|
273
294
|
| `focus` | Component received focus |
|
|
274
295
|
|
|
296
|
+
If all you need is embed + typed props + callbacks, you can stop here and use the API reference as needed.
|
|
297
|
+
|
|
275
298
|
---
|
|
276
299
|
|
|
277
300
|
## Props System
|
|
@@ -377,6 +400,28 @@ const MyComponent = ForgeFrame.create({
|
|
|
377
400
|
});
|
|
378
401
|
```
|
|
379
402
|
|
|
403
|
+
### Passing Props via URL or POST Body (Advanced)
|
|
404
|
+
|
|
405
|
+
Use prop definition flags to include specific values in the host page's initial HTTP request:
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
const Checkout = ForgeFrame.create({
|
|
409
|
+
tag: 'checkout',
|
|
410
|
+
url: 'https://payments.example.com/checkout',
|
|
411
|
+
props: {
|
|
412
|
+
sessionToken: { schema: prop.string(), queryParam: true }, // ?sessionToken=...
|
|
413
|
+
csrf: { schema: prop.string(), bodyParam: true }, // POST body field "csrf"
|
|
414
|
+
userId: { schema: prop.string(), bodyParam: 'user_id' }, // custom body field name
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
- `queryParam`: appends to the URL query string for initial load.
|
|
420
|
+
- `bodyParam`: sends values in a hidden form `POST` for initial load (iframe and popup).
|
|
421
|
+
- `bodyParam` only affects the initial navigation; later `updateProps()` uses postMessage.
|
|
422
|
+
- Object values are JSON-stringified. Function and `undefined` values are skipped.
|
|
423
|
+
- Most apps do not need this unless the host server requires initial URL/body parameters.
|
|
424
|
+
|
|
380
425
|
### Updating Props
|
|
381
426
|
|
|
382
427
|
Props can be updated after rendering.
|
|
@@ -404,7 +449,7 @@ In host windows, `window.hostProps` provides access to props and control methods
|
|
|
404
449
|
### TypeScript Setup
|
|
405
450
|
|
|
406
451
|
```typescript
|
|
407
|
-
import { type HostProps } from 'forgeframe';
|
|
452
|
+
import ForgeFrame, { type HostProps } from 'forgeframe';
|
|
408
453
|
|
|
409
454
|
interface MyProps {
|
|
410
455
|
email: string;
|
|
@@ -417,6 +462,10 @@ declare global {
|
|
|
417
462
|
}
|
|
418
463
|
}
|
|
419
464
|
|
|
465
|
+
// Required when the host page doesn't use ForgeFrame.create().
|
|
466
|
+
// If your host defines a component via create(), init is handled automatically.
|
|
467
|
+
ForgeFrame.initHost();
|
|
468
|
+
|
|
420
469
|
const { email, onLogin, close, resize } = window.hostProps!;
|
|
421
470
|
```
|
|
422
471
|
|
|
@@ -494,7 +543,9 @@ const data = await instance.exports.getFormData();
|
|
|
494
543
|
|
|
495
544
|
---
|
|
496
545
|
|
|
497
|
-
## Templates
|
|
546
|
+
## Templates (Advanced)
|
|
547
|
+
|
|
548
|
+
Use this section only when you need custom containers/loading UI beyond the default behavior.
|
|
498
549
|
|
|
499
550
|
### Container Template
|
|
500
551
|
|
|
@@ -568,7 +619,7 @@ const MyComponent = ForgeFrame.create({
|
|
|
568
619
|
|
|
569
620
|
---
|
|
570
621
|
|
|
571
|
-
## React Integration
|
|
622
|
+
## React Integration (Optional)
|
|
572
623
|
|
|
573
624
|
### Basic Usage
|
|
574
625
|
|
|
@@ -639,6 +690,8 @@ const ProfileReact = createComponent(ProfileComponent);
|
|
|
639
690
|
|
|
640
691
|
## Advanced Features
|
|
641
692
|
|
|
693
|
+
Most integrations can skip this section initially and return only when a specific requirement appears.
|
|
694
|
+
|
|
642
695
|
### Popup Windows
|
|
643
696
|
|
|
644
697
|
Render as a popup instead of iframe.
|
|
@@ -740,6 +793,7 @@ ForgeFrame.destroyByTag(tag) // Destroy all instances of a tag
|
|
|
740
793
|
ForgeFrame.destroyAll() // Destroy all instances
|
|
741
794
|
ForgeFrame.isHost() // Check if in host context
|
|
742
795
|
ForgeFrame.isEmbedded() // Alias for isHost() - more intuitive naming
|
|
796
|
+
ForgeFrame.initHost() // Flush host handshake (only needed when create() is not used on the host)
|
|
743
797
|
ForgeFrame.getHostProps() // Get hostProps in host context
|
|
744
798
|
ForgeFrame.isStandardSchema(val) // Check if value is a Standard Schema
|
|
745
799
|
|
|
@@ -72,6 +72,12 @@ export declare class Messenger {
|
|
|
72
72
|
* @param domain - Domain pattern to trust (string, RegExp, or array)
|
|
73
73
|
*/
|
|
74
74
|
addTrustedDomain(domain: DomainMatcher): void;
|
|
75
|
+
/**
|
|
76
|
+
* Removes a trusted domain from this messenger.
|
|
77
|
+
*
|
|
78
|
+
* @param domain - Domain pattern to remove (string, RegExp, or array)
|
|
79
|
+
*/
|
|
80
|
+
removeTrustedDomain(domain: DomainMatcher): void;
|
|
75
81
|
/**
|
|
76
82
|
* Checks if an origin is trusted.
|
|
77
83
|
*
|
package/dist/constants.d.ts
CHANGED
|
@@ -154,8 +154,4 @@ export type MessageName = (typeof MESSAGE_NAME)[keyof typeof MESSAGE_NAME];
|
|
|
154
154
|
* @internal
|
|
155
155
|
*/
|
|
156
156
|
export declare const WINDOW_NAME_PREFIX = "__forgeframe__";
|
|
157
|
-
|
|
158
|
-
* Current library version.
|
|
159
|
-
* @public
|
|
160
|
-
*/
|
|
161
|
-
export declare const VERSION = "0.0.1";
|
|
157
|
+
export declare const VERSION: string;
|
package/dist/core/component.d.ts
CHANGED
|
@@ -60,6 +60,11 @@ export declare function create<P extends Record<string, unknown> = Record<string
|
|
|
60
60
|
* @public
|
|
61
61
|
*/
|
|
62
62
|
export declare function getComponent<P extends Record<string, unknown> = Record<string, unknown>, X = unknown>(tag: string): ForgeFrameComponent<P, X> | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Returns the internal options metadata for a component factory.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export declare function getComponentOptions<P extends Record<string, unknown> = Record<string, unknown>, X = unknown>(component: ForgeFrameComponent<P, X>): ComponentOptions<P> | undefined;
|
|
63
68
|
/**
|
|
64
69
|
* Destroys a single component instance.
|
|
65
70
|
*
|
package/dist/core/consumer.d.ts
CHANGED
|
@@ -60,6 +60,10 @@ export declare class ConsumerComponent<P extends Record<string, unknown>, X = un
|
|
|
60
60
|
/** @internal */
|
|
61
61
|
private hostWindow;
|
|
62
62
|
/** @internal */
|
|
63
|
+
private openedHostDomain;
|
|
64
|
+
/** @internal */
|
|
65
|
+
private dynamicUrlTrustedOrigin;
|
|
66
|
+
/** @internal */
|
|
63
67
|
private iframe;
|
|
64
68
|
/** @internal */
|
|
65
69
|
private container;
|
|
@@ -174,6 +178,31 @@ export declare class ConsumerComponent<P extends Record<string, unknown>, X = un
|
|
|
174
178
|
* @internal
|
|
175
179
|
*/
|
|
176
180
|
private normalizeOptions;
|
|
181
|
+
/**
|
|
182
|
+
* Resolves the host URL from static or function options.
|
|
183
|
+
* @internal
|
|
184
|
+
*/
|
|
185
|
+
private resolveUrl;
|
|
186
|
+
/**
|
|
187
|
+
* Resolves dimensions from static or function options.
|
|
188
|
+
* @internal
|
|
189
|
+
*/
|
|
190
|
+
private resolveDimensions;
|
|
191
|
+
/**
|
|
192
|
+
* Resolves a URL to an origin, supporting relative URLs.
|
|
193
|
+
* @internal
|
|
194
|
+
*/
|
|
195
|
+
private resolveUrlOrigin;
|
|
196
|
+
/**
|
|
197
|
+
* Returns true when the domain option explicitly includes this origin.
|
|
198
|
+
* @internal
|
|
199
|
+
*/
|
|
200
|
+
private isExplicitDomainTrust;
|
|
201
|
+
/**
|
|
202
|
+
* Ensures the messenger trusts the origin for a resolved host URL.
|
|
203
|
+
* @internal
|
|
204
|
+
*/
|
|
205
|
+
private syncTrustedDomainForUrl;
|
|
177
206
|
/**
|
|
178
207
|
* Creates the prop context passed to prop callbacks and validators.
|
|
179
208
|
* @internal
|
|
@@ -210,6 +239,16 @@ export declare class ConsumerComponent<P extends Record<string, unknown>, X = un
|
|
|
210
239
|
* @internal
|
|
211
240
|
*/
|
|
212
241
|
private buildUrl;
|
|
242
|
+
/**
|
|
243
|
+
* Builds POST body parameters from props marked with bodyParam.
|
|
244
|
+
* @internal
|
|
245
|
+
*/
|
|
246
|
+
private buildBodyParams;
|
|
247
|
+
/**
|
|
248
|
+
* Submits a hidden form to navigate a target window via POST.
|
|
249
|
+
* @internal
|
|
250
|
+
*/
|
|
251
|
+
private submitBodyForm;
|
|
213
252
|
/**
|
|
214
253
|
* Builds the window.name payload for the host window.
|
|
215
254
|
* @internal
|
package/dist/core/host.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* or popup and handles communication with the consumer window. It also provides
|
|
8
8
|
* utilities for detecting host context and accessing hostProps.
|
|
9
9
|
*/
|
|
10
|
-
import type { HostProps, WindowNamePayload, PropsDefinition } from '../types';
|
|
10
|
+
import type { HostProps, WindowNamePayload, PropsDefinition, DomainMatcher } from '../types';
|
|
11
11
|
import { EventEmitter } from '../events/emitter';
|
|
12
12
|
/**
|
|
13
13
|
* Host-side component implementation.
|
|
@@ -32,6 +32,8 @@ import { EventEmitter } from '../events/emitter';
|
|
|
32
32
|
*/
|
|
33
33
|
export declare class HostComponent<P extends Record<string, unknown>> {
|
|
34
34
|
private propDefinitions;
|
|
35
|
+
private allowedConsumerDomains?;
|
|
36
|
+
private deferInit;
|
|
35
37
|
/** The hostProps object containing props and control methods passed from the consumer. */
|
|
36
38
|
hostProps: HostProps<P>;
|
|
37
39
|
/** Event emitter for lifecycle events. */
|
|
@@ -54,13 +56,43 @@ export declare class HostComponent<P extends Record<string, unknown>> {
|
|
|
54
56
|
private consumerProps;
|
|
55
57
|
/** @internal */
|
|
56
58
|
private initError;
|
|
59
|
+
/** @internal */
|
|
60
|
+
private destroyed;
|
|
61
|
+
/** @internal */
|
|
62
|
+
private initSent;
|
|
63
|
+
/** @internal */
|
|
64
|
+
private deferredInitFlushScheduled;
|
|
57
65
|
/**
|
|
58
66
|
* Creates a new HostComponent instance.
|
|
59
67
|
*
|
|
60
68
|
* @param payload - The payload parsed from window.name
|
|
61
69
|
* @param propDefinitions - Optional prop definitions for deserialization
|
|
70
|
+
* @param allowedConsumerDomains - Optional allowlist of consumer domains
|
|
71
|
+
* @param deferInit - Whether to defer INIT until a later explicit flush
|
|
72
|
+
*/
|
|
73
|
+
constructor(payload: WindowNamePayload<P>, propDefinitions?: PropsDefinition<P>, allowedConsumerDomains?: DomainMatcher | undefined, deferInit?: boolean);
|
|
74
|
+
/**
|
|
75
|
+
* Ensures the INIT handshake is sent at most once.
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
flushInit(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Schedules deferred INIT flush on the next microtask.
|
|
81
|
+
* This preserves legacy hostProps-only usage while giving same-tick
|
|
82
|
+
* host configuration a chance to run allowlist checks first.
|
|
83
|
+
* @internal
|
|
62
84
|
*/
|
|
63
|
-
|
|
85
|
+
private scheduleDeferredInitFlush;
|
|
86
|
+
/**
|
|
87
|
+
* Exposes hostProps on window and lazily flushes deferred init on first access.
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
private exposeHostProps;
|
|
91
|
+
/**
|
|
92
|
+
* Validates that the consumer domain is allowed.
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
private validateConsumerDomain;
|
|
64
96
|
/**
|
|
65
97
|
* Returns the hostProps object.
|
|
66
98
|
*
|
|
@@ -176,7 +208,9 @@ export declare class HostComponent<P extends Record<string, unknown>> {
|
|
|
176
208
|
*
|
|
177
209
|
* @public
|
|
178
210
|
*/
|
|
179
|
-
export declare function initHost<P extends Record<string, unknown>>(propDefinitions?: PropsDefinition<P
|
|
211
|
+
export declare function initHost<P extends Record<string, unknown>>(propDefinitions?: PropsDefinition<P>, allowedConsumerDomains?: DomainMatcher, options?: {
|
|
212
|
+
deferInit?: boolean;
|
|
213
|
+
}): HostComponent<P> | null;
|
|
180
214
|
/**
|
|
181
215
|
* Gets the current host component instance.
|
|
182
216
|
*
|
|
@@ -247,3 +281,9 @@ export declare function isEmbedded(): boolean;
|
|
|
247
281
|
* @public
|
|
248
282
|
*/
|
|
249
283
|
export declare function getHostProps<P extends Record<string, unknown>>(): HostProps<P> | undefined;
|
|
284
|
+
/**
|
|
285
|
+
* Clears and destroys the global host instance.
|
|
286
|
+
* Primarily intended for testing.
|
|
287
|
+
* @internal
|
|
288
|
+
*/
|
|
289
|
+
export declare function clearHostInstance(): void;
|