diff --git a/meteor/README.md b/meteor/README.md index 6efa87bcd0..601787e020 100644 --- a/meteor/README.md +++ b/meteor/README.md @@ -1,106 +1,101 @@ -#Meteor Type Definitions -------------------------- +# Meteor Type Definitions -These definitions are now deprecated. Although they will still work up to Meteor version 0.6.5.1 (and possibly much later), the better way to develop a Meteor app with TypeScript is by installing the [typescript-libs](https://atmosphere.meteor.com/package/typescript-libs) Meteor smart package. +These are the definitions for version 0.9.1 of Meteor. Although these definitions can be downloaded separately for use, the recommended way to use these +definitions in a Meteor application is by installing the [typescript-libs](https://atmosphere.meteor.com/package/typescript-libs) Meteor smart package. +The smart package contains TypeScript definitions forMeteor, common third-party libraries (e.g. jquery, underscore, d3 etc.), and common smart packages +(e.g. iron-router). + +From within any Meteor application that is version 0.9.0 or later, install this package in the standard manner: + + $ meteor add typescript-libs -You first need to have (Meteorite)[http://oortcloud.github.io/meteorite/] version and smart package manager. If you don't have it, install it with this command: -- `npm install -g meteorite` + +## Usage Overview +For most applications, there are 4 specific steps you will have to take to write your Meteor application in TypeScript using this package: + +1. [Reference the definitions] (#usage-type-definition-references) +2. [Declare functions for Templates in a special way] (#usage-templates) +3. [Declare Collections in a special way] (#usage-collections) +4. [Create custom definitions for code you write] (#usage-creating-definitions) +5. [Transpile your .ts files into .js files] (#usage-transpilation) -Once you have installed Meteorite, you can easily install the smart package with this command: -- `mrt install typescript-libs` -- I also recommend installing the Meteor typescript compiler: `mrt install typescript-compiler` + +## Usage: Type Definition References +Within any TypeScript file, you can reference the Meteor definition file with this line: + + /// -The smart packages and documentation for them can be found on [Atmosphere](https://atmosphere.meteor.com): -- [typescript-libs](https://atmosphere.meteor.com/package/typescript-libs) -- [typescript-compiler](https://atmosphere.meteor.com/package/typescript-compiler) + +## Usage: Templates +When specifying template functions, you will need to use "bracket notation" instead of "dot notation": + + Template['myTemplateName']['rendered'] = function ( ) { ... } + + Template['myTemplateName']['helpers']({ + foo: function () { + return Session.get("foo"); + } + }); + + Template['myTemplateName']['foo'] = function () { + return Session.get("foo"); + }; -Using the typescript-libs smart package eliminates the need for the Template and Collections steps listed below, although there -are several new modifications necessary to use typescript-libs (e.g. calling Template['yourTemplate']['helpers'], creating Data Objects). +For "dot" notation, TypeScript requires properties be specified on a variable (but not for bracket notation), and it will throw an error saying "myTemplateName" +does not exist on Template. -Kudos to [Olivier Refalo](https://github.com/orefalo) for developing the smart packages quicker and better than me! --------------------------- +## Usage: Collections +The majority of extra work required to use TypeScript with Meteor is creating and maintaining the collection interfaces. However, doing so also provides the +additional benefit of succinctly documenting collection schema definitions (that are actually enforced). + +To define collections, you will need to create an interface representing the collection, and then declare a Collection type variable with that interface type (as a generic): + + interface JobDAO { + _id?: string; + name: string; + status?: string; + queuedAt?: string; + } + + declare var Jobs: Meteor.Collection; + Jobs = new Meteor.Collection('jobs'); -#Overview +Finally, any TypeScript file using collections will need to contain a reference at the top pointing to the collection definitions: -In order to effectively write a Meteor app with TypeScript, you will probably need to do these things: - -- Reference the Meteor type definitions file (meteor.d.ts) -- Create a Template definition file -- Create Collections within a module or modules + /// + /// + /// -##Referencing Meteor type definitions in your app -- Place the meteor.d.ts file in a directory (maybe `/lib/typescript`) -- Add `/// ` to the top of any TypeScript file - -This will make these typed Meteor variables/objects available across your application: - -- Meteor -- Session -- Deps -- Accounts -- Match -- Computation -- Dependency -- EJSON -- HTTO -- Email -- Assets -- DPP - -*Please note that the Template variable is not automatically available. You need to follow the instructions below to use the Template variable.* +If you choose to define collections (using the code above) in a separate file (e.g. collections/models/models.ts) and then create a separate file per collection +with the methods and permissions for that collection (e.g. collections/jobs.ts), the collection definitions should be one directory deeper than the collection +method/permission declarations so that Meteor can find the variable declarations before use. (e.g. collections/models/models.ts). -##Defining Templates -In order to call `Template.yourTemplateName.method`, you will need to create a simple TypeScript definition file that declares a Template variable containing a list of template view-models/managers of type IMeteorViewModel (or IMeteorManager, which is the same as IMeteorViewModel). A good place for this definition could be `/client/views/view-model-types.d.ts`. Here is an example of that file: - /// - - declare var Template: { - newPosts: IMeteorViewModel; - bestPosts: IMeteorViewModel; - postsList: IMeteorViewModel; - comment: IMeteorViewModel; - commentSubmit: IMeteorViewModel; - notifications: IMeteorViewModel; - postPage: IMeteorViewModel; - postEdit: IMeteorViewModel; - postItem: IMeteorViewModel; - postNew: IMeteorViewModel; - header: IMeteorViewModel; - } - -After you create this file, you may access the Template variable by declaring something similar to `/// ` at the top of any TypeScript file containing references to Template. Something like `Template.postsList.helpers()` would then transpile successfully (and also have the benefits of typing). +## Usage: Creating Definitions +Here is a guide to creating definitions: -##Defining Collections -In TypeScript, global variables are not allowed, and in a Meteor app, creating a local variable (using `var `) limits a variable's scope to the file. However, you will probably want to define variables, such as collections, that can be used across multiple files. In the case of collections, one way to work around these limitations is to wrap the definitions of all collections within a module, and then make the module globally accessible. Here is an example (collections/models.ts): - module Models { - export var Posts = new Meteor.Collection('posts'); - export var Comments = new Meteor.Collection('comments'); - export var Notifications = new Meteor.Collection('notifications'); - } +## Usage: Transpilation +WebStorm is good TypeScript-aware editor. It can automatically transpile your TypeScript code into JavaScript every time you save a file. To enable this +feature in WebStorm on OSX, first install the TypeScript transpiler on your system: - this.Models = Models; + $ [sudo -H] npm install -g typescript -You can then access the Posts collection by placing something similar to `/// ` at the top of a TypeScript file. The code within the file would look something like this: +Then, within WebStorm, go to Preferences -> File Watchers -> "+" symbol and add TypeScript. - Models.Posts.findOne(Session.get('currentPostId')); - -For organizational purposes, any additional code related to each Collection can be placed in a separate file per each collection. Alternatively, you could wrap each collection in its own module (e.g. PostsModel for posts, CommentsModel for comments). +If you are not using a TypeScript-aware editor, you can transpile the files using the [Meteor Typescript Compiler](https://github.com/orefalo/meteor-typescript-compiler). -##Reference app -Listed below is a simple Meteor reference application created with TypeScript is listed below. It is based on the Microscope reference app in [Discover Meteor](http://www.discovermeteor.com/ "http://www.discovermeteor.com/"). - -- Sample Site: -- Code (TypeScript and transpiled JS): +## Example/Reference Projects +* [TypeScript demos](https://github.com/orefalo/meteor-typescript-demos) diff --git a/meteor/meteor-tests.ts b/meteor/meteor-tests.ts index ca1973f638..05f4f4b310 100644 --- a/meteor/meteor-tests.ts +++ b/meteor/meteor-tests.ts @@ -10,16 +10,19 @@ /*********************************** Begin setup for tests ******************************/ // A developer must declare a var Template like this in a separate file to use this TypeScript type definition file -interface ITemplate { - adminDashboard: IMeteorViewModel; - chat: IMeteorViewModel; -} -declare var Template: ITemplate; +//interface ITemplate { +// adminDashboard: Meteor.Template; +// chat: Meteor.Template; +//} +//declare var Template: ITemplate; -var Rooms = new Meteor.Collection('rooms'); -var Messages = new Meteor.Collection('messages'); -var Monkeys = new Meteor.Collection('monkeys'); +var Rooms = new Mongo.Collection('rooms'); +var Messages = new Mongo.Collection('messages'); +var Monkeys = new Mongo.Collection('monkeys'); +var x = new Mongo.Collection('x'); +var y = new Mongo.Collection('y'); +var check = function(str1, str2) {}; /********************************** End setup for tests *********************************/ @@ -88,9 +91,9 @@ Meteor.publish("counts-by-room", function (roomId) { }); }); -var Counts = new Meteor.Collection("counts"); +var Counts = new Mongo.Collection("counts"); -Deps.autorun(function () { +Tracker.autorun(function () { Meteor.subscribe("counts-by-room", Session.get("roomId")); }); @@ -106,7 +109,7 @@ Meteor.subscribe("allplayers"); /** * Also from Meteor.subscribe section */ -Deps.autorun(function () { +Tracker.autorun(function () { Meteor.subscribe("chat", {room: Session.get("current-room")}); Meteor.subscribe("privateMessages"); }); @@ -138,11 +141,11 @@ Meteor.call('foo', 1, 2, function (error, result) {} ); var result = Meteor.call('foo', 1, 2); /** - * From Collections, Meteor.Collection section + * From Collections, Mongo.Collection section */ // DA: I added the "var" keyword in there -var Chatrooms = new Meteor.Collection("chatrooms"); -Messages = new Meteor.Collection("messages"); +var Chatrooms = new Mongo.Collection("chatrooms"); +Messages = new Mongo.Collection("messages"); var myMessages = Messages.find({userId: Session.get('myUserId')}).fetch(); @@ -150,7 +153,7 @@ Messages.insert({text: "Hello, world!"}); Messages.update(myMessages[0]._id, {$set: {important: true}}); -var Posts = new Meteor.Collection("posts"); +var Posts = new Mongo.Collection("posts"); Posts.insert({title: "Hello world", body: "First post"}); // Couldn't find assert() in the meteor docs @@ -160,7 +163,7 @@ Posts.insert({title: "Hello world", body: "First post"}); * Todo: couldn't figure out how to make this next line work with Typescript * since there is already a Collection constructor with a different signature * - var Scratchpad = new Meteor.Collection; + var Scratchpad = new Mongo.Collection; for (var i = 0; i < 10; i++) Scratchpad.insert({number: i * 2}); assert(Scratchpad.find({number: {$lt: 9}}).count() === 5); @@ -179,7 +182,7 @@ Animal.prototype = { // Define a Collection that uses Animal as its document -var Animals = new Meteor.Collection("Animals", { +var Animals = new Mongo.Collection("Animals", { transform: function (doc) { return new Animal(doc); } }); @@ -191,8 +194,8 @@ Animals.findOne({name: "raptor"}).makeNoise(); // prints "roar" * From Collections, Collection.insert section */ // DA: I added the variable declaration statements to make this work -var Lists = new Meteor.Collection('Lists'); -var Items = new Meteor.Collection('Lists'); +var Lists = new Mongo.Collection('Lists'); +var Items = new Mongo.Collection('Lists'); var groceriesId = Lists.insert({name: "Groceries"}); Items.insert({list: groceriesId, name: "Watercress"}); @@ -201,9 +204,9 @@ Items.insert({list: groceriesId, name: "Persimmons"}); /** * From Collections, collection.update section */ -var Players = new Meteor.Collection('Players'); +var Players = new Mongo.Collection('Players'); -Template.adminDashboard.events({ +Template['adminDashboard'].events({ 'click .givePoints': function () { Players.update(Session.get("currentPlayer"), {$inc: {score: 5}}); } @@ -223,14 +226,14 @@ Meteor.methods({ /** * From Collections, collection.remove section */ -Template.chat.events({ +Template['chat'].events({ 'click .remove': function () { Messages.remove(this._id); } }); // DA: I added this next line -var Logs = new Meteor.Collection('logs'); +var Logs = new Mongo.Collection('logs'); Meteor.startup(function () { if (Meteor.isServer) { @@ -242,7 +245,7 @@ Meteor.startup(function () { /*** * From Collections, collection.allow section */ -Posts = new Meteor.Collection("posts"); +Posts = new Mongo.Collection("posts"); Posts.allow({ insert: function (userId, doc) { @@ -282,21 +285,11 @@ topPosts.forEach(function (post) { count += 1; }); -/** - * From Collections, cursor.count section - */ -var frag = Meteor.render(function () { - var highScoring = Posts.find({score: {$gt: 10}}); - return "

There are " + highScoring.count() + " posts with " + - "scores greater than 10

"; -}); -document.body.appendChild(frag); - /** * From Collections, cursor.observeChanges section */ // DA: I added this line to make it work -var Users = new Meteor.Collection('users'); +var Users = new Mongo.Collection('users'); var count1 = 0; var query = Users.find({admin: true, onlineNow: true}); @@ -317,23 +310,17 @@ setTimeout(function () {handle.stop();}, 5000); /** * From Sessions, Session.set section */ -Deps.autorun(function () { +Tracker.autorun(function () { Meteor.subscribe("chat-history", {room: Session.get("currentRoomId")}); }); -// Causes the function passed to Deps.autorun to be re-run, so +// Causes the function passed to Tracker.autorun to be re-run, so // that the chat-history subscription is moved to the room "home". Session.set("currentRoomId", "home"); /** * From Sessions, Session.get section */ -Session.set("enemy", "Eastasia"); -var frag1 = Meteor.render(function () { - return "

We've always been at war with " + - Session.get("enemy") + "

"; -}); - // Page will say "We've always been at war with Eastasia" // DA: commented out since transpiler didn't like append() @@ -362,15 +349,6 @@ Meteor.users.deny({update: function () { return true; }}); /** * From Accounts, Meteor.loginWithExternalService section */ -Accounts.loginServiceConfiguration.remove({ - service: "weibo" -}); -Accounts.loginServiceConfiguration.insert({ - service: "weibo", - clientId: "1292962797", - secret: "75a730b58f5691de5522789070c319bc" -}); - Meteor.loginWithGithub({ requestPermissions: ['user', 'public_repo'] }, function (err) { @@ -434,56 +412,16 @@ Accounts.emailTemplates.enrollAccount.text = function (user, url) { /** * From Templates, Template.myTemplate.helpers section */ -Template.adminDashboard.helpers({ +Template['adminDashboard'].helpers({ foo: function () { return Session.get("foo"); } }); -/** - * From Templates, Template.myTemplate.preserve - */ -Template.adminDashboard.preserve({ - 'input[id]': function (node) { return node.id; } -}); - -/** - * From Templates, Meteor.render section - */ -var frag2 = Meteor.render(function () { - return "

There are " + Players.find({online: true}).count() + - " players online.

"; -}); -document.body.appendChild(frag2); - -Players.update({idleTime: {$gt: 30}}, {$set: {online: false}}); - -/** - * From Templates, Meteor.renderList section - */ -var frag3 = Meteor.renderList( - Posts.find({tags: "frontpage"}), - function(post) { - var style = Session.equals("selectedId", post._id) ? "selected" : ""; - // A real app would need to quote/sanitize post.name - return '
' + post.name + '
'; - }); -document.body.appendChild(frag3); - -var somePost = Posts.findOne({tags: "frontpage"}); -Session.set("selectedId", somePost._id); - -var eventTester = { - 'click p': function (event: IMeteorEvent) { - var paragraph = event.currentTarget; // always a P - var clickedElement = event.target; // could be the P or a child element - } -} - /** * From Match section */ -var Chats = new Meteor.Collection('chats'); +var Chats = new Mongo.Collection('chats'); Meteor.publish("chats-in-room", function (roomId) { // Make sure roomId is a string, not an arbitrary mongo selector object. @@ -515,16 +453,16 @@ check({ name: undefined }, pat) // Throws an exception check(undefined, Match.Optional('test')); // OK /** - * From Deps, Deps.autorun section + * From Deps, Tracker.autorun section */ -Deps.autorun(function () { +Tracker.autorun(function () { var oldest = Monkeys.findOne('age = 20'); if (oldest) Session.set("oldest", oldest.name); }); -Deps.autorun(function (c) { +Tracker.autorun(function (c) { if (! Session.equals("shouldAlert", true)) return; @@ -535,29 +473,29 @@ Deps.autorun(function (c) { /** * From Deps, Deps.Computation */ -if (Deps.active) { - Deps.onInvalidate(function () { - Monkeys.destroy(); - Rooms.finalize(); - }); +if (Tracker.active) { + Tracker.onInvalidate(function () { + x.destroy(); + y.finalize(); + }); } /** - * From Deps, Deps.Dependency + * From Tracker, Tracker.Dependency */ var weather = "sunny"; -var weatherDep = new Deps.Dependency; +var weatherDep = new Tracker.Dependency; var getWeather = function () { - weatherDep.depend() - return weather; + weatherDep.depend(); + return weather; }; var setWeather = function (w) { - weather = w; - // (could add logic here to only call changed() - // if the new value is different from the old) - weatherDep.changed(); + weather = w; + // (could add logic here to only call changed() + // if the new value is different from the old) + weatherDep.changed(); }; /** @@ -608,3 +546,18 @@ Meteor.call('sendEmail', 'Hello from Meteor!', 'This is a test of Email.send.'); +var testTemplate = new Blaze.Template(); +var testView = new Blaze.View(); + +declare var el: HTMLElement; +Blaze.render(testTemplate, el); +Blaze.renderWithData(testTemplate, {testData: 123}, el); +Blaze.remove(testView); +Blaze.getData(el); +Blaze.getData(testView); +Blaze.toHTML(testTemplate); +Blaze.toHTML(testView); +Blaze.toHTMLWithData(testTemplate, {test: 1}); +Blaze.toHTMLWithData(testTemplate, function() {}); +Blaze.toHTMLWithData(testView, {test: 1}); +Blaze.toHTMLWithData(testView, function() {}); diff --git a/meteor/meteor.d.ts b/meteor/meteor.d.ts index a321dc00ec..48fa3266c1 100644 --- a/meteor/meteor.d.ts +++ b/meteor/meteor.d.ts @@ -1,604 +1,630 @@ -// Type definitions for Meteor 0.6.5 +// Type definitions for Meteor 0.9.1 // Project: http://www.meteor.com/ // Definitions by: Dave Allen // Definitions: https://github.com/borisyankov/DefinitelyTyped - -interface IMeteor { - - /******** - * Core * - ********/ - isClient: boolean; - isServer: boolean; - startup(func: Function): void; - absoluteUrl(path: string, - options: { - secure?: boolean; - replaceLocalhost?: boolean; - rootUrl?: string; - }): void; - settings: Object; - release: string; - - - /************************* - * Publish and Subscribe * - *************************/ - - /** - * Publish a record set. - * - * @param name Name of the attribute set. If null, the set has no name, and the record set is - * automatically sent to all connected clients. - * @param func Function called on the server each time a client subscribes. Inside the function, - * this is the publish handler object, described below. If the client passed arguments - * to subscribe, the function is called with the same arguments. - */ - publish(name: string, func: Function): any; - //Todo: Figure out a way to define this.userId, this.added, this.changed, etc that can be called from within publish - - /** - * Subscribe to a record set. Returns a handle that provides stop() and ready() methods. - * - * @param name Name of the subscription. Matches name of server's publish() call. - * @param arg1,arg2,arg3 Optional arguments passed to publisher function on server. - * @param callbacks Optional. May include onError and onReady callbacks. Can be Object or Function. If a function - * is passed instead of an object, it is interpreted as an onReady callback. - */ - subscribe(name: string, arg1?: any, arg2?: any, ars3?: any, arg4?: any, callbacks?: Object): IMeteorHandle; - - - /*********** - * Methods * - ***********/ - methods(methods: Object): void; - Error(error: number, reason?: string, details?: string): void; - // DA: Really should be defined like this: call(name: string, ...args?: any[], asyncCallback?: Function): void; - // But typescript does not allow Rest parameter (..args) to not be the last parameter defined - call(name: string, param1?: Object, param2?: Object, param3?: Object, param4?: Object, asyncCallback?: Function): void; - apply(name: string, options: any[], asyncCallback?: Function): void; - defer(callback: Function): void; - - - /********************* - * ServerConnections * - *********************/ - status(): { - connected: boolean; - status: string; - retryCount: number; - retryTime: number; - reason: string; - }; - reconnect(): void; - disconnect(): void; - - - /*************** - * Collections * - ***************/ - Collection(name: string, - options?: { - connection?: Object; - idGeneration?: string; - transform?: Function; - }): void; - - - /************ - * Accounts * - ************/ - user(): IMeteorUser; - userId(): string; - users: IMeteorUserCollection; - loggingIn(): boolean; - logout(callback?: Function): void; - loginWithPassword(user: Object, password: string, callback?: Function): void; - loginWithExternalService(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - loginWithFacebook(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - loginWithGithub(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - loginWithGoogle(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - loginWithMeetup(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - loginWithTwitter(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - loginWithWeibo(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }, - callback?: Function): void; - - /************* - * Templates * - *************/ - render(htmlFunc: Function): DocumentFragment; - renderList(observable: IMeteorCursor, docFunc: Function, elseFunc?: Function): DocumentFragment; - - /********** - * Timers * - **********/ - setTimeout(func: Function, delay: number): void; - setInterval(func: Function, delay: number): void; - clearTimeout(id: number): void; - clearInterval(id: number): void; - - - /******************** Begin definitions for contributed packages from Atmosphere (or elsewhere) *******************/ - - /************************************************** - * For Paginated-Subscription contributed package * - **************************************************/ - subscribeWithPagination(collection: string, limit: number): IMeteorHandle; - Template(): void; - - /************************************************* - * For Router or Iron-Router contributed package * - *************************************************/ - Router: IMeteorRouter; - - /********************************* - * For Error contributed package * - *********************************/ - Errors: IMeteorErrors; - - /******************** End definitions for contributed packages from Atmosphere (or elsewhere) *********************/ - -} // End Meteor.someFunction definitions - - -/*************** - * Collections * - ***************/ -interface IMeteorCollection { - find(selector?, options?: Object): IMeteorCursor; - findOne(selector, options?: Object): any; - insert(doc: Object, callback?: Function): string; - update(selector, modifier, options?: Object, callback?: Function): void; - remove(selector, callback?: Function): void; - allow(options: Object): boolean; - deny(options: Object): boolean; - ObjectID(hexString?: string): Object; -} - -interface IMeteorCursor { - forEach(callback: Function): void; - map(callback: Function): void; - fetch(): any[]; - count(): number; - rewind(): void; - observe(callbacks: Object): void; - observeChanges(callbacks: Object): void; -} - - -/************* - * Templates * - *************/ - /** - * To use Meteor's Template.templateName.function, you must define an interface in a separate file with - * extension ".d.ts". Within the interface, every template name must have a property by that name that - * is of type IMeteorViewModel or IMeteorManager (choose either depending on your philosophical - * preference -- both work the same) - * e.g. file ".../client/views/view-model-types.d.ts": - * - * interface ITemplate { - * postsList: IMeteorViewModel; - * comment: IMeteorViewModel; - * notifications: IMeteorViewModel; - * [your template name]: IMeteorViewModel; - * } - * declare var Template: ITemplate; + * These are the modules and interfaces that can't be automatically generated from the Meteor api.js file */ -interface IMeteorViewModel { - rendered(callback: Function): void; - created(callback: Function): void; - destroyed(callback: Function): void; - events(eventMap: {[eventName: string]: Function;}): void; - helpers(helpers: Object): void; - preserve(selector: Object): void; +declare module Meteor { + interface EJSONObject extends Object {} + + interface LoginWithExternalServiceOptions { + requestPermissions?: string[]; + requestOfflineToken?: Boolean; + forceApprovalPrompt?: Boolean; + userEmail?: string; + } + + function loginWithMeteorDeveloperAccount(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + function loginWithFacebook(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + function loginWithGithub(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + function loginWithGoogle(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + function loginWithMeetup(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + function loginWithTwitter(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + function loginWithWeibo(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void; + + interface UserEmail { + address:string; + verified:boolean; + } + + interface User { + _id?:string; + username?:string; + emails?:Meteor.UserEmail[]; + createdAt?: number; + profile?: any; + services?: any; + } + + interface SubscriptionHandle { + stop(): void; + ready(): boolean; + } + + interface TemplateBase { + [templateName: string]: Meteor.Template; + } + + interface RenderedTemplate extends Object {} + + interface DataContext extends Object {} + + interface Tinytest { + add(name:string, func:Function); + addAsync(name:string, func:Function); + } + + enum StatusEnum { + connected, + connecting, + failed, + waiting, + offline + } + + interface LiveQueryHandle { + stop(): void; + } + + interface EmailFields { + subject?: Function; + text?: Function; + } + + interface EmailTemplates { + from: string; + siteName: string; + resetPassword: Meteor.EmailFields; + enrollAccount: Meteor.EmailFields; + verifyEmail: Meteor.EmailFields; + } + + interface AccountsBase { + EmailTemplates: { + from: string; + siteName: string; + resetPassword: Meteor.EmailFields; + enrollAccount: Meteor.EmailFields; + verifyEmail: Meteor.EmailFields; + } + loginServicesConfigured(): boolean; + } + + interface MatchBase { + Any; + String; + Integer; + Boolean; + undefined; + null; + Object; + Optional(pattern):boolean; + ObjectIncluding(dico):boolean; + OneOf(...patterns); + Where(condition); + } + + interface AllowDenyOptions { + insert?: (userId:string, doc) => boolean; + update?: (userId, doc, fieldNames, modifier) => boolean; + remove?: (userId, doc) => boolean; + fetch?: string[]; + transform?: Function; + } + + interface Error { + error: number; + reason?: string; + details?: string; + } } -interface IMeteorManager { - rendered(callback: Function): void; - created(callback: Function): void; - destroyed(callback: Function): void; - events(eventMap: {[eventType: string]: Function;}): void; - helpers(helpers: Object): any; - preserve(selector: Object): void; +declare module Mongo { + interface CollectionFieldSpecifier { + [id: string]: Number; + } + + enum CollectionIdGenerationEnum { + STRING, + MONGO + } + +// interface CollectionOptions { +// connection: Object; +// idGeneration: Mongo.CollectionIdGenerationEnum; +// transform?: (document)=>any; +// } +// +// function Collection(name:string, options?: Mongo.CollectionOptions) : void; } -// DA: Currently not used, but I'd like to figure out a way to define the function signature -// for teh callbacks in IMeteorViewModel, IMeteorManager, and many other interfaces -interface IMeteorEvent { - type?: MeteorEventType.Value; - target?: Element; - currentTarget?: Element; - which?: number; - stopPropogation(): void; - stopImmediatePropogation(): void; - preventDefault(): void; - isPropogationStopped(): boolean; - isImmediatePropogationStopped(): boolean; - isDefaultPrevented(): boolean; +declare module Tracker { + function Computation(): void; + interface Computation { + + } + function Dependency(): void; + interface Dependency { + changed(): void; + depend(fromComputation: Tracker.Computation): boolean; + hasDependents(): boolean; + } } -declare module MeteorEventType { - export enum Value {'click', 'dblclick', 'focus', 'blur', 'change', - 'mouseenter', 'mouseleave', 'mousedown', 'mouseup', 'keydown', 'keypress', 'keyup', 'tap'} +declare module Package { + function describe(metadata:PackageDescribeAPI); + function on_use(func:{(api:Api, where?:string[]):void}); + function on_use(func:{(api:Api, where?:string):void}); + function on_test(func:{(api:Api):void}) ; + function register_extension(extension:string, options:PackageRegisterExtensionOptions); + interface PackageRegisterExtensionOptions {(bundle:Bundle, source_path:string, serve_path:string, where?:string[]):void} + interface PackageDescribeAPI { + summary: string; + } + interface Api { + export(variable:string); + export(variables:string[]); + use(deps:string, where?:string[]); + use(deps:string, where?:string); + use(deps:string[], where?:string[]); + use(deps:string[], where?:string); + add_files(file:string, where?:string[]); + add_files(file:string, where?:string); + add_files(file:string[], where?:string[]); + add_files(file:string[], where?:string); + imply(package:string); + imply(packages:string[]); + } + interface BundleOptions { + type: string; + path: string; + data: any; + where: string[]; + } + interface Bundle { + add_resource(options:BundleOptions); + error(diagnostics:string); + } } -/*********** - * Session * - ***********/ -interface IMeteorSession { - set(key: string, value: Object): void; - setDefault(key: string, value: Object): void; - get(key: string): Object; - equals(key: string, value: any): void; +declare module Npm { + function require(module:string); + function depends(dependencies:{[id:string]:string}); } -interface IMeteorHandle { - loaded(): number; - limit(): number; - ready(): boolean; - loadNextPage(): void; +declare module HTTP { + enum HTTPMethodEnum { + GET, + POST, + PUT, + DELETE + } + + interface HTTPRequest { + content?:string; + data?:any; + query?:string; + params?:{[id:string]:string}; + auth?:string; + headers?:{[id:string]:string}; + timeout?:number; + followRedirects?:boolean; + } + + interface HTTPResponse { + statusCode:number; + content:string; + // response is not always json + data:any; + headers:{[id:string]:string}; + } } -/************************** - * Accounts and Passwords * - **************************/ -interface IMeteorUser { - _id?: string; - username?: string; - emails?: { - address: string; - verified: boolean; - }; - profile?: any; - services?: any; - createdAt?: number; +declare module Email { + interface EmailMessage { + from: string; + to: any; // string or string[] + cc?: any; // string or string[] + bcc?: any; // string or string[] + replyTo?: any; // string or string[] + subject: string; + text?: string; + html?: string; + headers?: {[id: string]: string}; + } } -interface IMeteorUserCollection { - find(selector?, options?: Object): IMeteorCursor; - findOne(selector, options?: Object): IMeteorUser; - insert(doc: IMeteorUser, callback?: Function): IMeteorUser; - update(selector, modifier, options?: Object, callback?: Function): void; - remove(selector, callback?: Function): void; - allow(options: Object): boolean; - deny(options: Object): boolean; - ObjectID(hexString?: string): Object; +declare module DDP { + interface DDPStatic { + subscribe(name, ...rest); + call(method:string, ...parameters):void; + apply(method:string, ...parameters):void; + methods(IMeteorMethodsDictionary); + status():DDPStatus; + reconnect(); + disconnect(); + onReconnect(); + } + + interface DDPStatus { + connected: boolean; + status: Meteor.StatusEnum; + retryCount: number; + //To turn this into an interval until the next reconnection, use retryTime - (new Date()).getTime() + retryTime?: number; + reason?: string; + } } -interface IMeteorAccounts { - config(options: { - sendVerificationEmail?: boolean; - forbidClientAccountCreation?: boolean; - }): void; - ui: { - config(options: { - requestPermissions?: Object; - requestOfflineToken?: Object; - passwordSignupFields?: string; - }); - }; - validateNewUser(func: Function): void; - onCreateUser(func: Function): void; - createUser(options: { - username?: string; - email?: string; - password?: string; - profile?: string; - }, - callback?: Function): void; - changePassword(oldPassword: string, newPassword: string, callback?: Function): void; - forgotPassword(options: { - email: string; - }, - callback?: Function): void; - resetPassword(token: string, newPassword: string, callback?: Function): void; - setPassword(userId: string, newPassword: string): void; - verifyEmail(token: string, callback?: Function): void; - sendResetPasswordEmail(userId: string, email?: string): void; - sendEnrollmentEmail(userId: string, email?: string): void; - sendVerificationEmail(userId: string, email?: string): void; - emailTemplates: { - from: string; - siteName: string; - resetPassword: IMeteorEmailValues; - enrollAccount: IMeteorEmailValues; - verifyEmail: IMeteorEmailValues; - }; - // DA: I didn't see the signature for this, but it appears in the examples - loginServiceConfiguration: { - remove(options: Object): void; - insert(options: Object): void; - }; +declare module Random { + function fraction():number; + function hexString(numberOfDigits:number):string; // @param numberOfDigits, @returns a random hex string of the given length + function choice(array:any[]):string; // @param array, @return a random element in array + function choice(str:string):string; // @param str, @return a random char in str } -interface IMeteorEmailValues { - subject?: Function; - text?: Function; +declare module Blaze { + interface View { + name: string; + parentView: Blaze.View; + isCreated: boolean; + isRendered: boolean; + isDestroyed: boolean; + renderCount: number; + autorun(runFunc: Function): void; + onViewCreated(func: Function): void; + onViewReady(func: Function): void; + onViewDestroyed(func: Function): void; + firstNode(): Node; + lastNode(): Node; + template: Blaze.Template; + templateInstance(): any; + } + interface Template { + viewName: string; + renderFunction: Function; + constructView(): Blaze.View; + } } -interface IMeteorMatch { - test(value: any, pattern: any): boolean; - Any; - String; - Number; - Boolean; - undefined; - null; - Integer; - ObjectIncluding; - Object; - Optional(pattern: string); - OneOf(...args: string[]); - Where(condition: boolean); -} - -interface IExternalServiceParams { - options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - forceApprovalPrompt?: boolean; - }; - callback?: Function; -} - -/******** - * Deps * - ********/ -interface IMeteorDeps { - autorun(runFunc: Function): IMeteorComputationObject; - flush(): void; - nonreactive(func: Function): void; - active: boolean; - currentComputation: IMeteorComputationObject; - onInvalidate(callback: Function): void; - afterFlush(callback: Function): void; - - /** - * @constructor - */ - Computation(): void; - - /** - * @constructor - */ - Dependency(): void; -} - -interface IMeteorComputationObject { - stop(): void; - invalidate(): void; - onInvalidate(callback: Function): void; - stopped: boolean; - invalidated: boolean; - firstRun: boolean; -} - -interface IMeteorDependencyObject { - changed(): void; - depend(fromComputation?: IMeteorComputationObject): boolean; - hasDependents(): boolean; -} - -/********* - * EJSON * - *********/ -interface IMeteorEJSON { - parse(str: string): void; - stringify(val: any): string; - fromJSONValue(val): any; - toJSONValue(val): JSON; - equals(any: any): boolean; - clone(val: any): any; - newBinary(size: number): void; - isBinary(x: any): boolean; - addType(name: string, factory: Function): void; -} - -/**************** - * HTTP package * - ****************/ -interface IMeteorHTTP { - call(method: string, url: string, options: { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; - }, asyncCallback?: Function): IMeteorHTTPResult; - get(url: string, options?: { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; - }, asyncCallback?: Function): IMeteorHTTPResult; - post(url: string, options?: { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; - }, asyncCallback?: Function): IMeteorHTTPResult; - put(url: string, options?: { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; - }, asyncCallback?: Function): IMeteorHTTPResult; - del(url: string, options?: { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; - }, asyncCallback?: Function): IMeteorHTTPResult; -} - -// DA: Currently not used -// I would like to figure out a way to specify this as type for options for IMeteorHTTP methods. -// Tests don't work if I simply specify this interface as the type. -interface IMeteorHTTPCallOptions { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; -} - -interface IMeteorHTTPResult { - statusCode: number; - content: string; - data?: JSON; - headers: Object; -} - -/********* - * Email * - *********/ -interface IMeteorEmail { - send(options: { - from?: string; - to: any; - cc?: any; - bcc?: any; - replyTo?: any; - subject?: string; - text?: string; - html?: string; - headers?: Object; - }): void; -} - - -/********** - * Assets * - **********/ -interface IMeteorAssets { - getText(assetPath: string, asyncCallback?: Function): string; - getBinary(assetPath: string, asyncCallback?: Function): any; -} - -/******* - * DPP * - *******/ -interface IMeteorDPP { - connect(url: string): void; -} - -declare var Meteor: IMeteor; -declare var Collection: IMeteorCollection; -declare var Session: IMeteorSession; -declare var Deps: IMeteorDeps; -declare var Accounts: IMeteorAccounts; -declare var Match: IMeteorMatch; -declare function check(value: any, pattern: any): void; -declare var Computation: IMeteorComputationObject; -declare var Dependency: IMeteorDependencyObject; -declare var EJSON: IMeteorEJSON; -declare var HTTP: IMeteorHTTP; -declare var Email: IMeteorEmail; -declare var Assets: IMeteorAssets; -declare var DPP: IMeteorDPP; - -declare function changed(collection: string, id: string, fields, Object): void; - -/******************** Begin definitions for contributed packages from Atmosphere (or elsewhere) *********************/ - -/*************************************************** - * For Router and Iron-Router contributed packages * - ***************************************************/ -interface IMeteorRouter { - - // These are for Router - page(): void; - add(route: Object): void; - to(path: string, ...args: any[]): void; - filters(filtersMap: Object); - filter(filterName: string, options?: Object); - - // These are for Iron-Router - map(routeMap: Function): void; - path(route: string, params?: Object): void; - url(route: string): void; - routes: Object; - configure(options: IMeteorRouterConfig): void; -} - -// For Iron-Router -interface IMeteorRouterConfig { - layout: string; - notFoundTemplate: string; - loadingTemplate: string; - renderTemplates: Object; -} - -interface IMeteorErrors { - throw(message: string): void; - clear(): void; -} - -// For Router and Iron-Router contributed packages -declare var Router: IMeteorRouter; - -/******************** End definitions for contributed packages from Atmosphere (or elsewhere) ***********************/ - /** - * Todo: - * Define "this.function" functions. - * Define the signatures of callback functions and other functions. - ***/ + * These modules and interfaces are automatically generated from the Meteor api.js file + */ +declare module Meteor { + var isClient: boolean; + var isServer: boolean; + var isCordova: boolean; + function startup(func: Function): void; + function wrapAsync(func: Function, context?: Object): any; + function absoluteUrl(path?: string, options?: { + secure?: Boolean; + replaceLocalhost?: Boolean; + rootUrl?: string; + }): string; + var settings: {[id:string]: any}; + var release: string; + function publish(name: string, func: Function): void; + function subscribe(name, ...args): SubscriptionHandle; + function methods(methods: Object): void; + function Error(error, reason?, details?): void; + function call(name: string, ...params): void; + function apply(name: string, params, options?: { + wait?: Boolean; + onResultReceived?: Function; + }, asyncCallback?): void; + function status(): Meteor.StatusEnum; + function reconnect(): void; + function disconnect(): void; + function onConnection(callback: Function): void; + function user(): Meteor.User; + function userId(): string; + var users: Mongo.Collection; + function loggingIn(): boolean; + function logout(callback?: Function): void; + function logoutOtherClients(callback?: Function): void; + function loginWithPassword(user: any, password: string, callback?: Function): void; + function loginWithExternalService(options?: { + requestPermissions?: string[]; + requestOfflineToken?: Boolean; + forceApprovalPrompt?: Boolean; + userEmail?: string; + loginStyle?: string; + }, callback?: Function): void; + function setTimeout(func: Function, delay: number): number; + function setInterval(func: Function, delay: number): number; + function clearTimeout(id: number): void; + function clearInterval(id: number): void; + function EnvironmentVariable(): void; + function get(): string; + function withValue(value: any, func: Function): void; + function bindEnvironment(func: Function, onException: Function, _this: Object): Function; +} + +declare module Meteor { + interface EJSON { + parse(str: string): EJSON; + stringify(val: Meteor.EJSON, options?: { + indent?: any; // boolean, integer, or string + canonical?: Boolean; + }): string; + fromJSONValue(val: JSON): any; + toJSONValue(val: Meteor.EJSON): JSON; + equals(a: Meteor.EJSONObject, b: Meteor.EJSONObject, options?: { + keyOrderSensitive?: Boolean; + }): boolean; + clone(v:T): T; /** TODO: add return value **/ + newBinary(size: number): any; + isBinary(x): boolean; + addType(name: string, factory: Function): void; + } +} + +declare module DDP { + function connect(url: string): DDP.DDPStatic; +} + +declare module Mongo { + function Collection(name: string, options?: { + connection?: Object; + idGeneration?: Mongo.CollectionIdGenerationEnum; + transform?: (document)=>any; + }): void; + function ObjectID(hexString: string): void; +} + +declare module Mongo { + interface Collection { + find(selector?: any, options?: { + sort?: any; + skip?: number; + limit?: number; + fields?: Mongo.CollectionFieldSpecifier; + reactive?: Boolean; + transform?: (document)=>any; + }): Mongo.Cursor; + findOne(selector?: any, options?: { + sort?: any; + skip?: number; + fields?: Mongo.CollectionFieldSpecifier; + reactive?: Boolean; + transform?: (document)=>any; + }): Meteor.EJSONObject; + insert(doc: Object, callback?: Function): string; + update(selector: any, modifier: any, options?: { + multi?: Boolean; + upsert?: Boolean; + }, callback?: Function): number; + upsert(selector: any, modifier: any, options?: { + multi?: Boolean; + }, callback?: Function): {numberAffected?: number; insertedId?: string;}; + remove(selector: any, callback?: Function): void; + allow(options: Meteor.AllowDenyOptions): boolean; + deny(options: Meteor.AllowDenyOptions): boolean; + } +} + +declare module Mongo { + interface Cursor { + count(): number; + fetch(): any[]; + forEach(callback: Function, thisArg?: any): void; + map(callback: Function, thisArg?: any): void; + observe(callbacks: Object): Meteor.LiveQueryHandle; + observeChanges(callbacks: Object): Meteor.LiveQueryHandle; + } +} + +declare module Random { + function id(): string; +} + +declare module Tracker { + function autorun(runFunc: Function): Tracker.Computation; + function flush(): void; + function nonreactive(func: Function): void; + var active: boolean; + var currentComputation: Tracker.Computation; + function onInvalidate(callback: Function): void; + function afterFlush(callback: Function): void; +} + +declare module Tracker { + interface Computation { + stop(): void; + invalidate(): void; + onInvalidate(callback: Function): void; + stopped: boolean; + invalidated: boolean; + firstRun: boolean; + } +} + +declare module Tracker { + interface Dependency { + changed(): void; + depend(fromComputation?: Tracker.Computation): boolean; + hasDependents(): boolean; + } +} + +declare module Meteor { + interface Accounts extends Meteor.AccountsBase { + config(options: { + sendVerificationEmail?: Boolean; + forbidClientAccountCreation?: Boolean; + restrictCreationByEmailDomain?: any; // string or Function + loginExpirationInDays?: number; + oauthSecretKey?: string; + }): void; + ui: { + config(options: { + requestPermissions?: Object; + requestOfflineToken?: Object; + forceApprovalPrompt?: Boolean; + passwordSignupFields?: string; + }); /** TODO: add return value **/ + } + validateNewUser(func: Function): void; + onCreateUser(func: Function): void; + validateLoginAttempt(func: Function); /** TODO: add return value **/ + onLogin(func: Function); /** TODO: add return value **/ + onLoginFailure(func: Function); /** TODO: add return value **/ + createUser(options: { + username?: string; + email?: string; + password?: string; + profile?: Object; + }, callback?: Function): string; + changePassword(oldPassword: string, newPassword: string, callback?: Function): void; + forgotPassword(options: { + email?: string; + }, callback?: Function): void; + resetPassword(token: string, newPassword: string, callback?: Function): void; + setPassword(userId: string, newPassword: string): void; + verifyEmail(token: string, callback?: Function): void; + sendResetPasswordEmail(userId: string, email?: string): void; + sendEnrollmentEmail(userId: string, email?: string): void; + sendVerificationEmail(userId: string, email?: string): void; + emailTemplates: Meteor.EmailTemplates; + } +} + +declare module Meteor { + interface Match extends Meteor.MatchBase { + test(value: any, pattern: any): boolean; + } +} + +declare module Meteor { + interface Session { + set(key: string, value: any): void; + setDefault(key: string, value: any): void; + get(key: string): any; + equals(key: string, value: any): boolean; + } +} + +declare module HTTP { + function call(method: string, url, options?: { + content?: string; + data?: Object; + query?: string; + params?: Object; + auth?: string; + headers?: Object; + timeout?: number; + followRedirects?: Boolean; + }, asyncCallback?): HTTP.HTTPResponse; + function get(url, options?: { + }, asyncCallback?): HTTP.HTTPResponse; + function post(url, options?: { + }, asyncCallback?): HTTP.HTTPResponse; + function put(url, options?: { + }, asyncCallback?): HTTP.HTTPResponse; + function del(url, options?: { + }, asyncCallback?): HTTP.HTTPResponse; +} + +declare module Meteor { + interface Template { + rendered: Function; + created: Function; + destroyed: Function; + events(eventMap: {[id:string]: Function}): void; + helpers(helpers: Object): void; + findAll(selector: string); /** TODO: add return value **/ + $(selector: string); /** TODO: add return value **/ + find(selector?: string); /** TODO: add return value **/ + firstNode; /** TODO: add return value **/ + lastNode; /** TODO: add return value **/ + data; /** TODO: add return value **/ + autorun(runFunc: Function); /** TODO: add return value **/ + view; /** TODO: add return value **/ + registerHelper(name: string, func: Function); /** TODO: add return value **/ + body; /** TODO: add return value **/ + currentData(); /** TODO: add return value **/ + instance(); /** TODO: add return value **/ + parentData(numLevels: number); /** TODO: add return value **/ + } +} + +declare module Blaze { + function render(templateOrView: any, parentNode: Node, nextNode?: Node, parentView?: Blaze.View): Blaze.View; + function renderWithData(templateOrView: any, data: any, parentNode: Node, nextNode?: Node, parentView?: Blaze.View): Blaze.View; + function remove(renderedView: Blaze.View): void; + function With(data: any, contentFunc: Function); /** TODO: add return value **/ + function If(conditionFunc: Function, contentFunc: Function, elseFunc?: Function); /** TODO: add return value **/ + function Unless(conditionFunc: Function, contentFunc: Function, elseFunc?: Function); /** TODO: add return value **/ + function Each(argFunc: Function, contentFunc: Function, elseFunc?: Function); /** TODO: add return value **/ + function getData(elementOrView?: any); /** TODO: add return value **/ + var currentView; /** TODO: add return value **/ + function getView(element?: HTMLElement); /** TODO: add return value **/ + function toHTML(templateOrView: any): string; + function toHTMLWithData(templateOrView: any, data: any): string; + function View(name?: string, renderFunction?: Function): void; + function Template(viewName?: string, renderFunction?: Function): void; + function isTemplate(value: any): boolean; +} + +declare module Meteor { + interface ReactiveVar { + get(); /** TODO: add return value **/ + set(newValue: any); /** TODO: add return value **/ + } +} + +declare module Email { + function send(options: { + from?: string; + to?: any; // string or string[] + cc?: any; // string or string[] + bcc?: any; // string or string[] + replyTo?: any; // string or string[] + subject?: string; + text?: string; + html?: string; + headers?: Object; + }): void; +} + +declare module Assets { + function getText(assetPath: string, asyncCallback?: Function): string; + function getBinary(assetPath: string, asyncCallback?: Function): Meteor.EJSON; +} + +declare module Meteor { + interface Package { + describe(options: { + summary?: string; + version?: string; + name?: string; + git?: string; + }); /** TODO: add return value **/ + onUse(f: Function); /** TODO: add return value **/ + onTest(f: Function); /** TODO: add return value **/ + describe(options: { + }); /** TODO: add return value **/ + } +} + +declare module Meteor { + interface Api { + use(packageNameAndVersion?: string, architecture?: string, options?: { + weak?: Boolean; + unordered?: Boolean; + }); /** TODO: add return value **/ + versionsFrom(meteorversion: string); /** TODO: add return value **/ + imply(packagespecOrpackagespecs: any); /** TODO: add return value **/ + export(exportedObject: string, architecture?: string); /** TODO: add return value **/ + addFiles(filenameOrfilenames: any); /** TODO: add return value **/ + } +} + +declare var Template: Meteor.TemplateBase; +declare var Session: Meteor.Session; +declare var Accounts: Meteor.Accounts; +declare var Match: Meteor.Match; +declare var EJSON: Meteor.EJSON; +declare var Tinytest: Meteor.Tinytest;