@notabene/javascript-sdk 2.0.0-next.2 → 2.0.0-next.21
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/LICENSE.md +21 -0
- package/README.md +289 -233
- package/dist/js/notabene.js +1 -0
- package/dist/notabene.cjs +1 -1
- package/dist/notabene.d.ts +1092 -214
- package/dist/notabene.js +284 -113
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +36 -26
- package/src/__tests__/notabene.test.ts +43 -0
- package/src/components/EmbeddedComponent.ts +141 -22
- package/src/components/__tests__/EmbeddedComponent.test.ts +73 -20
- package/src/ivms/types.ts +230 -152
- package/src/locales.ts +47 -0
- package/src/notabene.ts +247 -90
- package/src/types.ts +769 -152
- package/src/utils/MessageEventManager.ts +70 -12
- package/src/utils/__tests__/MessageEventManager.test.ts +13 -5
- package/src/utils/arbitraries.ts +9 -4
- package/.editorconfig +0 -10
- package/.gitlab-ci.yml +0 -85
- package/.husky/commit-msg +0 -4
- package/.husky/pre-commit +0 -4
- package/.husky/pre-push +0 -4
- package/.prettierrc +0 -4
- package/.releaserc.json +0 -16
- package/.vscode/extensions.json +0 -3
- package/.vscode/settings.json +0 -11
- package/.yarn/releases/yarn-berry.cjs +0 -925
- package/.yarnrc.yml +0 -3
- package/CODEOWNERS +0 -1
- package/api-extractor.json +0 -434
- package/eslint.config.js +0 -24
- package/etc/javascript-sdk.api.md +0 -363
- package/index.html +0 -137
- package/temp/javascript-sdk.api.json +0 -3509
- package/temp/javascript-sdk.api.md +0 -363
- package/ts-out/src/__tests__/notabene.test.d.ts +0 -1
- package/ts-out/src/__tests__/notabene.test.js +0 -88
- package/ts-out/src/arbitraries.d.ts +0 -4
- package/ts-out/src/arbitraries.js +0 -8
- package/ts-out/src/components/EmbeddedComponent.d.ts +0 -25
- package/ts-out/src/components/EmbeddedComponent.js +0 -87
- package/ts-out/src/components/__tests__/EmbeddedComponent.test.d.ts +0 -1
- package/ts-out/src/components/__tests__/EmbeddedComponent.test.js +0 -132
- package/ts-out/src/ivms/types.d.ts +0 -252
- package/ts-out/src/ivms/types.js +0 -1
- package/ts-out/src/notabene.d.ts +0 -35
- package/ts-out/src/notabene.js +0 -59
- package/ts-out/src/types.d.ts +0 -357
- package/ts-out/src/types.js +0 -85
- package/ts-out/src/utils/MessageEventManager.d.ts +0 -12
- package/ts-out/src/utils/MessageEventManager.js +0 -45
- package/ts-out/src/utils/__tests__/MessageEventManager.test.d.ts +0 -1
- package/ts-out/src/utils/__tests__/MessageEventManager.test.js +0 -73
- package/ts-out/src/utils/arbitraries.d.ts +0 -6
- package/ts-out/src/utils/arbitraries.js +0 -7
- package/ts-out/src/utils/caip.d.ts +0 -13
- package/ts-out/src/utils/caip.js +0 -15
- package/ts-out/src/utils/urls.d.ts +0 -1
- package/ts-out/src/utils/urls.js +0 -14
- package/ts-out/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.json +0 -22
- package/tsconfig.tsbuildinfo +0 -1
- package/vite.config.js +0 -13
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
CMType,
|
|
3
3
|
HMType,
|
|
4
4
|
HostMessage,
|
|
5
|
-
Transaction,
|
|
6
5
|
TransactionResponse,
|
|
7
6
|
ValidationError,
|
|
8
7
|
} from '../types';
|
|
@@ -15,23 +14,32 @@ import {
|
|
|
15
14
|
* An embedded Notabene component
|
|
16
15
|
* @public
|
|
17
16
|
*/
|
|
18
|
-
|
|
17
|
+
|
|
18
|
+
export default class EmbeddedComponent<V, O> {
|
|
19
19
|
private _url: string;
|
|
20
|
-
private _value: Partial<
|
|
20
|
+
private _value: Partial<V>;
|
|
21
|
+
private _options?: O;
|
|
21
22
|
private _errors: ValidationError[] = [];
|
|
22
23
|
|
|
23
24
|
private iframe?: HTMLIFrameElement;
|
|
24
|
-
private eventManager: MessageEventManager
|
|
25
|
-
private
|
|
25
|
+
private eventManager: MessageEventManager<V, O>;
|
|
26
|
+
private modal?: HTMLDialogElement;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates an instance of EmbeddedComponent.
|
|
30
|
+
* @param url - The URL of the embedded component
|
|
31
|
+
* @param value - The initial transaction value
|
|
32
|
+
*/
|
|
26
33
|
|
|
27
|
-
constructor(url: string, value: Partial<
|
|
34
|
+
constructor(url: string, value: Partial<V>, options?: O) {
|
|
28
35
|
this._url = url;
|
|
29
36
|
this._value = value;
|
|
30
|
-
this.
|
|
37
|
+
this._options = options;
|
|
38
|
+
this.eventManager = new MessageEventManager<V, O>();
|
|
31
39
|
this.on(CMType.INVALID, (message) => {
|
|
32
40
|
if (message.type === CMType.INVALID) {
|
|
33
41
|
this._errors = message.errors;
|
|
34
|
-
this._value = message.value as
|
|
42
|
+
this._value = message.value as V;
|
|
35
43
|
}
|
|
36
44
|
});
|
|
37
45
|
this.on(CMType.RESIZE, (message) => {
|
|
@@ -40,64 +48,128 @@ export default class EmbeddedComponent {
|
|
|
40
48
|
}
|
|
41
49
|
});
|
|
42
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Gets the URL of the embedded component
|
|
53
|
+
* @returns The URL of the embedded component
|
|
54
|
+
*/
|
|
43
55
|
|
|
44
56
|
public get url(): string {
|
|
45
57
|
return this._url;
|
|
46
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Gets the current transaction value
|
|
61
|
+
* @returns The current transaction value
|
|
62
|
+
*/
|
|
47
63
|
|
|
48
|
-
public get value(): Partial<
|
|
64
|
+
public get value(): Partial<V> {
|
|
49
65
|
return this._value;
|
|
50
66
|
}
|
|
51
67
|
|
|
68
|
+
public get options(): O | undefined {
|
|
69
|
+
return this._options;
|
|
70
|
+
}
|
|
71
|
+
|
|
52
72
|
public get errors(): ValidationError[] {
|
|
53
73
|
return this._errors;
|
|
54
74
|
}
|
|
55
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Opens the component URL in the current window
|
|
78
|
+
*/
|
|
79
|
+
|
|
56
80
|
public open() {
|
|
57
81
|
document.location.href = this.url;
|
|
58
82
|
}
|
|
59
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Mounts the component to a parent element
|
|
86
|
+
* @param parentId - The ID of the parent element
|
|
87
|
+
* @throws Will throw an error if the parent element is not found
|
|
88
|
+
*/
|
|
89
|
+
|
|
60
90
|
mount(parentId: string) {
|
|
91
|
+
const parent = document.querySelector(parentId);
|
|
92
|
+
if (!parent) throw new Error(`parentID ${parentId} not found`);
|
|
93
|
+
this.embed(parent);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Embeds the component into a parent element
|
|
98
|
+
* @param parent - The parent element to embed the component into
|
|
99
|
+
*/
|
|
100
|
+
embed(parent: Element, modal: boolean = false) {
|
|
101
|
+
// console.log(this.url);
|
|
102
|
+
this.removeEmbed();
|
|
61
103
|
this.iframe = document.createElement('iframe');
|
|
62
|
-
this.iframe.src = this.url;
|
|
104
|
+
this.iframe.src = this.url + (!modal ? '&embedded=true' : '');
|
|
105
|
+
this.iframe.allow = 'web-share';
|
|
63
106
|
this.iframe.style.width = '100%';
|
|
64
107
|
this.iframe.style.height = '100px';
|
|
65
108
|
this.iframe.style.border = 'none';
|
|
66
109
|
this.iframe.style.overflow = 'hidden';
|
|
110
|
+
// this.iframe.setAttribute('allowtransparency', 'true');
|
|
111
|
+
// this.iframe.style.backgroundColor = 'transparent';
|
|
112
|
+
parent.appendChild(this.iframe);
|
|
67
113
|
|
|
68
|
-
window.addEventListener('message', (event) => {
|
|
114
|
+
window.addEventListener('message', (event: MessageEvent) => {
|
|
69
115
|
if (event.source !== this.iframe?.contentWindow) {
|
|
70
116
|
return;
|
|
71
117
|
}
|
|
72
|
-
console.log('received message from iframe', event.data);
|
|
118
|
+
// console.log('received message from iframe', event.data);
|
|
73
119
|
this.eventManager?.setPort(event.ports[0]);
|
|
74
|
-
this.ready = true;
|
|
75
120
|
});
|
|
76
121
|
|
|
77
|
-
const parent = document.querySelector(parentId);
|
|
78
|
-
if (!parent) throw new Error(`parentID ${parentId} not found`);
|
|
79
|
-
parent.appendChild(this.iframe);
|
|
80
122
|
this.iframe?.contentWindow?.focus();
|
|
81
123
|
}
|
|
82
124
|
|
|
83
|
-
|
|
125
|
+
removeEmbed() {
|
|
126
|
+
if (this.iframe) this.iframe.remove();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Sends a message to the embedded component
|
|
131
|
+
* @param message - The message to send
|
|
132
|
+
*/
|
|
133
|
+
send(message: HostMessage<V, O>): void {
|
|
84
134
|
this.eventManager.send(message);
|
|
85
135
|
}
|
|
86
136
|
|
|
87
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Adds an event listener for a specific message type
|
|
139
|
+
* @param messageType - The type of message to listen for
|
|
140
|
+
* @param callback - The callback function to execute when the message is received
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
on(messageType: string, callback: MessageCallback<V>): void {
|
|
88
144
|
this.eventManager.on(messageType, callback);
|
|
89
145
|
}
|
|
90
146
|
|
|
91
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Removes an event listener for a specific message type
|
|
149
|
+
* @param messageType - The type of message to stop listening for
|
|
150
|
+
* @param callback - The callback function to remove
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
off(messageType: string, callback: MessageCallback<V>): void {
|
|
92
154
|
this.eventManager.off(messageType, callback);
|
|
93
155
|
}
|
|
94
156
|
|
|
95
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Updates the transaction value and sends an update message to the component
|
|
159
|
+
* @param value - The new transaction value
|
|
160
|
+
*/
|
|
161
|
+
update(value: Partial<V>, options?: O) {
|
|
96
162
|
this._value = value;
|
|
97
|
-
|
|
163
|
+
if (options) this._options = options;
|
|
164
|
+
this.send({ type: HMType.UPDATE, value, options: this._options });
|
|
98
165
|
}
|
|
99
166
|
|
|
100
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Waits for the component to complete and returns the transaction response
|
|
169
|
+
* @returns A promise that resolves with the transaction response
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
completion(): Promise<TransactionResponse<V>> {
|
|
101
173
|
return new Promise((resolve, reject) => {
|
|
102
174
|
this.on(CMType.COMPLETE, (message) => {
|
|
103
175
|
resolve((message as any).response);
|
|
@@ -107,4 +179,51 @@ export default class EmbeddedComponent {
|
|
|
107
179
|
});
|
|
108
180
|
});
|
|
109
181
|
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Opens the component in a modal dialog
|
|
185
|
+
*/
|
|
186
|
+
|
|
187
|
+
openModal(): Promise<TransactionResponse<V>> {
|
|
188
|
+
if (this.modal) {
|
|
189
|
+
this.closeModal();
|
|
190
|
+
}
|
|
191
|
+
this.modal = document.createElement('dialog');
|
|
192
|
+
this.modal.style.border = 'none';
|
|
193
|
+
this.modal.style.backgroundColor = 'white';
|
|
194
|
+
this.modal.style.maxWidth = '100vw';
|
|
195
|
+
this.modal.style.maxHeight = '100vh';
|
|
196
|
+
this.modal.style.width = '600px';
|
|
197
|
+
this.modal.style.height = '600px';
|
|
198
|
+
|
|
199
|
+
document.body.appendChild(this.modal);
|
|
200
|
+
this.embed(this.modal, true);
|
|
201
|
+
this.on(CMType.CANCEL, () => {
|
|
202
|
+
this.closeModal();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
this.on(CMType.COMPLETE, () => {
|
|
206
|
+
this.closeModal();
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
this.modal.showModal();
|
|
210
|
+
this.modal.addEventListener('click', () => {
|
|
211
|
+
// console.log('click');
|
|
212
|
+
this.closeModal();
|
|
213
|
+
});
|
|
214
|
+
return this.completion();
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Closes the modal dialog
|
|
218
|
+
*
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
closeModal(): void {
|
|
222
|
+
if (this.modal) {
|
|
223
|
+
// console.log('closeModal');
|
|
224
|
+
this.modal?.close();
|
|
225
|
+
this.modal.remove();
|
|
226
|
+
this.modal = undefined;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
110
229
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AgentType,
|
|
4
|
+
CMType,
|
|
5
|
+
HMType,
|
|
6
|
+
type HostMessage,
|
|
7
|
+
type Transaction,
|
|
8
|
+
type TransactionOptions,
|
|
9
|
+
type Withdrawal,
|
|
10
|
+
} from '../../types';
|
|
3
11
|
import EmbeddedComponent from '../EmbeddedComponent';
|
|
4
12
|
|
|
5
13
|
const url = 'https://example.com';
|
|
@@ -8,9 +16,11 @@ const value: Partial<Transaction> = { amountDecimal: 100 };
|
|
|
8
16
|
|
|
9
17
|
describe('EmbeddedComponent', () => {
|
|
10
18
|
describe('creation', () => {
|
|
11
|
-
let component: EmbeddedComponent
|
|
19
|
+
let component: EmbeddedComponent<Withdrawal, TransactionOptions>;
|
|
12
20
|
beforeEach(() => {
|
|
13
|
-
component = new EmbeddedComponent(url, {
|
|
21
|
+
component = new EmbeddedComponent<Withdrawal, TransactionOptions>(url, {
|
|
22
|
+
amountDecimal: 100,
|
|
23
|
+
});
|
|
14
24
|
});
|
|
15
25
|
|
|
16
26
|
test('sets value', () => {
|
|
@@ -60,14 +70,20 @@ describe('EmbeddedComponent', () => {
|
|
|
60
70
|
});
|
|
61
71
|
|
|
62
72
|
test('mount', () => {
|
|
63
|
-
const component = new EmbeddedComponent
|
|
73
|
+
const component = new EmbeddedComponent<Withdrawal, TransactionOptions>(
|
|
74
|
+
url,
|
|
75
|
+
value,
|
|
76
|
+
);
|
|
64
77
|
component.mount(parentId);
|
|
65
|
-
expect(iframe?.src).toBe(url);
|
|
78
|
+
expect(iframe?.src).toBe(url + '&embedded=true');
|
|
66
79
|
expect(parentElement.appendChild).toHaveBeenCalledWith(iframe);
|
|
67
80
|
});
|
|
68
81
|
|
|
69
82
|
test('on', () => {
|
|
70
|
-
const component = new EmbeddedComponent
|
|
83
|
+
const component = new EmbeddedComponent<Withdrawal, TransactionOptions>(
|
|
84
|
+
url,
|
|
85
|
+
value,
|
|
86
|
+
);
|
|
71
87
|
const messageType = 'customEvent';
|
|
72
88
|
const callback = vi.fn();
|
|
73
89
|
component.on(messageType, callback);
|
|
@@ -78,7 +94,10 @@ describe('EmbeddedComponent', () => {
|
|
|
78
94
|
});
|
|
79
95
|
|
|
80
96
|
test('off', () => {
|
|
81
|
-
const component = new EmbeddedComponent
|
|
97
|
+
const component = new EmbeddedComponent<Withdrawal, TransactionOptions>(
|
|
98
|
+
url,
|
|
99
|
+
value,
|
|
100
|
+
);
|
|
82
101
|
const messageType = 'customEvent';
|
|
83
102
|
const callback = vi.fn();
|
|
84
103
|
component.on(messageType, callback);
|
|
@@ -96,7 +115,8 @@ describe('EmbeddedComponent', () => {
|
|
|
96
115
|
let messageHandler: (event: MessageEvent) => void;
|
|
97
116
|
let port: MessagePort;
|
|
98
117
|
let handshake: MessageEvent;
|
|
99
|
-
let component: EmbeddedComponent
|
|
118
|
+
let component: EmbeddedComponent<Withdrawal, TransactionOptions>;
|
|
119
|
+
let options: TransactionOptions;
|
|
100
120
|
|
|
101
121
|
beforeEach(() => {
|
|
102
122
|
port = {
|
|
@@ -113,7 +133,12 @@ describe('EmbeddedComponent', () => {
|
|
|
113
133
|
.mockImplementation((event, handler) => {
|
|
114
134
|
messageHandler = handler;
|
|
115
135
|
});
|
|
116
|
-
|
|
136
|
+
options = { allowedAgentTypes: [AgentType.PRIVATE, AgentType.VASP] };
|
|
137
|
+
component = new EmbeddedComponent<Withdrawal, TransactionOptions>(
|
|
138
|
+
url,
|
|
139
|
+
value,
|
|
140
|
+
options,
|
|
141
|
+
);
|
|
117
142
|
component.mount(parentId);
|
|
118
143
|
|
|
119
144
|
expect(messageHandler).toBeDefined();
|
|
@@ -121,23 +146,51 @@ describe('EmbeddedComponent', () => {
|
|
|
121
146
|
});
|
|
122
147
|
|
|
123
148
|
test('send', () => {
|
|
124
|
-
const message: HostMessage = {
|
|
149
|
+
const message: HostMessage<Withdrawal, TransactionOptions> = {
|
|
125
150
|
type: HMType.UPDATE,
|
|
126
|
-
value: {
|
|
151
|
+
value: {
|
|
152
|
+
requestId: 'id',
|
|
153
|
+
},
|
|
154
|
+
options: { allowedAgentTypes: [AgentType.PRIVATE] },
|
|
127
155
|
};
|
|
128
156
|
component.send(message);
|
|
129
|
-
|
|
130
|
-
// Assert that the message is sent to the embedded component
|
|
131
|
-
// and handled correctly.
|
|
157
|
+
expect(port.postMessage).toHaveBeenCalledWith(message);
|
|
132
158
|
});
|
|
133
159
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
160
|
+
describe('update', () => {
|
|
161
|
+
test('with out options', () => {
|
|
162
|
+
const newValue: Partial<Transaction> = { amountDecimal: 200 };
|
|
137
163
|
|
|
138
|
-
|
|
139
|
-
|
|
164
|
+
const message: HostMessage<Withdrawal, TransactionOptions> = {
|
|
165
|
+
type: HMType.UPDATE,
|
|
166
|
+
value: newValue,
|
|
167
|
+
options,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
component.update(newValue);
|
|
171
|
+
|
|
172
|
+
expect(component.value).toBe(newValue);
|
|
173
|
+
expect(component.options).toBe(options);
|
|
174
|
+
expect(port.postMessage).toHaveBeenCalledWith(message);
|
|
175
|
+
});
|
|
140
176
|
|
|
177
|
+
test('with options', () => {
|
|
178
|
+
const newValue: Partial<Transaction> = { amountDecimal: 200 };
|
|
179
|
+
const newOptions = { allowedAgentTypes: [AgentType.PRIVATE] };
|
|
180
|
+
|
|
181
|
+
const message: HostMessage<Withdrawal, TransactionOptions> = {
|
|
182
|
+
type: HMType.UPDATE,
|
|
183
|
+
value: newValue,
|
|
184
|
+
options: newOptions,
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
component.update(newValue, newOptions);
|
|
188
|
+
|
|
189
|
+
expect(component.value).toBe(newValue);
|
|
190
|
+
expect(component.options).toBe(newOptions);
|
|
191
|
+
expect(port.postMessage).toHaveBeenCalledWith(message);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
141
194
|
// TODO not sure this actually does what I want it to do
|
|
142
195
|
test('completion', async () => {
|
|
143
196
|
const response = { valid: true, value: 'completed' };
|
|
@@ -147,7 +200,7 @@ describe('EmbeddedComponent', () => {
|
|
|
147
200
|
// @ts-expect-error - we've already verified that port exists
|
|
148
201
|
port.onmessage({
|
|
149
202
|
data: { type: CMType.COMPLETE, response },
|
|
150
|
-
}
|
|
203
|
+
});
|
|
151
204
|
|
|
152
205
|
promise.then((result) => {
|
|
153
206
|
expect(result).toBe(response);
|