diff --git a/api/auth-store.js b/api/auth-store.js index b60a1ff..3841939 100644 --- a/api/auth-store.js +++ b/api/auth-store.js @@ -1,6 +1,6 @@ /** * Memory store for API key and token. - * @module auth-store + * @module planet-client/api/auth-store * @private */ diff --git a/api/auth.js b/api/auth.js index e8c3045..3990a8b 100644 --- a/api/auth.js +++ b/api/auth.js @@ -1,6 +1,6 @@ /** - * Provides methods for setting API authentication credentials. - * @module auth + * Provides methods for authenticating with a Planet API account. + * @module planet-client/api/auth */ var errors = require('./errors'); @@ -9,9 +9,10 @@ var store = require('./auth-store'); var urls = require('./urls'); /** - * Submit credentials for authentication. - * @param {string} email Email. - * @param {string} password Password. + * Submit credentials for authentication. Upon successful authentication, a + * token representing the user will be stored for subsequent API requests. + * @param {string} email The email associated with a Planet account. + * @param {string} password The password for a Planet account. * @return {Promise} A promise that resolves on successful login and is rejected * otherwise. */ @@ -47,7 +48,9 @@ function logout() { } /** - * Set an API key to be used for subsequent requests. + * Set an API key to be used for subsequent requests. This is an alternative + * to submitting credentials with the [`login`](#module:planet-client/api/auth~login) + * method. The stored key will be used for subsequent API requests. * @param {string} key An API key. */ function setKey(key) { diff --git a/api/errors.js b/api/errors.js index ce3d50e..91a1655 100644 --- a/api/errors.js +++ b/api/errors.js @@ -1,32 +1,58 @@ /** - * Includes specific Error types generated by API requests. - * @module errors - * @private + * Includes specific `Error` types generated by API requests. When a request + * method returns a promise that is rejected, you can use `instanceof` to + * determine what type of error you have. + * + * @module planet-client/api/errors */ /** - * An error based on a server response. + * The base class for all response errors. * @param {string} message Error message. * @param {XMLHttpRequest} response The response. * @param {string} body Any parsed response body. * @constructor + * @ignore */ function ResponseError(message, response, body) { + + /** + * A message providing details about the error. + * @type {string} + */ this.message = message; + + /** + * The server response. + * @type {IncomingMessage} + */ this.response = response; + + /** + * Any parsed response body. For "expected" errors, this will be an object + * representing the JSON response body. + * @type {Object} + */ this.body = body; + + /** + * The stack trace for the error. + * @type {string} + */ this.stack = (new Error()).stack; + } ResponseError.prototype = new Error(); ResponseError.prototype.name = 'ResponseError'; /** - * The request was bad (400). + * The request was bad (status `400`). * @param {string} message Error message. * @param {XMLHttpRequest} response The response. * @param {Object} body Any parsed response body (as JSON). - * @extends {ResponseError} + * @extends {module:planet-client/api/errors~ResponseError} * @constructor + * @ignore */ function BadRequest(message, response, body) { ResponseError.apply(this, arguments); @@ -36,12 +62,13 @@ BadRequest.prototype = new ResponseError(); BadRequest.prototype.name = 'BadRequest'; /** - * The request requires user authentication (401). + * The request requires user authentication (status `401`). * @param {string} message Error message. * @param {XMLHttpRequest} response The response. * @param {Object} body Any parsed response body (as JSON). - * @extends {ResponseError} + * @extends {module:planet-client/api/errors~ResponseError} * @constructor + * @ignore */ function Unauthorized(message, response, body) { ResponseError.apply(this, arguments); @@ -51,12 +78,13 @@ Unauthorized.prototype = new ResponseError(); Unauthorized.prototype.name = 'Unauthorized'; /** - * The client is forbidden from making the request (403). + * The client is forbidden from making the request (status `403`). * @param {string} message Error message. * @param {XMLHttpRequest} response The response. * @param {Object} body Any parsed response body (as JSON). - * @extends {ResponseError} + * @extends {module:planet-client/api/errors~ResponseError} * @constructor + * @ignore */ function Forbidden(message, response, body) { ResponseError.apply(this, arguments); @@ -70,8 +98,9 @@ Forbidden.prototype.name = 'Forbidden'; * @param {string} message Error message. * @param {XMLHttpRequest} response The response. * @param {string} body Any parsed response body. - * @extends {ResponseError} + * @extends {module:planet-client/api/errors~ResponseError} * @constructor + * @ignore */ function UnexpectedResponse(message, response, body) { ResponseError.apply(this, arguments); @@ -81,9 +110,10 @@ UnexpectedResponse.prototype = new ResponseError(); UnexpectedResponse.prototype.name = 'UnexpectedResponse'; /** - * An error generated when the request is aborted. + * An error generated when the request is terminated. * @param {string} message Error message. * @constructor + * @ignore */ function AbortedRequest(message) { this.message = message; diff --git a/api/mosaics.js b/api/mosaics.js index d733fb5..0b702f3 100644 --- a/api/mosaics.js +++ b/api/mosaics.js @@ -1,6 +1,6 @@ /** * Provides methods for getting scene metadata. - * @module mosaics + * @module planet-client/api/mosaics */ var Page = require('./page'); @@ -17,7 +17,9 @@ var util = require('./util'); * @param {function(function())} options.terminator A function that is called * with a function that can be called back to terminate the request. * @return {Promise.} A promise that resolves to mosaic metadata or is - * rejected with any error. + * rejected with any error. See the [`errors` + * module](#module:planet-client/api/errors) for a list of the possible + * error types. */ function get(id, options) { options = options || {}; @@ -41,8 +43,10 @@ function get(id, options) { * resources in the response. True by default. * @param {function(function())} options.terminator A function that is called * with a function that can be called back to terminate the request. - * @return {Promise.} A promise that resolves to a page of mosaic - * metadata or is rejected with any error. + * @return {Promise.} A promise that + * resolves to a page of mosaic metadata or is rejected with any error. + * See the [`errors` module](#module:planet-client/api/errors) for a list of + * the possible error types. */ function search(query, options) { options = options || {}; diff --git a/api/page.js b/api/page.js index a7e60ea..45ced28 100644 --- a/api/page.js +++ b/api/page.js @@ -1,7 +1,6 @@ /** * Provides a utility for working with pages of search results. - * @module page - * @private + * @module planet-client/api/page */ var url = require('url'); @@ -13,15 +12,16 @@ var url = require('url'); * @param {function(Object):Promise} factory Function that creates a promise of * new data given a query object. * @constructor + * @ignore */ function Page(data, factory) { var links = data.links; /** - * Get the previous page. If there is no previous page, `previous` will be - * `null`. + * Get the previous page. If there is no previous page, `prev` will be + * `null`. * @param {Object} options Any request options. - * @return {Promise.} The previous page. + * @return {Promise.} The previous page. * @method */ this.prev = !links.prev ? null : function(options) { @@ -29,10 +29,9 @@ function Page(data, factory) { }; /** - * Get the next page. + * Get the next page. If there is no next page, `next` will be `null`. * @param {Object} options Any request options. - * @return {Promise.} The next page. If there is no next page, - * `next` will be `null`. + * @return {Promise.} The next page. * @method */ this.next = !links.next ? null : function(options) { diff --git a/api/quads.js b/api/quads.js index 518c1c6..cd180c4 100644 --- a/api/quads.js +++ b/api/quads.js @@ -1,6 +1,6 @@ /** * Provides methods for getting mosaic quad metadata. - * @module quads + * @module planet-client/api/quads */ var Page = require('./page'); @@ -19,6 +19,8 @@ var util = require('./util'); * with a function that can be called back to terminate the request. * @return {Promise.} A promise that resolves to quad metadata or is * rejected with any error. + * See the [`errors` module](#module:planet-client/api/errors) for a list of + * the possible error types. */ function get(mosaicId, quadId, options) { options = options || {}; @@ -43,8 +45,10 @@ function get(mosaicId, quadId, options) { * resources in the response. True by default. * @param {function(function())} options.terminator A function that is called * with a function that can be called back to terminate the request. - * @return {Promise.} A promise that resolves to a page of quad - * metadata or is rejected with any error. + * @return {Promise.} A promise that + * resolves to a page of quad metadata or is rejected with any error. + * See the [`errors` module](#module:planet-client/api/errors) for a list of + * the possible error types. */ function search(mosaicId, query, options) { options = options || {}; @@ -75,6 +79,8 @@ function search(mosaicId, query, options) { * with a function that can be called back to terminate the request. * @return {Promise.} A promise that resolves to quad metadata or is * rejected with any error. + * See the [`errors` module](#module:planet-client/api/errors) for a list of + * the possible error types. */ function scenes(mosaicId, quadId, options) { options = options || {}; diff --git a/api/request.js b/api/request.js index bb114ef..a55caa6 100644 --- a/api/request.js +++ b/api/request.js @@ -1,6 +1,6 @@ /** * Provides methods for issuing API requests. - * @module requests + * @module planet-client/api/request * @private */ diff --git a/api/scenes.js b/api/scenes.js index 7b11eb3..350acee 100644 --- a/api/scenes.js +++ b/api/scenes.js @@ -1,6 +1,6 @@ /** * Provides methods getting scene metadata. - * @module scenes + * @module planet-client/api/scenes */ var Page = require('./page'); @@ -20,6 +20,8 @@ var util = require('./util'); * with a function that can be called back to terminate the request. * @return {Promise.} A promise that resolves to scene metadata or is * rejected with any error. + * See the [`errors` module](#module:planet-client/api/errors) for a list of + * the possible error types. */ function get(scene, options) { options = options || {}; @@ -49,8 +51,10 @@ function get(scene, options) { * resources in the response. True by default. * @param {function(function())} options.terminator A function that is called * with a function that can be called back to terminate the request. - * @return {Promise.} A promise that resolves to a page of scene - * metadata or is rejected with any error. + * @return {Promise.} A promise that + * resolves to a page of scene metadata or is rejected with any error. + * See the [`errors` module](#module:planet-client/api/errors) for a list of + * the possible error types. */ function search(query, options) { options = options || {}; diff --git a/api/urls.js b/api/urls.js index 5872b33..37b6c18 100644 --- a/api/urls.js +++ b/api/urls.js @@ -1,6 +1,6 @@ /** * API URL utilities. - * @module urls + * @module planet-client/api/urls * @private */ diff --git a/api/util.js b/api/util.js index 665c85d..086525c 100644 --- a/api/util.js +++ b/api/util.js @@ -1,6 +1,6 @@ /** * General utilities. - * @module util + * @module planet-client/api/util * @private */ diff --git a/api/workspaces.js b/api/workspaces.js index 33a0859..7da1be7 100644 --- a/api/workspaces.js +++ b/api/workspaces.js @@ -1,6 +1,6 @@ /** * Provides methods for working with workspaces. - * @module workspaces + * @module planet-client/api/workspaces * @private */ diff --git a/cli/find-mosaics.js b/cli/find-mosaics.js index d21905e..916c157 100644 --- a/cli/find-mosaics.js +++ b/cli/find-mosaics.js @@ -2,7 +2,8 @@ var mosaics = require('../api/mosaics'); /** * Recursively fetch all pages until the limit is reached. - * @param {Promise.} promise A promise that resolves to a page of mosaics. + * @param {Promise.} promise A promise that + * resolves to a page of mosaics. * @param {Array} list An array of mosaic metadata. * @param {number} limit The limit. * @return {Promise.} An array that resolves to an array of mosaics. diff --git a/cli/find-quads.js b/cli/find-quads.js index 36417d6..aa1129f 100644 --- a/cli/find-quads.js +++ b/cli/find-quads.js @@ -44,7 +44,8 @@ function resolveQuery(opts) { /** * Recursively fetch all pages until the limit is reached. - * @param {Promise.} promise A promise that resolves to a page of quads. + * @param {Promise.} promise A promise that + * resolves to a page of quads. * @param {Array} features An array of quad metadata. * @param {number} limit The limit. * @return {Promise.} An array that resolves to an array of quads. diff --git a/cli/find-scenes.js b/cli/find-scenes.js index 759ee18..2fc6180 100644 --- a/cli/find-scenes.js +++ b/cli/find-scenes.js @@ -133,7 +133,8 @@ function resolveQuery(opts) { /** * Recursively fetch all pages until the limit is reached. - * @param {Promise.} promise A promise that resolves to a page of scenes. + * @param {Promise.} promise A promise that + * resolves to a page of scenes. * @param {Array} features An array of scene metadata. * @param {number} limit The limit. * @return {Promise.} An array that resolves to an array of scenes. diff --git a/doc/config.json b/doc/config.json deleted file mode 100644 index 31e6cc3..0000000 --- a/doc/config.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "source": { - "include": ["api"] - }, - "opts": { - "destination": "./build/doc", - "encoding": "utf8", - "readme": "./doc/index.md", - "recurse": true, - "template": "./node_modules/minami" - }, - "plugins": [ - "plugins/markdown" - ], - "templates": { - "default": { - "layoutFile": "./doc/template/layout.tmpl", - "outputSourceFiles": false - } - } -} diff --git a/doc/index.md b/doc/index.md deleted file mode 100644 index 74af878..0000000 --- a/doc/index.md +++ /dev/null @@ -1,40 +0,0 @@ -## planet-client - -A JavaScript client for [Planet's imagery API](https://www.planet.com/docs/). - -### Installation - -The `planet-client` requires Node >= 0.12. Install the `planet-client` package `npm` (which comes with [Node](https://nodejs.org/)). - - npm install planet-client - -### Using the Library - -The `planet-client` package can be used in a Node based project or in the browser with a CommonJS module loader (like [Browserify](http://browserify.org/) or [Webpack](http://webpack.github.io/)). - -The library requires a global [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) implementation. This comes with Node >= 0.12 and [modern browsers](http://caniuse.com/#search=promise). To use `planet-client` in an environment without `Promise`, you can [use a polyfill](https://www.google.com/search?q=promise+polyfill). - -With the above prerequisites, you can start using the `planet-client` package in your application: - -```js -var planet = require('planet-client'); - -// set up your API key for all future requests -planet.auth.setKey(process.env.PL_API_KEY); - -var lastWeek = new Date(Date.now() - (7 * 24 * 60 * 60 * 1000)); - -var query = { - 'acquired.gte': lastWeek.toISOString() -}; - -planet.scenes.search(query) - .then(function(page) { - console.log('Total count: ' + page.data.count + ' scenes since ' + lastWeek); - }) - .catch(function(err) { - console.error('Failed to fetch scenes:', err.message); - }); -``` - -See the list of modules to the left for details on what is exported by the library. diff --git a/doc/layouts/main.html b/doc/layouts/main.html new file mode 100644 index 0000000..df9a415 --- /dev/null +++ b/doc/layouts/main.html @@ -0,0 +1,118 @@ + + + + {{ title }} + + + + {{{ contents }}} + + diff --git a/doc/partials/class.html b/doc/partials/class.html new file mode 100644 index 0000000..1e5403f --- /dev/null +++ b/doc/partials/class.html @@ -0,0 +1,24 @@ +

+ + {{#if ignore}} + mod.{{name}} + {{else}} + var {{lower name}} = new mod.{{name}}() + {{/if}} + +

+

{{md description}}

+{{#if methods}} + {{#each methods}} +
+ {{>method this}} +
+ {{/each}} +{{/if}} +{{#if members}} + {{#each members}} +
+ {{>member this}} +
+ {{/each}} +{{/if}} diff --git a/doc/partials/function.html b/doc/partials/function.html new file mode 100644 index 0000000..71f17d4 --- /dev/null +++ b/doc/partials/function.html @@ -0,0 +1,14 @@ +

+ + + mod.{{name}}({{listParams params}}) + + +

+

{{md description}}

+{{#if params}} + {{>params this}} +{{/if}} +{{#if returns}} + {{>returns this}} +{{/if}} diff --git a/doc/partials/member.html b/doc/partials/member.html new file mode 100644 index 0000000..934f1bb --- /dev/null +++ b/doc/partials/member.html @@ -0,0 +1,9 @@ +

+ + + {{instance memberof}}.{{name}} + + + : {{>type this}} +

+

{{md description}}

diff --git a/doc/partials/method.html b/doc/partials/method.html new file mode 100644 index 0000000..84ad023 --- /dev/null +++ b/doc/partials/method.html @@ -0,0 +1,14 @@ +

+ + + {{instance memberof}}.{{name}}({{listParams params}}) + + +

+

{{md description}}

+{{#if params}} + {{>params this}} +{{/if}} +{{#if returns}} + {{>returns this}} +{{/if}} diff --git a/doc/partials/module.html b/doc/partials/module.html new file mode 100644 index 0000000..b2a3c85 --- /dev/null +++ b/doc/partials/module.html @@ -0,0 +1,25 @@ +
+

+ {{name}} +

+

{{md description}}

+
+

var mod = require('{{name}}')

+ + {{#if classes}} + {{#each classes}} +
+ {{>class this}} +
+ {{/each}} + {{/if}} + + {{#if functions}} + {{#each functions}} +
+ {{>function this}} +
+ {{/each}} + {{/if}} + +
diff --git a/doc/partials/params.html b/doc/partials/params.html new file mode 100644 index 0000000..bf61f78 --- /dev/null +++ b/doc/partials/params.html @@ -0,0 +1,9 @@ +

Arguments

+
    + {{#each params}} +
  • + {{name}} : + {{>type this}} - {{md description}} +
  • + {{/each}} +
diff --git a/doc/partials/returns.html b/doc/partials/returns.html new file mode 100644 index 0000000..80eee1d --- /dev/null +++ b/doc/partials/returns.html @@ -0,0 +1,4 @@ +

Returns

+
    +
  • {{>type returns.[0]}} - {{md returns.[0].description}}
  • +
diff --git a/doc/partials/toc.html b/doc/partials/toc.html new file mode 100644 index 0000000..1ee273c --- /dev/null +++ b/doc/partials/toc.html @@ -0,0 +1,33 @@ +
+

Planet Client

+
+

API Modules

+ {{#if api}} + {{#each modules}} + + + + {{/each}} + {{/if}} +

CLI Usage

+
diff --git a/doc/partials/type.html b/doc/partials/type.html new file mode 100644 index 0000000..a03dbf2 --- /dev/null +++ b/doc/partials/type.html @@ -0,0 +1,3 @@ + + {{#each type.names}}{{#if @index}}|{{/if}}{{linkType this}}{{/each}} + diff --git a/doc/src/api/index.html b/doc/src/api/index.html new file mode 100644 index 0000000..e37e9ea --- /dev/null +++ b/doc/src/api/index.html @@ -0,0 +1,18 @@ +--- +layout: main.html +title: API Docs +--- + +
+
+

API Modules

+

+ The planet-client package is organized as a collection of modules that roughly follow the structure of the HTTP API. The API provides access to individual scenes from a variety of providers and mosaics of those scenes. +

+
+ {{#each modules}} + {{>module this}} + {{/each}} +
diff --git a/doc/src/cli/index.html b/doc/src/cli/index.html new file mode 100644 index 0000000..e9f5fa2 --- /dev/null +++ b/doc/src/cli/index.html @@ -0,0 +1,48 @@ +--- +layout: main.html +title: CLI Docs +--- + + +
+ +

CLI Usage

+ +

+ The planet-client package provides a planet executable. This can be installed globally (npm install --global planet-client), or if you install it locally, you can add the executable to your path (export PATH=path/to/node_modules/.bin:$PATH). +

+ +

+ The general syntax for the planet executable is planet [options]. To see a list of commands, run the following: +

+ +
planet --help
+ +

+ You can get help for a specific command by adding --help to the command name (e.g. planet find-scenes --help). +

+ +

+ To take advantage of command line completion with the planet executable, you can run the following in bash: +

+ +
eval "$(planet completion)"
+ +

+ To enable this every time you start a new shell, you can append the output of planet completion to your .bashrc: +

+ +
planet completion >> ~/.bashrc
+ +

+ The CLI will be fully documented when it is a bit more stable. For now, you can get a preview of what's available with this video: +

+ + + + + +
diff --git a/doc/src/index.html b/doc/src/index.html new file mode 100644 index 0000000..9f6dd18 --- /dev/null +++ b/doc/src/index.html @@ -0,0 +1,58 @@ +--- +layout: main.html +title: Planet Client +--- + + + +
+

planet-client

+ +

+ A JavaScript client for Planet's imagery API. +

+ +

Installation

+ +

+ Install the planet-client package with npm (which comes with Node). +

+ +
npm install planet-client
+ +

+ The planet-client package provides a library for use in your application and a planet executable for command line use. See details on both below. +

+ +

Using the Library

+ +

+ The planet-client package can be used in a Node based project or in the browser with a CommonJS module loader (like Browserify or Webpack). +

+ +

+ The library requires a global Promise implementation. This comes with Node >= 0.12 and modern browsers. To use planet-client in an environment without Promise, you can use a polyfill. +

+ +

+ With the above prerequisites, you can start using the planet-client package in your application. See the client API documentation for details on using the library. +

+ +

Using the CLI

+ +

+ The planet-client package provides a planet executable. This can be installed globally (npm install --global planet-client), or if you install it locally, you can add the executable to your path (export PATH=$PATH:path/to/node_modules/.bin). +

+ +

+ The general syntax for the planet executable is planet [options]. To see a list of commands, run the following: +

+ +
planet --help
+ +

+ See the CLI docs for more details on using the planet command. +

+
diff --git a/doc/template/layout.tmpl b/doc/template/layout.tmpl deleted file mode 100644 index d8b211f..0000000 --- a/doc/template/layout.tmpl +++ /dev/null @@ -1,40 +0,0 @@ - - - - - <?js= title ?> - Documentation - - - - - - - - - - - - - - - - - -
- -

- - - -
- - - - - diff --git a/package.json b/package.json index 18ce1e5..c6ef3a9 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ "test-debug": "mocha --debug-brk --recursive test", "start": "watchy --watch bin,examples,api,cli,test -- npm test", "postpublish": "npm run publish-doc", - "doc": "jsdoc --configure doc/config.json", + "apidoc": "jsdoc --template jsdoc-json --destination build/api.json api", + "doc": "npm run apidoc && node --harmony-generators tasks/build-docs.js", + "start-doc": "watchy --watch doc,api,tasks -- npm run doc", "publish-doc": "npm run doc && gh-pages --dist build/doc" }, "bin": { @@ -30,7 +32,13 @@ "eslint": "^0.22.1", "eslint-config-planet": "^2.0.0", "gh-pages": "^0.3.1", + "handlebars": "^3.0.3", "jsdoc": "^3.3.2", + "jsdoc-json": "^2.0.0", + "marked": "^0.3.5", + "metalsmith": "^2.0.1", + "metalsmith-in-place": "^1.3.1", + "metalsmith-layouts": "^1.3.0", "minami": "^1.1.0", "mocha": "^2.2.5", "nyc": "^3.1.0", diff --git a/tasks/build-docs.js b/tasks/build-docs.js new file mode 100644 index 0000000..f02acc3 --- /dev/null +++ b/tasks/build-docs.js @@ -0,0 +1,205 @@ +var Metalsmith = require('metalsmith'); +var handlebars = require('handlebars'); +var inPlace = require('metalsmith-in-place'); +var layouts = require('metalsmith-layouts'); +var marked = require('marked'); + +var pkg = require('../package.json'); +var api = require('../build/api.json'); + +function getNamed(name, array) { + var item; + for (var i = 0, ii = array.length; i < ii; ++i) { + if (array[i].name === name) { + item = array[i]; + break; + } + } + if (!item) { + item = {name: name}; + array.push(item); + } + return item; +} + +var MODULE_NAME_RE = /^module:([\w-\/]+)~/; + +function getModuleName(longname) { + var match = longname.match(MODULE_NAME_RE); + if (!match) { + throw new Error('Expected to parse a module name from ' + longname); + } + return match[1]; +} + +var CLASS_NAME_RE = /^module:[\w-\/]+~([A-Z]\w+)$/; + +function getClassName(memberof) { + var match = memberof.match(CLASS_NAME_RE); + if (!match) { + throw new Error('Expected to parse a class name from ' + memberof); + } + return match[1]; +} + +function getModule(longname, modules) { + var name = getModuleName(longname); + return getNamed(name, modules); +} + +function getClass(memberof, classes) { + var name = getClassName(memberof); + return getNamed(name, classes); +} + +function organizeDocs(docs) { + var modules = []; + for (var i = 0, ii = docs.length; i < ii; ++i) { + var doc = docs[i]; + var module, cls; + switch (doc.kind) { + case 'module': + module = getNamed(doc.name, modules); + assign(module, doc); + break; + case 'class': + module = getModule(doc.longname, modules); + if (!module.classes) { + module.classes = []; + } + cls = getClass(doc.longname, module.classes); + assign(cls, doc); + break; + case 'member': + module = getModule(doc.longname, modules); + cls = getClass(doc.memberof, module.classes); + if (!cls.members) { + cls.members = []; + } + cls.members.push(doc); + break; + case 'function': + module = getModule(doc.longname, modules); + if (doc.scope === 'instance') { + if (!module.classes) { + module.classes = []; + } + cls = getClass(doc.memberof, module.classes); + if (!cls.methods) { + cls.methods = []; + } + cls.methods.push(doc); + } else { + if (!module.functions) { + module.functions = []; + } + module.functions.push(doc); + } + break; + default: + //pass + } + } + return modules; +} + +function assign(target, source) { + for (var key in source) { + target[key] = source[key]; + } + return target; +} + +function main(callback) { + + var modules = organizeDocs(api.docs).filter(function(module) { + return module.access !== 'private'; + }).sort(function(a, b) { + return a.name < b.name ? -1 : 1; + }); + + var smith = new Metalsmith('.') + .source('doc/src') + .destination('build/doc') + .concurrency(25) + .metadata({ + version: pkg.version, + modules: modules + }) + .use(inPlace({ + engine: 'handlebars', + partials: 'doc/partials', + helpers: { + instance: function(memberof) { + var className = getClassName(memberof); + return className.charAt(0).toLowerCase() + className.slice(1); + }, + listParams: function(params) { + if (!params) { + return ''; + } + return params.map(function(param) { + return param.name; + }).filter(function(name) { + return name.indexOf('.') === -1; + }).join(', '); + }, + linkType: function(type) { + var openIndex = type.lastIndexOf('<'); + var closeIndex = type.indexOf('>'); + var match, link; + if (openIndex >= 0 && closeIndex > openIndex) { + match = type.slice(openIndex + 1, closeIndex).match( + CLASS_NAME_RE); + if (match) { + link = new handlebars.SafeString( + type.slice(0, openIndex + 1).replace('<', '<') + + '' + match[1] + '' + + type.slice(closeIndex).replace('>', '>')); + } else { + link = type; + } + } else { + match = type.match(CLASS_NAME_RE); + if (match) { + link = new handlebars.SafeString( + '