@10p.io/tunnel 0.0.0-stage → 20.60.1

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.
Files changed (4) hide show
  1. package/README.md +88 -2
  2. package/index.d.ts +116 -0
  3. package/index.js +328 -0
  4. package/package.json +40 -4
package/README.md CHANGED
@@ -1,3 +1,89 @@
1
- # Temporary Holding Version
1
+ # @10p.io/tunnel
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ TUN device + smoltcp userspace TCP/IP stack NAPI module for planx vnet (Pattern C privileged daemon).
4
+
5
+ ## Overview
6
+
7
+ Pattern C 分離 model の native side。 planx-networkd (= root process) が本 NAPI module を load
8
+ して TUN device + smoltcp Interface + tokio poll loop を起動する。 USER process side の
9
+ planx daemon は tRPC over unix socket で networkd に接続し、 L4 event のみ boundary を超える。
10
+
11
+ ## NAPI exports
12
+
13
+ - `setup_vnet({ selfHip, prefix, mtu })` → `{ ifaceName }`
14
+ - `addPeerAddress({ hipBytes })` / `removePeerAddress({ hipBytes })`
15
+ - `injectTcpData({ connId, payload })` / `injectTcpClose({ connId })` / `injectUdpSend({ dstPort, srcAddr, srcPort, payload })`
16
+ - `onEvent((ev: NetworkdEvent) => void)` / `offEvent()`
17
+
18
+ ## Dev build (single platform)
19
+
20
+ ```bash
21
+ nx build @10p.io/tunnel # release .node (native target only)
22
+ nx build:debug @10p.io/tunnel # debug .node
23
+ nx test @10p.io/tunnel # cargo test
24
+ nx lint @10p.io/tunnel # cargo clippy
25
+ ```
26
+
27
+ ## Release flow (5 platform fan-out + publish)
28
+
29
+ 5 per-arch package を repo commit して GAR publish するための flow。
30
+ **Mac local で実行する想定** (= CI では走らせない)。
31
+
32
+ ### Prerequisites
33
+
34
+ ```bash
35
+ brew install zig
36
+ rustup target add aarch64-apple-darwin x86_64-apple-darwin \
37
+ x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu \
38
+ x86_64-unknown-linux-musl
39
+ gcloud auth application-default login # or GOOGLE_APPLICATION_CREDENTIALS export
40
+ ```
41
+
42
+ ### Steps
43
+
44
+ ```bash
45
+ # 1. 5 platform 分の .node を prebuilt/ に生成
46
+ nx prebuild @10p.io/tunnel
47
+
48
+ # 2. prebuilt/*.node を packages/@10p.io/tunnel-{arch}/ に配布 +
49
+ # main package の index.js / index.d.ts を最新化
50
+ nx build @10p.io/tunnel
51
+
52
+ # 3. (commit .node files to repo — Rust source 改修ごとに必要)
53
+ git add prebuilt/ ../../../packages/@10p.io/tunnel-*/planx-tunnel.*.node
54
+ git commit -m "chore(tunnel): rebuild native binaries"
55
+
56
+ # 4. 全 publish (= main + 5 per-arch を tag:package run-many で publish)
57
+ nx run-many -t deploy -p 'tag:package' --parallel=2
58
+ ```
59
+
60
+ ### Dry run
61
+
62
+ ```bash
63
+ DRY_RUN=true nx run @10p.io/tunnel:deploy
64
+ ```
65
+
66
+ ## Per-arch binaries
67
+
68
+ | Package | Platform | libc |
69
+ | ------------------------------------------------ | ---------------- | ---- |
70
+ | `@10p.io/tunnel-darwin-arm64` | macOS Apple Silicon | - |
71
+ | `@10p.io/tunnel-darwin-x64` | macOS Intel | - |
72
+ | `@10p.io/tunnel-linux-x64-gnu` | Linux x86_64 | glibc |
73
+ | `@10p.io/tunnel-linux-arm64-gnu` | Linux ARM64 | glibc |
74
+ | `@10p.io/tunnel-linux-x64-musl` | Linux x86_64 | musl |
75
+
76
+ main `@10p.io/tunnel` package が optionalDependencies で各 per-arch を参照し、
77
+ runtime に NAPI loader (`index.js`) が platform 判定で適切な `.node` を require する。
78
+
79
+ ## Troubleshooting
80
+
81
+ - **401/403 on publish** → ~/.npmrc の GAR token 切れ / 権限を確認。
82
+ CI では on-merge-to-develop.yml の "Configure Artifact Registry auth" step が token を
83
+ 供給する (deploy script 自身は auth しない、#4645 で npx auth-refresh を撤去)。
84
+ 手動で publish する場合のみ `npx google-artifactregistry-auth` で refresh する。
85
+ - **napi build で "linker `cc` not found"** (Linux cross-compile) →
86
+ `--zig` flag が抜けている。 `prebuild.sh` 経由で実行する。
87
+ - **`cargo: command not found`** → rustup PATH 未設定。
88
+ `export PATH="$HOME/.cargo/bin:$PATH"`。
89
+ - **prebuilt/*.node が古い** → `nx prebuild` を re-run して `git add` し直す。
package/index.d.ts ADDED
@@ -0,0 +1,116 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ /**
7
+ * L4 event。 tagged union (= JS では `type` field で discriminator)。
8
+ *
9
+ * Note: NAPI-RS は Rust enum を tagged union として直接 export できないため、
10
+ * flat struct + `event_type` 文字列 + 全 field optional の形にする (= 旧 PacketEvent 互換)。
11
+ */
12
+ export interface NetworkdEvent {
13
+ /**
14
+ * "tcp_open" | "tcp_data" | "tcp_fin" | "tcp_rst" | "udp_dgram" |
15
+ * "tun_open_ok" | "tun_open_error" | "iface_build_error" | "iface_ready"
16
+ */
17
+ eventType: string
18
+ /** connection id (TCP 系のみ、 UDP / 状態 event は 0)。 */
19
+ connId: bigint
20
+ /** dst port (tcp_open / udp_dgram で meaningful、 他は 0)。 */
21
+ dstPort: number
22
+ /** payload bytes (event_type に依存)。 */
23
+ payload: Buffer
24
+ /** 送信元 IPv6 address (16 bytes raw)。 L4 event で meaningful、 状態 event は 0 bytes。 */
25
+ srcAddr: Buffer
26
+ /** 送信元 port。 */
27
+ srcPort: number
28
+ /** 宛先 IPv6 address (16 bytes raw)。 tcp_* で meaningful。 */
29
+ dstAddr: Buffer
30
+ }
31
+ /**
32
+ * JS から渡された callback を global state に登録する。
33
+ *
34
+ * 1 callback / engine の制約 (旧 callback は overwrite される)。 poll loop は state から
35
+ * callback を都度 lock-load して呼ぶ。
36
+ */
37
+ export declare function onEvent(callback: (arg: NetworkdEvent) => any): void
38
+ /** global state から callback を解除する (= 以降の poll loop event は dropped)。 */
39
+ export declare function offEvent(): void
40
+ export interface SetExitCaptureInput {
41
+ enabled: boolean
42
+ /** TUN に入れてはいけない address (exit 先 peer との WebRTC の相手、TURN 等)。元の経路の host route を張る。 */
43
+ bypass: Array<string>
44
+ /** ORCHID 以外の IPv6 も exit へ出すか (既定 false: exit が IPv6 に出られない時、SYN に RST を返して IPv4 に落とす)。 */
45
+ ipv6?: boolean
46
+ }
47
+ export interface SetExitCaptureOutput {
48
+ /** 実際に host route を張った bypass。 */
49
+ bypass: Array<string>
50
+ /** 失敗した経路の命令 (既にある / 既に無い経路も含む)。 */
51
+ failed: Array<string>
52
+ }
53
+ export interface InjectUdpDatagramInput {
54
+ /** 16 byte (IPv4 は `::ffff:a.b.c.d`)。返りの送り元 = 元の宛先。 */
55
+ srcAddr: Buffer
56
+ srcPort: number
57
+ dstAddr: Buffer
58
+ dstPort: number
59
+ payload: Buffer
60
+ }
61
+ export declare function setExitCapture(input: SetExitCaptureInput): SetExitCaptureOutput
62
+ export declare function exitDefaultGateway(): string | null
63
+ export declare function clearStaleExitRoutes(bypass: Array<string>): Array<string>
64
+ export declare function injectUdpDatagram(input: InjectUdpDatagramInput): void
65
+ export declare function injectTcpData(input: InjectTcpDataInput): void
66
+ export declare function injectTcpClose(input: InjectTcpCloseInput): void
67
+ export declare function injectUdpSend(input: InjectUdpSendInput): void
68
+ export declare function addPeerAddress(input: PeerAddressInput): void
69
+ export declare function removePeerAddress(input: PeerAddressInput): void
70
+ export declare function addSelfAddress(input: AddSelfAddressInput): void
71
+ export declare function setupVnet(input: SetupVnetInput): SetupVnetOutput
72
+ /** setup_vnet input。 */
73
+ export interface SetupVnetInput {
74
+ /** 自端末 HIP (= ORCHID v2 IPv6 文字列、 例: "2001:2a:dead:beef:8000:abcd:1234:5678")。 */
75
+ selfHip: string
76
+ /** routing prefix 長 (推奨: 32 = ORCHID v2 prefix + planx OGA ID で peer space 全域)。 */
77
+ prefix: number
78
+ /** MTU (推奨: 1280 = IPv6 minimum)。 */
79
+ mtu: number
80
+ /** 任意で interface name (None なら OS 既定)。 */
81
+ interfaceName?: string
82
+ }
83
+ /** setup_vnet output。 */
84
+ export interface SetupVnetOutput {
85
+ /** OS が assign した実 interface name (= "utun9" 等)。 */
86
+ ifaceName: string
87
+ }
88
+ /** add_self_address input (P3: hip 単位 additive 登録)。 */
89
+ export interface AddSelfAddressInput {
90
+ /** 追加する自 hip (= ORCHID v2 IPv6 文字列)。 */
91
+ selfHip: string
92
+ }
93
+ /** add/remove_peer_address input。 */
94
+ export interface PeerAddressInput {
95
+ /** peer HIP IPv6 raw 16 byte buffer。 */
96
+ hipBytes: Buffer
97
+ }
98
+ /** inject_tcp_data input。 */
99
+ export interface InjectTcpDataInput {
100
+ connId: bigint
101
+ payload: Buffer
102
+ }
103
+ /** inject_tcp_close input。 */
104
+ export interface InjectTcpCloseInput {
105
+ connId: bigint
106
+ }
107
+ /** inject_udp_send input。 */
108
+ export interface InjectUdpSendInput {
109
+ dstPort: number
110
+ /** 送信元 IPv6 address (16 bytes raw、 = remote peer の HIP)。 */
111
+ srcAddr: Buffer
112
+ srcPort: number
113
+ payload: Buffer
114
+ }
115
+ /** crate version (Cargo.toml の `[package].version` を expose)。 sanity check 用。 */
116
+ export declare function version(): string
package/index.js ADDED
@@ -0,0 +1,328 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path')
9
+
10
+ const { platform, arch } = process
11
+
12
+ let nativeBinding = null
13
+ let localFileExisted = false
14
+ let loadError = null
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
+ return readFileSync(lddPath, 'utf8').includes('musl')
22
+ } catch (e) {
23
+ return true
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header
27
+ return !glibcVersionRuntime
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'index.android-arm64.node'))
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./index.android-arm64.node')
39
+ } else {
40
+ nativeBinding = require('@10p.io/tunnel-android-arm64')
41
+ }
42
+ } catch (e) {
43
+ loadError = e
44
+ }
45
+ break
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'index.android-arm-eabi.node'))
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./index.android-arm-eabi.node')
51
+ } else {
52
+ nativeBinding = require('@10p.io/tunnel-android-arm-eabi')
53
+ }
54
+ } catch (e) {
55
+ loadError = e
56
+ }
57
+ break
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`)
60
+ }
61
+ break
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(
66
+ join(__dirname, 'index.win32-x64-msvc.node')
67
+ )
68
+ try {
69
+ if (localFileExisted) {
70
+ nativeBinding = require('./index.win32-x64-msvc.node')
71
+ } else {
72
+ nativeBinding = require('@10p.io/tunnel-win32-x64-msvc')
73
+ }
74
+ } catch (e) {
75
+ loadError = e
76
+ }
77
+ break
78
+ case 'ia32':
79
+ localFileExisted = existsSync(
80
+ join(__dirname, 'index.win32-ia32-msvc.node')
81
+ )
82
+ try {
83
+ if (localFileExisted) {
84
+ nativeBinding = require('./index.win32-ia32-msvc.node')
85
+ } else {
86
+ nativeBinding = require('@10p.io/tunnel-win32-ia32-msvc')
87
+ }
88
+ } catch (e) {
89
+ loadError = e
90
+ }
91
+ break
92
+ case 'arm64':
93
+ localFileExisted = existsSync(
94
+ join(__dirname, 'index.win32-arm64-msvc.node')
95
+ )
96
+ try {
97
+ if (localFileExisted) {
98
+ nativeBinding = require('./index.win32-arm64-msvc.node')
99
+ } else {
100
+ nativeBinding = require('@10p.io/tunnel-win32-arm64-msvc')
101
+ }
102
+ } catch (e) {
103
+ loadError = e
104
+ }
105
+ break
106
+ default:
107
+ throw new Error(`Unsupported architecture on Windows: ${arch}`)
108
+ }
109
+ break
110
+ case 'darwin':
111
+ localFileExisted = existsSync(join(__dirname, 'index.darwin-universal.node'))
112
+ try {
113
+ if (localFileExisted) {
114
+ nativeBinding = require('./index.darwin-universal.node')
115
+ } else {
116
+ nativeBinding = require('@10p.io/tunnel-darwin-universal')
117
+ }
118
+ break
119
+ } catch {}
120
+ switch (arch) {
121
+ case 'x64':
122
+ localFileExisted = existsSync(join(__dirname, 'index.darwin-x64.node'))
123
+ try {
124
+ if (localFileExisted) {
125
+ nativeBinding = require('./index.darwin-x64.node')
126
+ } else {
127
+ nativeBinding = require('@10p.io/tunnel-darwin-x64')
128
+ }
129
+ } catch (e) {
130
+ loadError = e
131
+ }
132
+ break
133
+ case 'arm64':
134
+ localFileExisted = existsSync(
135
+ join(__dirname, 'index.darwin-arm64.node')
136
+ )
137
+ try {
138
+ if (localFileExisted) {
139
+ nativeBinding = require('./index.darwin-arm64.node')
140
+ } else {
141
+ nativeBinding = require('@10p.io/tunnel-darwin-arm64')
142
+ }
143
+ } catch (e) {
144
+ loadError = e
145
+ }
146
+ break
147
+ default:
148
+ throw new Error(`Unsupported architecture on macOS: ${arch}`)
149
+ }
150
+ break
151
+ case 'freebsd':
152
+ if (arch !== 'x64') {
153
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
154
+ }
155
+ localFileExisted = existsSync(join(__dirname, 'index.freebsd-x64.node'))
156
+ try {
157
+ if (localFileExisted) {
158
+ nativeBinding = require('./index.freebsd-x64.node')
159
+ } else {
160
+ nativeBinding = require('@10p.io/tunnel-freebsd-x64')
161
+ }
162
+ } catch (e) {
163
+ loadError = e
164
+ }
165
+ break
166
+ case 'linux':
167
+ switch (arch) {
168
+ case 'x64':
169
+ if (isMusl()) {
170
+ localFileExisted = existsSync(
171
+ join(__dirname, 'index.linux-x64-musl.node')
172
+ )
173
+ try {
174
+ if (localFileExisted) {
175
+ nativeBinding = require('./index.linux-x64-musl.node')
176
+ } else {
177
+ nativeBinding = require('@10p.io/tunnel-linux-x64-musl')
178
+ }
179
+ } catch (e) {
180
+ loadError = e
181
+ }
182
+ } else {
183
+ localFileExisted = existsSync(
184
+ join(__dirname, 'index.linux-x64-gnu.node')
185
+ )
186
+ try {
187
+ if (localFileExisted) {
188
+ nativeBinding = require('./index.linux-x64-gnu.node')
189
+ } else {
190
+ nativeBinding = require('@10p.io/tunnel-linux-x64-gnu')
191
+ }
192
+ } catch (e) {
193
+ loadError = e
194
+ }
195
+ }
196
+ break
197
+ case 'arm64':
198
+ if (isMusl()) {
199
+ localFileExisted = existsSync(
200
+ join(__dirname, 'index.linux-arm64-musl.node')
201
+ )
202
+ try {
203
+ if (localFileExisted) {
204
+ nativeBinding = require('./index.linux-arm64-musl.node')
205
+ } else {
206
+ nativeBinding = require('@10p.io/tunnel-linux-arm64-musl')
207
+ }
208
+ } catch (e) {
209
+ loadError = e
210
+ }
211
+ } else {
212
+ localFileExisted = existsSync(
213
+ join(__dirname, 'index.linux-arm64-gnu.node')
214
+ )
215
+ try {
216
+ if (localFileExisted) {
217
+ nativeBinding = require('./index.linux-arm64-gnu.node')
218
+ } else {
219
+ nativeBinding = require('@10p.io/tunnel-linux-arm64-gnu')
220
+ }
221
+ } catch (e) {
222
+ loadError = e
223
+ }
224
+ }
225
+ break
226
+ case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'index.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./index.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('@10p.io/tunnel-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'index.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./index.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('@10p.io/tunnel-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'index.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./index.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('@10p.io/tunnel-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'index.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./index.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('@10p.io/tunnel-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
285
+ localFileExisted = existsSync(
286
+ join(__dirname, 'index.linux-s390x-gnu.node')
287
+ )
288
+ try {
289
+ if (localFileExisted) {
290
+ nativeBinding = require('./index.linux-s390x-gnu.node')
291
+ } else {
292
+ nativeBinding = require('@10p.io/tunnel-linux-s390x-gnu')
293
+ }
294
+ } catch (e) {
295
+ loadError = e
296
+ }
297
+ break
298
+ default:
299
+ throw new Error(`Unsupported architecture on Linux: ${arch}`)
300
+ }
301
+ break
302
+ default:
303
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
304
+ }
305
+
306
+ if (!nativeBinding) {
307
+ if (loadError) {
308
+ throw loadError
309
+ }
310
+ throw new Error(`Failed to load native binding`)
311
+ }
312
+
313
+ const { onEvent, offEvent, setExitCapture, exitDefaultGateway, clearStaleExitRoutes, injectUdpDatagram, injectTcpData, injectTcpClose, injectUdpSend, addPeerAddress, removePeerAddress, addSelfAddress, setupVnet, version } = nativeBinding
314
+
315
+ module.exports.onEvent = onEvent
316
+ module.exports.offEvent = offEvent
317
+ module.exports.setExitCapture = setExitCapture
318
+ module.exports.exitDefaultGateway = exitDefaultGateway
319
+ module.exports.clearStaleExitRoutes = clearStaleExitRoutes
320
+ module.exports.injectUdpDatagram = injectUdpDatagram
321
+ module.exports.injectTcpData = injectTcpData
322
+ module.exports.injectTcpClose = injectTcpClose
323
+ module.exports.injectUdpSend = injectUdpSend
324
+ module.exports.addPeerAddress = addPeerAddress
325
+ module.exports.removePeerAddress = removePeerAddress
326
+ module.exports.addSelfAddress = addSelfAddress
327
+ module.exports.setupVnet = setupVnet
328
+ module.exports.version = version
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@10p.io/tunnel",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "20.60.1",
4
+ "author": "Nozomu Miyamoto",
5
+ "description": "TUN device + smoltcp userspace TCP/IP stack NAPI module for planx vnet (Pattern C privileged daemon)",
6
+ "main": "index.js",
7
+ "types": "index.d.ts",
8
+ "homepage": "https://github.com/nontangent/x_x_machina/tree/develop/packages/@10p.io/tunnel",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/nontangent/x_x_machina.git"
12
+ },
13
+ "license": "MIT",
14
+ "napi": {
15
+ "binaryName": "planx-tunnel",
16
+ "targets": [
17
+ "aarch64-apple-darwin",
18
+ "x86_64-apple-darwin",
19
+ "x86_64-unknown-linux-gnu",
20
+ "aarch64-unknown-linux-gnu",
21
+ "x86_64-unknown-linux-musl",
22
+ "x86_64-pc-windows-msvc"
23
+ ]
24
+ },
25
+ "scripts": {
26
+ "artifacts": "napi artifacts",
27
+ "build": "napi build --platform --release",
28
+ "build:debug": "napi build --platform",
29
+ "version": "napi version"
30
+ },
31
+ "devDependencies": {
32
+ "@napi-rs/cli": "^2.18.4"
33
+ },
34
+ "engines": {
35
+ "node": ">= 20"
36
+ },
37
+ "files": [
38
+ "index.js",
39
+ "index.d.ts",
40
+ "*.node"
41
+ ]
42
+ }