From e1097156439cbd088d29887b2034892666aa47f6 Mon Sep 17 00:00:00 2001 From: Martijn van de Rijdt Date: Thu, 12 Oct 2023 11:10:12 -0400 Subject: [PATCH] Revert "Revert "Merge/6.2.0"" --- .eslintrc.json | 20 +- CHANGELOG.md | 29 + Gruntfile.js | 4 +- README.md | 10 +- app/controllers/media-controller.js | 2 +- app/controllers/transformation-controller.js | 79 +- app/lib/communicator.js | 2 +- app/lib/pdf.js | 1 + app/models/cache-model.js | 2 +- app/models/survey-model.js | 2 +- app/views/index.pug | 2 + app/views/surveys/webform.pug | 2 +- config/build.js | 35 +- config/express.js | 2 +- docs/app_controllers_api-controller.js.html | 2 +- .../app_controllers_api-v1-controller.js.html | 2 +- .../app_controllers_api-v2-controller.js.html | 2 +- ...trollers_authentication-controller.js.html | 2 +- docs/app_controllers_error-handler.js.html | 2 +- docs/app_controllers_media-controller.js.html | 4 +- ...app_controllers_offline-controller.js.html | 2 +- docs/app_controllers_pages-controller.js.html | 2 +- ..._controllers_submission-controller.js.html | 2 +- .../app_controllers_survey-controller.js.html | 2 +- ...trollers_transformation-controller.js.html | 78 +- docs/app_lib_communicator.js.html | 4 +- docs/app_lib_custom-error.js.html | 2 +- docs/app_lib_media.js.html | 2 +- docs/app_lib_pdf.js.html | 3 +- docs/app_lib_router-utils.js.html | 2 +- docs/app_lib_utils.js.html | 2 +- docs/app_models_account-model.js.html | 2 +- docs/app_models_cache-model.js.html | 4 +- docs/app_models_config-model.js.html | 2 +- docs/app_models_instance-model.js.html | 2 +- docs/app_models_record-model.js.html | 2 +- docs/app_models_submission-model.js.html | 2 +- docs/app_models_survey-model.js.html | 4 +- docs/app_models_user-model.js.html | 2 +- docs/global.html | 2 +- docs/index.html | 11 +- docs/module-account-model.html | 2 +- docs/module-api-controller.html | 2 +- docs/module-api-v1-controller.html | 2 +- docs/module-api-v2-controller.html | 2 +- docs/module-authentication-controller.html | 2 +- docs/module-cache-model.html | 2 +- docs/module-communicator.html | 2 +- docs/module-config-model.html | 2 +- docs/module-custom-error.html | 2 +- docs/module-duplicates.html | 2 +- docs/module-error-handler.html | 2 +- docs/module-instance-model.html | 2 +- docs/module-media-controller.html | 2 +- docs/module-offline-resources-controller.html | 2 +- docs/module-pages-controller.html | 2 +- docs/module-pdf.html | 2 +- docs/module-router-utils.html | 2 +- docs/module-submission-model.html | 2 +- docs/module-submissions-controller.html | 2 +- docs/module-survey-controller.html | 2 +- docs/module-survey-model.html | 2 +- docs/module-transformation-controller.html | 178 +- docs/module-user-model.html | 2 +- docs/module-utils.html | 2 +- docs/tools_duplicates.js.html | 2 +- docs/tutorial-00-getting-started.html | 6 +- docs/tutorial-02-heroku.html | 2 +- docs/tutorial-10-configure.html | 2 +- docs/tutorial-12-ordinals.html | 28 +- docs/tutorial-20-update.html | 2 +- docs/tutorial-30-develop.html | 2 +- docs/tutorial-32-api.html | 2 +- docs/tutorial-34-custom-widgets.html | 2 +- docs/tutorial-36-theming.html | 2 +- docs/tutorial-38-iframe-postmessage.html | 2 +- docs/tutorial-40-translate.html | 2 +- ...torial-60-authentication-and-security.html | 2 +- docs/tutorial-70-browser-support.html | 2 +- docs/tutorial-80-comments.html | 2 +- docs/tutorial-90-duplicates.html | 2 +- locales/src/en/translation.json | 5 + locales/src/es/translation.json | 12 +- locales/src/fr/translation.json | 6 +- locales/src/sk/translation.json | 19 +- locales/src/uk/translation.json | 408 ++++ package-lock.json | 1643 ++++++++++++----- package.json | 35 +- public/js/src/enketo-webform-oc.js | 17 +- public/js/src/enketo-webform.js | 12 +- public/js/src/module/connection.js | 139 +- public/js/src/module/controller-webform-oc.js | 16 +- public/js/src/module/controller-webform.js | 28 +- public/js/src/module/exponential-backoff.js | 28 + public/js/src/module/file-manager.js | 2 +- public/js/src/module/form.js | 6 +- public/js/src/module/geojson.js | 129 +- public/js/src/module/input.js | 6 +- public/js/src/module/records-queue.js | 279 +-- test/client/config/karma.conf.js | 14 +- test/client/connection.spec.js | 56 +- .../feature/geojson-external-instance.spec.js | 12 +- test/client/form-extensions.spec.js | 40 + test/client/records-queue.spec.js | 346 +++- ...nt.spec.js => relevant-extensions.spec.js} | 2 - test/fixtures/connection/preview.xml | 38 + ...-collection-with-unsupported-type.geojson} | 2 +- .../geojson/feature-collection.geojson | 26 +- test/server/transformation-controller.spec.js | 59 +- tutorials/00-getting-started.md | 8 + 110 files changed, 2826 insertions(+), 1193 deletions(-) create mode 100644 locales/src/uk/translation.json create mode 100644 public/js/src/module/exponential-backoff.js create mode 100644 test/client/form-extensions.spec.js rename test/client/{relevant.spec.js => relevant-extensions.spec.js} (99%) create mode 100644 test/fixtures/connection/preview.xml rename test/fixtures/geojson/{feature-collection-with-line.geojson => feature-collection-with-unsupported-type.geojson} (89%) diff --git a/.eslintrc.json b/.eslintrc.json index 0d3439df5..b140dd479 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,12 +9,27 @@ "structuredClone": true }, "extends": ["airbnb", "prettier"], - "plugins": ["chai-friendly", "jsdoc", "prettier", "unicorn"], + "plugins": [ + "chai-friendly", + "jsdoc", + "prettier", + "unicorn", + "@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", "parserOptions": { "sourceType": "module", "ecmaVersion": 2021 }, "settings": { + "import/parsers": { + "@typescript-eslint/parser": [".js", ".ts", ".tsx"] + }, + "import/resolver": { + "typescript": { + "alwaysTryTypes": true + } + }, "jsdoc": { "tagNamePreference": { "returns": "return" @@ -31,7 +46,8 @@ "enketo/widgets", "enketo/translator", "enketo/dialog", - "enketo/file-manager" + "enketo/file-manager", + "enketo-transformer/web" ] } ], diff --git a/CHANGELOG.md b/CHANGELOG.md index 392a403b8..cdf876274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,35 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 6.2.0 - 2023-07-03 + +- Make pdf generation timeout configurable (#560) +- Added the Ukrainian translation (#569) +- Optimizations: do less redundant work, part 2 (enketo-core#976) +- Fix: gracefully handle undefined key (enketo-core#978) +- Fix: TOC navigation in pages theme (enketo-core#983) +- Fix: Respect existing val of type='time' (enketo-core#980) + +## 6.1.0 - 2023-05-10 + +- removed: analog-scale widget (#525) _Note: now maintained by OpenClinica (https://github.com/OpenClinica/enketo-express-oc/tree/master/widget/analog-scale). Not considered a breaking change because usage outside of OpenClinica is not known_ +- fixed: The app UI strings in newly created repeats are not translated (#527) +- Fix: validate CSV header names according to XML spec (#530) +- Use pm2-runtime on docker/start.sh (#533) +- Fix: revert jQuery upgrade (#539) +- Use client-side transform for preview-by-URL (#540) +- changed: updated Slovak translation (#542) +- Use exponential backoff for submission attempts in offline mode (#543) +- feat(app): add enketo namespace to all debug statements (#547) +- Add support for LineString and Polygon GeoJSON types (#554) +- Fix: further simplify geopicker widget selector (#954) +- Fix: undesired newlines in print view in select/select1 labels (#957) +- Add browser-based transformation (#171) +- Reimplement draw/signature/annotate widget to preserve original image size when annotating and improve resize performance (#960) +- Fix: focus first active input/widget on load, page navigation, user-added repeat (#969) +- Performance improvements: NumberInput widgets, `excludeNonRelevant` (#971) +- Fix: localized numeral entry by keyboard in number input widgets (#973) + ## 6.0.0 - 2023-02-08 - **BREAKING CHANGE**: Removed IE11 support (enketo-core#946) diff --git a/Gruntfile.js b/Gruntfile.js index 3bbfb9222..59f304c97 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -6,7 +6,7 @@ module.exports = (grunt) => { '!.nyc_output', '!**/node_modules/**', '!test/client/forms/forms.js', - '!public/js/build/*', + '!public/js/build/**', '!docs/**', '!test-coverage/**', ]; @@ -105,7 +105,7 @@ module.exports = (grunt) => { 'find locales -name "translation-combined.json" -delete && rm -fr locales/??', }, 'clean-js': { - command: 'rm -f public/js/build/* && rm -f public/js/*.js', + command: 'rm -rf public/js/build/* && rm -f public/js/*.js', }, translation: { command: diff --git a/README.md b/README.md index ff3b9d99a..f40d7df62 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ OpenClinica users, in addition to the configuration documentation linked above, Enketo was initiated in 2009 by Martijn van de Rijdt as a web-based alternative or complement to [ODK Collect](https://docs.getodk.org/collect-intro/). It has become a core component of the ODK ecosystem and been adopted by several organizations beyond that ecosystem. -As of 2022, Enketo is maintained by [Trevor Schmidt](https://github.com/eyelidlessness/) and [the ODK team](https://getodk.org/about/team.html). Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its [Technical Advisory Board](https://getodk.org/about/ecosystem.html). +As of 2022, Enketo is maintained by the [ODK team](https://getodk.org/about/team.html) (primarily [Trevor Schmidt](https://github.com/eyelidlessness/)). Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its [Technical Advisory Board](https://getodk.org/about/ecosystem.html). Our current primary goals are: @@ -49,7 +49,7 @@ Feature requests and project discussion are welcome on the [ODK forum](https://f ### Translation -The user interface was translated by: Karol Kozyra (Swedish), Badisches Rotes Kreuz (German), Serkan Tümbaş (Turkish), Hélène Martin (French), Gurjot Sidhu(Hindi, Panjabi), "Abcmen" (Turkish), Otto Saldadze, Makhare Atchaidze, David Sichinava, Elene Ergeshidze (Georgian), Nancy Shapsough (Arabic), Noel O'Boyle (French), Miguel Moreno (Spanish), Tortue Torche (French), Bekim Kajtazi (Albanian), Marc Kreidler (German), Darío Hereñú (Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch). +The user interface was translated by: Oleg Zhyliak (Ukrainian), Karol Kozyra (Swedish), Badisches Rotes Kreuz (German), Serkan Tümbaş (Turkish), Hélène Martin (French), Gurjot Sidhu(Hindi, Panjabi), "Abcmen" (Turkish), Otto Saldadze, Makhare Atchaidze, David Sichinava, Elene Ergeshidze (Georgian), Nancy Shapsough (Arabic), Noel O'Boyle (French), Miguel Moreno (Spanish), Tortue Torche (French), Bekim Kajtazi (Albanian), Marc Kreidler (German), Darío Hereñú (Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch). _Send a message if you'd like to contribute! We use an easy web interface provided by [Transifex](https://www.transifex.com/projects/p/enketo-express/)._ @@ -80,13 +80,15 @@ OpenClinica has a few [additional text strings](./locales/src/en/translation-add ### Funding -The development of this application was funded by [KoBo Toolbox (Harvard Humanitarian Initiative)](http://www.kobotoolbox.org), [iMMAP](http://immap.org), [OpenClinica](https://openclinica.com), [London School of Hygiene and Tropical Medicine](https://opendatakit.lshtm.ac.uk/), [DIAL Open Source Center](https://www.osc.dial.community/) and [Enketo LLC](https://www.linkedin.com/company/enketo-llc). The [Enketo-core](https://github.com/enketo/enketo-core) library (the form engine + themes) used in this application obtained significant funding from [SEL (Columbia University)](http://modi.mech.columbia.edu/), the [Santa Fe Institute](http://www.santafe.edu/), [Ona](https://ona.io) and the [HRP project](http://www.who.int/reproductivehealth/topics/mhealth/en/). +The development of this application is now led by [ODK](https://getodk.org) and funded by customers of the ODK Cloud hosted service. + +Past funders include [KoBo Toolbox (Harvard Humanitarian Initiative)](http://www.kobotoolbox.org), [iMMAP](http://immap.org), [OpenClinica](https://openclinica.com), [London School of Hygiene and Tropical Medicine](https://opendatakit.lshtm.ac.uk/), [DIAL Open Source Center](https://www.osc.dial.community/) and [Enketo LLC](https://www.linkedin.com/company/enketo-llc). Also see [Enketo Core sponsors](https://github.com/enketo/enketo-core#sponsors). ### License See [the license document](https://github.com/enketo/enketo-express/blob/master/LICENSE) for this application's license. -Note that some of the libraries used in this app have a different license. In particular note [this one](https://github.com/enketo/enketo-xpathjs). +Note that some of the libraries used in this app have a different license. Note the 'Powered by Enketo' footer requirement as explained in [enketo-core](https://github.com/enketo/enketo-core#license). This requirement is applicable to all Enketo apps, including this one, unless an exemption was granted. diff --git a/app/controllers/media-controller.js b/app/controllers/media-controller.js index d7b025e68..7f639487d 100644 --- a/app/controllers/media-controller.js +++ b/app/controllers/media-controller.js @@ -8,7 +8,7 @@ const request = require('request'); const express = require('express'); const router = express.Router(); -const debug = require('debug')('media-controller'); +const debug = require('debug')('enketo:media-controller'); const { RequestFilteringHttpAgent, RequestFilteringHttpsAgent, diff --git a/app/controllers/transformation-controller.js b/app/controllers/transformation-controller.js index 8541eecd1..6d1290f5f 100644 --- a/app/controllers/transformation-controller.js +++ b/app/controllers/transformation-controller.js @@ -4,7 +4,7 @@ const transformer = require('enketo-transformer'); const communicator = require('../lib/communicator'); -const { TranslatedError } = require('../lib/custom-error'); +const { ResponseError, TranslatedError } = require('../lib/custom-error'); const surveyModel = require('../models/survey-model'); const cacheModel = require('../models/cache-model'); const account = require('../models/account-model'); @@ -13,7 +13,6 @@ const config = require('../models/config-model').server; const utils = require('../lib/utils'); const routerUtils = require('../lib/router-utils'); const express = require('express'); -const url = require('url'); const mediaLib = require('../lib/media'); const router = express.Router(); @@ -101,27 +100,15 @@ async function getSurveyParts(req, res, next) { /** @type {string | null} */ let formId = null; - /** @type {string | null} */ - let formFileName = null; - try { let survey = await _getSurveyParams(req); - // A request with "xformUrl" body parameter was used (unlaunched form) - if (survey.info != null) { - formFileName = survey.info.downloadUrl.replace( - /.*\/([^/]+)$/, - '$1' - ); - survey = await _getFormDirectly(survey); - - _respond(res, survey); + formId = survey.openRosaId; - return; + if (formId == null) { + throw new ResponseError(404); } - formId = survey.openRosaId; - const authenticated = await _authenticate(survey); const cached = await _getFormFromCache(authenticated); @@ -142,14 +129,10 @@ async function getSurveyParts(req, res, next) { }); } catch (error) { if (error.status === 403) { - const notFoundError = - formId == null - ? new TranslatedError('error.notfounddirectformurl', { - formFileName, - }) - : new TranslatedError('error.notfoundinformlist', { - formId, - }); + const notFoundError = new TranslatedError( + 'error.notfoundinformlist', + { formId } + ); notFoundError.status = 404; @@ -183,17 +166,6 @@ function getSurveyHash(req, res, next) { .catch(next); } -/** - * @param {module:survey-model~SurveyObject} survey - survey object - * - * @return { Promise } a Promise resolving with survey object with form transformation result - * - */ -function _getFormDirectly(survey) { - survey.openclinica = true; - return communicator.getXForm(survey).then(transformer.transform); -} - /** * @param {module:survey-model~SurveyObject} survey - survey object * @@ -233,8 +205,11 @@ function _updateCache(survey) { delete survey.mediaHash; delete survey.mediaUrlHash; delete survey.formHash; - - return _getFormDirectly(survey).then(cacheModel.set); + survey.openclinica = true; + return communicator + .getXForm(survey) + .then(transformer.transform) + .then(cacheModel.set); } return survey; @@ -359,7 +334,6 @@ function _setCookieAndCredentials(survey, req) { * @return { Promise } a Promise resolving with survey object */ function _getSurveyParams(req) { - const params = req.body; const customParamName = req.app.get( 'query parameter to pass to submission' ); @@ -376,32 +350,7 @@ function _getSurveyParams(req) { return _setCookieAndCredentials(survey, req); }); } - if (params.xformUrl) { - const urlObj = url.parse(params.xformUrl); - if (!urlObj || !urlObj.protocol || !urlObj.host) { - const error = new Error('Bad Request. Form URL is invalid.'); - error.status = 400; - throw error; - } - const xUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`; - - return account - .check({ - openRosaServer: xUrl, - }) - .then( - ( - survey // no need to check quota - ) => - Promise.resolve({ - info: { - downloadUrl: params.xformUrl, - }, - account: survey.account, - }) - ) - .then((survey) => _setCookieAndCredentials(survey, req)); - } + const error = new Error('Bad Request. Survey information not complete.'); error.status = 400; throw error; diff --git a/app/lib/communicator.js b/app/lib/communicator.js index 64ce88d30..49b91aa7e 100644 --- a/app/lib/communicator.js +++ b/app/lib/communicator.js @@ -6,7 +6,7 @@ const request = require('request'); const { Auth } = require('request/lib/auth'); const TError = require('./custom-error').TranslatedError; const config = require('../models/config-model').server; -const debug = require('debug')('openrosa-communicator'); +const debug = require('debug')('enketo:openrosa-communicator'); const Xml2Js = require('xml2js'); const parser = new Xml2Js.Parser(); diff --git a/app/lib/pdf.js b/app/lib/pdf.js index 78142dbaf..e5ab76031 100644 --- a/app/lib/pdf.js +++ b/app/lib/pdf.js @@ -121,6 +121,7 @@ async function get( }, scale, printBackground: true, + timeout, }); } catch (e) { e.status = e.status || 400; diff --git a/app/models/cache-model.js b/app/models/cache-model.js index 5d1355583..8de7b1369 100644 --- a/app/models/cache-model.js +++ b/app/models/cache-model.js @@ -9,7 +9,7 @@ const utils = require('../lib/utils'); const prefix = 'ca:'; const expiry = 30 * 24 * 60 * 60; -const debug = require('debug')('cache-model'); +const debug = require('debug')('enketo:cache-model'); const clientGet = promisify(cacheClient.get).bind(cacheClient); const clientSet = promisify(cacheClient.set).bind(cacheClient); diff --git a/app/models/survey-model.js b/app/models/survey-model.js index 5393a04cb..03a2f1a0f 100644 --- a/app/models/survey-model.js +++ b/app/models/survey-model.js @@ -8,7 +8,7 @@ const TError = require('../lib/custom-error').TranslatedError; const config = require('./config-model').server; const pending = {}; -const debug = require('debug')('survey-model'); +const debug = require('debug')('enketo:survey-model'); /** * @typedef {import('./account-model').AccountObj} AccountObj diff --git a/app/views/index.pug b/app/views/index.pug index 17118c774..d8594ef57 100644 --- a/app/views/index.pug +++ b/app/views/index.pug @@ -57,6 +57,8 @@ block content li= t("langs.sv") when "lo" li= t("langs.lo") + when "uk" + li= t("langs.uk") when "sk" li= t("langs.sk") when "tr" diff --git a/app/views/surveys/webform.pug b/app/views/surveys/webform.pug index 7e513dec5..40e997894 100644 --- a/app/views/surveys/webform.pug +++ b/app/views/surveys/webform.pug @@ -20,7 +20,7 @@ block style block script - var suffix = (type && type !== 'single') ? '-' + (type === 'full' || type === 'preview' || type === 'fieldsubmission' ? 'oc' : type): '' - script#main-script(defer, module, src=`${basePath}${offlinePath || ''}/js/build/enketo-webform${suffix}.js`) + script#main-script(defer, type='module', src=`${basePath}${offlinePath || ''}/js/build/enketo-webform${suffix}.js`) -// load jini stuff asynchronously (OC) if jini && !headless diff --git a/config/build.js b/config/build.js index fa9437f5f..07e30bffe 100644 --- a/config/build.js +++ b/config/build.js @@ -1,4 +1,5 @@ -const alias = require('esbuild-plugin-alias'); +// @ts-check + const path = require('path'); const pkg = require('../package.json'); @@ -6,24 +7,22 @@ const cwd = process.cwd(); const entryPoints = pkg.entries.map((entry) => path.resolve(cwd, entry)); -const isProduction = process.env.NODE_ENV === 'production'; - -module.exports = { +module.exports = /** @satisfies {import('esbuild').BuildOptions} */ ({ + alias: Object.fromEntries( + Object.entries(pkg.browser).map(([key, value]) => [ + key, + path.resolve(cwd, `${value}.js`), + ]) + ), bundle: true, + chunkNames: 'chunks/[name]-[hash]', entryPoints, - format: 'iife', - minify: isProduction, + entryNames: '[name]', + external: ['crypto', 'libxslt'], + format: 'esm', + minify: true, outdir: path.resolve(cwd, './public/js/build'), - plugins: [ - alias( - Object.fromEntries( - Object.entries(pkg.browser).map(([key, value]) => [ - key, - path.resolve(cwd, `${value}.js`), - ]) - ) - ), - ], - sourcemap: isProduction ? false : 'inline', + sourcemap: true, + splitting: true, target: ['chrome89', 'edge89', 'firefox90', 'safari13'], -}; +}); diff --git a/config/express.js b/config/express.js index b201d0c92..b4b78a89e 100644 --- a/config/express.js +++ b/config/express.js @@ -14,7 +14,7 @@ const errorHandler = require('../app/controllers/error-handler'); const controllersPath = path.join(__dirname, '../app/controllers'); const app = express(); -const debug = require('debug')('express'); +const debug = require('debug')('enketo:express'); const config = require('../app/models/config-model'); // general diff --git a/docs/app_controllers_api-controller.js.html b/docs/app_controllers_api-controller.js.html index 1cc969ebb..43d1cdba0 100644 --- a/docs/app_controllers_api-controller.js.html +++ b/docs/app_controllers_api-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_api-v1-controller.js.html b/docs/app_controllers_api-v1-controller.js.html index 0192c170f..3d30a5fba 100644 --- a/docs/app_controllers_api-v1-controller.js.html +++ b/docs/app_controllers_api-v1-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_api-v2-controller.js.html b/docs/app_controllers_api-v2-controller.js.html index 4581746b9..2f9d0af12 100644 --- a/docs/app_controllers_api-v2-controller.js.html +++ b/docs/app_controllers_api-v2-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_authentication-controller.js.html b/docs/app_controllers_authentication-controller.js.html index ef9be1c27..2abb748eb 100644 --- a/docs/app_controllers_authentication-controller.js.html +++ b/docs/app_controllers_authentication-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_error-handler.js.html b/docs/app_controllers_error-handler.js.html index a93c77a55..d93a80309 100644 --- a/docs/app_controllers_error-handler.js.html +++ b/docs/app_controllers_error-handler.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_media-controller.js.html b/docs/app_controllers_media-controller.js.html index eb18f02e7..259500a08 100644 --- a/docs/app_controllers_media-controller.js.html +++ b/docs/app_controllers_media-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -57,7 +57,7 @@

app/controllers/media-controller.js

const express = require('express'); const router = express.Router(); -const debug = require('debug')('media-controller'); +const debug = require('debug')('enketo:media-controller'); const { RequestFilteringHttpAgent, RequestFilteringHttpsAgent, diff --git a/docs/app_controllers_offline-controller.js.html b/docs/app_controllers_offline-controller.js.html index 6957722aa..ba36f5b4d 100644 --- a/docs/app_controllers_offline-controller.js.html +++ b/docs/app_controllers_offline-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_pages-controller.js.html b/docs/app_controllers_pages-controller.js.html index 18a4d1022..6ceb9ef2a 100644 --- a/docs/app_controllers_pages-controller.js.html +++ b/docs/app_controllers_pages-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_submission-controller.js.html b/docs/app_controllers_submission-controller.js.html index f4bd12dc3..8040e7084 100644 --- a/docs/app_controllers_submission-controller.js.html +++ b/docs/app_controllers_submission-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_survey-controller.js.html b/docs/app_controllers_survey-controller.js.html index e9200edd1..b66be66ba 100644 --- a/docs/app_controllers_survey-controller.js.html +++ b/docs/app_controllers_survey-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_controllers_transformation-controller.js.html b/docs/app_controllers_transformation-controller.js.html index 471a9e85b..ddf28135a 100644 --- a/docs/app_controllers_transformation-controller.js.html +++ b/docs/app_controllers_transformation-controller.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -53,7 +53,7 @@

app/controllers/transformation-controller.js

const transformer = require('enketo-transformer'); const communicator = require('../lib/communicator'); -const { TranslatedError } = require('../lib/custom-error'); +const { ResponseError, TranslatedError } = require('../lib/custom-error'); const surveyModel = require('../models/survey-model'); const cacheModel = require('../models/cache-model'); const account = require('../models/account-model'); @@ -62,7 +62,6 @@

app/controllers/transformation-controller.js

const utils = require('../lib/utils'); const routerUtils = require('../lib/router-utils'); const express = require('express'); -const url = require('url'); const mediaLib = require('../lib/media'); const router = express.Router(); @@ -100,27 +99,15 @@

app/controllers/transformation-controller.js

/** @type {string | null} */ let formId = null; - /** @type {string | null} */ - let formFileName = null; - try { let survey = await _getSurveyParams(req); - // A request with "xformUrl" body parameter was used (unlaunched form) - if (survey.info != null) { - formFileName = survey.info.downloadUrl.replace( - /.*\/([^/]+)$/, - '$1' - ); - survey = await _getFormDirectly(survey); - - _respond(res, survey); + formId = survey.openRosaId; - return; + if (formId == null) { + throw new ResponseError(404); } - formId = survey.openRosaId; - const authenticated = await _authenticate(survey); const cached = await _getFormFromCache(authenticated); @@ -141,14 +128,10 @@

app/controllers/transformation-controller.js

}); } catch (error) { if (error.status === 403) { - const notFoundError = - formId == null - ? new TranslatedError('error.notfounddirectformurl', { - formFileName, - }) - : new TranslatedError('error.notfoundinformlist', { - formId, - }); + const notFoundError = new TranslatedError( + 'error.notfoundinformlist', + { formId } + ); notFoundError.status = 404; @@ -182,16 +165,6 @@

app/controllers/transformation-controller.js

.catch(next); } -/** - * @param {module:survey-model~SurveyObject} survey - survey object - * - * @return { Promise<module:survey-model~SurveyObject> } a Promise resolving with survey object with form transformation result - * - */ -function _getFormDirectly(survey) { - return communicator.getXForm(survey).then(transformer.transform); -} - /** * @param {module:survey-model~SurveyObject} survey - survey object * @@ -232,7 +205,10 @@

app/controllers/transformation-controller.js

delete survey.mediaUrlHash; delete survey.formHash; - return _getFormDirectly(survey).then(cacheModel.set); + return communicator + .getXForm(survey) + .then(transformer.transform) + .then(cacheModel.set); } return survey; @@ -357,7 +333,6 @@

app/controllers/transformation-controller.js

* @return { Promise<module:survey-model~SurveyObject> } a Promise resolving with survey object */ function _getSurveyParams(req) { - const params = req.body; const customParamName = req.app.get( 'query parameter to pass to submission' ); @@ -374,32 +349,7 @@

app/controllers/transformation-controller.js

return _setCookieAndCredentials(survey, req); }); } - if (params.xformUrl) { - const urlObj = url.parse(params.xformUrl); - if (!urlObj || !urlObj.protocol || !urlObj.host) { - const error = new Error('Bad Request. Form URL is invalid.'); - error.status = 400; - throw error; - } - const xUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`; - - return account - .check({ - openRosaServer: xUrl, - }) - .then( - ( - survey // no need to check quota - ) => - Promise.resolve({ - info: { - downloadUrl: params.xformUrl, - }, - account: survey.account, - }) - ) - .then((survey) => _setCookieAndCredentials(survey, req)); - } + const error = new Error('Bad Request. Survey information not complete.'); error.status = 400; throw error; diff --git a/docs/app_lib_communicator.js.html b/docs/app_lib_communicator.js.html index 5c78ff47b..715038305 100644 --- a/docs/app_lib_communicator.js.html +++ b/docs/app_lib_communicator.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -55,7 +55,7 @@

app/lib/communicator.js

const { Auth } = require('request/lib/auth'); const TError = require('./custom-error').TranslatedError; const config = require('../models/config-model').server; -const debug = require('debug')('openrosa-communicator'); +const debug = require('debug')('enketo:openrosa-communicator'); const Xml2Js = require('xml2js'); const parser = new Xml2Js.Parser(); diff --git a/docs/app_lib_custom-error.js.html b/docs/app_lib_custom-error.js.html index a89faac0c..a7b7be15b 100644 --- a/docs/app_lib_custom-error.js.html +++ b/docs/app_lib_custom-error.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_lib_media.js.html b/docs/app_lib_media.js.html index b1aa15294..72c5268c1 100644 --- a/docs/app_lib_media.js.html +++ b/docs/app_lib_media.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_lib_pdf.js.html b/docs/app_lib_pdf.js.html index 38d655a32..e7bf9a0fc 100644 --- a/docs/app_lib_pdf.js.html +++ b/docs/app_lib_pdf.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -152,6 +152,7 @@

app/lib/pdf.js

}, scale: options.scale, printBackground: true, + timeout, }); } catch (e) { e.status = e.status || 400; diff --git a/docs/app_lib_router-utils.js.html b/docs/app_lib_router-utils.js.html index 5c97fac74..87832be91 100644 --- a/docs/app_lib_router-utils.js.html +++ b/docs/app_lib_router-utils.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_lib_utils.js.html b/docs/app_lib_utils.js.html index 6bc886c52..3d34ac675 100644 --- a/docs/app_lib_utils.js.html +++ b/docs/app_lib_utils.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_models_account-model.js.html b/docs/app_models_account-model.js.html index a4795cdf8..e9642a21b 100644 --- a/docs/app_models_account-model.js.html +++ b/docs/app_models_account-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_models_cache-model.js.html b/docs/app_models_cache-model.js.html index f4ebf4e5d..30d4d9c6c 100644 --- a/docs/app_models_cache-model.js.html +++ b/docs/app_models_cache-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -58,7 +58,7 @@

app/models/cache-model.js

const prefix = 'ca:'; const expiry = 30 * 24 * 60 * 60; -const debug = require('debug')('cache-model'); +const debug = require('debug')('enketo:cache-model'); const clientGet = promisify(cacheClient.get).bind(cacheClient); const clientSet = promisify(cacheClient.set).bind(cacheClient); diff --git a/docs/app_models_config-model.js.html b/docs/app_models_config-model.js.html index a7aa286f5..8e30ae171 100644 --- a/docs/app_models_config-model.js.html +++ b/docs/app_models_config-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_models_instance-model.js.html b/docs/app_models_instance-model.js.html index 27f6b7bd1..92faa4e9e 100644 --- a/docs/app_models_instance-model.js.html +++ b/docs/app_models_instance-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_models_record-model.js.html b/docs/app_models_record-model.js.html index 552f0b571..a6d09ed06 100644 --- a/docs/app_models_record-model.js.html +++ b/docs/app_models_record-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_models_submission-model.js.html b/docs/app_models_submission-model.js.html index 7a5e057fa..7085813f0 100644 --- a/docs/app_models_submission-model.js.html +++ b/docs/app_models_submission-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/app_models_survey-model.js.html b/docs/app_models_survey-model.js.html index 51bf7b41a..ed5564dd3 100644 --- a/docs/app_models_survey-model.js.html +++ b/docs/app_models_survey-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -57,7 +57,7 @@

app/models/survey-model.js

const config = require('./config-model').server; const pending = {}; -const debug = require('debug')('survey-model'); +const debug = require('debug')('enketo:survey-model'); /** * @typedef {import('./account-model').AccountObj} AccountObj diff --git a/docs/app_models_user-model.js.html b/docs/app_models_user-model.js.html index dd61f2bf2..19c39c4c7 100644 --- a/docs/app_models_user-model.js.html +++ b/docs/app_models_user-model.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/global.html b/docs/global.html index 7aa2af6de..b7afcd45a 100644 --- a/docs/global.html +++ b/docs/global.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/index.html b/docs/index.html index a7571544f..6cf06ae26 100644 --- a/docs/index.html +++ b/docs/index.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -67,7 +67,7 @@

To get started visit our technical documentation.

Project status

Enketo was initiated in 2009 by Martijn van de Rijdt as a web-based alternative or complement to ODK Collect. It has become a core component of the ODK ecosystem and been adopted by several organizations beyond that ecosystem.

-

As of 2022, Enketo is maintained by Trevor Schmidt and the ODK team. Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its Technical Advisory Board.

+

As of 2022, Enketo is maintained by the ODK team (primarily Trevor Schmidt). Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its Technical Advisory Board.

Our current primary goals are:

  • Increasing alignment with ODK Collect, particularly in service of submission edits.
  • @@ -76,7 +76,7 @@

    Project status

Feature requests and project discussion are welcome on the ODK forum.

Translation

-

The user interface was translated by: Badisches Rotes Kreuz (German), Serkan Tümbaş (Turkish), Hélène Martin (French), Gurjot Sidhu(Hindi, Panjabi), "Abcmen" (Turkish), Otto Saldadze, Makhare Atchaidze, David Sichinava, Elene Ergeshidze (Georgian), Nancy Shapsough (Arabic), Noel O'Boyle (French), Miguel Moreno (Spanish), Tortue Torche (French), Bekim Kajtazi (Albanian), Marc Kreidler (German), Darío Hereñú (Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch).

+

The user interface was translated by: Oleg Zhyliak (Ukrainian), Karol Kozyra (Swedish), Badisches Rotes Kreuz (German), Serkan Tümbaş (Turkish), Hélène Martin (French), Gurjot Sidhu(Hindi, Panjabi), "Abcmen" (Turkish), Otto Saldadze, Makhare Atchaidze, David Sichinava, Elene Ergeshidze (Georgian), Nancy Shapsough (Arabic), Noel O'Boyle (French), Miguel Moreno (Spanish), Tortue Torche (French), Bekim Kajtazi (Albanian), Marc Kreidler (German), Darío Hereñú (Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch).

Send a message if you'd like to contribute! We use an easy web interface provided by Transifex.

Releases

    @@ -110,10 +110,11 @@

    Releases

Funding

-

The development of this application was funded by KoBo Toolbox (Harvard Humanitarian Initiative), iMMAP, OpenClinica, London School of Hygiene and Tropical Medicine, DIAL Open Source Center and Enketo LLC. The Enketo-core library (the form engine + themes) used in this application obtained significant funding from SEL (Columbia University), the Santa Fe Institute, Ona and the HRP project.

+

The development of this application is now led by ODK and funded by customers of the ODK Cloud hosted service.

+

Past funders include KoBo Toolbox (Harvard Humanitarian Initiative), iMMAP, OpenClinica, London School of Hygiene and Tropical Medicine, DIAL Open Source Center and Enketo LLC. Also see Enketo Core sponsors.

License

See the license document for this application's license.

-

Note that some of the libraries used in this app have a different license. In particular note this one.

+

Note that some of the libraries used in this app have a different license.

Note the 'Powered by Enketo' footer requirement as explained in enketo-core. This requirement is applicable to all Enketo apps, including this one, unless an exemption was granted.

The Enketo logo and Icons are trademarked by Enketo LLC and should only be used for the 'Powered by Enketo' requirement mentioned above (if applicable). To prevent infringement simply replace the logo images in /public/images with your own or contact Enketo LLC to discuss the use inside your app.

Change log

diff --git a/docs/module-account-model.html b/docs/module-account-model.html index 8c61cbaf7..6a51efe72 100644 --- a/docs/module-account-model.html +++ b/docs/module-account-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-api-controller.html b/docs/module-api-controller.html index 425043586..e34aae1d0 100644 --- a/docs/module-api-controller.html +++ b/docs/module-api-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-api-v1-controller.html b/docs/module-api-v1-controller.html index 9086669bd..3cb588e88 100644 --- a/docs/module-api-v1-controller.html +++ b/docs/module-api-v1-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-api-v2-controller.html b/docs/module-api-v2-controller.html index bcc58e0ae..fb55d0648 100644 --- a/docs/module-api-v2-controller.html +++ b/docs/module-api-v2-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-authentication-controller.html b/docs/module-authentication-controller.html index f53576381..16a2614aa 100644 --- a/docs/module-authentication-controller.html +++ b/docs/module-authentication-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-cache-model.html b/docs/module-cache-model.html index a4263f323..0a709c799 100644 --- a/docs/module-cache-model.html +++ b/docs/module-cache-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-communicator.html b/docs/module-communicator.html index 3d3424bc6..97b4b7f32 100644 --- a/docs/module-communicator.html +++ b/docs/module-communicator.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-config-model.html b/docs/module-config-model.html index eadd37f6a..fb827e44c 100644 --- a/docs/module-config-model.html +++ b/docs/module-config-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-custom-error.html b/docs/module-custom-error.html index 552485cf6..d44bc4fc5 100644 --- a/docs/module-custom-error.html +++ b/docs/module-custom-error.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-duplicates.html b/docs/module-duplicates.html index 6714831e0..56babaef5 100644 --- a/docs/module-duplicates.html +++ b/docs/module-duplicates.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-error-handler.html b/docs/module-error-handler.html index 489868ebf..6746dca79 100644 --- a/docs/module-error-handler.html +++ b/docs/module-error-handler.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-instance-model.html b/docs/module-instance-model.html index bc5173c2c..b91f6bc72 100644 --- a/docs/module-instance-model.html +++ b/docs/module-instance-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-media-controller.html b/docs/module-media-controller.html index 457bd1f40..b93dcb89c 100644 --- a/docs/module-media-controller.html +++ b/docs/module-media-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-offline-resources-controller.html b/docs/module-offline-resources-controller.html index c05a4c915..91d418dc9 100644 --- a/docs/module-offline-resources-controller.html +++ b/docs/module-offline-resources-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-pages-controller.html b/docs/module-pages-controller.html index 532f1ef27..2538b2f48 100644 --- a/docs/module-pages-controller.html +++ b/docs/module-pages-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-pdf.html b/docs/module-pdf.html index d6cc99f7d..75a161bbc 100644 --- a/docs/module-pdf.html +++ b/docs/module-pdf.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-router-utils.html b/docs/module-router-utils.html index 0738862de..4eac30c58 100644 --- a/docs/module-router-utils.html +++ b/docs/module-router-utils.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-submission-model.html b/docs/module-submission-model.html index 5ca9286f7..bfc9d1be8 100644 --- a/docs/module-submission-model.html +++ b/docs/module-submission-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-submissions-controller.html b/docs/module-submissions-controller.html index 1aedc56a0..5b9cde825 100644 --- a/docs/module-submissions-controller.html +++ b/docs/module-submissions-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-survey-controller.html b/docs/module-survey-controller.html index 6345bb2d7..c957abb95 100644 --- a/docs/module-survey-controller.html +++ b/docs/module-survey-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-survey-model.html b/docs/module-survey-model.html index 8efe4fc68..e5d89a0cd 100644 --- a/docs/module-survey-model.html +++ b/docs/module-survey-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-transformation-controller.html b/docs/module-transformation-controller.html index da2be147f..c9cea8b5e 100644 --- a/docs/module-transformation-controller.html +++ b/docs/module-transformation-controller.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -98,7 +98,7 @@

(inner) Source:
@@ -252,7 +252,7 @@

(inner) Source:
@@ -406,7 +406,7 @@

(inner) _
Source:
@@ -560,7 +560,7 @@

(inner) Source:
@@ -704,160 +704,6 @@
Returns:
-

(inner) _getFormDirectly(survey) → {Promise.<module:survey-model~SurveyObject>}

- - - - - - -
- - -
Source:
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
survey - - -module:survey-model~SurveyObject - - - -

survey object

- - - - - - - - - - - - - - - - -
Returns:
- - -
-

a Promise resolving with survey object with form transformation result

-
- - - -
-
- Type -
-
- -Promise.<module:survey-model~SurveyObject> - - -
-
- - - - - - - - - -

(inner) _getFormFromCache(survey) → {Promise.<module:survey-model~SurveyObject>}

@@ -870,7 +716,7 @@

(inner) Source:
@@ -1024,7 +870,7 @@

(inner) Source:
@@ -1178,7 +1024,7 @@

(inner) _res
Source:
@@ -1333,7 +1179,7 @@

(in
Source:
@@ -1510,7 +1356,7 @@

(inner)
Source:
@@ -1668,7 +1514,7 @@

(inner) Source:
@@ -1850,7 +1696,7 @@

(async, inner
Source:
diff --git a/docs/module-user-model.html b/docs/module-user-model.html index 3c877b84b..429b003c0 100644 --- a/docs/module-user-model.html +++ b/docs/module-user-model.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/module-utils.html b/docs/module-utils.html index 7e37bb42a..77127d86c 100644 --- a/docs/module-utils.html +++ b/docs/module-utils.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/tools_duplicates.js.html b/docs/tools_duplicates.js.html index e5536d56e..2b3584aeb 100644 --- a/docs/tools_duplicates.js.html +++ b/docs/tools_duplicates.js.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/tutorial-00-getting-started.html b/docs/tutorial-00-getting-started.html index e1c9e5439..cf10e00d1 100644 --- a/docs/tutorial-00-getting-started.html +++ b/docs/tutorial-00-getting-started.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

@@ -96,6 +96,10 @@

How to configure

How to run

Run with npm start from project root.

You can now check that the app is running by going to e.g. http://localhost:8005 (depending on your server and port set in config/config.json or the port forwarding set up in Vagrant (default is 8006))

+

How to enable debug logs

+

Enketo uses the npm debug module. All debug statements are prefixed with enketo: and will not appear unless the environment variable is set. To enable debugging logs for enketo specifically, set DEBUG as follows:

+
export DEBUG=enketo*
+
diff --git a/docs/tutorial-02-heroku.html b/docs/tutorial-02-heroku.html index 15d90359f..478b48f53 100644 --- a/docs/tutorial-02-heroku.html +++ b/docs/tutorial-02-heroku.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/tutorial-10-configure.html b/docs/tutorial-10-configure.html index 0aa50736d..48f011705 100644 --- a/docs/tutorial-10-configure.html +++ b/docs/tutorial-10-configure.html @@ -32,7 +32,7 @@ -

Home

Github repo

Change log

Tutorials

Modules

Global

+

Home

Github repo

Change log

Tutorials

Modules

Global

diff --git a/docs/tutorial-12-ordinals.html b/docs/tutorial-12-ordinals.html index f0eb33c13..9c19022f4 100644 --- a/docs/tutorial-12-ordinals.html +++ b/docs/tutorial-12-ordinals.html @@ -1,14 +1,14 @@ - + Tutorial: Repeats & Ordinals - Enketo Express - + - - - + + +