@push.rocks/smartdns 7.5.1 → 7.8.0

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.
Binary file
Binary file
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartdns',
6
- version: '7.5.1',
6
+ version: '7.8.0',
7
7
  description: 'A robust TypeScript library providing advanced DNS management and resolution capabilities including support for DNSSEC, custom DNS servers, and integration with various DNS providers.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHlMQUF5TDtDQUN2TSxDQUFBIn0=
@@ -1,47 +1,28 @@
1
1
  import * as plugins from './plugins.js';
2
2
  export type TDnsProvider = 'google' | 'cloudflare';
3
3
  export declare const makeNodeProcessUseDnsProvider: (providerArg: TDnsProvider) => void;
4
+ export type TResolutionStrategy = 'doh' | 'udp' | 'system' | 'prefer-system' | 'prefer-udp';
4
5
  export interface ISmartDnsConstructorOptions {
5
- }
6
- export interface IDnsJsonResponse {
7
- Status: number;
8
- TC: boolean;
9
- RD: boolean;
10
- RA: boolean;
11
- AD: boolean;
12
- CD: boolean;
13
- Question: Array<{
14
- name: string;
15
- type: number;
16
- }>;
17
- Answer: Array<{
18
- name: string;
19
- type: number;
20
- TTL: number;
21
- data: string;
22
- }>;
23
- Additional: [];
24
- Comment: string;
6
+ strategy?: TResolutionStrategy;
7
+ allowDohFallback?: boolean;
8
+ timeoutMs?: number;
25
9
  }
26
10
  /**
27
- * class dnsly offers methods for working with dns from a dns provider like Google DNS
11
+ * Smartdns offers methods for working with DNS resolution.
12
+ * Supports system resolver, UDP wire-format, and DoH (DNS-over-HTTPS) via a Rust binary.
28
13
  */
29
14
  export declare class Smartdns {
30
- dnsServerIp: string;
31
- dnsServerPort: number;
15
+ private strategy;
16
+ private allowDohFallback;
17
+ private timeoutMs;
18
+ private rustBridge;
32
19
  dnsTypeMap: {
33
20
  [key: string]: number;
34
21
  };
35
- /**
36
- * constructor for class dnsly
37
- */
38
22
  constructor(optionsArg: ISmartDnsConstructorOptions);
23
+ private getRustBridge;
39
24
  /**
40
- * check a dns record until it has propagated to Google DNS
41
- * should be considerably fast
42
- * @param recordNameArg
43
- * @param recordTypeArg
44
- * @param expectedValue
25
+ * check a dns record until it has propagated
45
26
  */
46
27
  checkUntilAvailable(recordNameArg: string, recordTypeArg: plugins.tsclass.network.TDnsRecordType, expectedValue: string, cyclesArg?: number, intervalArg?: number): Promise<boolean>;
47
28
  /**
@@ -64,4 +45,12 @@ export declare class Smartdns {
64
45
  getNameServers(domainNameArg: string): Promise<string[]>;
65
46
  convertDnsTypeNameToTypeNumber(dnsTypeNameArg: string): number;
66
47
  convertDnsTypeNumberToTypeName(dnsTypeNumberArg: number): plugins.tsclass.network.TDnsRecordType;
48
+ /**
49
+ * Convert a DNS type string from Rust (e.g. "A", "AAAA") to the canonical TDnsRecordType.
50
+ */
51
+ private convertDnsTypeNameToCanonical;
52
+ /**
53
+ * Destroy the Rust client bridge and free resources.
54
+ */
55
+ destroy(): void;
67
56
  }
@@ -1,4 +1,5 @@
1
1
  import * as plugins from './plugins.js';
2
+ import { RustDnsClientBridge } from './classes.rustdnsclientbridge.js';
2
3
  export const makeNodeProcessUseDnsProvider = (providerArg) => {
3
4
  switch (providerArg) {
4
5
  case 'cloudflare':
@@ -19,27 +20,38 @@ export const makeNodeProcessUseDnsProvider = (providerArg) => {
19
20
  }
20
21
  };
21
22
  /**
22
- * class dnsly offers methods for working with dns from a dns provider like Google DNS
23
+ * Smartdns offers methods for working with DNS resolution.
24
+ * Supports system resolver, UDP wire-format, and DoH (DNS-over-HTTPS) via a Rust binary.
23
25
  */
24
26
  export class Smartdns {
25
- /**
26
- * constructor for class dnsly
27
- */
28
27
  constructor(optionsArg) {
28
+ this.strategy = 'prefer-system';
29
+ this.allowDohFallback = true;
30
+ this.rustBridge = null;
29
31
  this.dnsTypeMap = {
30
32
  A: 1,
31
- AAAA: 28,
33
+ NS: 2,
32
34
  CNAME: 5,
35
+ SOA: 6,
36
+ PTR: 12,
33
37
  MX: 15,
34
38
  TXT: 16,
39
+ AAAA: 28,
40
+ SRV: 33,
35
41
  };
42
+ this.strategy = optionsArg?.strategy || 'prefer-system';
43
+ this.allowDohFallback =
44
+ optionsArg?.allowDohFallback === undefined ? true : optionsArg.allowDohFallback;
45
+ this.timeoutMs = optionsArg?.timeoutMs;
46
+ }
47
+ getRustBridge() {
48
+ if (!this.rustBridge) {
49
+ this.rustBridge = new RustDnsClientBridge();
50
+ }
51
+ return this.rustBridge;
36
52
  }
37
53
  /**
38
- * check a dns record until it has propagated to Google DNS
39
- * should be considerably fast
40
- * @param recordNameArg
41
- * @param recordTypeArg
42
- * @param expectedValue
54
+ * check a dns record until it has propagated
43
55
  */
44
56
  async checkUntilAvailable(recordNameArg, recordTypeArg, expectedValue, cyclesArg = 50, intervalArg = 500) {
45
57
  let runCycles = 0;
@@ -65,7 +77,6 @@ export class Smartdns {
65
77
  }
66
78
  }
67
79
  catch (err) {
68
- // console.log(err);
69
80
  await plugins.smartdelay.delayFor(intervalArg);
70
81
  return await doCheck();
71
82
  }
@@ -96,44 +107,96 @@ export class Smartdns {
96
107
  return await this.getRecords(recordNameArg, 'TXT');
97
108
  }
98
109
  async getRecords(recordNameArg, recordTypeArg, retriesCounterArg = 20) {
99
- const requestUrl = `https://cloudflare-dns.com/dns-query?name=${recordNameArg}&type=${recordTypeArg}&do=1`;
100
- const returnArray = [];
101
- const getResponseBody = async (counterArg = 0) => {
102
- const response = await plugins.smartrequest.request(requestUrl, {
103
- method: 'GET',
104
- headers: {
105
- accept: 'application/dns-json',
106
- },
107
- });
108
- const responseBody = response.body;
109
- if (responseBody?.Status !== 0 && counterArg < retriesCounterArg) {
110
- await plugins.smartdelay.delayFor(500);
111
- return getResponseBody(counterArg + 1);
110
+ const trySystem = async () => {
111
+ // Prefer dns.lookup for A/AAAA so hosts file and OS resolver are honored
112
+ if (recordTypeArg === 'A' || recordTypeArg === 'AAAA') {
113
+ const family = recordTypeArg === 'A' ? 4 : 6;
114
+ const addresses = await new Promise((resolve, reject) => {
115
+ const timer = this.timeoutMs
116
+ ? setTimeout(() => reject(new Error('system lookup timeout')), this.timeoutMs)
117
+ : null;
118
+ plugins.dns.lookup(recordNameArg, { family, all: true }, (err, result) => {
119
+ if (timer)
120
+ clearTimeout(timer);
121
+ if (err)
122
+ return reject(err);
123
+ resolve(result || []);
124
+ });
125
+ });
126
+ return addresses.map((a) => ({
127
+ name: recordNameArg,
128
+ type: recordTypeArg,
129
+ dnsSecEnabled: false,
130
+ value: a.address,
131
+ }));
112
132
  }
113
- else {
114
- return responseBody;
133
+ if (recordTypeArg === 'TXT') {
134
+ const records = await new Promise((resolve, reject) => {
135
+ const timer = this.timeoutMs
136
+ ? setTimeout(() => reject(new Error('system resolveTxt timeout')), this.timeoutMs)
137
+ : null;
138
+ plugins.dns.resolveTxt(recordNameArg, (err, res) => {
139
+ if (timer)
140
+ clearTimeout(timer);
141
+ if (err)
142
+ return reject(err);
143
+ resolve(res || []);
144
+ });
145
+ });
146
+ return records.map((chunks) => ({
147
+ name: recordNameArg,
148
+ type: 'TXT',
149
+ dnsSecEnabled: false,
150
+ value: chunks.join(''),
151
+ }));
115
152
  }
153
+ return [];
116
154
  };
117
- const responseBody = await getResponseBody();
118
- if (!responseBody.Answer || !typeof responseBody.Answer[Symbol.iterator]) {
119
- return returnArray;
120
- }
121
- for (const dnsEntry of responseBody.Answer) {
122
- if (dnsEntry.data.startsWith('"') && dnsEntry.data.endsWith('"')) {
123
- dnsEntry.data = dnsEntry.data.replace(/^"(.*)"$/, '$1');
155
+ const tryRust = async (protocol) => {
156
+ const bridge = this.getRustBridge();
157
+ const result = await bridge.resolve(recordNameArg, recordTypeArg, protocol, undefined, undefined, this.timeoutMs);
158
+ return result.answers.map((answer) => ({
159
+ name: answer.name,
160
+ type: this.convertDnsTypeNameToCanonical(answer.type) || recordTypeArg,
161
+ dnsSecEnabled: result.adFlag,
162
+ value: answer.value,
163
+ }));
164
+ };
165
+ try {
166
+ if (this.strategy === 'system') {
167
+ return await trySystem();
168
+ }
169
+ if (this.strategy === 'doh') {
170
+ return await tryRust('doh');
124
171
  }
125
- if (dnsEntry.name.endsWith('.')) {
126
- dnsEntry.name = dnsEntry.name.substring(0, dnsEntry.name.length - 1);
172
+ if (this.strategy === 'udp') {
173
+ return await tryRust('udp');
174
+ }
175
+ if (this.strategy === 'prefer-udp') {
176
+ try {
177
+ const udpRes = await tryRust('udp');
178
+ if (udpRes.length > 0)
179
+ return udpRes;
180
+ return await tryRust('doh');
181
+ }
182
+ catch (err) {
183
+ return await tryRust('doh');
184
+ }
185
+ }
186
+ // prefer-system (default)
187
+ try {
188
+ const sysRes = await trySystem();
189
+ if (sysRes.length > 0)
190
+ return sysRes;
191
+ return this.allowDohFallback ? await tryRust('doh') : [];
192
+ }
193
+ catch (err) {
194
+ return this.allowDohFallback ? await tryRust('doh') : [];
127
195
  }
128
- returnArray.push({
129
- name: dnsEntry.name,
130
- type: this.convertDnsTypeNumberToTypeName(dnsEntry.type),
131
- dnsSecEnabled: responseBody.AD,
132
- value: dnsEntry.data,
133
- });
134
196
  }
135
- // console.log(responseBody);
136
- return returnArray;
197
+ catch (finalErr) {
198
+ return [];
199
+ }
137
200
  }
138
201
  /**
139
202
  * gets a record using nodejs dns resolver
@@ -182,5 +245,24 @@ export class Smartdns {
182
245
  }
183
246
  return null;
184
247
  }
248
+ /**
249
+ * Convert a DNS type string from Rust (e.g. "A", "AAAA") to the canonical TDnsRecordType.
250
+ */
251
+ convertDnsTypeNameToCanonical(typeName) {
252
+ const upper = typeName.toUpperCase();
253
+ if (upper in this.dnsTypeMap) {
254
+ return upper;
255
+ }
256
+ return null;
257
+ }
258
+ /**
259
+ * Destroy the Rust client bridge and free resources.
260
+ */
261
+ destroy() {
262
+ if (this.rustBridge) {
263
+ this.rustBridge.kill();
264
+ this.rustBridge = null;
265
+ }
266
+ }
185
267
  }
186
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kbnNjbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jbGllbnQvY2xhc3Nlcy5kbnNjbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFJeEMsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxXQUF5QixFQUFFLEVBQUU7SUFDekUsUUFBUSxXQUFXLEVBQUUsQ0FBQztRQUNwQixLQUFLLFlBQVk7WUFDZixPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztnQkFDckIsU0FBUztnQkFDVCxTQUFTO2dCQUNULHdCQUF3QjtnQkFDeEIsd0JBQXdCO2FBQ3pCLENBQUMsQ0FBQztZQUNILE1BQU07UUFDUixLQUFLLFFBQVE7WUFDWCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztnQkFDckIsU0FBUztnQkFDVCxTQUFTO2dCQUNULHdCQUF3QjtnQkFDeEIsd0JBQXdCO2FBQ3pCLENBQUMsQ0FBQztJQUNQLENBQUM7QUFDSCxDQUFDLENBQUM7QUFpQkY7O0dBRUc7QUFDSCxNQUFNLE9BQU8sUUFBUTtJQVluQjs7T0FFRztJQUNILFlBQVksVUFBdUM7UUFYNUMsZUFBVSxHQUE4QjtZQUM3QyxDQUFDLEVBQUUsQ0FBQztZQUNKLElBQUksRUFBRSxFQUFFO1lBQ1IsS0FBSyxFQUFFLENBQUM7WUFDUixFQUFFLEVBQUUsRUFBRTtZQUNOLEdBQUcsRUFBRSxFQUFFO1NBQ1IsQ0FBQztJQUtvRCxDQUFDO0lBRXZEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxtQkFBbUIsQ0FDOUIsYUFBcUIsRUFDckIsYUFBcUQsRUFDckQsYUFBcUIsRUFDckIsWUFBb0IsRUFBRSxFQUN0QixjQUFzQixHQUFHO1FBRXpCLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNsQixNQUFNLE9BQU8sR0FBRyxLQUFLLElBQUksRUFBRTtZQUN6QixJQUFJLFNB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
268
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kbnNjbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jbGllbnQvY2xhc3Nlcy5kbnNjbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFJdkUsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxXQUF5QixFQUFFLEVBQUU7SUFDekUsUUFBUSxXQUFXLEVBQUUsQ0FBQztRQUNwQixLQUFLLFlBQVk7WUFDZixPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztnQkFDckIsU0FBUztnQkFDVCxTQUFTO2dCQUNULHdCQUF3QjtnQkFDeEIsd0JBQXdCO2FBQ3pCLENBQUMsQ0FBQztZQUNILE1BQU07UUFDUixLQUFLLFFBQVE7WUFDWCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztnQkFDckIsU0FBUztnQkFDVCxTQUFTO2dCQUNULHdCQUF3QjtnQkFDeEIsd0JBQXdCO2FBQ3pCLENBQUMsQ0FBQztJQUNQLENBQUM7QUFDSCxDQUFDLENBQUM7QUFVRjs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sUUFBUTtJQWtCbkIsWUFBWSxVQUF1QztRQWpCM0MsYUFBUSxHQUF3QixlQUFlLENBQUM7UUFDaEQscUJBQWdCLEdBQUcsSUFBSSxDQUFDO1FBRXhCLGVBQVUsR0FBK0IsSUFBSSxDQUFDO1FBRS9DLGVBQVUsR0FBOEI7WUFDN0MsQ0FBQyxFQUFFLENBQUM7WUFDSixFQUFFLEVBQUUsQ0FBQztZQUNMLEtBQUssRUFBRSxDQUFDO1lBQ1IsR0FBRyxFQUFFLENBQUM7WUFDTixHQUFHLEVBQUUsRUFBRTtZQUNQLEVBQUUsRUFBRSxFQUFFO1lBQ04sR0FBRyxFQUFFLEVBQUU7WUFDUCxJQUFJLEVBQUUsRUFBRTtZQUNSLEdBQUcsRUFBRSxFQUFFO1NBQ1IsQ0FBQztR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
@@ -0,0 +1,59 @@
1
+ export type TClientDnsCommands = {
2
+ resolve: {
3
+ params: IResolveParams;
4
+ result: IResolveResult;
5
+ };
6
+ ping: {
7
+ params: Record<string, never>;
8
+ result: {
9
+ pong: boolean;
10
+ };
11
+ };
12
+ };
13
+ export interface IResolveParams {
14
+ name: string;
15
+ recordType: string;
16
+ protocol: 'udp' | 'doh';
17
+ serverAddr?: string;
18
+ dohUrl?: string;
19
+ timeoutMs?: number;
20
+ }
21
+ export interface IClientDnsAnswer {
22
+ name: string;
23
+ type: string;
24
+ ttl: number;
25
+ value: string;
26
+ }
27
+ export interface IResolveResult {
28
+ answers: IClientDnsAnswer[];
29
+ adFlag: boolean;
30
+ rcode: number;
31
+ }
32
+ /**
33
+ * Bridge to the Rust DNS client binary via smartrust IPC.
34
+ */
35
+ export declare class RustDnsClientBridge {
36
+ private bridge;
37
+ private spawnPromise;
38
+ constructor();
39
+ /**
40
+ * Lazily spawn the Rust binary. Only spawns once, caches the promise.
41
+ */
42
+ ensureSpawned(): Promise<void>;
43
+ /**
44
+ * Resolve a DNS query through the Rust binary.
45
+ */
46
+ resolve(name: string, recordType: string, protocol: 'udp' | 'doh', serverAddr?: string, dohUrl?: string, timeoutMs?: number): Promise<IResolveResult>;
47
+ /**
48
+ * Ping the Rust binary for health check.
49
+ */
50
+ ping(): Promise<boolean>;
51
+ /**
52
+ * Kill the Rust process.
53
+ */
54
+ kill(): void;
55
+ /**
56
+ * Whether the bridge is running.
57
+ */
58
+ get running(): boolean;
59
+ }
@@ -0,0 +1,110 @@
1
+ import * as plugins from './plugins.js';
2
+ /**
3
+ * Bridge to the Rust DNS client binary via smartrust IPC.
4
+ */
5
+ export class RustDnsClientBridge {
6
+ constructor() {
7
+ this.spawnPromise = null;
8
+ const packageDir = plugins.path.resolve(plugins.path.dirname(new URL(import.meta.url).pathname), '..');
9
+ // Determine platform suffix for dist_rust binaries (matches tsrust naming)
10
+ const platformSuffix = getPlatformSuffix();
11
+ const localPaths = [];
12
+ // dist_rust/ candidates (tsrust cross-compiled output, platform-specific)
13
+ if (platformSuffix) {
14
+ localPaths.push(plugins.path.join(packageDir, 'dist_rust', `rustdns-client_${platformSuffix}`));
15
+ }
16
+ // dist_rust/ without suffix (native build)
17
+ localPaths.push(plugins.path.join(packageDir, 'dist_rust', 'rustdns-client'));
18
+ // Local dev build paths
19
+ localPaths.push(plugins.path.join(packageDir, 'rust', 'target', 'release', 'rustdns-client'));
20
+ localPaths.push(plugins.path.join(packageDir, 'rust', 'target', 'debug', 'rustdns-client'));
21
+ this.bridge = new plugins.smartrust.RustBridge({
22
+ binaryName: 'rustdns-client',
23
+ cliArgs: ['--management'],
24
+ requestTimeoutMs: 30_000,
25
+ readyTimeoutMs: 10_000,
26
+ localPaths,
27
+ searchSystemPath: false,
28
+ });
29
+ this.bridge.on('stderr', (line) => {
30
+ if (line.trim()) {
31
+ console.log(`[rustdns-client] ${line}`);
32
+ }
33
+ });
34
+ }
35
+ /**
36
+ * Lazily spawn the Rust binary. Only spawns once, caches the promise.
37
+ */
38
+ async ensureSpawned() {
39
+ if (!this.spawnPromise) {
40
+ this.spawnPromise = this.bridge.spawn();
41
+ }
42
+ const ok = await this.spawnPromise;
43
+ if (!ok) {
44
+ this.spawnPromise = null;
45
+ throw new Error('Failed to spawn rustdns-client binary');
46
+ }
47
+ }
48
+ /**
49
+ * Resolve a DNS query through the Rust binary.
50
+ */
51
+ async resolve(name, recordType, protocol, serverAddr, dohUrl, timeoutMs) {
52
+ await this.ensureSpawned();
53
+ const params = {
54
+ name,
55
+ recordType,
56
+ protocol,
57
+ };
58
+ if (serverAddr)
59
+ params.serverAddr = serverAddr;
60
+ if (dohUrl)
61
+ params.dohUrl = dohUrl;
62
+ if (timeoutMs)
63
+ params.timeoutMs = timeoutMs;
64
+ return this.bridge.sendCommand('resolve', params);
65
+ }
66
+ /**
67
+ * Ping the Rust binary for health check.
68
+ */
69
+ async ping() {
70
+ await this.ensureSpawned();
71
+ const result = await this.bridge.sendCommand('ping', {});
72
+ return result.pong;
73
+ }
74
+ /**
75
+ * Kill the Rust process.
76
+ */
77
+ kill() {
78
+ this.bridge.kill();
79
+ this.spawnPromise = null;
80
+ }
81
+ /**
82
+ * Whether the bridge is running.
83
+ */
84
+ get running() {
85
+ return this.bridge.running;
86
+ }
87
+ }
88
+ /**
89
+ * Get the tsrust platform suffix for the current platform.
90
+ */
91
+ function getPlatformSuffix() {
92
+ const platform = process.platform;
93
+ const arch = process.arch;
94
+ const platformMap = {
95
+ 'linux': 'linux',
96
+ 'darwin': 'macos',
97
+ 'win32': 'windows',
98
+ };
99
+ const archMap = {
100
+ 'x64': 'amd64',
101
+ 'arm64': 'arm64',
102
+ };
103
+ const p = platformMap[platform];
104
+ const a = archMap[arch];
105
+ if (p && a) {
106
+ return `${p}_${a}`;
107
+ }
108
+ return null;
109
+ }
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ydXN0ZG5zY2xpZW50YnJpZGdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfY2xpZW50L2NsYXNzZXMucnVzdGRuc2NsaWVudGJyaWRnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQW9DeEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sbUJBQW1CO0lBSTlCO1FBRlEsaUJBQVksR0FBNEIsSUFBSSxDQUFDO1FBR25ELE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUNyQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUN2RCxJQUFJLENBQ0wsQ0FBQztRQUVGLDJFQUEyRTtRQUMzRSxNQUFNLGNBQWMsR0FBRyxpQkFBaUIsRUFBRSxDQUFDO1FBQzNDLE1BQU0sVUFBVSxHQUFhLEVBQUUsQ0FBQztRQUVoQywwRUFBMEU7UUFDMUUsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNsRyxDQUFDO1FBQ0QsMkNBQTJDO1FBQzNDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7UUFDOUUsd0JBQXdCO1FBQ3hCLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQztRQUM5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
@@ -1 +1,2 @@
1
1
  export * from './classes.dnsclient.js';
2
+ export * from './classes.rustdnsclientbridge.js';
@@ -1,2 +1,3 @@
1
1
  export * from './classes.dnsclient.js';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx3QkFBd0IsQ0FBQyJ9
2
+ export * from './classes.rustdnsclientbridge.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLGtDQUFrQyxDQUFDIn0=
@@ -2,9 +2,16 @@ import * as smartenv from '@push.rocks/smartenv';
2
2
  import type dnsType from 'dns';
3
3
  declare const dns: typeof dnsType;
4
4
  export { dns };
5
+ import * as path from 'path';
6
+ import { EventEmitter } from 'events';
7
+ export { path };
8
+ export declare const events: {
9
+ EventEmitter: typeof EventEmitter;
10
+ };
5
11
  import * as smartdelay from '@push.rocks/smartdelay';
6
12
  import * as smartpromise from '@push.rocks/smartpromise';
7
13
  import * as smartrequest from '@push.rocks/smartrequest';
8
- export { smartdelay, smartenv, smartpromise, smartrequest };
14
+ import * as smartrust from '@push.rocks/smartrust';
15
+ export { smartdelay, smartenv, smartpromise, smartrequest, smartrust };
9
16
  import * as tsclass from '@tsclass/tsclass';
10
17
  export { tsclass };
@@ -2,11 +2,17 @@ import * as smartenv from '@push.rocks/smartenv';
2
2
  const smartenvInstance = new smartenv.Smartenv();
3
3
  const dns = await smartenvInstance.getSafeNodeModule('dns');
4
4
  export { dns };
5
+ // node native scope
6
+ import * as path from 'path';
7
+ import { EventEmitter } from 'events';
8
+ export { path };
9
+ export const events = { EventEmitter };
5
10
  // pushrocks scope
6
11
  import * as smartdelay from '@push.rocks/smartdelay';
7
12
  import * as smartpromise from '@push.rocks/smartpromise';
8
13
  import * as smartrequest from '@push.rocks/smartrequest';
9
- export { smartdelay, smartenv, smartpromise, smartrequest };
14
+ import * as smartrust from '@push.rocks/smartrust';
15
+ export { smartdelay, smartenv, smartpromise, smartrequest, smartrust };
10
16
  import * as tsclass from '@tsclass/tsclass';
11
17
  export { tsclass };
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NsaWVudC9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUdqRCxNQUFNLEdBQUcsR0FBbUIsTUFBTSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUU1RSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFFZixrQkFBa0I7QUFDbEIsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFFekQsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxDQUFDO0FBRTVELE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDIn0=
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NsaWVudC9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUdqRCxNQUFNLEdBQUcsR0FBbUIsTUFBTSxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUU1RSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFFZixvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUV0QyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDaEIsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLEVBQUUsWUFBWSxFQUFFLENBQUM7QUFFdkMsa0JBQWtCO0FBQ2xCLE9BQU8sS0FBSyxVQUFVLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFFbkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQztBQUV2RSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyJ9