electron-wns 0.0.0 → 0.0.4

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 CHANGED
@@ -1,179 +1,99 @@
1
- # electron-wns
2
-
3
- A TypeScript library for receiving [Windows Push Notification Service (WNS)](https://learn.microsoft.com/en-us/windows/apps/develop/notifications/push-notifications/wns-overview) push messages in the **main process** of an [Electron](https://www.electronjs.org/) application.
4
-
5
- ---
6
-
7
- ## How WNS works
8
-
9
- ```
10
- ┌──────────┐ 1. getChannel() ┌──────────────────────┐
11
- │ Electron │ ──────────────────▶│ WNS (Microsoft) │
12
- │ App │ ◀────────────────── │ │
13
- └──────────┘ channel URI └──────────────────────┘
14
-
15
- │ 2. Send URI to backend
16
-
17
- ┌──────────┐ 3. POST /notify ┌──────────────────────┐
18
- │ Your │ ──────────────────▶│ WNS (Microsoft)
19
- Backend │ │ │
20
- └──────────┘ └──────────┬───────────┘
21
- │ 4. push delivered
22
-
23
- ┌──────────┐
24
- Electron │ ◀── 'notification' event
25
- │ App │
26
- └──────────┘
27
- ```
28
-
29
- 1. Your Electron app calls `client.getChannel()` to obtain a **channel URI** from WNS.
30
- 2. Your app sends the channel URI to your backend server.
31
- 3. Whenever your backend needs to push a message, it makes an authenticated HTTP POST to the channel URI via WNS.
32
- 4. WNS delivers the push to the device; `electron-wns` emits a `notification` event in your Electron main process.
33
-
34
- ---
35
-
36
- ## Requirements
37
-
38
- | Requirement | Details |
39
- |---|---|
40
- | **Operating system** | Windows 10 (build 1803) or later |
41
- | **PowerShell** | `powershell.exe` (Windows PowerShell 5.1+) or `pwsh` (PowerShell 7+) |
42
- | **Package identity** | The Electron app must be packaged as **MSIX** (or have a sparse-package identity) so that `PushNotificationChannelManager` can register the app with WNS. |
43
- | **Node.js / Electron** | Node.js ≥ 18, Electron ≥ 22 |
44
-
45
- > **Note – unpackaged Electron apps:** The underlying WinRT API (`PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync`) requires a package identity.
46
- > For unpackaged Win32 apps, consider using the [Windows App SDK push notification API](https://learn.microsoft.com/en-us/windows/apps/develop/notifications/push-notifications/push-quickstart) or packaging your app with MSIX.
47
-
48
- ---
49
-
50
- ## Installation
51
-
52
- ```bash
53
- npm install electron-wns
54
- ```
55
-
56
- ---
57
-
58
- ## Usage
59
-
60
- ### Obtain a channel URI
61
-
62
- ```ts
63
- import { WNSClient } from 'electron-wns';
64
-
65
- const client = new WNSClient();
66
-
67
- // Get the WNS channel URI for this app instance.
68
- // Share this URI with your backend – it uses it to push notifications.
69
- const channel = await client.getChannel();
70
- console.log('Channel URI:', channel.uri);
71
- console.log('Expires at:', channel.expiresAt);
72
- ```
73
-
74
- ### Listen for incoming push notifications
75
-
76
- ```ts
77
- import { WNSClient, WNSNotification } from 'electron-wns';
78
-
79
- const client = new WNSClient();
80
-
81
- client.on('channelUpdated', (channel) => {
82
- console.log('New channel URI:', channel.uri);
83
- // Re-register the new URI with your backend
84
- });
85
-
86
- client.on('notification', (n: WNSNotification) => {
87
- console.log('Push received!');
88
- console.log(' type :', n.notificationType); // 'toast' | 'tile' | 'badge' | 'raw'
89
- console.log(' payload:', n.payload);
90
- console.log(' at :', n.timestamp);
91
- });
92
-
93
- client.on('error', (err) => {
94
- console.error('WNS error:', err);
95
- });
96
-
97
- // Start the background WNS listener
98
- client.startListening();
99
-
100
- // Later, when the app is about to quit:
101
- client.stopListening();
102
- ```
103
-
104
- ### Refresh an expired channel
105
-
106
- ```ts
107
- // Channel URIs have a limited lifetime (check `channel.expiresAt` for the exact expiry).
108
- // Call refreshChannel() on startup or when the channel is nearing its expiry.
109
- const newChannel = await client.refreshChannel();
110
- ```
111
-
112
- ### Custom PowerShell path
113
-
114
- ```ts
115
- const client = new WNSClient({ powershellPath: 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe' });
116
- ```
117
-
118
- ---
119
-
120
- ## API
121
-
122
- ### `new WNSClient(options?)`
123
-
124
- | Option | Type | Default | Description |
125
- |---|---|---|---|
126
- | `powershellPath` | `string` | `powershell.exe` (Win) / `pwsh` | Path to the PowerShell executable. |
127
-
128
- ### Methods
129
-
130
- | Method | Returns | Description |
131
- |---|---|---|
132
- | `getChannel()` | `Promise<WNSChannel>` | Obtain (and cache) the WNS channel for this app. |
133
- | `refreshChannel()` | `Promise<WNSChannel>` | Force a fresh channel request and emit `channelUpdated`. |
134
- | `startListening()` | `void` | Spawn the background WNS listener. |
135
- | `stopListening()` | `void` | Kill the background listener. |
136
- | `isListening()` | `boolean` | Whether the listener is currently running. |
137
-
138
- ### Events
139
-
140
- | Event | Payload | Description |
141
- |---|---|---|
142
- | `channelUpdated` | `WNSChannel` | Emitted when a new channel URI is obtained. |
143
- | `notification` | `WNSNotification` | Emitted for each incoming push notification. |
144
- | `error` | `Error` | Non-fatal listener error. |
145
-
146
- ### Types
147
-
148
- ```ts
149
- interface WNSChannel {
150
- uri: string; // The channel URI to give to your backend
151
- expiresAt: string; // ISO 8601 expiry timestamp – check this field for the exact expiry
152
- }
153
-
154
- interface WNSNotification {
155
- notificationType: 'toast' | 'tile' | 'badge' | 'raw';
156
- payload: string; // XML for toast/tile/badge; arbitrary string for raw
157
- timestamp: string; // ISO 8601
158
- }
159
- ```
160
-
161
- ---
162
-
163
- ## How it works internally
164
-
165
- `electron-wns` ships two PowerShell helper scripts (`scripts/`):
166
-
167
- | Script | Purpose |
168
- |---|---|
169
- | `get-channel.ps1` | Calls `PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync()` (WinRT) and writes the channel URI as JSON to stdout. |
170
- | `wns-listener.ps1` | Obtains the channel, subscribes to `PushNotificationChannel.PushNotificationReceived`, and continuously writes incoming notification events as JSON to stdout. |
171
-
172
- The TypeScript library spawns these scripts as child processes and communicates via newline-delimited JSON on stdout, keeping the library dependency-free at runtime.
173
-
174
- ---
175
-
176
- ## License
177
-
178
- MIT
179
-
1
+ # electron-wns
2
+
3
+ Node native addon that allows you to receive push messages from Windows Push Notifications Services (WNS), in Electron (and node).
4
+
5
+ - Currently in an initial state of development, but so far I have been able to successfully
6
+ use this library to obtain a channel URI (with an included token), that could be used to send WNS
7
+ push messages to.
8
+
9
+ - Tested with Electron 32.2.4, but probably will work with most modern versions of electron (and node)
10
+ - Tested by launching in a packaged, and code signed context via a .MSIX installer (see https://www.electronforge.io/config/makers/msix)
11
+
12
+ - Library is actively being improved!
13
+
14
+ ## USAGE
15
+
16
+ 1. Clone this repo
17
+ 2. npm install
18
+ 3. npm run build (change the Electron version in package.json to match the version of electron your working with)
19
+ 4. Copy the built electron_wns.node into your electron project.
20
+ 5. Ensure that it is packaged up with the app. For electron packager / forge, you may need to adjust packager config:
21
+
22
+ Example:
23
+ - Place the .node file in assets/win32/wns/electron_wns.node within your repo.
24
+ - Adjust packager config to ensure that folder is packaged up with the application files:
25
+ ```
26
+ packagerConfig: {
27
+ extraResource: [
28
+ `./assets/${process.platform}`
29
+ ]
30
+ }
31
+ ```
32
+ - To reference the .node file by its absolute path I recommend a helper function
33
+ that works both when the app is packaged or not:
34
+
35
+ src/Assets.ts
36
+ ```
37
+ import { app } from 'electron';
38
+ import path from 'path';
39
+
40
+ // Helper functions for accessing assets/ folder when packaged with running electron app.
41
+ class Assets {
42
+ static getURL() {
43
+ if (app.isPackaged) {
44
+ return process.resourcesPath;
45
+ } else {
46
+ return path.normalize(`${__dirname}../../../assets`);
47
+ }
48
+ }
49
+ }
50
+
51
+ export default Assets;
52
+ ```
53
+
54
+ - require() the .node file to use it in the javascripts of your main process like so:
55
+ ```
56
+ const assetsURL = Assets.getURL();
57
+ const addonPath = path.join(assetsURL, 'win32', 'wns', 'electron_wns.node');
58
+
59
+ const runtimeRequire = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : require;
60
+
61
+ // Note: its a good idea to try/catch the following require() statement which will throw a MODULE_NOT_FOUND
62
+ // if the absolute path the .node file is wrong, or is compiled/built againts the wrong electron/node ABI.
63
+ electronWNS = runtimeRequire(addonPath);
64
+
65
+ const channel = await electronWNS.getChannel();
66
+ console.log('WNS channel URI:', channel.uri); // Your backend can use this to send to this device
67
+
68
+ electronWNS.startForegroundNotifications((notification) => {
69
+ console.log('Foreground WNS notification:', notification);
70
+ });
71
+
72
+ electronWNS.stopForegroundNotifications();
73
+ ```
74
+
75
+ ## Exposed API of electron_wns.node:
76
+
77
+ - `getChannel(): Promise<{ uri: string; expirationTicks: number }>`
78
+ - `startForegroundNotifications(callback: (notification) => void): void`
79
+ - `stopForegroundNotifications(): void`
80
+
81
+ ## Structure of Received Notifications
82
+
83
+ ```js
84
+ {
85
+ type: 'raw' | 'toast' | 'tile' | 'badge' | 'unknown',
86
+ content: string,
87
+ headers: Record<string, string> // populated for raw notifications
88
+ }
89
+ ```
90
+
91
+ ## TO COME:
92
+ - Typescript types
93
+ - Improving the way the library is integrated into your app - so that you can npm install, and access via a javascript wrapper
94
+ - electron rebuild support that automatically would detect your version of electron (electron rebuild)
95
+ - Typescript types/etc.
96
+
97
+ ## An Alternative Library:
98
+ - There is the NodeRT project: https://github.com/NodeRT/NodeRT
99
+ - But that is currently very outdated and does not compile against more modern versions of node/electron
package/binding.gyp ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "electron_wns",
5
+ "sources": [
6
+ "src/electron_wns.cpp"
7
+ ],
8
+ "include_dirs": [
9
+ "<!@(node -p \"require('node-addon-api').include\")"
10
+ ],
11
+ "defines": [
12
+ "NAPI_CPP_EXCEPTIONS"
13
+ ],
14
+ "dependencies": [
15
+ "<!(node -p \"require('node-addon-api').gyp\")"
16
+ ],
17
+ "conditions": [
18
+ ["OS=='win'", {
19
+ "libraries": [
20
+ "runtimeobject.lib",
21
+ "windowsapp.lib"
22
+ ],
23
+ "msvs_settings": {
24
+ "VCCLCompilerTool": {
25
+ "AdditionalOptions": [
26
+ "/EHsc"
27
+ ]
28
+ }
29
+ }
30
+ }]
31
+ ]
32
+ }
33
+ ]
34
+ }
package/index.js ADDED
@@ -0,0 +1,11 @@
1
+ const path = require('path');
2
+
3
+ const addonPath = path.join(__dirname, 'build', 'Release', 'electron_wns.node');
4
+ const binding = require(addonPath);
5
+
6
+ console.log('==> index.js binding.getChannel: ', typeof binding.getChannel);
7
+ module.exports = {
8
+ getChannel: binding.getChannel,
9
+ startForegroundNotifications: binding.startForegroundNotifications,
10
+ stopForegroundNotifications: binding.stopForegroundNotifications,
11
+ };
package/package.json CHANGED
@@ -1,40 +1,29 @@
1
- {
2
- "name": "electron-wns",
3
- "version": "0.0.0",
4
- "description": "Library for receiving Windows Push Notification Service (WNS) push messages in Electron apps",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist",
9
- "scripts"
10
- ],
11
- "scripts": {
12
- "build": "tsc",
13
- "test": "jest",
14
- "prepare": "npm run build"
15
- },
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/iotum/electron-wns.git"
19
- },
20
- "keywords": [
21
- "electron",
22
- "wns",
23
- "push",
24
- "notifications",
25
- "windows"
26
- ],
27
- "author": "",
28
- "license": "MIT",
29
- "bugs": {
30
- "url": "https://github.com/iotum/electron-wns/issues"
31
- },
32
- "homepage": "https://github.com/iotum/electron-wns#readme",
33
- "devDependencies": {
34
- "@types/jest": "^29.5.14",
35
- "@types/node": "^20.19.37",
36
- "jest": "^29.7.0",
37
- "ts-jest": "^29.4.6",
38
- "typescript": "^5.9.3"
39
- }
40
- }
1
+ {
2
+ "name": "electron-wns",
3
+ "version": "0.0.4",
4
+ "description": "Native Node addon for WNS channel creation and foreground notification listening",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "install": "npm run build:electron32",
8
+ "build": "npm run build:electron32",
9
+ "build:electron32": "electron-rebuild -f -v 32.2.4 -w electron-wns --module-dir .",
10
+ "build:node": "node-gyp rebuild",
11
+ "clean": "node-gyp clean"
12
+ },
13
+ "keywords": [
14
+ "electron",
15
+ "wns",
16
+ "windows",
17
+ "native-addon"
18
+ ],
19
+ "license": "MIT",
20
+ "gypfile": true,
21
+ "dependencies": {
22
+ "bindings": "^1.5.0",
23
+ "node-addon-api": "^8.1.0"
24
+ },
25
+ "devDependencies": {
26
+ "@electron/rebuild": "^3.7.1",
27
+ "node-gyp": "^11.1.0"
28
+ }
29
+ }
@@ -0,0 +1,256 @@
1
+ #include <napi.h>
2
+
3
+ #include <mutex>
4
+ #include <string>
5
+ #include <unordered_map>
6
+
7
+ #include <Windows.h>
8
+
9
+ #include <winrt/Windows.Data.Xml.Dom.h>
10
+ #include <winrt/Windows.Foundation.h>
11
+ #include <winrt/Windows.Foundation.Collections.h>
12
+ #include <winrt/Windows.Networking.PushNotifications.h>
13
+ #include <winrt/Windows.UI.Notifications.h>
14
+
15
+ namespace {
16
+ using winrt::Windows::Networking::PushNotifications::PushNotificationChannel;
17
+ using winrt::Windows::Networking::PushNotifications::PushNotificationChannelManager;
18
+ using winrt::Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs;
19
+ using winrt::Windows::Networking::PushNotifications::PushNotificationType;
20
+
21
+ std::mutex g_mutex;
22
+ std::once_flag g_apartmentInitFlag;
23
+ PushNotificationChannel g_channel{nullptr};
24
+ winrt::event_token g_notificationToken{};
25
+ bool g_isListening = false;
26
+ Napi::ThreadSafeFunction g_notificationTsfn;
27
+
28
+ std::string ToUtf8(std::wstring const& input);
29
+ std::string ToUtf8(winrt::hstring const& input);
30
+ PushNotificationChannel GetOrCreateChannel();
31
+
32
+ class GetChannelWorker : public Napi::AsyncWorker {
33
+ public:
34
+ GetChannelWorker(const Napi::Env& env, Napi::Promise::Deferred deferred)
35
+ : Napi::AsyncWorker(env), deferred_(deferred) {}
36
+
37
+ ~GetChannelWorker() override = default;
38
+
39
+ void Execute() override {
40
+ try {
41
+ auto channel = GetOrCreateChannel();
42
+ uri_ = ToUtf8(channel.Uri());
43
+
44
+ const auto expiration = channel.ExpirationTime();
45
+ expirationTicks_ = expiration.time_since_epoch().count();
46
+ } catch (const winrt::hresult_error& error) {
47
+ SetError(ToUtf8(error.message()));
48
+ } catch (const std::exception& error) {
49
+ SetError(error.what());
50
+ }
51
+ }
52
+
53
+ void OnOK() override {
54
+ Napi::Object result = Napi::Object::New(Env());
55
+ result.Set("uri", uri_);
56
+ result.Set("expirationTicks", Napi::Number::New(Env(), static_cast<double>(expirationTicks_)));
57
+ deferred_.Resolve(result);
58
+ }
59
+
60
+ void OnError(const Napi::Error& error) override { deferred_.Reject(error.Value()); }
61
+
62
+ private:
63
+ Napi::Promise::Deferred deferred_;
64
+ std::string uri_;
65
+ int64_t expirationTicks_ = 0;
66
+ };
67
+
68
+ void EnsureApartmentInitialized() {
69
+ std::call_once(g_apartmentInitFlag, []() {
70
+ try {
71
+ winrt::init_apartment(winrt::apartment_type::multi_threaded);
72
+ } catch (const winrt::hresult_error& error) {
73
+ if (error.code() != RPC_E_CHANGED_MODE) {
74
+ throw;
75
+ }
76
+ }
77
+ });
78
+ }
79
+
80
+ std::string ToUtf8(std::wstring const& input) {
81
+ if (input.empty()) {
82
+ return {};
83
+ }
84
+
85
+ int required = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), static_cast<int>(input.size()), nullptr, 0, nullptr, nullptr);
86
+ std::string output(static_cast<size_t>(required), '\0');
87
+ WideCharToMultiByte(CP_UTF8, 0, input.c_str(), static_cast<int>(input.size()), output.data(), required, nullptr, nullptr);
88
+ return output;
89
+ }
90
+
91
+ std::string ToUtf8(winrt::hstring const& input) {
92
+ return ToUtf8(std::wstring(input));
93
+ }
94
+
95
+ PushNotificationChannel GetOrCreateChannel() {
96
+ EnsureApartmentInitialized();
97
+
98
+ std::lock_guard<std::mutex> lock(g_mutex);
99
+ if (g_channel) {
100
+ return g_channel;
101
+ }
102
+
103
+ auto asyncOp = PushNotificationChannelManager::CreatePushNotificationChannelForApplicationAsync();
104
+ g_channel = asyncOp.get();
105
+ return g_channel;
106
+ }
107
+
108
+ std::string NotificationTypeToString(PushNotificationType type) {
109
+ switch (type) {
110
+ case PushNotificationType::Toast:
111
+ return "toast";
112
+ case PushNotificationType::Tile:
113
+ return "tile";
114
+ case PushNotificationType::Badge:
115
+ return "badge";
116
+ case PushNotificationType::Raw:
117
+ return "raw";
118
+ default:
119
+ return "unknown";
120
+ }
121
+ }
122
+
123
+ Napi::Value GetChannelWrapped(const Napi::CallbackInfo& info) {
124
+ Napi::Env env = info.Env();
125
+ auto deferred = Napi::Promise::Deferred::New(env);
126
+
127
+ auto* worker = new GetChannelWorker(env, deferred);
128
+ worker->Queue();
129
+
130
+ return deferred.Promise();
131
+ }
132
+
133
+ Napi::Value StartForegroundNotificationsWrapped(const Napi::CallbackInfo& info) {
134
+ Napi::Env env = info.Env();
135
+ if (info.Length() < 1 || !info[0].IsFunction()) {
136
+ throw Napi::TypeError::New(env, "startForegroundNotifications requires a callback function");
137
+ }
138
+
139
+ Napi::Function callback = info[0].As<Napi::Function>();
140
+
141
+ EnsureApartmentInitialized();
142
+ auto channel = GetOrCreateChannel();
143
+
144
+ std::lock_guard<std::mutex> lock(g_mutex);
145
+
146
+ if (g_isListening) {
147
+ if (g_notificationTsfn) {
148
+ g_notificationTsfn.Release();
149
+ }
150
+ channel.PushNotificationReceived(g_notificationToken);
151
+ g_isListening = false;
152
+ }
153
+
154
+ g_notificationTsfn = Napi::ThreadSafeFunction::New(
155
+ env,
156
+ callback,
157
+ "wns-foreground-notification-callback",
158
+ 0,
159
+ 1);
160
+
161
+ g_notificationToken = channel.PushNotificationReceived([](PushNotificationChannel const&, PushNotificationReceivedEventArgs const& args) {
162
+ std::lock_guard<std::mutex> callbackLock(g_mutex);
163
+ if (!g_notificationTsfn) {
164
+ return;
165
+ }
166
+
167
+ struct NotificationPayload {
168
+ std::string type;
169
+ std::string content;
170
+ std::unordered_map<std::string, std::string> headers;
171
+ } payload;
172
+
173
+ payload.type = NotificationTypeToString(args.NotificationType());
174
+
175
+ if (args.NotificationType() == PushNotificationType::Raw) {
176
+ auto raw = args.RawNotification();
177
+ payload.content = ToUtf8(raw.Content());
178
+
179
+ auto headerMap = raw.Headers();
180
+ for (const auto& pair : headerMap) {
181
+ payload.headers[ToUtf8(pair.Key())] = ToUtf8(pair.Value());
182
+ }
183
+ } else if (args.ToastNotification()) {
184
+ auto xmlDocument = args.ToastNotification().Content();
185
+ payload.content = ToUtf8(xmlDocument.GetXml());
186
+ }
187
+
188
+ auto status = g_notificationTsfn.BlockingCall(
189
+ new NotificationPayload(std::move(payload)),
190
+ [](Napi::Env callbackEnv, Napi::Function jsCallback, NotificationPayload* data) {
191
+ Napi::Object notification = Napi::Object::New(callbackEnv);
192
+ notification.Set("type", data->type);
193
+ notification.Set("content", data->content);
194
+
195
+ Napi::Object headers = Napi::Object::New(callbackEnv);
196
+ for (const auto& [key, value] : data->headers) {
197
+ headers.Set(key, value);
198
+ }
199
+ notification.Set("headers", headers);
200
+
201
+ jsCallback.Call({notification});
202
+ delete data;
203
+ });
204
+
205
+ if (status != napi_ok) {
206
+ return;
207
+ }
208
+ });
209
+
210
+ g_isListening = true;
211
+ return env.Undefined();
212
+ }
213
+
214
+ Napi::Value StopForegroundNotificationsWrapped(const Napi::CallbackInfo& info) {
215
+ Napi::Env env = info.Env();
216
+ EnsureApartmentInitialized();
217
+
218
+ std::lock_guard<std::mutex> lock(g_mutex);
219
+
220
+ if (!g_isListening) {
221
+ return env.Undefined();
222
+ }
223
+
224
+ if (g_channel) {
225
+ g_channel.PushNotificationReceived(g_notificationToken);
226
+ }
227
+
228
+ if (g_notificationTsfn) {
229
+ g_notificationTsfn.Release();
230
+ g_notificationTsfn = {};
231
+ }
232
+
233
+ g_isListening = false;
234
+ return env.Undefined();
235
+ }
236
+
237
+ Napi::Object Initialize(Napi::Env env, Napi::Object exports) {
238
+ try {
239
+ EnsureApartmentInitialized();
240
+ } catch (const winrt::hresult_error& error) {
241
+ Napi::Error::New(env, ToUtf8(error.message())).ThrowAsJavaScriptException();
242
+ return exports;
243
+ } catch (const std::exception& error) {
244
+ Napi::Error::New(env, error.what()).ThrowAsJavaScriptException();
245
+ return exports;
246
+ }
247
+
248
+ exports.Set("getChannel", Napi::Function::New(env, GetChannelWrapped));
249
+ exports.Set("startForegroundNotifications", Napi::Function::New(env, StartForegroundNotificationsWrapped));
250
+ exports.Set("stopForegroundNotifications", Napi::Function::New(env, StopForegroundNotificationsWrapped));
251
+
252
+ return exports;
253
+ }
254
+ } // namespace
255
+
256
+ NODE_API_MODULE(electron_wns, Initialize)
package/dist/channel.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * WNS channel management – obtaining and caching the push notification channel URI.
3
- */
4
- import { WNSChannel } from './types';
5
- /**
6
- * Request a push notification channel URI from WNS by running the
7
- * `get-channel.ps1` PowerShell helper.
8
- *
9
- * @throws {Error} If PowerShell fails or the channel URI cannot be obtained.
10
- */
11
- export declare function requestChannel(powershellPath: string): Promise<WNSChannel>;