From 34026b93c0468e1428770d964bae94e56c1eee8c Mon Sep 17 00:00:00 2001 From: Kiyotoshi Ichikawa Date: Thu, 5 Apr 2018 13:03:08 -0400 Subject: [PATCH 1/3] [browser-sync] Type definition for Option type is missing many valid properties. Also appending tests to cover newly added properties/interfaces. --- types/browser-sync/browser-sync-tests.ts | 276 +++++++++++++++++++++-- types/browser-sync/index.d.ts | 147 +++++++++--- 2 files changed, 379 insertions(+), 44 deletions(-) diff --git a/types/browser-sync/browser-sync-tests.ts b/types/browser-sync/browser-sync-tests.ts index bcd829367a..613f8aee25 100644 --- a/types/browser-sync/browser-sync-tests.ts +++ b/types/browser-sync/browser-sync-tests.ts @@ -8,11 +8,98 @@ import browserSync = require("browser-sync"); })(); browserSync({ - server: { - baseDir: "./" + ui: true +}); + +browserSync({ + ui: { + port: 9000, + weinre: { + port: 9001 + } } }); +browserSync({ + files: "app/css/style.css" +}); + +browserSync({ + files: [ + "app/css/style.css", + "app/js/*.js" + ] +}); + +browserSync({ + files: [ + "app/css/style.css", + "!app/js/*.js" + ] +}); + +browserSync({ + files: [ + "wp-content/themes/**/*.css", + { + match: ["wp-content/themes/**/*.css"], + fn: function (event, file) { + /** Custom event handler **/ + } + } + ] +}); + +browserSync({ + watchEvents: [ + "change", + "add", + "unlink", + "addDir", + "unlinkDir" + ] +}); + +browserSync({ + watch: true +}); + +browserSync({ + ignore: [ + "app/js/*.js" + ] +}); + +browserSync({ + single: true +}); + +browserSync({ + watchOptions: { + ignoreInitial: true, + ignored: '*.txt' + }, + files: ['./app'] +}); + +browserSync({ + files: [ + { + match: ["wp-content/themes/**/*.php"], + fn: function (event, file) { + /** Custom event handler **/ + }, + options: { + ignored: '*.txt' + } + } + ] +}); + +browserSync({ + server: "app" +}); + // multiple base directory browserSync({ server: { @@ -20,6 +107,39 @@ browserSync({ } }); +browserSync({ + server: true +}); + +browserSync({ + server: { + baseDir: "./" + } +}); + +browserSync({ + server: { + baseDir: "./", + index: "index.htm" + } +}); + +browserSync({ + server: { + baseDir: "./", + directory: true + } +}); + +browserSync({ + server: { + baseDir: "app", + serveStaticOptions: { + extensions: ["html"] + } + } +}); + browserSync({ proxy: "yourlocal.dev" }); @@ -27,8 +147,8 @@ browserSync({ browserSync({ proxy: { target: "http://yourlocal.dev", - proxyReq: function(proxyReq) { - console.log(proxyReq); + proxyReq: function (proxyReq) { + console.log(proxyReq); } } }); @@ -37,7 +157,7 @@ browserSync({ proxy: { target: "http://yourlocal.dev", proxyReq: [ - function(proxyReq) { + function (proxyReq) { console.log(proxyReq); } ] @@ -47,7 +167,7 @@ browserSync({ browserSync({ proxy: { target: "http://yourlocal.dev", - proxyRes: function(proxyRes, req, res) { + proxyRes: function (proxyRes, req, res) { console.log(proxyRes); } } @@ -57,13 +177,137 @@ browserSync({ proxy: { target: "http://yourlocal.dev", proxyRes: [ - function(proxyRes, req, res) { + function (proxyRes, req, res) { console.log(proxyRes); } ] } }); +browserSync({ + proxy: "https://yourlocal.dev", + https: { + key: "./path/to/the/key/file.key", + cert: "./path/to/the/cert/file.cer" + } +}); + +browserSync({ + port: 3000 +}); + +browserSync({ + proxy: "http://yourlocal.dev", + serveStatic: ['.', './app/css'] +}); + +browserSync({ + proxy: "http://yourlocal.dev", + serveStatic: [{ + route: '/assets', + dir: 'tmp' + }] +}); + +browserSync({ + proxy: "http://yourlocal.dev", + serveStatic: [{ + route: ['/assets', '/content'], + dir: 'tmp' + }] +}); + +browserSync({ + proxy: "http://yourlocal.dev", + serveStatic: [{ + route: '/assets', + dir: ['./tmp', './app'] + }] +}); + +browserSync({ + serveStatic: ['.', './app', './temp'], + serveStaticOptions: { + extensions: ['html'] // pretty urls + } +}); + +browserSync({ + https: true +}); + +browserSync({ + server: "./app", + https: true +}); + +browserSync({ + server: "./app", + https: { + key: "./path/to/the/key/file.key", + cert: "./path/to/the/cert/file.cer" + } +}); + +browserSync({ + httpModule: "http2" +}); + +browserSync({ + ghostMode: { + clicks: true, + scroll: true, + forms: { + inputs: true, + submit: true, + toggles: true + } + }, + proxy: "https://yourlocal.dev" +}); + +/** + * Not testing a bunch because they are either only string or boolean types. + * ....Also just got lazy and tired of writing the simple ones. + */ + +browserSync({ + snippetOptions: { + + // Ignore all HTML files within the templates folder + blacklist: [ + "templates/*.html" + ], + // Provide a custom Regex for inserting the snippet. + rule: { + match: /<\/body>/i, + fn: function (snippet, match) { + return snippet + match; + } + } + } +}); + +browserSync({ + rewriteRules: [ + { + match: /Browsersync/g, + fn: function (req, res, match) { + return 'kittenz'; + } + } + ] +}); + +browserSync({ + rewriteRules: [ + { + match: /(cats|kitten[sz]) are mediocre/g, + replace: "$1 are excellent" + } + ] +}); + var config = { server: { baseDir: "./" @@ -84,13 +328,13 @@ browserSync(config, function (err, bs) { browserSync.reload(); // single file -browserSync.reload( "styles.css" ); +browserSync.reload("styles.css"); // multiple files -browserSync.reload( ["styles.css", "ie.css"] ); +browserSync.reload(["styles.css", "ie.css"]); // streams support -browserSync.reload( { stream: true } ); +browserSync.reload({ stream: true }); browserSync.notify("Compiling, please wait!"); @@ -143,19 +387,19 @@ browser.exit(); browser.stream(); // -- "once" option. -browser.stream({once: true}); +browser.stream({ once: true }); // -- "match" option (string). -browser.stream({match: "**/*.js"}); +browser.stream({ match: "**/*.js" }); // -- "match" option (RegExp). -browser.stream({match: /\.js$/}); +browser.stream({ match: /\.js$/ }); // -- "match" option (function). -browser.stream({match: (testString) => true}); +browser.stream({ match: (testString) => true }); // -- "match" option (array). -browser.stream({match: ["**/*.js", /\.js$/, (testString) => true]}); +browser.stream({ match: ["**/*.js", /\.js$/, (testString) => true] }); // -- Both options. -browser.stream({once: true, match: ["**/*.js", /\.js$/, (testString) => true]}); +browser.stream({ once: true, match: ["**/*.js", /\.js$/, (testString) => true] }); diff --git a/types/browser-sync/index.d.ts b/types/browser-sync/index.d.ts index b22054c367..3b97fc8616 100644 --- a/types/browser-sync/index.d.ts +++ b/types/browser-sync/index.d.ts @@ -1,16 +1,21 @@ // Type definitions for browser-sync // Project: http://www.browsersync.io/ -// Definitions by: Asana , Joe Skeen +// Definitions by: Asana , +// Joe Skeen // Thomas "Thasmo" Deinhamer +// Kiyotoshi Ichikawa // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.2 /// /// +/// import * as chokidar from "chokidar"; import * as fs from "fs"; import * as http from "http"; import * as mm from "micromatch"; +import { ServeStaticOptions } from "serve-static"; declare namespace browserSync { interface Options { @@ -20,7 +25,7 @@ declare namespace browserSync { * * port - Default: 3001 * weinre.port - Default: 8080 - * Note: requires at least version 2.0.0 + * Note: Requires at least version 2.0.0. */ ui?: UIOptions | boolean; /** @@ -29,20 +34,40 @@ declare namespace browserSync { * patterns. * Default: false */ - files?: string | (string | FileCallback)[]; + files?: string | (string | FileCallback | object)[]; + /** + * Specify which file events to respond to. + * Available events: `add`, `change`, `unlink`, `addDir`, `unlinkDir` + */ + watchEvents?: string[]; + /** + * Watch files automatically. + */ + watch?: boolean; + /** + * Patterns for any watchers to ignore. + * Anything provided here will end up inside 'watchOptions.ignored'. + */ + ignore?: string[]; + /** + * Serve an index.html file for all non-asset routes. + * Useful when using client-routers. + */ + single?: boolean; /** * File watching options that get passed along to Chokidar. Check their docs for available options * Default: undefined - * Note: requires at least version 2.6.0 + * Note: Requires at least version 2.6.0. */ watchOptions?: chokidar.WatchOptions; /** * Use the built-in static server for basic HTML/JS/CSS websites. * Default: false */ - server?: ServerOptions; + server?: string | boolean | string[] | ServerOptions; /** * Proxy an EXISTING vhost. Browsersync will wrap your vhost with a proxy URL to view your site. + * Passing only a URL as a string equates to passing only target property of ProxyOptions type. * target - Default: undefined * ws - Default: undefined * middleware - Default: undefined @@ -50,25 +75,40 @@ declare namespace browserSync { * proxyRes - Default: undefined * proxyReq - Default: undefined */ - proxy?: string | boolean | ProxyOptions; + proxy?: string | ProxyOptions; /** * Use a specific port (instead of the one auto-detected by Browsersync) * Default: 3000 */ port?: number; + /** + * Functions or actual plugins used as middleware. + */ + middleware?: MiddlewareHandler | PerRouteMiddleware | (MiddlewareHandler | PerRouteMiddleware)[]; /** * Add additional directories from which static files should be served. * Should only be used in proxy or snippet mode. * Default: [] - * Note: requires at least version 2.8.0 + * Note: Requires at least version 2.8.0. */ - serveStatic?: string[]; + serveStatic?: (string | { route?: string | string[], dir?: string | string[]})[]; + /** + * Options that are passed to the serve-static middleware when you use the + * string[] syntax: eg: `serveStatic: ['./app']`. + * Please see [serve-static](https://github.com/expressjs/serve-static) for details. + */ + serveStaticOptions?: ServeStaticOptions; /** * Enable https for localhost development. - * Note - this is not needed for proxy option as it will be inferred from your target url. - * Note: requires at least version 1.3.0 + * Note: This may not be needed for proxy option as it will try to infer from your target url. + * Note: If privacy error is encountered please see HttpsOptions below, setting those will resolve. + * Note: Requires at least version 1.3.0. */ - https?: boolean; + https?: boolean | HttpsOptions; + /** + * Override http module to allow using 3rd party server modules (such as http2). + */ + httpModule?: string; /** * Clicks, Scrolls & Form inputs on any device will be mirrored to all others. * clicks - Default: true @@ -84,7 +124,7 @@ declare namespace browserSync { /** * Change the console logging prefix. Useful if you're creating your own project based on Browsersync * Default: BS - * Note: requires at least version 1.5.1 + * Note: Requires at least version 1.5.1. */ logPrefix?: string; /** @@ -100,19 +140,19 @@ declare namespace browserSync { /** * Log the snippet to the console when you're in snippet mode (no proxy/server) * Default: true - * Note: requires at least version 1.5.2 + * Note: Requires at least version 1.5.2. */ logSnippet?: boolean; /** * You can control how the snippet is injected onto each page via a custom regex + function. * You can also provide patterns for certain urls that should be ignored from the snippet injection. - * Note: requires at least version 2.0.0 + * Note: Requires at least version 2.0.0. */ snippetOptions?: SnippetOptions; /** * Add additional HTML rewriting rules. * Default: false - * Note: requires at least version 2.4.0 + * Note: Requires at least version 2.4.0. */ rewriteRules?: boolean | RewriteRules[]; /** @@ -139,7 +179,7 @@ declare namespace browserSync { /** * Add HTTP access control (CORS) headers to assets served by Browsersync. * Default: false - * Note: requires at least version 2.16.0 + * Note: Requires at least version 2.16.0. */ cors?: boolean; /** @@ -177,12 +217,12 @@ declare namespace browserSync { /** * Sync the scroll position of any element on the page. Add any amount of CSS selectors * Default: [] - * Note: requires at least version 2.9.0 + * Note: Requires at least version 2.9.0. */ scrollElements?: string[]; /** * Default: [] - * Note: requires at least version 2.9.0 + * Note: Requires at least version 2.9.0. * Sync the scroll position of any element on the page - where any scrolled element will cause * all others to match scroll position. This is helpful when a breakpoint alters which element * is actually scrolling @@ -197,13 +237,18 @@ declare namespace browserSync { /** * Restrict the frequency in which browser:reload events can be emitted to connected clients * Default: 0 - * Note: requires at least version 2.6.0 + * Note: Requires at least version 2.6.0. */ reloadDebounce?: number; + /** + * Emit only the first event during sequential time windows of a specified duration. + * Note: Requires at least version 2.13.0. + */ + reloadThrottle?: number; /** * User provided plugins * Default: [] - * Note: requires at least version 2.6.0 + * Note: Requires at least version 2.6.0. */ plugins?: any[]; /** @@ -224,6 +269,10 @@ declare namespace browserSync { * Override host detection if you know the correct IP to use */ host?: string; + /** + * Support environments where dynamic hostnames are not required (ie: electron). + */ + localOnly?: boolean; /** * Send file-change events to the browser * Default: true @@ -234,10 +283,16 @@ declare namespace browserSync { * Default: true */ timestamps?: boolean; + /** + * ¯\_(ツ)_/¯ + * Best guess, when ghostMode (or SocketIO?) is setup the events + * listed here will be emitted and able to hook into. + */ + clientEvents?: string[]; /** * Alter the script path for complete control over where the Browsersync Javascript is served * from. Whatever you return from this function will be used as the script path. - * Note: requires at least version 1.5.0 + * Note: Requires at least version 1.5.0. */ scriptPath?: (path: string) => string; /** @@ -248,10 +303,21 @@ declare namespace browserSync { * domain - Default: undefined * port - Default: undefined * clients.heartbeatTimeout - Default: 5000 - * Note: requires at least version 1.6.2 + * Note: Requires at least version 1.6.2. */ socket?: SocketOptions; - middleware?: MiddlewareHandler | PerRouteMiddleware | (MiddlewareHandler | PerRouteMiddleware)[]; + /** + * ¯\_(ツ)_/¯ + */ + tagNames?: TagNamesOptions; + /** + * ¯\_(ツ)_/¯ + */ + injectFileTypes?: string[]; + /** + * ¯\_(ツ)_/¯ + */ + excludeFileTypes?: string[]; } interface Hash { @@ -287,6 +353,7 @@ declare namespace browserSync { routes?: Hash; /** configure custom middleware */ middleware?: (MiddlewareHandler | PerRouteMiddleware)[]; + serveStaticOptions?: ServeStaticOptions } interface ProxyOptions { @@ -298,6 +365,11 @@ declare namespace browserSync { proxyReq?: ((res: http.ServerRequest) => any)[] | ((res: http.ServerRequest) => any); } + interface HttpsOptions { + key?: string; + cert?: string; + } + interface MiddlewareHandler { (req: http.IncomingMessage, res: http.ServerResponse, next: Function): any; } @@ -310,11 +382,17 @@ declare namespace browserSync { interface GhostOptions { clicks?: boolean; scroll?: boolean; - forms?: boolean; + forms?: boolean | { + submit?: boolean; + inputs?: boolean; + toggles?: boolean; + }; } interface SnippetOptions { - ignorePaths?: string; + async?: boolean, + whitelist?: string[], + blacklist?: string[], rule?: { match?: RegExp; fn?: (snippet: string, match: string) => any }; } @@ -327,9 +405,22 @@ declare namespace browserSync { clients?: { heartbeatTimeout?: number; }; } + interface TagNamesOptions { + less?: string; + scss?: string; + css?: string; + jpg?: string; + jpeg?: string; + png?: string; + svg?: string; + gif?: string; + js?: string; + } + interface RewriteRules { match: RegExp; - fn: (match: string) => string; + replace?: string; + fn?: (req: http.IncomingMessage, res: http.ServerResponse, match: string) => string; } interface StreamOptions { @@ -342,7 +433,7 @@ declare namespace browserSync { * Start the Browsersync service. This will launch a server, proxy or start the snippet mode * depending on your use-case. */ - (config?: Options, callback?: (err: Error, bs: Object) => any): BrowserSyncInstance; + (config?: Options, callback?: (err: Error, bs: object) => any): BrowserSyncInstance; /** * Create a Browsersync instance * @param name an identifier that can used for retrieval later @@ -367,7 +458,7 @@ declare namespace browserSync { * Start the Browsersync service. This will launch a server, proxy or start the snippet mode * depending on your use-case. */ - init(config?: Options, callback?: (err: Error, bs: Object) => any): BrowserSyncInstance; + init(config?: Options, callback?: (err: Error, bs: object) => any): BrowserSyncInstance; /** * Reload the browser * The reload method will inform all browsers about changed files and will either cause the browser From 55194a76e4854bca216f818098be7ebd5f5b8f67 Mon Sep 17 00:00:00 2001 From: Kiyotoshi Ichikawa Date: Wed, 25 Apr 2018 15:43:30 -0400 Subject: [PATCH 2/3] Updated types and appended some. The proxy.proxyRes property could be further expressed to take one or three parameters. Its previous representation was not correct according to the documentation and default configuration the package generates. Specified types for watchEvents, open, and logLevel options. Converted type Object references to object per recommended guidelines of DefinitelyTyped repo. Converted type Function references to arrow function. More SnippetOptions properties, defined FormsOptions under GhostOptions. Added and modified tests. --- types/browser-sync/browser-sync-tests.ts | 28 ++++++++++-- types/browser-sync/index.d.ts | 56 +++++++++++++++++------- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/types/browser-sync/browser-sync-tests.ts b/types/browser-sync/browser-sync-tests.ts index 613f8aee25..c63cb0c862 100644 --- a/types/browser-sync/browser-sync-tests.ts +++ b/types/browser-sync/browser-sync-tests.ts @@ -167,8 +167,8 @@ browserSync({ browserSync({ proxy: { target: "http://yourlocal.dev", - proxyRes: function (proxyRes, req, res) { - console.log(proxyRes); + proxyRes: function (proxyResponse, req, res) { + console.log(proxyResponse); } } }); @@ -177,8 +177,28 @@ browserSync({ proxy: { target: "http://yourlocal.dev", proxyRes: [ - function (proxyRes, req, res) { - console.log(proxyRes); + function (proxyResponse, req, res) { + console.log(proxyResponse); + } + ] + } +}); + +browserSync({ + proxy: { + target: "http://yourlocal.dev", + proxyRes: function (res) { + console.log(res); + } + } +}); + +browserSync({ + proxy: { + target: "http://yourlocal.dev", + proxyRes: [ + function (res) { + console.log(res); } ] } diff --git a/types/browser-sync/index.d.ts b/types/browser-sync/index.d.ts index 3b97fc8616..de0a457266 100644 --- a/types/browser-sync/index.d.ts +++ b/types/browser-sync/index.d.ts @@ -39,7 +39,7 @@ declare namespace browserSync { * Specify which file events to respond to. * Available events: `add`, `change`, `unlink`, `addDir`, `unlinkDir` */ - watchEvents?: string[]; + watchEvents?: WatchEvents | string[]; /** * Watch files automatically. */ @@ -72,7 +72,7 @@ declare namespace browserSync { * ws - Default: undefined * middleware - Default: undefined * reqHeaders - Default: undefined - * proxyRes - Default: undefined + * proxyRes - Default: undefined (http.ServerResponse if expecting single parameter) * proxyReq - Default: undefined */ proxy?: string | ProxyOptions; @@ -91,7 +91,7 @@ declare namespace browserSync { * Default: [] * Note: Requires at least version 2.8.0. */ - serveStatic?: (string | { route?: string | string[], dir?: string | string[]})[]; + serveStatic?: StaticOptions[] | string[]; /** * Options that are passed to the serve-static middleware when you use the * string[] syntax: eg: `serveStatic: ['./app']`. @@ -120,7 +120,7 @@ declare namespace browserSync { * Can be either "info", "debug", "warn", or "silent" * Default: info */ - logLevel?: string; + logLevel?: LogLevel; /** * Change the console logging prefix. Useful if you're creating your own project based on Browsersync * Default: BS @@ -170,7 +170,7 @@ declare namespace browserSync { * Decide which URL to open automatically when Browsersync starts. Defaults to "local" if none set. * Can be true, local, external, ui, ui-external, tunnel or false */ - open?: string | boolean; + open?: OpenOptions | boolean; /** * The browser(s) to open * Default: default @@ -320,6 +320,12 @@ declare namespace browserSync { excludeFileTypes?: string[]; } + type WatchEvents = "add" | "change" | "unlink" | "addDir" | "unlinkDir"; + + type LogLevel = "info" | "debug" | "warn" | "silent"; + + type OpenOptions = "local" | "external" | "ui" | "ui-external" | "tunnel"; + interface Hash { [path: string]: T; } @@ -353,16 +359,21 @@ declare namespace browserSync { routes?: Hash; /** configure custom middleware */ middleware?: (MiddlewareHandler | PerRouteMiddleware)[]; - serveStaticOptions?: ServeStaticOptions + serveStaticOptions?: ServeStaticOptions; } interface ProxyOptions { target?: string; middleware?: MiddlewareHandler; ws?: boolean; - reqHeaders?: (config: any) => Hash; - proxyRes?: ((res: http.ServerResponse, req: http.IncomingMessage, next: Function) => any)[] | ((res: http.ServerResponse, req: http.IncomingMessage, next: Function) => any); - proxyReq?: ((res: http.ServerRequest) => any)[] | ((res: http.ServerRequest) => any); + reqHeaders?: (config: object) => Hash; + proxyRes?: ProxyResponseMiddleware | ProxyResponseMiddleware[]; + proxyReq?: ((res: http.ServerRequest) => void)[] | ((res: http.ServerRequest) => void); + error?: (err: NodeJS.ErrnoException, req: http.IncomingMessage, res: http.ServerResponse) => void; + } + + interface ProxyResponseMiddleware { + (proxyRes: http.ServerResponse | http.IncomingMessage, res: http.ServerResponse, req: http.IncomingMessage): void; } interface HttpsOptions { @@ -370,11 +381,17 @@ declare namespace browserSync { cert?: string; } + interface StaticOptions { + route: string | string[], + dir: string | string[] + } + interface MiddlewareHandler { - (req: http.IncomingMessage, res: http.ServerResponse, next: Function): any; + (req: http.IncomingMessage, res: http.ServerResponse, next: () => void): any; } interface PerRouteMiddleware { + id?: string; route: string; handle: MiddlewareHandler; } @@ -382,18 +399,23 @@ declare namespace browserSync { interface GhostOptions { clicks?: boolean; scroll?: boolean; - forms?: boolean | { - submit?: boolean; - inputs?: boolean; - toggles?: boolean; - }; + forms?: FormsOptions | boolean; + } + + interface FormsOptions { + inputs: boolean, + submit: boolean, + toggles: boolean } interface SnippetOptions { - async?: boolean, + async?: boolean; whitelist?: string[], blacklist?: string[], - rule?: { match?: RegExp; fn?: (snippet: string, match: string) => any }; + rule?: { + match?: RegExp; + fn?: (snippet: string, match: string) => any + }; } interface SocketOptions { From c4493fb3a2fc0ba36c8c10d4be1454810353967e Mon Sep 17 00:00:00 2001 From: Kiyo Ichikawa Date: Tue, 12 Jun 2018 11:55:07 -0400 Subject: [PATCH 3/3] Adding cleanup and reset methods to type definition to help out with https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26417. Also, cleanup and adding some other missing props/methods. --- types/browser-sync/browser-sync-tests.ts | 52 +++++++++++++++++++++ types/browser-sync/index.d.ts | 59 ++++++++++++++++++------ 2 files changed, 96 insertions(+), 15 deletions(-) diff --git a/types/browser-sync/browser-sync-tests.ts b/types/browser-sync/browser-sync-tests.ts index c63cb0c862..1c7e7e5996 100644 --- a/types/browser-sync/browser-sync-tests.ts +++ b/types/browser-sync/browser-sync-tests.ts @@ -1,4 +1,5 @@ import browserSync = require("browser-sync"); +import { EventEmitter } from "events"; (() => { //make sure that the interfaces are correctly exposed @@ -391,6 +392,57 @@ bs.init({ bs.reload(); +browserSync.use( + { + plugin: function(opts: object, bs: browserSync.BrowserSyncInstance) { + console.log(opts); + }, + "plugin:name": "test" + }, + { files: "*.css" } +); + +browserSync.use({ + plugin: function(opts: object, bs: browserSync.BrowserSyncInstance) { + console.log(bs.name); + } +}); + +browserSync( + { + server: { + baseDir: "test/fixtures" + }, + logLevel: "silent", + open: false + } +); + +var instanceName = "TestInstance"; +var namedInstance = browserSync.create(instanceName); +namedInstance.init({ + server: { index: "./app" }, + https: true +}); + +console.log(namedInstance.getOption("https")); // Should output true. + +var existingInstance = browserSync.get(instanceName); + +browserSync.create("InstanceWithEventEmitter", new EventEmitter()); + +// Should output something greater than 0. +console.log(browserSync.instances.length); + +browserSync.reset(); + +// Should output 0. +console.log(browserSync.instances.length); + +var cleanupTestInstance = browserSync.create("CleanupTest"); +cleanupTestInstance.cleanup(); +console.log(cleanupTestInstance.active); // Should output false. + function browserSyncInit(): browserSync.BrowserSyncInstance { var browser = browserSync.create(); browser.init(); diff --git a/types/browser-sync/index.d.ts b/types/browser-sync/index.d.ts index de0a457266..bcf0aa966e 100644 --- a/types/browser-sync/index.d.ts +++ b/types/browser-sync/index.d.ts @@ -456,11 +456,15 @@ declare namespace browserSync { * depending on your use-case. */ (config?: Options, callback?: (err: Error, bs: object) => any): BrowserSyncInstance; + /** + * + */ + instances: Array; /** * Create a Browsersync instance * @param name an identifier that can used for retrieval later */ - create(name?: string): BrowserSyncInstance; + create(name?: string, emitter?: NodeJS.EventEmitter): BrowserSyncInstance; /** * Get a single instance by name. This is useful if you have your build scripts in separate files * @param name the identifier used for retrieval @@ -471,6 +475,11 @@ declare namespace browserSync { * @param name the name of the instance */ has(name: string): boolean; + /** + * Reset the state of the module. + * (should only be needed for test environments) + */ + reset(): void; } interface BrowserSyncInstance { @@ -481,6 +490,24 @@ declare namespace browserSync { * depending on your use-case. */ init(config?: Options, callback?: (err: Error, bs: object) => any): BrowserSyncInstance; + /** + * This method will close any running server, stop file watching & exit the current process. + */ + exit(): void; + /** + * Helper method for browser notifications + * @param message Can be a simple message such as 'Connected' or HTML + * @param timeout How long the message will remain in the browser. @since 1.3.0 + */ + notify(message: string, timeout?: number): void; + /** + * Method to pause file change events + */ + pause(): void; + /** + * Method to resume paused watchers + */ + resume(): void; /** * Reload the browser * The reload method will inform all browsers about changed files and will either cause the browser @@ -510,28 +537,30 @@ declare namespace browserSync { */ stream(opts?: StreamOptions): NodeJS.ReadWriteStream; /** - * Helper method for browser notifications - * @param message Can be a simple message such as 'Connected' or HTML - * @param timeout How long the message will remain in the browser. @since 1.3.0 + * Instance Cleanup. */ - notify(message: string, timeout?: number): void; + cleanup(fn?: (error: NodeJS.ErrnoException, bs: BrowserSyncInstance) => void): void; /** - * This method will close any running server, stop file watching & exit the current process. + * Register a plugin. + * Must implement at least a 'plugin' property that returns + * callable function. + * + * @method use + * @param {object} module The object to be `required`. + * @param {object} options The + * @param {any} cb A callback function that will return any errors. */ - exit(): void; + use(module: { "plugin:name"?: string, plugin: (opts: object, bs: BrowserSyncInstance) => any }, options?: object, cb?: any): void; + /** + * Callback helper to examine what options have been set. + * @param {string} name The key to search options map for. + */ + getOption(name: string): any; /** * Stand alone file-watcher. Use this along with Browsersync to create your own, minimal build system */ watch(patterns: string, opts?: chokidar.WatchOptions, fn?: (event: string, file: fs.Stats) => any) : NodeJS.EventEmitter; - /** - * Method to pause file change events - */ - pause(): void; - /** - * Method to resume paused watchers - */ - resume(): void; /** * The internal Event Emitter used by the running Browsersync instance (if there is one). You can use * this to emit your own events, such as changed files, logging etc.