.. Licensed under the Apache License, Version 2.0 (the "License"); you may not
.. use this file except in compliance with the License. You may obtain a copy of
.. the License at
..
..   http://www.apache.org/licenses/LICENSE-2.0
..
.. Unless required by applicable law or agreed to in writing, software
.. distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
.. WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
.. License for the specific language governing permissions and limitations under
.. the License.

.. default-domain:: js

.. _query-server/js:

==========
JavaScript
==========

.. note::
    While every design function has access to all JavaScript objects, the table
    below describes appropriate usage cases. For example, you may use
    :func:`emit` in :ref:`mapfun`, but :func:`getRow` is not permitted
    during :ref:`mapfun`.

+--------------------------------+---------------------------------------------+
| JS Function                    | Reasonable to use in design doc functions   |
+================================+=============================================+
| :func:`emit`                   | :ref:`mapfun`                               |
+--------------------------------+---------------------------------------------+
| :func:`getRow`                 | :ref:`listfun`                              |
+--------------------------------+---------------------------------------------+
| :data:`JSON`                   | any                                         |
+--------------------------------+---------------------------------------------+
| :func:`isArray`                | any                                         |
+--------------------------------+---------------------------------------------+
| :func:`log`                    | any                                         |
+--------------------------------+---------------------------------------------+
| :func:`provides`               | :ref:`showfun`, :ref:`listfun`              |
+--------------------------------+---------------------------------------------+
| :func:`registerType`           | :ref:`showfun`, :ref:`listfun`              |
+--------------------------------+---------------------------------------------+
| :func:`require`                | any, except :ref:`reducefun`                |
+--------------------------------+---------------------------------------------+
| :func:`send`                   | :ref:`listfun`                              |
+--------------------------------+---------------------------------------------+
| :func:`start`                  | :ref:`listfun`                              |
+--------------------------------+---------------------------------------------+
| :func:`sum`                    | any                                         |
+--------------------------------+---------------------------------------------+
| :func:`toJSON`                 | any                                         |
+--------------------------------+---------------------------------------------+

Design functions context
========================

Each design function executes in a special context of predefined objects,
modules and functions:

.. function:: emit(key, value)

    Emits a `key`-`value` pair for further processing by CouchDB after the map
    function is done.

    :param key: The view key
    :param value: The `key`'s associated value

    .. code-block:: javascript

        function(doc){
            emit(doc._id, doc._rev);
        }

.. function:: getRow()

    Extracts the next row from a related view result.

    :return: View result row
    :rtype: object

    .. code-block:: javascript

        function(head, req){
            send('[');
            row = getRow();
            if (row){
                send(toJSON(row));
                while(row = getRow()){
                    send(',');
                    send(toJSON(row));
                }
            }
            return ']';
        }

.. data:: JSON

    `JSON2 <https://github.com/apache/couchdb/blob/main/share/server/json2.js>`_
    object.

.. function:: isArray(obj)

    A helper function to check if the provided value is an `Array`.

    :param obj: Any JavaScript value
    :return: ``true`` if `obj` is `Array`-typed, ``false`` otherwise
    :rtype: boolean

.. function:: log(message)

    Log a message to the CouchDB log (at the `INFO` level).

    :param message: Message to be logged

    .. code-block:: javascript

        function(doc){
            log('Procesing doc ' + doc['_id']);
            emit(doc['_id'], null);
        }

    After the map function has run, the following line can be found in CouchDB
    logs (e.g. at `/var/log/couchdb/couch.log`):

    .. code-block:: text

        [Sat, 03 Nov 2012 17:38:02 GMT] [info] [<0.7543.0>] OS Process #Port<0.3289> Log :: Processing doc 8d300b86622d67953d102165dbe99467

.. function:: provides(key, func)

    Registers callable handler for specified MIME key.

    :param key: MIME key previously defined by :func:`registerType`
    :param func: MIME type handler

.. function:: registerType(key, *mimes)

    Registers list of MIME types by associated `key`.

    :param key: MIME types
    :param mimes: MIME types enumeration

    Predefined mappings (`key`-`array`):

    - **all**: ``*/*``
    - **text**: ``text/plain; charset=utf-8``, ``txt``
    - **html**: ``text/html; charset=utf-8``
    - **xhtml**: ``application/xhtml+xml``, ``xhtml``
    - **xml**: ``application/xml``, ``text/xml``, ``application/x-xml``
    - **js**: ``text/javascript``, ``application/javascript``,
      ``application/x-javascript``
    - **css**: ``text/css``
    - **ics**: ``text/calendar``
    - **csv**: ``text/csv``
    - **rss**: ``application/rss+xml``
    - **atom**: ``application/atom+xml``
    - **yaml**: ``application/x-yaml``, ``text/yaml``
    - **multipart_form**: ``multipart/form-data``
    - **url_encoded_form**: ``application/x-www-form-urlencoded``
    - **json**: ``application/json``, ``text/x-json``

.. function:: require(path)

    Loads CommonJS module by a specified `path`. The path should not start with
    a slash.

    :param path: A CommonJS module path started from design document root
    :return: Exported statements

.. function:: send(chunk)

    Sends a single string `chunk` in response.

    :param chunk: Text chunk

    .. code-block:: javascript

        function(head, req){
            send('Hello,');
            send(' ');
            send('Couch');
            return ;
        }

.. function:: start(init_resp)

    Initiates chunked response. As an option, a custom
    :ref:`response <response_object>` object may be sent at this point.
    For `list`-functions only!

    .. note::
        list functions may set the `HTTP response code` and `headers` by calling
        this function. This function must be called before :func:`send`,
        :func:`getRow` or a `return` statement; otherwise, the query server will
        implicitly call this function with the empty object (``{}``).

    .. code-block:: javascript

        function(head, req){
            start({
                "code": 302,
                "headers": {
                    "Location": "http://couchdb.apache.org"
                }
            });
            return "Relax!";
        }

.. function:: sum(arr)

    Sum `arr`'s items.

    :param arr: Array of numbers
    :rtype: number

.. function:: toJSON(obj)

    Encodes `obj` to JSON string. This is an alias for the ``JSON.stringify``
    method.

    :param obj: JSON-encodable object
    :return: JSON string

.. _commonjs:

CommonJS Modules
================

Support for `CommonJS Modules <http://wiki.commonjs.org/wiki/Modules/1.1.1>`_
(introduced in CouchDB 0.11.0) allows you to create modular design functions
without the need for duplication of functionality.

Here's a CommonJS module that checks user permissions:

.. code-block:: javascript

    function user_context(userctx, secobj) {
        var is_admin = function() {
            return userctx.indexOf('_admin') != -1;
        }
        return {'is_admin': is_admin}
    }

    exports['user'] = user_context

Each module has access to additional global variables:

- **module** (`object`): Contains information about the stored module

  - **id** (`string`): The module id; a JSON path in ddoc context
  - **current** (`code`): Compiled module code object
  - **parent** (`object`): Parent frame
  - **exports** (`object`): Export statements

- **exports** (`object`): Shortcut to the ``module.exports`` object

The CommonJS module can be added to a design document, like so:

.. code-block:: javascript

    {
        "views": {
            "lib": {
                "security": "function user_context(userctx, secobj) { ... }"
            }
        },
        "validate_doc_update": "function(newdoc, olddoc, userctx, secobj) {
            user = require('views/lib/security').user_context(userctx, secobj);
            return user.is_admin();
        }"
        "_id": "_design/test"
    }

Modules paths are relative to the design document's ``views`` object, but
modules can only be loaded from the object referenced via ``lib``. The
``lib`` structure can still be used for view functions as well, by simply
storing view functions at e.g. ``views.lib.map``, ``views.lib.reduce``, etc.
