@metamask-previews/base-controller 3.2.3-preview.e3b05ea → 4.0.0-preview.3fbb6b41
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/CHANGELOG.md +27 -1
- package/dist/{BaseController.d.ts → BaseControllerV1.d.ts} +6 -4
- package/dist/BaseControllerV1.d.ts.map +1 -0
- package/dist/{BaseController.js → BaseControllerV1.js} +8 -6
- package/dist/BaseControllerV1.js.map +1 -0
- package/dist/BaseControllerV2.d.ts +26 -15
- package/dist/BaseControllerV2.d.ts.map +1 -1
- package/dist/BaseControllerV2.js +22 -8
- package/dist/BaseControllerV2.js.map +1 -1
- package/dist/ControllerMessenger.d.ts +56 -211
- package/dist/ControllerMessenger.d.ts.map +1 -1
- package/dist/ControllerMessenger.js +36 -200
- package/dist/ControllerMessenger.js.map +1 -1
- package/dist/RestrictedControllerMessenger.d.ts +161 -0
- package/dist/RestrictedControllerMessenger.d.ts.map +1 -0
- package/dist/RestrictedControllerMessenger.js +201 -0
- package/dist/RestrictedControllerMessenger.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/BaseController.d.ts.map +0 -1
- package/dist/BaseController.js.map +0 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _RestrictedControllerMessenger_instances, _RestrictedControllerMessenger_controllerMessenger, _RestrictedControllerMessenger_controllerName, _RestrictedControllerMessenger_allowedActions, _RestrictedControllerMessenger_allowedEvents, _RestrictedControllerMessenger_isAllowedEvent, _RestrictedControllerMessenger_isAllowedAction, _RestrictedControllerMessenger_isInCurrentNamespace;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.RestrictedControllerMessenger = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* A restricted controller messenger.
|
|
18
|
+
*
|
|
19
|
+
* This acts as a wrapper around the controller messenger instance that restricts access to actions
|
|
20
|
+
* and events.
|
|
21
|
+
*
|
|
22
|
+
* @template Namespace - The namespace for this messenger. Typically this is the name of the controller or
|
|
23
|
+
* module that this messenger has been created for. The authority to publish events and register
|
|
24
|
+
* actions under this namespace is granted to this restricted messenger instance.
|
|
25
|
+
* @template Action - A type union of all Action types.
|
|
26
|
+
* @template Event - A type union of all Event types.
|
|
27
|
+
* @template AllowedAction - A type union of the 'type' string for any allowed actions.
|
|
28
|
+
* This must not include internal actions that are in the messenger's namespace.
|
|
29
|
+
* @template AllowedEvent - A type union of the 'type' string for any allowed events.
|
|
30
|
+
* This must not include internal events that are in the messenger's namespace.
|
|
31
|
+
*/
|
|
32
|
+
class RestrictedControllerMessenger {
|
|
33
|
+
/**
|
|
34
|
+
* Constructs a restricted controller messenger
|
|
35
|
+
*
|
|
36
|
+
* The provided allowlists grant the ability to call the listed actions and subscribe to the
|
|
37
|
+
* listed events. The "name" provided grants ownership of any actions and events under that
|
|
38
|
+
* namespace. Ownership allows registering actions and publishing events, as well as
|
|
39
|
+
* unregistering actions and clearing event subscriptions.
|
|
40
|
+
*
|
|
41
|
+
* @param options - The controller options.
|
|
42
|
+
* @param options.controllerMessenger - The controller messenger instance that is being wrapped.
|
|
43
|
+
* @param options.name - The name of the thing this messenger will be handed to (e.g. the
|
|
44
|
+
* controller name). This grants "ownership" of actions and events under this namespace to the
|
|
45
|
+
* restricted controller messenger returned.
|
|
46
|
+
* @param options.allowedActions - The list of actions that this restricted controller messenger
|
|
47
|
+
* should be alowed to call.
|
|
48
|
+
* @param options.allowedEvents - The list of events that this restricted controller messenger
|
|
49
|
+
* should be allowed to subscribe to.
|
|
50
|
+
*/
|
|
51
|
+
constructor({ controllerMessenger, name, allowedActions, allowedEvents, }) {
|
|
52
|
+
_RestrictedControllerMessenger_instances.add(this);
|
|
53
|
+
_RestrictedControllerMessenger_controllerMessenger.set(this, void 0);
|
|
54
|
+
_RestrictedControllerMessenger_controllerName.set(this, void 0);
|
|
55
|
+
_RestrictedControllerMessenger_allowedActions.set(this, void 0);
|
|
56
|
+
_RestrictedControllerMessenger_allowedEvents.set(this, void 0);
|
|
57
|
+
__classPrivateFieldSet(this, _RestrictedControllerMessenger_controllerMessenger, controllerMessenger, "f");
|
|
58
|
+
__classPrivateFieldSet(this, _RestrictedControllerMessenger_controllerName, name, "f");
|
|
59
|
+
__classPrivateFieldSet(this, _RestrictedControllerMessenger_allowedActions, allowedActions !== null && allowedActions !== void 0 ? allowedActions : null, "f");
|
|
60
|
+
__classPrivateFieldSet(this, _RestrictedControllerMessenger_allowedEvents, allowedEvents !== null && allowedEvents !== void 0 ? allowedEvents : null, "f");
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Register an action handler.
|
|
64
|
+
*
|
|
65
|
+
* This will make the registered function available to call via the `call` method.
|
|
66
|
+
*
|
|
67
|
+
* The action type this handler is registered under *must* be in the current namespace.
|
|
68
|
+
*
|
|
69
|
+
* @param action - The action type. This is a unqiue identifier for this action.
|
|
70
|
+
* @param handler - The action handler. This function gets called when the `call` method is
|
|
71
|
+
* invoked with the given action type.
|
|
72
|
+
* @throws Will throw if an action handler that is not in the current namespace is being registered.
|
|
73
|
+
* @template ActionType - A type union of Action type strings that are namespaced by Namespace.
|
|
74
|
+
*/
|
|
75
|
+
registerActionHandler(action, handler) {
|
|
76
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
77
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, action)) {
|
|
78
|
+
throw new Error(`Only allowed registering action handlers prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
79
|
+
}
|
|
80
|
+
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").registerActionHandler(action, handler);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Unregister an action handler.
|
|
84
|
+
*
|
|
85
|
+
* This will prevent this action from being called.
|
|
86
|
+
*
|
|
87
|
+
* The action type being unregistered *must* be in the current namespace.
|
|
88
|
+
*
|
|
89
|
+
* @param action - The action type. This is a unique identifier for this action.
|
|
90
|
+
* @throws Will throw if an action handler that is not in the current namespace is being unregistered.
|
|
91
|
+
* @template ActionType - A type union of Action type strings that are namespaced by Namespace.
|
|
92
|
+
*/
|
|
93
|
+
unregisterActionHandler(action) {
|
|
94
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
95
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, action)) {
|
|
96
|
+
throw new Error(`Only allowed unregistering action handlers prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
97
|
+
}
|
|
98
|
+
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").unregisterActionHandler(action);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Call an action.
|
|
102
|
+
*
|
|
103
|
+
* This function will call the action handler corresponding to the given action type, passing
|
|
104
|
+
* along any parameters given.
|
|
105
|
+
*
|
|
106
|
+
* The action type being called must be on the action allowlist.
|
|
107
|
+
*
|
|
108
|
+
* @param actionType - The action type. This is a unqiue identifier for this action.
|
|
109
|
+
* @param params - The action parameters. These must match the type of the parameters of the
|
|
110
|
+
* registered action handler.
|
|
111
|
+
* @throws Will throw when no handler has been registered for the given type.
|
|
112
|
+
* @template ActionType - A type union of allowed Action type strings.
|
|
113
|
+
* @returns The action return value.
|
|
114
|
+
*/
|
|
115
|
+
call(actionType, ...params) {
|
|
116
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isAllowedAction).call(this, actionType)) {
|
|
117
|
+
throw new Error(`Action missing from allow list: ${actionType}`);
|
|
118
|
+
}
|
|
119
|
+
const response = __classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").call(actionType, ...params);
|
|
120
|
+
return response;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Publish an event.
|
|
124
|
+
*
|
|
125
|
+
* Publishes the given payload to all subscribers of the given event type.
|
|
126
|
+
*
|
|
127
|
+
* The event type being published *must* be in the current namespace.
|
|
128
|
+
*
|
|
129
|
+
* @param event - The event type. This is a unique identifier for this event.
|
|
130
|
+
* @param payload - The event payload. The type of the parameters for each event handler must
|
|
131
|
+
* match the type of this payload.
|
|
132
|
+
* @throws Will throw if an event that is not in the current namespace is being published.
|
|
133
|
+
* @template EventType - A type union of Event type strings that are namespaced by Namespace.
|
|
134
|
+
*/
|
|
135
|
+
publish(event, ...payload) {
|
|
136
|
+
/* istanbul ignore if */ // Branch unreachable with valid types
|
|
137
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, event)) {
|
|
138
|
+
throw new Error(`Only allowed publishing events prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
139
|
+
}
|
|
140
|
+
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").publish(event, ...payload);
|
|
141
|
+
}
|
|
142
|
+
subscribe(event, handler, selector) {
|
|
143
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isAllowedEvent).call(this, event)) {
|
|
144
|
+
throw new Error(`Event missing from allow list: ${event}`);
|
|
145
|
+
}
|
|
146
|
+
if (selector) {
|
|
147
|
+
return __classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").subscribe(event, handler, selector);
|
|
148
|
+
}
|
|
149
|
+
return __classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").subscribe(event, handler);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Unsubscribe from an event.
|
|
153
|
+
*
|
|
154
|
+
* Unregisters the given function as an event handler for the given event.
|
|
155
|
+
*
|
|
156
|
+
* The event type being unsubscribed to must be on the event allowlist.
|
|
157
|
+
*
|
|
158
|
+
* @param event - The event type. This is a unique identifier for this event.
|
|
159
|
+
* @param handler - The event handler to unregister.
|
|
160
|
+
* @throws Will throw if the given event is not an allowed event for this controller messenger.
|
|
161
|
+
* @template EventType - A type union of allowed Event type strings.
|
|
162
|
+
*/
|
|
163
|
+
unsubscribe(event, handler) {
|
|
164
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isAllowedEvent).call(this, event)) {
|
|
165
|
+
throw new Error(`Event missing from allow list: ${event}`);
|
|
166
|
+
}
|
|
167
|
+
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").unsubscribe(event, handler);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Clear subscriptions for a specific event.
|
|
171
|
+
*
|
|
172
|
+
* This will remove all subscribed handlers for this event.
|
|
173
|
+
*
|
|
174
|
+
* The event type being cleared *must* be in the current namespace.
|
|
175
|
+
*
|
|
176
|
+
* @param event - The event type. This is a unique identifier for this event.
|
|
177
|
+
* @throws Will throw if a subscription for an event that is not in the current namespace is being cleared.
|
|
178
|
+
* @template EventType - A type union of Event type strings that are namespaced by Namespace.
|
|
179
|
+
*/
|
|
180
|
+
clearEventSubscriptions(event) {
|
|
181
|
+
if (!__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, event)) {
|
|
182
|
+
throw new Error(`Only allowed clearing events prefixed by '${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:'`);
|
|
183
|
+
}
|
|
184
|
+
__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerMessenger, "f").clearEventSubscriptions(event);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.RestrictedControllerMessenger = RestrictedControllerMessenger;
|
|
188
|
+
_RestrictedControllerMessenger_controllerMessenger = new WeakMap(), _RestrictedControllerMessenger_controllerName = new WeakMap(), _RestrictedControllerMessenger_allowedActions = new WeakMap(), _RestrictedControllerMessenger_allowedEvents = new WeakMap(), _RestrictedControllerMessenger_instances = new WeakSet(), _RestrictedControllerMessenger_isAllowedEvent = function _RestrictedControllerMessenger_isAllowedEvent(eventType) {
|
|
189
|
+
// Safely upcast to allow runtime check
|
|
190
|
+
const allowedEvents = __classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedEvents, "f");
|
|
191
|
+
return (__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, eventType) ||
|
|
192
|
+
(allowedEvents !== null && allowedEvents.includes(eventType)));
|
|
193
|
+
}, _RestrictedControllerMessenger_isAllowedAction = function _RestrictedControllerMessenger_isAllowedAction(actionType) {
|
|
194
|
+
// Safely upcast to allow runtime check
|
|
195
|
+
const allowedActions = __classPrivateFieldGet(this, _RestrictedControllerMessenger_allowedActions, "f");
|
|
196
|
+
return (__classPrivateFieldGet(this, _RestrictedControllerMessenger_instances, "m", _RestrictedControllerMessenger_isInCurrentNamespace).call(this, actionType) ||
|
|
197
|
+
(allowedActions !== null && allowedActions.includes(actionType)));
|
|
198
|
+
}, _RestrictedControllerMessenger_isInCurrentNamespace = function _RestrictedControllerMessenger_isInCurrentNamespace(name) {
|
|
199
|
+
return name.startsWith(`${__classPrivateFieldGet(this, _RestrictedControllerMessenger_controllerName, "f")}:`);
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=RestrictedControllerMessenger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestrictedControllerMessenger.js","sourceRoot":"","sources":["../src/RestrictedControllerMessenger.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ActionConstraint,\n ActionHandler,\n ControllerMessenger,\n EventConstraint,\n ExtractActionParameters,\n ExtractActionResponse,\n ExtractEventHandler,\n ExtractEventPayload,\n NamespacedName,\n NotNamespacedBy,\n SelectorEventHandler,\n SelectorFunction,\n} from './ControllerMessenger';\n\n/**\n * A restricted controller messenger.\n *\n * This acts as a wrapper around the controller messenger instance that restricts access to actions\n * and events.\n *\n * @template Namespace - The namespace for this messenger. Typically this is the name of the controller or\n * module that this messenger has been created for. The authority to publish events and register\n * actions under this namespace is granted to this restricted messenger instance.\n * @template Action - A type union of all Action types.\n * @template Event - A type union of all Event types.\n * @template AllowedAction - A type union of the 'type' string for any allowed actions.\n * This must not include internal actions that are in the messenger's namespace.\n * @template AllowedEvent - A type union of the 'type' string for any allowed events.\n * This must not include internal events that are in the messenger's namespace.\n */\nexport class RestrictedControllerMessenger<\n Namespace extends string,\n Action extends ActionConstraint,\n Event extends EventConstraint,\n AllowedAction extends string,\n AllowedEvent extends string,\n> {\n readonly #controllerMessenger: ControllerMessenger<\n ActionConstraint,\n EventConstraint\n >;\n\n readonly #controllerName: Namespace;\n\n readonly #allowedActions: NotNamespacedBy<Namespace, AllowedAction>[] | null;\n\n readonly #allowedEvents: NotNamespacedBy<Namespace, AllowedEvent>[] | null;\n\n /**\n * Constructs a restricted controller messenger\n *\n * The provided allowlists grant the ability to call the listed actions and subscribe to the\n * listed events. The \"name\" provided grants ownership of any actions and events under that\n * namespace. Ownership allows registering actions and publishing events, as well as\n * unregistering actions and clearing event subscriptions.\n *\n * @param options - The controller options.\n * @param options.controllerMessenger - The controller messenger instance that is being wrapped.\n * @param options.name - The name of the thing this messenger will be handed to (e.g. the\n * controller name). This grants \"ownership\" of actions and events under this namespace to the\n * restricted controller messenger returned.\n * @param options.allowedActions - The list of actions that this restricted controller messenger\n * should be alowed to call.\n * @param options.allowedEvents - The list of events that this restricted controller messenger\n * should be allowed to subscribe to.\n */\n constructor({\n controllerMessenger,\n name,\n allowedActions,\n allowedEvents,\n }: {\n controllerMessenger: ControllerMessenger<ActionConstraint, EventConstraint>;\n name: Namespace;\n allowedActions?: NotNamespacedBy<Namespace, AllowedAction>[];\n allowedEvents?: NotNamespacedBy<Namespace, AllowedEvent>[];\n }) {\n this.#controllerMessenger = controllerMessenger;\n this.#controllerName = name;\n this.#allowedActions = allowedActions ?? null;\n this.#allowedEvents = allowedEvents ?? null;\n }\n\n /**\n * Register an action handler.\n *\n * This will make the registered function available to call via the `call` method.\n *\n * The action type this handler is registered under *must* be in the current namespace.\n *\n * @param action - The action type. This is a unqiue identifier for this action.\n * @param handler - The action handler. This function gets called when the `call` method is\n * invoked with the given action type.\n * @throws Will throw if an action handler that is not in the current namespace is being registered.\n * @template ActionType - A type union of Action type strings that are namespaced by Namespace.\n */\n registerActionHandler<\n ActionType extends Action['type'] & NamespacedName<Namespace>,\n >(action: ActionType, handler: ActionHandler<Action, ActionType>) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!this.#isInCurrentNamespace(action)) {\n throw new Error(\n `Only allowed registering action handlers prefixed by '${\n this.#controllerName\n }:'`,\n );\n }\n this.#controllerMessenger.registerActionHandler(action, handler);\n }\n\n /**\n * Unregister an action handler.\n *\n * This will prevent this action from being called.\n *\n * The action type being unregistered *must* be in the current namespace.\n *\n * @param action - The action type. This is a unique identifier for this action.\n * @throws Will throw if an action handler that is not in the current namespace is being unregistered.\n * @template ActionType - A type union of Action type strings that are namespaced by Namespace.\n */\n unregisterActionHandler<\n ActionType extends Action['type'] & NamespacedName<Namespace>,\n >(action: ActionType) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!this.#isInCurrentNamespace(action)) {\n throw new Error(\n `Only allowed unregistering action handlers prefixed by '${\n this.#controllerName\n }:'`,\n );\n }\n this.#controllerMessenger.unregisterActionHandler(action);\n }\n\n /**\n * Call an action.\n *\n * This function will call the action handler corresponding to the given action type, passing\n * along any parameters given.\n *\n * The action type being called must be on the action allowlist.\n *\n * @param actionType - The action type. This is a unqiue identifier for this action.\n * @param params - The action parameters. These must match the type of the parameters of the\n * registered action handler.\n * @throws Will throw when no handler has been registered for the given type.\n * @template ActionType - A type union of allowed Action type strings.\n * @returns The action return value.\n */\n call<\n ActionType extends\n | AllowedAction\n | (Action['type'] & NamespacedName<Namespace>),\n >(\n actionType: ActionType,\n ...params: ExtractActionParameters<Action, ActionType>\n ): ExtractActionResponse<Action, ActionType> {\n if (!this.#isAllowedAction(actionType)) {\n throw new Error(`Action missing from allow list: ${actionType}`);\n }\n const response = this.#controllerMessenger.call<ActionType>(\n actionType,\n ...params,\n );\n\n return response;\n }\n\n /**\n * Publish an event.\n *\n * Publishes the given payload to all subscribers of the given event type.\n *\n * The event type being published *must* be in the current namespace.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @param payload - The event payload. The type of the parameters for each event handler must\n * match the type of this payload.\n * @throws Will throw if an event that is not in the current namespace is being published.\n * @template EventType - A type union of Event type strings that are namespaced by Namespace.\n */\n publish<EventType extends Event['type'] & NamespacedName<Namespace>>(\n event: EventType,\n ...payload: ExtractEventPayload<Event, EventType>\n ) {\n /* istanbul ignore if */ // Branch unreachable with valid types\n if (!this.#isInCurrentNamespace(event)) {\n throw new Error(\n `Only allowed publishing events prefixed by '${this.#controllerName}:'`,\n );\n }\n this.#controllerMessenger.publish(event, ...payload);\n }\n\n /**\n * Subscribe to an event.\n *\n * Registers the given function as an event handler for the given event type.\n *\n * The event type being subscribed to must be on the event allowlist.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event handler must\n * match the type of the payload for this event type.\n * @throws Will throw if the given event is not an allowed event for this controller messenger.\n * @template EventType - A type union of Event type strings.\n */\n subscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n >(eventType: EventType, handler: ExtractEventHandler<Event, EventType>): void;\n\n /**\n * Subscribe to an event, with a selector.\n *\n * Registers the given handler function as an event handler for the given\n * event type. When an event is published, its payload is first passed to the\n * selector. The event handler is only called if the selector's return value\n * differs from its last known return value.\n *\n * The event type being subscribed to must be on the event allowlist.\n *\n * @param eventType - The event type. This is a unique identifier for this event.\n * @param handler - The event handler. The type of the parameters for this event\n * handler must match the return type of the selector.\n * @param selector - The selector function used to select relevant data from\n * the event payload. The type of the parameters for this selector must match\n * the type of the payload for this event type.\n * @throws Will throw if the given event is not an allowed event for this controller messenger.\n * @template EventType - A type union of Event type strings.\n * @template SelectorReturnValue - The selector return value.\n */\n subscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n SelectorReturnValue,\n >(\n eventType: EventType,\n handler: SelectorEventHandler<SelectorReturnValue>,\n selector: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ): void;\n\n subscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n SelectorReturnValue,\n >(\n event: EventType,\n handler: ExtractEventHandler<Event, EventType>,\n selector?: SelectorFunction<\n ExtractEventPayload<Event, EventType>,\n SelectorReturnValue\n >,\n ) {\n if (!this.#isAllowedEvent(event)) {\n throw new Error(`Event missing from allow list: ${event}`);\n }\n\n if (selector) {\n return this.#controllerMessenger.subscribe(event, handler, selector);\n }\n return this.#controllerMessenger.subscribe(event, handler);\n }\n\n /**\n * Unsubscribe from an event.\n *\n * Unregisters the given function as an event handler for the given event.\n *\n * The event type being unsubscribed to must be on the event allowlist.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @param handler - The event handler to unregister.\n * @throws Will throw if the given event is not an allowed event for this controller messenger.\n * @template EventType - A type union of allowed Event type strings.\n */\n unsubscribe<\n EventType extends\n | AllowedEvent\n | (Event['type'] & NamespacedName<Namespace>),\n >(event: EventType, handler: ExtractEventHandler<Event, EventType>) {\n if (!this.#isAllowedEvent(event)) {\n throw new Error(`Event missing from allow list: ${event}`);\n }\n this.#controllerMessenger.unsubscribe(event, handler);\n }\n\n /**\n * Clear subscriptions for a specific event.\n *\n * This will remove all subscribed handlers for this event.\n *\n * The event type being cleared *must* be in the current namespace.\n *\n * @param event - The event type. This is a unique identifier for this event.\n * @throws Will throw if a subscription for an event that is not in the current namespace is being cleared.\n * @template EventType - A type union of Event type strings that are namespaced by Namespace.\n */\n clearEventSubscriptions<\n EventType extends Event['type'] & NamespacedName<Namespace>,\n >(event: EventType) {\n if (!this.#isInCurrentNamespace(event)) {\n throw new Error(\n `Only allowed clearing events prefixed by '${this.#controllerName}:'`,\n );\n }\n this.#controllerMessenger.clearEventSubscriptions(event);\n }\n\n /**\n * Determine whether the given event type is allowed. Event types are\n * allowed if they are in the current namespace or on the list of\n * allowed events.\n *\n * @param eventType - The event type to check.\n * @returns Whether the event type is allowed.\n */\n #isAllowedEvent(\n eventType: Event['type'],\n ): eventType is\n | NamespacedName<Namespace>\n | NotNamespacedBy<Namespace, AllowedEvent> {\n // Safely upcast to allow runtime check\n const allowedEvents: string[] | null = this.#allowedEvents;\n return (\n this.#isInCurrentNamespace(eventType) ||\n (allowedEvents !== null && allowedEvents.includes(eventType))\n );\n }\n\n /**\n * Determine whether the given action type is allowed. Action types\n * are allowed if they are in the current namespace or on the list of\n * allowed actions.\n *\n * @param actionType - The action type to check.\n * @returns Whether the action type is allowed.\n */\n #isAllowedAction(\n actionType: Action['type'],\n ): actionType is\n | NamespacedName<Namespace>\n | NotNamespacedBy<Namespace, AllowedAction> {\n // Safely upcast to allow runtime check\n const allowedActions: string[] | null = this.#allowedActions;\n return (\n this.#isInCurrentNamespace(actionType) ||\n (allowedActions !== null && allowedActions.includes(actionType))\n );\n }\n\n /**\n * Determine whether the given name is within the current namespace.\n *\n * @param name - The name to check\n * @returns Whether the name is within the current namespace\n */\n #isInCurrentNamespace(name: string): name is NamespacedName<Namespace> {\n return name.startsWith(`${this.#controllerName}:`);\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export type { BaseConfig, BaseState, Listener } from './
|
|
2
|
-
export {
|
|
3
|
-
export type { Listener as ListenerV2, StateDeriver, StateMetadata, StatePropertyMetadata, } from './BaseControllerV2';
|
|
4
|
-
export { BaseController
|
|
1
|
+
export type { BaseConfig, BaseState, Listener } from './BaseControllerV1';
|
|
2
|
+
export { BaseControllerV1 } from './BaseControllerV1';
|
|
3
|
+
export type { Listener as ListenerV2, StateDeriver, StateMetadata, StatePropertyMetadata, ControllerGetStateAction, ControllerStateChangeEvent, } from './BaseControllerV2';
|
|
4
|
+
export { BaseController, getAnonymizedState, getPersistentState, } from './BaseControllerV2';
|
|
5
5
|
export * from './ControllerMessenger';
|
|
6
|
+
export * from './RestrictedControllerMessenger';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EACV,QAAQ,IAAI,UAAU,EACtB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iCAAiC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,12 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.getPersistentState = exports.getAnonymizedState = exports.
|
|
18
|
-
var
|
|
19
|
-
Object.defineProperty(exports, "
|
|
17
|
+
exports.getPersistentState = exports.getAnonymizedState = exports.BaseController = exports.BaseControllerV1 = void 0;
|
|
18
|
+
var BaseControllerV1_1 = require("./BaseControllerV1");
|
|
19
|
+
Object.defineProperty(exports, "BaseControllerV1", { enumerable: true, get: function () { return BaseControllerV1_1.BaseControllerV1; } });
|
|
20
20
|
var BaseControllerV2_1 = require("./BaseControllerV2");
|
|
21
|
-
Object.defineProperty(exports, "
|
|
21
|
+
Object.defineProperty(exports, "BaseController", { enumerable: true, get: function () { return BaseControllerV2_1.BaseController; } });
|
|
22
22
|
Object.defineProperty(exports, "getAnonymizedState", { enumerable: true, get: function () { return BaseControllerV2_1.getAnonymizedState; } });
|
|
23
23
|
Object.defineProperty(exports, "getPersistentState", { enumerable: true, get: function () { return BaseControllerV2_1.getPersistentState; } });
|
|
24
24
|
__exportStar(require("./ControllerMessenger"), exports);
|
|
25
|
+
__exportStar(require("./RestrictedControllerMessenger"), exports);
|
|
25
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AASzB,uDAI4B;AAH1B,kHAAA,cAAc,OAAA;AACd,sHAAA,kBAAkB,OAAA;AAClB,sHAAA,kBAAkB,OAAA;AAEpB,wDAAsC;AACtC,kEAAgD","sourcesContent":["export type { BaseConfig, BaseState, Listener } from './BaseControllerV1';\nexport { BaseControllerV1 } from './BaseControllerV1';\nexport type {\n Listener as ListenerV2,\n StateDeriver,\n StateMetadata,\n StatePropertyMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from './BaseControllerV2';\nexport {\n BaseController,\n getAnonymizedState,\n getPersistentState,\n} from './BaseControllerV2';\nexport * from './ControllerMessenger';\nexport * from './RestrictedControllerMessenger';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/base-controller",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-preview.3fbb6b41",
|
|
4
4
|
"description": "Provides scaffolding for controllers as well a communication system for all controllers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -24,16 +24,17 @@
|
|
|
24
24
|
"build:docs": "typedoc",
|
|
25
25
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/base-controller",
|
|
26
26
|
"publish:preview": "yarn npm publish --tag preview",
|
|
27
|
-
"test": "jest",
|
|
27
|
+
"test": "jest --reporters=jest-silent-reporter",
|
|
28
28
|
"test:clean": "jest --clearCache",
|
|
29
|
+
"test:verbose": "jest --verbose",
|
|
29
30
|
"test:watch": "jest --watch"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@metamask/utils": "^8.
|
|
33
|
+
"@metamask/utils": "^8.2.0",
|
|
33
34
|
"immer": "^9.0.6"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
|
-
"@metamask/auto-changelog": "^3.4.
|
|
37
|
+
"@metamask/auto-changelog": "^3.4.3",
|
|
37
38
|
"@types/jest": "^27.4.1",
|
|
38
39
|
"@types/sinon": "^9.0.10",
|
|
39
40
|
"deepmerge": "^4.2.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BaseController.d.ts","sourceRoot":"","sources":["../src/BaseController.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,qBAAa,cAAc,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,SAAS;IACnE;;OAEG;IACH,aAAa,EAAE,CAAC,CAAW;IAE3B;;OAEG;IACH,YAAY,EAAE,CAAC,CAAW;IAE1B;;OAEG;IACH,QAAQ,UAAS;IAEjB;;OAEG;IACH,IAAI,SAAoB;IAExB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAI;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAI;IAEjC,OAAO,CAAC,cAAc,CAAyB;IAE/C,OAAO,CAAC,aAAa,CAAwB;IAE7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IAEvD;;;;;;OAMG;gBACS,MAAM,GAAE,OAAO,CAAC,CAAC,CAAW,EAAE,KAAK,GAAE,OAAO,CAAC,CAAC,CAAW;IAMrE;;;;;;OAMG;IACH,SAAS,CAAC,UAAU;IAQpB;;;;OAIG;IACH,IAAI,MAAM,MAET;IAED;;;;OAIG;IACH,IAAI,KAAK,MAER;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,UAAQ,EAAE,UAAU,UAAO;IAsBlE;;OAEG;IACH,MAAM;IAUN;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAI/B;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAMjC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,UAAQ;CAM5C;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BaseController.js","sourceRoot":"","sources":["../src/BaseController.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * State change callbacks\n */\nexport type Listener<T> = (state: T) => void;\n\n/**\n * @type BaseConfig\n *\n * Base controller configuration\n * @property disabled - Determines if this controller is enabled\n */\nexport interface BaseConfig {\n disabled?: boolean;\n}\n\n/**\n * @type BaseState\n *\n * Base state representation\n * @property name - Unique name for this controller\n */\nexport interface BaseState {\n name?: string;\n}\n\n/**\n * Controller class that provides configuration, state management, and subscriptions.\n *\n * The core purpose of every controller is to maintain an internal data object\n * called \"state\". Each controller is responsible for its own state, and all global wallet state\n * is tracked in a controller as state.\n */\nexport class BaseController<C extends BaseConfig, S extends BaseState> {\n /**\n * Default options used to configure this controller\n */\n defaultConfig: C = {} as C;\n\n /**\n * Default state set on this controller\n */\n defaultState: S = {} as S;\n\n /**\n * Determines if listeners are notified of state changes\n */\n disabled = false;\n\n /**\n * Name of this controller used during composition\n */\n name = 'BaseController';\n\n private readonly initialConfig: C;\n\n private readonly initialState: S;\n\n private internalConfig: C = this.defaultConfig;\n\n private internalState: S = this.defaultState;\n\n private readonly internalListeners: Listener<S>[] = [];\n\n /**\n * Creates a BaseController instance. Both initial state and initial\n * configuration options are merged with defaults upon initialization.\n *\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(config: Partial<C> = {} as C, state: Partial<S> = {} as S) {\n // Use assign since generics can't be spread: https://git.io/vpRhY\n this.initialState = state as S;\n this.initialConfig = config as C;\n }\n\n /**\n * Enables the controller. This sets each config option as a member\n * variable on this instance and triggers any defined setters. This\n * also sets initial state and triggers any listeners.\n *\n * @returns This controller instance.\n */\n protected initialize() {\n this.internalState = this.defaultState;\n this.internalConfig = this.defaultConfig;\n this.configure(this.initialConfig);\n this.update(this.initialState);\n return this;\n }\n\n /**\n * Retrieves current controller configuration options.\n *\n * @returns The current configuration.\n */\n get config() {\n return this.internalConfig;\n }\n\n /**\n * Retrieves current controller state.\n *\n * @returns The current state.\n */\n get state() {\n return this.internalState;\n }\n\n /**\n * Updates controller configuration.\n *\n * @param config - New configuration options.\n * @param overwrite - Overwrite config instead of merging.\n * @param fullUpdate - Boolean that defines if the update is partial or not.\n */\n configure(config: Partial<C>, overwrite = false, fullUpdate = true) {\n if (fullUpdate) {\n this.internalConfig = overwrite\n ? (config as C)\n : Object.assign(this.internalConfig, config);\n\n for (const [key, value] of Object.entries(this.internalConfig)) {\n if (value !== undefined) {\n (this as any)[key] = value;\n }\n }\n } else {\n for (const key of Object.keys(config) as (keyof C)[]) {\n /* istanbul ignore else */\n if (typeof this.internalConfig[key] !== 'undefined') {\n this.internalConfig[key] = (config as C)[key];\n (this as any)[key] = config[key];\n }\n }\n }\n }\n\n /**\n * Notifies all subscribed listeners of current state.\n */\n notify() {\n if (this.disabled) {\n return;\n }\n\n this.internalListeners.forEach((listener) => {\n listener(this.internalState);\n });\n }\n\n /**\n * Adds new listener to be notified of state changes.\n *\n * @param listener - The callback triggered when state changes.\n */\n subscribe(listener: Listener<S>) {\n this.internalListeners.push(listener);\n }\n\n /**\n * Removes existing listener from receiving state changes.\n *\n * @param listener - The callback to remove.\n * @returns `true` if a listener is found and unsubscribed.\n */\n unsubscribe(listener: Listener<S>) {\n const index = this.internalListeners.findIndex((cb) => listener === cb);\n index > -1 && this.internalListeners.splice(index, 1);\n return index > -1;\n }\n\n /**\n * Updates controller state.\n *\n * @param state - The new state.\n * @param overwrite - Overwrite state instead of merging.\n */\n update(state: Partial<S>, overwrite = false) {\n this.internalState = overwrite\n ? Object.assign({}, state as S)\n : Object.assign({}, this.internalState, state);\n this.notify();\n }\n}\n\nexport default BaseController;\n"]}
|