diff --git a/README.md b/README.md index a9be0471a1..026994fdd5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Also see the [definitelytyped.org](http://definitelytyped.org) website, although information in this README is more up-to-date. -*You can also read this README in [Spanish](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.es.md) and [Korean!](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.ko.md)* +*You can also read this README in [Spanish](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.es.md), [Korean](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.ko.md), and [Russian](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.ru.md)!* ## What are declaration files? @@ -169,10 +169,10 @@ If a package was never on DefinitelyTyped, it does not need to be added to `notN #### Lint -All new packages must be linted. To lint a package, add a `tslint.json` to that package containing +All new packages must be linted. To lint a package, add a `tslint.json` to that package containing ```js -{ - "extends": "dtslint/dt.json" +{ + "extends": "dtslint/dt.json" } ``` diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000000..b90bdeac7c --- /dev/null +++ b/README.ru.md @@ -0,0 +1,353 @@ + + +# DefinitelyTyped [![Build Status](https://travis-ci.org/DefinitelyTyped/DefinitelyTyped.svg?branch=master)](https://travis-ci.org/DefinitelyTyped/DefinitelyTyped) + +[![Join the chat at https://gitter.im/borisyankov/DefinitelyTyped](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/borisyankov/DefinitelyTyped?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +> Репозиторий для *высококачественных* определений типов TypeScript. + +Также посетите веб-сайт [definitelytyped.org](http://definitelytyped.org), хотя информация в этом README более свежая. + +*Вы также можете прочитать этот README на [английском](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.md), [испанском](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.es.md) and [корейском](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.ko.md).* + +## Что такое файлы декларации (файлы описания/объявления типов)? + +Смотрите [руководство по TypeScript](http://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html). + +## Как их получить? + +### npm + +Это предпочтительный метод. Это доступно только для пользователей TypeScript 2.0+. Например: + +```sh +npm install --save-dev @types/node +``` + +Затем типы должны автоматически включаться компилятором. +Подробнее смотрите в [справочнике](http://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html). + +Для пакета NPM "foo", описания будут находиться в "@types/foo". +Если вы не можете найти свой пакет, ищите его в [TypeSearch](https://microsoft.github.io/TypeSearch/). + +Если вы все еще не можете найти его, проверьте [включает](http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html) ли пакет собственную типизацию. +Обычно это отражается в поле `"types"` или `"typings"` файла `package.json`, или просто ищите любые файлы ".d.ts" в пакете и вручную включайте их в `/// `. + + +### Другие методы + +Эти методы могут быть использованы TypeScript 1.0. + +* [Typings](https://github.com/typings/typings) +* ~~[NuGet](http://nuget.org/packages?q=DefinitelyTyped)~~ (используйте предпочтительные альтернативы, публикация типа nuget DT отключена) +* Вручную загрузите из ветки `master` этого репозитория + +Возможно, вам придется добавить ручные [ссылки](http://www.typescriptlang.org/docs/handbook/triple-slash-directives.html). + + +## Как я могу внести свой вклад? + +DefinitelyTyped работает только благодаря вкладу таких пользователей, как вы! + +### Тестирование + +Прежде чем поделиться своим улучшением с миром, используйте его сами. + +#### Тестирование редактирования существующего пакета + +Для добавления новых функций вы можете использовать [разрешение модулей](http://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation). +Вы также можете напрямую редактировать типы в `node_modules/@types/foo/index.d.ts`, или скопировать их оттуда и выполнить следующие шаги. + + +#### Тестирование ногово пакета + +Добавьте к вашему `tsconfig.json`: + +```json +"baseUrl": "types", +"typeRoots": ["types"], +``` + +(Вы также можете использовать `src/types`.) +Создайте `types/foo/index.d.ts` содержащие объявления для модуля "foo". +Теперь вы сможете импортировать из `"foo"` в свой код, и он будет направлен к новому определению типа. +Затем запустите сборку (build) *и* запустите код, чтобы убедиться, что ваше определение типа действительно соответствует тому, что происходит во время выполнения. +После того как вы проверили свои определения с реальным кодом, создайте [Запрос на принятие изменений (PR)](#make-a-pull-request) +и следуйте инструкциям [чтобы отредактировать существующий](#edit-an-existing-package) или +[создать новый пакет](#create-a-new-package). + + +### Запрос на принятие изменений (PR) + +После того, как вы проверили ваш пакет, вы можете поделиться им с DefinitelyTyped. + +Во-первых, [разветвите](https://guides.github.com/activities/forking/) этот репозиторий, установите [node](https://nodejs.org/), и запустите `npm install`. + + +#### Изменение существующего пакета + +* `cd types/my-package-to-edit` +* Внесите изменения. Не забудьте отредактировать тесты. + Если вы вносите критические изменения, не забудьте [обновить основную версию](#i-want-to-update-a-package-to-a-new-major-version). +* Вы также можете добавить себя в раздел "Definitions by" заголовка пакета. + * Это приведет к тому, что вы будете уведомлены (через ваше имя пользователя GitHub) о том, что кто-то делает запрос на принятие изменений (PR) или проблему с пакетом. + * Сделайте это, добавив свое имя в конец строки, например `// Definitions by: Alice , Bob `. + * Или, если есть больше людей, это может быть многострочным + + ```typescript + // Definitions by: Alice + // Bob + // Steve + // John + ``` + +* Если есть `tslint.json`, запустите `npm run lint package-name`. В противном случае запустите `tsc` in в директории пакета. + +Когда вы создаете PR для редактирования существующего пакета, `dt-bot` должен @-уведомить previous authors. +предыдущих авторов. Если этого не произойдет, вы можете сделать это самостоятельно в комментарии, связанном с PR. + + +#### Созданое нового пакета + +Если вы являетесь автором библиотеки и ваш пакет написан на TypeScript, [свяжите автоматически сгенерированные файлы объявлений](http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html) в вашем пакете, а не публикуйте в DefinitelyTyped. + +Если вы добавляете типизацию для пакета NPM, создайте директорию с тем же именем. +Если пакет, для которого вы добавляете типизацию, отсутствует в NPM, убедитесь, что выбранное вами имя не конфликтует с именем пакета в NPM. +(Вы можете использовать `npm info foo` чтобы проверить наличие пакета `foo`.) + +Ваш пакет должен иметь такую ​​структуру: + +| Файл | Назначение | +| ------------- | ---------------------------------------------------------------------------------------------------- | +| index.d.ts | Содержит типизацию для пакета. | +| foo-tests.ts | Содержит пример кода, который проверяет типизацию. Этот код *не* запускается, но он проверен на тип. | +| tsconfig.json | Позволяет вам запускать `tsc` внутри пакета. | +| tslint.json | Включает linting. | + +Создайте их, запустив `npx dts-gen --dt --name my-package-name --template module` если у вас ≥ 5.2.0, `npm install -g dts-gen` и `dts-gen --dt --name my-package-name --template module` в противном случае. +Посмотреть все варианты на [dts-gen](https://github.com/Microsoft/dts-gen). + +Вы можете отредактировать `tsconfig.json` чтобы добавить новые файлы, добавить `"target": "es6"` (необходимо для асинхронных функций), добавить в `"lib"`, или добавить опцию компилятора `"jsx"`. + +Члены группы DefinitelyTyped регулярно следят за новыми PR, но имейте в виду, что количество других PR может замедлить ход событий. + +Хороший пример пакета смотрите [base64-js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/base64-js). + + +#### Распространенные ошибки + +* Сначала следуйте советам из справочника [handbook](http://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html). +* Форматирование: либо используйте все табы, либо всегда используйте 4 пробела. +* `function sum(nums: number[]): number`: используйте `ReadonlyArray` если функция не записывает свои параметры. +* `interface Foo { new(): Foo; }`: + Это определяет тип объектов, с методом `new`. Вы, вероятно, хотите объявить `declare class Foo { constructor(); }`. +* `const Class: { new(): IClass; }`: + Предпочитайте использовать объявление класса `class Class { constructor(); }` вместо `new`. +* `getMeAT(): T`: + Если параметр типа не отображается в типах каких-либо параметров, у вас нет универсальной функции, а просто замаскированное утверждение типа. + Предпочитайте использовать утверждение реального типа, например, `getMeAT() as number`. + Пример, где допустим параметр типа: `function id(value: T): T;`. + Пример, где это недопустимо: `function parseJson(json: string): T;`. + Исключение: `new Map()` все ОК. +* Использование типов `Function` and `Object` почти никогда не является хорошей идеей. В 99% случаев можно указать более конкретный тип. Примеры: `(x: number) => number` для [функций](http://www.typescriptlang.org/docs/handbook/functions.html#function-types) and `{ x: number, y: number }` для объектов. Если нет никакой уверенности в типе, [`any`](http://www.typescriptlang.org/docs/handbook/basic-types.html#any) является правильным выбором, а не `Object`. Если единственным известным фактом о типе является то, что это какой-то объект, используйте тип [`object`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#object-type), а не `Object` или `{ [key: string]: any }`. +* `var foo: string | any`: + когда `any` используется в типе объединения, результирующий тип все еще `any`. Таким образом, хотя `string` часть аннотации этого типа может _выглядеть_ полезной, на самом деле она не предлагает никакой дополнительной проверки типов по сравнению с простым использованием `any`. + В зависимости от намерения, приемлемыми альтернативами могут быть `any`, `string`, или `string | object`. + + +#### Удаление пакета + +Когда пакет [объединяет](http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html) свои собственные типы, типы должны быть удалены из DefinitelyTyped чтобы избежать путаницы. + +Вы можете удалить его, запустив `npm run not-needed -- typingsPackageName asOfVersion sourceRepoURL [libraryName]`. + +* `typingsPackageName`: название директории, который нужно удалить. +* `asOfVersion`: заглушка будет опубликована в `@types/foo` с этой версией. Должна быть выше, чем любая опубликованная на данный момент версия +* `sourceRepoURL`: Это должно указывать на репозиторий, который содержит типизации. +* `libraryName`: описательное имя библиотеки, например, "Angular 2" вместо "angular2". (Если опущено, будет идентично "typingsPackageName".) + +Любые другие пакеты в DefinitelyTyped которые ссылаются на удаленный пакет, должны быть обновлены для ссылки на связанные типы. Для этого добавьте в `package.json` ссыклу `"dependencies": { "foo": "x.y.z" }`. + +Если пакет никогда не был в DefinitelyTyped, его не нужно добавлять в `notNeededPackages.json`. + + +#### Lint + +Все новые пакеты должны быть проанализированы lint. Для этого добавьте `tslint.json` в этот пакет, содержащий + +```js +{ + "extends": "dtslint/dt.json" +} +``` + +Это должно быть единственным содержимым в файле `tslint.json` готового проекта. Если `tslint.json` отключает правила, это потому, что это еще не исправлено. Например: + +```js +{ + "extends": "dtslint/dt.json", + "rules": { + // This package uses the Function type, and it will take effort to fix. + "ban-types": false + } +} +``` + +(Чтобы указать, что правило lint действительно не применяется, используйте `// tslint:disable rule-name` или лучше, `//tslint:disable-next-line rule-name`.) + +Чтобы проверить, что выражение имеет заданный тип, используйте `$ExpectType`. Чтобы проверить, что выражение вызывает ошибку компиляции, используйте `$ExpectError`. + +```js +// $ExpectType void +f(1); + +// $ExpectError +f("one"); +``` + +Для получения дополнительной информации см. [dtslint](https://github.com/Microsoft/dtslint#write-tests) readme. + +Протестируйте, запустив `npm run lint package-name` где `package-name` - это имя вашего пакета. +Этот скрипт использует [dtslint](https://github.com/Microsoft/dtslint). + + +## Часто задаваемые вопросы + +#### Какая связь между этим репозиторием и пакетами `@types` в NPM? + +Ветвь `master` автоматически публикуется в область `@types` на NPM благодаря [types-publisher](https://github.com/Microsoft/types-publisher). + +#### Я отправил PR. Когда он сольется? + +Это зависит, но большинство запросов на получение данных будут объединены в течение недели. PR, утвержденные автором, указанным в заголовке определения, обычно объединяются быстрее; PR для новых определений займет больше времени, так как они требуют большего количества проверок от сопровождающих. Каждый PR проверяется членом команды TypeScript или DefinitelyTyped перед объединением, поэтому будьте терпеливы, так как человеческий фактор может вызвать задержки. Посмотрите на [PR Burndown Board](https://github.com/DefinitelyTyped/DefinitelyTyped/projects/3?card_filter_query=is%3Aopen) чтобы увидеть, как сопровождающие работают через открытые PR. + +#### Мой PR слит; когда будет обновлен пакет `@types` NPM? + +Пакеты NPM должны обновиться в течение нескольких часов. Если прошло более 24 часов, пингуйте @RyanCavanaugh и @andy-ms в PR, чтобы расследовать. + +#### Я пишу определение, которое зависит от другого определения. Должен ли я использовать `` или import? + +Если модуль, на который вы ссылаетесь, является внешним модулем (использует `export`), используйте import. +Если модуль, на который вы ссылаетесь, является окружающим модулем (использует `declare module`, или просто объявляет глобальные переменные), используйте ``. + +#### Я заметил, что у некоторых пакетов есть `package.json`. + +Обычно вам это не нужно. При публикации пакета мы обычно автоматически создаем `package.json`. +`package.json` может быть включен для определения зависимостей. Вот [пример](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/pikaday/package.json). +Мы не разрешаем определять другие поля, такие как "description", вручную. +Кроме того, если вам нужно сослаться на более старую версию типизаций, вы должны сделать это, добавив в `package.json` строки `"dependencies": { "@types/foo": "x.y.z" }`. + +#### В некоторых пакетах отсутствует `tslint.json`, а в некоторых `tsconfig.json` отсутствует `"noImplicitAny": true`, `"noImplicitThis": true`, или `"strictNullChecks": true`. + +Тогда они не правы. Вы можете помочь, отправив PR, чтобы исправить их. + +#### Могу ли я запросить определение? + +Вот [текущие запрошенные определения](https://github.com/DefinitelyTyped/DefinitelyTyped/labels/Definition%3ARequest). + +#### Как насчет определений типов для DOM? + +Если типы являются частью веб-стандарта, они должны быть добавлены в [TSJS-lib-generator](https://github.com/Microsoft/TSJS-lib-generator) чтобы они могли стать частью `lib.dom.d.ts` по умолчанию. + +#### Пакет использует export `export =`, но я предпочитаю использовать импорт по умолчанию. Могу ли я изменить `export =` на `export default`? + +Если вы используете TypeScript 2.7 или более позднюю версию, используйте `--esModuleInterop` в вашем проекте. +В противном случае, если импорт по умолчанию работает в вашей среде (например, Webpack, SystemJS, esm), рассмотрите возможность включения опции компилятора [`--allowSyntheticDefaultImports`](http://www.typescriptlang.org/docs/handbook/compiler-options.html). +Не меняйте определение типа, если оно точное. +Для пакета NPM, `export =` является точным, если `node -p 'require("foo")'` является экспортом, а `export default` является точным, если `node -p 'require("foo").default'` является экспортом. + +#### Я хочу использовать функции из TypeScript 2.1 или выше. + +В таком случае вам нужно будет добавить комментарий к последней строке заголовка вашего определения (после `// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped`): `// TypeScript Version: 2.1`. + +#### Я хочу добавить DOM API, отсутствующий в TypeScript по умолчанию. + +Это может принадлежать [TSJS-Lib-Generator](https://github.com/Microsoft/TSJS-lib-generator#readme). Смотрите инструкции там. +Если стандарт все еще является черновиком, добавляйте сюда. +Используйте имя, начинающееся с `dom-` и включите ссылку на стандарт в качестве ссылки "Project" в заголовке. +Когда он завершает черновой режим, мы можем удалить его из DefinitelyTyped и объявить устаревшим связанный пакет `@types`. + +#### Я хочу обновить пакет новой старшей версии + +Если вы намерены продолжить обновление старой версии пакета, вы можете создать новую подпапку с текущей версией, например, `v2` и скопируйте в него существующие файлы. Если это так, вам необходимо: + +1. Обновите относительные пути в `tsconfig.json` а также в `tslint.json`. +2. Добавьте правила сопоставления путей, чтобы убедиться, что тесты выполняются для предполагаемой версии. + +Например [history v2 `tsconfig.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/history/v2/tsconfig.json) looks like: + +```json +{ + "compilerOptions": { + "baseUrl": "../../", + "typeRoots": ["../../"], + "paths": { + "history": [ "history/v2" ] + }, + }, + "files": [ + "index.d.ts", + "history-tests.ts" + ] +} +``` + +Если в DefinitelyTyped есть другие пакеты, несовместимые с новой версией, вам нужно будет добавить сопоставления путей к старой версии. Вам также нужно будет сделать это для пакетов в зависимости от пакетов в зависимости от старой версии. + +Например, `react-router` зависит от `history@2`, поэтому [react-router `tsconfig.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-router/tsconfig.json) есть сопоставление пути с `"history": [ "history/v2" ]`; +транзитивно `react-router-bootstrap` (который зависит от `react-router`) также добавляет отображение пути в свой [tsconfig.json](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-router-bootstrap/tsconfig.json). + +Также, `/// ` не будет работать с отображением пути, поэтому зависимости должны использовать `import`. + +#### Как мне написать определения для пакетов, которые могут использоваться и глобально и в качестве модуля? + +Руководство TypeScript содержит отличную [общую информацию о написании определений](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html), а также [этот пример файла определения](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html) , в котором показано, как создать определение с использованием синтаксиса модуля в стиле ES6, а также указаны объекты, доступные для глобальной области. Этот метод демонстрируется практически в определении для [definition for big.js](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/big.js/index.d.ts), библиотекой, которую можно загружать глобально с помощью тега скрипта на веб-странице или импортировать с помощью импорта по требованию или в стиле ES6. + +Чтобы проверить, как ваше определение может использоваться как при глобальных ссылках, так и в качестве импортированного модуля, создайте тестовую папку `test`, и поместите туда два тестовых файла. Назовите один `YourLibraryName-global.test.ts` а другой `YourLibraryName-module.test.ts`. *Глобальный* тестовый файл должен использовать определение в соответствии с тем, как он будет использоваться в скрипте, загруженном на веб-страницу, где библиотека доступна в глобальной области видимости - в этом сценарии не следует указывать оператор импорта. Тестовый файл *модуля* должен использовать определение в соответствии с тем, как оно будет использоваться при импорте (включая оператор(ы) `import`). Если вы указали свойство `files` в файле `tsconfig.json`, обязательно включите оба тестовых файла. [Практический пример этого](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/big.js/test) также доступен в определении big.js. + +Обратите внимание, что не требуется полностью использовать определение в каждом тестовом файле - достаточно протестировать только глобально доступные элементы в глобальном тестовом файле и полностью выполнить определение в тестовом файле модуля, или наоборот. + +#### А как насчет областных пакетов? + +Типы для пакета с областью `@foo/bar` должны указываться в `types/foo__bar`. Обратите внимание на двойное подчеркивание. + +Когда `dts-gen` используется для компоновки пакета с областью действия, свойство `paths` должно быть вручную адаптировано в сгенерированном файле +`tsconfig.json` для правильной ссылки на пакет с областью действия: + +```json +{ + "paths":{ + "@foo/bar": ["foo__bar"] + } +} +``` + + +#### История файлов в GitHub выглядит неполной. + +GitHub не [поддерживает](http://stackoverflow.com/questions/5646174/how-to-make-github-follow-directory-history-after-renames) историю файлов для переименованных файлов. Вместо этого используйте [`git log --follow`](https://www.git-scm.com/docs/git-log). + +#### Должен ли я добавить пустой namespace в пакет, который не экспортирует модуль для использования импорта в стиле ES6? + +Некоторые пакеты, такие как [chai-http](https://github.com/chaijs/chai-http), экспортируют функцию. + +Импорт этого модуля с импортом в стиле ES6 в форме `import * as foo from "foo";` приводит к ошибке: + +> error TS2497: Module 'foo' resolves to a non-module entity and cannot be imported using this construct + +Эту ошибку можно устранить, объединив объявление функции с пустым namespace'ом с тем же именем, но это не рекомендуется. +Это часто цитируемый [ответ с Stack Overflow](https://stackoverflow.com/questions/39415661/what-does-resolves-to-a-non-module-entity-and-cannot-be-imported-using-this) по этому вопросу. + +Более целесообразно импортировать модуль, используя `import foo = require("foo");` синтаксис или использовать импорт по умолчанию, такой как `import foo from "foo";` при использовании флага `--allowSyntheticDefaultImports`, если среда выполнения вашего модуля поддерживает схему взаимодействия для модулей не-ECMAScript как таковых. + +## Лицензия + +Этот проект лицензирован по лицензии MIT. + +Авторские права на файлы определений принадлежат каждому участнику, указанному в начале каждого файла определения. + +[![Analytics](https://ga-beacon.appspot.com/UA-47495295-4/borisyankov/DefinitelyTyped)](https://github.com/igrigorik/ga-beacon) + +[![Build Status](https://typescript.visualstudio.com/TypeScript/_apis/build/status/sandersn.types-publisher-watchdog)](https://typescript.visualstudio.com/TypeScript/_build/latest?definitionId=13) В среднем пакеты публикуются на npm менее чем за 10000 секунд? + +[![Build Status](https://typescript.visualstudio.com/TypeScript/_apis/build/status/sandersn.typescript-bot-watchdog)](https://typescript.visualstudio.com/TypeScript/_build/latest?definitionId=14) Был ли typescript-bot активным на DefinitelyTyped в последние два часа? diff --git a/node-gettext/index.d.ts b/node-gettext/index.d.ts new file mode 100644 index 0000000000..735f8db84b --- /dev/null +++ b/node-gettext/index.d.ts @@ -0,0 +1,27 @@ +// Type definitions for node-gettext 2.0 +// Project: http://github.com/alexanderwallin/node-gettext +// Definitions by: Sameer K.C. +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export = GetText; +declare class GetText { + constructor(options?: { debug: boolean; }); + addTranslations(locale: string, domain: string, translations: object): void; + dgettext(domain: string, msgid: string): string; + dngettext(domain: string, msgid: string, msgidPlural: string, count: number): string; + dnpgettext(domain: string, msgctxt: string, msgid: string, msgidPlural: string, count: number): string; + dpgettext(domain: string, msgctxt: string, msgid: string): string; + emit(eventName: string, eventData: any): void; + getComment(domain: string, msgctxt: string, msgid: string): object | boolean; + gettext(msgid: string): string; + ngettext(msgid: string, msgidPlural: string, count: number): string; + npgettext(msgctxt: string, msgid: string, msgidPlural: string, count: number): string; + off(eventName: string, callback: (params: any) => void): string; + on(eventName: string, callback: (params: any) => void): void; + pgettext(msgctxt: string, msgid: string): string; + setLocale(locale: string): void; + setTextDomain(domain: string): void; + static getLanguageCode(locale: string): string; + textdomain(domain: string): void; + warn(message: string): void; +} diff --git a/node-gettext/node-gettext-tests.ts b/node-gettext/node-gettext-tests.ts new file mode 100644 index 0000000000..e20e6aacac --- /dev/null +++ b/node-gettext/node-gettext-tests.ts @@ -0,0 +1,34 @@ +// with tsc v 2.7 & esModuleInterop & allowSyntheticDefaultImports enabled in tsconfig.json +import Gettext from 'node-gettext'; +// or without +// import Gettext = require('node-getttext'); + +const translations = {}; +const gt = new Gettext({ debug: true }); +const msgid = 'Get translation'; +const msgidPlural = 'Get translations'; +const domain = 'domain'; +const msgctxt = 'context'; +const count = 2; + +gt.addTranslations('en-US', 'messages', translations); +gt.setTextDomain(domain); +gt.textdomain(domain); +gt.setLocale('en-US'); +gt.gettext(msgid); +gt.dgettext('', msgid); +gt.dngettext(domain, msgid, msgidPlural, count); +gt.dnpgettext(domain, msgctxt, msgid, msgidPlural, count); +gt.dpgettext(domain, msgctxt, msgid); +gt.getComment(domain, msgctxt, msgid); +gt.ngettext(msgid, msgidPlural, count); +gt.npgettext(msgctxt, msgid, msgidPlural, count); +gt.pgettext(msgctxt, msgid); +Gettext.getLanguageCode('en-US'); +gt.warn('warning'); +const errorListener = (error: string) => { + // do something; +}; +gt.on('error', errorListener); +gt.emit('error', 'Error occurred'); +gt.off('error', errorListener); diff --git a/node-gettext/tsconfig.json b/node-gettext/tsconfig.json new file mode 100644 index 0000000000..9306d23426 --- /dev/null +++ b/node-gettext/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [ + "index.d.ts", + "node-gettext-tests.ts" + ] +} diff --git a/types/hibp/tslint.json b/node-gettext/tslint.json similarity index 100% rename from types/hibp/tslint.json rename to node-gettext/tslint.json diff --git a/notNeededPackages.json b/notNeededPackages.json index 251442309d..4acd790e24 100644 --- a/notNeededPackages.json +++ b/notNeededPackages.json @@ -684,6 +684,12 @@ "sourceRepoURL": "https://handsontable.com/", "asOfVersion": "0.35.0" }, + { + "libraryName": "hibp", + "typingsPackageName": "hibp", + "sourceRepoURL": "https://github.com/wKovacs64/hibp", + "asOfVersion": "7.3.0" + }, { "libraryName": "homeworks", "typingsPackageName": "homeworks", @@ -1482,6 +1488,12 @@ "sourceRepoURL": "https://github.com/zeh/simplesignal", "asOfVersion": "1.0.0" }, + { + "libraryName": "sip.js", + "typingsPackageName": "sip.js", + "sourceRepoURL": "https://github.com/onsip/SIP.js", + "asOfVersion": "0.12.0" + }, { "libraryName": "smooth-scrollbar", "typingsPackageName": "smooth-scrollbar", diff --git a/types/ace/index.d.ts b/types/ace/index.d.ts index cd20b57f05..2588539c0c 100644 --- a/types/ace/index.d.ts +++ b/types/ace/index.d.ts @@ -549,6 +549,16 @@ declare namespace AceAjax { getFoldsInRange(range: Range): any; highlight(text: string): void; + + + /** + * Highlight lines from `startRow` to `EndRow`. + * @param startRow Define the start line of the highlight + * @param endRow Define the end line of the highlight + * @param clazz Set the CSS class for the marker + * @param inFront Set to `true` to establish a front marker + **/ + highlightLines(startRow:number, endRow: number, clazz: string, inFront: boolean): Range; /** * Sets the `EditSession` to point to a new `Document`. If a `BackgroundTokenizer` exists, it also points to `doc`. diff --git a/types/ali-oss/index.d.ts b/types/ali-oss/index.d.ts index 13f7f56ff9..e4f9e09e7c 100644 --- a/types/ali-oss/index.d.ts +++ b/types/ali-oss/index.d.ts @@ -18,6 +18,7 @@ declare namespace OSS { internal?: boolean; // access OSS with aliyun internal network or not, default is false. If your servers are running on aliyun too, you can set true to save lot of money. secure?: boolean; // instruct OSS client to use HTTPS (secure: true) or HTTP (secure: false) protocol. timeout?: string | number; // instance level timeout for all operations, default is 60s + cname?: boolean; // use custom domain name } interface Bucket { @@ -29,7 +30,7 @@ declare namespace OSS { type StorageType = "Standard" | "IA" | "Archive"; - type ACLType = "public-read-write" | "public-read" | "and private"; + type ACLType = "public-read-write" | "public-read" | "private"; type HTTPMethods = "GET" | "POST" | "DELETE" | "PUT"; @@ -174,6 +175,7 @@ declare namespace OSS { mime?: string; // custom mime, will send with Content-Type entity header meta?: UserMeta; // user meta, will send with x-oss-meta- prefix string e.g.: { uid: 123, pid: 110 } callback: ObjectCallback; + headers?: object; } interface PutObjectResult { @@ -188,6 +190,7 @@ declare namespace OSS { mime: string; // custom mime, will send with Content-Type entity header meta: UserMeta; callback: ObjectCallback; + headers?: object; } interface AppendObjectOptions { diff --git a/types/autobahn/autobahn-tests.ts b/types/autobahn/autobahn-tests.ts index d753e960fe..8f05c25141 100644 --- a/types/autobahn/autobahn-tests.ts +++ b/types/autobahn/autobahn-tests.ts @@ -43,5 +43,7 @@ function test_client() { }); }; - connection.open(); + if (!connection.isOpen && !connection.isRetrying && connection.session == null) { + connection.open(); + } } diff --git a/types/autobahn/index.d.ts b/types/autobahn/index.d.ts index c62f6115af..7a518e0fd4 100644 --- a/types/autobahn/index.d.ts +++ b/types/autobahn/index.d.ts @@ -1,6 +1,6 @@ -// Type definitions for AutobahnJS v0.9.7 +// Type definitions for AutobahnJS 0.9 // Project: http://autobahn.ws/js/ -// Definitions by: Elad Zelingher , Andy Hawkins , Wladimir Totino , Mathias Teier +// Definitions by: Elad Zelingher , Andy Hawkins , Wladimir Totino , Mathias Teier // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// @@ -191,7 +191,9 @@ declare namespace autobahn { constructor(options?: IConnectionOptions); isOpen: boolean; - + isRetrying: boolean; + session?: Session; + open(): void; close(reason?: string, message?: string): void; diff --git a/types/autobahn/tslint.json b/types/autobahn/tslint.json index a41bf5d19a..a0357daa61 100644 --- a/types/autobahn/tslint.json +++ b/types/autobahn/tslint.json @@ -7,7 +7,6 @@ "ban-types": false, "callable-types": false, "comment-format": false, - "dt-header": false, "eofline": false, "export-just-namespace": false, "import-spacing": false, diff --git a/types/boxen/boxen-tests.ts b/types/boxen/boxen-tests.ts new file mode 100644 index 0000000000..303e5dd7fa --- /dev/null +++ b/types/boxen/boxen-tests.ts @@ -0,0 +1,37 @@ +import boxen = require('boxen'); + +boxen('unicorn'); // $ExpectType string +boxen('unicorn', { borderColor: 'black' }); // $ExpectType string +boxen('unicorn', { borderStyle: 'double' }); // $ExpectType string +boxen('unicorn', { borderStyle: 'foo' }); // $ExpectError +// $ExpectType string +boxen('unicorn', { + borderStyle: { + topLeft: '+', + topRight: '+', + bottomLeft: '+', + bottomRight: '+', + horizontal: '-', + vertical: '|', + }, +}); +boxen('unicorn', { dimBorder: true }); // $ExpectType string +boxen('unicorn', { padding: 1 }); // $ExpectType string +boxen('unicorn', { padding: { top: 1 } }); // $ExpectType string +boxen('unicorn', { padding: { right: 1 } }); // $ExpectType string +boxen('unicorn', { padding: { bottom: 1 } }); // $ExpectType string +boxen('unicorn', { padding: { left: 1 } }); // $ExpectType string +boxen('unicorn', { margin: 1 }); // $ExpectType string +boxen('unicorn', { margin: { top: 1 } }); // $ExpectType string +boxen('unicorn', { margin: { right: 1 } }); // $ExpectType string +boxen('unicorn', { margin: { bottom: 1 } }); // $ExpectType string +boxen('unicorn', { margin: { left: 1 } }); // $ExpectType string +boxen('unicorn', { float: 'right' }); // $ExpectType string +boxen('unicorn', { float: 'center' }); // $ExpectType string +boxen('unicorn', { float: 'left' }); // $ExpectType string +boxen('unicorn', { float: 'foo' }); // $ExpectError +boxen('unicorn', { backgroundColor: 'white' }); // $ExpectType string +boxen('unicorn', { align: 'left' }); // $ExpectType string +boxen('unicorn', { align: 'center' }); // $ExpectType string +boxen('unicorn', { align: 'right' }); // $ExpectType string +boxen('unicorn', { align: 'foo' }); // $ExpectError diff --git a/types/boxen/index.d.ts b/types/boxen/index.d.ts new file mode 100644 index 0000000000..94b68bb5c7 --- /dev/null +++ b/types/boxen/index.d.ts @@ -0,0 +1,114 @@ +// Type definitions for boxen 2.1 +// Project: https://github.com/sindresorhus/boxen#readme +// Definitions by: BendingBender +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.1 + +import { BoxDefinition, BoxNames } from 'cli-boxes'; + +export = boxen; + +/** + * Create boxes in the terminal + * @param input Text inside the box. + */ +declare function boxen(input: string, options?: boxen.Options): string; + +declare namespace boxen { + interface Options { + /** + * Color of the box border. + * Values: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `gray` or a hex value like `#ff0000` + */ + borderColor?: string; + + /** + * Style of the box border. + * Can be any of the above predefined styles or an object. + * + * Predefined values: + * - `single` + * ``` + * ┌───┐ + * │foo│ + * └───┘ + * ``` + * - `double` + * ``` + * ╔═══╗ + * ║foo║ + * ╚═══╝ + * ``` + * - `round` (`single` sides with round corners) + * ``` + * ╭───╮ + * │foo│ + * ╰───╯ + * ``` + * - `single-double` (`single` on top and bottom, `double` on right and left) + * ``` + * ╓───╖ + * ║foo║ + * ╙───╜ + * ``` + * - `double-single` (`double` on top and bottom, `single` on right and left) + * ``` + * ╒═══╕ + * │foo│ + * ╘═══╛ + * ``` + * - `classic` + * ``` + * +---+ + * |foo| + * +---+ + * ``` + */ + borderStyle?: BoxNames | BoxDefinition; + + /** + * Reduce opacity of the border. + * @default false + */ + dimBorder?: boolean; + + /** + * Space between the text and box border. + * When a number is specified, the left/right padding is 3 times the top/bottom to make it look nice. + * @default 0 + */ + padding?: number | PositionOptions; + + /** + * Space around the box. + * When a number is specified, the left/right margin is 3 times the top/bottom to make it look nice. + * @default 0 + */ + margin?: number | PositionOptions; + + /** + * Float the box on the available terminal screen space. + * @default 'left' + */ + float?: 'right' | 'center' | 'left'; + + /** + * Color of the background. + * Values: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `gray` or a hex value like `#ff0000` + */ + backgroundColor?: string; + + /** + * Align the text in the box based on the widest line. + * @default 'left' + */ + align?: 'left' | 'center' | 'right'; + } + + interface PositionOptions { + top?: number; + right?: number; + bottom?: number; + left?: number; + } +} diff --git a/types/boxen/tsconfig.json b/types/boxen/tsconfig.json new file mode 100644 index 0000000000..6d34147e83 --- /dev/null +++ b/types/boxen/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "boxen-tests.ts" + ] +} diff --git a/types/boxen/tslint.json b/types/boxen/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/boxen/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/bytebuffer/index.d.ts b/types/bytebuffer/index.d.ts index 4423d7872b..bafed6edf8 100644 --- a/types/bytebuffer/index.d.ts +++ b/types/bytebuffer/index.d.ts @@ -146,7 +146,7 @@ declare class ByteBuffer /** * Concatenates multiple ByteBuffers into one. */ - static concat( buffers: Array, encoding?: string | boolean, litteEndian?: boolean, noAssert?: boolean ): ByteBuffer; + static concat( buffers: Array, encoding?: string | boolean, litteEndian?: boolean, noAssert?: boolean ): ByteBuffer; /** * Decodes a base64 encoded string to a ByteBuffer. @@ -185,7 +185,7 @@ declare class ByteBuffer * @param littleEndian Whether to use little or big endian byte order. Defaults to ByteBuffer.DEFAULT_ENDIAN. * @param noAssert Whether to skip assertions of offsets and values. Defaults to ByteBuffer.DEFAULT_NOASSERT. */ - static wrap( buffer: ByteBuffer | ArrayBuffer | Uint8Array | string, enc?: string | boolean, littleEndian?: boolean, noAssert?: boolean ): ByteBuffer; + static wrap( buffer: ByteBuffer | Buffer | ArrayBuffer | Uint8Array | string, enc?: string | boolean, littleEndian?: boolean, noAssert?: boolean ): ByteBuffer; /** * Decodes a zigzag encoded signed 32bit integer. @@ -220,7 +220,7 @@ declare class ByteBuffer /** * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended data's length. */ - append( source: ByteBuffer | ArrayBuffer | Uint8Array | string, encoding?: string | number, offset?: number ): ByteBuffer; + append( source: ByteBuffer | Buffer | ArrayBuffer | Uint8Array | string, encoding?: string | number, offset?: number ): ByteBuffer; /** * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents behind the specified offset up to the length of this ByteBuffer's data. @@ -291,7 +291,7 @@ declare class ByteBuffer /** * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the prepended data's length. If there is not enough space available before the specified offset, the backing buffer will be resized and its contents moved accordingly. */ - prepend( source: ByteBuffer | string | ArrayBuffer, encoding?: string | number, offset?: number ): ByteBuffer; + prepend( source: ByteBuffer | string | ArrayBuffer | Buffer, encoding?: string | number, offset?: number ): ByteBuffer; /** * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the prepended data's length. If there is not enough space available before the specified offset, the backing buffer will be resized and its contents moved accordingly. @@ -480,7 +480,7 @@ declare class ByteBuffer /** * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between ByteBuffer#offset and ByteBuffer#limit. Will transparently ByteBuffer#flip this ByteBuffer if offset > limit but the actual offsets remain untouched. */ - toBuffer( forceCopy?: boolean ): ArrayBuffer; + toBuffer( forceCopy?: boolean ): Buffer; /** *Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are: @@ -517,7 +517,7 @@ declare class ByteBuffer /** * Writes an array of bytes. This is an alias for append */ - writeBytes( source: ByteBuffer | ArrayBuffer | Uint8Array | string, encoding?: string | number, offset?: number ): ByteBuffer; + writeBytes( source: ByteBuffer | Buffer | ArrayBuffer | Uint8Array | string, encoding?: string | number, offset?: number ): ByteBuffer; /** * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL characters itself. diff --git a/types/classnames/bind.d.ts b/types/classnames/bind.d.ts index 4af94d1835..9befbabd4c 100644 --- a/types/classnames/bind.d.ts +++ b/types/classnames/bind.d.ts @@ -1,3 +1,3 @@ -import * as cn from "./index"; +import classNames = require('./index'); -export function bind(styles: Record): typeof cn; +export function bind(styles: Record): typeof classNames; diff --git a/types/classnames/tsconfig.json b/types/classnames/tsconfig.json index f9b03432fc..0e8475e613 100644 --- a/types/classnames/tsconfig.json +++ b/types/classnames/tsconfig.json @@ -6,7 +6,7 @@ ], "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": false, + "strictNullChecks": true, "strictFunctionTypes": true, "baseUrl": "../", "typeRoots": [ diff --git a/types/cordova-plugin-x-socialsharing/index.d.ts b/types/cordova-plugin-x-socialsharing/index.d.ts index a5105c898c..d1a4740b58 100644 --- a/types/cordova-plugin-x-socialsharing/index.d.ts +++ b/types/cordova-plugin-x-socialsharing/index.d.ts @@ -1,13 +1,13 @@ -// Type definitions for SocialSharing-PhoneGap-Plugin v5.1.8 +// Type definitions for SocialSharing-PhoneGap-Plugin v5.1.9 // Project: https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin // Definitions by: Markus Wagner , Larry Bahr // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped interface Window { - plugins: Plugins; + plugins: CordovaPlugins; } -interface Plugins { +interface CordovaPlugins { socialsharing: SocialSharingPlugin.SocialSharing; } diff --git a/types/d3-cloud/d3-cloud-tests.ts b/types/d3-cloud/d3-cloud-tests.ts index 862b7f0d82..e3bffed4cb 100644 --- a/types/d3-cloud/d3-cloud-tests.ts +++ b/types/d3-cloud/d3-cloud-tests.ts @@ -1,3 +1,12 @@ +import d3Cloud = require('./index.d'); +import d3 = require('d3'); + +// $ExpectType Cloud +d3Cloud(); + +// $ExpectType Cloud +d3.layout.cloud(); + interface ICompTextSize{ text:string; size:number; diff --git a/types/d3-cloud/index.d.ts b/types/d3-cloud/index.d.ts index 70e2140bd5..fdf2dbc719 100644 --- a/types/d3-cloud/index.d.ts +++ b/types/d3-cloud/index.d.ts @@ -5,6 +5,8 @@ import * as d3 from 'd3'; +export = d3.layout.cloud; + declare module 'd3' { namespace layout { export function cloud(): Cloud; diff --git a/types/d3-dsv/d3-dsv-tests.ts b/types/d3-dsv/d3-dsv-tests.ts index 259180632f..8e05b04e61 100644 --- a/types/d3-dsv/d3-dsv-tests.ts +++ b/types/d3-dsv/d3-dsv-tests.ts @@ -21,6 +21,9 @@ const csvTestStringWithHeader = `Year,Make,Model,Length\n${csvTestString}`; const tsvTestStringWithHeader = `Year\tMake\tModel\tLength\n${tsvTestString}`; const pipedTestStringWithHeader = `Year|Make|Model|Length\n${pipedTestString}`; +type Headers = "Year" | "Make" | "Model" | "Length"; +type ParsedHeaders = "year" | "make" | "model" | "length"; + interface ParsedTestObject { year: Date | null; make: string; @@ -28,17 +31,56 @@ interface ParsedTestObject { length: number; } -let parseArray: d3Dsv.DSVParsedArray; -let parseMappedArray: d3Dsv.DSVParsedArray; - let parseRowsArray: string[][]; let parseRowsMappedArray: ParsedTestObject[]; - let parsedTestObject: ParsedTestObject; -let columns: string[]; + +let num: number; let str: string; let strMaybe: string | undefined; +let columns: string[]; +let headers: Headers[]; +let parsedHeaders: ParsedHeaders[]; + +// ------------------------------------------------------------------------------------------ +// Test Shared Types and Interfaces +// ------------------------------------------------------------------------------------------ + +declare let row: d3Dsv.DSVRowString; +strMaybe = row.property; + +declare let row2: d3Dsv.DSVRowString; +strMaybe = row2.Make; +strMaybe = row2.Property; // $ExpectError + +declare let raw: d3Dsv.DSVRaw; +strMaybe = raw.make; +strMaybe = raw.property; // $ExpectError + +declare let rowArray: d3Dsv.DSVRowArray; +strMaybe = rowArray[0].property; +columns = rowArray.columns; +num = rowArray.length; + +declare let rowArrayHeader: d3Dsv.DSVRowArray; +strMaybe = rowArrayHeader[0].Make; +strMaybe = rowArrayHeader[0].Property; // $ExpectError +headers = rowArrayHeader.columns; +num = rowArrayHeader.length; + +declare let parseMappedArray: d3Dsv.DSVParsedArray; +strMaybe = parseMappedArray[0].make; +strMaybe = parseMappedArray[0].property; // $ExpectError +parsedTestObject = parseMappedArray[0]; +parsedHeaders = parseMappedArray.columns; +num = parseMappedArray.length; + +declare let parseArray: d3Dsv.DSVParsedArray; +strMaybe = parseArray[0].property; +columns = parseArray.columns; +num = parseArray.length; + // ------------------------------------------------------------------------------------------ // Test CSV // ------------------------------------------------------------------------------------------ @@ -48,8 +90,7 @@ let strMaybe: string | undefined; // without row mapper ----------------------------------------------------------------------- parseArray = d3Dsv.csvParse(csvTestStringWithHeader); -columns = parseArray.columns; -strMaybe = parseArray[0].Year; +rowArrayHeader = d3Dsv.csvParse(csvTestStringWithHeader); // with row mapper --------------------------------------------------------------------------- @@ -73,8 +114,12 @@ parseMappedArray = d3Dsv.csvParse(csvTestStringWithHeader, (rawRow, index, colum return pr; }); -columns = parseMappedArray.columns; -parsedTestObject = parseMappedArray[0]; +parseMappedArray = d3Dsv.csvParse(csvTestStringWithHeader, (rawRow, index, columns) => { + const rr: d3Dsv.DSVRowString = rawRow; + const i: number = index; + const c: Headers[] = columns; + return parsedTestObject; +}); // csvParseRows(...) ============================================================================ @@ -108,12 +153,11 @@ parseRowsMappedArray = d3Dsv.csvParseRows(csvTestString, (rawRow, index) => { str = d3Dsv.csvFormat(parseRowsMappedArray); str = d3Dsv.csvFormat(parseRowsMappedArray, ["year", "length"]); -// $ExpectError -str = d3Dsv.csvFormat(parseRowsMappedArray, ["year", "unknown"]); +str = d3Dsv.csvFormat(parseRowsMappedArray, ["year", "unknown"]); // $ExpectError // csvFormatRows(...) ======================================================================== -str = d3Dsv.csvFormatRows(parseRowsMappedArray.map((d, i) => [ +str = d3Dsv.csvFormatRows(parseRowsMappedArray.map((d) => [ d.year ? d.year.getFullYear().toString() : '', d.make, d.model, @@ -129,8 +173,7 @@ str = d3Dsv.csvFormatRows(parseRowsMappedArray.map((d, i) => [ // without row mapper ----------------------------------------------------------------------- parseArray = d3Dsv.tsvParse(tsvTestStringWithHeader); -columns = parseArray.columns; -strMaybe = parseArray[0].Year; +rowArrayHeader = d3Dsv.tsvParse(csvTestStringWithHeader); // with row mapper --------------------------------------------------------------------------- @@ -154,8 +197,12 @@ parseMappedArray = d3Dsv.tsvParse(tsvTestStringWithHeader, (rawRow, index, colum return pr; }); -columns = parseMappedArray.columns; -parsedTestObject = parseMappedArray[0]; +parseMappedArray = d3Dsv.tsvParse(tsvTestStringWithHeader, (rawRow, index, columns) => { + const rr: d3Dsv.DSVRowString = rawRow; + const i: number = index; + const c: Headers[] = columns; + return parsedTestObject; +}); // tsvParseRows(...) ============================================================================ @@ -189,12 +236,11 @@ parseRowsMappedArray = d3Dsv.tsvParseRows(tsvTestString, (rawRow, index) => { str = d3Dsv.tsvFormat(parseRowsMappedArray); str = d3Dsv.tsvFormat(parseRowsMappedArray, ["year", "length"]); -// $ExpectError -str = d3Dsv.tsvFormat(parseRowsMappedArray, ["year", "unknown"]); +str = d3Dsv.tsvFormat(parseRowsMappedArray, ["year", "unknown"]); // $ExpectError // tsvFormatRows(...) ======================================================================== -str = d3Dsv.tsvFormatRows(parseRowsMappedArray.map((d, i) => [ +str = d3Dsv.tsvFormatRows(parseRowsMappedArray.map((d) => [ d.year ? d.year.getFullYear().toString() : '', d.make, d.model, @@ -215,8 +261,7 @@ dsv = d3Dsv.dsvFormat('|'); // without row mapper ----------------------------------------------------------------------- parseArray = dsv.parse(pipedTestStringWithHeader); -columns = parseArray.columns; -strMaybe = parseArray[0].Year; +rowArrayHeader = dsv.parse(csvTestStringWithHeader); // with row mapper --------------------------------------------------------------------------- @@ -240,8 +285,12 @@ parseMappedArray = dsv.parse(pipedTestStringWithHeader, (rawRow, index, columns) return pr; }); -columns = parseMappedArray.columns; -parsedTestObject = parseMappedArray[0]; +parseMappedArray = dsv.parse(pipedTestStringWithHeader, (rawRow, index, columns) => { + const rr: d3Dsv.DSVRowString = rawRow; + const i: number = index; + const c: Headers[] = columns; + return parsedTestObject; +}); // parseRows(...) ============================================================================ @@ -275,12 +324,11 @@ parseRowsMappedArray = dsv.parseRows(pipedTestString, (rawRow, index) => { str = dsv.format(parseRowsMappedArray); str = dsv.format(parseRowsMappedArray, ["year", "length"]); -// $ExpectError -str = dsv.format(parseRowsMappedArray, ["year", "unknown"]); +str = dsv.format(parseRowsMappedArray, ["year", "unknown"]); // $ExpectError // formatRows(...) ======================================================================== -str = dsv.formatRows(parseRowsMappedArray.map((d, i) => [ +str = dsv.formatRows(parseRowsMappedArray.map((d) => [ d.year ? d.year.getFullYear().toString() : '', d.make, d.model, diff --git a/types/d3-dsv/index.d.ts b/types/d3-dsv/index.d.ts index bdebc5ca01..fcfaa67339 100644 --- a/types/d3-dsv/index.d.ts +++ b/types/d3-dsv/index.d.ts @@ -15,21 +15,41 @@ /** * An object representing a DSV parsed row with values represented as strings. + * When the DSV content is not well-structured and some column-values are missing, `undefined` is used as value. */ -export interface DSVRowString { - [key: string]: string | undefined; -} +export type DSVRowString = { + [key in Columns]: string | undefined; +}; + +/** + * An object in raw format before parsing, that is with only string values. + * When the DSV content is not well-structured and some column-values are missing, `undefined` is used as value. + */ +export type DSVRaw = { + [key in keyof T]: string | undefined; +}; /** * An object representing a DSV parsed row with values represented as an arbitrary datatype, depending * on the performed parsed row mapping. * - * @deprecated + * @deprecated Use `object` instead. */ export interface DSVRowAny { [key: string]: any; } +/** + * An array object representing all deserialized rows. The array is enhanced with a property listing + * the names of the parsed columns. + */ +export interface DSVRowArray extends Array> { + /** + * List of column names. + */ + columns: Columns[]; +} + /** * An array object representing all parsed rows. The array is enhanced with a property listing * the names of the parsed columns. @@ -38,7 +58,7 @@ export interface DSVParsedArray extends Array { /** * List of column names. */ - columns: string[]; + columns: Array; } // ------------------------------------------------------------------------------------------ @@ -55,11 +75,12 @@ export interface DSVParsedArray extends Array { * * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). * - * Equivalent to dsvFormat(",").parse. + * Equivalent to `dsvFormat(",").parse`. * * @param csvString A string, which must be in the comma-separated values format. */ -export function csvParse(csvString: string): DSVParsedArray; +// tslint:disable-next-line:no-unnecessary-generics +export function csvParse(csvString: string): DSVRowArray; /** * Parses the specified string, which must be in the comma-separated values format, returning an array of objects representing the parsed rows. * @@ -68,7 +89,7 @@ export function csvParse(csvString: string): DSVParsedArray; * * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). * - * Equivalent to dsvFormat(",").parse. + * Equivalent to `dsvFormat(",").parse`. * * @param csvString A string, which must be in the comma-separated values format. * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), @@ -76,9 +97,9 @@ export function csvParse(csvString: string): DSVParsedArray; * the row is skipped and will be omitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function csvParse( +export function csvParse( csvString: string, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): DSVParsedArray; // csvParseRows(...) ======================================================================== @@ -92,7 +113,7 @@ export function csvParse( * If a row conversion function is not specified, field values are strings. For safety, there is no automatic conversion to numbers, dates, or other types. * In some cases, JavaScript may coerce strings to numbers for you automatically (for example, using the + operator), but better is to specify a row conversion function. * - * Equivalent to dsvFormat(",").parseRows. + * Equivalent to `dsvFormat(",").parseRows`. * * @param csvString A string, which must be in the comma-separated values format. */ @@ -103,7 +124,7 @@ export function csvParseRows(csvString: string): string[][]; * Unlike csvParse, this method treats the header line as a standard row, and should be used whenever CSV content does not contain a header. * Each row is represented as an array rather than an object. Rows may have variable length. * - * Equivalent to dsvFormat(",").parseRows. + * Equivalent to `dsvFormat(",").parseRows`. * * @param csvString A string, which must be in the comma-separated values format. * @param row A row conversion function which is invoked for each row, being passed an array representing the current row (d), the index (i) @@ -127,7 +148,7 @@ export function csvParseRows( * If columns is not specified, the list of column names that forms the header row is determined by the union of all properties on all objects in rows; * the order of columns is nondeterministic. * - * Equivalent to dsvFormat(",").format. + * Equivalent to `dsvFormat(",").format`. * * @param rows Array of object rows. * @param columns An array of strings representing the column names. @@ -145,7 +166,7 @@ export function csvFormat(rows: T[], columns?: Array) * To convert an array of objects to an array of arrays while explicitly specifying the columns, use array.map. * If you like, you can also array.concat this result with an array of column names to generate the first row. * - * Equivalent to dsvFormat(",").formatRows. + * Equivalent to `dsvFormat(",").formatRows`. * * @param rows An array of array of string rows. */ @@ -165,11 +186,12 @@ export function csvFormatRows(rows: string[][]): string; * * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). * - * Equivalent to dsvFormat("\t").parse. + * Equivalent to `dsvFormat("\t").parse`. * * @param tsvString A string, which must be in the tab-separated values format. */ -export function tsvParse(tsvString: string): DSVParsedArray; +// tslint:disable-next-line:no-unnecessary-generics +export function tsvParse(tsvString: string): DSVRowArray; /** * Parses the specified string, which must be in the tab-separated values format, returning an array of objects representing the parsed rows. * @@ -178,7 +200,7 @@ export function tsvParse(tsvString: string): DSVParsedArray; * * The returned array also exposes a columns property containing the column names in input order (in contrast to Object.keys, whose iteration order is arbitrary). * - * Equivalent to dsvFormat("\t").parse. + * Equivalent to `dsvFormat("\t").parse`. * * @param tsvString A string, which must be in the tab-separated values format. * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), @@ -186,10 +208,10 @@ export function tsvParse(tsvString: string): DSVParsedArray; * the row is skipped and will be omitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function tsvParse( +export function tsvParse( tsvString: string, - row: (rawRow: DSVRowString, index: number, columns: string[]) => MappedRow | undefined | null -): DSVParsedArray; + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null +): DSVParsedArray; // tsvParseRows(...) ======================================================================== @@ -202,7 +224,7 @@ export function tsvParse( * If a row conversion function is not specified, field values are strings. For safety, there is no automatic conversion to numbers, dates, or other types. * In some cases, JavaScript may coerce strings to numbers for you automatically (for example, using the + operator), but better is to specify a row conversion function. * - * Equivalent to dsvFormat("\t").parseRows. + * Equivalent to `dsvFormat("\t").parseRows`. * * @param tsvString A string, which must be in the tab-separated values format. */ @@ -213,7 +235,7 @@ export function tsvParseRows(tsvString: string): string[][]; * Unlike tsvParse, this method treats the header line as a standard row, and should be used whenever TSV content does not contain a header. * Each row is represented as an array rather than an object. Rows may have variable length. * - * Equivalent to dsvFormat("\t").parseRows. + * Equivalent to `dsvFormat("\t").parseRows`. * * @param tsvString A string, which must be in the tab-separated values format. * @param row A row conversion function which is invoked for each row, being passed an array representing the current row (d), the index (i) @@ -221,10 +243,10 @@ export function tsvParseRows(tsvString: string): string[][]; * the row is skipped and will be omitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function tsvParseRows( +export function tsvParseRows( tsvString: string, - row: (rawRow: string[], index: number) => MappedRow | undefined | null -): MappedRow[]; + row: (rawRow: string[], index: number) => ParsedRow | undefined | null +): ParsedRow[]; // tsvFormat(...) ============================================================================ @@ -237,7 +259,7 @@ export function tsvParseRows( * If columns is not specified, the list of column names that forms the header row is determined by the union of all properties on all objects in rows; * the order of columns is nondeterministic. * - * Equivalent to dsvFormat("\t").format. + * Equivalent to `dsvFormat("\t").format`. * * @param rows Array of object rows. * @param columns An array of strings representing the column names. @@ -255,7 +277,7 @@ export function tsvFormat(rows: T[], columns?: Array) * To convert an array of objects to an array of arrays while explicitly specifying the columns, use array.map. * If you like, you can also array.concat this result with an array of column names to generate the first row. * - * Equivalent to dsvFormat("\t").formatRows. + * Equivalent to `dsvFormat("\t").formatRows`. * * @param rows An array of array of string rows. */ @@ -279,7 +301,8 @@ export interface DSV { * * @param dsvString A string, which must be in the delimiter-separated values format with the appropriate delimiter. */ - parse(dsvString: string): DSVParsedArray; + // tslint:disable-next-line:no-unnecessary-generics + parse(dsvString: string): DSVRowArray; /** * Parses the specified string, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of objects representing the parsed rows. * @@ -294,9 +317,9 @@ export interface DSV { * the row is skipped and will be omitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ - parse( + parse( dsvString: string, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): DSVParsedArray; /** diff --git a/types/d3-fetch/d3-fetch-tests.ts b/types/d3-fetch/d3-fetch-tests.ts index 4d49d86a7f..8d6b862afc 100644 --- a/types/d3-fetch/d3-fetch-tests.ts +++ b/types/d3-fetch/d3-fetch-tests.ts @@ -1,62 +1,158 @@ import * as d3Fetch from 'd3-fetch'; -import { DSVParsedArray, DSVRowString } from 'd3-dsv'; +import { DSVParsedArray, DSVRaw, DSVRowString } from 'd3-dsv'; -interface MyType { - foo: string; +// ---------------------------------------------------------------------------- +// Preparatory Steps +// ---------------------------------------------------------------------------- + +type Headers = "Year" | "Make" | "Model" | "Length"; + +interface Car { + year: Date; + make: string; + model: string; + length: number; } -const url = 'foo.bar'; - -const init: RequestInit = {}; - -let p1: Promise = d3Fetch.blob(url); -p1 = d3Fetch.blob(url, init); - -let p2: Promise = d3Fetch.buffer(url); -p2 = d3Fetch.buffer(url, init); - -let p3: Promise = d3Fetch.image(url); -const imageProperties = { - width: '300px', - height: '500px' -}; -p3 = d3Fetch.image(url, imageProperties); - -let p4: Promise = d3Fetch.json(url); -p4 = d3Fetch.json(url, init); -let p5: Promise = d3Fetch.json(url); -p5 = d3Fetch.json(url, init); - -let myString: Promise; -myString = d3Fetch.text(url); -myString = d3Fetch.text(url, init); - -const parseRow = (rawRow: DSVRowString, index: number, columns: string[]): (MyType | undefined | null) => { - const myType: MyType | null = rawRow['foo'] ? { foo: rawRow['foo'] + '+ bar' } : null; - return myType; -}; -let promise1: Promise>; -let promise2: Promise>; -promise1 = d3Fetch.csv(url); -promise1 = d3Fetch.csv(url, init); -promise2 = d3Fetch.csv(url, parseRow); -promise2 = d3Fetch.csv(url, init, parseRow); -promise1 = d3Fetch.dsv(';', url); -promise1 = d3Fetch.dsv(';', url, init); -promise2 = d3Fetch.dsv(';', url, parseRow); -promise2 = d3Fetch.dsv(';', url, init, parseRow); -promise1 = d3Fetch.tsv(url); -promise1 = d3Fetch.tsv(url, init); -promise2 = d3Fetch.tsv(url, parseRow); -promise2 = d3Fetch.tsv(url, init, parseRow); - +let anyPromise: Promise; +let arrayPromise: Promise; +let blobPromise: Promise; let docPromise: Promise; +let imagePromise: Promise; +let carPromise: Promise; +let stringPromise: Promise; +let xmlDocPromise: Promise; + +const url = 'example.org'; +const init: RequestInit = {}; +const map = new Map(); + +const imageProperties = { + width: 300, + height: 500, + crossOrigin: "anonymous", +}; + +// ---------------------------------------------------------------------------- +// Non DSV file format +// ---------------------------------------------------------------------------- + +blobPromise = d3Fetch.blob(url); +blobPromise = d3Fetch.blob(url, init); + +arrayPromise = d3Fetch.buffer(url); +arrayPromise = d3Fetch.buffer(url, init); + +imagePromise = d3Fetch.image(url); +imagePromise = d3Fetch.image(url, imageProperties); +// $ExpectError +imagePromise = d3Fetch.image(url, {width: "500px"}); // fails, string not assignable to number | undefined + +anyPromise = d3Fetch.json(url); +anyPromise = d3Fetch.json(url, init); + +carPromise = d3Fetch.json(url); +carPromise = d3Fetch.json(url, init); + +stringPromise = d3Fetch.text(url); +stringPromise = d3Fetch.text(url, init); + docPromise = d3Fetch.html(url); docPromise = d3Fetch.html(url, init); docPromise = d3Fetch.svg(url); docPromise = d3Fetch.svg(url, init); -let xmlDocPromise: Promise; xmlDocPromise = d3Fetch.xml(url); xmlDocPromise = d3Fetch.xml(url, init); + +// ---------------------------------------------------------------------------- +// DSV file format +// ---------------------------------------------------------------------------- + +let rawPromise: Promise>; +let rawPromiseHeader: Promise>>; +let parsedPromise: Promise>; + +declare const parseRowString: (rawRow: DSVRowString, index: number, columns: string[]) => Car | undefined | null; + +const parseRow = (d: DSVRowString, index: number, columns: Headers[]): Car | undefined | null => { + const item: string | undefined = d[columns[0]]; + const car = d.Make === 'Ford' ? null : + { + year: new Date(+d.Make!, 0, 1), + make: d.Make!, + model: d.Model!, + length: +d.Length!, + }; + return index % 2 === 0 ? undefined : car; +}; + +const parseRowSimple = (d: DSVRaw) => { + return { + year: new Date(+d.make!, 0, 1), + make: d.make!, + model: d.model!, + length: +d.length!, + }; +}; + +// CSV + +rawPromise = d3Fetch.csv(url); +rawPromise = d3Fetch.csv(url, init); + +rawPromiseHeader = d3Fetch.csv(url); +rawPromiseHeader = d3Fetch.csv(url, init); + +parsedPromise = d3Fetch.csv(url, parseRowString); +parsedPromise = d3Fetch.csv(url, init, parseRowString); + +parsedPromise = d3Fetch.csv(url, parseRow); +parsedPromise = d3Fetch.csv(url, init, parseRow); + +parsedPromise = d3Fetch.csv(url, parseRow); +parsedPromise = d3Fetch.csv(url, init, parseRow); +parsedPromise = d3Fetch.csv(url, parseRowSimple); + +anyPromise = d3Fetch.csv(url, (d: DSVRaw) => map.set(d.model!, +d.year!)); + +// DSV + +rawPromise = d3Fetch.dsv("|", url); +rawPromise = d3Fetch.dsv("|", url, init); + +rawPromiseHeader = d3Fetch.dsv("|", url); +rawPromiseHeader = d3Fetch.dsv("|", url, init); + +parsedPromise = d3Fetch.dsv("|", url, parseRowString); +parsedPromise = d3Fetch.dsv("|", url, init, parseRowString); + +parsedPromise = d3Fetch.dsv("|", url, parseRow); +parsedPromise = d3Fetch.dsv("|", url, init, parseRow); + +parsedPromise = d3Fetch.dsv("|", url, parseRow); +parsedPromise = d3Fetch.dsv("|", url, init, parseRow); +parsedPromise = d3Fetch.dsv("|", url, parseRowSimple); + +anyPromise = d3Fetch.dsv("|", url, (d: DSVRaw) => map.set(d.model!, +d.year!)); + +// TSV + +rawPromise = d3Fetch.tsv(url); +rawPromise = d3Fetch.tsv(url, init); + +rawPromiseHeader = d3Fetch.tsv(url); +rawPromiseHeader = d3Fetch.tsv(url, init); + +parsedPromise = d3Fetch.tsv(url, parseRowString); +parsedPromise = d3Fetch.tsv(url, init, parseRowString); + +parsedPromise = d3Fetch.tsv(url, parseRow); +parsedPromise = d3Fetch.tsv(url, init, parseRow); + +parsedPromise = d3Fetch.tsv(url, parseRow); +parsedPromise = d3Fetch.tsv(url, init, parseRow); +parsedPromise = d3Fetch.tsv(url, parseRowSimple); + +anyPromise = d3Fetch.csv(url, (d: DSVRaw) => map.set(d.model!, +d.year!)); diff --git a/types/d3-fetch/index.d.ts b/types/d3-fetch/index.d.ts index f6dc317784..4110ba4a7b 100644 --- a/types/d3-fetch/index.d.ts +++ b/types/d3-fetch/index.d.ts @@ -1,12 +1,13 @@ // Type definitions for d3-fetch 1.1 // Project: https://d3js.org/d3-fetch/ // Definitions by: Hugues Stefanski +// denisname // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 // Last module patch version validated against: 1.1.0 -import { DSVParsedArray, DSVRowString } from 'd3-dsv'; +import { DSVParsedArray, DSVRowArray, DSVRowString } from "d3-dsv"; /** * Fetches the binary file at the specified input URL and returns it as a Promise of a Blob. @@ -33,13 +34,15 @@ export function buffer(url: string, init?: RequestInit): Promise; * * If init is specified, it is passed along to the underlying call to fetch. * + * The generic parameter describes the column names as a union of string literal types. + * * @param url A valid URL string. * @param init An optional request initialization object. */ -export function csv( +export function csv( url: string, - init?: RequestInit, -): Promise>; + init?: RequestInit +): Promise>; /** * Fetches the CSV file at the specified input URL and returns * a promise of an array of objects representing the parsed rows. @@ -47,7 +50,8 @@ export function csv( * The specified row conversion function is used to map and filter row objects to a more-specific representation; * see dsv.csvParse for details. * - * The generic parameter describes the type of the object representation of a parsed row. + * The first generic parameter describes the type of the object representation of a parsed row. + * The second generic parameter describes the column names as a union of string literal types. * * @param url A valid URL string. * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), @@ -55,9 +59,9 @@ export function csv( * the row is skipped and will be omitted from the array returned by dsv.csvParse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function csv( +export function csv( url: string, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): Promise>; /** * Fetches the CSV file at the specified input URL and returns @@ -68,7 +72,8 @@ export function csv( * The specified row conversion function is used to map and filter row objects to a more-specific representation; * see dsv.csvParse for details. * - * The generic parameter describes the type of the object representation of a parsed row. + * The first generic parameter describes the type of the object representation of a parsed row. + * The second generic parameter describes the column names as a union of string literal types. * * @param url A valid URL string. * @param init An request initialization object. @@ -77,10 +82,10 @@ export function csv( * the row is skipped and will be omitted from the array returned by dsv.csvParse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function csv( +export function csv( url: string, init: RequestInit, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): Promise>; /** @@ -90,15 +95,17 @@ export function csv( * * If init is specified, it is passed along to the underlying call to fetch. * + * The generic parameter describes the column names as a union of string literal types. + * * @param delimiter The delimiter character used in the DSV file to be fetched. * @param url A valid URL string. * @param init An optional request initialization object. */ -export function dsv( +export function dsv( delimiter: string, url: string, - init?: RequestInit, -): Promise>; + init?: RequestInit +): Promise>; /** * Fetches the DSV file with the specified delimiter character at the specified input URL and returns * a promise of an array of objects representing the parsed rows. @@ -106,7 +113,8 @@ export function dsv( * The specified row conversion function is used to map and filter row objects to a more-specific representation; * see dsv.parse for details. * - * The generic parameter describes the type of the object representation of a parsed row. + * The first generic parameter describes the type of the object representation of a parsed row. + * The second generic parameter describes the column names as a union of string literal types. * * @param delimiter The delimiter character used in the DSV file to be fetched. * @param url A valid URL string. @@ -115,10 +123,10 @@ export function dsv( * the row is skipped and will be omitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function dsv( +export function dsv( delimiter: string, url: string, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): Promise>; /** * Fetches the DSV file with the specified delimiter character at the specified input URL and returns @@ -129,7 +137,8 @@ export function dsv( * The specified row conversion function is used to map and filter row objects to a more-specific representation; * see dsv.parse for details. * - * The generic parameter describes the type of the object representation of a parsed row. + * The first generic parameter describes the type of the object representation of a parsed row. + * The second generic parameter describes the column names as a union of string literal types. * * @param delimiter The delimiter character used in the DSV file to be fetched. * @param url A valid URL string. @@ -139,11 +148,11 @@ export function dsv( * the row is skipped and will be omitted from the array returned by dsv.parse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function dsv( +export function dsv( delimiter: string, url: string, init: RequestInit, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): Promise>; /** @@ -164,7 +173,7 @@ export function html(url: string, init?: RequestInit): Promise; * @param url A valid URL string. * @param init An optional object of image properties to set. */ -export function image(url: string, init?: {[key: string]: any}): Promise; +export function image(url: string, init?: Partial): Promise; /** * Fetches the json file at the specified input URL and returns it as a Promise of a parsed JSON object. @@ -204,13 +213,15 @@ export function text(url: string, init?: RequestInit): Promise; * * If init is specified, it is passed along to the underlying call to fetch. * + * The generic parameter describes the column names as a union of string literal types. + * * @param url A valid URL string. * @param init An optional request initialization object. */ -export function tsv( +export function tsv( url: string, - init?: RequestInit, -): Promise>; + init?: RequestInit +): Promise>; /** * Fetches the TSV file at the specified input URL and returns * a promise of an array of objects representing the parsed rows. The values of the properties of the parsed row @@ -219,7 +230,8 @@ export function tsv( * The specified row conversion function is used to map and filter row objects to a more-specific representation; * see dsv.tsvParse for details. * - * The generic parameter describes the type of the object representation of a parsed row. + * The first generic parameter describes the type of the object representation of a parsed row. + * The second generic parameter describes the column names as a union of string literal types. * * @param url A valid URL string. * @param row A row conversion function which is invoked for each row, being passed an object representing the current row (d), @@ -227,9 +239,9 @@ export function tsv( * the row is skipped and will be omitted from the array returned by dsv.tsvParse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function tsv( +export function tsv( url: string, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): Promise>; /** * Fetches the TSV file at the specified input URL and returns @@ -240,7 +252,8 @@ export function tsv( * The specified row conversion function is used to map and filter row objects to a more-specific representation; * see dsv.tsvParse for details. * - * The generic parameter describes the type of the object representation of a parsed row. + * The first generic parameter describes the type of the object representation of a parsed row. + * The second generic parameter describes the column names as a union of string literal types. * * @param url A valid URL string. * @param init An request initialization object. @@ -249,10 +262,10 @@ export function tsv( * the row is skipped and will be omitted from the array returned by dsv.tsvParse; otherwise, the returned value defines the corresponding row object. * In effect, row is similar to applying a map and filter operator to the returned rows. */ -export function tsv( +export function tsv( url: string, init: RequestInit, - row: (rawRow: DSVRowString, index: number, columns: string[]) => ParsedRow | undefined | null + row: (rawRow: DSVRowString, index: number, columns: Columns[]) => ParsedRow | undefined | null ): Promise>; /** diff --git a/types/distributions/distributions-tests.ts b/types/distributions/distributions-tests.ts new file mode 100644 index 0000000000..04cb1b65bb --- /dev/null +++ b/types/distributions/distributions-tests.ts @@ -0,0 +1,17 @@ +import * as distributions from 'distributions'; + +const normal = distributions.Normal(); +normal.cdf(0); +normal.pdf(0); +normal.inv(0); +normal.mean(); +normal.median(); +normal.variance(); + +const uniform = distributions.Uniform(); +uniform.cdf(0); +uniform.pdf(0); +uniform.inv(0); +uniform.mean(); +uniform.median(); +uniform.variance(); diff --git a/types/distributions/index.d.ts b/types/distributions/index.d.ts new file mode 100644 index 0000000000..cdfbc93c6b --- /dev/null +++ b/types/distributions/index.d.ts @@ -0,0 +1,18 @@ +// Type definitions for distributions 2.0 +// Project: https://github.com/AndreasMadsen/distributions +// Definitions by: Marco Lanaro +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +export function Normal(mean?: number, sd?: number): Distribution; +export function Studentt(df: number): Distribution; +export function Uniform(a?: number, b?: number): Distribution; +export function Binomial(properbility: number, size: number): Distribution; + +export interface Distribution { + pdf: (x: number) => number; + cdf: (x: number) => number; + inv: (p: number) => number; + mean: () => number; + median: () => number; + variance: () => number; +} diff --git a/types/distributions/tsconfig.json b/types/distributions/tsconfig.json new file mode 100644 index 0000000000..995b1007ef --- /dev/null +++ b/types/distributions/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "esModuleInterop": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "distributions-tests.ts" + ] +} diff --git a/types/distributions/tslint.json b/types/distributions/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/distributions/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/draft-js/draft-js-tests.tsx b/types/draft-js/draft-js-tests.tsx index c0c64256fd..2375da74d4 100644 --- a/types/draft-js/draft-js-tests.tsx +++ b/types/draft-js/draft-js-tests.tsx @@ -315,6 +315,7 @@ ReactDOM.render( const editorState = EditorState.createEmpty(); const contentState = editorState.getCurrentContent(); +const entityMap = contentState.getEntityMap(); const rawContentState: RawDraftContentState = convertToRaw(contentState); rawContentState.blocks.forEach((block: RawDraftContentBlock) => { diff --git a/types/draft-js/index.d.ts b/types/draft-js/index.d.ts index 4f2c34dd3a..4c00e7598f 100644 --- a/types/draft-js/index.d.ts +++ b/types/draft-js/index.d.ts @@ -9,6 +9,7 @@ // Santiago Vilar // Ulf Schwekendiek // Pablo Varela +// Claudio Procida // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 @@ -754,6 +755,7 @@ declare namespace Draft { createEntity(type: DraftEntityType, mutability: DraftEntityMutability, data?: Object): ContentState; getEntity(key: string): EntityInstance; + getEntityMap(): any; getLastCreatedEntityKey(): string; mergeEntityData(key: string, toMerge: { [key: string]: any }): ContentState; replaceEntityData(key: string, toMerge: { [key: string]: any }): ContentState; diff --git a/types/expo/expo-tests.tsx b/types/expo/expo-tests.tsx index 57e028e8bf..481c1b27c4 100644 --- a/types/expo/expo-tests.tsx +++ b/types/expo/expo-tests.tsx @@ -47,6 +47,7 @@ import { Region, registerRootComponent, ScreenOrientation, + SecureStore, Svg, Updates } from 'expo'; @@ -484,6 +485,30 @@ async () => { isString(queryParams2['y'] || ''); }; +// #region securestore +async () => { + await SecureStore.setItemAsync('some-key', 'some-val', { + keychainService: "some-service", + keychainAccessible: SecureStore.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY, + }); + const result = await SecureStore.getItemAsync('some-key', { keychainService: "some-service" }); + if (result != null) { + result.slice() === 'some-val'; + } + await SecureStore.deleteItemAsync('some-key', { keychainService: "some-service" }); +}; + +const allSecureStoreKeychainAccessibleValues: number[] = [ + SecureStore.WHEN_UNLOCKED, + SecureStore.AFTER_FIRST_UNLOCK, + SecureStore.ALWAYS, + SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY, + SecureStore.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY, + SecureStore.AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY, + SecureStore.ALWAYS_THIS_DEVICE_ONLY, +]; +// #endregion + () => ( // Pavel Ihm // Bartosz Dotryw +// Jason Killian // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 @@ -2301,12 +2302,23 @@ export namespace ScreenOrientation { export namespace SecureStore { interface SecureStoreOptions { keychainService?: string; + } + + interface SecureStoreSetOptions extends SecureStoreOptions { keychainAccessible?: number; } - function setItemAsync(key: string, value: string, options?: SecureStoreOptions): Promise; + function setItemAsync(key: string, value: string, options?: SecureStoreSetOptions): Promise; function getItemAsync(key: string, options?: SecureStoreOptions): Promise; function deleteItemAsync(key: string, options?: SecureStoreOptions): Promise; + + const WHEN_UNLOCKED: number; + const AFTER_FIRST_UNLOCK: number; + const ALWAYS: number; + const WHEN_UNLOCKED_THIS_DEVICE_ONLY: number; + const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: number; + const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: number; + const ALWAYS_THIS_DEVICE_ONLY: number; } /** diff --git a/types/express-jwt/index.d.ts b/types/express-jwt/index.d.ts index 1187f4fbca..d1029849cc 100644 --- a/types/express-jwt/index.d.ts +++ b/types/express-jwt/index.d.ts @@ -58,10 +58,3 @@ declare namespace jwt { constructor(code: ErrorCode, error: { message: string }); } } -declare global { - namespace Express { - export interface Request { - user?: any - } - } -} diff --git a/types/express-rate-limit/express-rate-limit-tests.ts b/types/express-rate-limit/express-rate-limit-tests.ts index aa5c51a016..4b94ef6b05 100644 --- a/types/express-rate-limit/express-rate-limit-tests.ts +++ b/types/express-rate-limit/express-rate-limit-tests.ts @@ -3,7 +3,19 @@ import RateLimit = require("express-rate-limit"); const apiLimiter = new RateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, - delayMs: 0 // disabled + headers: false, + skipFailedRequests: false, + skipSuccessfulRequests: true, +}); + +const apiLimiterWithMaxFn = new RateLimit({ + windowMs: 15 * 60 * 1000, + max: () => 5, +}); + +const apiLimiterWithMaxPromiseFn = new RateLimit({ + windowMs: 15 * 60 * 1000, + max: () => Promise.resolve(5), }); const apiLimiterWithMessageObject = new RateLimit({ @@ -17,8 +29,6 @@ const apiLimiterWithMessageObject = new RateLimit({ const createAccountLimiter = new RateLimit({ windowMs: 60 * 60 * 1000, // 1 hour window - delayAfter: 1, // begin slowing down responses after the first request - delayMs: 3 * 1000, // slow down subsequent responses by 3 seconds per request max: 5, // start blocking after 5 requests message: "Too many accounts created from this IP, please try again after an hour", handler: (req, _, next) => next(new Error(`TooManyRequests: ${req.ip}`)) diff --git a/types/express-rate-limit/index.d.ts b/types/express-rate-limit/index.d.ts index b3f074f28d..9d3459e21b 100644 --- a/types/express-rate-limit/index.d.ts +++ b/types/express-rate-limit/index.d.ts @@ -1,6 +1,8 @@ -// Type definitions for express-rate-limit 2.9 +// Type definitions for express-rate-limit 3.3 // Project: https://github.com/nfriedly/express-rate-limit -// Definitions by: Cyril Schumacher , makepost +// Definitions by: Cyril Schumacher +// makepost +// Jeremy Forsythe // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.2 @@ -21,19 +23,80 @@ declare namespace RateLimit { [key: string]: any; } + type MaxValueFn = () => number | Promise; + interface Options { - delayAfter?: number; - delayMs?: number; + /** + * The funciton to handle requests once `max` is exceeded. It receives the request and response objects. + * The "next" param is available if you need to pass to the next middleware. The `req.rateLimit` object + * has `limit`, `current`, and `remaining` number of requests, and if the store provides it, a `resetTime` + * Date object. + * Default: `(req, res, next) => res.status(options.statusCode).send(options.message)` + */ handler?(req: express.Request, res: express.Response, next: express.NextFunction): any; + + /** + * Enable headers for request limit (`X-RateLimit-Limit`) and current usage (`X-RateLimit-Remaining`) on all + * responses andtime to wait before retrying (`Retry-After`) when `max` is exceeded. Defaults to `true`. + */ headers?: boolean; + + /** + * Function used to generate keys. Defaults to using `req.ip`. + * Default: `(req, res) => req.ip` + */ keyGenerator?(req: express.Request, res: express.Response): string; - max?: number; + + /** + * Max number of connections during `windowMs` before sending a 429 response. May be a `number` or + * a function that returns a `number` or a `Promise`. Defaults to `5`. Set to `0` to disable. + */ + max?: number | MaxValueFn; + + /** + * Error message sent to user when `max` is exceeded. May be a `string`, JSON object, or any other value + * that Express's `req.send()` supports. Defaults to `'Too many requests, please try again later.'`. + */ message?: string | Buffer | Message; - skip?(req: express.Request, res: express.Response): boolean; - skipFailedRequests?: boolean; - statusCode?: number; - store?: Store; + + /** + * Function that is called the first time `max` is exceeded. The `req.rateLimit` object has `limit`, `current`, + * and `remaining` number of requests and, if the store provides it, a `resetTime` Date object. Default is + * an empty function. + * Default: `(req, res, opts) => {}` + */ onLimitReached?(req: express.Request, res: express.Response, optionsUsed: Options): void; + + /** + * Function used to skip requests. Returning `true` from the function will skip limiting for that request. Defaults to + * always `false` (count all requests). + * Default: `(req, res) => false` + */ + skip?(req: express.Request, res: express.Response): boolean; + + /** + * When set to `true`, failed requests (status >= 400, request canceled or errored) won't be counted. Defaults to `false`. + */ + skipFailedRequests?: boolean; + + /** + * When set to `true`, successful requests (status < 400) won't be counted. Defaults to `false`. + */ + skipSuccessfulRequests?: boolean; + + /** + * HTTP status code returned when `max` is exceeded. Defaults to `429`. + */ + statusCode?: number; + + /** + * The storage to use when persisting rate limit attempts. + */ + store?: Store; + + /** + * How long in milliseconds to keep records of requests in memory. Defaults to `60000` (1 minute). + */ windowMs?: number; } } diff --git a/types/express-rate-limit/v2/express-rate-limit-tests.ts b/types/express-rate-limit/v2/express-rate-limit-tests.ts new file mode 100644 index 0000000000..aa5c51a016 --- /dev/null +++ b/types/express-rate-limit/v2/express-rate-limit-tests.ts @@ -0,0 +1,39 @@ +import RateLimit = require("express-rate-limit"); + +const apiLimiter = new RateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, + delayMs: 0 // disabled +}); + +const apiLimiterWithMessageObject = new RateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, + message: { + status: 429, + message: 'To many requests, try again later' + } +}); + +const createAccountLimiter = new RateLimit({ + windowMs: 60 * 60 * 1000, // 1 hour window + delayAfter: 1, // begin slowing down responses after the first request + delayMs: 3 * 1000, // slow down subsequent responses by 3 seconds per request + max: 5, // start blocking after 5 requests + message: "Too many accounts created from this IP, please try again after an hour", + handler: (req, _, next) => next(new Error(`TooManyRequests: ${req.ip}`)) +}); + +const callbackWithFewerParams = new RateLimit({ + handler: (req, res) => res.status(429).json(`TooManyRequests: ${req.ip}`) +}); + +class SomeStore implements RateLimit.Store { + incr(key: string, cb: RateLimit.StoreIncrementCallback) { } + decrement(key: string) { } + resetKey(key: string) { } +} + +const limiterWithStore = new RateLimit({ + store: new SomeStore() +}); diff --git a/types/express-rate-limit/v2/index.d.ts b/types/express-rate-limit/v2/index.d.ts new file mode 100644 index 0000000000..b3f074f28d --- /dev/null +++ b/types/express-rate-limit/v2/index.d.ts @@ -0,0 +1,42 @@ +// Type definitions for express-rate-limit 2.9 +// Project: https://github.com/nfriedly/express-rate-limit +// Definitions by: Cyril Schumacher , makepost +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.2 + +import express = require("express"); + +declare namespace RateLimit { + type StoreIncrementCallback = (err?: {}, hits?: number) => void; + + interface Store { + incr(key: string, cb: StoreIncrementCallback): void; + decrement(key: string): void; + resetKey(key: string): void; + } + + interface Message { + status: number; + message: string; + [key: string]: any; + } + + interface Options { + delayAfter?: number; + delayMs?: number; + handler?(req: express.Request, res: express.Response, next: express.NextFunction): any; + headers?: boolean; + keyGenerator?(req: express.Request, res: express.Response): string; + max?: number; + message?: string | Buffer | Message; + skip?(req: express.Request, res: express.Response): boolean; + skipFailedRequests?: boolean; + statusCode?: number; + store?: Store; + onLimitReached?(req: express.Request, res: express.Response, optionsUsed: Options): void; + windowMs?: number; + } +} + +declare var RateLimit: new (options: RateLimit.Options) => express.RequestHandler; +export = RateLimit; diff --git a/types/express-rate-limit/v2/tsconfig.json b/types/express-rate-limit/v2/tsconfig.json new file mode 100644 index 0000000000..0e9b4d2ad4 --- /dev/null +++ b/types/express-rate-limit/v2/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../../", + "typeRoots": [ + "../../" + ], + "paths": { + "express-rate-limit": ["express-rate-limit/v2"] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "express-rate-limit-tests.ts" + ] +} diff --git a/types/express-rate-limit/v2/tslint.json b/types/express-rate-limit/v2/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/express-rate-limit/v2/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/express-slow-down/express-slow-down-tests.ts b/types/express-slow-down/express-slow-down-tests.ts new file mode 100644 index 0000000000..e7d049bd7d --- /dev/null +++ b/types/express-slow-down/express-slow-down-tests.ts @@ -0,0 +1,31 @@ +import slowDown = require("express-slow-down"); + +const slowerAllDefaults = slowDown({}); + +const slowerWithOptions = slowDown({ + windowMs: 15 * 60 * 1000, // 15 minutes, + delayAfter: 1, + delayMs: 0, // disabled + skipFailedRequests: false, + skipSuccessfulRequests: true, +}); + +const slowerWithCallbacks = slowDown({ + keyGenerator: (req, res) => req.ip, + skip: (req, res) => false, + onLimitReached: (req, res, opts) => { + console.log(req.slowDown.current); + console.log(req.slowDown.remaining); + console.log(req.slowDown.limit); + }, +}); + +class MockStore implements slowDown.Store { + incr(key: string, cb: slowDown.StoreIncrementCallback) { } + decrement(key: string) { } + resetKey(key: string) { } +} + +const slowerWithStore = slowDown({ + store: new MockStore() +}); diff --git a/types/express-slow-down/index.d.ts b/types/express-slow-down/index.d.ts new file mode 100644 index 0000000000..f7aeab76fd --- /dev/null +++ b/types/express-slow-down/index.d.ts @@ -0,0 +1,111 @@ +// Type definitions for express-slow-down 1.1 +// Project: https://github.com/nfriedly/express-slow-down +// Definitions by: Jeremy Forsythe +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.2 + +import express = require("express"); + +declare namespace SlowDown { + type StoreIncrementCallback = (err?: {}, hits?: number) => void; + + interface SlowDownRequestAugmentation { + /** + * The `options.delayAfter` value + */ + limit: number; + + /** + * The number of requests in the current window + */ + current: number; + + /** + * the number of requests remaining before rate-limiting begins + */ + remaining: number; + + /** + * When the window will reset, `current` will return to `0`, and `remaining` will return + * to limit. Represents milliseconds since epoch (compare to `Date.now()`). This field + * depends on store support. It will be `undefined` if the store does not provide the value. + */ + resetTime?: number; + + /** + * Amount of delay imposed on current request in milliseconds + */ + delay: number; + } + + /** + * Express Request with the added `slowDown` property + */ + interface RequestWithSlowDown extends express.Request { + slowDown: SlowDownRequestAugmentation; + } + + interface Store { + incr(key: string, cb: StoreIncrementCallback): void; + decrement(key: string): void; + resetKey(key: string): void; + } + + /** + * express-slow-down options + */ + interface Options { + /** + * How long to keep records of requests in memory. Defaults to `60000` (1 minute) + */ + windowMs?: number; + + /** + * Max number of connections during `windowMs` before starting to delay responses. + * Defaults to `1`. Set to `0` to disable delaying. + */ + delayAfter?: number; + + /** + * How long to delay the response, multiplied by `(number recent hits - delayAfter)`. + * Defaults to `1000` (1 second). Set to `0` to disable delaying. + */ + delayMs?: number; + + /** + * When `true` failed requests (response status >= 400) won't be counted. Defaults to `false`. + */ + skipFailedRequests?: boolean; + + /** + * When `true` successful requests (response status < 400) won't be counted. Defaults to `false`. + */ + skipSuccessfulRequests?: boolean; + + /** + * Function used to generate keys. By default user IP address (`req.ip`) is used. + * Default: `(req, res) => req.ip` + */ + keyGenerator?(req: express.Request, res: express.Response): string; + + /** + * Function used to skip requests. Returning `true` from the function will skip delaying for that request. + * Default: `(req, res) => false` + */ + skip?(req: express.Request, res: express.Response): boolean; + + /** + * Function to execute the first time the limit is reached within `windowMs`. + * Default: `(req, res, opts) => {}` + */ + onLimitReached?(req: RequestWithSlowDown, res: express.Response, optionsUsed: Options): void; + + /** + * The storage to use when persisting request attempts. By default, the MemoryStore is used. + */ + store?: Store; + } +} + +declare function SlowDown(options: SlowDown.Options): express.RequestHandler; +export = SlowDown; diff --git a/types/express-slow-down/tsconfig.json b/types/express-slow-down/tsconfig.json new file mode 100644 index 0000000000..9973398566 --- /dev/null +++ b/types/express-slow-down/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "express-slow-down-tests.ts" + ] +} diff --git a/types/express-slow-down/tslint.json b/types/express-slow-down/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/express-slow-down/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/firefox-webext-browser/index.d.ts b/types/firefox-webext-browser/index.d.ts index 84dc4f15e7..9b318f9b4b 100644 --- a/types/firefox-webext-browser/index.d.ts +++ b/types/firefox-webext-browser/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for WebExtension Development in FireFox 64.0 +// Type definitions for WebExtension Development in FireFox 65.0 // Project: https://developer.mozilla.org/en-US/Add-ons/WebExtensions // Definitions by: Jasmin Bom // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped @@ -178,6 +178,8 @@ declare namespace browser._manifest { alternate_urls?: string[]; /** @deprecated Unsupported on Firefox. */ prepopulated_id?: number; + /** Encoding of the search term. */ + encoding?: string; /** Sets the default engine to a built-in engine only. */ is_default?: boolean; /** @@ -455,14 +457,17 @@ declare namespace browser._manifest { interface ThemeType { images?: { additional_backgrounds?: ImageDataOrExtensionURL[]; + /** @deprecated Please use _theme.images.theme_frame_, this alias will be removed in Firefox 69. */ headerURL?: ImageDataOrExtensionURL; theme_frame?: ImageDataOrExtensionURL; }; colors?: { tab_selected?: ThemeColor; + /** @deprecated Please use _theme.colors.frame_, this alias will be removed in Firefox 69. */ accentcolor?: ThemeColor; frame?: ThemeColor; frame_inactive?: ThemeColor; + /** @deprecated Please use _theme.colors.tab_background_text_, this alias will be removed in Firefox 69. */ textcolor?: ThemeColor; tab_background_text?: ThemeColor; tab_background_separator?: ThemeColor; @@ -470,6 +475,7 @@ declare namespace browser._manifest { tab_text?: ThemeColor; tab_line?: ThemeColor; toolbar?: ThemeColor; + /** @deprecated Please use _theme.colors.bookmark_text_, this alias will be removed in Firefox 69. */ toolbar_text?: ThemeColor; bookmark_text?: ThemeColor; toolbar_field?: ThemeColor; @@ -3535,11 +3541,6 @@ declare namespace browser.userScripts { unregister(): Promise; } - /** A set of API methods provided by the extensions to its userScripts */ - interface ExportedAPIMethods { - [key: string]: (...args: any[]) => any; - } - /* userScripts functions */ /** * Register a user script programmatically given its `userScripts.UserScriptOptions`, and resolves to a @@ -3547,12 +3548,28 @@ declare namespace browser.userScripts { */ function register(userScriptOptions: UserScriptOptions): Promise; + /* userScripts events */ /** - * Provides a set of custom API methods available to the registered userScripts + * Event called when a new userScript global has been created * * Allowed in: Content scripts only */ - function setScriptAPIs(exportedAPIMethods: ExportedAPIMethods): void; + const onBeforeScript: WebExtEvent<(userScript: { + /** The userScript metadata (as set in userScripts.register) */ + metadata: any; + /** The userScript global */ + global: any; + /** + * Exports all the properties of a given plain object as userScript globals + * @param sourceObject A plain object whose properties are exported as userScript globals + */ + defineGlobals: (sourceObject: object) => void; + /** + * Convert a given value to make it accessible to the userScript code + * @param value A value to convert into an object accessible to the userScript + */ + export: (value: any) => any; + }) => void>; } /** @@ -5570,16 +5587,24 @@ declare namespace browser.geckoProfiler { | "stackwalk" | "tasktracer" | "threads" - | "trackopts"; + | "trackopts" + | "jstracer"; + + type Supports = "windowLength"; /* geckoProfiler functions */ /** Starts the profiler with the specified settings. */ function start(settings: { /** - * The size in bytes of the buffer used to store profiling data. A larger value allows capturing a profile that - * covers a greater amount of time. + * The maximum size in bytes of the buffer used to store profiling data. A larger value allows capturing a + * profile that covers a greater amount of time. */ bufferSize: number; + /** + * The length of the window of time that's kept in the buffer. Any collected samples are discarded as soon as + * they are older than the number of seconds specified in this setting. Zero means no duration restriction. + */ + windowLength?: number; /** * Interval in milliseconds between samples of profiling data. A smaller value will increase the detail of the * profiles captured. @@ -5821,6 +5846,8 @@ declare namespace browser.contextMenus { * context where there is no current page, such as in a launcher context menu. */ pageUrl?: string; + /** The id of the frame of the element where the context menu was clicked. */ + frameId?: number; /** The URL of the frame of the element where the context menu was clicked, if it was in a frame. */ frameUrl?: string; /** The text for the context selection, if any. */ @@ -6100,6 +6127,8 @@ declare namespace browser.menus { * context where there is no current page, such as in a launcher context menu. */ pageUrl?: string; + /** The id of the frame of the element where the context menu was clicked. */ + frameId?: number; /** The URL of the frame of the element where the context menu was clicked, if it was in a frame. */ frameUrl?: string; /** The text for the context selection, if any. */ @@ -6939,6 +6968,8 @@ declare namespace browser.tabs { sharingState?: SharingState; /** Whether the tab is drawing attention. */ attention?: boolean; + /** The ID of this tab's successor, if any; `tabs.TAB_ID_NONE` otherwise. */ + successorTabId?: number; } /** @@ -7320,6 +7351,10 @@ declare namespace browser.tabs { openerTabId?: number; /** Whether the load should replace the current history entry for the tab. */ loadReplace?: boolean; + /** + * The ID of this tab's successor. If specified, the successor tab must be in the same window as this tab. + */ + successorTabId?: number; }): Promise; /** * Modifies the properties of a tab. Properties that are not specified in `updateProperties` are not modified. @@ -7349,6 +7384,10 @@ declare namespace browser.tabs { openerTabId?: number; /** Whether the load should replace the current history entry for the tab. */ loadReplace?: boolean; + /** + * The ID of this tab's successor. If specified, the successor tab must be in the same window as this tab. + */ + successorTabId?: number; }): Promise; /** @@ -7517,6 +7556,29 @@ declare namespace browser.tabs { */ function hide(tabIds: number | number[]): Promise; + /** + * Removes an array of tabs from their lines of succession and prepends or appends them in a chain to another tab. + * @param tabIds An array of tab IDs to move in the line of succession. For each tab in the array, the tab's + * current predecessors will have their successor set to the tab's current successor, and each tab will then be + * set to be the successor of the previous tab in the array. Any tabs not in the same window as the tab + * indicated by the second argument (or the first tab in the array, if no second argument) will be skipped. + * @param [tabId] The ID of a tab to set as the successor of the last tab in the array, or `tabs.TAB_ID_NONE` to + * leave the last tab without a successor. If options.append is true, then this tab is made the predecessor of + * the first tab in the array instead. + */ + function moveInSuccession(tabIds: number[], tabId?: number, options?: { + /** Whether to move the tabs before (false) or after (true) tabId in the succession. Defaults to false. */ + append?: boolean; + /** + * Whether to link up the current predecessors or successor (depending on options.append) of tabId to the other + * side of the chain after it is prepended or appended. If true, one of the following happens: if + * options.append is false, the first tab in the array is set as the successor of any current predecessors of + * tabId; if options.append is true, the current successor of tabId is set as the successor of the last tab in + * the array. Defaults to false. + */ + insert?: boolean; + }): Promise; + /* tabs events */ /** * Fired when a tab is created. Note that the tab's URL may not be set at the time this event fired, but you can @@ -7571,6 +7633,8 @@ declare namespace browser.tabs { const onActivated: WebExtEvent<(activeInfo: { /** The ID of the tab that has become active. */ tabId: number; + /** The ID of the tab that was previously active, if that tab is still open. */ + previousTabId?: number; /** The ID of the window the active tab changed inside of. */ windowId: number; }) => void>; diff --git a/types/google.script.client-side/google.script.client-side-tests.ts b/types/google.script.client-side/google.script.client-side-tests.ts new file mode 100644 index 0000000000..5e3c059c01 --- /dev/null +++ b/types/google.script.client-side/google.script.client-side-tests.ts @@ -0,0 +1,39 @@ +google.script.url.getLocation(location => { + location.hash; // $ExpectedType string + location.parameter; // $ExpectedType { [key: string]: string } + location.parameters; // $ExpectedType { [key: string]: ReadonlyArray } +}); + +google.script.history.push(null); +google.script.history.push({ timestamp: Date.now() }, { foo: 'bar', fiz: 'baz' }); +google.script.history.push({ timestamp: Date.now() }, { foo: ['bar', 'cat'], fiz: 'baz' }, 'anchor1'); + +google.script.history.replace(null); +google.script.history.replace({ timestamp: Date.now() }, { foo: 'bar', fiz: 'baz' }); +google.script.history.replace({ timestamp: Date.now() }, { foo: ['bar', 'cat'], fiz: 'baz' }, 'anchor1'); + +google.script.history.setChangeHandler(e => { + e.state; // $ExpectedType google.script.history.State + e.location.hash; // $ExpectedType string + e.location.parameter; // $ExpectedType { [key: string]: string } + e.location.parameters; // $ExpectedType { [key: string]: ReadonlyArray } +}); + +google.script.host.origin; // $ExpectType string +google.script.host.close(); +google.script.host.editor.focus(); +google.script.host.setHeight(450); +google.script.host.setWidth(300); + +google.script.run.withSuccessHandler(() => {}).executeScript({ message: 'test for google.script.run' }); + +google.script.run + .withSuccessHandler(value => {}) + .withFailureHandler(error => {}) + .getEmail(); + +google.script.run + .withSuccessHandler((value, userObject) => {}) + .withFailureHandler((error, userObject) => {}) + .withUserObject({}) + .getSomeData(Date.now(), { options: 'none' }, 'anchor1', true, null); diff --git a/types/google.script.client-side/index.d.ts b/types/google.script.client-side/index.d.ts new file mode 100644 index 0000000000..566fbb7397 --- /dev/null +++ b/types/google.script.client-side/index.d.ts @@ -0,0 +1,151 @@ +// Type definitions for Google Apps Script Client-side API 0.0 +// Project: https://developers.google.com/apps-script/guides/html/reference/host +// Definitions by: clomie +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.2 + +declare namespace google.script { + interface UrlLocation { + /** + * The string value of URL fragment after the # character, or an emptry string if no URL fragment is present + */ + hash: string; + + /** + * An object of key/value pairs that correspond to the URL request parameters. + * Only the first value will be returned for parameters that have multiple values. + * If no parameters are present, this will be an empty object. + */ + parameter: { [key: string]: string }; + + /** + * An object similar to location.parameter, but with an array of values for each key. + * If no parameters are present, this will be an empty object. + */ + parameters: { [key: string]: ReadonlyArray }; + } + + namespace url { + /** + * Gets a URL location object and passes it to the specified callback function (as the only argument). + * @param callback a client-side callback function to run, using the location object as the only argument. + */ + function getLocation(callback: (location: UrlLocation) => void): void; + } + + namespace history { + type State = object | null; + interface Query { + [key: string]: string | ReadonlyArray; + } + + /** + * Pushes the provided state object, URL parameters and URL fragment onto the browser history stack. + * @param stateObject An developer-defined object to be associated with a browser history event, and which resurfaces when the state is popped. + * Typically used to store application state information (such as page data) for future retrieval. + * @param params An object containing URL parameters to associate with this state. + * For example, {foo: “bar”, fiz: “baz”} equates to "?foo=bar&fiz=baz". + * Alternatively, arrays can be used: {foo: [“bar”, “cat”], fiz: “baz”} equates to "?foo=bar&foo=cat&fiz=baz". + * If null or undefined, the current URL parameters are not changed. If empty, the URL parameters are cleared. + * @param hash The string URL fragment appearing after the '#' character. + * If null or undefined, the current URL fragment is not changed. If empty, the URL fragment is cleared. + */ + function push(stateObject: State, params?: Query, hash?: string): void; + + /** + * Replaces the top event on the browser history stack with the provided (developer-defined) state object, URL parameters and URL fragment. + * @param stateObject An developer-defined object to be associated with a browser history event, and which resurfaces when the state is popped. + * Typically used to store application state information (such as page data) for future retrieval. + * @param params An object containing URL parameters to associate with this state. + * For example, {foo: “bar”, fiz: “baz”} equates to "?foo=bar&fiz=baz". + * Alternatively, arrays can be used: {foo: [“bar”, “cat”], fiz: “baz”} equates to "?foo=bar&foo=cat&fiz=baz". + * If null or undefined, the current URL parameters are not changed. If empty, the URL parameters are cleared. + * @param hash The string URL fragment appearing after the '#' character. + * If null or undefined, the current URL fragment is not changed. If empty, the URL fragment is cleared. + */ + function replace(stateObject: State, params?: Query, hash?: string): void; + + interface HistoryChangeEvent { + /** + * The state object associated with the popped event. + * This object is identical to the state object that used in the corresponding push() or replace() method that added the popped state to the history stack. + */ + state: State; + + /** + * A location object associated with the popped event + */ + location: UrlLocation; + } + + /** + * Sets a callback function to respond to changes in the browser history. + * @param callback a client-side callback function to run upon a history change event, using the event object as the only argument. + */ + function setChangeHandler(handler: (event: HistoryChangeEvent) => void): void; + } + + namespace host { + /** + * Provides the host domain, so scripts can set their origin correctly. + */ + const origin: string; + + /** + * Closes the current dialog or sidebar. + */ + function close(): void; + + namespace editor { + /** + * Switches browser focus from the dialog or sidebar to the Google Docs, Sheets, or Forms editor. + */ + function focus(): void; + } + + /** + * Sets the height of the current dialog. + * @param height the new height, in pixels + */ + function setHeight(height: number): void; + + /** + * Sets the width of the current dialog. + * @param width the new width, in pixels + */ + function setWidth(width: number): void; + } + + const run: Runner; + + interface Runner { + /** + * Executes the server-side Apps Script function with the corresponding name. + */ + [functionName: string]: (...args: any[]) => void; + + /** + * Sets a callback function to run if the server-side function throws an exception. + * Without a failure handler, failures are logged to the JavaScript console. + * To override this, call withFailureHandler(null) or supply a failure handler that does nothing. + * @param handler a client-side callback function to run if the server-side function throws an exception; + * the Error object is passed to the function as the first argument, and the user object (if any) is passed as a second argument + */ + withFailureHandler(handler: (error: Error, object?: any) => void): Runner; + + /** + * Sets a callback function to run if the server-side function returns successfully. + * @param handler a client-side callback function to run if the server-side function returns successfully; + * the server's return value is passed to the function as the first argument, and the user object (if any) is passed as a second argument + */ + withSuccessHandler(handler: (value?: any, object?: any) => void): Runner; + + /** + * Sets an object to pass as a second parameter to the success and failure handlers. + * @param object an object to pass as a second parameter to the success and failure handlers; + * because user objects are not sent to the server, they are not subject to the restrictions on parameters and return values for server calls. + * User objects cannot, however, be objects constructed with the new operator + */ + withUserObject(object: any): Runner; + } +} diff --git a/types/google.script.client-side/tsconfig.json b/types/google.script.client-side/tsconfig.json new file mode 100644 index 0000000000..83c99e2f06 --- /dev/null +++ b/types/google.script.client-side/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "google.script.client-side-tests.ts" + ] +} diff --git a/types/google.script.client-side/tslint.json b/types/google.script.client-side/tslint.json new file mode 100644 index 0000000000..f93cf8562a --- /dev/null +++ b/types/google.script.client-side/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +} diff --git a/types/got/got-tests.ts b/types/got/got-tests.ts index 1626cae86a..d80d0aadcf 100644 --- a/types/got/got-tests.ts +++ b/types/got/got-tests.ts @@ -286,3 +286,75 @@ got('http://todomvc.com', { // Test got.TimeoutError. got('http://todomvc.com', {timeout: 1}).catch((err) => err instanceof got.TimeoutError); + +// Test hooks. +got('example.com', { + hooks: { + beforeRedirect: [ + options => { + if (options.hostname === 'deadSite') { + options.hostname = 'fallbackSite'; + } + } + ] + } +}); +got('example.com', { + hooks: { + beforeRetry: [ + (options, error, retryCount) => { + if (error instanceof got.HTTPError && error.statusCode === 413) { // Payload too large + options.body = 'new body'; + } + } + ] + } +}); +got('example.com', { + hooks: { + afterResponse: [ + (response, retryWithMergedOptions) => { + if (response.statusCode === 401) { // Unauthorized + const updatedOptions = { + headers: { + token: 'new token' // Refresh the access token + } + }; + + // Make a new retry + return retryWithMergedOptions(updatedOptions); + } + + // No changes otherwise + return response; + } + ] + } +}); +// Test async hooks. +{ + const doSomethingAsync = (): Promise => { + throw new Error('unimplemented'); + }; + + got('example.com', { + hooks: { + beforeRedirect: [ + async () => { + await doSomethingAsync(); + } + ], + beforeRetry: [ + async () => { + await doSomethingAsync(); + } + ], + afterResponse: [ + async (response) => { + await doSomethingAsync(); + return response; + } + ] + } + }); +} diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 079e84ff62..09b451f4bb 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for got 9.2 +// Type definitions for got 9.3 // Project: https://github.com/sindresorhus/got#readme // Definitions by: BendingBender // Linus Unnebäck @@ -102,12 +102,50 @@ declare namespace got { type GotUrl = string | https.RequestOptions | Url | URL; - type Hook = (options: T) => any; - type Hooks = Record<'beforeRequest', Array>>; + /** + * Hooks allow modifications during the request lifecycle. Hook functions may be async and are + * run serially. + * + * @see https://github.com/sindresorhus/got#hooks + * @template Options Request options. + * @template Body Response body type. + */ + interface Hooks { + beforeRequest?: Array>; + beforeRedirect?: Array>; + beforeRetry?: Array>; + afterResponse?: Array>; + } + + /** + * @param options Normalized request options. + */ + type BeforeRequestHook = (options: Options) => any; + + /** + * @param options Normalized request options. + */ + type BeforeRedirectHook = (options: Options) => any; + + /** + * @param options Normalized request options. + * @param error Request error. + * @param retryCount Number of retry. + */ + type BeforeRetryHook = (options: Options, error: GotError, retryCount: number) => any; + + /** + * @param response Response object. + * @param retryWithMergedOptions Retries request with the updated options. + */ + type AfterResponseHook = ( + response: Response, + retryWithMergedOptions: (updateOptions: Options) => GotPromise + ) => Response | Promise>; interface GotBodyOptions extends GotOptions { body?: string | Buffer | nodeStream.Readable; - hooks?: Hooks>; + hooks?: Hooks, string | Buffer | nodeStream.Readable>; } interface GotJSONOptions extends GotOptions { @@ -115,14 +153,14 @@ declare namespace got { body?: object; form?: boolean; json: true; - hooks?: Hooks; + hooks?: Hooks; } interface GotFormOptions extends GotOptions { - body?: {[key: string]: any}; + body?: Record; form: true; json?: boolean; - hooks?: Hooks>; + hooks?: Hooks, Record>; } interface GotOptions extends InternalRequestOptions { diff --git a/types/hibp/hibp-tests.ts b/types/hibp/hibp-tests.ts deleted file mode 100644 index cdcd1851bf..0000000000 --- a/types/hibp/hibp-tests.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as hibp from 'hibp'; - -hibp -.search('someAccountOrEmail') -.then(data => { - if (data.breaches || data.pastes) { - // Bummer... - console.log(data); - } else { - // Phew! We're clear. - console.log('Good news — no pwnage found!'); - } -}) -.catch(err => { - // Something went wrong. - console.log(err.message); -}); diff --git a/types/hibp/index.d.ts b/types/hibp/index.d.ts deleted file mode 100644 index 27819f1c96..0000000000 --- a/types/hibp/index.d.ts +++ /dev/null @@ -1,97 +0,0 @@ -// Type definitions for hibp 7.2 -// Project: https://github.com/wkovacs64/hibp -// Definitions by: Silas Rech -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.8 - -/// - -export interface BreachOptions { - domain?: string; - truncate?: boolean; -} - -export interface Breach { - Name: string; - Title: string; - Domain: string; - BreachDate: string; - AddedDate: string; - ModifiedDate: string; - PwnCount: number; - Description: string; - LogoPath: string; - DataClasses: string[]; - IsVerified: boolean; - IsFabricated: boolean; - IsSensitive: boolean; - IsRetired: boolean; - IsSpamList: boolean; -} - -export interface Paste { - Id: string; - Source: string; - Title: string; - Date: string; - EmailCount: number; -} - -export interface Range { - suffix: string; - count: number; -} - -/** - * Fetches data for a specific breach event. - */ -export function breach(breachName: string): Promise; - -/** - * Fetches breach data for a specific account. - */ -export function breachedAccount(account: string, options?: BreachOptions): Promise; - -/** - * Fetches all breach events in the system. - */ -export function breaches(options?: { domain?: string }): Promise; - -/** - * Fetches all data classes in the system. - */ -export function dataClasses(): Promise; - -/** - * Fetches paste data for a specific email address. - */ -export function pasteAccount(email: string): Promise; - -/** - * Fetches the number of times the the given password has been exposed in a breach (0 indicating no exposure). - * The password is given in plain text, but only the first 5 characters of its SHA-1 hash will be submitted to the API. - */ -export function pwnedPassword(password: string): Promise; - -/** - * Fetches the SHA-1 hash suffixes for the given 5-character SHA-1 hash prefix. - * - * When a password hash with the same first 5 characters is found in the Pwned Passwords repository, - * the API will respond with an HTTP 200 and include the suffix of every hash beginning with the specified prefix, - * followed by a count of how many times it appears in the data set. - * - * This function parses the response and returns a more structured format. - */ -export function pwnedPasswordRange(prefix: string): Promise; - -/** - * Fetches all breaches and all pastes associated with the provided account (email address or username). - * - * Note that the remote API does not support querying pastes by username (only email addresses), - * so in the event the provided account is not a valid email address, - * only breach data is queried and the "pastes" field of the resulting object will always be null. - * - * This is exactly how searching via the current web interface behaves, which this convenience method is designed to mimic. - * - */ -export function search(account: string, options?: BreachOptions): Promise<{ breaches?: Breach[], pastes?: Paste[] }>; diff --git a/types/iobroker/index.d.ts b/types/iobroker/index.d.ts index 314d8c8e30..81381d801d 100644 --- a/types/iobroker/index.d.ts +++ b/types/iobroker/index.d.ts @@ -828,10 +828,12 @@ declare global { ca: Array; } + type MessagePayload = string | Record; + /** Callback information for a passed message */ interface MessageCallbackInfo { /** The original message payload */ - message: string | object; + message: MessagePayload; /** ID of this callback */ id: number; // ??? @@ -839,14 +841,13 @@ declare global { /** Timestamp of this message */ time: number; } - type MessageCallback = (result?: any) => void; /** A message being passed between adapter instances */ interface Message { /** The command to be executed */ command: string; /** The message payload */ - message: string | object; + message: MessagePayload; /** The source of this message */ from: string; /** ID of this message */ @@ -1038,8 +1039,8 @@ declare global { * @param command (optional) Command name of the target instance. Default: "send" * @param message The message (e.g. params) to send. */ - sendTo(instanceName: string, message: string | object, callback?: MessageCallback | MessageCallbackInfo): void; - sendTo(instanceName: string, command: string, message: string | object, callback?: MessageCallback | MessageCallbackInfo): void; + sendTo(instanceName: string, message: MessagePayload, callback?: MessageCallback | MessageCallbackInfo): void; + sendTo(instanceName: string, command: string, message: MessagePayload, callback?: MessageCallback | MessageCallbackInfo): void; /** * Sends a message to a specific instance or all instances of some specific adapter. * @param instanceName The instance to send this message to. @@ -1048,18 +1049,18 @@ declare global { * @param command (optional) Command name of the target instance. Default: "send" * @param message The message (e.g. params) to send. */ - sendToAsync(instanceName: string, message: string | object): Promise; - sendToAsync(instanceName: string, command: string, message: string | object): Promise; + sendToAsync(instanceName: string, message: MessagePayload): Promise; + sendToAsync(instanceName: string, command: string, message: MessagePayload): Promise; /** * Sends a message to a specific host or all hosts. */ - sendToHost(hostName: string, message: string | object, callback?: MessageCallback | MessageCallbackInfo): void; - sendToHost(hostName: string, command: string, message: string | object, callback?: MessageCallback | MessageCallbackInfo): void; + sendToHost(hostName: string, message: MessagePayload, callback?: MessageCallback | MessageCallbackInfo): void; + sendToHost(hostName: string, command: string, message: MessagePayload, callback?: MessageCallback | MessageCallbackInfo): void; /** * Sends a message to a specific host or all hosts. */ - sendToHostAsync(hostName: string, message: string | object): Promise; - sendToHostAsync(hostName: string, command: string, message: string | object): Promise; + sendToHostAsync(hostName: string, message: MessagePayload): Promise; + sendToHostAsync(hostName: string, command: string, message: MessagePayload): Promise; /** Convert ID to {device: D, channel: C, state: S} */ idToDCS(id: string): { @@ -1125,9 +1126,9 @@ declare global { getForeignObjects(pattern: string, type: ObjectType, enums: EnumList, options: unknown, callback: GetObjectsCallback): void; // tslint:enable:unified-signatures /** Get foreign objects by pattern, by specific type and resolve their enums. */ - getForeignObjectsAsync(pattern: string, options?: unknown): Promise>; - getForeignObjectsAsync(pattern: string, type: ObjectType, options?: unknown): Promise>; - getForeignObjectsAsync(pattern: string, type: ObjectType, enums: EnumList, options?: unknown): Promise>; + getForeignObjectsAsync(pattern: string, options?: unknown): Promise>; + getForeignObjectsAsync(pattern: string, type: ObjectType, options?: unknown): Promise>; + getForeignObjectsAsync(pattern: string, type: ObjectType, enums: EnumList, options?: unknown): Promise>; /** Creates or overwrites an object (which might not belong to this adapter) in the object db */ setForeignObject(id: string, obj: ioBroker.SettableObject, callback?: SetObjectCallback): void; setForeignObject(id: string, obj: ioBroker.SettableObject, options: unknown, callback?: SetObjectCallback): void; @@ -1591,6 +1592,8 @@ declare global { // TODO: Redefine callbacks as subclass of GenericCallback type GenericCallback = (err: string | null, result?: T) => void; + type MessageCallback = (response?: Message) => void; + type SetObjectCallback = (err: string | null, obj: { id: string }) => void; type GetObjectCallback = (err: string | null, obj: ioBroker.Object | null | undefined) => void; type GetEnumCallback = (err: string | null, enums: Record, requestedEnum: string) => void; diff --git a/types/iobroker/iobroker-tests.ts b/types/iobroker/iobroker-tests.ts index fcdc4d5c9e..f49eb34576 100644 --- a/types/iobroker/iobroker-tests.ts +++ b/types/iobroker/iobroker-tests.ts @@ -99,7 +99,8 @@ function messageHandler(msg: ioBroker.Message) { msg.callback.time.toFixed(); msg.command.toLowerCase(); msg.from.toLowerCase(); - msg.message.toString(); + typeof msg.message === "object" && msg.message.anything; + typeof msg.message === "string" && msg.message.toLowerCase(); } function unloadHandler(callback: ioBroker.EmptyCallback) { @@ -170,6 +171,9 @@ adapter.getForeignObject("obj.id", (err, obj) => { }); adapter.getObjectAsync("obj.id").then(obj => obj._id.toLowerCase()); adapter.getForeignObjectAsync("obj.id").then(obj => obj._id.toLowerCase()); +adapter.getForeignObjects("*", (err, objs) => objs["foo"]._id.toLowerCase()); +adapter.getForeignObjectsAsync("*").then(objs => objs["foo"]._id.toLowerCase()); + adapter.subscribeObjects("*"); adapter.subscribeStates("*"); adapter.subscribeForeignObjects("*"); @@ -195,3 +199,45 @@ switch (adapter.log.level) { default: assertNever(adapter.log.level); } + +adapter.sendTo("foo.0", "command", "message"); +adapter.sendTo("foo.0", "message"); +adapter.sendTo("foo.0", "command", {msg: "message"}); +adapter.sendTo("foo.0", {msg: "message"}); + +function handleMessageResponse(response?: ioBroker.Message) { + if (!response) return; + response._id.toFixed(); + response.callback.ack.valueOf(); + response.callback.id.toFixed(); + response.callback.message.toString(); + response.callback.time.toFixed(); + response.command.toLowerCase(); + response.from.toLowerCase(); + typeof response.message === "object" && response.message.anything; + typeof response.message === "string" && response.message.toLowerCase(); +} +adapter.sendTo("foo.0", "command", "message", handleMessageResponse); +adapter.sendTo("foo.0", "message", handleMessageResponse); +adapter.sendTo("foo.0", "command", {msg: "message"}, handleMessageResponse); +adapter.sendTo("foo.0", {msg: "message"}, handleMessageResponse); + +adapter.sendToAsync("foo.0", "command", "message").then(handleMessageResponse); +adapter.sendToAsync("foo.0", "message").then(handleMessageResponse); +adapter.sendToAsync("foo.0", "command", {msg: "message"}).then(handleMessageResponse); +adapter.sendToAsync("foo.0", {msg: "message"}).then(handleMessageResponse); + +adapter.sendToHost("host-foo", "command", "message"); +adapter.sendToHost("host-foo", "message"); +adapter.sendToHost("host-foo", "command", {msg: "message"}); +adapter.sendToHost("host-foo", {msg: "message"}); + +adapter.sendToHost("host-foo", "command", "message", handleMessageResponse); +adapter.sendToHost("host-foo", "message", handleMessageResponse); +adapter.sendToHost("host-foo", "command", {msg: "message"}, handleMessageResponse); +adapter.sendToHost("host-foo", {msg: "message"}, handleMessageResponse); + +adapter.sendToHostAsync("host-foo", "command", "message").then(handleMessageResponse); +adapter.sendToHostAsync("host-foo", "message").then(handleMessageResponse); +adapter.sendToHostAsync("host-foo", "command", {msg: "message"}).then(handleMessageResponse); +adapter.sendToHostAsync("host-foo", {msg: "message"}).then(handleMessageResponse); diff --git a/types/is-valid-path/index.d.ts b/types/is-valid-path/index.d.ts new file mode 100644 index 0000000000..2aa54e3e99 --- /dev/null +++ b/types/is-valid-path/index.d.ts @@ -0,0 +1,8 @@ +// Type definitions for is-valid-path 0.1 +// Project: https://github.com/jonschlinkert/is-valid-path +// Definitions by: Zlatko Andonovski +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare function isValidPath(path?: string | null): boolean; + +export = isValidPath; diff --git a/types/is-valid-path/is-valid-path-tests.ts b/types/is-valid-path/is-valid-path-tests.ts new file mode 100644 index 0000000000..a0ca7ac1a9 --- /dev/null +++ b/types/is-valid-path/is-valid-path-tests.ts @@ -0,0 +1,18 @@ +// Tests are from the NPM README (https://www.npmjs.com/package/is-valid-path). + +import isValid = require('is-valid-path'); + +isValid('abc.js'); +isValid('abc/def/ghi.js'); +isValid('foo.js'); + +isValid(); +isValid(null); +isValid('!foo.js'); +isValid('*.js'); +isValid('**/abc.js'); +isValid('abc/*.js'); +isValid('abc/(aaa|bbb).js'); +isValid('abc/[a-z].js'); +isValid('abc/{a,b}.js'); +isValid('abc/?.js'); diff --git a/types/is-valid-path/tsconfig.json b/types/is-valid-path/tsconfig.json new file mode 100644 index 0000000000..da95d11317 --- /dev/null +++ b/types/is-valid-path/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "is-valid-path-tests.ts" + ] +} diff --git a/types/is-valid-path/tslint.json b/types/is-valid-path/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/is-valid-path/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/jasmine-given/index.d.ts b/types/jasmine-given/index.d.ts index e2b630eccd..df2fe424a9 100644 --- a/types/jasmine-given/index.d.ts +++ b/types/jasmine-given/index.d.ts @@ -3,9 +3,17 @@ // Definitions by: Shai Reznik // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare function Given(func: (done?: () => void) => void): void; -declare function When(func: (done?: () => void) => void): void; -declare function Then(func: (done?: () => void) => void): void; -declare function Then(label: string, func: (done?: () => void) => void): void; -declare function And(func: (done?: () => void) => void): void; -declare function Invariant(func: (done?: () => void) => void): void; +/** Action method that should be called when the async work is complete */ +interface DoneFn { + (): void; + + /** fails the spec and indicates that it has completed. If the message is an Error, Error.message is used */ + fail: (message?: Error | string) => void; +} + +declare function Given(func: (done?: DoneFn) => void): void; +declare function When(func: (done?: DoneFn) => void): void; +declare function Then(func: (done?: DoneFn) => void): void; +declare function Then(label: string, func: (done?: DoneFn) => void): void; +declare function And(func: (done?: DoneFn) => void): void; +declare function Invariant(func: (done?: DoneFn) => void): void; diff --git a/types/jasmine-given/jasmine-given-tests.ts b/types/jasmine-given/jasmine-given-tests.ts index 7658502b68..10a6b824fe 100644 --- a/types/jasmine-given/jasmine-given-tests.ts +++ b/types/jasmine-given/jasmine-given-tests.ts @@ -39,3 +39,33 @@ Invariant((done) => { done(); } }); + +Given((done) => { + if (done) { + done.fail(); + } +}); + +When((done) => { + if (done) { + done.fail(); + } +}); + +Then('expected condition 2', (done) => { + if (done) { + done.fail(); + } +}); + +And((done) => { + if (done) { + done.fail(); + } +}); + +Invariant((done) => { + if (done) { + done.fail(); + } +}); diff --git a/types/jest/index.d.ts b/types/jest/index.d.ts index 6fb82e76b2..4073e21087 100644 --- a/types/jest/index.d.ts +++ b/types/jest/index.d.ts @@ -39,11 +39,15 @@ interface NodeRequire { /** * Returns the actual module instead of a mock, bypassing all checks on * whether the module should receive a mock implementation or not. + * + * @deprecated Use `jest.requireActual` instead. */ requireActual(moduleName: string): any; /** * Returns a mock module instead of the actual module, bypassing all checks * on whether the module should be required normally or not. + * + * @deprecated Use `jest.requireMock`instead. */ requireMock(moduleName: string): any; } @@ -127,6 +131,16 @@ declare namespace jest { * Mocks a module with an auto-mocked version when it is being required. */ function mock(moduleName: string, factory?: any, options?: MockOptions): typeof jest; + /** + * Returns the actual module instead of a mock, bypassing all checks on + * whether the module should receive a mock implementation or not. + */ + function requireActual(moduleName: string): any; + /** + * Returns a mock module instead of the actual module, bypassing all checks + * on whether the module should be required normally or not. + */ + function requireMock(moduleName: string): any; /** * Resets the module registry - the cache of all required modules. This is * useful to isolate modules where local state might conflict between tests. diff --git a/types/jest/jest-tests.ts b/types/jest/jest-tests.ts index de1ba90456..4164e009e4 100644 --- a/types/jest/jest-tests.ts +++ b/types/jest/jest-tests.ts @@ -251,6 +251,12 @@ jest .useFakeTimers() .useRealTimers(); +// https://jestjs.io/docs/en/jest-object#jestrequireactualmodulename +jest.requireActual("./thisReturnsTheActualModule"); + +// https://jestjs.io/docs/en/jest-object#jestrequiremockmodulename +jest.requireMock("./thisAlwaysReturnsTheMock"); + /* Mocks and spies */ const mock1: jest.Mock = jest.fn(); diff --git a/types/johnny-five/index.d.ts b/types/johnny-five/index.d.ts index a770cd2126..53716f9b33 100644 --- a/types/johnny-five/index.d.ts +++ b/types/johnny-five/index.d.ts @@ -4,6 +4,7 @@ // Zoltan Ujvary // Simon Colmer // XtrimSystems +// Marcin Obiedziński // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// @@ -111,11 +112,10 @@ export declare class Board { io: any; id: string; - repl: any; + repl: Repl; isReady: boolean; pins: Array; port: string; - inject: Repl; on(event: string, cb: () => void): this; on(event: "ready", cb: () => void): this; diff --git a/types/js-combinatorics/index.d.ts b/types/js-combinatorics/index.d.ts index 702ef1f9a2..8023aeff73 100644 --- a/types/js-combinatorics/index.d.ts +++ b/types/js-combinatorics/index.d.ts @@ -8,7 +8,7 @@ declare namespace __Combinatorics { interface IGenerator { /** - * Returns the element or undefined if no more element is available. + * Returns the element or undefined if no more elements are available. */ next():T; @@ -18,24 +18,24 @@ declare namespace __Combinatorics { forEach(f:(item:T) => void):void; /** - * All elements at once with function applied to each element. + * Returns an array that is the output of calling the callback function separately on each element. */ map(f:(item:T) => TResult):TResult[]; /** - * Returns an array with elements that passes the filter function. + * Returns an array of elements that return `true` for the filter function. */ filter(predicate:(item:T) => boolean):T[]; /** - * All elements at once. + * Returns an array of all elements. */ toArray():T[]; /** - * Returns the number of elements to be generated which equals to generator.toArray().length - * but it is precalculated without actually generating elements. - * Handy when you prepare for large iteration. + * Returns the total number of elements to be generated. This equals the result of calling + * `generator.toArray().length` but it is precalculated without actually generating any elements. + * Handy when doing setup for a potentially long-running loop. */ length:number; @@ -44,7 +44,7 @@ declare namespace __Combinatorics { interface IPredictableGenerator extends IGenerator { /** - * Returns the nth element (starting 0). + * Returns the nth element (indexed from 0). */ nth(n:number):T; @@ -53,11 +53,10 @@ declare namespace __Combinatorics { interface ICartesianProductGenerator extends IPredictableGenerator { /** - * Arguments are coordinates in integer. - * Arguments can be out of bounds but it returns undefined in such cases. + * Arguments are integer coordinates. + * Arguments can be out of bounds but it returns `undefined` in such cases. */ get(...coordinates:number[]):T; - } /** @@ -76,46 +75,47 @@ declare namespace __Combinatorics { function factorial(n:number):number; /** - * Returns the factoradic representation of n in array, in least significant order. + * Returns the factoradic representation of `n` in an array, in + * least significant order. * See http://en.wikipedia.org/wiki/Factorial_number_system */ function factoradic(n:number):number[]; /** - * Generates the power set of array. + * Generates the power set of `a`. */ function power(a:T[]):IPredictableGenerator; /** - * Generates the combination of array with n elements. - * When n is ommited, the length of the array is used. + * Generates the combination of `a` with `n` elements. + * `n` defaults to the length of `a`. */ function combination(a:T[], n?:number):IGenerator; /** - * Generates the combination of array with n elements, which + * Generates the combination of `a` with `n` elements, which * also supports larger sets of elements. - * When n is ommited, the length of the array is used. - * Somewhat slower than combination() + * When `n` is ommited, the length of the array is used. + * Somewhat slower than `combination()` */ function bigCombination(a:T[], n?:number):IGenerator; /** - * Generates the permutation of array with n elements. - * When n is ommited, the length of the array is used. + * Generates the permutation of `a` with `n` elements. + * `n` defaults to the length of `a`. */ function permutation(a:T[], n?:number):IGenerator; /** - * Generates the permutation of the combination of n. - * Equivalent to permutation(combination(a)), but more efficient. + * Generates the permutation of the combination of `a`. + * Equivalent to `permutation(combination(a))`, but more efficient. */ function permutationCombination(a:T[]):IGenerator; /** - * Generates n-digit "numbers" where each digit is an element in array. + * Generates `n`-digit "numbers" where each digit is an element in array. * Note this "number" is in the least significant order. - * When n is ommited, the length of the array is used. + * `n` defaults to the length of `a`. */ function baseN(a:T[], n?:number):IPredictableGenerator; diff --git a/types/keyv__mongo/index.d.ts b/types/keyv__mongo/index.d.ts new file mode 100644 index 0000000000..f468f3530b --- /dev/null +++ b/types/keyv__mongo/index.d.ts @@ -0,0 +1,33 @@ +// Type definitions for @keyv/mongo 1.0 +// Project: https://github.com/lukechilds/keyv-mongo +// Definitions by: BendingBender +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// + +import { Store } from 'keyv'; +import { EventEmitter } from 'events'; + +export = KeyvMongo; + +declare class KeyvMongo extends EventEmitter implements Store { + readonly ttlSupport: false; + namespace?: string; + + constructor(uri?: string); + constructor(options?: KeyvMongo.Options); // tslint:disable-line:unified-signatures + + get(key: string): Promise; + set(key: string, value: TValue, ttl?: number): Promise; + delete(key: string): Promise; + clear(): Promise; +} + +declare namespace KeyvMongo { + interface Options { + uri?: string; + url?: string; + collection?: string; + } +} diff --git a/types/keyv__mongo/keyv__mongo-tests.ts b/types/keyv__mongo/keyv__mongo-tests.ts new file mode 100644 index 0000000000..6e8d1ea971 --- /dev/null +++ b/types/keyv__mongo/keyv__mongo-tests.ts @@ -0,0 +1,12 @@ +import Keyv = require('keyv'); +import KeyvMongo = require('@keyv/mongo'); + +new Keyv('mongodb://user:pass@localhost:27017/dbname', { collection: 'cache' }); + +new KeyvMongo({ uri: 'mongodb://user:pass@localhost:27017/dbname' }); +new KeyvMongo({ url: 'mongodb://user:pass@localhost:27017/dbname' }); +new KeyvMongo({ collection: 'cache' }); +new KeyvMongo('mongodb://user:pass@localhost:27017/dbname'); + +const mongo = new KeyvMongo('mongodb://user:pass@localhost:27017/dbname'); +new Keyv({ store: mongo }); diff --git a/types/keyv__mongo/tsconfig.json b/types/keyv__mongo/tsconfig.json new file mode 100644 index 0000000000..ca38c4e787 --- /dev/null +++ b/types/keyv__mongo/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "paths": { + "@keyv/mongo": [ + "keyv__mongo" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "keyv__mongo-tests.ts" + ] +} diff --git a/types/keyv__mongo/tslint.json b/types/keyv__mongo/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/keyv__mongo/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/keyv__mysql/index.d.ts b/types/keyv__mysql/index.d.ts new file mode 100644 index 0000000000..4aef9d06e0 --- /dev/null +++ b/types/keyv__mysql/index.d.ts @@ -0,0 +1,33 @@ +// Type definitions for @keyv/mysql 1.1 +// Project: https://github.com/lukechilds/keyv-mysql +// Definitions by: BendingBender +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// + +import { Store } from 'keyv'; +import { EventEmitter } from 'events'; + +export = KeyvMysql; + +declare class KeyvMysql extends EventEmitter implements Store { + readonly ttlSupport: false; + namespace?: string; + + constructor(uri?: string); + constructor(options?: KeyvMysql.Options); // tslint:disable-line:unified-signatures + + get(key: string): Promise; + set(key: string, value: string | undefined): Promise; + delete(key: string): Promise; + clear(): Promise; +} + +declare namespace KeyvMysql { + interface Options { + uri?: string; + table?: string; + keySize?: number; + } +} diff --git a/types/keyv__mysql/keyv__mysql-tests.ts b/types/keyv__mysql/keyv__mysql-tests.ts new file mode 100644 index 0000000000..5a1947710d --- /dev/null +++ b/types/keyv__mysql/keyv__mysql-tests.ts @@ -0,0 +1,12 @@ +import Keyv = require('keyv'); +import KeyvMysql = require('@keyv/mysql'); + +new Keyv('mysql://user:pass@localhost:3306/dbname', { table: 'cache' }); + +new KeyvMysql('mysql://user:pass@localhost:3306/dbname'); +new KeyvMysql({ uri: 'mysql://user:pass@localhost:3306/dbname' }); +new KeyvMysql({ table: 'cache' }); +new KeyvMysql({ keySize: 100 }); + +const mysql = new KeyvMysql({ uri: 'mysql://user:pass@localhost:3306/dbname' }); +new Keyv({ store: mysql }); diff --git a/types/keyv__mysql/tsconfig.json b/types/keyv__mysql/tsconfig.json new file mode 100644 index 0000000000..e50e632d7c --- /dev/null +++ b/types/keyv__mysql/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "paths": { + "@keyv/mysql": [ + "keyv__mysql" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "keyv__mysql-tests.ts" + ] +} diff --git a/types/keyv__mysql/tslint.json b/types/keyv__mysql/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/keyv__mysql/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/keyv__postgres/index.d.ts b/types/keyv__postgres/index.d.ts new file mode 100644 index 0000000000..3431ce748f --- /dev/null +++ b/types/keyv__postgres/index.d.ts @@ -0,0 +1,32 @@ +// Type definitions for @keyv/postgres 1.0 +// Project: https://github.com/lukechilds/keyv-postgres +// Definitions by: BendingBender +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// + +import { Store } from 'keyv'; +import { EventEmitter } from 'events'; + +export = KeyvPostgres; + +declare class KeyvPostgres extends EventEmitter implements Store { + readonly ttlSupport: false; + namespace?: string; + + constructor(options?: KeyvPostgres.Options); + + get(key: string): Promise; + set(key: string, value: string | undefined): Promise; + delete(key: string): Promise; + clear(): Promise; +} + +declare namespace KeyvPostgres { + interface Options { + uri?: string; + table?: string; + keySize?: number; + } +} diff --git a/types/keyv__postgres/keyv__postgres-tests.ts b/types/keyv__postgres/keyv__postgres-tests.ts new file mode 100644 index 0000000000..1ad3d362d0 --- /dev/null +++ b/types/keyv__postgres/keyv__postgres-tests.ts @@ -0,0 +1,11 @@ +import Keyv = require('keyv'); +import KeyvPostgres = require('@keyv/postgres'); + +new Keyv('postgresql://user:pass@localhost:5432/dbname', { table: 'cache' }); + +new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname' }); +new KeyvPostgres({ table: 'cache' }); +new KeyvPostgres({ keySize: 100 }); + +const postgres = new KeyvPostgres({ uri: 'postgresql://user:pass@localhost:5432/dbname' }); +new Keyv({ store: postgres }); diff --git a/types/keyv__postgres/tsconfig.json b/types/keyv__postgres/tsconfig.json new file mode 100644 index 0000000000..d793c92899 --- /dev/null +++ b/types/keyv__postgres/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "paths": { + "@keyv/postgres": [ + "keyv__postgres" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "keyv__postgres-tests.ts" + ] +} diff --git a/types/keyv__postgres/tslint.json b/types/keyv__postgres/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/keyv__postgres/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/keyv__redis/index.d.ts b/types/keyv__redis/index.d.ts new file mode 100644 index 0000000000..bf009906f8 --- /dev/null +++ b/types/keyv__redis/index.d.ts @@ -0,0 +1,32 @@ +// Type definitions for @keyv/redis 1.3 +// Project: https://github.com/lukechilds/keyv-redis +// Definitions by: BendingBender +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// + +import { Store } from 'keyv'; +import { ClientOpts } from 'redis'; +import { EventEmitter } from 'events'; + +export = KeyvRedis; + +declare class KeyvRedis extends EventEmitter implements Store { + readonly ttlSupport: true; + namespace?: string; + + constructor(options?: KeyvRedis.Options); + constructor(uri: string, options?: KeyvRedis.Options); + + get(key: string): Promise; + set(key: string, value: string | undefined, ttl?: number): Promise; + delete(key: string): Promise; + clear(): Promise; +} + +declare namespace KeyvRedis { + interface Options extends ClientOpts { + uri?: string; + } +} diff --git a/types/keyv__redis/keyv__redis-tests.ts b/types/keyv__redis/keyv__redis-tests.ts new file mode 100644 index 0000000000..3f0187fd38 --- /dev/null +++ b/types/keyv__redis/keyv__redis-tests.ts @@ -0,0 +1,13 @@ +import Keyv = require('keyv'); +import KeyvRedis = require('@keyv/redis'); + +new Keyv('redis://user:pass@localhost:6379', { max_attempts: 1 }); + +new KeyvRedis({ uri: 'redis://user:pass@localhost:6379' }); +new KeyvRedis('redis://user:pass@localhost:6379', { max_attempts: 1 }); +new KeyvRedis('redis://user:pass@localhost:6379', { + uri: 'redis://user:pass@localhost:6379', + max_attempts: 1, +}); +const redis = new KeyvRedis('redis://user:pass@localhost:6379'); +new Keyv({ store: redis }); diff --git a/types/keyv__redis/tsconfig.json b/types/keyv__redis/tsconfig.json new file mode 100644 index 0000000000..bbd87dfade --- /dev/null +++ b/types/keyv__redis/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "paths": { + "@keyv/redis": [ + "keyv__redis" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "keyv__redis-tests.ts" + ] +} diff --git a/types/keyv__redis/tslint.json b/types/keyv__redis/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/keyv__redis/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/keyv__sqlite/index.d.ts b/types/keyv__sqlite/index.d.ts new file mode 100644 index 0000000000..3a59e7b2b7 --- /dev/null +++ b/types/keyv__sqlite/index.d.ts @@ -0,0 +1,33 @@ +// Type definitions for @keyv/sqlite 2.0 +// Project: https://github.com/lukechilds/keyv-sqlite +// Definitions by: BendingBender +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// + +import { Store } from 'keyv'; +import { EventEmitter } from 'events'; + +export = KeyvSqlite; + +declare class KeyvSqlite extends EventEmitter implements Store { + readonly ttlSupport: false; + namespace?: string; + + constructor(options?: KeyvSqlite.Options); + + get(key: string): Promise; + set(key: string, value: string | undefined): Promise; + delete(key: string): Promise; + clear(): Promise; +} + +declare namespace KeyvSqlite { + interface Options { + uri?: string; + busyTimeout?: number; + table?: string; + keySize?: number; + } +} diff --git a/types/keyv__sqlite/keyv__sqlite-tests.ts b/types/keyv__sqlite/keyv__sqlite-tests.ts new file mode 100644 index 0000000000..e109dbf4a1 --- /dev/null +++ b/types/keyv__sqlite/keyv__sqlite-tests.ts @@ -0,0 +1,12 @@ +import Keyv = require('keyv'); +import KeyvSqlite = require('@keyv/sqlite'); + +new Keyv('sqlite://path/to/database.sqlite', { table: 'cache' }); + +new KeyvSqlite({ uri: 'sqlite://path/to/database.sqlite' }); +new KeyvSqlite({ busyTimeout: 10000 }); +new KeyvSqlite({ table: 'cache' }); +new KeyvSqlite({ keySize: 100 }); + +const sqlite = new KeyvSqlite({ uri: 'sqlite://path/to/database.sqlite' }); +new Keyv({ store: sqlite }); diff --git a/types/keyv__sqlite/tsconfig.json b/types/keyv__sqlite/tsconfig.json new file mode 100644 index 0000000000..5546f7acef --- /dev/null +++ b/types/keyv__sqlite/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "paths": { + "@keyv/sqlite": [ + "keyv__sqlite" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "keyv__sqlite-tests.ts" + ] +} diff --git a/types/keyv__sqlite/tslint.json b/types/keyv__sqlite/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/keyv__sqlite/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/knockout/index.d.ts b/types/knockout/index.d.ts index fa0e195788..8bf99b79db 100644 --- a/types/knockout/index.d.ts +++ b/types/knockout/index.d.ts @@ -140,7 +140,7 @@ interface KnockoutSubscribableStatic { interface KnockoutSubscription { /** - * Terminates a subscription + * Terminates a subscription */ dispose(): void; } @@ -213,9 +213,6 @@ interface KnockoutReadonlyComputed extends KnockoutReadonlyObservable { interface KnockoutComputed extends KnockoutReadonlyComputed, KnockoutObservable, KnockoutComputedFunctions { fn: KnockoutComputedFunctions; - // It's possible for 'a' to be undefined, since the equalityComparer is run on the initial - // computation with undefined as the first argument. This is user-relevant for deferred computeds. - equalityComparer(a: T | undefined, b: T): boolean; /** * Manually disposes the computed observable, clearing all subscriptions to dependencies. * This function is useful if you want to stop a computed observable from being updated or want to clean up memory for a diff --git a/types/koa-router/index.d.ts b/types/koa-router/index.d.ts index 8d8f35df6b..b2163d09d1 100644 --- a/types/koa-router/index.d.ts +++ b/types/koa-router/index.d.ts @@ -19,12 +19,6 @@ import * as Koa from "koa"; -declare module "koa" { - interface Context { - params: any; - } -} - declare namespace Router { export interface IRouterOptions { /** @@ -61,11 +55,11 @@ declare namespace Router { } export interface IMiddleware { - (ctx: Router.IRouterContext, next: () => Promise): any; + (ctx: Koa.ParameterizedContext<{}, IRouterContext>, next: () => Promise): any; } export interface IParamMiddleware { - (param: string, ctx: Router.IRouterContext, next: () => Promise): any; + (param: string, ctx: Koa.ParameterizedContext<{}, IRouterContext>, next: () => Promise): any; } export interface IRouterAllowedMethodsOptions { @@ -88,7 +82,7 @@ declare namespace Router { sensitive?: boolean; strict?: boolean; } - + export interface IUrlOptionsQuery { query: object | string; } @@ -190,19 +184,19 @@ declare class Router { */ put(name: string, path: string | RegExp, ...middleware: Array): Router; put(path: string | RegExp | (string | RegExp)[], ...middleware: Array): Router; - + /** * HTTP link method */ link(name: string, path: string | RegExp, ...middleware: Array): Router; link(path: string | RegExp | (string | RegExp)[], ...middleware: Array): Router; - + /** * HTTP unlink method */ unlink(name: string, path: string | RegExp, ...middleware: Array): Router; unlink(path: string | RegExp | (string | RegExp)[], ...middleware: Array): Router; - + /** * HTTP delete method @@ -283,21 +277,21 @@ declare class Router { /** * Generate URL for route. Takes either map of named `params` or series of * arguments (for regular expression routes) - * + * * router = new Router(); * router.get('user', "/users/:id", ... - * + * * router.url('user', { id: 3 }); * // => "/users/3" - * + * * Query can be generated from third argument: - * + * * router.url('user', { id: 3 }, { query: { limit: 1 } }); * // => "/users/3?limit=1" - * + * * router.url('user', { id: 3 }, { query: "limit=1" }); * // => "/users/3?limit=1" - * + * */ url(name: string, params: any, options?: Router.IUrlOptionsQuery): string; url(name: string, params: any, options?: Router.IUrlOptionsQuery): Error; diff --git a/types/koa-router/koa-router-tests.ts b/types/koa-router/koa-router-tests.ts index e1c90c636d..50e66509ea 100644 --- a/types/koa-router/koa-router-tests.ts +++ b/types/koa-router/koa-router-tests.ts @@ -1,7 +1,7 @@ import Koa = require("koa"); import Router = require("koa-router"); -const app = new Koa(); +const app = new Koa<{}, {}>(); const router = new Router({ prefix: "/users" @@ -49,6 +49,10 @@ const match = router.match('/users/:id', 'GET'); let layer: Router.Layer let layerOptions: Router.ILayerOptions +const mw: Router.IMiddleware = (ctx: Router.IRouterContext, next: () => Promise) => { + ctx.body = "Ok"; +}; + app.use(router.routes()); app.use(router.allowedMethods()); diff --git a/types/koa-useragent/koa-useragent-tests.ts b/types/koa-useragent/koa-useragent-tests.ts index 579983786c..594b9b2206 100644 --- a/types/koa-useragent/koa-useragent-tests.ts +++ b/types/koa-useragent/koa-useragent-tests.ts @@ -5,7 +5,7 @@ const app = new Koa(); app.use(userAgent); -app.use((ctx, next) => { +app.use((ctx: Koa.Context, next) => { ctx.userAgent.isAuthoritative; // $ExpectType boolean ctx.userAgent.isMobile; // $ExpectType boolean ctx.userAgent.isTablet; // $ExpectType boolean diff --git a/types/koa/index.d.ts b/types/koa/index.d.ts index 802d6a242f..cc0fa86141 100644 --- a/types/koa/index.d.ts +++ b/types/koa/index.d.ts @@ -431,12 +431,12 @@ declare interface ContextDelegatedResponse { flushHeaders(): void; } -declare class Application extends EventEmitter { +declare class Application extends EventEmitter { proxy: boolean; - middleware: Application.Middleware[]; + middleware: Application.Middleware[]; subdomainOffset: number; env: string; - context: Application.BaseContext; + context: Application.BaseContext & CustomT; request: Application.BaseRequest; response: Application.BaseResponse; silent: boolean; @@ -497,7 +497,9 @@ declare class Application extends EventEmitter { * * Old-style middleware will be converted. */ - use(middleware: Application.Middleware): this; + use( + middleware: Application.Middleware, + ): Application; /** * Return a request handler callback @@ -510,10 +512,10 @@ declare class Application extends EventEmitter { * * @api private */ - createContext( + createContext( req: IncomingMessage, res: ServerResponse, - ): Application.Context; + ): Application.ParameterizedContext; /** * Default error handler. @@ -524,7 +526,7 @@ declare class Application extends EventEmitter { } declare namespace Application { - type Middleware = compose.Middleware; + type Middleware = compose.Middleware>; interface BaseRequest extends ContextDelegatedRequest { /** @@ -684,7 +686,7 @@ declare namespace Application { request: Request; } - interface Context extends BaseContext { + type ParameterizedContext = BaseContext & { app: Application; request: Request; response: Response; @@ -693,12 +695,14 @@ declare namespace Application { originalUrl: string; cookies: Cookies; accept: accepts.Accepts; - state: any; + state: StateT; /** * To bypass Koa's built-in response handling, you may explicitly set `ctx.respond = false;` */ respond?: boolean; - } + } & CustomT; + + interface Context extends ParameterizedContext {} } export = Application; diff --git a/types/koa/koa-tests.ts b/types/koa/koa-tests.ts index 2ddf9b41e2..c3d29298be 100644 --- a/types/koa/koa-tests.ts +++ b/types/koa/koa-tests.ts @@ -1,19 +1,18 @@ import Koa = require("koa"); -declare module 'koa' { - export interface BaseContext { - db(): void; - } - export interface Context { - user: {}; - } +interface DbBaseContext { + db(): void; } -const app = new Koa(); +interface UserContext { + user: {}; +} + +const app = new Koa<{}, DbBaseContext>(); app.context.db = () => {}; -app.use(async ctx => { +app.use<{}, UserContext>(async ctx => { console.log(ctx.db); ctx.user = {}; }); diff --git a/types/linkifyjs/index.d.ts b/types/linkifyjs/index.d.ts index 9c095a41f3..a036ab52c1 100644 --- a/types/linkifyjs/index.d.ts +++ b/types/linkifyjs/index.d.ts @@ -1,8 +1,11 @@ // Type definitions for linkifyjs 2.1 // Project: https://github.com/SoapBox/linkifyjs#readme // Definitions by: Sean Zhu +// Ovidiu Bute // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.1 +// TypeScript Version: 2.8 + +import * as React from "react"; export type PossiblyFuncOfHrefAndType = | T @@ -26,9 +29,9 @@ export interface LinkifyOptions { * Also accepts a function that takes the unformatted href, the link type * (e.g., 'url', 'email', etc.) and returns the object. */ - attributes?: PossiblyFuncOfHrefAndType<{ - [attrName: string]: string; - }> | null; + attributes?: PossiblyFuncOfHrefAndType< + React.AnchorHTMLAttributes + > | null; /** * className diff --git a/types/linkifyjs/linkifyjs-tests.ts b/types/linkifyjs/linkifyjs-tests.ts deleted file mode 100644 index 5688f9f99f..0000000000 --- a/types/linkifyjs/linkifyjs-tests.ts +++ /dev/null @@ -1,141 +0,0 @@ -import linkifyHtml from "linkifyjs/html"; - -// From the docs here: https://soapbox.github.io/linkifyjs/docs/options.html - -/* attributes */ - -linkifyHtml("github.com", { - attributes: { - rel: "nofollow" - } -}); - -/* className */ - -linkifyHtml("github.com", { - className: "new-link--url" -}); - -linkifyHtml("github.com", { - className(href, type) { - return "new-link--" + type; - } -}); - -linkifyHtml("github.com", { - className: { - url: "new-link--url", - email(href: string) { - return "new-link--email"; - } - } -}); - -/* events */ - -linkifyHtml("", { - events: { - click(e) { - alert("Link clicked!"); - }, - mouseover(e) { - alert("Link hovered!"); - } - } -}); - -/* defaultProtocol */ - -/* format */ - -linkifyHtml("", { - format(value, type) { - if (type === "url" && value.length > 50) { - value = value.slice(0, 50) + "…"; - } - return value; - } -}); - -linkifyHtml("", { - format: { - url(value) { - return value.length > 50 ? value.slice(0, 50) + "…" : value; - } - } -}); - -/* formatHref */ - -linkifyHtml("This site is #rad", { - formatHref(href, type) { - if (type === "hashtag") { - href = "https://twitter.com/hashtag/" + href.substring(1); - } - return href; - } -}); - -linkifyHtml("Hey @dhh, check out issue #23", { - formatHref: { - mention(href) { - return "https://github.com" + href; - }, - ticket(href) { - return ( - "https://github.com/SoapBox/linkifyjs/issues/" + - href.substring(1) - ); - } - } -}); - -/* ignoreTags */ - -linkifyHtml( - // tslint:disable-next-line:prefer-template - 'Please ignore \n' + - "but do b.ca", - { - ignoreTags: ["script", "style"] - } -); - -/* nl2br */ - -/* tagName */ - -linkifyHtml("github.com", { - tagName: "span" -}); - -linkifyHtml("#swag", { - tagName: { - hashtag: "span" - } -}); - -/* target */ - -linkifyHtml("github.com", { - target: "_parent" -}); - -linkifyHtml("test-email@example.com", { - target: { - url: "_parent", - email: null - } -}); - -/* validate */ - -// Don't linkify links that don't begin in a protocol -// e.g., "http://google.com" will be linkified, but "google.com" will not. -linkifyHtml("www.google.com", { - validate: { - url(value) { - return /^(http|ftp)s?:\/\//.test(value); - } - } -}); diff --git a/types/linkifyjs/linkifyjs-tests.tsx b/types/linkifyjs/linkifyjs-tests.tsx new file mode 100644 index 0000000000..02d9d3b6d5 --- /dev/null +++ b/types/linkifyjs/linkifyjs-tests.tsx @@ -0,0 +1,227 @@ +import * as React from "react"; +import linkifyHtml from "linkifyjs/html"; +import Linkify from "linkifyjs/react"; + +declare function describe(desc: string, f: () => void): void; + +describe("linkifyjs/html", () => { + /** + * The following tests were taken directly from the documentation: + * https://soapbox.github.io/linkifyjs/docs/options.html + */ + + /* attributes */ + + linkifyHtml("github.com", { + attributes: { + rel: "nofollow" + } + }); + + /* className */ + + linkifyHtml("github.com", { + className: "new-link--url" + }); + + linkifyHtml("github.com", { + className(href, type) { + return "new-link--" + type; + } + }); + + linkifyHtml("github.com", { + className: { + url: "new-link--url", + email(href: string) { + return "new-link--email"; + } + } + }); + + /* events */ + + linkifyHtml("", { + events: { + click(e) { + alert("Link clicked!"); + }, + mouseover(e) { + alert("Link hovered!"); + } + } + }); + + /* defaultProtocol */ + + /* format */ + + linkifyHtml("", { + format(value, type) { + if (type === "url" && value.length > 50) { + value = value.slice(0, 50) + "…"; + } + return value; + } + }); + + linkifyHtml("", { + format: { + url(value) { + return value.length > 50 ? value.slice(0, 50) + "…" : value; + } + } + }); + + /* formatHref */ + + linkifyHtml("This site is #rad", { + formatHref(href, type) { + if (type === "hashtag") { + href = "https://twitter.com/hashtag/" + href.substring(1); + } + return href; + } + }); + + linkifyHtml("Hey @dhh, check out issue #23", { + formatHref: { + mention(href) { + return "https://github.com" + href; + }, + ticket(href) { + return ( + "https://github.com/SoapBox/linkifyjs/issues/" + + href.substring(1) + ); + } + } + }); + + /* ignoreTags */ + + linkifyHtml( + // tslint:disable-next-line:prefer-template + 'Please ignore \n' + + "but do b.ca", + { + ignoreTags: ["script", "style"] + } + ); + + /* nl2br */ + + /* tagName */ + + linkifyHtml("github.com", { + tagName: "span" + }); + + linkifyHtml("#swag", { + tagName: { + hashtag: "span" + } + }); + + /* target */ + + linkifyHtml("github.com", { + target: "_parent" + }); + + linkifyHtml("test-email@example.com", { + target: { + url: "_parent", + email: null + } + }); + + /* validate */ + + // Don't linkify links that don't begin in a protocol + // e.g., "http://google.com" will be linkified, but "google.com" will not. + linkifyHtml("www.google.com", { + validate: { + url(value) { + return /^(http|ftp)s?:\/\//.test(value); + } + } + }); +}); + +describe("linkifyjs/react", () => { + /** + * The following tests were taken directly from the documentation: + * https://soapbox.github.io/linkifyjs/docs/linkify-react.html + */ + + /* Usage */ + + { + // render() + const options = { + /* … */ + }; + const content = + "For help with GitHub.com, please email support@github.com"; + + {content} + ; + } + + /* Events */ + + { + const content = + "For help with GitHub.com, please email support@github.com"; + const linkProps = { + onClick: (event: any) => { + if (!confirm("Are you sure you want to leave this page?")) { + event.preventDefault(); + } + } + }; + {content}; + } + + /** + * The following tests were made specifically for DefinitelyTyped. + */ + + /* Default values for all props */ + { + const content = + "For help with GitHub.com, please email support@github.com"; + + {content} + ; + } + + /* Custom class name */ + + { + const content = + "For help with GitHub.com, please email support@github.com"; + + {content} + ; + } + + /* Custom tag name */ + + { + const content = + "For help with GitHub.com, please email support@github.com"; + + {content} + ; + } +}); diff --git a/types/linkifyjs/react.d.ts b/types/linkifyjs/react.d.ts new file mode 100644 index 0000000000..0631b6c460 --- /dev/null +++ b/types/linkifyjs/react.d.ts @@ -0,0 +1,11 @@ +import * as React from "react"; +import { LinkifyOptions } from "./index"; + +export interface LinkifyProps { + options?: LinkifyOptions; + tagName?: string; +} + +declare class Linkify extends React.Component {} + +export default Linkify; diff --git a/types/linkifyjs/tsconfig.json b/types/linkifyjs/tsconfig.json index 52b1940fcd..16becbcf0a 100644 --- a/types/linkifyjs/tsconfig.json +++ b/types/linkifyjs/tsconfig.json @@ -1,25 +1,17 @@ { "compilerOptions": { "module": "commonjs", - "lib": [ - "es6", - "dom" - ], + "lib": ["es6", "dom"], "noImplicitAny": true, "noImplicitThis": true, "strictNullChecks": true, "strictFunctionTypes": true, "baseUrl": "../", - "typeRoots": [ - "../" - ], + "typeRoots": ["../"], "types": [], "noEmit": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "jsx": "preserve" }, - "files": [ - "index.d.ts", - "html.d.ts", - "linkifyjs-tests.ts" - ] + "files": ["index.d.ts", "html.d.ts", "react.d.ts", "linkifyjs-tests.tsx"] } diff --git a/types/loadable__component/index.d.ts b/types/loadable__component/index.d.ts new file mode 100644 index 0000000000..c4877bd8a9 --- /dev/null +++ b/types/loadable__component/index.d.ts @@ -0,0 +1,47 @@ +// Type definitions for @loadable/component 5.2 +// Project: https://github.com/smooth-code/loadable-components +// Definitions by: Martynas Kadiša +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +import * as React from 'react'; + +export interface DefaultImportedComponent

{ + default: React.ComponentType

; +} + +export type DefaultComponent

= React.ComponentType

| DefaultImportedComponent

; + +export interface Options { + fallback?: JSX.Element; +} + +export type LoadableComponent = React.ComponentType; +export type LoadableLibrary = React.ComponentType<{ + fallback?: JSX.Element; + children?: (module: TModule) => React.ReactNode; + ref?: React.Ref; +}> & + TModule; + +declare function lib( + loadFn: (props: object) => Promise, + options?: Options +): LoadableLibrary; + +declare function loadableFunc( + loadFn: (props: T) => Promise>, + options?: Options +): LoadableComponent; + +declare const loadable: typeof loadableFunc & { lib: typeof lib }; + +export default loadable; + +export namespace lazy { + function lib(loadFn: (props: object) => Promise): LoadableLibrary; +} + +export function lazy(loadFn: (props: T) => Promise>): LoadableComponent; + +export function loadableReady(done?: () => any): Promise; diff --git a/types/loadable__component/loadable__component-tests.tsx b/types/loadable__component/loadable__component-tests.tsx new file mode 100644 index 0000000000..d286711be1 --- /dev/null +++ b/types/loadable__component/loadable__component-tests.tsx @@ -0,0 +1,117 @@ +import * as React from 'react'; +import loadable, { lazy, loadableReady } from '@loadable/component'; + +const TestComponent: React.SFC<{ foo: string }> = () => <>test; + +function defaultImportComponentLoader() { + return new Promise<{ default: typeof TestComponent }>(resolve => resolve({ default: TestComponent })); +} + +function importComponentLoader() { + return new Promise(resolve => resolve(TestComponent)); +} + +const lib = { + getTestObj: () => ({ bar: 'bar', foo: 'foo' }) +}; + +function defaultImportLibLoader() { + return new Promise<{ default: typeof lib }>(resolve => resolve(({ default: lib }))); +} + +function importLibLoader() { + return new Promise(resolve => resolve(lib)); +} + +// loadable +{ + // Should infer props from imported component with default export + const LoadableDefaultComponent = loadable(defaultImportComponentLoader); + ; + + // Should infer props from imported component without default export + const LoadableComponent = loadable(importComponentLoader); + ; + + // Should allow passing JSX element to fallback in options + loadable(defaultImportComponentLoader, { fallback:

loading...
}); + + // Should allow passing `fallback` prop to loadable component + loading...} />; +} + +// lazy +{ + // Should infer props from imported component with default export + const LazyDefaultComponent = lazy(defaultImportComponentLoader); + ; + + // Should infer props from imported component without default export + const LazyComponent = lazy(importComponentLoader); + ; + + // Should allow passing fallback prop + loading...} />; +} + +// loadable.lib +{ + // Should infer types from module with default export and reflect them in children render prop + const LoadableDefaultLibrary = loadable.lib(defaultImportLibLoader); + + {({ default: { getTestObj } }) => getTestObj().foo} + ; + + // Should infer types from module without default export and reflect them in children render prop + const LoadableLibrary = loadable.lib(importLibLoader); + + {({ getTestObj }) => getTestObj().foo} + ; + + // Should allow passing fallback JSX element + loadable.lib(importLibLoader, { fallback:
loading lib...
}); + + // Should allow passing fallback prop + Loading library...}> + {({ getTestObj }) => getTestObj().foo} + ; + + // Should reflect inferred types from module in ref + const ref = React.createRef(); + ; + ref.current!.getTestObj().foo; +} + +// lazy.lib +{ + // Should infer types from module with default export and reflect them in children render prop + const LazyDefaultLibrary = lazy.lib(defaultImportLibLoader); + + {({ default: { getTestObj } }) => getTestObj().foo} + ; + + // Should infer types from module without default export and reflect them in children render prop + const LazyLibrary = lazy.lib(importLibLoader); + + {({ getTestObj }) => getTestObj().foo} + ; + + // Should allow passing fallback prop + Loading library...}> + {({ getTestObj }) => getTestObj().foo} + ; + + // Should reflect inferred types from module in ref + const ref = React.createRef(); + ; + ref.current!.getTestObj().foo; +} + +// loadableReady +{ + // Should allow passing callback argument + loadableReady(() => {}); + + // Should return a promise + loadableReady().then(() => {}); +} diff --git a/types/loadable__component/tsconfig.json b/types/loadable__component/tsconfig.json new file mode 100644 index 0000000000..440535e42b --- /dev/null +++ b/types/loadable__component/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "jsx": "react", + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "paths": { + "@loadable/component": [ + "loadable__component" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "loadable__component-tests.tsx" + ] +} diff --git a/types/loadable__component/tslint.json b/types/loadable__component/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/loadable__component/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/loadable__server/index.d.ts b/types/loadable__server/index.d.ts new file mode 100644 index 0000000000..eafbd7eec7 --- /dev/null +++ b/types/loadable__server/index.d.ts @@ -0,0 +1,86 @@ +// Type definitions for @loadable/server 5.2 +// Project: https://github.com/smooth-code/loadable-components +// Definitions by: Martynas Kadiša +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +import { ComponentType, ReactElement, Component } from 'react'; + +export type ChunkExtractorOptions = { + /** + * Webpack entrypoints to load (default to `["main"]`) + */ + entrypoints?: string | string[]; + /** + * Optional output path (only for `requireEntrypoint`) + */ + outputPath?: string; +} & ({ + /** + * Stats file path generated using `@loadable/webpack-plugin` + */ + statsFile: string; + } | { + /** + * Stats generated using `@loadable/webpack-plugin`. + */ + stats: object; + }); + +/** + * Used to collect chunks server-side and get them as script tags or script elements + */ +export class ChunkExtractor { + constructor(options: ChunkExtractorOptions); + + /** + * Wrap your application in a `ChunkExtractorManager` + */ + collectChunks( + /** + * JSX element that will be wrapped in `ChunkExtractorManager` + */ + element: JSX.Element + ): JSX.Element; + + /** + * Require the entrypoint of your application as a commonjs module. + */ + requireEntrypoint(name?: string): { default: ComponentType }; + + /** + * Get scripts as a string of `