From 00ab3a3d2af9644a2fa8548d064de08fd71e3b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Thu, 15 Jun 2017 16:05:04 +0200 Subject: [PATCH] sip.js: fix importing as a module (#16811) * sip.js: fix conflicts with importing the SIPjs library. - the 'sipjs' namespace is now linked to the 'sip.js' module import - the old 'SIP' interface has been merged into the type definition in the 'sipjs' namespace so typing can be used naturally. Tested successfully with typescript 2.3.3 and sip.js 0.7.7 * sip.js: fix SIP.C namespace It was exposed as a class but it is actually a namespace containing constants. This was causing build errors. Also, the namespace name was wrong. * sip.js: remove the wrapper sipjs namespace and export things instead Following the suggestion of @andy-ms, this commits removes the wrapper namespace and the `declare module` block, and instead just exports all the things individually. --- types/sip.js/index.d.ts | 616 +++++++++++++++++------------------ types/sip.js/sip.js-tests.ts | 24 +- 2 files changed, 317 insertions(+), 323 deletions(-) diff --git a/types/sip.js/index.d.ts b/types/sip.js/index.d.ts index 4cb973ad10..2e3394386f 100644 --- a/types/sip.js/index.d.ts +++ b/types/sip.js/index.d.ts @@ -3,331 +3,325 @@ // Definitions by: Kir Dergachev // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -interface SIP { - UA: { - new (configuration?: sipjs.ConfigurationParameters): sipjs.UA; - }; - URI: { - new (scheme?: string, user?: string, host?: string, port?: number, parameters?: string[], headers?: string[]): sipjs.URI; - parse(uri: string): sipjs.URI; - }; - NameAddrHeader: { - new (uri: string | sipjs.URI, displayName: string, parameters: Array<{ key: string, value: string }>): sipjs.NameAddrHeader; - parse(name_addr_header: string): sipjs.NameAddrHeader; - }; +export as namespace sipjs; + +export class URI { + scheme?: string; + user?: string; + host?: string; + port?: number; + + constructor(scheme?: string, user?: string, host?: string, port?: number, parameters?: string[], headers?: string[]); + static parse(uri: string): sipjs.URI; + + setParam(key: string, value?: string): void; + getParam(key: string): string; + hasParam(key: string): string; + deleteParam(key: string): string; + clearParams(): void; + setHeader(name: string, value: string): void; + getHeader(name: string): string[]; + hasHeader(name: string): boolean; + deleteHeader(name: string): string[]; + clearHeaders(): void; + clone(): URI; + toString(): string; } -declare namespace sipjs { - interface URI { - scheme?: string; - user?: string; - host?: string; - port?: number; +export namespace UA.EventArgs { + interface ConnectedArgs { attempts: number; } + interface UnregisteredArgs { response: string; cause: string; } + interface RegistrationFailedArgs extends UnregisteredArgs { } +} - setParam(key: string, value?: string): void; - getParam(key: string): string; - hasParam(key: string): string; - deleteParam(key: string): string; - clearParams(): void; - setHeader(name: string, value: string): void; - getHeader(name: string): string[]; - hasHeader(name: string): boolean; - deleteHeader(name: string): string[]; - clearHeaders(): void; - clone(): URI; - toString(): string; +export class UA { + constructor(configuration?: sipjs.ConfigurationParameters); + + start(): void; + stop(): void; + register(options?: ExtraHeadersOptions): UA; + unregister(options?: UnregisterOptions): void; + isRegistered(): boolean; + isConnected(): boolean; + message(target: string | URI, body: string, options?: MessageOptions): Message; + subscribe(target: string | URI, event: string, options?: SubscribeOptions): Subscription; + invite(target: string | URI, element?: InviteOptions | HTMLAudioElement | HTMLVideoElement): Session; + request(method: string, target: string | URI, options?: RequestOptions): ClientContext; + + on(name: 'connected', callback: (args: UA.EventArgs.ConnectedArgs) => void): void; + on(name: 'disconnected' | 'registered' | string, callback: () => void): void; + on(name: 'unregistered', callback: (args: UA.EventArgs.UnregisteredArgs) => void): void; + on(name: 'registrationFailed', callback: (args: UA.EventArgs.RegistrationFailedArgs) => void): void; + on(name: 'invite', callback: (session: Session) => void): void; + on(name: 'message', callback: (message: Message) => void): void; +} + +export namespace C { + namespace supported { + const REQUIRED: string; + const SUPPORTED: string; + const UNSUPPORTED: string; } - namespace UA.EventArgs { - interface ConnectedArgs { attempts: number; } - interface UnregisteredArgs { response: string; cause: string; } - interface RegistrationFailedArgs extends UnregisteredArgs { } + namespace causes { + const INVALID_TARGET: string; + const CONNECTION_ERROR: string; + const REQUEST_TIMEOUT: string; + const SIP_FAILURE_CODE: string; + } +} + +export interface Session { + startTime?: Date; + endTime?: Date; + ua?: UA; + method?: string; + mediaHandler?: WebRTC.MediaHandler; + request?: IncomingRequest | OutgoingRequest; + localIdentity?: NameAddrHeader; + remoteIdentity?: NameAddrHeader; + data: ClientContext | ServerContext; + + dtmf(tone: string | number, options?: Session.DtmfOptions): Session; + terminate(options?: Session.CommonOptions): Session; + bye(options?: Session.CommonOptions): Session; + getLocalStreams(): any[]; + getRemoteStreams(): any[]; + refer(target: string | Session, options?: ExtraHeadersOptions): Session; + mute(options?: ExtraHeadersOptions): void; + unmute(options?: ExtraHeadersOptions): void; + cancel(options?: Session.CommonOptions): void; + progress(options?: Session.ProgressOptions): void; + accept(options?: Session.AcceptOptions): void; + reject(options?: Session.CommonOptions): void; + reply(options?: Session.CommonOptions): void; + followRefer(callback: () => void): void; + + on(name: 'progress', callback: (response: IncomingResponse) => void): void; + on(name: 'accepted', callback: (data: { code: number, response: IncomingResponse }) => void): void; + on(name: 'failed' | 'rejected', callback: (response: IncomingResponse, cause: string) => void): void; + on(name: 'terminated', callback: (message: IncomingResponse, cause: string) => void): void; + on(name: 'cancel' | string, callback: () => void): void; + on(name: 'replaced', callback: (newSession: Session) => void): void; + on(name: 'dtmf', callback: (request: IncomingRequest, dtmf: Session.DTMF) => void): void; + on(name: 'muted' | 'unmuted', callback: (data: Session.Muted) => void): void; + on(name: 'refer' | 'bye', callback: (request: IncomingRequest) => void): void; +} + +export namespace Session { + interface DtmfOptions extends ExtraHeadersOptions { + duration?: number; + interToneGap?: number; } - interface UA { - start(): void; - stop(): void; - register(options?: ExtraHeadersOptions): UA; - unregister(options?: UnregisterOptions): void; - isRegistered(): boolean; - isConnected(): boolean; - message(target: string | URI, body: string, options?: MessageOptions): Message; - subscribe(target: string | URI, event: string, options?: SubscribeOptions): Subscription; - invite(target: string | URI, element?: InviteOptions | HTMLAudioElement | HTMLVideoElement): Session; - request(method: string, target: string | URI, options?: RequestOptions): ClientContext; - - on(name: 'connected', callback: (args: UA.EventArgs.ConnectedArgs) => void): void; - on(name: 'disconnected' | 'registered' | string, callback: () => void): void; - on(name: 'unregistered', callback: (args: UA.EventArgs.UnregisteredArgs) => void): void; - on(name: 'registrationFailed', callback: (args: UA.EventArgs.RegistrationFailedArgs) => void): void; - on(name: 'invite', callback: (session: Session) => void): void; - on(name: 'message', callback: (message: Message) => void): void; - } - - namespace UA.C { - class supported { - REQUIRED: string; - SUPPORTED: string; - UNSUPPORTED: string; - } - - class causes { - INVALID_TARGET: string; - CONNECTION_ERROR: string; - REQUEST_TIMEOUT: string; - SIP_FAILURE_CODE: string; - } - } - - interface Session { - startTime?: Date; - endTime?: Date; - ua?: UA; - method?: string; - mediaHandler?: WebRTC.MediaHandler; - request?: IncomingRequest | OutgoingRequest; - localIdentity?: NameAddrHeader; - remoteIdentity?: NameAddrHeader; - data: ClientContext | ServerContext; - - dtmf(tone: string | number, options?: Session.DtmfOptions): Session; - terminate(options?: Session.CommonOptions): Session; - bye(options?: Session.CommonOptions): Session; - getLocalStreams(): any[]; - getRemoteStreams(): any[]; - refer(target: string | Session, options?: ExtraHeadersOptions): Session; - mute(options?: ExtraHeadersOptions): void; - unmute(options?: ExtraHeadersOptions): void; - cancel(options?: Session.CommonOptions): void; - progress(options?: Session.ProgressOptions): void; - accept(options?: Session.AcceptOptions): void; - reject(options?: Session.CommonOptions): void; - reply(options?: Session.CommonOptions): void; - followRefer(callback: () => void): void; - - on(name: 'progress', callback: (response: IncomingResponse) => void): void; - on(name: 'accepted', callback: (data: { code: number, response: IncomingResponse }) => void): void; - on(name: 'failed' | 'rejected', callback: (response: IncomingResponse, cause: string) => void): void; - on(name: 'terminated', callback: (message: IncomingResponse, cause: string) => void): void; - on(name: 'cancel' | string, callback: () => void): void; - on(name: 'replaced', callback: (newSession: Session) => void): void; - on(name: 'dtmf', callback: (request: IncomingRequest, dtmf: Session.DTMF) => void): void; - on(name: 'muted' | 'unmuted', callback: (data: Session.Muted) => void): void; - on(name: 'refer' | 'bye', callback: (request: IncomingRequest) => void): void; - } - - namespace Session { - interface DtmfOptions extends ExtraHeadersOptions { - duration?: number; - interToneGap?: number; - } - - interface CommonOptions extends ExtraHeadersOptions { - status_code?: number; - reason_phrase?: string; - body?: string; - } - - interface ProgressOptions extends ExtraHeadersOptions { - rel100?: boolean; - media?: MediaConstraints; - } - - interface AcceptOptions { - RTCConstraints?: any; - media?: MediaOptions; - } - - interface DTMF extends Object {} - - interface Muted { - audio?: boolean; - video?: boolean; - } - } - - interface RenderHint { - remote?: Element; - local?: Element; - } - - interface MediaConstraints { - audio: boolean; - video: boolean; - } - - interface TurnServer { - urls?: string | string[]; - username?: string; - password?: string; - } - - namespace WebRTC { - interface Options { - stunServers?: string | string[]; - turnServers?: TurnServer | TurnServer[]; - RTCConstraints?: any; - } - - type MediaHandlerFactory = (session: Session, options: Options) => MediaHandler; - - class MediaHandler { - getLocalStreams(): any[]; - getRemoteStreams(): any[]; - render(renderHint: RenderHint): void; - - on(name: 'userMediaRequest', callback: (constraints: MediaConstraints) => void): void; - on(name: 'addStream' | 'userMedia', callback: (stream: any) => void): void; - on(name: 'userMediaFailed', callback: (error: string) => void): void; - on(name: 'iceCandidate', callback: (candidate: any) => void): void; - on( - name: 'iceGathering' | 'iceGatheringComplete' | 'iceConnection' | 'iceConnectionChecking' | 'iceConnectionConnected' | 'iceConnectionCompleted' | 'iceConnectionFailed' | - 'iceConnectionDisconnected' | 'iceConnectionClosed' | string, - callback: () => void): void; - on(name: 'dataChannel' | 'getDescription' | 'setDescription', callback: (sdpWrapper: { type: string, sdp: string }) => void): void; - } - } - - /* Parameters */ - interface ConfigurationParameters { - uri?: string; - wsServers?: string | string[] | Array<{ ws_uri: string; weigth: number }>; - allowLegacyNotifications?: boolean; - authenticationFactory?: WebRTC.MediaHandlerFactory; - authorizationUser?: string; - autostart?: boolean; - connectionRecoveryMaxInterval?: number; - connectionRecoveryMinInterval?: number; - displayName?: string; - hackCleanJitsiSdpImageattr?: boolean; - hackStripTcp?: boolean; - hackIpInContact?: boolean; - hackViaTcp?: boolean; - hackWssInTransport?: boolean; - iceCheckingTimeout?: number; - instanceId?: string; - log?: { - builtinEnabled?: boolean; - level?: number | string; - connector?(level: string, category: string, label: string, content: string): void; - }; - mediaHandlerFactory?: WebRTC.MediaHandlerFactory; - noAnswerTimeout?: number; - password?: string; - register?: boolean; - registerExpires?: number; - registrarServer?: string; - rel100?: string; - replaces?: string; - stunServers?: string | string[]; - traceSip?: boolean; - turnServers?: TurnServer | TurnServer[]; - usePreloadedRoute?: boolean; - userAgentString?: string; - wsServerMaxReconnection?: number; - wsServerReconnectionTimeout?: number; - } - - /* Options */ - interface ExtraHeadersOptions { - extraHeaders?: string[]; - } - - interface UnregisterOptions extends ExtraHeadersOptions { - all?: boolean; - } - - interface MessageOptions extends ExtraHeadersOptions { - contentType?: string; - } - - interface SubscribeOptions extends ExtraHeadersOptions { - expires?: number; - } - - interface MediaOptions { - constraints?: MediaConstraints; - stream?: any; - render?: RenderHint; - } - - interface InviteOptions extends ExtraHeadersOptions { - media?: MediaOptions; - anonymous?: boolean; - rel100?: string; - inviteWithoutSdp?: boolean; - RTCConstraints?: any; - } - - interface RequestOptions extends ExtraHeadersOptions { + interface CommonOptions extends ExtraHeadersOptions { + status_code?: number; + reason_phrase?: string; body?: string; } - /* Contexts */ - interface Message extends ClientContext { - body: string; + interface ProgressOptions extends ExtraHeadersOptions { + rel100?: boolean; + media?: MediaConstraints; } - interface Subscription extends ClientContext { - id: string; - state: string; - event: string; - dialog: string; - timers: {}; - errorCodes: number[]; - subscribe(): Subscription; - unsubscribe(): void; - close(): void; + interface AcceptOptions { + RTCConstraints?: any; + media?: MediaOptions; } - /* Context */ - interface Context { - ua: UA; - method: string; - request: OutgoingRequest; - localIdentity: NameAddrHeader; - remoteIdentity: NameAddrHeader; - data: {}; - on(name: 'progress' | 'accepted' | 'rejected' | 'failed', callback: (response: IncomingMessage, cause: string) => void): void; - on(name: 'notify', callback: (request: IncomingRequest) => void): void; - on(name: string, callback: () => void): void; - } + interface DTMF extends Object {} - interface ClientContext extends Context { - cancel(options?: { status_code?: number, reason_phrase?: string }): ClientContext; - } - - interface ServerContext extends Context { - progress(options?: Session.ProgressOptions): void; - accept(options?: Session.AcceptOptions): void; - reject(options?: Session.CommonOptions): void; - reply(options?: Session.CommonOptions): void; - } - - /* Request */ - interface Request extends Context { - } - - interface IncomingRequest extends Request { - } - - interface OutgoingRequest extends Request { - } - - interface IncomingResponse extends Request { - } - - interface IncomingMessage extends Request { - } - - /* Header */ - interface NameAddrHeader { - uri: string | URI; - displayName: string; - - setParam(key: string, value?: string): void; - getParam(key: string): string; - deleteParam(key: string): string; - clearParams(): void; + interface Muted { + audio?: boolean; + video?: boolean; } } + +export interface RenderHint { + remote?: Element; + local?: Element; +} + +export interface MediaConstraints { + audio: boolean; + video: boolean; +} + +export interface TurnServer { + urls?: string | string[]; + username?: string; + password?: string; +} + +export namespace WebRTC { + interface Options { + stunServers?: string | string[]; + turnServers?: TurnServer | TurnServer[]; + RTCConstraints?: any; + } + + type MediaHandlerFactory = (session: Session, options: Options) => MediaHandler; + + class MediaHandler { + getLocalStreams(): any[]; + getRemoteStreams(): any[]; + render(renderHint: RenderHint): void; + + on(name: 'userMediaRequest', callback: (constraints: MediaConstraints) => void): void; + on(name: 'addStream' | 'userMedia', callback: (stream: any) => void): void; + on(name: 'userMediaFailed', callback: (error: string) => void): void; + on(name: 'iceCandidate', callback: (candidate: any) => void): void; + on( + name: 'iceGathering' | 'iceGatheringComplete' | 'iceConnection' | 'iceConnectionChecking' | 'iceConnectionConnected' | 'iceConnectionCompleted' | 'iceConnectionFailed' | + 'iceConnectionDisconnected' | 'iceConnectionClosed' | string, + callback: () => void): void; + on(name: 'dataChannel' | 'getDescription' | 'setDescription', callback: (sdpWrapper: { type: string, sdp: string }) => void): void; + } +} + +/* Parameters */ +export interface ConfigurationParameters { + uri?: string; + wsServers?: string | string[] | Array<{ ws_uri: string; weigth: number }>; + allowLegacyNotifications?: boolean; + authenticationFactory?: WebRTC.MediaHandlerFactory; + authorizationUser?: string; + autostart?: boolean; + connectionRecoveryMaxInterval?: number; + connectionRecoveryMinInterval?: number; + displayName?: string; + hackCleanJitsiSdpImageattr?: boolean; + hackStripTcp?: boolean; + hackIpInContact?: boolean; + hackViaTcp?: boolean; + hackWssInTransport?: boolean; + iceCheckingTimeout?: number; + instanceId?: string; + log?: { + builtinEnabled?: boolean; + level?: number | string; + connector?(level: string, category: string, label: string, content: string): void; + }; + mediaHandlerFactory?: WebRTC.MediaHandlerFactory; + noAnswerTimeout?: number; + password?: string; + register?: boolean; + registerExpires?: number; + registrarServer?: string; + rel100?: string; + replaces?: string; + stunServers?: string | string[]; + traceSip?: boolean; + turnServers?: TurnServer | TurnServer[]; + usePreloadedRoute?: boolean; + userAgentString?: string; + wsServerMaxReconnection?: number; + wsServerReconnectionTimeout?: number; +} + +/* Options */ +export interface ExtraHeadersOptions { + extraHeaders?: string[]; +} + +export interface UnregisterOptions extends ExtraHeadersOptions { + all?: boolean; +} + +export interface MessageOptions extends ExtraHeadersOptions { + contentType?: string; +} + +export interface SubscribeOptions extends ExtraHeadersOptions { + expires?: number; +} + +export interface MediaOptions { + constraints?: MediaConstraints; + stream?: any; + render?: RenderHint; +} + +export interface InviteOptions extends ExtraHeadersOptions { + media?: MediaOptions; + anonymous?: boolean; + rel100?: string; + inviteWithoutSdp?: boolean; + RTCConstraints?: any; +} + +export interface RequestOptions extends ExtraHeadersOptions { + body?: string; +} + +/* Contexts */ +export interface Message extends ClientContext { + body: string; +} + +export interface Subscription extends ClientContext { + id: string; + state: string; + event: string; + dialog: string; + timers: {}; + errorCodes: number[]; + subscribe(): Subscription; + unsubscribe(): void; + close(): void; +} + +/* Context */ +export interface Context { + ua: UA; + method: string; + request: OutgoingRequest; + localIdentity: NameAddrHeader; + remoteIdentity: NameAddrHeader; + data: {}; + on(name: 'progress' | 'accepted' | 'rejected' | 'failed', callback: (response: IncomingMessage, cause: string) => void): void; + on(name: 'notify', callback: (request: IncomingRequest) => void): void; + on(name: string, callback: () => void): void; +} + +export interface ClientContext extends Context { + cancel(options?: { status_code?: number, reason_phrase?: string }): ClientContext; +} + +export interface ServerContext extends Context { + progress(options?: Session.ProgressOptions): void; + accept(options?: Session.AcceptOptions): void; + reject(options?: Session.CommonOptions): void; + reply(options?: Session.CommonOptions): void; +} + +/* Request */ +export interface Request extends Context { +} + +export interface IncomingRequest extends Request { +} + +export interface OutgoingRequest extends Request { +} + +export interface IncomingResponse extends Request { +} + +export interface IncomingMessage extends Request { +} + +/* Header */ +export class NameAddrHeader { + uri: string | URI; + displayName: string; + + constructor(uri: string | sipjs.URI, displayName: string, parameters: Array<{ key: string, value: string }>); + static parse(name_addr_header: string): sipjs.NameAddrHeader; + + setParam(key: string, value?: string): void; + getParam(key: string): string; + deleteParam(key: string): string; + clearParams(): void; +} diff --git a/types/sip.js/sip.js-tests.ts b/types/sip.js/sip.js-tests.ts index 23b2578194..44f61fea25 100644 --- a/types/sip.js/sip.js-tests.ts +++ b/types/sip.js/sip.js-tests.ts @@ -1,11 +1,11 @@ -declare var sip: SIP; +import * as SIP from 'sip.js'; -let ua: sipjs.UA = new sip.UA(); +let ua: SIP.UA = new SIP.UA(); -const mediaHandler = (session: sipjs.Session, options: sipjs.WebRTC.Options) => new sipjs.WebRTC.MediaHandler(); +const mediaHandler = (session: SIP.Session, options: SIP.WebRTC.Options) => new SIP.WebRTC.MediaHandler(); const logConnector = (level: string, category: string, label: string, content: string) => null; -const uaWithConfig: sipjs.UA = new sip.UA({ +const uaWithConfig: SIP.UA = new SIP.UA({ uri: "wss://uri", wsServers: ["s1", "s2"], allowLegacyNotifications: true, @@ -61,14 +61,14 @@ ua.unregister({ extraHeaders: [""], all: true }); const isConnected: boolean = ua.isConnected(); const isRegistered: boolean = ua.isRegistered(); -const message: sipjs.Message = ua.message("", "", { contentType: "" }); +const message: SIP.Message = ua.message("", "", { contentType: "" }); ua.subscribe("", "", { expires: 1, extraHeaders: [""] }); -const subscription: sipjs.Subscription = ua.subscribe(new sip.URI(), "", { expires: 1, extraHeaders: [""] }); +const subscription: SIP.Subscription = ua.subscribe(new SIP.URI(), "", { expires: 1, extraHeaders: [""] }); let session = ua.invite("", new HTMLVideoElement()); -const inviteOptions: sipjs.InviteOptions = { +const inviteOptions: SIP.InviteOptions = { media: { constraints: { audio: true, video: false }, stream: new MediaStream(), @@ -82,14 +82,14 @@ const inviteOptions: sipjs.InviteOptions = { session = ua.invite("", inviteOptions); -ua.on('connected', (args: sipjs.UA.EventArgs.ConnectedArgs) => { }); +ua.on('connected', (args: SIP.UA.EventArgs.ConnectedArgs) => { }); ua.on('disconnected', () => { }); ua.on('registered', () => { }); -ua.on('unregistered', (args: sipjs.UA.EventArgs.UnregisteredArgs) => { }); -ua.on('registrationFailed', (args: sipjs.UA.EventArgs.RegistrationFailedArgs) => { }); -ua.on('invite', (session: sipjs.Session) => { +ua.on('unregistered', (args: SIP.UA.EventArgs.UnregisteredArgs) => { }); +ua.on('registrationFailed', (args: SIP.UA.EventArgs.RegistrationFailedArgs) => { }); +ua.on('invite', (session: SIP.Session) => { session.on('progress', (response) => {}); session.on('accepted', (response) => {}); session.on('rejected', (response) => {}); }); -ua.on('message', (message: sipjs.Message) => { }); +ua.on('message', (message: SIP.Message) => { });