mirror of
https://github.com/FlipsideCrypto/DefinitelyTyped.git
synced 2026-02-06 10:56:53 +00:00
New definitions for nat-upnp (#47551)
* Add nat-upnp typings * Fixed index.d.ts header * Removed accidental docstring meant to be source comment * Apply suggestions from code review Co-authored-by: Piotr Błażejewicz (Peter Blazejewicz) <peterblazejewicz@users.noreply.github.com> * Add test cases for nat-upnp optional callbacks missing * Fix linter errors Co-authored-by: Piotr Błażejewicz (Peter Blazejewicz) <peterblazejewicz@users.noreply.github.com>
This commit is contained in:
parent
f03fd4b231
commit
35d8a9f149
230
types/nat-upnp/index.d.ts
vendored
Normal file
230
types/nat-upnp/index.d.ts
vendored
Normal file
@ -0,0 +1,230 @@
|
||||
// Type definitions for nat-upnp 1.1
|
||||
// Project: https://github.com/indutny/node-nat-upnp
|
||||
// Definitions by: SimplyLinn <https://github.com/SimplyLinn>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
/// <reference types="node" />
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
/**
|
||||
* Standard options that many options use.
|
||||
*/
|
||||
export interface StandardOpts {
|
||||
public?:
|
||||
| number
|
||||
| null
|
||||
| {
|
||||
port?: number;
|
||||
host?: string;
|
||||
};
|
||||
private?:
|
||||
| number
|
||||
| null
|
||||
| {
|
||||
port?: number;
|
||||
host?: string;
|
||||
};
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw SSDP/UPNP repsonse
|
||||
* Entire SSDP/UPNP schema is beyond the scope of these typings.
|
||||
* Please look up the protol documentation if you wanna do
|
||||
* lower level communication.
|
||||
*/
|
||||
export type RawResponse = Partial<
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
'@': { 'xmlns:u': string };
|
||||
[key: string]: unknown;
|
||||
}
|
||||
>
|
||||
>;
|
||||
|
||||
/**
|
||||
* Callback with a generic as result type
|
||||
*/
|
||||
export type CB<T> = (err: Error | null, res?: T) => void;
|
||||
|
||||
export interface RawService {
|
||||
serviceType: string;
|
||||
serviceId: string;
|
||||
controlURL?: string;
|
||||
eventSubURL?: string;
|
||||
SCPDURL?: string;
|
||||
}
|
||||
|
||||
export interface RawDevice {
|
||||
deviceType: string;
|
||||
presentationURL: string;
|
||||
friendlyName: string;
|
||||
manufacturer: string;
|
||||
manufacturerURL: string;
|
||||
modelDescription: string;
|
||||
modelName: string;
|
||||
modelNumber: string;
|
||||
modelURL: string;
|
||||
serialNumber: string;
|
||||
UDN: string;
|
||||
UPC: string;
|
||||
serviceList?: { service: RawService | RawService[] };
|
||||
deviceList?: { device: RawDevice | RawDevice[] };
|
||||
}
|
||||
|
||||
export interface Device {
|
||||
/**
|
||||
* Get the available services on the network device
|
||||
* @param types List of service types to lookf or
|
||||
* @param callback
|
||||
*/
|
||||
getService(
|
||||
types: string[],
|
||||
callback: CB<{
|
||||
service: string;
|
||||
SCPDURL: string;
|
||||
controlURL: string;
|
||||
}>,
|
||||
): void;
|
||||
/**
|
||||
* Parse out available services
|
||||
* and devices from a root device
|
||||
* @param info
|
||||
* @returns the available devices and services in array form
|
||||
*/
|
||||
parseDescription(info: {
|
||||
device?: RawDevice;
|
||||
}): {
|
||||
services: RawService[];
|
||||
devices: RawDevice[];
|
||||
};
|
||||
/**
|
||||
* Perform a SSDP/UPNP request
|
||||
* @param action the action to perform
|
||||
* @param args arguments of said action
|
||||
* @param callback Callback to be run when completed, or on error
|
||||
*/
|
||||
run(action: string, args: string[], callback: CB<RawResponse>): void;
|
||||
}
|
||||
|
||||
// Note for the SSDP class/interface
|
||||
// The implementation leads me to believe that
|
||||
// createSockets()
|
||||
// createSocket(interface)
|
||||
// parseResponse(response, addr)
|
||||
// are all private methods.
|
||||
// and have thusly not been typed in the interface
|
||||
|
||||
export interface Ssdp extends EventEmitter {
|
||||
/**
|
||||
* Search for a SSDP compatible server on the network
|
||||
* @param device Search Type (ST) header, specifying which device to search for
|
||||
* @param promise An existing EventEmitter to emit event on
|
||||
* @returns The event emitter provided in Promise, or a newly instantiated one.
|
||||
*/
|
||||
search(device: string, promise?: EventEmitter): EventEmitter;
|
||||
/**
|
||||
* Close all sockets
|
||||
*/
|
||||
close(): void;
|
||||
}
|
||||
|
||||
//
|
||||
// Types for client.
|
||||
//
|
||||
export interface NewPortMappingOpts extends StandardOpts {
|
||||
description?: string;
|
||||
ttl?: number;
|
||||
}
|
||||
export type DeletePortMappingOpts = StandardOpts;
|
||||
export interface GetMappingOpts {
|
||||
local?: boolean;
|
||||
description?: RegExp | string;
|
||||
}
|
||||
export interface Mapping {
|
||||
public: { host: string; port: number };
|
||||
private: { host: string; port: number };
|
||||
protocol: string;
|
||||
enabled: boolean;
|
||||
description: string;
|
||||
ttl: number;
|
||||
local: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main client interface.
|
||||
*/
|
||||
export interface Client {
|
||||
/**
|
||||
* Create a new port mapping
|
||||
* @param options Options for the new port mapping
|
||||
* @param [callback] Callback to be run when completed, or on error
|
||||
*/
|
||||
portMapping(options: NewPortMappingOpts, callback?: CB<RawResponse>): void;
|
||||
/**
|
||||
* Remove a port mapping
|
||||
* @param options Specify which port mapping to remove
|
||||
* @param [callback] Callback to be run when completed, or on error
|
||||
*/
|
||||
portUnmapping(options: DeletePortMappingOpts, callback?: CB<RawResponse>): void;
|
||||
/**
|
||||
* Get a list of existing mappings
|
||||
* @param callback Callback to be run when completed, or on error
|
||||
*/
|
||||
getMappings(callback: CB<Mapping[]>): void;
|
||||
/**
|
||||
* Get a list of existing mappings
|
||||
* @param options Filter mappings based on these options
|
||||
* @param callback Callback to be run when completed, or on error
|
||||
*/
|
||||
getMappings(options: GetMappingOpts, callback: CB<Mapping[]>): void;
|
||||
/**
|
||||
* Fetch the external IP from the gateway
|
||||
* @param callback Callback to be run when completed, or on error
|
||||
*/
|
||||
externalIp(callback: CB<string>): void;
|
||||
/**
|
||||
* Get the gateway device for communication
|
||||
* @param callback
|
||||
*/
|
||||
findGateway(callback: CB<Device>): void;
|
||||
/**
|
||||
* Close the underlaying sockets and resources
|
||||
*/
|
||||
close(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NAT-UPNP client
|
||||
*/
|
||||
export function createClient(): Client;
|
||||
|
||||
/**
|
||||
* The other creator functions are exported as
|
||||
* an object with the create function as a property.
|
||||
*/
|
||||
export const device: {
|
||||
/**
|
||||
* Create a gateway device object with the specified url
|
||||
* @param url
|
||||
*/
|
||||
create(url: string): Device;
|
||||
};
|
||||
export const ssdp: {
|
||||
/**
|
||||
* Create a Simple Service Discovery Protocol client
|
||||
*/
|
||||
create(): Ssdp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Exported utility function.
|
||||
*/
|
||||
export const utils: {
|
||||
getNamespace(
|
||||
data: {
|
||||
'@'?: Record<string, string>;
|
||||
},
|
||||
uri: string,
|
||||
): string;
|
||||
};
|
||||
131
types/nat-upnp/nat-upnp-tests.ts
Normal file
131
types/nat-upnp/nat-upnp-tests.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { ssdp, device, utils, createClient } from 'nat-upnp';
|
||||
|
||||
const ssdpClient = ssdp.create();
|
||||
const promiseEventEmitter = ssdpClient.search('urn:schemas-upnp-org:device:InternetGatewayDevice:1');
|
||||
promiseEventEmitter.on('device', res => {
|
||||
console.log('onDevice', res);
|
||||
});
|
||||
setTimeout(() => ssdpClient.close(), 100);
|
||||
|
||||
utils.getNamespace(
|
||||
{
|
||||
'@': {
|
||||
'xmlns:u': 'urn:schemas-upnp-org:service:WANIPConnection:1',
|
||||
},
|
||||
},
|
||||
'urn:schemas-upnp-org:service:WANIPConnection:1',
|
||||
);
|
||||
|
||||
const Device = device.create('');
|
||||
console.log(Device);
|
||||
const NATClient = createClient();
|
||||
NATClient.findGateway((err, gatewayDevice) => {
|
||||
if (err || gatewayDevice == null) {
|
||||
console.error(
|
||||
'NATClient.findGateway',
|
||||
err || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
gatewayDevice.getService(['test'], (err2, service) => {
|
||||
if (err2 || service == null) {
|
||||
console.error(
|
||||
'gatewayDevice.getService',
|
||||
err2 || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(service.service, service.SCPDURL, service.controlURL);
|
||||
});
|
||||
gatewayDevice.run('action', ['arg'], (err2, res) => {
|
||||
if (err2 || res == null) {
|
||||
console.error(
|
||||
'gatewayDevice.run',
|
||||
err2 || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(res);
|
||||
});
|
||||
});
|
||||
|
||||
NATClient.externalIp((err, ip) => {
|
||||
if (err || ip == null) {
|
||||
console.error(
|
||||
'NATClient.externalIp',
|
||||
err || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(ip);
|
||||
});
|
||||
|
||||
NATClient.getMappings((err, mappings) => {
|
||||
if (err || mappings == null) {
|
||||
console.error(
|
||||
'NATClient.getMappings(cb)',
|
||||
err || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(mappings.map(m => m));
|
||||
});
|
||||
|
||||
NATClient.getMappings({ local: true, description: /test/ }, (err, mappings) => {
|
||||
if (err || mappings == null) {
|
||||
console.error(
|
||||
'NATClient.getMappings(opts, cb)',
|
||||
err || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(mappings.map(m => m));
|
||||
});
|
||||
|
||||
NATClient.portMapping({
|
||||
public: 9998,
|
||||
private: 2221,
|
||||
description: 'nat-upnp-test 1',
|
||||
});
|
||||
|
||||
NATClient.portUnmapping({
|
||||
public: 9998,
|
||||
private: 2221,
|
||||
});
|
||||
|
||||
NATClient.portMapping(
|
||||
{
|
||||
public: 9999,
|
||||
private: 2222,
|
||||
description: 'nat-upnp-test 2',
|
||||
},
|
||||
(err, res) => {
|
||||
if (err || res == null) {
|
||||
console.error(
|
||||
'NATClient.portMapping',
|
||||
err || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(res);
|
||||
},
|
||||
);
|
||||
|
||||
NATClient.portUnmapping(
|
||||
{
|
||||
public: 9999,
|
||||
private: 2222,
|
||||
},
|
||||
(err, res) => {
|
||||
if (err || res == null) {
|
||||
console.error(
|
||||
'NATClient.portUnmapping',
|
||||
err || new Error('Invalid callback data, neither error, nor response provided'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(res);
|
||||
},
|
||||
);
|
||||
|
||||
setTimeout(() => NATClient.close(), 1000);
|
||||
23
types/nat-upnp/tsconfig.json
Normal file
23
types/nat-upnp/tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"nat-upnp-tests.ts"
|
||||
]
|
||||
}
|
||||
1
types/nat-upnp/tslint.json
Normal file
1
types/nat-upnp/tslint.json
Normal file
@ -0,0 +1 @@
|
||||
{ "extends": "dtslint/dt.json" }
|
||||
Loading…
Reference in New Issue
Block a user