diff --git a/.travis.yml b/.travis.yml index 5fd4f73..a668782 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,6 +45,8 @@ env: - SAUCE_USERNAME=ptitjes matrix: + - COMMAND=test-types + - SERVER=couchdb:latest CLIENT=node COMMAND=test - SERVER=couchdb:latest CLIENT=phantom COMMAND=test diff --git a/package-lock.json b/package-lock.json index 01f0c22..669f6be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,21 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/debug": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz", + "integrity": "sha512-orGL5LXERPYsLov6CWs3Fh6203+dXzJkR7OnddIr2514Hsecwc8xRpzCapshBbKFImCsvS/mk6+FWiN5LyZJAQ==", + "dev": true + }, + "@types/pouchdb-core": { + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/@types/pouchdb-core/-/pouchdb-core-6.1.9.tgz", + "integrity": "sha512-JDSk8jmtIcno/HaEfgCtfeMtkU0LyrhG6KO5jq89qDd/ynMS2LupBc39qdi/aEAA6/krYPb427148yh10Bn7Ig==", + "dev": true, + "requires": { + "@types/debug": "0.0.30" + } + }, "JSONStream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", @@ -14131,6 +14146,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", + "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "dev": true + }, "uglify-js": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.9.tgz", diff --git a/package.json b/package.json index be34659..1e32835 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "main": "lib/index.js", "jsnext:main": "lib/index.es.js", "module": "lib/index.es.js", + "types": "types/index.d.ts", "repository": { "type": "git", "url": "git@github.com:pouchdb-community/pouchdb-authentication.git" @@ -51,6 +52,7 @@ "test-local": "CLIENT=local npm run test", "test-node": "CLIENT=node npm run test", "test-phantom": "CLIENT=phantom npm run test", + "test-types": "tsc --noEmit -p types", "release": "standard-version" }, "dependencies": { @@ -63,6 +65,7 @@ "url-parse": "1.2.0" }, "devDependencies": { + "@types/pouchdb-core": "^6.1.9", "add-cors-to-couchdb": "0.0.6", "brfs": "^1.4.3", "browserify": "^14.5.0", @@ -91,6 +94,7 @@ "rollup-plugin-node-resolve": "^3.0.0", "rollup-plugin-replace": "^2.0.0", "standard-version": "^4.2.0", + "typescript": "^2.6.2", "uglify-js": "^3.1.9", "watchify": "^3.9.0" }, diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..69ec092 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,181 @@ +// Type definitions for pouchdb-authentication 1.0 +// Project: https://pouchdb.com/ +// Definitions by: Didier Villevalois +// Definitions: https://github.com/pouchdb-community/pouchdb-authentication +// TypeScript Version: 2.3 + +/// + +// TODO: Fixing this lint error will require a large refactor +/* tslint:disable:no-single-declare-module */ + +declare namespace PouchDB { + namespace Authentication { + + interface UserContext { + name: string; + roles?: string[]; + } + + interface User extends UserContext { + } + + interface LoginResponse extends Core.BasicResponse, UserContext { + } + + interface SessionResponse extends Core.BasicResponse { + info: { + authenticated: string; + authentication_db: string; + authentication_handlers: string[]; + }; + userCtx: UserContext; + } + + interface PutUserOptions extends Core.Options { + metadata?: any; + roles?: string[]; + } + } + + interface Database { + /** + * Log in an existing user. + * Throws an error if the user doesn't exist yet, the password is wrong, the HTTP server is unreachable, or a meteor struck your computer. + */ + logIn(username: string, password: string, + callback: Core.Callback): void; + + logIn(username: string, password: string, + options: Core.Options, + callback: Core.Callback): void; + + logIn(username: string, password: string, + options?: Core.Options): Promise; + + /** + * Logs out whichever user is currently logged in. + * If nobody's logged in, it does nothing and just returns `{"ok" : true}`. + */ + logOut(callback: Core.Callback): void; + + logOut(): Promise; + + /** + * Returns information about the current session. + * In other words, this tells you which user is currently logged in. + */ + getSession(callback: Core.Callback): void; + + getSession(): Promise; + + /** + * Sign up a new user who doesn't exist yet. + * Throws an error if the user already exists or if the username is invalid, or if some network error occurred. + * CouchDB has some limitations on user names (e.g. they cannot contain the character `:`). + */ + signUp(username: string, password: string, + callback: Core.Callback): void; + + signUp(username: string, password: string, + options: Authentication.PutUserOptions, + callback: Core.Callback): void; + + signUp(username: string, password: string, + options?: Authentication.PutUserOptions): Promise; + + /** + * Returns the user document associated with a username. + * (CouchDB, in a pleasing show of consistency, stores users as JSON documents in the special `_users` database.) + * This is the primary way to get metadata about a user. + */ + getUser(username: string, + callback: Core.Callback & Core.GetMeta>): void; + + getUser(username: string, + options: PouchDB.Core.Options, + callback: Core.Callback & Core.GetMeta>): void; + + getUser(username: string, + options?: PouchDB.Core.Options): Promise & Core.GetMeta>; + + /** + * Update the metadata of a user. + */ + putUser(username: string, + callback: Core.Callback): void; + + putUser(username: string, options: Authentication.PutUserOptions, + callback: Core.Callback): void; + + putUser(username: string, options?: Authentication.PutUserOptions): Promise; + + /** + * Delete a user. + */ + deleteUser(username: string, + callback: Core.Callback): void; + + deleteUser(username: string, + options: Core.Options, + callback: Core.Callback): void; + + deleteUser(username: string, + options?: Core.Options): Promise; + + /** + * Set new `password` for user `username`. + */ + changePassword(username: string, password: string, + callback: Core.Callback): void; + + changePassword(username: string, password: string, + options: Core.Options, + callback: Core.Callback): void; + + changePassword(username: string, password: string, + options?: Core.Options): Promise; + + /** + * Renames `oldUsername` to `newUsername`. + */ + changeUsername(oldUsername: string, newUsername: string, + callback: Core.Callback): void; + + changeUsername(oldUsername: string, newUsername: string, + options: Core.Options, + callback: Core.Callback): void; + + changeUsername(oldUsername: string, newUsername: string, + options?: Core.Options): Promise; + + /** + * Sign up a new admin. + */ + signUpAdmin(username: string, password: string, + callback: Core.Callback): void; + + signUpAdmin(username: string, password: string, + options: Authentication.PutUserOptions, + callback: Core.Callback): void; + + signUpAdmin(username: string, password: string, + options?: Authentication.PutUserOptions): Promise; + + /** + * Delete an admin. + */ + deleteAdmin(username: string, + callback: Core.Callback): void; + + deleteAdmin(username: string, options: Core.Options, + callback: Core.Callback): void; + + deleteAdmin(username: string, options?: Core.Options): Promise; + } +} + +declare module 'pouchdb-authentication' { + const plugin: PouchDB.Plugin; + export = plugin; +} diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 0000000..0776d53 --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "moduleResolution": "node", + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "type-tests.ts" + ] +} diff --git a/types/tslint.json b/types/tslint.json new file mode 100644 index 0000000..2c9f905 --- /dev/null +++ b/types/tslint.json @@ -0,0 +1,7 @@ +{ + "extends": "dtslint/dt.json", + "rules": { + "no-declare-current-package": false, + "no-any-union": false + } +} diff --git a/types/type-tests.ts b/types/type-tests.ts new file mode 100644 index 0000000..34d2d5d --- /dev/null +++ b/types/type-tests.ts @@ -0,0 +1,29 @@ +function testAuthentication() { + const db = new PouchDB<{ foo: number }>(); + + db.logIn('username', 'password'); + + db.logOut(); + + db.getSession(); + + db.signUp('username', 'password', { + roles: ['role1', 'role2'], metadata: { anyStuff: 'whatever' }, + }); + + db.putUser('username', { + roles: ['role1', 'role2'], metadata: { anyStuff: 'whatever' }, + }); + + db.getUser('username'); + + db.deleteUser('username'); + + db.changePassword('username', 'password'); + + db.changeUsername('oldUsername', 'newUsername'); + + db.signUpAdmin('username', 'password'); + + db.deleteAdmin('username'); +}