From fe2be0ab49ec31cdd5ae482cf01fd3203bf1a1d3 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Mon, 27 Aug 2018 18:47:39 -0400 Subject: [PATCH] meteor: Set up a "generate-globals" script to automatically generate global typings from module typings. Fixes #15071 (as best we can without a massive breaking change). --- types/meteor/accounts-base.d.ts | 171 +--- types/meteor/blaze.d.ts | 109 --- types/meteor/browser-policy-common.d.ts | 36 - types/meteor/check.d.ts | 24 - types/meteor/ddp-rate-limiter.d.ts | 15 - types/meteor/ddp.d.ts | 39 - types/meteor/ejson.d.ts | 38 - types/meteor/email.d.ts | 35 - types/meteor/globals/README.md | 3 + types/meteor/globals/accounts-base.d.ts | 148 ++++ types/meteor/globals/blaze.d.ts | 107 +++ .../meteor/globals/browser-policy-common.d.ts | 34 + types/meteor/globals/check.d.ts | 22 + types/meteor/globals/ddp-rate-limiter.d.ts | 13 + types/meteor/globals/ddp.d.ts | 36 + types/meteor/globals/ejson.d.ts | 37 + types/meteor/globals/email.d.ts | 34 + types/meteor/globals/http.d.ts | 48 ++ types/meteor/globals/meteor.d.ts | 220 +++++ types/meteor/globals/mongo.d.ts | 234 ++++++ types/meteor/globals/random.d.ts | 13 + types/meteor/globals/reactive-var.d.ts | 8 + types/meteor/globals/session.d.ts | 9 + types/meteor/globals/templating.d.ts | 6 + types/meteor/globals/tiny-test.d.ts | 36 + types/meteor/globals/tools.d.ts | 102 +++ types/meteor/globals/tracker.d.ts | 37 + types/meteor/http.d.ts | 49 -- types/meteor/index.d.ts | 18 + types/meteor/meteor.d.ts | 227 ----- types/meteor/mongo.d.ts | 239 +----- types/meteor/random.d.ts | 14 - types/meteor/reactive-var.d.ts | 9 - types/meteor/scripts/generate-globals | 79 ++ types/meteor/session.d.ts | 11 - types/meteor/templating.d.ts | 8 - types/meteor/test/globals/README.md | 3 + types/meteor/test/globals/meteor-tests.ts | 785 ++++++++++++++++++ types/meteor/test/meteor-tests-module-only.ts | 8 + types/meteor/{ => test}/meteor-tests.ts | 11 +- types/meteor/tiny-test.d.ts | 38 - types/meteor/tools.d.ts | 105 --- types/meteor/tracker.d.ts | 39 - types/meteor/tsconfig.json | 24 +- 44 files changed, 2081 insertions(+), 1200 deletions(-) create mode 100644 types/meteor/globals/README.md create mode 100644 types/meteor/globals/accounts-base.d.ts create mode 100644 types/meteor/globals/blaze.d.ts create mode 100644 types/meteor/globals/browser-policy-common.d.ts create mode 100644 types/meteor/globals/check.d.ts create mode 100644 types/meteor/globals/ddp-rate-limiter.d.ts create mode 100644 types/meteor/globals/ddp.d.ts create mode 100644 types/meteor/globals/ejson.d.ts create mode 100644 types/meteor/globals/email.d.ts create mode 100644 types/meteor/globals/http.d.ts create mode 100644 types/meteor/globals/meteor.d.ts create mode 100644 types/meteor/globals/mongo.d.ts create mode 100644 types/meteor/globals/random.d.ts create mode 100644 types/meteor/globals/reactive-var.d.ts create mode 100644 types/meteor/globals/session.d.ts create mode 100644 types/meteor/globals/templating.d.ts create mode 100644 types/meteor/globals/tiny-test.d.ts create mode 100644 types/meteor/globals/tools.d.ts create mode 100644 types/meteor/globals/tracker.d.ts create mode 100755 types/meteor/scripts/generate-globals create mode 100644 types/meteor/test/globals/README.md create mode 100644 types/meteor/test/globals/meteor-tests.ts create mode 100644 types/meteor/test/meteor-tests-module-only.ts rename types/meteor/{ => test}/meteor-tests.ts (98%) diff --git a/types/meteor/accounts-base.d.ts b/types/meteor/accounts-base.d.ts index b4e78c1664..6e25e71b07 100644 --- a/types/meteor/accounts-base.d.ts +++ b/types/meteor/accounts-base.d.ts @@ -1,54 +1,3 @@ -interface URLS { - resetPassword: (token: string) => string; - verifyEmail: (token: string) => string; - enrollAccount: (token: string) => string; -} - -interface EmailFields { - from?: () => string; - subject?: (user: Meteor.User) => string; - text?: (user: Meteor.User, url: string) => string; - html?: (user: Meteor.User, url: string) => string; -} - -declare module Accounts { - var urls: URLS; - - function user(): Meteor.User; - - function userId(): string; - - function createUser(options: { - username?: string; - email?: string; - password?: string; - profile?: Object; - }, callback?: Function): string; - - function config(options: { - sendVerificationEmail?: boolean; - forbidClientAccountCreation?: boolean; - restrictCreationByEmailDomain?: string | Function; - loginExpirationInDays?: number; - oauthSecretKey?: string; - passwordResetTokenExpirationInDays?: number; - passwordEnrollTokenExpirationInDays?: number; - ambiguousErrorMessages?: boolean; - }): void; - - function onLogin(func: Function): { - stop: () => void - }; - - function onLoginFailure(func: Function): { - stop: () => void - }; - - function loginServicesConfigured(): boolean; - - function onPageLoadLogin(func: Function): void; -} - declare module "meteor/accounts-base" { interface URLS { resetPassword: (token: string) => string; @@ -56,6 +5,13 @@ declare module "meteor/accounts-base" { enrollAccount: (token: string) => string; } + interface EmailFields { + from?: () => string; + subject?: (user: Meteor.User) => string; + text?: (user: Meteor.User, url: string) => string; + html?: (user: Meteor.User, url: string) => string; + } + module Accounts { var urls: URLS; @@ -93,42 +49,7 @@ declare module "meteor/accounts-base" { function onPageLoadLogin(func: Function): void; } -} -declare module Accounts { - function changePassword(oldPassword: string, newPassword: string, callback?: Function): void; - - function forgotPassword(options: { - email?: string; - }, callback?: Function): void; - - function resetPassword(token: string, newPassword: string, callback?: Function): void; - - function verifyEmail(token: string, callback?: Function): void; - - function onEmailVerificationLink(callback: Function): void; - - function onEnrollmentLink(callback: Function): void; - - function onResetPasswordLink(callback: Function): void; - - function loggingIn(): boolean; - - function logout(callback?: Function): void; - - function logoutOtherClients(callback?: Function): void; - - var ui: { - config(options: { - requestPermissions?: Object; - requestOfflineToken?: Object; - forceApprovalPrompt?: Object; - passwordSignupFields?: string; - }): void; - }; -} - -declare module "meteor/accounts-base" { module Accounts { function changePassword(oldPassword: string, newPassword: string, callback?: Function): void; @@ -161,72 +82,6 @@ declare module "meteor/accounts-base" { }): void; }; } -} - -interface Header { - [id: string]: string; -} - -interface EmailTemplates { - from: string; - siteName: string; - headers?: Header; - resetPassword: EmailFields; - enrollAccount: EmailFields; - verifyEmail: EmailFields; -} - -declare module Accounts { - var emailTemplates: EmailTemplates; - - function addEmail(userId: string, newEmail: string, verified?: boolean): void; - - function removeEmail(userId: string, email: string): void; - - function onCreateUser(func: Function): void; - - function findUserByEmail(email: string): Object; - - function findUserByUsername(username: string): Object; - - function sendEnrollmentEmail(userId: string, email?: string): void; - - function sendResetPasswordEmail(userId: string, email?: string): void; - - function sendVerificationEmail(userId: string, email?: string): void; - - function setUsername(userId: string, newUsername: string): void; - - function setPassword(userId: string, newPassword: string, options?: { - logout?: Object; - }): void; - - function validateNewUser(func: Function): boolean; - - function validateLoginAttempt(func: Function): { - stop: () => void - }; - - function _hashPassword(password: string): { digest: string; algorithm: string; }; - - interface IValidateLoginAttemptCbOpts { - type: string; - allowed: boolean; - error: Meteor.Error; - user: Meteor.User; - connection: Meteor.Connection; - methodName: string; - methodArguments: any[]; - } -} - -declare module "meteor/accounts-base" { - interface EmailFields { - from?: () => string; - subject?: (user: Meteor.User) => string; - text?: (user: Meteor.User, url: string) => string; - html?: (user: Meteor.User, url: string) => string; - } interface Header { [id: string]: string; @@ -284,23 +139,11 @@ declare module "meteor/accounts-base" { methodArguments: any[]; } } -} -declare module Accounts { - function onLogout(func: Function): void; -} - -declare module "meteor/accounts-base" { module Accounts { function onLogout(func: Function): void; } -} -declare module Accounts { - function onLogout(func: (user: Meteor.User, connection: Meteor.Connection) => void): void; -} - -declare module "meteor/accounts-base" { module Accounts { function onLogout(func: (user: Meteor.User, connection: Meteor.Connection) => void): void; } diff --git a/types/meteor/blaze.d.ts b/types/meteor/blaze.d.ts index dbb562558d..bd3b3cf79e 100644 --- a/types/meteor/blaze.d.ts +++ b/types/meteor/blaze.d.ts @@ -1,112 +1,3 @@ - -declare module Blaze { - var View: ViewStatic; - - interface ViewStatic { - new (name?: string, renderFunction?: Function): View; - } - - interface View { - name: string; - parentView: View; - isCreated: boolean; - isRendered: boolean; - isDestroyed: boolean; - renderCount: number; - autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation; - onViewCreated(func: Function): void; - onViewReady(func: Function): void; - onViewDestroyed(func: Function): void; - firstNode(): Node; - lastNode(): Node; - template: Template; - templateInstance(): TemplateInstance; - } - var currentView: View; - - function isTemplate(value: any): boolean; - - interface HelpersMap { - [key: string]: Function; - } - - interface EventsMap { - [key: string]: Function; - } - - var Template: TemplateStatic; - - interface TemplateStatic { - new (viewName?: string, renderFunction?: Function): Template; - - registerHelper(name: string, func: Function): void; - instance(): TemplateInstance; - currentData(): any; - parentData(numLevels: number): any; - } - - interface Template { - viewName: string; - renderFunction: Function; - constructView(): View; - head: Template; - find(selector: string): HTMLElement; - findAll(selector: string): HTMLElement[]; - $: any; - onCreated(cb: Function): void; - onRendered(cb: Function): void; - onDestroyed(cb: Function): void; - created: Function; - rendered: Function; - destroyed: Function; - helpers(helpersMap: HelpersMap): void; - events(eventsMap: EventsMap): void; - } - - var TemplateInstance: TemplateInstanceStatic; - - interface TemplateInstanceStatic { - new (view: View): TemplateInstance; - } - - interface TemplateInstance { - $(selector: string): any; - autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation; - data: Object; - find(selector: string): HTMLElement; - findAll(selector: string): HTMLElement[]; - firstNode: Object; - lastNode: Object; - subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle; - subscriptionsReady(): boolean; - view: Object; - } - - function Each(argFunc: Function, contentFunc: Function, elseFunc?: Function): View; - - function Unless(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View; - - function If(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View; - - function Let(bindings: Function, contentFunc: Function): View; - - function With(data: Object | Function, contentFunc: Function): View; - - function getData(elementOrView?: HTMLElement | View): Object; - - function getView(element?: HTMLElement): View; - - function remove(renderedView: View): void; - - function render(templateOrView: Template | View, parentNode: Node, nextNode?: Node, parentView?: View): View; - - function renderWithData(templateOrView: Template | View, data: Object | Function, parentNode: Node, nextNode?: Node, parentView?: View): View; - - function toHTML(templateOrView: Template | View): string; - - function toHTMLWithData(templateOrView: Template | View, data: Object | Function): string; -} - declare module "meteor/blaze" { module Blaze { var View: ViewStatic; diff --git a/types/meteor/browser-policy-common.d.ts b/types/meteor/browser-policy-common.d.ts index 6d82eab683..4aa3810f45 100644 --- a/types/meteor/browser-policy-common.d.ts +++ b/types/meteor/browser-policy-common.d.ts @@ -1,39 +1,3 @@ - -declare module BrowserPolicy { - var framing: { - disallow(): void; - restrictToOrigin(origin: string): void; - allowAll(): void; - }; - - var content: { - allowEval(): void; - allowInlineStyles(): void; - allowInlineScripts(): void; - allowSameOriginForAll(): void; - allowDataUrlForAll(): void; - allowOriginForAll(origin: string): void; - allowImageOrigin(origin: string): void; - allowMediaOrigin(origin: string): void; - allowFontOrigin(origin: string): void; - allowStyleOrigin(origin: string): void; - allowScriptOrigin(origin: string): void; - allowFrameOrigin(origin: string): void; - allowContentTypeSniffing(): void; - allowAllContentOrigin(): void; - allowAllContentDataUrl(): void; - allowAllContentSameOrigin(): void; - - disallowAll(): void; - disallowInlineStyles(): void; - disallowEval(): void; - disallowInlineScripts(): void; - disallowFont(): void; - disallowObject(): void; - disallowAllContent(): void; - }; -} - declare module "meteor/browser-policy-common" { module BrowserPolicy { var framing: { diff --git a/types/meteor/check.d.ts b/types/meteor/check.d.ts index 57482cd3f5..065850fb4e 100644 --- a/types/meteor/check.d.ts +++ b/types/meteor/check.d.ts @@ -1,27 +1,3 @@ - -declare module Match { - var Any: any; - var String: any; - var Integer: any; - var Boolean: any; - var undefined: any; - var Object: any; - - function Maybe(pattern: any): boolean; - - function Optional(pattern: any): boolean; - - function ObjectIncluding(dico: any): boolean; - - function OneOf(...patterns: any[]): any; - - function Where(condition: any): any; - - function test(value: any, pattern: any): boolean; -} - -declare function check(value: any, pattern: any): void; - declare module "meteor/check" { module Match { var Any: any; diff --git a/types/meteor/ddp-rate-limiter.d.ts b/types/meteor/ddp-rate-limiter.d.ts index dc906f4ac1..86e47bf9ac 100644 --- a/types/meteor/ddp-rate-limiter.d.ts +++ b/types/meteor/ddp-rate-limiter.d.ts @@ -1,18 +1,3 @@ - -declare module DDPRateLimiter { - interface Matcher { - type?: string | ((type: string) => boolean); - name?: string | ((name: string) => boolean); - userId?: string | ((userId: string) => boolean); - connectionId?: string | ((connectionId: string) => boolean); - clientAddress?: string | ((clientAddress: string) => boolean); - } - - function addRule(matcher: Matcher, numRequests: number, timeInterval: number): string; - - function removeRule(ruleId: string): boolean; -} - declare module "meteor/ddp-rate-limiter" { module DDPRateLimiter { interface Matcher { diff --git a/types/meteor/ddp.d.ts b/types/meteor/ddp.d.ts index 083244d601..ea4ca4fc96 100644 --- a/types/meteor/ddp.d.ts +++ b/types/meteor/ddp.d.ts @@ -1,42 +1,3 @@ - - -declare module DDP { - interface DDPStatic { - subscribe(name: string, ...rest: any[]): Meteor.SubscriptionHandle; - call(method: string, ...parameters: any[]): void; - apply(method: string, ...parameters: any[]): void; - methods(IMeteorMethodsDictionary: any): any; - status(): DDPStatus; - reconnect(): void; - disconnect(): void; - onReconnect(): void; - } - - function _allSubscriptionsReady(): boolean; - - type Status = 'connected' | 'connecting' | 'failed' | 'waiting' | 'offline'; - - interface DDPStatus { - connected: boolean; - status: Status; - retryCount: number; - retryTime?: number; - reason?: string; - } - - function connect(url: string): DDPStatic; -} - -declare module DDPCommon { - interface MethodInvocation { - new (options: {}): MethodInvocation; - - unblock(): void; - - setUserId(userId: number): void; - } -} - declare module "meteor/ddp" { module DDP { interface DDPStatic { diff --git a/types/meteor/ejson.d.ts b/types/meteor/ejson.d.ts index aa5cd0f5f9..3c9f161097 100644 --- a/types/meteor/ejson.d.ts +++ b/types/meteor/ejson.d.ts @@ -1,41 +1,3 @@ -interface EJSONableCustomType { - clone?(): EJSONableCustomType; - equals?(other: Object): boolean; - toJSONValue(): JSONable; - typeName(): string; -} -interface EJSONable { - [key: string]: number | string | boolean | Object | number[] | string[] | Object[] | Date | Uint8Array | EJSONableCustomType | undefined | null; -} -interface JSONable { - [key: string]: number | string | boolean | Object | number[] | string[] | Object[] | undefined | null; -} -interface EJSON extends EJSONable { } - -declare module EJSON { - function addType(name: string, factory: (val: JSONable) => EJSONableCustomType): void; - - function clone(val: T): T; - - function equals(a: EJSON, b: EJSON, options?: { - keyOrderSensitive?: boolean; - }): boolean; - - function fromJSONValue(val: JSONable): any; - - function isBinary(x: Object): boolean; - var newBinary: any; - - function parse(str: string): EJSON; - - function stringify(val: EJSON, options?: { - indent?: boolean | number | string; - canonical?: boolean; - }): string; - - function toJSONValue(val: EJSON): JSONable; -} - declare module "meteor/ejson" { interface EJSONableCustomType { clone?(): EJSONableCustomType; diff --git a/types/meteor/email.d.ts b/types/meteor/email.d.ts index 0e0e81590d..464dbed8a9 100644 --- a/types/meteor/email.d.ts +++ b/types/meteor/email.d.ts @@ -1,38 +1,3 @@ -declare module Email { - function send(options: { - from?: string; - to?: string | string[]; - cc?: string | string[]; - bcc?: string | string[]; - replyTo?: string | string[]; - subject?: string; - text?: string; - html?: string; - headers?: Object; - attachments?: Object[]; - mailComposer?: MailComposer; - }): void; -} - -interface MailComposerOptions { - escapeSMTP: boolean; - encoding: string; - charset: string; - keepBcc: boolean; - forceEmbeddedImages: boolean; -} - -declare var MailComposer: MailComposerStatic; -interface MailComposerStatic { - new (options: MailComposerOptions): MailComposer; -} -interface MailComposer { - addHeader(name: string, value: string): void; - setMessageOption(from: string, to: string, body: string, html: string): void; - streamMessage(): void; - pipe(stream: any /** fs.WriteStream **/): void; -} - declare module "meteor/email" { module Email { function send(options: { diff --git a/types/meteor/globals/README.md b/types/meteor/globals/README.md new file mode 100644 index 0000000000..b9e3615b2b --- /dev/null +++ b/types/meteor/globals/README.md @@ -0,0 +1,3 @@ +This `globals/` directory is generated by `scripts/generate-globals`! To update +this directory, edit the corresponding files outside `globals/` and re-run +`scripts/generate-globals`. \ No newline at end of file diff --git a/types/meteor/globals/accounts-base.d.ts b/types/meteor/globals/accounts-base.d.ts new file mode 100644 index 0000000000..f7b914f734 --- /dev/null +++ b/types/meteor/globals/accounts-base.d.ts @@ -0,0 +1,148 @@ +declare interface URLS { + resetPassword: (token: string) => string; + verifyEmail: (token: string) => string; + enrollAccount: (token: string) => string; +} + +declare interface EmailFields { + from?: () => string; + subject?: (user: Meteor.User) => string; + text?: (user: Meteor.User, url: string) => string; + html?: (user: Meteor.User, url: string) => string; +} + +declare module Accounts { + var urls: URLS; + + function user(): Meteor.User; + + function userId(): string; + + function createUser(options: { + username?: string; + email?: string; + password?: string; + profile?: Object; + }, callback?: Function): string; + + function config(options: { + sendVerificationEmail?: boolean; + forbidClientAccountCreation?: boolean; + restrictCreationByEmailDomain?: string | Function; + loginExpirationInDays?: number; + oauthSecretKey?: string; + passwordResetTokenExpirationInDays?: number; + passwordEnrollTokenExpirationInDays?: number; + ambiguousErrorMessages?: boolean; + }): void; + + function onLogin(func: Function): { + stop: () => void + }; + + function onLoginFailure(func: Function): { + stop: () => void + }; + + function loginServicesConfigured(): boolean; + + function onPageLoadLogin(func: Function): void; +} + +declare module Accounts { + function changePassword(oldPassword: string, newPassword: string, callback?: Function): void; + + function forgotPassword(options: { + email?: string; + }, callback?: Function): void; + + function resetPassword(token: string, newPassword: string, callback?: Function): void; + + function verifyEmail(token: string, callback?: Function): void; + + function onEmailVerificationLink(callback: Function): void; + + function onEnrollmentLink(callback: Function): void; + + function onResetPasswordLink(callback: Function): void; + + function loggingIn(): boolean; + + function logout(callback?: Function): void; + + function logoutOtherClients(callback?: Function): void; + + var ui: { + config(options: { + requestPermissions?: Object; + requestOfflineToken?: Object; + forceApprovalPrompt?: Object; + passwordSignupFields?: string; + }): void; + }; +} + +declare interface Header { + [id: string]: string; +} + +declare interface EmailTemplates { + from: string; + siteName: string; + headers?: Header; + resetPassword: EmailFields; + enrollAccount: EmailFields; + verifyEmail: EmailFields; +} + +declare module Accounts { + var emailTemplates: EmailTemplates; + + function addEmail(userId: string, newEmail: string, verified?: boolean): void; + + function removeEmail(userId: string, email: string): void; + + function onCreateUser(func: Function): void; + + function findUserByEmail(email: string): Object; + + function findUserByUsername(username: string): Object; + + function sendEnrollmentEmail(userId: string, email?: string): void; + + function sendResetPasswordEmail(userId: string, email?: string): void; + + function sendVerificationEmail(userId: string, email?: string): void; + + function setUsername(userId: string, newUsername: string): void; + + function setPassword(userId: string, newPassword: string, options?: { + logout?: Object; + }): void; + + function validateNewUser(func: Function): boolean; + + function validateLoginAttempt(func: Function): { + stop: () => void + }; + + function _hashPassword(password: string): { digest: string; algorithm: string; }; + + interface IValidateLoginAttemptCbOpts { + type: string; + allowed: boolean; + error: Meteor.Error; + user: Meteor.User; + connection: Meteor.Connection; + methodName: string; + methodArguments: any[]; + } +} + +declare module Accounts { + function onLogout(func: Function): void; +} + +declare module Accounts { + function onLogout(func: (user: Meteor.User, connection: Meteor.Connection) => void): void; +} diff --git a/types/meteor/globals/blaze.d.ts b/types/meteor/globals/blaze.d.ts new file mode 100644 index 0000000000..2082382100 --- /dev/null +++ b/types/meteor/globals/blaze.d.ts @@ -0,0 +1,107 @@ +declare module Blaze { + var View: ViewStatic; + + interface ViewStatic { + new (name?: string, renderFunction?: Function): View; + } + + interface View { + name: string; + parentView: View; + isCreated: boolean; + isRendered: boolean; + isDestroyed: boolean; + renderCount: number; + autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation; + onViewCreated(func: Function): void; + onViewReady(func: Function): void; + onViewDestroyed(func: Function): void; + firstNode(): Node; + lastNode(): Node; + template: Template; + templateInstance(): TemplateInstance; + } + var currentView: View; + + function isTemplate(value: any): boolean; + + interface HelpersMap { + [key: string]: Function; + } + + interface EventsMap { + [key: string]: Function; + } + + var Template: TemplateStatic; + + interface TemplateStatic { + new (viewName?: string, renderFunction?: Function): Template; + + registerHelper(name: string, func: Function): void; + instance(): TemplateInstance; + currentData(): any; + parentData(numLevels: number): any; + } + + interface Template { + viewName: string; + renderFunction: Function; + constructView(): View; + head: Template; + find(selector: string): HTMLElement; + findAll(selector: string): HTMLElement[]; + $: any; + onCreated(cb: Function): void; + onRendered(cb: Function): void; + onDestroyed(cb: Function): void; + created: Function; + rendered: Function; + destroyed: Function; + helpers(helpersMap: HelpersMap): void; + events(eventsMap: EventsMap): void; + } + + var TemplateInstance: TemplateInstanceStatic; + + interface TemplateInstanceStatic { + new (view: View): TemplateInstance; + } + + interface TemplateInstance { + $(selector: string): any; + autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation; + data: Object; + find(selector: string): HTMLElement; + findAll(selector: string): HTMLElement[]; + firstNode: Object; + lastNode: Object; + subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle; + subscriptionsReady(): boolean; + view: Object; + } + + function Each(argFunc: Function, contentFunc: Function, elseFunc?: Function): View; + + function Unless(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View; + + function If(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View; + + function Let(bindings: Function, contentFunc: Function): View; + + function With(data: Object | Function, contentFunc: Function): View; + + function getData(elementOrView?: HTMLElement | View): Object; + + function getView(element?: HTMLElement): View; + + function remove(renderedView: View): void; + + function render(templateOrView: Template | View, parentNode: Node, nextNode?: Node, parentView?: View): View; + + function renderWithData(templateOrView: Template | View, data: Object | Function, parentNode: Node, nextNode?: Node, parentView?: View): View; + + function toHTML(templateOrView: Template | View): string; + + function toHTMLWithData(templateOrView: Template | View, data: Object | Function): string; +} diff --git a/types/meteor/globals/browser-policy-common.d.ts b/types/meteor/globals/browser-policy-common.d.ts new file mode 100644 index 0000000000..826065844f --- /dev/null +++ b/types/meteor/globals/browser-policy-common.d.ts @@ -0,0 +1,34 @@ +declare module BrowserPolicy { + var framing: { + disallow(): void; + restrictToOrigin(origin: string): void; + allowAll(): void; + }; + + var content: { + allowEval(): void; + allowInlineStyles(): void; + allowInlineScripts(): void; + allowSameOriginForAll(): void; + allowDataUrlForAll(): void; + allowOriginForAll(origin: string): void; + allowImageOrigin(origin: string): void; + allowMediaOrigin(origin: string): void; + allowFontOrigin(origin: string): void; + allowStyleOrigin(origin: string): void; + allowScriptOrigin(origin: string): void; + allowFrameOrigin(origin: string): void; + allowContentTypeSniffing(): void; + allowAllContentOrigin(): void; + allowAllContentDataUrl(): void; + allowAllContentSameOrigin(): void; + + disallowAll(): void; + disallowInlineStyles(): void; + disallowEval(): void; + disallowInlineScripts(): void; + disallowFont(): void; + disallowObject(): void; + disallowAllContent(): void; + }; +} diff --git a/types/meteor/globals/check.d.ts b/types/meteor/globals/check.d.ts new file mode 100644 index 0000000000..1b1ec39736 --- /dev/null +++ b/types/meteor/globals/check.d.ts @@ -0,0 +1,22 @@ +declare module Match { + var Any: any; + var String: any; + var Integer: any; + var Boolean: any; + var undefined: any; + var Object: any; + + function Maybe(pattern: any): boolean; + + function Optional(pattern: any): boolean; + + function ObjectIncluding(dico: any): boolean; + + function OneOf(...patterns: any[]): any; + + function Where(condition: any): any; + + function test(value: any, pattern: any): boolean; +} + +declare function check(value: any, pattern: any): void; diff --git a/types/meteor/globals/ddp-rate-limiter.d.ts b/types/meteor/globals/ddp-rate-limiter.d.ts new file mode 100644 index 0000000000..5093837eb1 --- /dev/null +++ b/types/meteor/globals/ddp-rate-limiter.d.ts @@ -0,0 +1,13 @@ +declare module DDPRateLimiter { + interface Matcher { + type?: string | ((type: string) => boolean); + name?: string | ((name: string) => boolean); + userId?: string | ((userId: string) => boolean); + connectionId?: string | ((connectionId: string) => boolean); + clientAddress?: string | ((clientAddress: string) => boolean); + } + + function addRule(matcher: Matcher, numRequests: number, timeInterval: number): string; + + function removeRule(ruleId: string): boolean; +} diff --git a/types/meteor/globals/ddp.d.ts b/types/meteor/globals/ddp.d.ts new file mode 100644 index 0000000000..2b92528391 --- /dev/null +++ b/types/meteor/globals/ddp.d.ts @@ -0,0 +1,36 @@ +declare module DDP { + interface DDPStatic { + subscribe(name: string, ...rest: any[]): Meteor.SubscriptionHandle; + call(method: string, ...parameters: any[]): void; + apply(method: string, ...parameters: any[]): void; + methods(IMeteorMethodsDictionary: any): any; + status(): DDPStatus; + reconnect(): void; + disconnect(): void; + onReconnect(): void; + } + + function _allSubscriptionsReady(): boolean; + + type Status = 'connected' | 'connecting' | 'failed' | 'waiting' | 'offline'; + + interface DDPStatus { + connected: boolean; + status: Status; + retryCount: number; + retryTime?: number; + reason?: string; + } + + function connect(url: string): DDPStatic; +} + +declare module DDPCommon { + interface MethodInvocation { + new (options: {}): MethodInvocation; + + unblock(): void; + + setUserId(userId: number): void; + } +} diff --git a/types/meteor/globals/ejson.d.ts b/types/meteor/globals/ejson.d.ts new file mode 100644 index 0000000000..3a85075c6b --- /dev/null +++ b/types/meteor/globals/ejson.d.ts @@ -0,0 +1,37 @@ +declare interface EJSONableCustomType { + clone?(): EJSONableCustomType; + equals?(other: Object): boolean; + toJSONValue(): JSONable; + typeName(): string; +} +declare interface EJSONable { + [key: string]: number | string | boolean | Object | number[] | string[] | Object[] | Date | Uint8Array | EJSONableCustomType | undefined | null; +} +declare interface JSONable { + [key: string]: number | string | boolean | Object | number[] | string[] | Object[] | undefined | null; +} +declare interface EJSON extends EJSONable { } + +declare module EJSON { + function addType(name: string, factory: (val: JSONable) => EJSONableCustomType): void; + + function clone(val: T): T; + + function equals(a: EJSON, b: EJSON, options?: { + keyOrderSensitive?: boolean; + }): boolean; + + function fromJSONValue(val: JSONable): any; + + function isBinary(x: Object): boolean; + var newBinary: any; + + function parse(str: string): EJSON; + + function stringify(val: EJSON, options?: { + indent?: boolean | number | string; + canonical?: boolean; + }): string; + + function toJSONValue(val: EJSON): JSONable; +} diff --git a/types/meteor/globals/email.d.ts b/types/meteor/globals/email.d.ts new file mode 100644 index 0000000000..f80528893b --- /dev/null +++ b/types/meteor/globals/email.d.ts @@ -0,0 +1,34 @@ +declare module Email { + function send(options: { + from?: string; + to?: string | string[]; + cc?: string | string[]; + bcc?: string | string[]; + replyTo?: string | string[]; + subject?: string; + text?: string; + html?: string; + headers?: Object; + attachments?: Object[]; + mailComposer?: MailComposer; + }): void; +} + +declare interface MailComposerOptions { + escapeSMTP: boolean; + encoding: string; + charset: string; + keepBcc: boolean; + forceEmbeddedImages: boolean; +} + +declare var MailComposer: MailComposerStatic; +declare interface MailComposerStatic { + new (options: MailComposerOptions): MailComposer; +} +declare interface MailComposer { + addHeader(name: string, value: string): void; + setMessageOption(from: string, to: string, body: string, html: string): void; + streamMessage(): void; + pipe(stream: any /** fs.WriteStream **/): void; +} diff --git a/types/meteor/globals/http.d.ts b/types/meteor/globals/http.d.ts new file mode 100644 index 0000000000..88a67fe790 --- /dev/null +++ b/types/meteor/globals/http.d.ts @@ -0,0 +1,48 @@ +declare module HTTP { + 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; + headers?: { + [id: string]: string + }; + content?: string; + data?: any; + } + + function call(method: string, url: string, options?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; + + function del(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; + + function get(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; + + function post(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; + + function put(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; + + function call(method: string, url: string, options?: { + content?: string; + data?: Object; + query?: string; + params?: Object; + auth?: string; + headers?: Object; + timeout?: number; + followRedirects?: boolean; + npmRequestOptions?: Object; + beforeSend?: Function; + }, asyncCallback?: Function): HTTP.HTTPResponse; +} diff --git a/types/meteor/globals/meteor.d.ts b/types/meteor/globals/meteor.d.ts new file mode 100644 index 0000000000..7a90b0611e --- /dev/null +++ b/types/meteor/globals/meteor.d.ts @@ -0,0 +1,220 @@ +declare module Meteor { + /** Global props **/ + var isClient: boolean; + var isCordova: boolean; + var isServer: boolean; + var isProduction: boolean; + var release: string; + /** Global props **/ + + /** Settings **/ + interface Settings { + public: { + [id: string]: any + }, [id: string]: any + } + var settings: Settings; + /** Settings **/ + + /** User **/ + interface UserEmail { + address: string; + verified: boolean; + } + interface User { + _id?: string; + username?: string; + emails?: UserEmail[]; + createdAt?: number; + profile?: any; + services?: any; + } + + function user(): User; + + function userId(): string; + var users: Mongo.Collection; + /** User **/ + + /** Error **/ + var Error: ErrorStatic; + interface ErrorStatic { + new (error: string | number, reason?: string, details?: string): Error; + } + interface Error { + error: string | number; + reason?: string; + details?: string; + } + /** Error **/ + + /** Method **/ + function methods(methods: Object): void; + + function call(name: string, ...args: any[]): any; + + function apply(name: string, args: EJSONable[], options?: { + wait?: boolean; + onResultReceived?: Function; + returnStubValue?: boolean; + throwStubExceptions?: boolean; + }, asyncCallback?: Function): any; + /** Method **/ + + /** Url **/ + function absoluteUrl(path?: string, options?: { + secure?: boolean; + replaceLocalhost?: boolean; + rootUrl?: string; + }): string; + /** Url **/ + + /** Timeout **/ + function setInterval(func: Function, delay: number): number; + + function setTimeout(func: Function, delay: number): number; + + function clearInterval(id: number): void; + + function clearTimeout(id: number): void; + + function defer(func: Function): void; + /** Timeout **/ + + /** utils **/ + function startup(func: Function): void; + + function wrapAsync(func: Function, context?: Object): any; + + function bindEnvironment(func: Function): any; + /** utils **/ + + /** Pub/Sub **/ + interface SubscriptionHandle { + stop(): void; + ready(): boolean; + } + interface LiveQueryHandle { + stop(): void; + } + /** Pub/Sub **/ +} + +declare module Meteor { + /** Login **/ + interface LoginWithExternalServiceOptions { + requestPermissions?: string[]; + requestOfflineToken?: Boolean; + forceApprovalPrompt?: Boolean; + loginUrlParameters?: Object; + redirectUrl?: string; + loginHint?: string; + loginStyle?: 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; + + function loggingIn(): boolean; + + function loginWith(options?: { + requestPermissions?: string[]; + requestOfflineToken?: boolean; + loginUrlParameters?: Object; + userEmail?: string; + loginStyle?: string; + redirectUrl?: string; + }, callback?: Function): void; + + function loginWithPassword(user: Object | string, password: string, callback?: Function): void; + + function loginWithToken(token: string, callback?: Function): void; + + function logout(callback?: Function): void; + + function logoutOtherClients(callback?: Function): void; + /** Login **/ + + /** Event **/ + interface Event { + type: string; + target: HTMLElement; + currentTarget: HTMLElement; + which: number; + stopPropagation(): void; + stopImmediatePropagation(): void; + preventDefault(): void; + isPropagationStopped(): boolean; + isImmediatePropagationStopped(): boolean; + isDefaultPrevented(): boolean; + } + interface EventHandlerFunction extends Function { + (event?: Meteor.Event, templateInstance?: Blaze.TemplateInstance): void; + } + interface EventMap { + [id: string]: Meteor.EventHandlerFunction; + } + /** Event **/ + + /** Connection **/ + function reconnect(): void; + + function disconnect(): void; + /** Connection **/ + + /** Status **/ + function status(): DDP.DDPStatus; + /** Status **/ + + /** Pub/Sub **/ + function subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle; + /** Pub/Sub **/ +} + +declare module Meteor { + /** Connection **/ + interface Connection { + id: string; + close: Function; + onClose: Function; + clientAddress: string; + httpHeaders: Object; + } + + function onConnection(callback: Function): void; + /** Connection **/ + + function publish(name: string, func: Function): void; + + function _debug(...args: any[]): void; +} + +declare interface Subscription { + added(collection: string, id: string, fields: Object): void; + changed(collection: string, id: string, fields: Object): void; + connection: Meteor.Connection; + error(error: Error): void; + onStop(func: Function): void; + ready(): void; + removed(collection: string, id: string): void; + stop(): void; + userId: string; +} + +declare module Meteor { + /** Global props **/ + var isDevelopment: boolean; + var isTest: boolean; + /** Global props **/ +} diff --git a/types/meteor/globals/mongo.d.ts b/types/meteor/globals/mongo.d.ts new file mode 100644 index 0000000000..108008febe --- /dev/null +++ b/types/meteor/globals/mongo.d.ts @@ -0,0 +1,234 @@ +declare module Mongo { + + type BsonType = 1 | "double" | + 2 | "string" | + 3 | "object" | + 4 | "array" | + 5 | "binData" | + 6 | "undefined" | + 7 | "objectId" | + 8 | "bool" | + 9 | "date" | + 10 | "null" | + 11 | "regex" | + 12 | "dbPointer" | + 13 | "javascript" | + 14 | "symbol" | + 15 | "javascriptWithScope" | + 16 | "int" | + 17 | "timestamp" | + 18 | "long" | + 19 | "decimal" | + -1 | "minKey" | + 127 | "maxKey" | "number" + + type FieldExpression = { + $eq?: T, + $gt?: T, + $gte?: T, + $lt?: T, + $lte?: T, + $in?: T[], + $nin?: T[], + $ne?: T, + $exists?: boolean, + $type?: BsonType[] | BsonType, + $not?: FieldExpression, + $expr?: FieldExpression, + $jsonSchema?: any, + $mod?: number[], + $regex?: RegExp | string, + $options?: string, + $text?: { $search: string, $language?: string, $caseSensitive?: boolean, $diacriticSensitive?: boolean }, + $where?: string | Function, + $geoIntersects?: any, + $geoWithin?: any, + $near?: any, + $nearSphere?: any, + $all?: T[], + $elemMatch?: T extends {} ? Query : FieldExpression, + $size?: number, + $bitsAllClear?: any, + $bitsAllSet?: any, + $bitsAnyClear?: any, + $bitsAnySet?: any, + $comment?: string + } + + type Flatten = T extends any[] ? T[0] : T + + type Query = { + [P in keyof T]?: Flatten | RegExp | FieldExpression> + } & { + $or?: Query[], + $and?: Query[], + $nor?: Query[] + } & Dictionary + + type QueryWithModifiers = { + $query: Query, + $comment?: string, + $explain?: any, + $hint?: any, + $maxScan?: any, + $max?: any, + $maxTimeMS?: any, + $min?: any, + $orderby?: any, + $returnKey?: any, + $showDiskLoc?: any, + $natural?: any + } + + type Selector = Query | QueryWithModifiers + + type Dictionary = { [key: string]: T } + type PartialMapTo = Partial> + type OnlyArrays = T extends any[] ? T : never; + type OnlyElementsOfArrays = T extends any[] ? Partial : never + type ElementsOf = { + [P in keyof T]?: OnlyElementsOfArrays + } + type PushModifier = { + [P in keyof T]?: + OnlyElementsOfArrays | + { $each?: T[P], $position?: number, $slice?: number, $sort?: 1 | -1 | Dictionary } + } + type ArraysOrEach = { + [P in keyof T]?: OnlyArrays | { $each: T[P] } + } + type CurrentDateModifier = { $type: "timestamp" | "date" } | true + type Modifier = T | { + $currentDate?: Partial> & Dictionary, + $inc?: PartialMapTo & Dictionary, + $min?: PartialMapTo & Dictionary, + $max?: PartialMapTo & Dictionary, + $mul?: PartialMapTo & Dictionary, + $rename?: PartialMapTo & Dictionary, + $set?: Partial & Dictionary, + $setOnInsert?: Partial & Dictionary, + $unset?: PartialMapTo & Dictionary, + $addToSet?: ArraysOrEach & Dictionary, + $push?: PushModifier & Dictionary, + $pull?: ElementsOf & Dictionary, + $pullAll?: Partial & Dictionary, + $pop?: PartialMapTo & Dictionary<1 | -1>, + } + + + interface SortSpecifier { } + interface FieldSpecifier { + [id: string]: Number; + } + + var Collection: CollectionStatic; + interface CollectionStatic { + new (name: string, options?: { + connection?: Object | null; + idGeneration?: string; + transform?: Function; + }): Collection; + } + interface Collection { + allow(options: { + insert?: (userId: string, doc: T) => boolean; + update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean; + remove?: (userId: string, doc: T) => boolean; + fetch?: string[]; + transform?: Function; + }): boolean; + deny(options: { + insert?: (userId: string, doc: T) => boolean; + update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean; + remove?: (userId: string, doc: T) => boolean; + fetch?: string[]; + transform?: Function; + }): boolean; + find(selector?: Selector | ObjectID | string, options?: { + sort?: SortSpecifier; + skip?: number; + limit?: number; + fields?: FieldSpecifier; + reactive?: boolean; + transform?: Function; + }): Cursor; + findOne(selector?: Selector | ObjectID | string, options?: { + sort?: SortSpecifier; + skip?: number; + fields?: FieldSpecifier; + reactive?: boolean; + transform?: Function; + }): T; + insert(doc: T, callback?: Function): string; + rawCollection(): any; + rawDatabase(): any; + remove(selector: Selector | ObjectID | string, callback?: Function): number; + update(selector: Selector | ObjectID | string, modifier: Modifier, options?: { + multi?: boolean; + upsert?: boolean; + }, callback?: Function): number; + upsert(selector: Selector | ObjectID | string, modifier: Modifier, options?: { + multi?: boolean; + }, callback?: Function): { + numberAffected?: number; insertedId?: string; + }; + _ensureIndex(keys: { + [key: string]: number | string + } | string, options?: { + [key: string]: any + }): void; + _dropIndex(keys: { + [key: string]: number | string + } | string): void; + } + + var Cursor: CursorStatic; + interface CursorStatic { + new (): Cursor; + } + interface ObserveCallbacks { + added?(document: Object): void; + addedAt?(document: Object, atIndex: number, before: Object): void; + changed?(newDocument: Object, oldDocument: Object): void; + changedAt?(newDocument: Object, oldDocument: Object, indexAt: number): void; + removed?(oldDocument: Object): void; + removedAt?(oldDocument: Object, atIndex: number): void; + movedTo?(document: Object, fromIndex: number, toIndex: number, before: Object): void; + } + interface ObserveChangesCallbacks { + added?(id: string, fields: Object): void; + addedBefore?(id: string, fields: Object, before: Object): void; + changed?(id: string, fields: Object): void; + movedBefore?(id: string, before: Object): void; + removed?(id: string): void; + } + interface Cursor { + count(applySkipLimit?: boolean): number; + fetch(): Array; + forEach(callback: (doc: T, index: number, cursor: Cursor) => void, thisArg?: any): void; + map(callback: (doc: T, index: number, cursor: Cursor) => U, thisArg?: any): Array; + observe(callbacks: ObserveCallbacks): Meteor.LiveQueryHandle; + observeChanges(callbacks: ObserveChangesCallbacks): Meteor.LiveQueryHandle; + } + + var ObjectID: ObjectIDStatic; + interface ObjectIDStatic { + new(hexString?: string): ObjectID; + } + interface ObjectID { + toHexString(): string; + equals(otherID: ObjectID): boolean; + } + + function setConnectionOptions(options: any): void; +} + +declare module Mongo { + interface AllowDenyOptions { + insert?: (userId: string, doc: any) => boolean; + update?: (userId: string, doc: any, fieldNames: string[], modifier: any) => boolean; + remove?: (userId: string, doc: any) => boolean; + fetch?: string[]; + transform?: Function; + } +} diff --git a/types/meteor/globals/random.d.ts b/types/meteor/globals/random.d.ts new file mode 100644 index 0000000000..db334d98c6 --- /dev/null +++ b/types/meteor/globals/random.d.ts @@ -0,0 +1,13 @@ +declare module Random { + function id(numberOfChars?: number): string; + + function secret(numberOfChars?: number): string; + + function fraction(): number; + // @param numberOfDigits, @returns a random hex string of the given length + function hexString(numberOfDigits: number): string; + // @param array, @return a random element in array + function choice(array: any[]): string; + // @param str, @return a random char in str + function choice(str: string): string; +} diff --git a/types/meteor/globals/reactive-var.d.ts b/types/meteor/globals/reactive-var.d.ts new file mode 100644 index 0000000000..5d322ad27b --- /dev/null +++ b/types/meteor/globals/reactive-var.d.ts @@ -0,0 +1,8 @@ +declare var ReactiveVar: ReactiveVarStatic; +declare interface ReactiveVarStatic { + new (initialValue: T, equalsFunc?: Function): ReactiveVar; +} +declare interface ReactiveVar { + get(): T; + set(newValue: T): void; +} diff --git a/types/meteor/globals/session.d.ts b/types/meteor/globals/session.d.ts new file mode 100644 index 0000000000..1e7c4f24f2 --- /dev/null +++ b/types/meteor/globals/session.d.ts @@ -0,0 +1,9 @@ +declare module Session { + function equals(key: string, value: string | number | boolean | any): boolean; + + function get(key: string): any; + + function set(key: string, value: EJSONable | any): void; + + function setDefault(key: string, value: EJSONable | any): void; +} diff --git a/types/meteor/globals/templating.d.ts b/types/meteor/globals/templating.d.ts new file mode 100644 index 0000000000..5962fb9a71 --- /dev/null +++ b/types/meteor/globals/templating.d.ts @@ -0,0 +1,6 @@ +declare var Template: TemplateStatic; +declare interface TemplateStatic extends Blaze.TemplateStatic { + new (viewName?: string, renderFunction?: Function): Blaze.Template; + body: Blaze.Template; + [index: string]: any | Blaze.Template; +} diff --git a/types/meteor/globals/tiny-test.d.ts b/types/meteor/globals/tiny-test.d.ts new file mode 100644 index 0000000000..1289d87d23 --- /dev/null +++ b/types/meteor/globals/tiny-test.d.ts @@ -0,0 +1,36 @@ +declare interface ILengthAble { + length: number; +} + +declare interface ITinytestAssertions { + ok(doc: Object): void; + expect_fail(): void; + fail(doc: Object): void; + runId(): string; + equal(actual: T, expected: T, message?: string, not?: boolean): void; + notEqual(actual: T, expected: T, message?: string): void; + instanceOf(obj: Object, klass: Function, message?: string): void; + notInstanceOf(obj: Object, klass: Function, message?: string): void; + matches(actual: any, regexp: RegExp, message?: string): void; + notMatches(actual: any, regexp: RegExp, message?: string): void; + throws(f: Function, expected?: string | RegExp): void; + isTrue(v: boolean, msg?: string): void; + isFalse(v: boolean, msg?: string): void; + isNull(v: any, msg?: string): void; + isNotNull(v: any, msg?: string): void; + isUndefined(v: any, msg?: string): void; + isNotUndefined(v: any, msg?: string): void; + isNan(v: any, msg?: string): void; + isNotNan(v: any, msg?: string): void; + include(s: Array | Object | string, value: any, msg?: string, not?: boolean): void; + + notInclude(s: Array | Object | string, value: any, msg?: string, not?: boolean): void; + length(obj: ILengthAble, expected_length: number, msg?: string): void; + _stringEqual(actual: string, expected: string, msg?: string): void; +} + +declare module Tinytest { + function add(description: string, func: (test: ITinytestAssertions) => void): void; + + function addAsync(description: string, func: (test: ITinytestAssertions) => void): void; +} diff --git a/types/meteor/globals/tools.d.ts b/types/meteor/globals/tools.d.ts new file mode 100644 index 0000000000..ecba67f06b --- /dev/null +++ b/types/meteor/globals/tools.d.ts @@ -0,0 +1,102 @@ +declare module App { + function accessRule(pattern: string, options?: { + type?: string; + launchExternal?: boolean; + }): void; + + function configurePlugin(id: string, config: Object): void; + + function icons(icons: Object): void; + + function info(options: { + id?: string; + version?: string; + name?: string; + description?: string; + author?: string; + email?: string; + website?: string; + }): void; + + function launchScreens(launchScreens: Object): void; + + function setPreference(name: string, value: string, platform?: string): void; +} + +declare function execFileAsync(command: string, args?: any[], options?: { + cwd?: Object; + env?: Object; + stdio?: any[] | string; + destination?: any; + waitForClose?: string; +}): any; +declare function execFileSync(command: string, args?: any[], options?: { + cwd?: Object; + env?: Object; + stdio?: any[] | string; + destination?: any; + waitForClose?: string; +}): String; + +declare module Assets { + function getBinary(assetPath: string, asyncCallback?: Function): EJSON; + + function getText(assetPath: string, asyncCallback?: Function): string; + + function absoluteFilePath(assetPath: string): string; +} + +declare module Cordova { + function depends(dependencies: { + [id: string]: string + }): void; +} + +declare module Npm { + function depends(dependencies: { + [id: string]: string + }): void; + + function require(name: string): any; +} + +declare namespace Package { + function describe(options: { + summary?: string; + version?: string; + name?: string; + git?: string; + documentation?: string; + debugOnly?: boolean; + prodOnly?: boolean; + testOnly?: boolean; + }): void; + + function onTest(func: (api: PackageAPI) => void): void; + + function onUse(func: (api: PackageAPI) => void): void; + + function registerBuildPlugin(options?: { + name?: string; + use?: string | string[]; + sources?: string[]; + npmDependencies?: Object; + }): void; +} + +declare interface PackageAPI { + new (): PackageAPI; + addAssets(filenames: string | string[], architecture: string | string[]): void; + addFiles(filenames: string | string[], architecture?: string | string[], options?: { + bare?: boolean; + }): void; + export(exportedObjects: string | string[], architecture?: string | string[], exportOptions?: Object, testOnly?: boolean): void; + imply(packageNames: string | string[], architecture?: string | string[]): void; + use(packageNames: string | string[], architecture?: string | string[], options?: { + weak?: boolean; + unordered?: boolean; + }): void; + versionsFrom(meteorRelease: string | string[]): void; +} + +declare var console: Console; diff --git a/types/meteor/globals/tracker.d.ts b/types/meteor/globals/tracker.d.ts new file mode 100644 index 0000000000..15c1be408a --- /dev/null +++ b/types/meteor/globals/tracker.d.ts @@ -0,0 +1,37 @@ +declare module Tracker { + function Computation(): void; + interface Computation { + firstRun: boolean; + invalidate(): void; + invalidated: boolean; + onInvalidate(callback: Function): void; + onStop(callback: Function): void; + stop(): void; + stopped: boolean; + } + var currentComputation: Computation; + + var Dependency: DependencyStatic; + interface DependencyStatic { + new (): Dependency; + } + interface Dependency { + changed(): void; + depend(fromComputation?: Computation): boolean; + hasDependents(): boolean; + } + + var active: boolean; + + function afterFlush(callback: Function): void; + + function autorun(runFunc: (computation: Computation) => void, options?: { + onError?: Function; + }): Computation; + + function flush(): void; + + function nonreactive(func: Function): void; + + function onInvalidate(callback: Function): void; +} diff --git a/types/meteor/http.d.ts b/types/meteor/http.d.ts index 0d8bb6afa1..166a5cf96a 100644 --- a/types/meteor/http.d.ts +++ b/types/meteor/http.d.ts @@ -1,52 +1,3 @@ -declare module HTTP { - 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; - headers?: { - [id: string]: string - }; - content?: string; - data?: any; - } - - function call(method: string, url: string, options?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; - - function del(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; - - function get(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; - - function post(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; - - function put(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse; - - function call(method: string, url: string, options?: { - content?: string; - data?: Object; - query?: string; - params?: Object; - auth?: string; - headers?: Object; - timeout?: number; - followRedirects?: boolean; - npmRequestOptions?: Object; - beforeSend?: Function; - }, asyncCallback?: Function): HTTP.HTTPResponse; -} - declare module "meteor/http" { module HTTP { interface HTTPRequest { diff --git a/types/meteor/index.d.ts b/types/meteor/index.d.ts index f2fec81268..0822bab8e7 100644 --- a/types/meteor/index.d.ts +++ b/types/meteor/index.d.ts @@ -12,24 +12,42 @@ // TypeScript Version: 2.8 /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// +/// /// /// /// +/// /// +/// /// +/// /// +/// /// +/// /// /// diff --git a/types/meteor/meteor.d.ts b/types/meteor/meteor.d.ts index 07c1365459..ca08c31c98 100644 --- a/types/meteor/meteor.d.ts +++ b/types/meteor/meteor.d.ts @@ -1,105 +1,3 @@ -declare module Meteor { - /** Global props **/ - var isClient: boolean; - var isCordova: boolean; - var isServer: boolean; - var isProduction: boolean; - var release: string; - /** Global props **/ - - /** Settings **/ - interface Settings { - public: { - [id: string]: any - }, [id: string]: any - } - var settings: Settings; - /** Settings **/ - - /** User **/ - interface UserEmail { - address: string; - verified: boolean; - } - interface User { - _id?: string; - username?: string; - emails?: UserEmail[]; - createdAt?: number; - profile?: any; - services?: any; - } - - function user(): User; - - function userId(): string; - var users: Mongo.Collection; - /** User **/ - - /** Error **/ - var Error: ErrorStatic; - interface ErrorStatic { - new (error: string | number, reason?: string, details?: string): Error; - } - interface Error { - error: string | number; - reason?: string; - details?: string; - } - /** Error **/ - - /** Method **/ - function methods(methods: Object): void; - - function call(name: string, ...args: any[]): any; - - function apply(name: string, args: EJSONable[], options?: { - wait?: boolean; - onResultReceived?: Function; - returnStubValue?: boolean; - throwStubExceptions?: boolean; - }, asyncCallback?: Function): any; - /** Method **/ - - /** Url **/ - function absoluteUrl(path?: string, options?: { - secure?: boolean; - replaceLocalhost?: boolean; - rootUrl?: string; - }): string; - /** Url **/ - - /** Timeout **/ - function setInterval(func: Function, delay: number): number; - - function setTimeout(func: Function, delay: number): number; - - function clearInterval(id: number): void; - - function clearTimeout(id: number): void; - - function defer(func: Function): void; - /** Timeout **/ - - /** utils **/ - function startup(func: Function): void; - - function wrapAsync(func: Function, context?: Object): any; - - function bindEnvironment(func: Function): any; - /** utils **/ - - /** Pub/Sub **/ - interface SubscriptionHandle { - stop(): void; - ready(): boolean; - } - interface LiveQueryHandle { - stop(): void; - } - /** Pub/Sub **/ -} - declare module "meteor/meteor" { module Meteor { /** Global props **/ @@ -202,91 +100,7 @@ declare module "meteor/meteor" { } /** Pub/Sub **/ } -} -declare module Meteor { - /** Login **/ - interface LoginWithExternalServiceOptions { - requestPermissions?: string[]; - requestOfflineToken?: Boolean; - forceApprovalPrompt?: Boolean; - loginUrlParameters?: Object; - redirectUrl?: string; - loginHint?: string; - loginStyle?: 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; - - function loggingIn(): boolean; - - function loginWith(options?: { - requestPermissions?: string[]; - requestOfflineToken?: boolean; - loginUrlParameters?: Object; - userEmail?: string; - loginStyle?: string; - redirectUrl?: string; - }, callback?: Function): void; - - function loginWithPassword(user: Object | string, password: string, callback?: Function): void; - - function loginWithToken(token: string, callback?: Function): void; - - function logout(callback?: Function): void; - - function logoutOtherClients(callback?: Function): void; - /** Login **/ - - /** Event **/ - interface Event { - type: string; - target: HTMLElement; - currentTarget: HTMLElement; - which: number; - stopPropagation(): void; - stopImmediatePropagation(): void; - preventDefault(): void; - isPropagationStopped(): boolean; - isImmediatePropagationStopped(): boolean; - isDefaultPrevented(): boolean; - } - interface EventHandlerFunction extends Function { - (event?: Meteor.Event, templateInstance?: Blaze.TemplateInstance): void; - } - interface EventMap { - [id: string]: Meteor.EventHandlerFunction; - } - /** Event **/ - - /** Connection **/ - function reconnect(): void; - - function disconnect(): void; - /** Connection **/ - - /** Status **/ - function status(): DDP.DDPStatus; - /** Status **/ - - /** Pub/Sub **/ - function subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle; - /** Pub/Sub **/ -} - -declare module "meteor/meteor" { module Meteor { /** Login **/ interface LoginWithExternalServiceOptions { @@ -368,39 +182,7 @@ declare module "meteor/meteor" { function subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle; /** Pub/Sub **/ } -} -declare module Meteor { - /** Connection **/ - interface Connection { - id: string; - close: Function; - onClose: Function; - clientAddress: string; - httpHeaders: Object; - } - - function onConnection(callback: Function): void; - /** Connection **/ - - function publish(name: string, func: Function): void; - - function _debug(...args: any[]): void; -} - -interface Subscription { - added(collection: string, id: string, fields: Object): void; - changed(collection: string, id: string, fields: Object): void; - connection: Meteor.Connection; - error(error: Error): void; - onStop(func: Function): void; - ready(): void; - removed(collection: string, id: string): void; - stop(): void; - userId: string; -} - -declare module "meteor/meteor" { module Meteor { /** Connection **/ interface Connection { @@ -430,16 +212,7 @@ declare module "meteor/meteor" { stop(): void; userId: string; } -} -declare module Meteor { - /** Global props **/ - var isDevelopment: boolean; - var isTest: boolean; - /** Global props **/ -} - -declare module "meteor/meteor" { module Meteor { /** Global props **/ var isDevelopment: boolean; diff --git a/types/meteor/mongo.d.ts b/types/meteor/mongo.d.ts index 2de51c385b..ced791205b 100644 --- a/types/meteor/mongo.d.ts +++ b/types/meteor/mongo.d.ts @@ -1,230 +1,6 @@ -declare module Mongo { - - type BsonType = 1 | "double" | - 2 | "string" | - 3 | "object" | - 4 | "array" | - 5 | "binData" | - 6 | "undefined" | - 7 | "objectId" | - 8 | "bool" | - 9 | "date" | - 10 | "null" | - 11 | "regex" | - 12 | "dbPointer" | - 13 | "javascript" | - 14 | "symbol" | - 15 | "javascriptWithScope" | - 16 | "int" | - 17 | "timestamp" | - 18 | "long" | - 19 | "decimal" | - -1 | "minKey" | - 127 | "maxKey" | "number" - - type FieldExpression = { - $eq?: T, - $gt?: T, - $gte?: T, - $lt?: T, - $lte?: T, - $in?: T[], - $nin?: T[], - $ne?: T, - $exists?: boolean, - $type?: BsonType[] | BsonType, - $not?: FieldExpression, - $expr?: FieldExpression, - $jsonSchema?: any, - $mod?: number[], - $regex?: RegExp | string, - $options?: string, - $text?: { $search: string, $language?: string, $caseSensitive?: boolean, $diacriticSensitive?: boolean }, - $where?: string | Function, - $geoIntersects?: any, - $geoWithin?: any, - $near?: any, - $nearSphere?: any, - $all?: T[], - $elemMatch?: T extends {} ? Query : FieldExpression, - $size?: number, - $bitsAllClear?: any, - $bitsAllSet?: any, - $bitsAnyClear?: any, - $bitsAnySet?: any, - $comment?: string - } - - type Flatten = T extends any[] ? T[0] : T - - type Query = { - [P in keyof T]?: Flatten | RegExp | FieldExpression> - } & { - $or?: Query[], - $and?: Query[], - $nor?: Query[] - } & Dictionary - - type QueryWithModifiers = { - $query: Query, - $comment?: string, - $explain?: any, - $hint?: any, - $maxScan?: any, - $max?: any, - $maxTimeMS?: any, - $min?: any, - $orderby?: any, - $returnKey?: any, - $showDiskLoc?: any, - $natural?: any - } - - type Selector = Query | QueryWithModifiers - - type Dictionary = { [key: string]: T } - type PartialMapTo = Partial> - type OnlyArrays = T extends any[] ? T : never; - type OnlyElementsOfArrays = T extends any[] ? Partial : never - type ElementsOf = { - [P in keyof T]?: OnlyElementsOfArrays - } - type PushModifier = { - [P in keyof T]?: - OnlyElementsOfArrays | - { $each?: T[P], $position?: number, $slice?: number, $sort?: 1 | -1 | Dictionary } - } - type ArraysOrEach = { - [P in keyof T]?: OnlyArrays | { $each: T[P] } - } - type CurrentDateModifier = { $type: "timestamp" | "date" } | true - type Modifier = T | { - $currentDate?: Partial> & Dictionary, - $inc?: PartialMapTo & Dictionary, - $min?: PartialMapTo & Dictionary, - $max?: PartialMapTo & Dictionary, - $mul?: PartialMapTo & Dictionary, - $rename?: PartialMapTo & Dictionary, - $set?: Partial & Dictionary, - $setOnInsert?: Partial & Dictionary, - $unset?: PartialMapTo & Dictionary, - $addToSet?: ArraysOrEach & Dictionary, - $push?: PushModifier & Dictionary, - $pull?: ElementsOf & Dictionary, - $pullAll?: Partial & Dictionary, - $pop?: PartialMapTo & Dictionary<1 | -1>, - } - - - interface SortSpecifier { } - interface FieldSpecifier { - [id: string]: Number; - } - - var Collection: CollectionStatic; - interface CollectionStatic { - new (name: string, options?: { - connection?: Object | null; - idGeneration?: string; - transform?: Function; - }): Collection; - } - interface Collection { - allow(options: { - insert?: (userId: string, doc: T) => boolean; - update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean; - remove?: (userId: string, doc: T) => boolean; - fetch?: string[]; - transform?: Function; - }): boolean; - deny(options: { - insert?: (userId: string, doc: T) => boolean; - update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean; - remove?: (userId: string, doc: T) => boolean; - fetch?: string[]; - transform?: Function; - }): boolean; - find(selector?: Selector | ObjectID | string, options?: { - sort?: SortSpecifier; - skip?: number; - limit?: number; - fields?: FieldSpecifier; - reactive?: boolean; - transform?: Function; - }): Cursor; - findOne(selector?: Selector | ObjectID | string, options?: { - sort?: SortSpecifier; - skip?: number; - fields?: FieldSpecifier; - reactive?: boolean; - transform?: Function; - }): T; - insert(doc: T, callback?: Function): string; - rawCollection(): any; - rawDatabase(): any; - remove(selector: Selector | ObjectID | string, callback?: Function): number; - update(selector: Selector | ObjectID | string, modifier: Modifier, options?: { - multi?: boolean; - upsert?: boolean; - }, callback?: Function): number; - upsert(selector: Selector | ObjectID | string, modifier: Modifier, options?: { - multi?: boolean; - }, callback?: Function): { - numberAffected?: number; insertedId?: string; - }; - _ensureIndex(keys: { - [key: string]: number | string - } | string, options?: { - [key: string]: any - }): void; - _dropIndex(keys: { - [key: string]: number | string - } | string): void; - } - - var Cursor: CursorStatic; - interface CursorStatic { - new (): Cursor; - } - interface ObserveCallbacks { - added?(document: Object): void; - addedAt?(document: Object, atIndex: number, before: Object): void; - changed?(newDocument: Object, oldDocument: Object): void; - changedAt?(newDocument: Object, oldDocument: Object, indexAt: number): void; - removed?(oldDocument: Object): void; - removedAt?(oldDocument: Object, atIndex: number): void; - movedTo?(document: Object, fromIndex: number, toIndex: number, before: Object): void; - } - interface ObserveChangesCallbacks { - added?(id: string, fields: Object): void; - addedBefore?(id: string, fields: Object, before: Object): void; - changed?(id: string, fields: Object): void; - movedBefore?(id: string, before: Object): void; - removed?(id: string): void; - } - interface Cursor { - count(applySkipLimit?: boolean): number; - fetch(): Array; - forEach(callback: (doc: T, index: number, cursor: Cursor) => void, thisArg?: any): void; - map(callback: (doc: T, index: number, cursor: Cursor) => U, thisArg?: any): Array; - observe(callbacks: ObserveCallbacks): Meteor.LiveQueryHandle; - observeChanges(callbacks: ObserveChangesCallbacks): Meteor.LiveQueryHandle; - } - - var ObjectID: ObjectIDStatic; - interface ObjectIDStatic { - new(hexString?: string): ObjectID; - } - interface ObjectID { - toHexString(): string; - equals(otherID: ObjectID): boolean; - } - - function setConnectionOptions(options: any): void; -} - declare module "meteor/mongo" { module Mongo { + type BsonType = 1 | "double" | 2 | "string" | 3 | "object" | @@ -340,6 +116,7 @@ declare module "meteor/mongo" { $pop?: PartialMapTo & Dictionary<1 | -1>, } + interface SortSpecifier { } interface FieldSpecifier { [id: string]: Number; @@ -446,19 +223,7 @@ declare module "meteor/mongo" { function setConnectionOptions(options: any): void; } -} -declare module Mongo { - interface AllowDenyOptions { - insert?: (userId: string, doc: any) => boolean; - update?: (userId: string, doc: any, fieldNames: string[], modifier: any) => boolean; - remove?: (userId: string, doc: any) => boolean; - fetch?: string[]; - transform?: Function; - } -} - -declare module "meteor/mongo" { module Mongo { interface AllowDenyOptions { insert?: (userId: string, doc: any) => boolean; diff --git a/types/meteor/random.d.ts b/types/meteor/random.d.ts index 6a0232088f..775616396e 100644 --- a/types/meteor/random.d.ts +++ b/types/meteor/random.d.ts @@ -1,17 +1,3 @@ -declare module Random { - function id(numberOfChars?: number): string; - - function secret(numberOfChars?: number): string; - - function fraction(): number; - // @param numberOfDigits, @returns a random hex string of the given length - function hexString(numberOfDigits: number): string; - // @param array, @return a random element in array - function choice(array: any[]): string; - // @param str, @return a random char in str - function choice(str: string): string; -} - declare module "meteor/random" { module Random { function id(numberOfChars?: number): string; diff --git a/types/meteor/reactive-var.d.ts b/types/meteor/reactive-var.d.ts index 8426433b7f..ec399d598f 100644 --- a/types/meteor/reactive-var.d.ts +++ b/types/meteor/reactive-var.d.ts @@ -1,12 +1,3 @@ -declare var ReactiveVar: ReactiveVarStatic; -interface ReactiveVarStatic { - new (initialValue: T, equalsFunc?: Function): ReactiveVar; -} -interface ReactiveVar { - get(): T; - set(newValue: T): void; -} - declare module "meteor/reactive-var" { var ReactiveVar: ReactiveVarStatic; interface ReactiveVarStatic { diff --git a/types/meteor/scripts/generate-globals b/types/meteor/scripts/generate-globals new file mode 100755 index 0000000000..3c5f8fc781 --- /dev/null +++ b/types/meteor/scripts/generate-globals @@ -0,0 +1,79 @@ +#!/usr/bin/env node + +/* +For a Meteor package that is exposed as both a global and an ES6 module, we +unfortunately need to provide two copies of the typings for compatibility with +existing code that expects to augment and use either the global or the ES6 +module. We maintain the module typings by hand and use this script to generate +the global typings in the `globals/` subdirectory. Not every package is exposed +globally; `generate-globals` reads `tsconfig.json` to get the list of expected +files in `globals/`. Similarly, we maintain `meteor-tests.ts` (which tests the +the modules that also have globals) by hand, and this script generates +`globals/meteor-tests.ts` (which tests the globals). + +Usage: scripts/generate-globals + +This script may be used by Meteor typings packages in DefinitelyTyped other than +`meteor` itself. + +Inspired by prior art (but not believed to constitute a derivative work): +https://github.com/meteor-typings/meteor/blob/09ef92da99549ac090603ce70cfa632db4fad6e7/gulpfile.js#L43 +*/ + +// @ts-check + +// We are relying on the following modules to be transitive dependencies of +// DefinitelyTyped and npm 5 to install them in a place visible to us. :/ +let ts = require("typescript"); +let path = require("path"); +let os = require("os"); +let fs = require("fs"); +let mkdirp = require("mkdirp"); +let rimraf = require("rimraf"); + +function formatDiagnostic(diag) { + return ts.flattenDiagnosticMessageText(diag.messageText, os.EOL); +} + +let rcfResult = ts.readConfigFile("tsconfig.json", (path) => { + try { + return fs.readFileSync(path, "UTF-8"); + } catch (e) { + return undefined; + } +}); +let configObject = rcfResult.config; +if (!configObject) { + throw new Error(formatDiagnostic(rcfResult.error)); +} +rimraf.sync("globals"); +rimraf.sync("test/globals"); +let readmeText = `This \`globals/\` directory is generated by \`scripts/generate-globals\`! To update +this directory, edit the corresponding files outside \`globals/\` and re-run +\`scripts/generate-globals\`.`.replace("\n", os.EOL); +mkdirp.sync("globals"); +fs.writeFileSync("globals/README.md", readmeText, "UTF-8"); +mkdirp.sync("test/globals"); +fs.writeFileSync("test/globals/README.md", readmeText, "UTF-8"); +for (let outFile of configObject.files) { + let m = /^(test\/)?globals\/(.*)$/.exec(outFile); + if (m) { + let inFile = (m[1] || "") + m[2]; + let inLines = fs.readFileSync(inFile, "UTF-8").split(os.EOL); + let isTest = !!m[1]; + let outLines = inLines.map((l) => { + if (/^import /.test(l)) return null; + if (isTest) { + return l; + } else { + let m2; + if ((m2 = /^ ([^} ].*)$/.exec(l)) != null) return "declare " + m2[1]; + if ((m2 = /^ (.*)$/.exec(l)) != null) return m2[1]; + if (l == "") return l; + return null; // Strip `declare module "..." {` and `}`. + } + }).filter((l) => l != null); + mkdirp.sync(path.dirname(outFile)); + fs.writeFileSync(outFile, outLines.join(os.EOL), "UTF-8"); + } +} diff --git a/types/meteor/session.d.ts b/types/meteor/session.d.ts index 3dad5e682c..221e0e379e 100644 --- a/types/meteor/session.d.ts +++ b/types/meteor/session.d.ts @@ -1,14 +1,3 @@ - -declare module Session { - function equals(key: string, value: string | number | boolean | any): boolean; - - function get(key: string): any; - - function set(key: string, value: EJSONable | any): void; - - function setDefault(key: string, value: EJSONable | any): void; -} - declare module "meteor/session" { module Session { function equals(key: string, value: string | number | boolean | any): boolean; diff --git a/types/meteor/templating.d.ts b/types/meteor/templating.d.ts index e3b05109fb..0d8da7e899 100644 --- a/types/meteor/templating.d.ts +++ b/types/meteor/templating.d.ts @@ -1,11 +1,3 @@ - -declare var Template: TemplateStatic; -interface TemplateStatic extends Blaze.TemplateStatic { - new (viewName?: string, renderFunction?: Function): Blaze.Template; - body: Blaze.Template; - [index: string]: any | Blaze.Template; -} - declare module "meteor/templating" { var Template: TemplateStatic; interface TemplateStatic extends Blaze.TemplateStatic { diff --git a/types/meteor/test/globals/README.md b/types/meteor/test/globals/README.md new file mode 100644 index 0000000000..b9e3615b2b --- /dev/null +++ b/types/meteor/test/globals/README.md @@ -0,0 +1,3 @@ +This `globals/` directory is generated by `scripts/generate-globals`! To update +this directory, edit the corresponding files outside `globals/` and re-run +`scripts/generate-globals`. \ No newline at end of file diff --git a/types/meteor/test/globals/meteor-tests.ts b/types/meteor/test/globals/meteor-tests.ts new file mode 100644 index 0000000000..c2145be0a6 --- /dev/null +++ b/types/meteor/test/globals/meteor-tests.ts @@ -0,0 +1,785 @@ +// This file may use only modules that have corresponding globals, because +// `globals/meteor-tests.ts` is generated from it. Tests that involve modules +// that don't have corresponding globals belong in +// `meteor-tests-module-only.ts`. + +/** + * All code below was copied from the examples at http://docs.meteor.com/. + * When necessary, code was added to make the examples work (e.g. declaring a variable + * that was assumed to have been declared earlier) + */ + +/*********************************** Begin setup for tests ******************************/ + +// Avoid conflicts between `meteor-tests.ts` and `globals/meteor-tests.ts`. +namespace MeteorTests { + +var Rooms = new Mongo.Collection('rooms'); +var Messages = new Mongo.Collection('messages'); +interface MonkeyDAO { + _id: string; + name: string; +} +var Monkeys = new Mongo.Collection('monkeys'); +//var x = new Mongo.Collection('x'); +//var y = new Mongo.Collection('y'); +/********************************** End setup for tests *********************************/ + + +/** + * From Core, Meteor.startup section + * Tests Meteor.isServer, Meteor.startup, Collection.insert(), Collection.find() + */ +if (Meteor.isServer) { + Meteor.startup(function () { + if (Rooms.find().count() === 0) { + Rooms.insert({ name: "Initial room" }); + } + }); +} + +/** + * From Publish and Subscribe, Meteor.publish section + **/ +Meteor.publish("rooms", function () { + return Rooms.find({}, { fields: { secretInfo: 0 } }); +}); + +Meteor.publish("adminSecretInfo", function () { + return Rooms.find({ admin: this.userId }, { fields: { secretInfo: 1 } }); +}); + +Meteor.publish("roomAndMessages", function (roomId: string) { + check(roomId, String); + return [ + Rooms.find({ _id: roomId }, { fields: { secretInfo: 0 } }), + Messages.find({ roomId: roomId }) + ]; +}); + +/** + * Also from Publish and Subscribe, Meteor.publish section + */ +Meteor.publish("counts-by-room", function (roomId: string) { + var self = this; + check(roomId, String); + var count = 0; + var initializing = true; + var handle = Messages.find({ roomId: roomId }).observeChanges({ + added: function (id: any) { + count++; + // if (!initializing) + // this.changed("counts", roomId, {count: count}); + }, + removed: function (id: any) { + count--; + // Todo: Not sure how to define in typescript + // self.changed("counts", roomId, {count: count}); + } + }); + + initializing = false; + + // Todo: Not sure how to define in typescript + // self.added("counts", roomId, {count: count}); + self.ready(); + + self.onStop(function () { + handle.stop(); + }); +}); + +var Counts = new Mongo.Collection("counts"); + +Tracker.autorun(function () { + Meteor.subscribe("counts-by-room", Session.get("roomId")); +}); + +// Checking status +let status: DDP.Status = 'connected'; + +console.log("Current room has " + + Counts.find(Session.get("roomId")).count + + " messages."); + +/** + * From Publish and Subscribe, Meteor.subscribe section + */ +Meteor.subscribe("allplayers"); + +/** + * Also from Meteor.subscribe section + */ +Tracker.autorun(function () { + Meteor.subscribe("chat", { room: Session.get("current-room") }); + Meteor.subscribe("privateMessages"); +}); + +/** + * From Methods, Meteor.methods section + */ +Meteor.methods({ + foo: function (arg1: string, arg2: number[]) { + check(arg1, String); + check(arg2, [Number]); + + var you_want_to_throw_an_error = true; + if (you_want_to_throw_an_error) + throw new Meteor.Error("404", "Can't find my pants"); + return "some return value"; + }, + + bar: function () { + // .. do other stuff .. + return "baz"; + } +}); + +/** + * From Methods, Meteor.Error section + */ +function meteorErrorTestFunction1() { + throw new Meteor.Error("logged-out", + "The user must be logged in to post a comment."); +} + +function meteorErrorTestFunction2() { + throw new Meteor.Error(403, + "The user must be logged in to post a comment."); +} + +Meteor.call("methodName", function (error: Meteor.Error) { + if (error.error === "logged-out") { + Session.set("errorMessage", "Please log in to post a comment."); + } +}); +var error = new Meteor.Error("logged-out", "The user must be logged in to post a comment."); +console.log(error.error === "logged-out"); +console.log(error.reason === "The user must be logged in to post a comment."); +console.log(error.details !== ""); + +/** + * From Methods, Meteor.call section + */ +Meteor.call('foo', 1, 2, function (error: any, result: any) { }); +var result = Meteor.call('foo', 1, 2); + +/** + * From Collections, Mongo.Collection section + */ +// DA: I added the "var" keyword in there + +interface ChatroomsDAO { + _id?: string; +} +interface MessagesDAO { + _id?: string; +} +var Chatrooms = new Mongo.Collection("chatrooms"); +Messages = new Mongo.Collection("messages"); + +var myMessages: any[] = Messages.find({ userId: Session.get('myUserId') }).fetch(); + +Messages.insert({ text: "Hello, world!" }); + +Messages.update(myMessages[0]._id, { $set: { important: true } }); + +var Posts = new Mongo.Collection("posts"); +Posts.insert({ title: "Hello world", body: "First post" }); + +// Couldn't find assert() in the meteor docs +//assert(Posts.find().count() === 1); + +/** + * 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 Mongo.Collection; + for (var i = 0; i < 10; i++) + Scratchpad.insert({number: i * 2}); + assert(Scratchpad.find({number: {$lt: 9}}).count() === 5); + **/ + +class Animal { + constructor(doc: any) {} +} + +interface AnimalDAO { + _id?: string; + name: string; + sound: string; + makeNoise?: () => void; +} + +// Define a Collection that uses Animal as its document +var Animals = new Mongo.Collection("Animals", { + transform: function (doc: any): Animal { return new Animal(doc); } +}); + +// Create an Animal and call its makeNoise method +Animals.insert({ name: "raptor", sound: "roar" }); +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 Mongo.Collection('Lists'); +var Items = new Mongo.Collection('Lists'); + +var groceriesId = Lists.insert({ name: "Groceries" }); +Items.insert({ list: groceriesId, name: "Watercress" }); +Items.insert({ list: groceriesId, name: "Persimmons" }); + +/** + * From Collections, collection.update section + */ +var Players = new Mongo.Collection('Players'); + +Template['adminDashboard'].events({ + 'click .givePoints': function () { + Players.update(Session.get("currentPlayer"), { $inc: { score: 5 } }); + } +}); + +/** + * Also from Collections, collection.update section + */ +Meteor.methods({ + declareWinners: function () { + Players.update({ score: { $gt: 10 } }, + { $addToSet: { badges: "Winner" } }, + { multi: true }); + } +}); + +/** + * From Collections, collection.remove section + */ +Template['chat'].events({ + 'click .remove': function () { + Messages.remove(this._id); + } +}); + +// DA: I added this next line +var Logs = new Mongo.Collection('logs'); + +Meteor.startup(function () { + if (Meteor.isServer) { + Logs.remove({}); + Players.remove({ karma: { $lt: -2 } }); + } +}); + +/*** + * From Collections, collection.allow section + */ + +interface iPost { + _id: string; + owner: string; + userId: string; + locked: boolean; +} + +Posts = new Mongo.Collection("posts"); + +Posts.allow({ + insert: function (userId: string, doc: iPost) { + // the user must be logged in, and the document must be owned by the user + return (userId && doc.owner === userId); + }, + update: function (userId: string, doc: iPost, fields: string[], modifier: any) { + // can only change your own documents + return doc.owner === userId; + }, + remove: function (userId: string, doc: iPost) { + // can only remove your own documents + return doc.owner === userId; + }, + fetch: ['owner'] +}); + +Posts.deny({ + update: function (userId: string, doc: iPost, fields: string[], modifier: any) { + // can't change owners + return doc.userId !== userId; + }, + remove: function (userId: string, doc: iPost) { + // can't remove locked documents + return doc.locked; + }, + fetch: ['locked'] // no need to fetch 'owner' +}); + +/** + * From Collections, cursor.forEach section + */ +var topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 }); +var count = 0; +topPosts.forEach(function (post: { title: string }) { + console.log("Title of post " + count + ": " + post.title); + count += 1; +}); + +/** + * From Collections, cursor.observeChanges section + */ +// DA: I added this line to make it work +var Users = new Mongo.Collection('users'); + +var count1 = 0; +var query = Users.find({ admin: true, onlineNow: true }); +var handle = query.observeChanges({ + added: function (id: string, user: { name: string }) { + count1++; + console.log(user.name + " brings the total to " + count1 + " admins."); + }, + removed: function () { + count1--; + console.log("Lost one. We're now down to " + count1 + " admins."); + } +}); + +let cursor: Mongo.Cursor; + +// After five seconds, stop keeping the count. +setTimeout(function () { handle.stop(); }, 5000); + +// Additional testing for Mongo.Collection +enum InlineObjectType { + Invalid, + Link, + Image, + Video, + Person +} +interface CommentsDAO { + text: string; + authorId: string; + inlineLinks: { objectType: InlineObjectType, objectId: string, objectUrl: string }[], + tags: string[], + viewNumber: number, + private: boolean +} + +var Comments = new Mongo.Collection("comments"); + +Comments.find({ text: { $regex: /test/ } }); +Comments.find({ viewNumber: { $gt: 100 } }); +Comments.find({ viewNumber: { $not: { $lt: 100, $gt: 1000 } } }); +Comments.find({ tags: { $in: [ "tag-1", "tag-2", "tag-3" ] } }); +Comments.find({ $or: [ { text: "hello" }, { text: "world" } ] }); +Comments.find({ $or: [ + { text: "hello" }, + { text: "world", viewNumber: { $gt: 0 } } +], authorId: "test-author-id" }); +Comments.find({ $and: [ + { $or: [{ authorId: "author-id-1" }, { authorId: "author-id-2" }] }, + { $or: [{ tags: "tag-1" }, { tags: "tag-2" }] } +]}); + +Comments.find({ inlineLinks: { $exists: true, $type: "array" } }); +Comments.find({ inlineLinks: { $elemMatch: { + objectType: InlineObjectType.Image, + objectUrl: { $regex: "https://(www\.?)youtube\.com" } +} } }); +Comments.find({ "inlineLinks.objectType": InlineObjectType.Person }); +Comments.find({ tags: "tag-1" }); +Comments.find({ tags: { $all: ["tag-1", "tag2"] } }); + +Comments.update({ viewNumber: { $exists: false } }, { $set: { viewNumber: 0 } }); +Comments.update({ authorId: "author-id-1" }, { $push: { tags: "test-tag-1" } }); +Comments.update({ authorId: "author-id-1" }, { $push: { tags: { $each: [ "test-tag-2", "test-tag-3" ] } } }); + +Comments.update({ authorId: "author-id-1" }, { $push: { inlineLinks: { + objectId: "test-object-id", + objectType: InlineObjectType.Link, + objectUrl: "https://test.url/" +} } }); +Comments.update({ viewNumber: { $exists: false } }, { $set: { viewNumber: 0 } }); +Comments.update({ private: true }, { $unset: { tags: true } }); + +/** + * From Sessions, Session.set section + */ +Tracker.autorun(function () { + Meteor.subscribe("chat-history", { room: Session.get("currentRoomId") }); +}); + +// 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 + */ +// Page will say "We've always been at war with Eastasia" + +// DA: commented out since transpiler didn't like append() +//document.body.append(frag1); + +// Page will change to say "We've always been at war with Eurasia" +Session.set("enemy", "Eurasia"); + +/** + * From Sessions, Session.equals section + */ +var value: string; +Session.get("key") === value; +Session.equals("key", value); + +/** + * From Accounts, Meteor.users section + */ +Meteor.publish("userData", function () { + return Meteor.users.find({ _id: this.userId }, + { fields: { 'other': 1, 'things': 1 } }); +}); + +Meteor.users.deny({ update: function () { return true; } }); + +/** + * From Accounts, Meteor.loginWithExternalService section + */ +Meteor.loginWithGithub({ + requestPermissions: ['user', 'public_repo'] +}, function (err: Meteor.Error) { + if (err) + Session.set('errorMessage', err.reason || 'Unknown error'); +}); + +/** + * From Accounts, Accounts.ui.config section + */ +Accounts.ui.config({ + requestPermissions: { + facebook: ['user_likes'], + github: ['user', 'repo'] + }, + requestOfflineToken: { + google: true + }, + passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL' +}); + +/** + * From Accounts, Accounts.validateNewUser section + */ +Accounts.validateNewUser(function (user: { username: string }) { + if (user.username && user.username.length >= 3) + return true; + throw new Meteor.Error("403", "Username must have at least 3 characters"); +}); +// Validate username, without a specific error message. +Accounts.validateNewUser(function (user: { username: string }) { + return user.username !== "root"; +}); + +/** + * From Accounts, Accounts.onCreateUser section + */ +Accounts.onCreateUser(function (options: { profile: any }, user: { profile: any, dexterity: number }) { + var d6 = function () { return Math.floor(Math.random() * 6) + 1; }; + user.dexterity = d6() + d6() + d6(); + // We still want the default hook's 'profile' behavior. + if (options.profile) + user.profile = options.profile; + return user; +}); + +/** + * From Passwords, Accounts.emailTemplates section + */ +Accounts.emailTemplates.siteName = "AwesomeSite"; +Accounts.emailTemplates.from = "AwesomeSite Admin "; +Accounts.emailTemplates.enrollAccount.subject = function (user: { profile: { name: string } }) { + return "Welcome to Awesome Town, " + user.profile.name; +}; +Accounts.emailTemplates.enrollAccount.text = function (user: any, url: string) { + return "You have been selected to participate in building a better future!" + + " To activate your account, simply click the link below:\n\n" + + url; +}; + +/** + * From Templates, Template.myTemplate.helpers section + */ +Template['adminDashboard'].helpers({ + foo: function () { + return Session.get("foo"); + } +}); + +Template['newTemplate'].helpers({ + helperName: function () { + } +}); + +Template['newTemplate'].created = function () { + +}; + +Template['newTemplate'].rendered = function () { + +}; + +Template['newTemplate'].destroyed = function () { + +}; + +Template['newTemplate'].events({ + 'click .something': function (event: Meteor.Event, template: Blaze.TemplateInstance) { + } +}); + +Template.registerHelper('testHelper', function () { + return 'tester'; +}); + +var instance = Template.instance(); +var data = Template.currentData(); +var data = Template.parentData(1); +var body = Template.body; + +/** + * From Match section + */ +var Chats = new Mongo.Collection('chats'); + +Meteor.publish("chats-in-room", function (roomId: string) { + // Make sure roomId is a string, not an arbitrary mongo selector object. + check(roomId, String); + return Chats.find({ room: roomId }); +}); + +Meteor.methods({ + addChat: function (roomId: string, message: { text: string, timestamp: Date, tags: string }) { + check(roomId, String); + check(message, { + text: String, + timestamp: Date, + // Optional, but if present must be an array of strings. + tags: Match.Optional('Test String') + }); + + // ... do something with the message ... + } +}); + +/** + * From Match patterns section + */ +var pat = { name: Match.Optional('test') }; +check({ name: "something" }, pat) // OK +check({}, pat) // OK +check({ name: undefined }, pat) // Throws an exception + +// Outside an object +check(undefined, Match.Optional('test')); // OK + +/** + * From Deps, Tracker.autorun section + */ +Tracker.autorun(function () { + var oldest = Monkeys.findOne('age = 20'); + + if (oldest) + Session.set("oldest", oldest.name); +}); + +Tracker.autorun(function (c) { + if (!Session.equals("shouldAlert", true)) + return; + + c.stop(); + alert("Oh no!"); +}); + +/** + * From Deps, Deps.Computation + */ +if (Tracker.active) { + Tracker.onInvalidate(function () { + console.log('invalidated'); + }); +} + +/** + * From Tracker, Tracker.Dependency + */ +var weather = "sunny"; +var weatherDep = new Tracker.Dependency; + +var getWeather = function () { + weatherDep.depend(); + return weather; +}; + +var setWeather = function (w: string) { + weather = w; + // (could add logic here to only call changed() + // if the new value is different from the old) + weatherDep.changed(); +}; + +/** + * From HTTP, HTTP.call section + */ +Meteor.methods({ + checkTwitter: function (userId: string) { + check(userId, String); + this.unblock(); + var result = HTTP.call("GET", "http://api.twitter.com/xyz", + { params: { user: userId } }); + if (result.statusCode === 200) + return true + return false; + } +}); + + +HTTP.call("POST", "http://api.twitter.com/xyz", + { data: { some: "json", stuff: 1 } }, + function (error: Meteor.Error, result: any) { + if (result.statusCode === 200) { + Session.set("twizzled", true); + } + }); + +/** + * From Email, Email.send section + */ +Meteor.methods({ + sendEmail: function (to: string, from: string, subject: string, text: string) { + check([to, from, subject, text], [String]); + + // Let other method calls from the same client start running, + // without waiting for the email sending to complete. + this.unblock(); + } +}); + +// In your client code: asynchronously send an email +Meteor.call('sendEmail', + 'alice@example.com', + 'Hello from Meteor!', + 'This is a test of Email.send.'); + +var testTemplate = new Blaze.Template('foo'); +var testView = new Blaze.View('foo'); +Blaze.Template.instance(); + +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 () { }); + +var reactiveVar1 = new ReactiveVar('test value'); +var reactiveVar2 = new ReactiveVar('test value', function (oldVal: any) { return true; }); + +var varValue: string = reactiveVar1.get(); +reactiveVar1.set('new value'); + +// Covers this PR: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/8233 +var isConfigured: boolean = Accounts.loginServicesConfigured(); +Accounts.onPageLoadLogin(function () { + // do something +}); + +// Covers this PR: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/8065 +var loginOpts = { + requestPermissions: ["a", "b"], + requestOfflineToken: true, + loginUrlParameters: { asdf: 1, qwer: "1234" }, + loginHint: "Help me", + loginStyle: "Bold and powerful", + redirectUrl: "popup", + profile: "asdfasdf" +}; +Meteor.loginWithMeteorDeveloperAccount(loginOpts, function (error: Meteor.Error) { }); + +Accounts.emailTemplates.siteName = "AwesomeSite"; +Accounts.emailTemplates.from = "AwesomeSite Admin "; +Accounts.emailTemplates.headers = { asdf: 'asdf', qwer: 'qwer' }; + +Accounts.emailTemplates.enrollAccount.subject = function (user: Meteor.User) { + return "Welcome to Awesome Town, " + user.profile.name; +}; +Accounts.emailTemplates.enrollAccount.html = function (user: Meteor.User, url: string) { + return "

Some html here

"; +}; +Accounts.emailTemplates.enrollAccount.from = function () { + return "asdf@asdf.com"; +}; +Accounts.emailTemplates.enrollAccount.text = function (user: Meteor.User, url: string) { + return "You have been selected to participate in building a better future!" + + " To activate your account, simply click the link below:\n\n" + + url; +}; + +var handle = Accounts.validateLoginAttempt(function (attemptInfoObject: Accounts.IValidateLoginAttemptCbOpts) { + var type: string = attemptInfoObject.type; + var allowed: boolean = attemptInfoObject.allowed; + var error: Meteor.Error = attemptInfoObject.error; + var user: Meteor.User = attemptInfoObject.user; + var connection: Meteor.Connection = attemptInfoObject.connection; + var methodName: string = attemptInfoObject.methodName; + var methodArguments: any[] = attemptInfoObject.methodArguments; + return true; +}); +handle.stop(); + + +// Covers https://github.com/meteor-typings/meteor/issues/8 +const publicSetting = Meteor.settings.public['somePublicSetting']; +const deeperPublicSetting = Meteor.settings.public['somePublicSetting']['deeperSetting']; +const privateSetting = Meteor.settings['somePrivateSetting']; +const deeperPrivateSetting = Meteor.settings['somePrivateSettings']['deeperSetting']; + + +// Covers https://github.com/meteor-typings/meteor/issues/9 +const username = (Template.instance().find('#username')).value; + + +// Covers https://github.com/meteor-typings/meteor/issues/3 +BrowserPolicy.framing.disallow(); +BrowserPolicy.content.allowEval(); + + +// Covers https://github.com/meteor-typings/meteor/issues/18 +if (Meteor.isDevelopment) { + Rooms._dropIndex({ field: 1 }); +} + + +// Covers https://github.com/meteor-typings/meteor/issues/20 +Rooms.find().count(true); + + +// Covers https://github.com/meteor-typings/meteor/issues/21 +if (Meteor.isTest) { + // do something +} + +DDPRateLimiter.addRule({ userId: 'foo' }, 5, 1000); + +DDPRateLimiter.addRule({ userId: userId => userId == 'foo' }, 5, 1000); + +Template.instance().autorun(() => { }).stop(); + +// Mongo Collection without connection (local collection) +const collectionWithoutConnection = new Mongo.Collection("monkey", { + connection: null +}); + +} // End of namespace diff --git a/types/meteor/test/meteor-tests-module-only.ts b/types/meteor/test/meteor-tests-module-only.ts new file mode 100644 index 0000000000..3591b90635 --- /dev/null +++ b/types/meteor/test/meteor-tests-module-only.ts @@ -0,0 +1,8 @@ +// This file is for tests that involve modules that don't have corresponding +// globals. + +import { onPageLoad } from "meteor/server-render"; +import { ServiceConfiguration } from "meteor/service-configuration"; +import { WebApp } from "meteor/webapp"; + +// We have no actual tests beyond the imports yet. diff --git a/types/meteor/meteor-tests.ts b/types/meteor/test/meteor-tests.ts similarity index 98% rename from types/meteor/meteor-tests.ts rename to types/meteor/test/meteor-tests.ts index a321e4a409..c7fde5b8be 100644 --- a/types/meteor/meteor-tests.ts +++ b/types/meteor/test/meteor-tests.ts @@ -1,10 +1,14 @@ +// This file may use only modules that have corresponding globals, because +// `globals/meteor-tests.ts` is generated from it. Tests that involve modules +// that don't have corresponding globals belong in +// `meteor-tests-module-only.ts`. + /** * All code below was copied from the examples at http://docs.meteor.com/. * When necessary, code was added to make the examples work (e.g. declaring a variable * that was assumed to have been declared earlier) */ - /*********************************** Begin setup for tests ******************************/ import { Mongo } from "meteor/mongo"; import { Meteor } from "meteor/meteor"; @@ -19,6 +23,9 @@ import { Accounts } from "meteor/accounts-base"; import { BrowserPolicy } from "meteor/browser-policy-common"; import { DDPRateLimiter } from "meteor/ddp-rate-limiter"; +// Avoid conflicts between `meteor-tests.ts` and `globals/meteor-tests.ts`. +namespace MeteorTests { + var Rooms = new Mongo.Collection('rooms'); var Messages = new Mongo.Collection('messages'); interface MonkeyDAO { @@ -786,3 +793,5 @@ Template.instance().autorun(() => { }).stop(); const collectionWithoutConnection = new Mongo.Collection("monkey", { connection: null }); + +} // End of namespace diff --git a/types/meteor/tiny-test.d.ts b/types/meteor/tiny-test.d.ts index 15e0939684..8d149e0711 100644 --- a/types/meteor/tiny-test.d.ts +++ b/types/meteor/tiny-test.d.ts @@ -1,41 +1,3 @@ - -interface ILengthAble { - length: number; -} - -interface ITinytestAssertions { - ok(doc: Object): void; - expect_fail(): void; - fail(doc: Object): void; - runId(): string; - equal(actual: T, expected: T, message?: string, not?: boolean): void; - notEqual(actual: T, expected: T, message?: string): void; - instanceOf(obj: Object, klass: Function, message?: string): void; - notInstanceOf(obj: Object, klass: Function, message?: string): void; - matches(actual: any, regexp: RegExp, message?: string): void; - notMatches(actual: any, regexp: RegExp, message?: string): void; - throws(f: Function, expected?: string | RegExp): void; - isTrue(v: boolean, msg?: string): void; - isFalse(v: boolean, msg?: string): void; - isNull(v: any, msg?: string): void; - isNotNull(v: any, msg?: string): void; - isUndefined(v: any, msg?: string): void; - isNotUndefined(v: any, msg?: string): void; - isNan(v: any, msg?: string): void; - isNotNan(v: any, msg?: string): void; - include(s: Array | Object | string, value: any, msg?: string, not?: boolean): void; - - notInclude(s: Array | Object | string, value: any, msg?: string, not?: boolean): void; - length(obj: ILengthAble, expected_length: number, msg?: string): void; - _stringEqual(actual: string, expected: string, msg?: string): void; -} - -declare module Tinytest { - function add(description: string, func: (test: ITinytestAssertions) => void): void; - - function addAsync(description: string, func: (test: ITinytestAssertions) => void): void; -} - declare module "meteor/tiny-test" { interface ILengthAble { length: number; diff --git a/types/meteor/tools.d.ts b/types/meteor/tools.d.ts index a23a2bafaa..f45f75d0cc 100644 --- a/types/meteor/tools.d.ts +++ b/types/meteor/tools.d.ts @@ -1,107 +1,3 @@ - -declare module App { - function accessRule(pattern: string, options?: { - type?: string; - launchExternal?: boolean; - }): void; - - function configurePlugin(id: string, config: Object): void; - - function icons(icons: Object): void; - - function info(options: { - id?: string; - version?: string; - name?: string; - description?: string; - author?: string; - email?: string; - website?: string; - }): void; - - function launchScreens(launchScreens: Object): void; - - function setPreference(name: string, value: string, platform?: string): void; -} - -declare function execFileAsync(command: string, args?: any[], options?: { - cwd?: Object; - env?: Object; - stdio?: any[] | string; - destination?: any; - waitForClose?: string; -}): any; -declare function execFileSync(command: string, args?: any[], options?: { - cwd?: Object; - env?: Object; - stdio?: any[] | string; - destination?: any; - waitForClose?: string; -}): String; - -declare module Assets { - function getBinary(assetPath: string, asyncCallback?: Function): EJSON; - - function getText(assetPath: string, asyncCallback?: Function): string; - - function absoluteFilePath(assetPath: string): string; -} - -declare module Cordova { - function depends(dependencies: { - [id: string]: string - }): void; -} - -declare module Npm { - function depends(dependencies: { - [id: string]: string - }): void; - - function require(name: string): any; -} - -declare namespace Package { - function describe(options: { - summary?: string; - version?: string; - name?: string; - git?: string; - documentation?: string; - debugOnly?: boolean; - prodOnly?: boolean; - testOnly?: boolean; - }): void; - - function onTest(func: (api: PackageAPI) => void): void; - - function onUse(func: (api: PackageAPI) => void): void; - - function registerBuildPlugin(options?: { - name?: string; - use?: string | string[]; - sources?: string[]; - npmDependencies?: Object; - }): void; -} - -interface PackageAPI { - new (): PackageAPI; - addAssets(filenames: string | string[], architecture: string | string[]): void; - addFiles(filenames: string | string[], architecture?: string | string[], options?: { - bare?: boolean; - }): void; - export(exportedObjects: string | string[], architecture?: string | string[], exportOptions?: Object, testOnly?: boolean): void; - imply(packageNames: string | string[], architecture?: string | string[]): void; - use(packageNames: string | string[], architecture?: string | string[], options?: { - weak?: boolean; - unordered?: boolean; - }): void; - versionsFrom(meteorRelease: string | string[]): void; -} - -declare var console: Console; - declare module "meteor/tools" { module App { function accessRule(pattern: string, options?: { @@ -135,7 +31,6 @@ declare module "meteor/tools" { destination?: any; waitForClose?: string; }): any; - function execFileSync(command: string, args?: any[], options?: { cwd?: Object; env?: Object; diff --git a/types/meteor/tracker.d.ts b/types/meteor/tracker.d.ts index 495ae46abd..8a8b69c8da 100644 --- a/types/meteor/tracker.d.ts +++ b/types/meteor/tracker.d.ts @@ -1,42 +1,3 @@ - -declare module Tracker { - function Computation(): void; - interface Computation { - firstRun: boolean; - invalidate(): void; - invalidated: boolean; - onInvalidate(callback: Function): void; - onStop(callback: Function): void; - stop(): void; - stopped: boolean; - } - var currentComputation: Computation; - - var Dependency: DependencyStatic; - interface DependencyStatic { - new (): Dependency; - } - interface Dependency { - changed(): void; - depend(fromComputation?: Computation): boolean; - hasDependents(): boolean; - } - - var active: boolean; - - function afterFlush(callback: Function): void; - - function autorun(runFunc: (computation: Computation) => void, options?: { - onError?: Function; - }): Computation; - - function flush(): void; - - function nonreactive(func: Function): void; - - function onInvalidate(callback: Function): void; -} - declare module "meteor/tracker" { module Tracker { function Computation(): void; diff --git a/types/meteor/tsconfig.json b/types/meteor/tsconfig.json index 0d080fd75f..7ad451fd56 100644 --- a/types/meteor/tsconfig.json +++ b/types/meteor/tsconfig.json @@ -19,28 +19,48 @@ }, "files": [ "accounts-base.d.ts", + "globals/accounts-base.d.ts", "blaze.d.ts", + "globals/blaze.d.ts", "browser-policy-common.d.ts", + "globals/browser-policy-common.d.ts", "check.d.ts", + "globals/check.d.ts", "ddp-rate-limiter.d.ts", + "globals/ddp-rate-limiter.d.ts", "ddp.d.ts", + "globals/ddp.d.ts", "ejson.d.ts", + "globals/ejson.d.ts", "email.d.ts", + "globals/email.d.ts", "http.d.ts", + "globals/http.d.ts", "meteor.d.ts", + "globals/meteor.d.ts", "mongo.d.ts", + "globals/mongo.d.ts", "random.d.ts", + "globals/random.d.ts", "reactive-var.d.ts", + "globals/reactive-var.d.ts", "server-render.d.ts", "service-configuration.d.ts", "session.d.ts", + "globals/session.d.ts", "templating.d.ts", + "globals/templating.d.ts", "tiny-test.d.ts", + "globals/tiny-test.d.ts", "tools.d.ts", + "globals/tools.d.ts", "tracker.d.ts", + "globals/tracker.d.ts", "underscore.d.ts", "webapp.d.ts", "index.d.ts", - "meteor-tests.ts" + "test/meteor-tests.ts", + "test/globals/meteor-tests.ts", + "test/meteor-tests-module-only.ts" ] -} \ No newline at end of file +}